Skip to content

Commit 9c557da

Browse files
committed
fix: escape the key with ~ or/in its the json Pointer name
1 parent d0abb0e commit 9c557da

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

Src/JsonDiffPatchDotNet.UnitTests/JsonDeltaFormatterUnitTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using JsonDiffPatchDotNet.Formatters.JsonPatch;
22
using Newtonsoft.Json.Linq;
33
using NUnit.Framework;
4+
using System.Linq;
45

56
namespace JsonDiffPatchDotNet.UnitTests
67
{
@@ -121,6 +122,20 @@ public void Format_ArrayRemoveInDescOrder_Success()
121122
AssertOperation(operations[1], OperationTypes.Remove, "/1");
122123
}
123124

125+
[Test]
126+
public void Format_EscapeOfJsonPointer_Success()
127+
{
128+
var left = JObject.Parse(@"{ ""a/b"": ""a"", ""a~b"": ""ab"", ""a/~b"": ""abb"",""a/b/c~"": ""abc"" }");
129+
var right = JObject.Parse(@"{ ""a/b"": ""ab"", ""a~b"": ""ba"", ""a/~b"": ""bba"",""a/b/c~"": ""cba"" }");
130+
var patch = Differ.Diff(left, right);
131+
var operations = Formatter.Format(patch);
132+
133+
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~1b") && x.Value.ToString().Equals("ab")));
134+
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~0b") && x.Value.ToString().Equals("ba")));
135+
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~1~0b") && x.Value.ToString().Equals("bba")));
136+
Assert.IsTrue(operations.Any(x => x.Path.Equals("/a~1b~1c~0") && x.Value.ToString().Equals("cba")));
137+
}
138+
124139
private void AssertOperation(Operation operation, string expectedOp, string expectedPath, JValue expectedValue = null)
125140
{
126141
Assert.AreEqual(expectedOp, operation.Op);

Src/JsonDiffPatchDotNet/Formatters/JsonPatch/JsonDeltaFormatter.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected override void Format(DeltaType type, JsonFormatContext context, JToken
5151

5252
protected override void NodeBegin(JsonFormatContext context, string key, string leftKey, DeltaType type, NodeType nodeType, bool isLast)
5353
{
54-
context.Path.Add(leftKey);
54+
context.Path.Add(Escape(leftKey));
5555
}
5656

5757
protected override void NodeEnd(JsonFormatContext context, string key, string leftKey, DeltaType type, NodeType nodeType, bool isLast)
@@ -64,6 +64,13 @@ protected override void RootBegin(JsonFormatContext context, DeltaType type, Nod
6464

6565
protected override void RootEnd(JsonFormatContext context, DeltaType type, NodeType nodeType) { }
6666

67+
private string Escape(string key)
68+
{
69+
if (string.IsNullOrEmpty(key)) return key;
70+
return key.Replace("~", "~0")
71+
.Replace("/", "~1");
72+
}
73+
6774
private void FormatNode(JsonFormatContext context, JToken delta, JToken left)
6875
{
6976
FormatDeltaChildren(context, delta, left);

0 commit comments

Comments
 (0)