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

    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