polyfill icon indicating copy to clipboard operation
polyfill copied to clipboard

[PHP 8.2] Add `ini_parse_quantity` function

Open Ayesh opened this issue 3 years ago • 2 comments

Polyfill taken from PHP.Watch - PHP 8.2: New ini_parse_quantity function

Tries to mimic the native warnings with E_USER_WARNING errors, and overflow/underflow conditions by inspecting the int to float type change.

Ayesh avatar Jul 12 '22 22:07 Ayesh

Tried adding the following tests, but they don't seem to work for some reason:

    /**
     * @covers \Symfony\Polyfill\Php82\Php82::ini_parse_quantity
     */
    public function testIniParseQuantityWarningsInvalidCharactersIgnored()
    {
        $this->expectWarning();
        $this->expectWarningMessageMatches('/Invalid quantity "5em", interpreting as "5m" for backwards compatibility/');
        ini_parse_quantity('5em');
    }

    /**
     * @covers \Symfony\Polyfill\Php82\Php82::ini_parse_quantity
     */
    public function testIniParseQuantityWarningsNoDigits()
    {
        $this->expectWarning();
        $this->expectWarningMessageMatches('/Invalid quantity "NOVALUE": no valid leading digits, interpreting as "0" for backwards compatibility/');
        ini_parse_quantity('NOVALUE');
    }

    /**
     * @covers \Symfony\Polyfill\Php82\Php82::ini_parse_quantity
     */
    public function testIniParseQuantityUnknownMultiplier()
    {
        $this->expectWarning();
        $this->expectWarningMessageMatches('/Invalid quantity "123R": unknown multiplier "R", interpreting as "123" for backwards compatibility/');
        ini_parse_quantity('123R');
    }

Ayesh avatar Jul 12 '22 23:07 Ayesh

Tried adding the following tests, but they don't seem to work for some reason

you can try add anchors /^...$/i or use expectWarningMessage()

WinterSilence avatar Aug 30 '22 18:08 WinterSilence

only the error message seems to be slightly different than on PHP 8.2.

If it wasn't for the error-messages, this would be a trivial function to polyfill :-)

Here is a simple, brute-force test script I wrote while trying to create my own implementation.

<?php
require 'src/Php82/Php82.php';
use Symfony\Polyfill\Php82\Php82;

function do_test($test) {
    error_clear_last();
    $x = @ini_parse_quantity($test);
    $err_x = error_get_last()['message'] ?? '';

    error_clear_last();
    $y = @Php82::ini_parse_quantity($test);
    $err_y = error_get_last()['message'] ?? '';

    if ($x !== $y || $err_x !== $err_y) {
        echo 'FAIL: "', $test, '"', PHP_EOL, $x, PHP_EOL, $y, PHP_EOL, $err_x, PHP_EOL, $err_y, PHP_EOL;
        exit;
    }
}

$chars = [' ', '-', '+', '0', '1', '7', '9', 'a', 'b', 'o', 'f', 'g', 'k', 'm', 'x', 'z'];

do_test('');
foreach ($chars as $char1) {
    do_test($char1);
    foreach ($chars as $char2) {
        do_test($char1 . $char2);
        foreach ($chars as $char3) {
            do_test($char1 . $char2 . $char3);
            foreach ($chars as $char4) {
                do_test($char1 . $char2 . $char3 . $char4);
                foreach ($chars as $char5) {
                    do_test($char1 . $char2 . $char3 . $char4 . $char5);
                    foreach ($chars as $char6) {
                        do_test($char1 . $char2 . $char3 . $char4 . $char5 . $char6);
                    }
                }
            }
        }
    }
}

fisharebest avatar Jan 20 '23 11:01 fisharebest

What's the status on this?

King2500 avatar Jan 24 '23 09:01 King2500

The C implementation is here: https://github.com/php/php-src/blob/master/Zend/zend_ini.c#L590

Would anyone be interested in porting this to PHP? I suppose @Ayesh is not available to finish this PR.

nicolas-grekas avatar Jan 26 '23 08:01 nicolas-grekas

I'm closing to signal that someone else should take over. PR welcome.

nicolas-grekas avatar Jul 10 '23 06:07 nicolas-grekas

Would anyone be interested in porting this to PHP?

I have done this and have a working solution. (I need it for one of my own projects.)

Using the brute-force test technique above, it gives the same output and errors as the core function for all strings up to 7 characters.

  • The tests only run on PHP82, as they require the core function as a reference.
  • The code follows the C source - including gotos and pointer-based string access.

Would you want me to create a PR now (with this rather hideous code) or wait until I have time to clean it up (which might not be soon)?

fisharebest avatar Aug 03 '23 15:08 fisharebest

I've submitted PR #439

fisharebest avatar Aug 04 '23 10:08 fisharebest