Ejemplo n.º 1
0
        /// <summary>
        /// Constructs a new <see cref="JsonReaderState"/> instance.
        /// </summary>
        /// <param name="options">Defines the customized behavior of the <see cref="Utf8JsonReader"/>
        /// that is different from the JSON RFC (for example how to handle comments or maximum depth allowed when reading).
        /// By default, the <see cref="Utf8JsonReader"/> follows the JSON RFC strictly (i.e. comments within the JSON are invalid) and reads up to a maximum depth of 64.</param>
        /// <exception cref="ArgumentException">
        /// Thrown when the max depth is set to a non-positive value (&lt; 0)
        /// </exception>
        /// <remarks>
        /// An instance of this state must be passed to the <see cref="Utf8JsonReader"/> ctor with the JSON data.
        /// Unlike the <see cref="Utf8JsonReader"/>, which is a ref struct, the state can survive
        /// across async/await boundaries and hence this type is required to provide support for reading
        /// in more data asynchronously before continuing with a new instance of the <see cref="Utf8JsonReader"/>.
        /// </remarks>
        public JsonReaderState(JsonReaderOptions options = default)
        {
            _lineNumber                 = default;
            _bytePositionInLine         = default;
            _bytesConsumed              = default;
            _inObject                   = default;
            _isNotPrimitive             = default;
            _numberFormat               = default;
            _stringHasEscaping          = default;
            _trailingCommaBeforeComment = default;
            _tokenType                  = default;
            _previousTokenType          = default;
            _readerOptions              = options;

            // Only allocate if the user reads a JSON payload beyond the depth that the _allocationFreeContainer can handle.
            // This way we avoid allocations in the common, default cases, and allocate lazily.
            _bitStack = default;

            _sequencePosition = default;
        }
