fix: escape the key with ~ or/in its the json Pointer name

pull/61/head
lingbo 2022-02-01 21:45:02 +08:00
parent d0abb0e7a7
commit 9c557daf91
2 changed files with 23 additions and 1 deletions

View File

@ -1,6 +1,7 @@
using JsonDiffPatchDotNet.Formatters.JsonPatch;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using System.Linq;
namespace JsonDiffPatchDotNet.UnitTests
{
@ -121,6 +122,20 @@ namespace JsonDiffPatchDotNet.UnitTests
AssertOperation(operations[1], OperationTypes.Remove, "/1");
}
[Test]
public void Format_EscapeOfJsonPointer_Success()
{
var left = JObject.Parse(@"{ ""a/b"": ""a"", ""a~b"": ""ab"", ""a/~b"": ""abb"",""a/b/c~"": ""abc"" }");
var right = JObject.Parse(@"{ ""a/b"": ""ab"", ""a~b"": ""ba"", ""a/~b"": ""bba"",""a/b/c~"": ""cba"" }");
var patch = Differ.Diff(left, right);
var operations = Formatter.Format(patch);
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~1b") && x.Value.ToString().Equals("ab")));
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~0b") && x.Value.ToString().Equals("ba")));
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~1~0b") && x.Value.ToString().Equals("bba")));
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~1b~1c~0") && x.Value.ToString().Equals("cba")));
}
private void AssertOperation(Operation operation, string expectedOp, string expectedPath, JValue expectedValue = null)
{
Assert.AreEqual(expectedOp, operation.Op);

View File

@ -51,7 +51,7 @@ namespace JsonDiffPatchDotNet.Formatters.JsonPatch
protected override void NodeBegin(JsonFormatContext context, string key, string leftKey, DeltaType type, NodeType nodeType, bool isLast)
{
context.Path.Add(leftKey);
context.Path.Add(Escape(leftKey));
}
protected override void NodeEnd(JsonFormatContext context, string key, string leftKey, DeltaType type, NodeType nodeType, bool isLast)
@ -64,6 +64,13 @@ namespace JsonDiffPatchDotNet.Formatters.JsonPatch
protected override void RootEnd(JsonFormatContext context, DeltaType type, NodeType nodeType) { }
private string Escape(string key)
{
if (string.IsNullOrEmpty(key)) return key;
return key.Replace("~", "~0")
.Replace("/", "~1");
}
private void FormatNode(JsonFormatContext context, JToken delta, JToken left)
{
FormatDeltaChildren(context, delta, left);