Skip to content

Edge Case: SyntaxErrorException throws ValueError in PHP 8 #71

@flavioheleno

Description

@flavioheleno

In the SyntaxErrorException.php the message formatting code (lines 19 and 20 to be more precise), uses str_repeat with $token['pos'] for its $times parameter, which will position the arrow (^) in the exception message, working as an indicator of the invalid symbol in the expression that was evaluated as path (as seen below).

php > (new JmesPath\Parser(new JmesPath\Lexer()))->parse(';');
PHP Warning:  Uncaught JmesPath\SyntaxErrorException: Syntax error at character 0
;
^
Unexpected "unknown" token (nud_unknown). Expected one of the following tokens: "identifier", "quoted_identifier", "current", "literal", "expref", "not", "lparen", "lbrace", "flatten", "filter", "star", "lbracket" in /Users/flavio/Documents/open-source/jmespath.php/src/Parser.php:466
Stack trace:
#0 /Users/flavio/Documents/open-source/jmespath.php/src/Parser.php(515): JmesPath\Parser->syntax('Unexpected "unk...')
#1 /Users/flavio/Documents/open-source/jmespath.php/src/Parser.php(97): JmesPath\Parser->__call('nud_unknown', Array)
#2 /Users/flavio/Documents/open-source/jmespath.php/src/Parser.php(79): JmesPath\Parser->expr()
#3 php shell code(1): JmesPath\Parser->parse(';')
#4 {main}
  thrown in /Users/flavio/Documents/open-source/jmespath.php/src/Parser.php on line 466

That works fine as long as the expression is successfully parsed and therefore assigns a positive value for $token['pos'], but I found out that for some invalid expressions (say an equal sign, for whatever reason), $token['pos'] gets assigned -1 from start and as the parsing fails before assigning a different value to it, it will be kept a negative value, thus being used like that in str_repeat.

From the PHP Manual, we can see what $time works for and its restrictions as follows:

times

Number of time the string string should be repeated.
times has to be greater than or equal to 0. If the times is set to 0, the function will return an empty string.

Note that although not being documented, passing a negative value for $time leads str_repeat to return NULL instead of an empty string and to also emit a Warning (PHP 7) or throw a ValueError (PHP 8):

// php 7
php > var_dump(str_repeat(' ', -1));
PHP Warning:  str_repeat(): Second argument has to be greater than or equal to 0 in php shell code on line 1

Warning: str_repeat(): Second argument has to be greater than or equal to 0 in php shell code on line 1
NULL
// php 8
php > var_dump(str_repeat(' ', -1));
PHP Warning:  Uncaught ValueError: str_repeat(): Argument #2 ($times) must be greater than or equal to 0 in php shell code:1
Stack trace:
#0 php shell code(1): str_repeat(' ', -1)
#1 {main}
  thrown in php shell code on line 1

Warning: Uncaught ValueError: str_repeat(): Argument #2 ($times) must be greater than or equal to 0 in php shell code:1
Stack trace:
#0 php shell code(1): str_repeat(' ', -1)
#1 {main}
  thrown in php shell code on line 1

This is, IMO, an edge case for both the Parser and SyntaxErrorException that most library users will not be facing in regular usage, but worth fixing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions