Esempio n. 1
0
 public SocketStream(Context ctx, Socket socket, string openedPath, StreamContext context, bool isAsync = false)
     : base(ctx, null, StreamAccessOptions.Read | StreamAccessOptions.Write, openedPath, context)
 {
     Debug.Assert(socket != null);
     this.socket = socket;
     this.IsWriteBuffered = false;
     this.eof = false;
     this.isAsync = isAsync;
     this.IsReadBuffered = false;
 }
Esempio n. 2
0
        /// <summary>
		/// Tests whether a given interface is defined.
		/// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="ifaceName">The name of the interface.</param>
		/// <param name="autoload">Whether to attempt to call <c>__autoload</c>.</param>
		/// <returns><B>true</B> if the interface given by <paramref name="ifaceName"/> has been defined,
		/// <B>false</B> otherwise.</returns>
		public static bool interface_exists(Context ctx, string ifaceName, bool autoload = true)
        {
            var info = ctx.GetDeclaredType(ifaceName);
            if (info == null && autoload)
            {
                throw new NotImplementedException("autoload");
            }

            //
            return info != null && info.Type.GetTypeInfo().IsInterface;
        }
Esempio n. 3
0
        /// <summary>
		/// Tests whether a given class is defined.
		/// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="className">The name of the class.</param>
		/// <param name="autoload">Whether to attempt to call <c>__autoload</c>.</param>
		/// <returns><B>true</B> if the class given by <paramref name="className"/> has been defined,
		/// <B>false</B> otherwise.</returns>
		public static bool class_exists(Context ctx, string className, bool autoload = true)
        {
            var info = ctx.GetDeclaredType(className);
            if (info == null && autoload)
            {
                throw new NotImplementedException("autoload");
            }

            //
            return info != null;
        }
Esempio n. 4
0
        /// <summary>
		/// Calls a function or a method defined by callback with given arguments.
		/// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="function">Target callback.</param>
		/// <param name="args">The arguments.</param>
		/// <returns>The return value.</returns>
		public static PhpValue call_user_func(Context ctx, IPhpCallable function, params PhpValue[] args)
        {
            if (function == null)
            {
                //PhpException.ArgumentNull("function");
                //return null;
                throw new ArgumentNullException();  // NOTE: should not be reached, runtime converts NULL to InvalidCallback instance
            }

            Debug.Assert(args != null);

            // invoke the callback:
            return function.Invoke(ctx, args);
        }
Esempio n. 5
0
        /// <summary>
        /// Calls a function or a method defined by callback with arguments stored in an array.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="function">Target callback.</param>
        /// <param name="args">Arguments. Can be null.</param>
        /// <returns>The returned value.</returns>
        public static PhpValue call_user_func_array(Context ctx, IPhpCallable function, PhpArray args)
        {
            PhpValue[] args_array;

            if (args != null && args.Count != 0)
            {
                args_array = new PhpValue[args.Count];
                args.CopyValuesTo(args_array, 0);
            }
            else
            {
                args_array = Core.Utilities.ArrayUtils.EmptyValues;
            }

            return call_user_func(ctx, function, args_array);
        }
Esempio n. 6
0
        public static TextElement FromValue(Context ctx, PhpValue value)
        {
            switch (value.TypeCode)
            {
                case PhpTypeCode.Object:
                    if (value.Object is byte[])
                    {
                        return new TextElement((byte[])value.Object);
                    }
                    goto default;

                case PhpTypeCode.WritableString:
                    return new TextElement(value.WritableString, ctx.StringEncoding);

                default:
                    return new TextElement(value.ToStringOrThrow(ctx));
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Retrieves defined constants.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="categorize">Returns a multi-dimensional array with categories in the keys of the first dimension and constants and their values in the second dimension. </param>
        /// <returns>Retrives the names and values of all the constants currently defined.</returns>
        public static PhpArray get_defined_constants(Context ctx, bool categorize = false)
        {
            var result = new PhpArray();

            if (categorize)
            {
                throw new NotImplementedException();
            }
            else
            {
                foreach (var c in ctx.GetConstants())
                {
                    result.Add(c.Key, c.Value);
                }
            }

            //
            return result;
        }
Esempio n. 8
0
        int ProcessStatus(Context ctx, ref PhpValue status)
        {
            switch (status.TypeCode)
            {
                case PhpTypeCode.Alias:
                    return ProcessStatus(ctx, ref status.Alias.Value);

                case PhpTypeCode.Long:
                case PhpTypeCode.Int32:
                    return (int)status.ToLong();

                default:
                    if (ctx != null)
                    {
                        ctx.Echo(status);
                    }
                    return 0;
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Increases the level of buffering, enables output buffering if disabled and assignes the filtering callback
        /// to the new level of buffering.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="filter">The filtering callback. Ignores invalid callbacks.</param>
        /// <param name="chunkSize">Not supported.</param>
        /// <param name="erase">Not supported.</param>
        /// <returns>Whether the filter is valid callback.</returns>
        public static bool ob_start(Context ctx, Delegate filter = null, int chunkSize = 0, bool erase = true)
        {
            if (chunkSize != 0)
                //PhpException.ArgumentValueNotSupported("chunkSize", "!= 0");
                throw new NotSupportedException("chunkSize != 0");
            if (!erase)
                //PhpException.ArgumentValueNotSupported("erase", erase);
                throw new NotSupportedException("erase == false");

            ctx.BufferedOutput.IncreaseLevel();

            bool result = true;

            // skips filter setting if filter is not specified or valid:
            if (filter != null) //  && (result = filter.Bind())) // TODO: PhpCallback.Bind -> Delegate, done by caller
                ctx.BufferedOutput.SetFilter(filter);

            ctx.IsOutputBuffered = true;

            return result;
        }
Esempio n. 10
0
 public static int preg_match_all(Context ctx, string pattern, string subject)
 {
     PhpArray matches;
     return preg_match_all(ctx, pattern, subject, out matches);
 }
Esempio n. 11
0
 /// <summary>
 /// Create <see cref="Generator"/> with specified state machine function and parameters.
 /// </summary>
 public static Generator BuildGenerator(Context ctx, object @this, PhpArray locals, GeneratorStateMachineDelegate method) => new Generator(ctx, @this, locals, method);
Esempio n. 12
0
        /// <summary>
        /// Check if the path lays inside of the directory tree specified 
        /// by the <c>open_basedir</c> configuration option and return the resulting <paramref name="absolutePath"/>.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="relativePath">The filename to search for.</param>
        /// <param name="absolutePath">The combined absolute path (either in the working directory 
        /// or in an include path wherever it has been found first).</param>
        /// <returns><c>true</c> if the file was found in an include path.</returns>
        private static bool CheckIncludePath(Context ctx, string relativePath, ref string absolutePath)
        {
            // Note: If the absolutePath exists, it overtakse the include_path search.
            if (Path.IsPathRooted(relativePath)) return false;
            if (File.Exists(absolutePath)) return false;

            var paths = ctx.IncludePaths;
            if (paths == null || paths.Length == 0) return false;

            foreach (string s in paths)
            {
                if (string.IsNullOrEmpty(s)) continue;
                string abs = Path.GetFullPath(Path.Combine(s, relativePath));
                if (File.Exists(abs))
                {
                    absolutePath = abs;
                    return true;
                }
            }
            return false;
        }
Esempio n. 13
0
        /// <summary>
        /// Openes a PhpStream using the appropriate StreamWrapper.
        /// </summary>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="path">URI or filename of the resource to be opened.</param>
        /// <param name="mode">A file-access mode as passed to the PHP function.</param>
        /// <param name="options">A combination of <see cref="StreamOpenOptions"/>.</param>
        /// <param name="context">A valid StreamContext. Must not be <c>null</c>.</param>
        /// <returns></returns>
        public static PhpStream Open(Context ctx, string path, string mode, StreamOpenOptions options, StreamContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            Debug.Assert(ctx != null);

            StreamWrapper wrapper;
            if (!PhpStream.ResolvePath(ctx, ref path, out wrapper, CheckAccessMode.FileMayExist, (CheckAccessOptions)options))
                return null;

            return wrapper.Open(ctx, ref path, mode, options, context);

        }
Esempio n. 14
0
 /// <summary>
 /// Simple version of the stream opening function
 /// </summary>
 /// <param name="ctx">Current runtime context.</param>
 /// <param name="path">URI or filename of the resource to be opened</param>
 /// <param name="mode">File access mode</param>
 /// <returns></returns>
 internal static PhpStream Open(Context ctx, string path, StreamOpenMode mode)
 {
     string modeStr = null;
     switch (mode)
     {
         case StreamOpenMode.ReadBinary: modeStr = "rb"; break;
         case StreamOpenMode.WriteBinary: modeStr = "wb"; break;
         case StreamOpenMode.ReadText: modeStr = "rt"; break;
         case StreamOpenMode.WriteText: modeStr = "wt"; break;
     }
     Debug.Assert(modeStr != null);
     return Open(ctx, path, modeStr, StreamOpenOptions.Empty, StreamContext.Default);
 }
Esempio n. 15
0
 static void OutputChunks(Context ctx, object[] chunks, int count)
 {
     for (int i = 0; i < count; i++)
     {
         OutputChunk(ctx, chunks[i]);
     }
 }
Esempio n. 16
0
 internal void Output(Context ctx)
 {
     var chunks = _chunks;
     if (chunks != null)
     {
         if (chunks.GetType() == typeof(object[]))
         {
             OutputChunks(ctx, (object[])chunks, _chunksCount);
         }
         else
         {
             OutputChunk(ctx, chunks);
         }
     }
 }
Esempio n. 17
0
 public static int preg_match(Context ctx, string pattern, string subject, out PhpArray matches, int flags = 0, long offset = 0)
 {
     throw new NotImplementedException();
 }
Esempio n. 18
0
 public static int preg_match_all(Context ctx, string pattern, string subject, out PhpArray matches, int flags = PREG_PATTERN_ORDER, int offset = 0)
 {
     throw new NotImplementedException();
 }
Esempio n. 19
0
 public static int preg_match(Context ctx, string pattern, string subject)
 {
     var regex = new PerlRegex.Regex(pattern);
     return regex.Match(subject).Success ? 1 : 0;
 }
Esempio n. 20
0
 public static PhpValue date_sunset(Context ctx, int timestamp, TimeFormats format, double latitude, double longitude)
 {
     return GetSunTime(ctx, timestamp, format, latitude, longitude, Double.NaN, Double.NaN, false);
 }
Esempio n. 21
0
        public static PhpArray preg_grep(Context ctx, string pattern, PhpArray input, int flags = 0)
        {
            if (input == null)
            {
                return null;
            }

            var result = new PhpArray(input.Count);

            if (input.Count != 0)
            {
                var regex = new PerlRegex.Regex(pattern);

                var enumerator = input.GetFastEnumerator();
                while (enumerator.MoveNext())
                {
                    var str = enumerator.CurrentValue.ToStringOrThrow(ctx);
                    var m = regex.Match(str);

                    // move a copy to return array if success and not invert or
                    // not success and invert
                    if (m.Success ^ (flags & PREG_GREP_INVERT) != 0)
                    {
                        result.Add(enumerator.CurrentKey, enumerator.CurrentValue.DeepCopy());
                    }
                }
            }

            //
            return result;
        }
Esempio n. 22
0
 public static PhpValue date_sunset(Context ctx, int timestamp, TimeFormats format, double latitude, double longitude, double zenith, double offset)
 {
     return GetSunTime(ctx, timestamp, format, latitude, longitude, zenith, offset, false);
 }
Esempio n. 23
0
        static void OutputChunk(Context ctx, object chunk)
        {
            AssertChunkObject(chunk);

            if (chunk.GetType() == typeof(string)) ctx.Output.Write((string)chunk);
            else if (chunk.GetType() == typeof(byte[])) ctx.OutputStream.Write((byte[])chunk);
            else if (chunk.GetType() == typeof(PhpString)) ((PhpString)chunk).Output(ctx);
            else if (chunk.GetType() == typeof(char[])) ctx.Output.Write((char[])chunk);
            else throw new ArgumentException();
        }
Esempio n. 24
0
        static PhpValue GetSunTime(Context ctx, int timestamp, TimeFormats format, double latitude, double longitude, double zenith, double offset, bool getSunrise)
        {
            var zone = PhpTimeZone.GetCurrentTimeZone(ctx);
            var utc = DateTimeUtils.UnixTimeStampToUtc(timestamp);
            var local = TimeZoneInfo.ConvertTime(utc, zone);

            if (Double.IsNaN(latitude) || Double.IsNaN(longitude) || Double.IsNaN(zenith))
            {
                //LibraryConfiguration config = LibraryConfiguration.GetLocal(ScriptContext.CurrentContext);

                //if (Double.IsNaN(latitude))
                //    latitude = config.Date.Latitude;
                //if (Double.IsNaN(longitude))
                //    longitude = config.Date.Longitude;
                //if (Double.IsNaN(zenith))
                //    zenith = (getSunrise) ? config.Date.SunriseZenith : config.Date.SunsetZenith;
                throw new NotImplementedException();
            }

            if (Double.IsNaN(offset))
                offset = zone.GetUtcOffset(local).TotalHours;

            double result_utc = CalculateSunTime(local.DayOfYear, latitude, longitude, zenith, getSunrise);
            double result = result_utc + offset;

            switch (format)
            {
                case TimeFormats.Integer:
                    return PhpValue.Create((timestamp - (timestamp % (24 * 3600))) + (int)(3600 * result));

                case TimeFormats.String:
                    return PhpValue.Create(string.Format("{0:00}:{1:00}", (int)result, (int)(60 * (result - (double)(int)result))));

                case TimeFormats.Double:
                    return PhpValue.Create(result);

                default:
                    //PhpException.InvalidArgument("format");
                    //return PhpValue.Null;
                    throw new ArgumentException();
            }
        }
Esempio n. 25
0
 public string ToStringOrThrow(Context ctx) => ToString(ctx.StringEncoding);
Esempio n. 26
0
 public static PhpValue preg_replace(Context ctx, PhpValue pattern, PhpValue replacement, PhpValue subject, int limit = -1)
 {
     long count;
     return preg_replace(ctx, pattern, replacement, subject, limit, out count);
 }
Esempio n. 27
0
 public static PhpStream Open(Context ctx, string path, string mode, StreamOpenOptions options)
 {
     return Open(ctx, path, mode, options, StreamContext.Default);
 }
Esempio n. 28
0
        /// <summary>
        /// Perform a regular expression search and replace.
        /// </summary>
        /// <param name="ctx">A reference to current context. Cannot be <c>null</c>.</param>
        /// <param name="pattern">The pattern to search for. It can be either a string or an array with strings.</param>
        /// <param name="replacement">The string or an array with strings to replace.
        /// If this parameter is a string and the pattern parameter is an array, all patterns will be
        /// replaced by that string. If both pattern and replacement parameters are arrays, each pattern will be
        /// replaced by the replacement counterpart. If there are fewer elements in the replacement array than
        /// in the pattern array, any extra patterns will be replaced by an empty string.</param>
        /// <param name="subject">The string or an array with strings to search and replace.
        /// If subject is an array, then the search and replace is performed on every entry of subject, and the return value is an array as well.</param>
        /// <param name="limit">The maximum possible replacements for each pattern in each subject string. Defaults to <c>-1</c> (no limit).</param>
        /// <param name="count">This variable will be filled with the number of replacements done.</param>
        /// <returns></returns>
        public static PhpValue preg_replace(Context ctx, PhpValue pattern, PhpValue replacement, PhpValue subject, int limit, out long count)
        {
            count = 0;

            // PHP's behaviour for undocumented limit range
            if (limit < -1)
            {
                limit = 0;
            }

            //
            var replacement_array = replacement.AsArray();
            var pattern_array = pattern.AsArray();

            if (pattern_array == null)
            {
                if (replacement_array == null)
                {
                    // string pattern
                    // string replacement

                    return preg_replace(ctx, pattern.ToStringOrThrow(ctx), replacement.ToStringOrThrow(ctx), null, subject, limit, ref count);
                }
                else
                {
                    // string pattern and array replacement not allowed:
                    throw new ArgumentException("replacement_array_pattern_not", nameof(replacement));
                    // return PhpValue.Null;
                }
            }
            else if (replacement_array == null)
            {
                // array  pattern
                // string replacement
            }
            else
            {
                // array pattern
                // array replacement
            }

            throw new NotImplementedException();
        }
Esempio n. 29
0
        /// <summary>
        /// Merges the path with the current working directory
        /// to get a canonicalized absolute pathname representing the same file.
        /// </summary>
        /// <remarks>
        /// This method is an analogy of <c>main/safe_mode.c: php_checkuid</c>.
        /// Looks for the file in the <c>include_path</c> and checks for <c>open_basedir</c> restrictions.
        /// </remarks>
        /// <param name="ctx">Current runtime context.</param>
        /// <param name="path">An absolute or relative path to a file.</param>
        /// <param name="wrapper">The wrapper found for the specified file or <c>null</c> if the path resolution fails.</param>
        /// <param name="mode">The checking mode of the <see cref="CheckAccess"/> method (file, directory etc.).</param>
        /// <param name="options">Additional options for the <see cref="CheckAccess"/> method.</param>
        /// <returns><c>true</c> if all the resolution and checking passed without an error, <b>false</b> otherwise.</returns>
        /// <exception cref="PhpException">Security violation - when the target file 
        /// lays outside the tree defined by <c>open_basedir</c> configuration option.</exception>
        public static bool ResolvePath(Context ctx, ref string path, out StreamWrapper wrapper, CheckAccessMode mode, CheckAccessOptions options)
        {
            // Path will contain the absolute path without file:// or the complete URL; filename is the relative path.
            string filename, scheme = GetSchemeInternal(path, out filename);
            wrapper = StreamWrapper.GetWrapper(ctx, scheme, (StreamOptions)options);
            if (wrapper == null) return false;

            if (wrapper.IsUrl)
            {
                // Note: path contains the whole URL, filename the same without the scheme:// portion.
                // What to check more?
            }
            else if (scheme != "php")
            {
                try
                {
                    // Filename contains the original path without the scheme:// portion, check for include path.
                    bool isInclude = false;
                    if ((options & CheckAccessOptions.UseIncludePath) > 0)
                    {
                        isInclude = CheckIncludePath(ctx, filename, ref path);
                    }

                    // Path will now contain an absolute path (either to an include or actual directory).
                    if (!isInclude)
                    {
                        path = Path.GetFullPath(Path.Combine(ctx.WorkingDirectory, filename));
                    }
                }
                catch (System.Exception)
                {
                    if ((options & CheckAccessOptions.Quiet) == 0)
                        PhpException.Throw(PhpError.Warning, ErrResources.stream_filename_invalid, FileSystemUtils.StripPassword(path));
                    return false;
                }

                // NOTE: we should let OS & Security configuration to decide
                //var global_config = Configuration.Global;

                //// Note: extensions check open_basedir too -> double check..
                //if (!global_config.SafeMode.IsPathAllowed(path))
                //{
                //    if ((options & CheckAccessOptions.Quiet) == 0)
                //        PhpException.Throw(PhpError.Warning, ErrResources.open_basedir_effect, path, global_config.SafeMode.GetAllowedPathPrefixesJoin());
                //    return false;
                //}

                // Replace all '/' with '\'.
                // path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                Debug.Assert(
                    path.IndexOf(Path.AltDirectorySeparatorChar) == -1 ||
                    (Path.AltDirectorySeparatorChar == Path.DirectorySeparatorChar),    // on Mono, so ignore it
                    string.Format("'{0}' should not contain '{1}' char.", path, Path.AltDirectorySeparatorChar));

                // The file wrapper expects an absolute path w/o the scheme, others expect the scheme://url.
                if (scheme != "file")
                {
                    path = String.Format("{0}://{1}", scheme, path);
                }
            }

            return true;
        }
Esempio n. 30
0
        static PhpValue preg_replace(Context ctx, string pattern, string replacement, PhpCallable callback, PhpValue subject, int limit, ref long count)
        {
            var regex = new PerlRegex.Regex(pattern);

            // TODO: count
            // TODO: callback

            var subject_array = subject.AsArray();
            if (subject_array == null)
            {
                return PhpValue.Create(regex.Replace(subject.ToStringOrThrow(ctx), replacement, limit));
            }
            else
            {
                var arr = new PhpArray(subject_array, false);
                var enumerator = arr.GetFastEnumerator();
                while (enumerator.MoveNext())
                {
                    var newvalue = regex.Replace(enumerator.CurrentValue.ToStringOrThrow(ctx), replacement, limit);
                    enumerator.CurrentValue = PhpValue.Create(newvalue);
                }

                return PhpValue.Create(arr);
            }
        }
Esempio n. 31
0
        /// <summary>
        /// PhpStream is created by a StreamWrapper together with the
        /// encapsulated RawStream (the actual file opening is handled 
        /// by the wrapper).
        /// </summary>
        /// <remarks>
        /// This class newly implements the auto-remove behavior too
        /// (see <see cref="StreamAccessOptions.Temporary"/>).
        /// </remarks>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="openingWrapper">The parent instance.</param>
        /// <param name="accessOptions">The additional options parsed from the <c>fopen()</c> mode.</param>
        /// <param name="openedPath">The absolute path to the opened resource.</param>
        /// <param name="context">The stream context passed to fopen().</param>
        public PhpStream(Context ctx, StreamWrapper openingWrapper, StreamAccessOptions accessOptions, string openedPath, StreamContext context)
            : base(PhpStreamTypeName)
        {
            Debug.Assert(ctx != null);
            Debug.Assert(context != null);

            _ctx = ctx;
            _context = context;

            this.Wrapper = openingWrapper;
            this.OpenedPath = openedPath;

            // Stream modifiers (defined in open-time).
            this.Options = accessOptions;

            // Allocate the text conversion filters for this stream.
            if ((accessOptions & StreamAccessOptions.UseText) > 0)
            {
                if ((accessOptions & StreamAccessOptions.Read) > 0)
                {
                    textReadFilter = new TextReadFilter();
                }
                if ((accessOptions & StreamAccessOptions.Write) > 0)
                {
                    textWriteFilter = new TextWriteFilter();
                }
            }

            // this.readTimeout = ScriptContext.CurrentContext.Config.FileSystem.DefaultSocketTimeout;
        }
Esempio n. 32
0
 string IPhpConvertible.ToStringOrThrow(Context ctx) => ToString();