fix: truncate URI Template prefix modifier by character, not byte (#192)

Operator::inject() applied the ":N" prefix modifier with the
byte-oriented substr(), splitting multibyte UTF-8 characters in half
and producing invalid percent-encoded output (e.g. the euro sign
truncated to its first byte only).

RFC 6570 Section 2.4.1 defines the prefix length as a count of
characters, so use mb_substr() with an explicit UTF-8 encoding
instead. ext-mbstring is already a hard dependency of this package.
This commit is contained in:
dualfroz committed 2026-09-06 06:07:07 +02:00
1 parent 0a2c361a43
commit 98e2fac9c1
2 files changed
+18 -2

No files matched your search

+4 -2
View File
@@ -19,10 +19,10 @@ use Stringable;
use function implode;
use function is_array;
use function mb_substr;
use function preg_match;
use function rawurlencode;
use function str_contains;
use function substr;
/**
* Processing behavior according to the expression type operator.
@@ -156,7 +156,9 @@ enum Operator: string
}
if (':' === $varSpec->modifier) {
$value = substr($value, 0, $varSpec->position);
// RFC 6570 section 2.4.1: the prefix length counts characters, not octets,
// so truncating has to be multibyte aware.
$value = mb_substr($value, 0, $varSpec->position, 'UTF-8');
}
return [$this->decode($value), $this->isNamed()];