StackOverflowException in JsonConvert.DeserializeXmlNode



我们最近从 6.0.1 升级到 Json.NET 10.0r2,自从升级以来,我注意到我们的一个单元测试在尝试反序列化无效的 JSON 时抛出了堆栈溢出异常。 测试的目的是确保处理无效的 Json。 同样的测试曾经抛出一个JsonSerializationException,但现在使用StackOverflow使nUnit下降。

我已经通过这个测试在 Json.NET 自己的单元测试项目中复制了它:

[Test]
public void FailOnInvalidJSON( )
{
string json = @"{'Row' : ";
Assert.Throws<JsonSerializationException>(()=>JsonConvert.DeserializeXmlNode(json, "ROOT"));
}

关于变通方法的任何想法?

谢谢!

更新

并迅速固定在更改集822c3f0。 应该在 10.0.2 之后的下一个版本中。

原始答案

看起来在 8.0.1 版中对JsonTextReader的更改可能发现了XmlNodeConverter中的错误。

在 7.0.1 中,当到达意外的文件末尾时,JsonReader.TokenType在下次尝试Read()后变为JsonToken.None,这会导致DeserializeNode()抛出Unexpected JsonToken when deserializing node: None异常。 但是在 8.0.1 及更高版本中,TokenType似乎停留在最后遇到的标记的类型上,即JsonToken.PropertyName,这会导致无限递归。

正确的解决方法是,在 2171 行附近XmlNodeConverter.DeserializeNode()检查从reader.Read()返回:

case JsonToken.PropertyName:
if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null)
{
throw JsonSerializationException.Create(reader, "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifying a DeserializeRootElementName.");
}
string propertyName = reader.Value.ToString();
// Need to check the return from reader.Read() here:
if (!reader.Read())
{
throw JsonSerializationException.Create(reader, "Unexpected end of file when deserializing property: " + propertyName );
}

。而且XmlNodeConverter.cs似乎还有几个地方需要检查从reader.Read()返回,例如在 1942 行附近的ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager)

如果需要,您可以报告问题。

同时,您的解决方法选项是:

  • 以不同的方式损坏 JSON,例如:

    string json = @"{'Row' : }";
    

    并检查更一般的异常JsonException

  • 将 JSON 预解析为JToken

    Assert.Throws<JsonException>(()=>JsonConvert.DeserializeXmlNode(JToken.Parse(json).ToString(), "ROOT"));
    

相关内容

  • 没有找到相关文章

最新更新