Closed liggitt closed 9 months ago
Per https://tools.ietf.org/html/rfc6901#section-3:
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.
Per http://jsonpatch.com/#json-pointer:
To point to the root of the document use an empty string for the pointer. The pointer
/
doesn’t point to the root, it points to a key of""
on the root (which is totally valid in JSON).
In addition to incorrectly accepting "bogus/...", looking briefly at the testcases, it doesn't look like "" or "/" are handled properly either.
Again, any changes should consider the behavior change impact on currently accepted patches
Good catch! So because the current behavior is pretty weird and probably not useful, it's pretty safe to assume we won't be breaking compatibility by just rejecting paths that don't have a leading /
.
it's pretty safe to assume we won't be breaking compatibility by just rejecting paths that don't have a leading
/
.
you underestimate how much people thrash to get a patch applying (c.f. https://github.com/kubernetes/kubernetes/pull/81381#discussion_r313780676) :)
Ooof. I guess it makes sense that they'd trash around and find out you can put garbage on the beginning. I don't want to make life harder for package users, but do want to just fix this obvious bug. I'm open to all options, including a configuration flag to configure the proper behavior so folks can opt in safely.
For kubernetes, if you want to retain the current, buggy behavior, either you could use a version of jsonpatch that allows for configuration of this new, proper behavior. Or we could make it a hard error and you could detect and prepend /blah
to the beginning of patches that don't include a /
.
I'm really open to all options here.
I looked really hard for examples of mistaken patches like foo/bar
used against the kubernetes API and couldn't find any. I think erroring on that case is reasonable.
Tests should probably also be added for these special cases as well (which are valid and should not error):
""
(root object)"/"
(the ""
property at the root)"/foo/"
(the ""
property in the "foo" property)Totally agree. I'll get this coded up into a PR for you to review shortly.
Totally agree. I'll get this coded up into a PR for you to review shortly.
Thanks, sounds good
Azure AD will send PATCH
requests for the SCIM protocol in this format:
{"schemas":["urn:ietf:params:scim:api:messages:2.0:PatchOp"],"Operations":[{"op":"Replace","path":"active","value":"True"},{"op":"Add","path":"displayName","value":"Test 2 Smith"},{"op":"Replace","path":"externalId","value":"Test2"}]}
(without the leading /
)
How can we support this case, which seems to contradict what's expected from Kubernetes API?
Right now I get an error that says active
does not exist in the document
That's not a valid patch path, is it?
@liggitt after reading and learning more about the RFC6902 it definitely looks like the case. I don't think I have an alternative on Azure side of things though. It looks very odd to me that they're sending wrong requests that do not respect the standard... I'll keep researching for alternatives 😢
Yeah, it's definitely invalid. The path is a jsonpointer, which is defined as "zero or more segments each prefixed with /"
I've run into this too.. particularly the rejection of ""
as a valid path (i.e. the whole document).
Any progress on this?
Same -- ""
is a common case.
Dropped the ball on this one, need to get back to it.
Good catch! So because the current behavior is pretty weird and probably not useful, it's pretty safe to assume we won't be breaking compatibility by just rejecting paths that don't have a leading
/
.
That assumption is breaking valid JSONPatches #142
Would it make sense to create a new version clearly stating the breaking compatibility change?
So, do we agree that paths like some/field
are invalid? It seems that with the current implementation, such a patch would fail saying that some/field
is missing (so we wouldn't break the aforementioned Azure AD patch, because it already does not work). So except for ""
, all paths should start with /
.
If https://github.com/evanphx/json-patch/issues/134 is implemented first, this validation could be be as simple as using a custom type for Path
and From
with an UnmarshalText
method that checks for the slash.
I guess I really dropped the ball on this, gonna leave the current behavior.
The JSONPatch library splits the path by / and discards the first segment, assuming it is empty:
https://github.com/evanphx/json-patch/blob/cb8f3b5f9db3c390f2cdf6e67f7e6ea3b339a197/patch.go#L338-L344
This means that an operation with a patch like
bogus/path/to/item
will successfully apply to/path/to/item
Seen in https://github.com/kubernetes/kubernetes/issues/81422
Before fixing this, we should consider the compatibility implications of rejecting patches that were previously accepted.