Skip to content

fix server errors found by API conformance tests - #657

Open
cportele wants to merge 6 commits into
api-validation-fixes-part1from
api-validation-fixes-part2
Open

cportele wants to merge 6 commits into
api-validation-fixes-part1from
api-validation-fixes-part2

Conversation

@cportele

Copy link
Copy Markdown
Contributor

Builds on #656.

Further fixes found by testing several ldproxy APIs with schemathesis and ogc-checker. Several of them share one pattern: a value that PostgreSQL rejects was passed to the database. Before part 1 such a request of a feature list did not complete; with part 1 it ends with a server error. These fixes validate or encode the values before the query is executed, so the request gets the correct result or a 400.

CQL2

  • NUL character in a string literal (ScalarLiteral): rejected when the filter is parsed,
    PostgreSQL rejects such strings.
  • Function as argument of a spatial predicate (CqlTextVisitor): a parse error that names the
    function instead of an internal error message.

SQL

  • Array predicates with an empty array (FilterEncoderSql): A_CONTAINS(p, ()) etc. was
    encoded as IN (). Now encoded by its meaning, consistent with the other array predicates where a
    property without values does not match: a property with values contains the empty array, no
    property overlaps with it, is contained by it or equals it.
  • Dates before the year 1 (SqlDialectPgis): the ISO year 0 (0000-01-01) and negative years
    are written as BC years, PostgreSQL has no year 0.

CRS

  • Geocentric target CRS of 2D data (CrsTransformerFactoryProj, CrsTransformerProj):
    transforming to e.g. EPSG:4936 failed, the result was sized for two coordinates. A geocentric
    target now has three dimensions also for a 2D source; the result is sized for the coordinates the
    operation returns, and only the first coordinates are kept if the operation returns more than
    the target uses. 3D→2D behaves as before.

Features

  • Feature id removed by a property selection (WithoutProperties): a selection without the id
    dropped the id, e.g. the HTML map then got no geometry for the page. Always keep the feature id.

A function as an argument of a spatial predicate in CQL2 text, e.g.
S_INTERSECTS(geometry, ENVELOPE(...)), failed with a ClassCastException,
whose message was returned to the client. Such filters are now rejected
with a parse error that names the function.
A selection of properties, e.g. from the properties or exclude-properties
parameter of an API, also removed the id of the feature, if it was not
selected. The id identifies the feature and is now always kept. Ids of
nested objects are not affected.
An array predicate with an empty array, e.g. A_CONTAINS(names, ()) or a
queryable parameter of an array property with an empty value, was encoded as
`IN ()`. The database rejects that statement, and since the error of a streamed
read is not propagated, the request did not complete.

An empty array is now encoded according to its meaning, consistent with the
other array predicates where a property without values does not match: a
property with values contains the empty array, and no property overlaps with
it, is contained by it or is equal to it.
A date or timestamp in the year 0000, e.g. `datetime=0000-01-01`, is valid in
ISO 8601 and RFC 3339, but PostgreSQL has no year 0 and rejected the literal.
The request failed with an internal error or, for a streamed read, did not
complete.

Dates and timestamps before the year 1 are now written in the notation of
PostgreSQL: the ISO year 0 is 1 BC, the year -1 is 2 BC etc.
Transforming 2D coordinates to a geocentric CRS, e.g. EPSG:4936 (ETRS89 X-Y-Z),
failed with an internal error. The transformation returns three coordinates per
position, but the result was sized for two.

A geocentric target now has three dimensions, also for a 2D source, and the
result of a transformation is sized for the coordinates it returns. If a
transformation returns more coordinates than the target uses, only the first
coordinates of each position are kept.
A character string in a filter that contains the character U+0000, e.g. in a
CQL2-JSON filter of a search request, was passed to the database. PostgreSQL
rejects such a string, and since the error of a streamed read is not
propagated, the request did not complete.

A character string with U+0000 is now rejected when the filter is parsed.
@cportele
cportele force-pushed the api-validation-fixes-part2 branch from 1335ae8 to 3885efd Compare October 19, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant