guzzle / uri-template

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pct-encoded reserved character(%2F) was encoded twice

TheNorthMemory opened this issue · comments

PHP version: 8.1.3

Description

As of a community reporting, while the uri was already contains the pct-encoded(reserved characters) component, eg: AIO%2FFR. The {+var} syntax is explained this one as of AIO%252FFR. It is leading to misinterpreting the original percent data octet string.

I've also checked the RFC3986 and RFC6570 specifications.

RFC3986 2.4. When to Encode or Decode was mentioned there:

Because the percent ("%") character serves as the indicator for
percent-encoded octets, it must be percent-encoded as "%25" for that
octet to be used as data within a URI. Implementations must not
percent-encode or decode the same string more than once, as decoding
an already decoded string might lead to misinterpreting a percent
data octet as the beginning of a percent-encoding, or vice versa in
the case of percent-encoding an already percent-encoded string.

RFC6570 3.2.1. Variable Expansion was mentioned there:

The allowed set for a given expansion depends on the expression type:
reserved ("+") and fragment ("#") expansions allow the set of
characters in the union of ( unreserved / reserved / pct-encoded ) to
be passed through without pct-encoding, whereas all other expression
types allow only unreserved characters to be passed through without
pct-encoding. Note that the percent character ("%") is only allowed
as part of a pct-encoded triplet and only for reserved/fragment
expansion: in all other cases, a value character of "%" MUST be pct-
encoded as "%25" by variable expansion.

The pct-encoded reserved character(%2F) may pass through but it was encoded the char(%) to %25. It is mismatched the specs.

How to reproduce

<?php

require_once './vendor/autoload.php';

use GuzzleHttp\UriTemplate\UriTemplate;
echo UriTemplate::expand('merchant-service/images/{+slot}', ['slot' => 'AIO%2FFR']);
// result: merchant-service/images/AIO%252FFR
// Actually, there was required the url like this: `merchant-service/images/AIO%2FFR`

Possible Solution

Additional context

Thanks for the report.

Related: uri-templates/uritemplate-test#41.

Copy that. I've also strange that the RFC6570 wasn't any samples about double pct-encode.

It sugguest that this library should be followed the RFC3986 Implementations must not
percent-encode or decode the same string more than once
. If upgrading with this suggestion, it may works well with Guzzle\Psr7\Uri::filterPath (https://github.com/guzzle/psr7/blob/2.5/src/Uri.php#L693-L697)

If you have any time to prepare a PR, or half of a PR, that would be much appreciated. I am spread thin these days, lol.