uri-template icon indicating copy to clipboard operation
uri-template copied to clipboard

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

Open TheNorthMemory opened this issue 2 years ago • 4 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

TheNorthMemory avatar Mar 09 '22 15:03 TheNorthMemory