public static bool IsX64 { get; } = IntPtr.Size == 8;
+ // NOTE: InvalidAdvance_Large test is constrained to run on Windows and MacOSX because it causes
+ // problems on Linux due to the way deferred memory allocation works. On Linux, the allocation can
+ // succeed even if there is not enough memory but then the test may get killed by the OOM killer at the
+ // time the memory is accessed which triggers the full memory allocation.
+ [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)]
[ConditionalFact(nameof(IsX64))]
[OuterLoop]
public void InvalidAdvance_Large()
// All other UTF-16 characters can be represented by either 1 or 2 UTF-8 bytes.
public const int MaxExpansionFactorWhileTranscoding = 3;
- public const int MaxTokenSize = 1_000_000_000 / MaxExpansionFactorWhileEscaping; // 166_666_666 bytes
- public const int MaxBase46ValueTokenSize = (1_000_000_000 >> 2 * 3) / MaxExpansionFactorWhileEscaping; // 125_000_000 bytes
- public const int MaxCharacterTokenSize = 1_000_000_000 / MaxExpansionFactorWhileEscaping; // 166_666_666 characters
+ public const int MaxEscapedTokenSize = 1_000_000_000; // Max size for already escaped value.
+ public const int MaxUnescapedTokenSize = MaxEscapedTokenSize / MaxExpansionFactorWhileEscaping; // 166_666_666 bytes
+ public const int MaxBase46ValueTokenSize = (MaxEscapedTokenSize >> 2 * 3) / MaxExpansionFactorWhileEscaping; // 125_000_000 bytes
+ public const int MaxCharacterTokenSize = MaxEscapedTokenSize / MaxExpansionFactorWhileEscaping; // 166_666_666 characters
public const int MaximumFormatInt64Length = 20; // 19 + sign (i.e. -9223372036854775808)
public const int MaximumFormatUInt64Length = 20; // i.e. 18446744073709551615
public static void ThrowArgumentException(ReadOnlySpan<byte> propertyName, ReadOnlySpan<byte> value)
{
- if (propertyName.Length > JsonConstants.MaxTokenSize)
+ if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize)
{
ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length));
}
else
{
- Debug.Assert(value.Length > JsonConstants.MaxTokenSize);
+ Debug.Assert(value.Length > JsonConstants.MaxUnescapedTokenSize);
ThrowArgumentException(SR.Format(SR.ValueTooLarge, value.Length));
}
}
public static void ThrowArgumentException(ReadOnlySpan<byte> propertyName, ReadOnlySpan<char> value)
{
- if (propertyName.Length > JsonConstants.MaxTokenSize)
+ if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize)
{
ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length));
}
}
else
{
- Debug.Assert(value.Length > JsonConstants.MaxTokenSize);
+ Debug.Assert(value.Length > JsonConstants.MaxUnescapedTokenSize);
ThrowArgumentException(SR.Format(SR.ValueTooLarge, value.Length));
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateProperty(ReadOnlySpan<byte> propertyName)
{
- if (propertyName.Length > JsonConstants.MaxTokenSize)
+ if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize)
ThrowHelper.ThrowArgumentException_PropertyNameTooLarge(propertyName.Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateValue(ReadOnlySpan<byte> value)
{
- if (value.Length > JsonConstants.MaxTokenSize)
+ if (value.Length > JsonConstants.MaxUnescapedTokenSize)
ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidatePropertyAndValue(ReadOnlySpan<char> propertyName, ReadOnlySpan<byte> value)
{
- if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxTokenSize)
+ if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxUnescapedTokenSize)
ThrowHelper.ThrowArgumentException(propertyName, value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidatePropertyAndValue(ReadOnlySpan<byte> propertyName, ReadOnlySpan<char> value)
{
- if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize)
+ if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize)
ThrowHelper.ThrowArgumentException(propertyName, value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidatePropertyAndValue(ReadOnlySpan<byte> propertyName, ReadOnlySpan<byte> value)
{
- if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxTokenSize)
+ if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize || value.Length > JsonConstants.MaxUnescapedTokenSize)
ThrowHelper.ThrowArgumentException(propertyName, value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidatePropertyAndBytes(ReadOnlySpan<byte> propertyName, ReadOnlySpan<byte> bytes)
{
- if (propertyName.Length > JsonConstants.MaxTokenSize || bytes.Length > JsonConstants.MaxBase46ValueTokenSize)
+ if (propertyName.Length > JsonConstants.MaxUnescapedTokenSize || bytes.Length > JsonConstants.MaxBase46ValueTokenSize)
ThrowHelper.ThrowArgumentException(propertyName, bytes);
}
private void WriteBase64StringHelper(ReadOnlySpan<byte> utf8PropertyName, ReadOnlySpan<byte> bytes)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
JsonWriterHelper.ValidateBytes(bytes);
private void WriteStringHelper(ReadOnlySpan<byte> utf8PropertyName, DateTime value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteStringByOptions(utf8PropertyName, value);
private void WriteStringHelper(ReadOnlySpan<byte> utf8PropertyName, DateTimeOffset value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteStringByOptions(utf8PropertyName, value);
private void WriteNumberHelper(ReadOnlySpan<byte> utf8PropertyName, decimal value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteNumberByOptions(utf8PropertyName, value);
private void WriteNumberHelper(ReadOnlySpan<byte> utf8PropertyName, double value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
JsonWriterHelper.ValidateDouble(value);
private void WriteNumberHelper(ReadOnlySpan<byte> utf8PropertyName, float value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
JsonWriterHelper.ValidateSingle(value);
private void WriteStringHelper(ReadOnlySpan<byte> utf8PropertyName, Guid value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteStringByOptions(utf8PropertyName, value);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ValidatePropertyNameAndDepth(ReadOnlySpan<byte> utf8PropertyName)
{
- if (utf8PropertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth)
+ if (utf8PropertyName.Length > JsonConstants.MaxUnescapedTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth)
ThrowHelper.ThrowInvalidOperationOrArgumentException(utf8PropertyName, _currentDepth);
}
private void WriteLiteralHelper(ReadOnlySpan<byte> utf8PropertyName, ReadOnlySpan<byte> value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteLiteralByOptions(utf8PropertyName, value);
private void WriteLiteralMinimized(ReadOnlySpan<char> escapedPropertyName, ReadOnlySpan<byte> value)
{
- Debug.Assert(value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(value.Length <= JsonConstants.MaxUnescapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - value.Length - 4);
// All ASCII, 2 quotes for property name, and 1 colon => escapedPropertyName.Length + value.Length + 3
private void WriteLiteralMinimized(ReadOnlySpan<byte> escapedPropertyName, ReadOnlySpan<byte> value)
{
- Debug.Assert(value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(value.Length <= JsonConstants.MaxUnescapedTokenSize);
Debug.Assert(escapedPropertyName.Length < int.MaxValue - value.Length - 4);
int minRequired = escapedPropertyName.Length + value.Length + 3; // 2 quotes for property name, and 1 colon
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(value.Length <= JsonConstants.MaxUnescapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - value.Length - 5 - s_newLineLength);
// All ASCII, 2 quotes for property name, 1 colon, and 1 space => escapedPropertyName.Length + value.Length + 4
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(value.Length <= JsonConstants.MaxUnescapedTokenSize);
Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - value.Length - 5 - s_newLineLength);
int minRequired = indent + escapedPropertyName.Length + value.Length + 4; // 2 quotes for property name, 1 colon, and 1 space
private void WriteNumberHelper(ReadOnlySpan<byte> utf8PropertyName, long value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteNumberByOptions(utf8PropertyName, value);
private void WritePropertyNameHelper(ReadOnlySpan<byte> utf8PropertyName)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteStringByOptionsPropertyName(utf8PropertyName);
private void WriteStringMinimizedPropertyName(ReadOnlySpan<char> escapedPropertyName)
{
- Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue - 4) / JsonConstants.MaxExpansionFactorWhileTranscoding);
// All ASCII, 2 quotes for property name, and 1 colon => escapedPropertyName.Length + 3
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue - 5 - indent - s_newLineLength) / JsonConstants.MaxExpansionFactorWhileTranscoding);
// All ASCII, 2 quotes for property name, 1 colon, and 1 space => escapedPropertyName.Length + 4
private void WriteStringMinimizedPropertyName(ReadOnlySpan<byte> escapedPropertyName)
{
- Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < int.MaxValue - 4);
int minRequired = escapedPropertyName.Length + 3; // 2 quotes for property name, and 1 colon
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - 5 - s_newLineLength);
int minRequired = indent + escapedPropertyName.Length + 4; // 2 quotes for property name, 1 colon, and 1 space
private void WriteStringHelper(ReadOnlySpan<byte> utf8PropertyName, ReadOnlySpan<byte> utf8Value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize && utf8Value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize && utf8Value.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteStringByOptions(utf8PropertyName, utf8Value);
private void WriteStringHelperEscapeValue(ReadOnlySpan<byte> utf8PropertyName, ReadOnlySpan<char> value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
JsonWriterHelper.ValidateValue(value);
private void WriteStringHelperEscapeValue(ReadOnlySpan<byte> utf8PropertyName, ReadOnlySpan<byte> utf8Value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
JsonWriterHelper.ValidateValue(utf8Value);
private void WriteStringHelperEscapeProperty(ReadOnlySpan<char> propertyName, ReadOnlySpan<byte> utf8Value)
{
- Debug.Assert(utf8Value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8Value.Length <= JsonConstants.MaxUnescapedTokenSize);
JsonWriterHelper.ValidateProperty(propertyName);
private void WriteStringHelperEscapeProperty(ReadOnlySpan<byte> utf8PropertyName, ReadOnlySpan<byte> utf8Value)
{
- Debug.Assert(utf8Value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8Value.Length <= JsonConstants.MaxUnescapedTokenSize);
JsonWriterHelper.ValidateProperty(utf8PropertyName);
// TODO: https://github.com/dotnet/corefx/issues/36958
private void WriteStringMinimized(ReadOnlySpan<char> escapedPropertyName, ReadOnlySpan<char> escapedValue)
{
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxUnescapedTokenSize);
Debug.Assert(escapedPropertyName.Length < ((int.MaxValue - 6) / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length);
// All ASCII, 2 quotes for property name, 2 quotes for value, and 1 colon => escapedPropertyName.Length + escapedValue.Length + 5
// TODO: https://github.com/dotnet/corefx/issues/36958
private void WriteStringMinimized(ReadOnlySpan<byte> escapedPropertyName, ReadOnlySpan<byte> escapedValue)
{
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < int.MaxValue - escapedValue.Length - 6);
int minRequired = escapedPropertyName.Length + escapedValue.Length + 5; // 2 quotes for property name, 2 quotes for value, and 1 colon
// TODO: https://github.com/dotnet/corefx/issues/36958
private void WriteStringMinimized(ReadOnlySpan<char> escapedPropertyName, ReadOnlySpan<byte> escapedValue)
{
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length - 6);
// All ASCII, 2 quotes for property name, 2 quotes for value, and 1 colon => escapedPropertyName.Length + escapedValue.Length + 5
// TODO: https://github.com/dotnet/corefx/issues/36958
private void WriteStringMinimized(ReadOnlySpan<byte> escapedPropertyName, ReadOnlySpan<char> escapedValue)
{
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length - 6);
// All ASCII, 2 quotes for property name, 2 quotes for value, and 1 colon => escapedPropertyName.Length + escapedValue.Length + 5
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < ((int.MaxValue - 7 - indent - s_newLineLength) / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length);
// All ASCII, 2 quotes for property name, 2 quotes for value, 1 colon, and 1 space => escapedPropertyName.Length + escapedValue.Length + 6
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - escapedValue.Length - 7 - s_newLineLength);
int minRequired = indent + escapedPropertyName.Length + escapedValue.Length + 6; // 2 quotes for property name, 2 quotes for value, 1 colon, and 1 space
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length - 7 - indent - s_newLineLength);
// All ASCII, 2 quotes for property name, 2 quotes for value, 1 colon, and 1 space => escapedPropertyName.Length + escapedValue.Length + 6
int indent = Indentation;
Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
- Debug.Assert(escapedValue.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize);
Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length - 7 - indent - s_newLineLength);
// All ASCII, 2 quotes for property name, 2 quotes for value, 1 colon, and 1 space => escapedPropertyName.Length + escapedValue.Length + 6
private void WriteNumberHelper(ReadOnlySpan<byte> utf8PropertyName, ulong value)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteNumberByOptions(utf8PropertyName, value);
private void WriteStringValueHelper(ReadOnlySpan<byte> utf8Value)
{
- Debug.Assert(utf8Value.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8Value.Length <= JsonConstants.MaxUnescapedTokenSize);
WriteStringByOptions(utf8Value);
private void WriteStartHelper(ReadOnlySpan<byte> utf8PropertyName, byte token)
{
- Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxUnescapedTokenSize);
ValidateDepth();
Assert.False(json.ValueTextEquals(lookup));
}
+ // NOTE: LookupOverflow test is constrained to run on Windows and MacOSX because it causes
+ // problems on Linux due to the way deferred memory allocation works. On Linux, the allocation can
+ // succeed even if there is not enough memory but then the test may get killed by the OOM killer at the
+ // time the memory is accessed which triggers the full memory allocation.
+ [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)]
[ConditionalFact(nameof(IsX64))]
[OuterLoop]
public static void LookupOverflow()
{
public class Utf8JsonWriterTests
{
+ private const int MaxExpansionFactorWhileEscaping = 6;
+ private const int MaxEscapedTokenSize = 1_000_000_000; // Max size for already escaped value.
+ private const int MaxUnescapedTokenSize = MaxEscapedTokenSize / MaxExpansionFactorWhileEscaping; // 166_666_666 bytes
+
public static bool IsX64 { get; } = IntPtr.Size >= 8;
[Theory]
Assert.Throws<InvalidOperationException>(() => jsonUtf8.WriteStartArray(JsonEncodedText.Encode("name")));
}
+ // NOTE: WritingTooLargeProperty test is constrained to run on Windows and MacOSX because it causes
+ // problems on Linux due to the way deferred memory allocation works. On Linux, the allocation can
+ // succeed even if there is not enough memory but then the test may get killed by the OOM killer at the
+ // time the memory is accessed which triggers the full memory allocation.
+ [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)]
[ConditionalTheory(nameof(IsX64))]
[OuterLoop]
[InlineData(true, true)]
try
{
- key = new byte[1_000_000_000];
- keyChars = new char[1_000_000_000];
+ key = new byte[MaxUnescapedTokenSize + 1];
+ keyChars = new char[MaxUnescapedTokenSize + 1];
}
catch (OutOfMemoryException)
{
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteStartArray(key));
}
+ // NOTE: WritingTooLargePropertyStandalone test is constrained to run on Windows and MacOSX because it causes
+ // problems on Linux due to the way deferred memory allocation works. On Linux, the allocation can
+ // succeed even if there is not enough memory but then the test may get killed by the OOM killer at the
+ // time the memory is accessed which triggers the full memory allocation.
+ [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)]
[ConditionalTheory(nameof(IsX64))]
[OuterLoop]
[InlineData(true, true)]
try
{
- key = new byte[1_000_000_000];
- keyChars = new char[1_000_000_000];
+ key = new byte[MaxUnescapedTokenSize + 1];
+ keyChars = new char[MaxUnescapedTokenSize + 1];
}
catch (OutOfMemoryException)
{
}
}
+ // NOTE: WriteLargeKeyOrValue test is constrained to run on Windows and MacOSX because it causes
+ // problems on Linux due to the way deferred memory allocation works. On Linux, the allocation can
+ // succeed even if there is not enough memory but then the test may get killed by the OOM killer at the
+ // time the memory is accessed which triggers the full memory allocation.
+ [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)]
[ConditionalTheory(nameof(IsX64))]
[OuterLoop]
[InlineData(true, true)]
try
{
- key = new byte[1_000_000_001];
- value = new byte[1_000_000_001];
+ key = new byte[MaxUnescapedTokenSize + 1];
+ value = new byte[MaxUnescapedTokenSize + 1];
}
catch (OutOfMemoryException)
{
}
}
+ // NOTE: WriteLargeKeyValue test is constrained to run on Windows and MacOSX because it causes
+ // problems on Linux due to the way deferred memory allocation works. On Linux, the allocation can
+ // succeed even if there is not enough memory but then the test may get killed by the OOM killer at the
+ // time the memory is accessed which triggers the full memory allocation.
+ [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)]
[ConditionalTheory(nameof(IsX64))]
[OuterLoop]
[InlineData(true, true)]
try
{
- key = new byte[1_000_000_001];
- value = new byte[1_000_000_001];
+ key = new byte[MaxUnescapedTokenSize + 1];
+ value = new byte[MaxUnescapedTokenSize + 1];
}
catch (OutOfMemoryException)
{
}
WriteTooLargeHelper(options, key, value);
- WriteTooLargeHelper(options, key.Slice(0, 1_000_000_000), value);
- WriteTooLargeHelper(options, key, value.Slice(0, 1_000_000_000));
+ WriteTooLargeHelper(options, key.Slice(0, MaxUnescapedTokenSize), value);
+ WriteTooLargeHelper(options, key, value.Slice(0, MaxUnescapedTokenSize));
WriteTooLargeHelper(options, key.Slice(0, 10_000_000 / 3), value.Slice(0, 10_000_000 / 3), noThrow: true);
}
+ // NOTE: WriteLargeKeyEscapedValue test is constrained to run on Windows and MacOSX because it causes
+ // problems on Linux due to the way deferred memory allocation works. On Linux, the allocation can
+ // succeed even if there is not enough memory but then the test may get killed by the OOM killer at the
+ // time the memory is accessed which triggers the full memory allocation.
+ [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)]
+ [ConditionalTheory(nameof(IsX64))]
+ [OuterLoop]
+ [InlineData(true, true)]
+ [InlineData(true, false)]
+ [InlineData(false, true)]
+ [InlineData(false, false)]
+ public void WriteLargeKeyEscapedValue(bool formatted, bool skipValidation)
+ {
+ var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
+
+ Span<byte> key;
+ Span<byte> value;
+
+ try
+ {
+ // Since the byte values are 0 they will be escaped and size > MaxUnescapedTokenSize but < MaxEscapedTokenSize.
+ key = new byte[MaxUnescapedTokenSize / 2];
+ value = new byte[MaxUnescapedTokenSize / 2];
+ }
+ catch (OutOfMemoryException)
+ {
+ return;
+ }
+
+ WriteTooLargeHelper(options, key, value, noThrow: true);
+ }
+
[Theory]
[MemberData(nameof(JsonDateTimeTestData.DateTimeFractionTrimBaseTests), MemberType = typeof(JsonDateTimeTestData))]
[MemberData(nameof(JsonDateTimeTestData.DateTimeFractionTrimUtcOffsetTests), MemberType = typeof(JsonDateTimeTestData))]