Repository navigation
v0.6.0
-
Fixed. OAS 3.0 documents that use a boolean
additionalPropertiesno
longer fail validation (#49).additionalPropertieswas grouped withitems
andnot, which really do forbid a boolean before OAS 3.1, but the 3.0
specification spells this one out as "Value can be boolean or object" — and
additionalProperties: falseis the standard closed-object idiom of the 3.0
corpus. The document loaded and then everyvalidateRequest()/
validateResponse()threwUnsupportedSchema. -
Fixed. A property whose name is numeric or whose schema is a boolean is
validated instead of being silently dropped (#50). PHP normalizes the array
key"2020"to an integer, and the directional filter discarded any member
it did not recognise — together with itsrequiredentry — so the whole
declaration went unchecked in both directions, with no diagnostic. Direction
(readOnly/writeOnly) is now the only reason a property is dropped;
anything else is passed through for the compiler and the backend to judge,
and the compiler no longer rejects an integer-normalized name inproperties
or$defs. -
Fixed. A boolean property schema in a form or multipart body no longer
escapes as a bareInvalidArgumentExceptionout ofvalidateRequest()
(#51). The body decoders readpropertiesthrough a helper that accepted
object schemas only; a boolean member now maps to the unconstrained schema
for decoding, and the backend enforces what the boolean says. -
Internal.
MediaType::isJson()normalizes its own argument, like the
twin helper inproperty-testing-openapi. It assumed a pre-normalized value,
so the answer depended on which caller had remembered to normalize first —
the same asymmetry that hid a multipart bug inmediaMatches()until 0.5.1. -
Fixed. A
+in the query string is read as a space (#52). A query is
application/x-www-form-urlencodedcontent, so+spells a space — which is
what an HTML form submits over GET and what every SAPI hands the application.
Percent-decoding it literally reported a violation for the exact value the
application receives as correct, and disagreed with this package's own form
body decoder, which has always folded+first. -
Fixed. A query or cookie key with no
=carries the empty value instead
of failing deserialization (#53). An exploded object parameter is handed
every pair a sibling parameter does not claim, so one stray&flagin the
request failed an unrelated parameter. The styles that have no valueless
form —simple,label,matrix— stay strict. -
Fixed. A multipart body whose closing delimiter carries no trailing CRLF,
or is followed by an epilogue, is accepted (#54). RFC 2046 §5.1.1 makes both
legal andleague/openapi-psr7-validatoraccepts them; requiring the exact
bytes--<boundary>--\r\nturned a conforming client into a
request.body.decodeviolation. A body with no parts at all stays rejected —
the same clause requires at least one — andtests/Differential/now pins
every one of these four verdicts against league. -
Fixed.
encoding.contentTypeis honoured for
application/x-www-form-urlencodedbodies (#55). It was neither applied nor
rejected, so a property declaredapplication/jsonarrived as a string,
failed its own object schema, and was reported asrequest.body.schema— a
valid request called invalid, with a message pointing away from the cause.
A JSON media type is now decoded and validated against the property schema;
any other is validated as the string it already is, the rule an undecoded
body already follows. -
Fixed. A declared multipart part header is validated against its schema,
not merely checked for presence (#58). The constraint was stated by the
document and enforced by nothing, while the same declaration on a response
header was fully validated. A part header is read with thesimplestyle,
like a request header parameter; acontent-form or non-simpledeclaration
fails closed rather than passing an unchecked value through. -
Fixed. A path template whose placeholder shares its segment with literals
—/report.{format},/v{version}/items,/{a}-{b}— is matched (#56). Such
a path compiled and then matched nothing at all, so the operation was
unreachable, and a request that literally equalled the template was blamed for
a missing parameter instead. Concrete paths still win over templated ones, a
decoded separator still cannot escape a segment, and the literal runs are
matched as written. -
Fixed. A parameter violation renders its
actualvalue again (#63).
redactsActual()returned true forheader,cookie,queryandbody—
every location a violation normally carries — soexpectedwas printed in
full, schema and all, beside anactualthat always said[redacted]. The
class already carried a name-based rule written for exactly those locations
and unreachable behind the location check. It decides now, and it is applied
to container members too, so a credential sitting under a member name the
instance path does not reach is still replaced. Bodies stay redacted
wholesale: their member names belong to the application, and a whole-body
violation has the instance path$. -
Changed. Schema compilation is cached per
Contractinstance, keyed by
schema, direction and dialect. The directional rewrite, the JSON round trip
and the backend's parse ran on every validated message, which made
fromArray()a parser andvalidateRequest()the compiler. Measured on a
document with three parameters and a twenty-property body,
validateRequest()went from 1.173 ms to 0.067 ms per call. The new
ValidateRequestBenchmeasures the hot path; the benchmark suite covered
only response selection before. -
Added.
response.body.missing— a response that declares a schema and
arrives with an empty body is a violation (#57), the mirror of
request.body.missing. Checking only the bodies that arrived meant the one
failure contract testing exists to catch, an endpoint answering 200 with
nothing, was the one it passed. Excluded:204,304, every response to a
HEADrequest, and a media type entry declaring no schema or the
unconstrained boolean one.