Make WordPress Core

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's profile 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)

54740.diff (860 bytes) - added by ryelle 3 years ago.
test case

Download all attachments as: .zip

Change History (5)

@ryelle
3 years ago

test case

#1 @ryelle
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.

#2 @rachelbaker
3 years ago

@TimothyBlynJacobs Any thoughts on this?

#3 @TimothyBlynJacobs
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.

#4 @anna.bansaghi
2 years ago

Hi here,

This ticket might be related: #56368

Note: See TracTickets for help on using tickets.