Skip to content

Commit 8eec399

Browse files
committed
fix
1 parent 7a451f1 commit 8eec399

2 files changed

Lines changed: 38 additions & 0 deletions

File tree

rules/Php72/NodeFactory/AnonymousFunctionFactory.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public function create(
8282
public function createAnonymousFunctionFromExpr(Expr $expr): ?Closure
8383
{
8484
$stringValue = $this->inlineCodeParser->stringify($expr);
85+
$stringValue = $this->normalizeHexBackreferenceExpression($stringValue);
8586

8687
$phpCode = '<?php ' . $stringValue . ';';
8788
$contentStmts = $this->simplePhpParser->parseString($phpCode);
@@ -125,6 +126,24 @@ public function createAnonymousFunctionFromExpr(Expr $expr): ?Closure
125126
return $anonymousFunction;
126127
}
127128

129+
private function normalizeHexBackreferenceExpression(string $stringValue): string
130+
{
131+
// Only rewrite when the expression has no quotes, to avoid mutating string literals.
132+
if (str_contains($stringValue, "'") || str_contains($stringValue, '"')) {
133+
return $stringValue;
134+
}
135+
136+
return Strings::replace(
137+
$stringValue,
138+
'#0x(?<backreference>\\\d+|\$\d+)#',
139+
static function (array $match): string {
140+
$backreference = $match['backreference'];
141+
$number = ltrim($backreference, '\\$');
142+
return 'hexdec($matches[' . $number . '])';
143+
}
144+
);
145+
}
146+
128147
/**
129148
* @param Param[] $params
130149
* @return string[]

src/PhpParser/Parser/InlineCodeParser.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
*/
5353
private const string BACKREFERENCE_NO_DOUBLE_QUOTE_START_REGEX = '#(?<!")(?<backreference>\$\d+)#';
5454

55+
/**
56+
* @see https://regex101.com/r/8Dk7Qn/1
57+
*/
58+
private const string HEX_BACKREFERENCE_REGEX = '#0x(?<backreference>\\\d+|\$\d+)#';
59+
5560
public function __construct(
5661
private BetterStandardPrinter $betterStandardPrinter,
5762
private SimplePhpParser $simplePhpParser,
@@ -81,6 +86,20 @@ public function parseString(string $fileContent): array
8186
public function stringify(Expr $expr): string
8287
{
8388
if ($expr instanceof String_) {
89+
if (! str_contains($expr->value, "'") && ! str_contains($expr->value, '"') && StringUtils::isMatch(
90+
$expr->value,
91+
self::HEX_BACKREFERENCE_REGEX
92+
)) {
93+
return Strings::replace(
94+
$expr->value,
95+
self::HEX_BACKREFERENCE_REGEX,
96+
static function (array $match): string {
97+
$number = ltrim((string) $match['backreference'], '\\$');
98+
return 'hexdec($matches[' . $number . '])';
99+
}
100+
);
101+
}
102+
84103
if (! StringUtils::isMatch($expr->value, self::BACKREFERENCE_NO_QUOTE_REGEX)) {
85104
return Strings::replace(
86105
$expr->value,

0 commit comments

Comments
 (0)