Skip to content

GuzzleHttp\Psr7\Uri not encoding + (plus) symbol as expected #618

@edegaudenzi

Description

@edegaudenzi

PHP version: x.y.z (hint: php --version)
8.3.6 (Ubuntu 24.04.1)
guzzlehttp/psr7 v2.7.0

Description
Trying to build a URI with this class the '+' (plus) symbol remains un-encoded, so that:
where=Name=="Guzzle+ Org"
becomes:
where=Name%3D%3D%22Guzzle+%20Org%22
instead of expected:
where=Name%3D%3D%22Guzzle%2B%20Org%22

How to reproduce

var_export(
    \GuzzleHttp\Psr7\Uri::withQueryValues(new \GuzzleHttp\Psr7\Uri('https://example.com/prefix/web/index.php'), ['where' => 'Name=="Guzzle+ Org"'])
);

Possible Solution
add '+' => '%2B' to private const QUERY_SEPARATORS_REPLACEMENT = ['=' => '%3D', '&' => '%26'];

Additional context
Issue with the solution is: the '+' symbol, technically, is a legal sub-delims symbol as RFC3986 calls them; the PHP function rawurlencode() used to perform this task is implementing RFC3986 so - correctly - by NOT encoding the '+' symbol.
Saying this, we then need to encode the '+' symbol BEFORE arriving to execute rawurlencode() (and theoretically not when used as sub-delimiter), pretty much as it already happens for '=' and '&': that's easy enough (see solution above).
Problem now is, will it affect any other existing logic? Is it a logic bomb?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions