Skip to content

IriHelper::createIri corrupts query parameter values containing bracketed numeric indexes #8288

Description

@soyuka

Description

IriHelper::createIri normalizes list-style query parameters by collapsing encoded numeric bracket indexes (foo[0]foo[]) using a regex applied to the whole encoded query string:

$query = http_build_query($parameters, '', '&', \PHP_QUERY_RFC3986);
$parts['query'] = preg_replace('/%5B\d+%5D(?!%5B)/', '%5B%5D', $query);

https://github.com/api-platform/core/blob/main/src/Metadata/Util/IriHelper.php#L67-L71

Because the regex runs on the encoded string, it cannot distinguish bracket sequences that belong to a parameter key from those inside a parameter value. A value containing a bracketed numeric index is silently rewritten:

IriHelper::createIri(['path' => '/objects', 'query' => ''], ['v' => 'x[0]'], 'page', 2.);
// expected: /objects?v=x%5B0%5D&page=2
// actual:   /objects?v=x%5B%5D&page=2  → value becomes "x[]"

This corrupts pagination links (hydra:next, HAL/JSON:API equivalents) for any collection request where a filter value legitimately contains [N] — e.g. searching for literal text like item[0].

Context

#8278 fixed the structural variant of this bug (nested array keys being collapsed) with a negative lookahead, which is the right minimal fix for the 4.3 patch branch. The value-corruption case is pre-existing and out of scope there.

Proposed fix

Stop regexing the encoded string. Instead, rewrite numeric leaf keys recursively on the $parameters array before calling http_build_query, so values are never touched. Roughly: walk the array, and for each list-like level re-key sequential numeric leaves so http_build_query emits foo[] natively (or post-process only the key part of each key=value pair).

Slightly bigger change than a one-line regex, so targeting main rather than a patch branch.

/cc from review of #8278

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions