예제 #1
0
 /// <summary>
 /// Deserializes a <see cref="StackItem"/> from byte array.
 /// </summary>
 /// <param name="data">The byte array to parse.</param>
 /// <param name="limits">The limits for the deserialization.</param>
 /// <param name="referenceCounter">The <see cref="ReferenceCounter"/> used by the <see cref="StackItem"/>.</param>
 /// <returns>The deserialized <see cref="StackItem"/>.</returns>
 public static StackItem Deserialize(byte[] data, ExecutionEngineLimits limits, ReferenceCounter referenceCounter = null)
 {
     using MemoryStream ms     = new(data, false);
     using BinaryReader reader = new(ms, Utility.StrictUTF8, true);
     return(Deserialize(reader, limits with {
         MaxItemSize = (uint) data.Length
     }, referenceCounter));
예제 #2
0
        /// <summary>
        /// Create a new structure with the same content as this structure. All nested structures will be copied by value.
        /// </summary>
        /// <param name="limits">Execution engine limits</param>
        /// <returns>The copied structure.</returns>
        public Struct Clone(ExecutionEngineLimits limits)
        {
            int            count  = (int)(limits.MaxStackSize - 1);
            Struct         result = new(ReferenceCounter);
            Queue <Struct> queue  = new();

            queue.Enqueue(result);
            queue.Enqueue(this);
            while (queue.Count > 0)
            {
                Struct a = queue.Dequeue();
                Struct b = queue.Dequeue();
                foreach (StackItem item in b)
                {
                    count--;
                    if (count < 0)
                    {
                        throw new InvalidOperationException("Beyond clone limits!");
                    }
                    if (item is Struct sb)
                    {
                        Struct sa = new(ReferenceCounter);
                        a.Add(sa);
                        queue.Enqueue(sa);
                        queue.Enqueue(sb);
                    }
                    else
                    {
                        a.Add(item);
                    }
                }
            }
            return(result);
        }
예제 #3
0
        /// <summary>
        /// Deserializes a <see cref="StackItem"/> from byte array.
        /// </summary>
        /// <param name="data">The byte array to parse.</param>
        /// <param name="limits">The limits for the deserialization.</param>
        /// <param name="referenceCounter">The <see cref="ReferenceCounter"/> used by the <see cref="StackItem"/>.</param>
        /// <returns>The deserialized <see cref="StackItem"/>.</returns>
        public static StackItem Deserialize(ReadOnlyMemory <byte> data, ExecutionEngineLimits limits, ReferenceCounter referenceCounter = null)
        {
            MemoryReader reader = new(data);

            return(Deserialize(ref reader, limits with {
                MaxItemSize = (uint)data.Length
            }, referenceCounter));
예제 #4
0
        public override bool Equals(StackItem?other, ExecutionEngineLimits limits)
        {
            if (other is not Struct s)
            {
                return(false);
            }
            Stack <StackItem> stack1 = new();
            Stack <StackItem> stack2 = new();

            stack1.Push(this);
            stack2.Push(s);
            uint count = limits.MaxStackSize;

            while (stack1.Count > 0)
            {
                if (count-- == 0)
                {
                    throw new InvalidOperationException("Too many struct items to compare.");
                }
                StackItem a = stack1.Pop();
                StackItem b = stack2.Pop();
                if (a is Struct sa)
                {
                    if (ReferenceEquals(a, b))
                    {
                        continue;
                    }
                    if (b is not Struct sb)
                    {
                        return(false);
                    }
                    if (sa.Count != sb.Count)
                    {
                        return(false);
                    }
                    foreach (StackItem item in sa)
                    {
                        stack1.Push(item);
                    }
                    foreach (StackItem item in sb)
                    {
                        stack2.Push(item);
                    }
                }
                else
                {
                    if (!a.Equals(b))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
예제 #5
0
        internal override bool Equals(StackItem?other, ExecutionEngineLimits limits)
        {
            uint maxComparableSize = limits.MaxComparableSize;

            return(Equals(other, ref maxComparableSize));
        }
예제 #6
0
        /// <summary>
        /// Deserializes a <see cref="StackItem"/> from <see cref="JObject"/>.
        /// </summary>
        /// <param name="json">The <see cref="JObject"/> to deserialize.</param>
        /// <param name="limits">The limits for the deserialization.</param>
        /// <param name="referenceCounter">The <see cref="ReferenceCounter"/> used by the <see cref="StackItem"/>.</param>
        /// <returns>The deserialized <see cref="StackItem"/>.</returns>
        public static StackItem Deserialize(JObject json, ExecutionEngineLimits limits, ReferenceCounter referenceCounter = null)
        {
            uint maxStackSize = limits.MaxStackSize;

            return(Deserialize(json, ref maxStackSize, referenceCounter));
        }
예제 #7
0
 public virtual bool Equals(StackItem?other, ExecutionEngineLimits limits)
 {
     return(Equals(other));
 }
예제 #8
0
        internal override bool Equals(StackItem?other, ExecutionEngineLimits limits)
        {
            if (other is not Struct s)
            {
                return(false);
            }
            Stack <StackItem> stack1 = new();
            Stack <StackItem> stack2 = new();

            stack1.Push(this);
            stack2.Push(s);
            uint count             = limits.MaxStackSize;
            uint maxComparableSize = limits.MaxComparableSize;

            while (stack1.Count > 0)
            {
                if (count-- == 0)
                {
                    throw new InvalidOperationException("Too many struct items to compare.");
                }
                StackItem a = stack1.Pop();
                StackItem b = stack2.Pop();
                if (a is ByteString byteString)
                {
                    if (!byteString.Equals(b, ref maxComparableSize))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (maxComparableSize == 0)
                    {
                        throw new InvalidOperationException("The operand exceeds the maximum comparable size.");
                    }
                    maxComparableSize -= 1;
                    if (a is Struct sa)
                    {
                        if (ReferenceEquals(a, b))
                        {
                            continue;
                        }
                        if (b is not Struct sb)
                        {
                            return(false);
                        }
                        if (sa.Count != sb.Count)
                        {
                            return(false);
                        }
                        foreach (StackItem item in sa)
                        {
                            stack1.Push(item);
                        }
                        foreach (StackItem item in sb)
                        {
                            stack2.Push(item);
                        }
                    }
                    else
                    {
                        if (!a.Equals(b))
                        {
                            return(false);
                        }
                    }
                }
            }
            return(true);
        }