eclipse-ee4j / eclipse-ee4j/parsson

The '/' character in JSON property key name isn't encoding in operation path of a JsonPatch as required by RFC6901 - Json Pointer

Open
#17 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
17
Forks
25
PR merge metrics
No merged PRs in 30d

Description

Hello,

I had a problem with the JsonPatch implementation of this library.

Actually, if one of the JsonStructure has a property key name that contains a '/', it isn't encode in the operation 'path'. So the property key name is interpreted by JsonPointer as two keys.

But in the [RFC6902 - JsonPatch](https://tools.ietf.org/html/rfc6902#page-4), it's specified :

> Additionally, operation objects MUST have exactly one "path" member.
> That member's value **is a string containing a JSON-Pointer value
> [RFC6901] that references a location within the target document** (the
> "target location") where the operation is performed.

And in the [RFC6901 - JsonPointer](https://tools.ietf.org/html/rfc6901#page-2), it's specified :

> 3. Syntax
>
> A JSON Pointer is a Unicode string (see [RFC4627], Section 3)
> containing a sequence of zero or more reference tokens, each prefixed
> by a '/' (%x2F) character.
>
> Because the characters '\~' (%x7E) and **'/' (%x2F) have special
> meanings in JSON Pointer**, '~' needs to be encoded as '~0' and **'/'
> needs to be encoded as '~1'** when these characters appear in a
> reference token.

Therefore, I understand that the '/' character in a json property key name should be encode in \~1 in the operation path. Therefore, json property key name 'a/b' should have the path 'a~1b'.

The class code below put in light the problem and throw a `javax.json.JsonException` specified that the JSON Object don't con't contains 'a'. Which is actually true, we have 'a/b' and this is what we are looking for.
```
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonPatch;
import javax.json.JsonReader;
import javax.json.JsonReaderFactory;
import javax.json.JsonStructure;
import javax.json.JsonValue;
import java.io.StringReader;

class Scratch {
private static final String FIRST_JSON = "{\n" +
" \"a/b\": \"valeurA\"\n" +
"}\n";

private static final String SECOND_JSON = "{\n" +
" \"a/b\": \"valeurB\"\n" +
"}\n";

private static final JsonReaderFactory READER_FACTORY = Json.createReaderFactory(null);

public static void main(String[] args) {
try (
JsonReader firstJsonReader = Scratch.READER_FACTORY.createReader(new StringReader(FIRST_JSON));
JsonReader secondJsonReader = Scratch.READER_FACTORY.createReader(new StringReader(SECOND_JSON))
) {
JsonStructure firstJsonStructure = firstJsonReader.read();
JsonStructure secondJsonStructure = secondJsonReader.read();

JsonPatch jsonPatch = Json.createDiff(firstJsonStructure, secondJsonStructure);
for (JsonValue jsonValue : jsonPatch.toJsonArray()) {
JsonObject jsonObject = jsonValue.asJsonObject();
final String jsonPath = jsonObject.getString("path");
firstJsonStructure.getValue(jsonPath);
}
}
}
}
```

To fix this problem, I suggest to replace `path + '/' + key` usage in the method `diffObject` in the `JsonPatchImpl.java`, line 224, by a `path + '/' + Json.encodePointer(key)`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.