Ejemplo n.º 2
0
        public override object?Deserialize(ReadOnlySequence <byte> input, Type type)
        {
            if (this.TraceEnabled)
            {
                this.TraceDeserialize(input, type);
            }

            var readerOptions = new JsonReaderOptions();

            if (this.Options != null)
            {
                readerOptions.AllowTrailingCommas = this.Options.AllowTrailingCommas;
                readerOptions.CommentHandling     = this.Options.ReadCommentHandling;
                readerOptions.MaxDepth            = this.Options.MaxDepth;
            }
            ;

            var reader = new Utf8JsonReader(input, readerOptions);

            return(JsonSerializer.Deserialize(ref reader, type, this.Options));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Constructs a new <see cref="JsonReaderState"/> instance.
        /// </summary>
        /// <param name="maxDepth">Sets the maximum depth allowed when reading JSON, with the default set as 64.
        /// Reading past this depth will throw a <exception cref="JsonReaderException"/>.</param>
        /// <param name="options">Defines the customized behavior of the <see cref="Utf8JsonReader"/>
        /// that is different from the JSON RFC (for example how to handle comments).
        /// By default, the <see cref="Utf8JsonReader"/> follows the JSON RFC strictly (i.e. comments within the JSON are invalid).</param>
        /// <exception cref="ArgumentException">
        /// Thrown when the max depth is set to a non-positive value (&lt;= 0)
        /// </exception>
        /// <remarks>
        /// An instance of this state must be passed to the <see cref="Utf8JsonReader"/> ctor with the JSON data.
        /// Unlike the <see cref="Utf8JsonReader"/>, which is a ref struct, the state can survive
        /// across async/await boundaries and hence this type is required to provide support for reading
        /// in more data asynchronously before continuing with a new instance of the <see cref="Utf8JsonReader"/>.
        /// </remarks>
        public JsonReaderState(int maxDepth = DefaultMaxDepth, JsonReaderOptions options = default)
        {
            if (maxDepth <= 0)
            {
                throw ThrowHelper.GetArgumentException_MaxDepthMustBePositive();
            }

            _lineNumber         = default;
            _bytePositionInLine = default;
            _bytesConsumed      = default;
            _maxDepth           = maxDepth;
            _inObject           = default;
            _isNotPrimitive     = default;
            _tokenType          = default;
            _previousTokenType  = default;
            _readerOptions      = options;

            // Only allocate if the user reads a JSON payload beyond the depth that the _allocationFreeContainer can handle.
            // This way we avoid allocations in the common, default cases, and allocate lazily.
            _bitStack = default;
        }
Ejemplo n.º 4
0
        public static void ReaderOptionsWinMaxDepth()
        {
            byte[] utf8 = Encoding.UTF8.GetBytes("[[]]");

            var readerOptions = new JsonReaderOptions
            {
                MaxDepth = 1,
            };

            var serializerOptions = new JsonSerializerOptions
            {
                MaxDepth = 5,
            };

            var state = new JsonReaderState(readerOptions);

            Assert.Throws <JsonException>(() =>
            {
                var reader = new Utf8JsonReader(utf8, isFinalBlock: false, state);
                JsonSerializer.Deserialize(ref reader, typeof(int), serializerOptions);
            });
        }
        private IDictionary <string, string> ParseStream(Stream input)
        {
            _data.Clear();

            var jsonReaderOptions = new JsonReaderOptions
            {
                CommentHandling     = JsonCommentHandling.Skip,
                AllowTrailingCommas = true,
            };

            using (var reader = new StreamReader(input))
                using (JsonDocument doc = JsonDocument.Parse(reader.ReadToEnd(), jsonReaderOptions))
                {
                    if (doc.RootElement.Type != JsonValueType.Object)
                    {
                        throw new FormatException(Resources.FormatError_UnsupportedJSONToken(doc.RootElement.Type));
                    }
                    VisitElement(doc.RootElement);
                }

            return(_data);
        }
Ejemplo n.º 6
0
        public static void ReaderOptionsWinTrailingCommas()
        {
            byte[] utf8 = Encoding.UTF8.GetBytes("[1, 2, 3,]");

            var serializerOptions = new JsonSerializerOptions
            {
                AllowTrailingCommas = true,
            };

            Assert.Throws <JsonException>(() =>
            {
                var reader = new Utf8JsonReader(utf8);
                JsonSerializer.Deserialize(ref reader, typeof(int[]), serializerOptions);
            });

            Assert.Throws <JsonException>(() =>
            {
                var reader = new Utf8JsonReader(utf8, isFinalBlock: false, state: default);
                JsonSerializer.Deserialize(ref reader, typeof(int[]), serializerOptions);
            });

            var readerOptions = new JsonReaderOptions {
                AllowTrailingCommas = true
            };

            {
                var   reader = new Utf8JsonReader(utf8, readerOptions);
                int[] result = JsonSerializer.Deserialize <int[]>(ref reader);
                Assert.Equal(3, result.Length);
            }

            {
                var   reader = new Utf8JsonReader(utf8, readerOptions);
                int[] result = JsonSerializer.Deserialize <int[]>(ref reader, serializerOptions);
                Assert.Equal(3, result.Length);
            }
        }
Ejemplo n.º 7
0
        public static void WriteIncredibleDepth()
        {
            const int         TargetDepth = 500;
            JsonReaderOptions optionsCopy = s_readerOptions;

            optionsCopy.MaxDepth = TargetDepth + 1;
            const int SpacesPre   = 12;
            const int SpacesSplit = 85;
            const int SpacesPost  = 4;

            byte[] jsonIn = new byte[SpacesPre + TargetDepth + SpacesSplit + TargetDepth + SpacesPost];
            jsonIn.AsSpan(0, SpacesPre).Fill((byte)' ');
            Span <byte> openBrackets = jsonIn.AsSpan(SpacesPre, TargetDepth);

            openBrackets.Fill((byte)'[');
            jsonIn.AsSpan(SpacesPre + TargetDepth, SpacesSplit).Fill((byte)' ');
            Span <byte> closeBrackets = jsonIn.AsSpan(SpacesPre + TargetDepth + SpacesSplit, TargetDepth);

            closeBrackets.Fill((byte)']');
            jsonIn.AsSpan(SpacesPre + TargetDepth + SpacesSplit + TargetDepth).Fill((byte)' ');

            var buffer = new ArrayBufferWriter <byte>(jsonIn.Length);

            using (JsonDocument doc = JsonDocument.Parse(jsonIn, optionsCopy))
            {
                var writer = new Utf8JsonWriter(buffer);
                doc.RootElement.WriteAsValue(writer);
                writer.Flush();

                ReadOnlySpan <byte> formatted = buffer.WrittenSpan;

                Assert.Equal(TargetDepth + TargetDepth, formatted.Length);
                Assert.True(formatted.Slice(0, TargetDepth).SequenceEqual(openBrackets), "OpenBrackets match");
                Assert.True(formatted.Slice(TargetDepth).SequenceEqual(closeBrackets), "CloseBrackets match");
            }
        }
Ejemplo n.º 8
0
        public void Read_ObjectWithComments_ShouldMatch(JsonCommentHandling commentHandling)
        {
            const string json = @"/* Comment */{ /* Comment */
""a"":1,
// Comment
""b"": // Comment
    2,
/* Comment */
""c"": /* Comment */ 3,
""d"": [ // Comment
4/* Comment */,/* Comment */ 5 /* Comment */ ]/* Comment */
/* Comment */}";

            var jsonReaderOptions = new JsonReaderOptions
            {
                CommentHandling = commentHandling,
            };
            var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json).AsSpan(), jsonReaderOptions);

            reader.Read();

            var converter = new ObjectConverter();
            var actual    = converter.Read(ref reader, typeof(object), new JsonSerializerOptions());

            var expected = new Dictionary <string, object>
            {
                ["a"] = 1L,
                ["b"] = 2L,
                ["c"] = 3L,
                ["d"] = new List <object> {
                    4L, 5L
                },
            };

            JsonDeepEqualAssert.Equal(expected, actual);
        }
Ejemplo n.º 9
0
                public static PhpValue Deserialize(ReadOnlySpan <byte> utf8bytes, JsonReaderOptions options, JsonDecodeOptions phpoptions)
                {
                    var reader = new Utf8JsonReader(utf8bytes, options);

                    return(ReadValue(ref reader, phpoptions));
                }
Ejemplo n.º 10
0
                /// <summary>
                /// Deserializes the value, sets json_last_error or throws <see cref="JsonException"/> eventually.
                /// </summary>
                public static PhpValue DeserializeWithError(Context ctx, ReadOnlySpan <byte> utf8bytes, JsonReaderOptions options, JsonDecodeOptions phpoptions)
                {
                    try
                    {
                        var value = Deserialize(utf8bytes, options, phpoptions);

                        SetLastJsonError(ctx, JSON_ERROR_NONE);

                        return(value);
                    }
                    catch (JsonException jsonex)
                    {
                        if ((phpoptions & JsonDecodeOptions.JSON_THROW_ON_ERROR) == 0)
                        {
                            SetLastJsonError(ctx, jsonex.getCode());
                            return(PhpValue.Null);
                        }
                        else
                        {
                            throw;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        // internal error,
                        // treat as syntax error

                        if ((phpoptions & JsonDecodeOptions.JSON_THROW_ON_ERROR) == 0)
                        {
                            SetLastJsonError(ctx, JSON_ERROR_SYNTAX);
                            return(PhpValue.Null);
                        }
                        else
                        {
                            throw new JsonException(ex.Message, JSON_ERROR_SYNTAX, ex as Throwable);
                        }
                    }
                }
        private static LocalizationCatalog?ReadLocalizationCatalog(Stream?localizationStream, JsonReaderOptions readerOptions)
        {
            if (localizationStream == null)
            {
                return(null);
            }

            var localizationReader = new Utf8JsonStreamReader(localizationStream, readerOptions);

            return(ReadLocalizationCatalog(ref localizationReader));
        }
 public static Utf8StreamingJsonReader From(ReadOnlySequence <byte> buffer, JsonReaderOptions options, out Utf8JsonReader jsonReader) => From(new BufferReader <byte>(buffer), true, options, out jsonReader);
Ejemplo n.º 13
0
        public static byte[] JsonLabSequenceReturnBytesHelper(byte[] data, out int length, JsonReaderOptions options = JsonReaderOptions.Default)
        {
            ReadOnlySequence <byte> sequence = CreateSegments(data);
            var reader = new Utf8JsonReader(sequence)
            {
                Options = options
            };

            byte[] result = JsonLabReaderLoop(data.Length, out length, ref reader);
            reader.Dispose();

            // TODO: Should we reset the value and valuetype once we are done?
            //Assert.True(reader.Value.IsEmpty);
            //Assert.Equal(JsonValueType.Unknown, reader.ValueType);
            return(result);
        }
Ejemplo n.º 14
0
        public static byte[] HeapableJsonLabReturnBytesHelper(byte[] data, out int length, JsonReaderOptions options = JsonReaderOptions.Default)
        {
            var json = new Utf8Json()
            {
                Options = options
            };

            Utf8Json.Reader reader = json.GetReader(data);
            return(JsonLabReaderLoop(data.Length, out length, ref reader));
        }
        private static Utf8StreamingJsonReader From(IBufferReader <byte> reader, bool dispose, JsonReaderOptions options, out Utf8JsonReader jsonReader)
        {
            var Reader = new Utf8StreamingJsonReader(reader, dispose);

            jsonReader = Reader.GetInitialReader(options);

            return(Reader);
        }
 public static Utf8StreamingJsonReader From(IBufferReader <byte> reader, JsonReaderOptions options, out Utf8JsonReader jsonReader) => From(reader, false, options, out jsonReader);
        public async Task <(bool success, bool noValue, object model, Exception exception)> ReadAsync(FromBodyPropertyInputFormatterContext context, Func <Func <Stream, JsonSerializerOptions, Task>, Task> readRequestBody, Encoding encoding)
        {
            if (!string.Equals(_actionId, context.ActionId, StringComparison.Ordinal))
            {
                throw new InvalidOperationException("Invalid action '" + context.ActionId + "', initialize for action '" + _actionId + "'.");
            }

            if (!HasReadRequestBody)
            {
                HasReadRequestBody = true;
                await readRequestBody(async (s, options) => {
                    _options          = options;
                    int bufferSize    = 0x4096;
                    var propertyData  = new Dictionary <string, List <byte[]> >(StringComparer.Ordinal);
                    var readerOptions = new JsonReaderOptions {
                        AllowTrailingCommas = options.AllowTrailingCommas,
                        CommentHandling     = options.ReadCommentHandling,
                        MaxDepth            = options.MaxDepth
                    };
                    var readerState      = new JsonReaderState(readerOptions);
                    var buffer           = ArrayPool <byte> .Shared.Rent(bufferSize);
                    Memory <byte> memory = buffer.AsMemory(0, bufferSize);
                    int length;
                    int offset             = 0;
                    string currentProperty = null;
                    int depth = 0;
                    DataBlockMode blockMode = DataBlockMode.Start;
                    bool handled            = false;
                    bool finalBlock         = false;
                    int consumed            = 0;
                    try {
                        length     = await s.ReadAsync(memory);
                        finalBlock = length == 0;
                        do
                        {
                            (handled, consumed) = HandleDataBlock(context, ref blockMode, ref depth, ref readerState, memory.Span.Slice(offset, length), finalBlock, ref currentProperty, propertyData);
                            offset += consumed;
                            if (!handled)
                            {
                                int bytesInBuffer = length - offset;
                                if (bytesInBuffer == 0)
                                {
                                    // read more data
                                    length     = await s.ReadAsync(memory);
                                    finalBlock = length == 0;
                                    offset     = 0;
                                }
                                else if ((uint)bytesInBuffer > ((uint)bufferSize / 2))
                                {
                                    // expand buffer
                                    bufferSize  = (bufferSize < (int.MaxValue / 2)) ? bufferSize * 2 : int.MaxValue;
                                    var buffer2 = ArrayPool <byte> .Shared.Rent(bufferSize);

                                    // copy the unprocessed data
                                    Buffer.BlockCopy(buffer, offset, buffer2, 0, bytesInBuffer);

                                    // return previous buffer
                                    ArrayPool <byte> .Shared.Return(buffer);
                                    buffer = buffer2;
                                    memory = buffer.AsMemory(0, bufferSize);

                                    // read more data
                                    length     = await s.ReadAsync(memory.Slice(bytesInBuffer));
                                    finalBlock = length == 0;
                                    length    += bytesInBuffer;
                                    offset     = 0;
                                }
                                else
                                {
                                    Buffer.BlockCopy(buffer, offset, buffer, 0, bytesInBuffer);

                                    // read more data
                                    length     = await s.ReadAsync(memory.Slice(bytesInBuffer));
                                    finalBlock = length == 0;
                                    length    += bytesInBuffer;
                                    offset     = 0;
                                }
                            }
                        }while (!handled);
                    }
                    finally {
                        ArrayPool <byte> .Shared.Return(buffer);
                    }

                    foreach ((var key, var value) in propertyData)
                    {
                        _values.Add(key, value.SelectMany(z => z).ToArray());
                    }
                });
            }

            if (!_keys.TryGetValue(context.FieldName, out var propertyType))
            {
                throw new InvalidOperationException("Unknown property '" + context.FieldName + "' requested.");
            }
            else if (_values.TryGetValue(context.FieldName, out var propertyData))
            {
                try {
                    var v = JsonSerializer.Deserialize(propertyData, propertyType, _options);
                    return(true, false, v, null);
                }
                catch (Exception ex) {
                    return(false, false, null, ex);
                }
            }

            return(true, true, null, null);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Configures the <see cref="JsonReaderOptions"/> to use.
        /// </summary>
        /// <param name="config">The <see cref="SerializationExtensions{T}"/> instance.</param>
        /// <param name="options">The <see cref="JsonReaderOptions"/> to use.</param>
        public static void ReaderOptions(this SerializationExtensions <SystemJsonSerializer> config, JsonReaderOptions options)
        {
            Guard.AgainstNull(config, nameof(config));
            Guard.AgainstNull(options, nameof(options));
            var settings = config.GetSettings();

            settings.Set(options);
        }