Skip to content

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

@soyuka

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions