Navigation Menu

Skip to content
This repository has been archived by the owner on Nov 25, 2019. It is now read-only.

Commit

Permalink
Lower MaxDepth quota
Browse files Browse the repository at this point in the history
  • Loading branch information
youssefm committed Mar 28, 2012
1 parent 1aa4404 commit 5c43933
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 18 deletions.
Expand Up @@ -254,8 +254,19 @@ public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpC
{
jsonSerializer.Error += (sender, e) =>
{
formatterLogger.LogError(e.ErrorContext.Path, e.ErrorContext.Error.Message);
e.ErrorContext.Handled = true;
Exception exception = e.ErrorContext.Error;
// reader quota exceptions are fatal and cannot be recovered from
// we need to shortcircuit any further deserialization
if (exception is JsonReaderQuotaException)
{
e.ErrorContext.Handled = false;
}
else
{
formatterLogger.LogError(e.ErrorContext.Path, exception.Message);
e.ErrorContext.Handled = true;
}
};
}
return jsonSerializer.Deserialize(jsonTextReader, type);
Expand Down
@@ -0,0 +1,32 @@
using System.Runtime.Serialization;
using Newtonsoft.Json;

namespace System.Net.Http.Formatting
{
/// <summary>
/// Exception type to indicate that json reader quotas have been exceeded.
/// </summary>
[Serializable]
internal class JsonReaderQuotaException : JsonReaderException
{
public JsonReaderQuotaException()
: base()
{
}

public JsonReaderQuotaException(string message)
: base(message)
{
}

protected JsonReaderQuotaException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}

public JsonReaderQuotaException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}
Expand Up @@ -29,9 +29,9 @@ public override object Value

public override bool Read()
{
if (this.Depth > _maxDepth)
if (Depth > _maxDepth)
{
throw new JsonReaderException(RS.Format(Properties.Resources.JsonTooDeep, _maxDepth));
throw new JsonReaderQuotaException(RS.Format(Properties.Resources.JsonTooDeep, _maxDepth));
}
return base.Read();
}
Expand Down
9 changes: 2 additions & 7 deletions src/System.Net.Http.Formatting/FormattingUtilities.cs
Expand Up @@ -15,9 +15,9 @@ namespace System.Net.Http
internal static class FormattingUtilities
{
/// <summary>
/// The default max depth for our formatter is 1K
/// The default max depth for our formatter is 256
/// </summary>
public const int DefaultMaxDepth = 1024;
public const int DefaultMaxDepth = 256;

/// <summary>
/// The default min depth for our formatter is 1
Expand All @@ -34,11 +34,6 @@ internal static class FormattingUtilities
/// </summary>
public const string HttpRequestedWithHeaderValue = @"xmlhttprequest";

/// <summary>
/// JSON literal for 'null'
/// </summary>
public const string JsonNullLiteral = "null";

/// <summary>
/// HTTP Host header field name
/// </summary>
Expand Down
Expand Up @@ -85,6 +85,7 @@
<Link>Properties\TransparentCommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="CloneableExtensions.cs" />
<Compile Include="Formatting\JsonReaderQuotaException.cs" />
<Compile Include="Formatting\StringWithQualityHeaderValueComparer.cs" />
<Compile Include="Formatting\FormDataCollection.cs" />
<Compile Include="Formatting\ContentNegotiationResult.cs" />
Expand Down
Expand Up @@ -200,7 +200,7 @@ public void DeserializingDeepArraysThrows()
}
string json = sb.ToString();

Assert.Throws(typeof(JsonReaderException), () => Deserialize(json, typeof(object)));
Assert.Throws(typeof(JsonReaderQuotaException), () => Deserialize(json, typeof(object)));
}

[Theory]
Expand Down
@@ -1,10 +1,10 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Reflection;
using System.Text;
using Microsoft.TestCommon;
using Moq;
using Xunit;
using Xunit.Extensions;
using System.Reflection;

namespace System.Net.Http.Formatting
{
Expand Down Expand Up @@ -57,6 +57,30 @@ public void ModelErrorsPopulatedWithValidationErrors(string json, Type type, int
Assert.DoesNotThrow(() => JsonNetSerializationTest.Deserialize(json, type, formatter, mockLogger.Object));
Assert.Equal(expectedErrors, errors);
}

[Fact]
public void HittingMaxDepthRaisesOnlyOneValidationError()
{
// Arrange
JsonMediaTypeFormatter formatter = new JsonMediaTypeFormatter();
int errors = 0;
Mock<IFormatterLogger> mockLogger = new Mock<IFormatterLogger>();
mockLogger.Setup(mock => mock.LogError(It.IsAny<string>(), It.IsAny<string>())).Callback(() => errors++);

StringBuilder sb = new StringBuilder("{'A':null}");
for (int i = 0; i < 5000; i++)
{
sb.Insert(0, "{'A':");
sb.Append('}');
}
string json = sb.ToString();

// Act
Assert.DoesNotThrow(() => JsonNetSerializationTest.Deserialize(json, typeof(Nest), formatter, mockLogger.Object));

// Assert
Assert.Equal(1, errors);
}
}

// this IRMS treats all member names that start with "Required" as required
Expand Down Expand Up @@ -89,4 +113,9 @@ public string Throws
}
}
}

public class Nest
{
public Nest A { get; set; }
}
}
Expand Up @@ -74,7 +74,7 @@ public void MaxDepth_RoundTrips()
Assert.Reflection.IntegerProperty(
new DataContractJsonMediaTypeFormatter(),
c => c.MaxDepth,
expectedDefaultValue: 1024,
expectedDefaultValue: 256,
minLegalValue: 1,
illegalLowerValue: 0,
maxLegalValue: null,
Expand Down
Expand Up @@ -62,7 +62,7 @@ public void MaxDepthReturnsCorrectValue()
Assert.Reflection.IntegerProperty(
new FormUrlEncodedMediaTypeFormatter(),
f => f.MaxDepth,
expectedDefaultValue: 1024,
expectedDefaultValue: 256,
minLegalValue: 1,
illegalLowerValue: 0,
maxLegalValue: null,
Expand Down
Expand Up @@ -82,7 +82,7 @@ public void MaxDepth_RoundTrips()
Assert.Reflection.IntegerProperty(
new JsonMediaTypeFormatter(),
c => c.MaxDepth,
expectedDefaultValue: 1024,
expectedDefaultValue: 256,
minLegalValue: 1,
illegalLowerValue: 0,
maxLegalValue: null,
Expand Down
Expand Up @@ -50,7 +50,7 @@ public void MaxDepthReturnsCorrectValue()
Assert.Reflection.IntegerProperty(
new XmlMediaTypeFormatter(),
f => f.MaxDepth,
expectedDefaultValue: 1024,
expectedDefaultValue: 256,
minLegalValue: 1,
illegalLowerValue: 0,
maxLegalValue: null,
Expand Down

0 comments on commit 5c43933

Please sign in to comment.