Skip to content

Commit

Permalink
Merge pull request #510 from MauricioFauth/fuzz-errors
Browse files Browse the repository at this point in the history
Fix undefined array key errors and a deprecation
  • Loading branch information
MauricioFauth committed Sep 16, 2023
2 parents 3d0c3a6 + dd1e775 commit 445804d
Show file tree
Hide file tree
Showing 23 changed files with 708 additions and 58 deletions.
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ parameters:
count: 1
path: src/Components/AlterOperation.php

-
message: "#^Parameter \\#1 \\$key of function array_key_exists expects int\\|string, float\\|int\\|string given\\.$#"
count: 2
path: src/Components/AlterOperation.php

-
message: "#^Property PhpMyAdmin\\\\SqlParser\\\\Components\\\\AlterOperation\\:\\:\\$options \\(PhpMyAdmin\\\\SqlParser\\\\Components\\\\OptionsArray\\) does not accept PhpMyAdmin\\\\SqlParser\\\\Components\\\\OptionsArray\\|null\\.$#"
count: 1
Expand Down
6 changes: 1 addition & 5 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
<InvalidScalarArgument occurrences="1">
<code>$arrayKey</code>
</InvalidScalarArgument>
<MixedArrayOffset occurrences="1">
<code>Parser::$STATEMENT_PARSERS[$token-&gt;value]</code>
</MixedArrayOffset>
<MoreSpecificImplementedParamType occurrences="1">
<code>$component</code>
</MoreSpecificImplementedParamType>
Expand Down Expand Up @@ -631,8 +628,7 @@
<code>$this-&gt;last</code>
<code>$this-&gt;last</code>
</LoopInvalidation>
<MixedArrayAccess occurrences="42">
<code>$this-&gt;str[$this-&gt;last + 1]</code>
<MixedArrayAccess occurrences="41">
<code>$this-&gt;str[$this-&gt;last + 1]</code>
<code>$this-&gt;str[$this-&gt;last++]</code>
<code>$this-&gt;str[$this-&gt;last]</code>
Expand Down
6 changes: 3 additions & 3 deletions src/Components/AlterOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

use function array_key_exists;
use function in_array;
use function is_numeric;
use function is_int;
use function is_string;
use function trim;

Expand Down Expand Up @@ -412,7 +412,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =

