예제 #1
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));
            }
        }
예제 #2
0
        public virtual void __unserialize(PhpArray array)
        {
            var flattenedStorage = array.TryGetValue(0, out var storageVal) && storageVal.IsPhpArray(out var storageArray)
                ? storageArray : throw new InvalidDataException();

            var e = flattenedStorage.GetFastEnumerator();

            while (e.MoveNext())
            {
                var key = e.CurrentValue.IsObject ? e.CurrentValue.Object : throw new InvalidDataException();

                if (!e.MoveNext())
                {
                    throw new InvalidDataException();
                }
                var val = e.CurrentValue;

                Keys.AttachImpl(storage, key, val);
            }

            __peach__runtimeFields = array.TryGetValue(1, out var propsVal) && propsVal.IsPhpArray(out var propsArray)
                ? propsArray : throw new InvalidDataException();
        }
예제 #3
0
 /// <summary>
 /// Adds an object inside the storage, and optionally associate it to some data.
 /// </summary>
 public virtual void attach(object @object, PhpValue data = default(PhpValue)) => Keys.AttachImpl(storage, @object, data);
예제 #4
0
        /// <summary>
        /// Unserializes storage entries and attach them to the current storage.
        /// </summary>
        public virtual void unserialize(PhpString serialized)
        {
            // x:{count_int};{item0},{value0};...;m:{members_array}
            if (serialized.Length < 12)
            {
                throw new ArgumentException(nameof(serialized));                         // quick check
            }
            var stream = new MemoryStream(serialized.ToBytes(_ctx));

            try
            {
                PhpValue tmp;
                var      reader = new PhpSerialization.PhpSerializer.ObjectReader(_ctx, stream, default(RuntimeTypeHandle));

                // x:
                if (stream.ReadByte() != 'x' || stream.ReadByte() != ':')
                {
                    throw new InvalidDataException();
                }
                // i:{count};
                tmp = reader.Deserialize();
                if (tmp.TypeCode != PhpTypeCode.Long)
                {
                    throw new InvalidDataException();
                }
                var count = tmp.ToLong();
                if (count < 0)
                {
                    throw new InvalidDataException(nameof(count));
                }

                stream.Seek(-1, SeekOrigin.Current);    // back to `;`

                // {item},{value}
                while (count-- > 0)
                {
                    // ;obj
                    if (stream.ReadByte() != ';')
                    {
                        throw new InvalidDataException();
                    }
                    var obj = reader.Deserialize();
                    // ,data
                    PhpValue data;
                    if (stream.ReadByte() == ',')
                    {
                        data = reader.Deserialize();
                    }
                    else
                    {
                        // backward compatibility with data created with old PHP SplObjectStorage
                        data = PhpValue.Void;
                        stream.Seek(-1, SeekOrigin.Current);    // back to `;`
                    }

                    //
                    Keys.AttachImpl(storage, obj.AsObject(), data);
                }

                // ;
                if (stream.ReadByte() != ';')
                {
                    throw new InvalidDataException();
                }

                // m:{array}
                if (stream.ReadByte() != 'm' || stream.ReadByte() != ':')
                {
                    throw new InvalidDataException();
                }

                tmp = reader.Deserialize();
                if (tmp.IsArray)
                {
                    var arr = tmp.AsArray();
                    if (arr != null && arr.Count != 0)  // do not leak empty arrays
                    {
                        __peach__runtimeFields = arr;
                    }
                }
                else
                {
                    throw new InvalidDataException();
                }
            }
            catch (Exception e)
            {
                PhpException.Throw(PhpError.Notice,
                                   Resources.LibResources.deserialization_failed, e.Message, stream.Position.ToString(), stream.Length.ToString());
            }
        }