[wp-trac] [WordPress Trac] #57312: pattern validation fails in case of multitype validation using WP JSON REST
WordPress Trac
noreply at wordpress.org
Sun Dec 11 15:36:21 UTC 2022
#57312: pattern validation fails in case of multitype validation using WP JSON REST
--------------------------+------------------------------
Reporter: joeyojoeyo12 | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: REST API | Version:
Severity: normal | Resolution:
Keywords: | Focuses:
--------------------------+------------------------------
Old description:
> 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:
>
> {{{
> 'my_data' => [
> '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?
New description:
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?
--
Comment (by TimothyBlynJacobs):
Note: There is a typo on the schema. Your `patternProperty` definition 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
`type`s to support, it will find the first type based match and continue
validating against that.
The validator is thus able to accept `none` as an `array` and will then
proceed to use array validation for which the `items` keyword applies.
However, what you'll want to do is flip the order so a `string` type will
match first.
The `pattern` keyword only applies to `string` types, so if an `array` is
passed, it won't try to assert that it matches the `^none$` regex.
However, `enum` can apply to any type. So by setting an `enum` of `[
"none" ]` you are declaring that `my_data` must 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 `oneOf` in 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 `string` value to
an `array`. For instance, `"Aabcde1"` is accepted, not only `[ "Aabcde1"
]`.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/57312#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list