Opened 3 years ago
Last modified 2 years ago
#54740 new defect (bug)
REST API: oneOf validation behaves unexpectedly with strings/arrays
Reported by: | ryelle | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 5.6 |
Component: | REST API | Keywords: | |
Focuses: | Cc: |
Description
I'm trying to validate block.json files against the block.json schema, which uses oneOf
in a few places (for example, "style"). Using rest_validate_value_from_schema
, I end up with this error: "[style] matches more than one of the expected formats.".
I think this is a bug in the validation, because style
can be one of a string or an array of strings, but the code that checks the value (rest_is_array
) converts the string to an array, forcing it to match both options.
Attachments (1)
Change History (5)
#1
@
3 years ago
54740.diff adds a (failing) test case for the test_one_of
unit test, to show the error. The first added case fails, because the string matches both the string & array options. The last case also fails, when it should match neither, so I think there's a different type casting happening somewhere else.
#3
@
3 years ago
Yeah, so essentially the issue is that the WordPress JSON Schema validator supports loose typing because we accept data that isn't originally JSON like form-encoded data or URL based. One of the more extreme examples is that we allow a string value when a property expects an array.
So a schema like the one provided where you specify a oneOf
of an array or array of strings is something you'd never do as a REST API validation schema, because it is the default behavior.
Of course, this causes problems if you are using another validator that is more strict, you need to allow for a bare string value.
I think it could be possible for the schema validation to be updated such that rest_find_one_matching_schema
would understand if a value was validated successfully without any type coercion, but that may be pretty challenging to implement as the type coercion is fairly fundamental to our schema validator.
For now, instead of using oneOf
you should be able do something like this.
{ "type": [ "array", "string" ], "items": { "type": "string" } }
The type
keyword can be a list of types, and the items
keyword will only apply if it is validating an array
. The oneOf
keyword allows for more complex validation, but in general, if something can be expressed with a list of types, that would be preferred.
test case