Opened 3 years ago
Last modified 3 years ago
#57312 new defect (bug)
pattern validation fails in case of multitype validation using WP JSON REST
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | REST API | Keywords: | |
| Focuses: | Cc: |
Description (last modified by )
Just as this https://core.trac.wordpress.org/ticket/56483 question for which I'm still waiting for a reply; I seemingly found another issue when trying to validate the input via oneOf. Concretely, I'm trying to validate that an object has:
- pattern properties
- with values being either a
^none$string or a an array of strings matching another regex, like^[A-Z][a-z]{5}[0-9]$.
Try to submit your data via the js FormData API which holds an object that should validate against sth like this:
[
'type' => 'object',
'patternProperties' => [
'$[a-z]{5}$' => [
'type' => [
'array',
'string',
],
'pattern' => '^none$',
'items' => [
'type' => 'string',
'pattern' => '^[A-Z][a-z]{5}[0-9]$',
],
'uniqueItems' => true,
'required' => true,
],
],
'additionalProperties' => false,
'minProperties' => 1,
'required' => true,
]
If you submit something like:
{
"my_data":{
"abcde":"none"
}
}
It will result in a Bad Request error, telling you that my_data[abcde] does not match with ^none$.
I've tried to use "enum": ["none"] instead of "pattern": "^none$", which is when it also responds with a 400 Bad Request, saying that my_data[abcde] is not none.
Seems like a bug?
Note: See
TracTickets for help on using
tickets.
Note: There is a typo on the schema. Your
patternPropertydefinition is using a$for the start of string declaration instead of a^. After correcting that, this is the error I'm getting.my_data[abcde][0] does not match pattern ^[A-Z][a-z]{5}[0-9]$The REST API needs to support type juggling so when you declare a list of
types to support, it will find the first type based match and continue validating against that.The validator is thus able to accept
noneas anarrayand will then proceed to use array validation for which theitemskeyword applies. However, what you'll want to do is flip the order so astringtype will match first.The
patternkeyword only applies tostringtypes, so if anarrayis passed, it won't try to assert that it matches the^none$regex. However,enumcan apply to any type. So by setting anenumof[ "none" ]you are declaring thatmy_datamust be a dictionary with 5 letter keys where each value must be"none".The corrected schema is:
[ 'type' => 'object', 'patternProperties' => [ '^[a-z]{5}$' => [ 'type' => [ 'string', 'array', ], 'pattern' => '^none$', 'items' => [ 'type' => 'string', 'pattern' => '^[A-Z][a-z]{5}[0-9]$', ], 'uniqueItems' => true, 'required' => true, ], ], 'additionalProperties' => false, 'minProperties' => 1, 'required' => true, ]However, I'd recommend using
oneOfin this case to have a simpler to understand schema.[ 'type' => 'object', 'patternProperties' => [ '^[a-z]{5}$' => [ 'oneOf' => [ [ 'type' => 'string', 'enum' => [ 'none' ] ], [ 'type' => 'array', 'items' => [ 'type' => 'string', 'pattern' => '^[A-Z][a-z]{5}[0-9]$', ], 'uniqueItems' => true, ] ], ], ], 'additionalProperties' => false, 'minProperties' => 1, 'required' => true, ]It has the side-effect of allowing a type upgrade from a
stringvalue to anarray. For instance,"Aabcde1"is accepted, not only[ "Aabcde1" ].