$state = 2;
} elseif ($state === 2) {
if (is_string($token->value) || is_numeric($token->value)) {
if (is_string($token->value) || is_int($token->value)) {
$arrayKey = $token->value;
} else {
$arrayKey = $token->token;
Expand Down Expand Up @@ -445,7 +445,7 @@ public static function parse(Parser $parser, TokensList $list, array $options =
);
break;
}
} elseif (! empty(Parser::$STATEMENT_PARSERS[$token->value])) {
} elseif (! empty(Parser::$STATEMENT_PARSERS[$arrayKey])) {
// We have reached the end of ALTER operation and suddenly found
// a start to new statement, but have not found a delimiter between them
$parser->error(
Expand Down
4 changes: 4 additions & 0 deletions src/Components/ArrayObj.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ public static function parse(Parser $parser, TokensList $list, array $options =

// End of statement.
if ($token->type === Token::TYPE_DELIMITER) {
if ($brackets > 0) {
$parser->error('A closing bracket was expected.', $token);
}

break;
}

Expand Down
9 changes: 8 additions & 1 deletion src/Statements/AlterStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,14 @@ class AlterStatement extends Statement
public function parse(Parser $parser, TokensList $list)
{
++$list->idx; // Skipping `ALTER`.
$this->options = OptionsArray::parse($parser, $list, static::$OPTIONS);
$parsedOptions = OptionsArray::parse($parser, $list, static::$OPTIONS);
if ($parsedOptions->isEmpty()) {
$parser->error('Unrecognized alter operation.', $list->tokens[$list->idx]);

return;
}

$this->options = $parsedOptions;
++$list->idx;

// Parsing affected table.
Expand Down
10 changes: 8 additions & 2 deletions src/Statements/WithStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

use function array_slice;
use function count;
use function preg_match;

/**
* `WITH` statement.
Expand Down Expand Up @@ -114,7 +115,7 @@ public function parse(Parser $parser, TokensList $list)
}

if ($state === 0) {
if ($token->type !== Token::TYPE_NONE) {
if ($token->type !== Token::TYPE_NONE || ! preg_match('/^[a-zA-Z0-9_$]+$/', $token->token)) {
$parser->error('The name of the CTE was expected.', $token);
break;
}
Expand All @@ -124,7 +125,12 @@ public function parse(Parser $parser, TokensList $list)
$state = 1;
} elseif ($state === 1) {
if ($token->type === Token::TYPE_OPERATOR && $token->value === '(') {
$this->withers[$wither]->columns = Array2d::parse($parser, $list);
$columns = Array2d::parse($parser, $list);
if ($parser->errors !== []) {
break;
}

$this->withers[$wither]->columns = $columns;
$state = 2;
} elseif ($token->type === Token::TYPE_KEYWORD && $token->keyword === 'AS') {
$state = 3;
Expand Down
2 changes: 1 addition & 1 deletion src/Token.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ public function extract()
case self::TYPE_NUMBER:
$ret = str_replace('--', '', $this->token); // e.g. ---42 === -42
if ($this->flags & self::FLAG_NUMBER_HEX) {
$ret = str_replace(['-', '+'], '', $this->token);
if ($this->flags & self::FLAG_NUMBER_NEGATIVE) {
$ret = str_replace('-', '', $this->token);
$ret = -hexdec($ret);
} else {
$ret = hexdec($ret);
Expand Down
4 changes: 4 additions & 0 deletions tests/Misc/BugsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ public function testBug(string $test): void
public function bugProvider(): array
{
return [
['bugs/fuzz1'],
['bugs/fuzz2'],
['bugs/fuzz3'],
['bugs/fuzz4'],
['bugs/gh9'],
['bugs/gh14'],
['bugs/gh16'],
Expand Down
1 change: 1 addition & 0 deletions tests/data/bugs/fuzz1.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER..2
94 changes: 94 additions & 0 deletions tests/data/bugs/fuzz1.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"query": "ALTER..2",
"lexer": {
"@type": "PhpMyAdmin\\SqlParser\\Lexer",
"str": "ALTER..2",
"len": 8,
"last": 8,
"list": {
"@type": "PhpMyAdmin\\SqlParser\\TokensList",
"tokens": [
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "ALTER",
"value": "ALTER",
"keyword": "ALTER",
"type": 1,
"flags": 3,
"position": 0
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": ".",
"value": ".",
"keyword": null,
"type": 2,
"flags": 16,
"position": 5
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": ".2",
"value": 0.2,
"keyword": null,
"type": 6,
"flags": 2,
"position": 6
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": null,
"value": null,
"keyword": null,
"type": 9,
"flags": 0,
"position": null
}
],
"count": 4,
"idx": 4
},
"delimiter": ";",
"delimiterLen": 1,
"strict": false,
"errors": []
},
"parser": {
"@type": "PhpMyAdmin\\SqlParser\\Parser",
"list": {
"@type": "@1"
},
"statements": [
{
"@type": "PhpMyAdmin\\SqlParser\\Statements\\AlterStatement",
"table": null,
"altered": [],
"options": null,
"first": 0,
"last": 0
}
],
"brackets": 0,
"strict": false,
"errors": []
},
"errors": {
"lexer": [],
"parser": [
[
"Unrecognized alter operation.",
{
"@type": "@2"
},
0
],
[
"Unexpected beginning of statement.",
{
"@type": "@4"
},
0
]
]
}
}
1 change: 1 addition & 0 deletions tests/data/bugs/fuzz2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WITH](
111 changes: 111 additions & 0 deletions tests/data/bugs/fuzz2.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"query": "WITH](",
"lexer": {
"@type": "PhpMyAdmin\\SqlParser\\Lexer",
"str": "WITH](",
"len": 6,
"last": 6,
"list": {
"@type": "PhpMyAdmin\\SqlParser\\TokensList",
"tokens": [
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "WITH",
"value": "WITH",
"keyword": "WITH",
"type": 1,
"flags": 3,
"position": 0
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "]",
"value": "]",
"keyword": null,
"type": 0,
"flags": 0,
"position": 4
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": "(",
"value": "(",
"keyword": null,
"type": 2,
"flags": 16,
"position": 5
},
{
"@type": "PhpMyAdmin\\SqlParser\\Token",
"token": null,
"value": null,
"keyword": null,
"type": 9,
"flags": 0,
"position": null
}
],
"count": 4,
"idx": 4
},
"delimiter": ";",
"delimiterLen": 1,
"strict": false,
"errors": []
},
"parser": {
"@type": "PhpMyAdmin\\SqlParser\\Parser",
"list": {
"@type": "@1"
},
"statements": [
{
"@type": "PhpMyAdmin\\SqlParser\\Statements\\WithStatement",
"withers": [],
"cteStatementParser": null,
"options": {
"@type": "PhpMyAdmin\\SqlParser\\Components\\OptionsArray",
"options": []
},
"first": 0,
"last": 0
}
],
"brackets": 1,
"strict": false,
"errors": []
},
"errors": {
"lexer": [
[
"Unexpected character.",
"]",
4,
0
]
],
"parser": [
[
"The name of the CTE was expected.",
{
"@type": "@3"
},
0
],
[
"Unexpected end of the WITH CTE.",
{
"@type": "@3"
},
0
],
[
"Unexpected beginning of statement.",
{
"@type": "@3"
},
0
]
]
}
}
1 change: 1 addition & 0 deletions tests/data/bugs/fuzz3.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WITH*/A(
Loading

0 comments on commit 445804d

Please sign in to comment.