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
- 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
Assessment
This issue has not been assessed yet.