Esempio n. 1
0
        public PhpValue GetValue(PhpValue value, Context ctx, Type classContext)
        {
            var receiver = value.AsObject();

            if (receiver != null)
            {
                // CONSIDER: value = Operators.PropertyGetValue( .. )

                var t = receiver.GetPhpTypeInfo();
                if (BinderHelpers.TryResolveDeclaredProperty(t, classContext, false, Name, out var p))
                {
                    value = p.GetValue(ctx, receiver);
                }
                else
                {
                    value = Operators.RuntimePropertyGetValue(ctx, t, receiver, propertyName: Name);
                }

                return(Next.GetValue(value, ctx, classContext));
            }
            else
            {
                PhpException.VariableMisusedAsObject(value, false);
                return(PhpValue.Null);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Tests whether <paramref name="value"/>'s class is derived from a class given by <paramref name="class_name"/>.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="value">The object to test.</param>
        /// <param name="class_name">The name of the class.</param>
        /// <param name="allow_string">If this parameter set to FALSE, string class name as object is not allowed. This also prevents from calling autoloader if the class doesn't exist.</param>
        /// <returns><B>true</B> if the object <paramref name="value"/> belongs to <paramref name="class_name"/> class or
        /// a class which is a subclass of <paramref name="class_name"/>, <B>false</B> otherwise.</returns>
        public static bool is_a(Context ctx, PhpValue value, string class_name, bool allow_string)
        {
            // first load type of {value}
            PhpTypeInfo tvalue;
            var         obj = value.AsObject();

            if (obj != null)
            {
                tvalue = obj.GetPhpTypeInfo();
            }
            else
            {
                var tname = value.AsString();
                if (tname != null && allow_string)
                {
                    // value can be a string specifying a class name
                    tvalue = ctx.GetDeclaredType(tname, true);
                }
                else
                {
                    // invalid argument type ignored
                    return(false);
                }
            }

            // second, load type of {class_name}
            var ctype = ctx.GetDeclaredType(class_name, false);

            // check is_a
            return(tvalue != null && ctype != null && tvalue.Type.IsSubclassOf(ctype.Type.AsType()));
        }
Esempio n. 3
0
        public void __construct(Context ctx, PhpValue name)
        {
            Debug.Assert(_routine == null, "Subsequent call not allowed.");

            object instance;
            var    str = name.ToStringOrNull();

            if (str != null)
            {
                _closure = null;
                _routine = ctx.GetDeclaredFunction(str) ?? throw new ReflectionException(string.Format(Resources.LibResources.function_does_not_exist, str));
            }
            else if ((instance = name.AsObject()) != null)
            {
                if (instance is Closure closure)
                {
                    _closure = closure;
                    _routine = closure.Callable() as RoutineInfo;
                    // TODO: handle its $this parameter and use parameters
                }
            }

            if (_routine == null)
            {
                throw new ReflectionException();
            }
        }
Esempio n. 4
0
        public void __construct(Context ctx, PhpValue name)
        {
            Debug.Assert(_routine == null, "Subsequent call not allowed.");

            object instance;
            var    str = name.ToStringOrNull();

            if (str != null)
            {
                _routine = ctx.GetDeclaredFunction(str);
            }
            else if ((instance = name.AsObject()) != null)
            {
                if (instance is Closure)
                {
                    // _routine = ((Closure)instance).routine; // TODO: handle its $this parameter and use parameters
                    throw new NotImplementedException();
                }
            }

            if (_routine == null)
            {
                throw new ArgumentException();  // TODO: ReflectionException
            }
        }
    internal RuntimeTypeHandle ResolveNewScope(object newthis, PhpValue newscope = default(PhpValue))
    {
        if (newscope.IsSet)
        {
            // Operators.TypeNameOrObjectToType(newscope) + handle "static"

            object obj;
            string str;

            if ((obj = (newscope.AsObject())) != null)
            {
                return(obj.GetType().TypeHandle);
            }
            else if ((str = PhpVariable.AsString(newscope)) != null)
            {
                return("static".Equals(str, StringComparison.OrdinalIgnoreCase)
                    ? _scope
                    : _ctx.GetDeclaredTypeOrThrow(str, true).TypeHandle);
            }
            else if (newscope.IsNull)
            {
                return(default(RuntimeTypeHandle));
            }
            else
            {
                throw new ArgumentException(nameof(newscope));
            }
        }

        return(ReferenceEquals(newthis, null) ? _scope : newthis.GetType().TypeHandle);
    }
Esempio n. 6
0
        /// <summary>
        /// Verifies whether a property has been defined for the given object object or class.
        /// </summary>
        /// <remarks>
        /// If an object is passed in the first parameter, the property is searched among runtime fields as well.
        /// </remarks>
        public static bool property_exists(Context ctx, PhpValue classNameOrObject, string propertyName)
        {
            var tinfo = TypeNameOrObjectToType(ctx, classNameOrObject);

            if (tinfo == null)
            {
                return(false);
            }

            if (tinfo.GetDeclaredProperty(propertyName) != null)
            {
                // CT property found
                return(true);
            }

            var instance = classNameOrObject.AsObject();

            if (instance != null && tinfo.GetRuntimeProperty(propertyName, instance) != null)
            {
                // RT property found
                return(true);
            }

            //
            return(false);
        }
Esempio n. 7
0
        /// <summary>
        /// Internal image save.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="im">Image resource.</param>
        /// <param name="to">Optional. Filename or stream. If not specified the functiona saves the image to output stream.</param>
        /// <param name="saveaction">Callback that actually save the image to given stream. Called when all checks pass.</param>
        /// <returns>True if save succeeded.</returns>
        static bool imagesave(Context ctx, PhpResource im, PhpValue to /* = null*/, Action <Image <Rgba32>, Stream> saveaction)
        {
            Debug.Assert(saveaction != null);

            // check the gd2 resource
            var img = PhpGdImageResource.ValidImage(im);

            if (img == null)
            {
                return(false);
            }

            try
            {
                // not specified stream or filename -> save to the output stream
                if (to.IsEmpty)
                {
                    saveaction(img.Image, ctx.OutputStream);
                    return(true);
                }

                // filename specified?
                var filename = to.ToStringOrNull();
                if (filename != null)
                {
                    using (var stream = File.OpenWrite(Path.Combine(ctx.WorkingDirectory, filename)))
                    {
                        saveaction(img.Image, stream);
                    }

                    return(true);
                }

                // to a PHP stream ?
                // validate the stream resource, outputs warning in case of invalid resource
                var phpstream = PhpStream.GetValid(to.AsObject() as PhpResource, FileAccess.Write);
                if (phpstream == null)
                {
                    return(false);
                }

                // save image to byte[] and pass it to php stream

                var ms = new MemoryStream();

                saveaction(img.Image, ms);

                phpstream.WriteBytes(ms.ToArray());
                phpstream.Flush();

                // stream is closed after the operation
                phpstream.Dispose();
            }
            catch
            {
                return(false);
            }

            return(true);
        }
Esempio n. 8
0
        /// <summary>
        /// Removes an object from the storage.
        /// </summary>
        public virtual void offsetUnset(PhpValue offset)
        {
            var obj = offset.AsObject();

            if (obj != null)
            {
                this.storage.Remove(Keys.MakeKey(obj));
            }
        }
Esempio n. 9
0
 public override void __construct(Context ctx, PhpValue @class)
 {
     _instance = @class.AsObject();
     if (_instance == null)
     {
         throw new ReflectionException();
     }
     _tinfo = _instance.GetPhpTypeInfo();
 }
Esempio n. 10
0
        /// <summary>
        /// This function allows to use parser inside object. All callback functions could be set with
        /// xml_set_element_handler() etc and assumed to be methods of object.
        /// </summary>
        /// <param name="parser">A reference to the XML parser to use inside the object. </param>
        /// <param name="objRef">The object where to use the XML parser.</param>
        /// <returns>Returns TRUE on success or FALSE on failure. </returns>
        public static bool xml_set_object(PhpResource parser, PhpValue objRef)
        {
            var xmlParser = XmlParserResource.ValidResource(parser);

            if (xmlParser != null)
            {
                xmlParser.HandlerObject = objRef.AsObject();
                return(true);
            }

            return(false);
        }
Esempio n. 11
0
        public PhpAlias GetAlias(ref PhpValue value, Context ctx, Type classContext)
        {
            PhpValue tmp;

            if (value.AsObject() is ArrayAccess arrayaccess)
            {
                // special case for ArrayAccess avoids conversion to IntStringKey

                tmp = arrayaccess.offsetGet(Key);

                switch (Next.Operation)
                {
                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.EnsureAlias(ref tmp);
                    break;

                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(PhpValue.EnsureObject(ref tmp));
                    break;

                case RuntimeChainOperation.End:
                    return(PhpValue.EnsureAlias(ref tmp));

                default:
                    throw new InvalidOperationException();
                }
            }
            else
            {
                var arr = PhpValue.EnsureArray(ref value);

                switch (Next.Operation)
                {
                case RuntimeChainOperation.ArrayItem:
                    tmp = PhpValue.Create(arr.EnsureItemArray(Key));
                    break;

                case RuntimeChainOperation.Property:
                    tmp = PhpValue.FromClass(arr.EnsureItemObject(Key));
                    break;

                case RuntimeChainOperation.End:
                    return(arr.EnsureItemAlias(Key));

                default:
                    throw new InvalidOperationException();
                }
            }

            //
            return(Next.GetAlias(ref tmp, ctx, classContext));
        }
Esempio n. 12
0
        /// <summary>
        /// Returns the data associated with an object in the storage.
        /// </summary>
        public virtual PhpValue offsetGet(PhpValue offset)
        {
            var obj = offset.AsObject();

            if (obj != null && this.storage.TryGetValue(Keys.MakeKey(obj), out PhpValue value))
            {
                return(value.Array[Keys.Info]);
            }
            else
            {
                throw new UnexpectedValueException();
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Associate data to an object in the storage.
        /// </summary>
        public virtual void offsetSet(PhpValue offset, PhpValue value = default(PhpValue))
        {
            var obj = offset.AsObject();

            if (obj != null)
            {
                Keys.AttachImpl(storage, obj, value);
            }
            else
            {
                throw new ArgumentException(nameof(offset));
            }
        }
Esempio n. 14
0
        public static string get_class(PhpValue @object)
        {
            var obj = @object.AsObject();

            if (obj == null || obj is PhpResource)
            {
                // TODO: Warning: get_class() expects parameter 1 to be object, {PhpVariable.GetTypeName(@object)} given
                PhpException.InvalidArgumentType(nameof(@object), PhpVariable.TypeNameObject);
                return(null); // FALSE
            }

            return(PhpVariable.GetClassName(obj));
        }
Esempio n. 15
0
        /// <summary>
        /// Tests whether <paramref name="value"/>'s class is derived from a class given by <paramref name="class_name"/>.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="value">The object to test.</param>
        /// <param name="class_name">The name of the class.</param>
        /// <param name="allow_string">If this parameter set to FALSE, string class name as object is not allowed. This also prevents from calling autoloader if the class doesn't exist.</param>
        /// <returns><B>true</B> if the object <paramref name="value"/> belongs to <paramref name="class_name"/> class or
        /// a class which is a subclass of <paramref name="class_name"/>, <B>false</B> otherwise.</returns>
        public static bool is_a(Context ctx, PhpValue value, string class_name, bool allow_string)
        {
            var obj = value.AsObject();

            if (allow_string)
            {
                // value can be a string specifying a class name
                // autoload is allowed

                throw new NotImplementedException();
            }
            else
            {
                return(is_a(ctx, obj, class_name));
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Get <see cref="PhpTypeInfo"/> from either a class name or a class instance.
        /// </summary>
        /// <returns>Type info instance if object is valid class reference, otherwise <c>null</c>.</returns>
        internal static PhpTypeInfo TypeNameOrObjectToType(Context ctx, PhpValue @object, RuntimeTypeHandle selftype = default(RuntimeTypeHandle), bool autoload = true, bool allowName = true)
        {
            object obj;
            string str;

            if ((obj = (@object.AsObject())) != null)
            {
                return(obj.GetPhpTypeInfo());
            }
            else if ((str = PhpVariable.AsString(@object)) != null)
            {
                return(allowName ? ctx.GetDeclaredType(str, autoload) : null);
            }
            else
            {
                // other @object types are not handled
                return((selftype.Equals(default) || [email protected])
Esempio n. 17
0
        /// <summary>
        /// Resolves type of <paramref name="class"/>.
        /// </summary>
        /// <param name="ctx">Context.</param>
        /// <param name="class">Either string or class instance. Otherwise an exception is thrown.</param>
        /// <returns>Type info. Cannot get <c>null</c>.</returns>
        /// <exception cref="ReflectionException">In case <paramref name="class"/> does not exist or <paramref name="class"/> is not a string or object.</exception>
        public static PhpTypeInfo ResolvePhpTypeInfo(Context ctx, PhpValue @class)
        {
            object instance;

            if (@class.IsString(out var classname))
            {
                return(ctx.GetDeclaredType(classname, true)
                       ?? throw new ReflectionException(string.Format(Resources.Resources.class_does_not_exist, classname)));
            }
            else if ((instance = @class.AsObject()) != null)
            {
                return(instance.GetPhpTypeInfo());
            }
            else
            {
                throw new ReflectionException(string.Format(ErrResources.invalid_argument_type, nameof(@class), "string or object"));
            }
        }
Esempio n. 18
0
 /// <summary>
 /// Constructs the array iterator.
 /// </summary>
 /// <param name="ctx">Runtime context.</param>
 /// <param name="array">The array or object to be iterated on.</param>
 /// <param name="flags">Flags to control the behaviour of the ArrayIterator object. See ArrayIterator::setFlags().</param>
 public virtual void __construct(Context /*!*/ ctx, PhpValue array, int flags = 0)
 {
     if ((_array = array.ArrayOrNull()) != null)
     {
         InitArrayIteratorHelper();  // instantiate now, avoid repetitous checks during iteration
     }
     else if ((_dobj = array.AsObject()) != null)
     {
         //InitObjectIteratorHelper();   // lazily to avoid one additional allocation
     }
     else
     {
         throw new ArgumentException();
         //// throw an PHP.Library.SPL.InvalidArgumentException if anything besides an array or an object is given.
         //Exception.ThrowSplException(
         //    _ctx => new InvalidArgumentException(_ctx, true),
         //    context,
         //    null, 0, null);
     }
 }
Esempio n. 19
0
        internal static PhpTypeInfo ResolvePhpTypeInfo(Context ctx, PhpValue @class)
        {
            object instance;

            var classname = @class.ToStringOrNull();

            if (classname != null)
            {
                return(ctx.GetDeclaredType(classname, true));
            }
            else if ((instance = @class.AsObject()) != null)
            {
                return(instance.GetPhpTypeInfo());
            }
            else
            {
                // argument type exception
            }

            return(null);
        }
Esempio n. 20
0
        static bool TryProcessMethodFromStream(PhpValue value, ProcessMethod @default, ref ProcessMethod processing, bool readable = false)
        {
            if (Operators.IsSet(value))
            {
                var stream = value.AsObject() as PhpStream;
                if (stream != null && (readable ? stream.CanRead : stream.CanWrite))
                {
                    processing = new ProcessMethod(stream);
                }
                else
                {
                    return(false); // failure
                }
            }
            else
            {
                processing = @default;
            }

            return(true);
        }
Esempio n. 21
0
 static object AsKey(PhpValue offset)
 {
     return(offset.AsObject()
            ?? throw (offset.IsNull ? ObjectNullException() : TypeErrorException()));
 }
Esempio n. 22
0
        /// <summary>
        /// Checks whether a dereferenced variable is an instance of class.
        /// </summary>
        /// <param name="variable">The variable.</param>
        /// <returns>Whether <paramref name="variable"/> is <see cref="object"/>.</returns>
        public static bool is_object(PhpValue variable)
        {
            var obj = variable.AsObject();

            return(obj != null && !(obj is __PHP_Incomplete_Class) && !(obj is PhpResource));
        }
Esempio n. 23
0
 /// <summary>
 /// Checks whether an object exists in the storage.
 /// </summary>
 /// <remarks>Alias for <see cref="contains(object)"/>.</remarks>
 public virtual bool offsetExists(PhpValue offset) => contains(offset.AsObject());