Skip to content

Commit 8bd6a32

Browse files
bug #457 Fix ini_parse_quantity() (nicolas-grekas)
This PR was merged into the 1.x branch. Discussion ---------- Fix ini_parse_quantity() Fix #448 /cc `@fisharebest` could you please have a look? `@TimWolla` also maybe? Commits ------- 353f5d1 Fix ini_parse_quantity()
2 parents 3f7e0b8 + 353f5d1 commit 8bd6a32

File tree

2 files changed

+39
-26
lines changed

2 files changed

+39
-26
lines changed

src/Php82/Php82.php

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,42 @@ public static function ini_parse_quantity(string $value): int
174174

175175
return 0;
176176
}
177+
178+
$digits_consumed = $digits;
179+
/* Ignore leading whitespace. */
180+
while ($digits_consumed < $str_end && false !== strpos($ctype_space, $value[$digits_consumed])) {
181+
++$digits_consumed;
182+
}
183+
if ($digits_consumed !== $str_end && ($value[$digits_consumed] === '+' || $value[$digits_consumed] === '-')) {
184+
++$digits_consumed;
185+
}
186+
187+
if ($value[$digits_consumed] === '0') {
188+
/* Value is just 0 */
189+
if ($digits_consumed + 1 === $str_end) {
190+
goto evaluation;
191+
}
192+
switch ($value[$digits_consumed + 1]) {
193+
case 'x':
194+
case 'X':
195+
case 'o':
196+
case 'O':
197+
case 'b':
198+
case 'B':
199+
$digits_consumed += 2;
200+
break;
201+
}
202+
}
203+
204+
if ($digits !== $digits_consumed) {
205+
$message = sprintf(
206+
'Invalid quantity "%s": no digits after base prefix, interpreting as "0" for backwards compatibility',
207+
self::escapeString($value)
208+
);
209+
trigger_error($message, \E_USER_WARNING);
210+
211+
return 0;
212+
}
177213
}
178214

179215
evaluation:
@@ -197,16 +233,6 @@ public static function ini_parse_quantity(string $value): int
197233

198234
$digits_end = $digits;
199235

200-
// The native function treats 0x0x123 the same as 0x123. This is a bug which we must replicate.
201-
if (
202-
16 === $base
203-
&& $digits_end + 2 < $str_end
204-
&& '0x' === substr($value, $digits_end, 2)
205-
&& false !== strpos($allowed_digits, $value[$digits_end + 2])
206-
) {
207-
$digits_end += 2;
208-
}
209-
210236
while ($digits_end < $str_end && false !== strpos($allowed_digits, $value[$digits_end])) {
211237
++$digits_end;
212238
}

tests/Php82/Php82Test.php

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -240,19 +240,6 @@ public function testIniParseQuantity()
240240
$this->assertSame(-17179869184, ini_parse_quantity('-0X10G'));
241241
}
242242

243-
public function testIniParseQuantityUndocumentedFeatures()
244-
{
245-
$this->assertSame(18, ini_parse_quantity('0x0x12'));
246-
247-
$this->assertSame(2, ini_parse_quantity('0b+10'));
248-
$this->assertSame(8, ini_parse_quantity('0o+10'));
249-
$this->assertSame(16, ini_parse_quantity('0x+10'));
250-
251-
$this->assertSame(2, ini_parse_quantity('0b 10'));
252-
$this->assertSame(8, ini_parse_quantity('0o 10'));
253-
$this->assertSame(16, ini_parse_quantity('0x 10'));
254-
}
255-
256243
public function testIniParseQuantityZeroWithMultiplier()
257244
{
258245
// Note that "1 K" is valid
@@ -314,8 +301,8 @@ public function testIniParseQuantityNoLeadingDigits()
314301
public function testIniParseQuantityOutOfRange()
315302
{
316303
error_clear_last();
317-
$this->assertSame(-4096, @ini_parse_quantity(' 0x-4K '));
318-
$this->assertSame('Invalid quantity " 0x-4K ": value is out of range, using overflow result for backwards compatibility', error_get_last()['message']);
304+
$this->assertSame(0, @ini_parse_quantity(' 0x-4K '));
305+
$this->assertSame('Invalid quantity " 0x-4K ": no digits after base prefix, interpreting as "0" for backwards compatibility', error_get_last()['message']);
319306
$this->assertContains(error_get_last()['type'], [\E_WARNING, \E_USER_WARNING]);
320307
}
321308

@@ -339,7 +326,7 @@ public function testIniParseQuantitySignAfterPrefixButNoDigits()
339326
{
340327
error_clear_last();
341328
$this->assertSame(0, @ini_parse_quantity(' 0b- '));
342-
$this->assertSame('Invalid quantity " 0b- ": no valid leading digits, interpreting as "0" for backwards compatibility', error_get_last()['message']);
329+
$this->assertSame('Invalid quantity " 0b- ": no digits after base prefix, interpreting as "0" for backwards compatibility', error_get_last()['message']);
343330
$this->assertContains(error_get_last()['type'], [\E_WARNING, \E_USER_WARNING]);
344331
}
345332

0 commit comments

Comments
 (0)