Skip to content

Commit

Permalink
Merge #287 - Fix #285 - Fixing conflict in lexer when '*/*' was in a …
Browse files Browse the repository at this point in the history
…query.

Pull-request: #287
Fixes: #285

Signed-off-by: William Desportes <williamdes@wdes.fr>
  • Loading branch information
williamdes committed Feb 10, 2020
2 parents 7148669 + 101e0b0 commit 6b42052
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 6 deletions.
20 changes: 15 additions & 5 deletions src/Context.php
Expand Up @@ -336,18 +336,28 @@ public static function isComment($str, $end = false)
if ($len === 0) {
return null;
}

// If comment is Bash style (#):
if ($str[0] === '#') {
return Token::FLAG_COMMENT_BASH;
} elseif (($len > 1) && ($str[0] === '/') && ($str[1] === '*')) {
return (($len > 2) && ($str[2] === '!')) ?
}
// If comment is opening C style (/*), warning, it could be a MySQL command (/*!)
if (($len > 1) && ($str[0] === '/') && ($str[1] === '*')) {
return ($len > 2) && ($str[2] === '!') ?
Token::FLAG_COMMENT_MYSQL_CMD : Token::FLAG_COMMENT_C;
} elseif (($len > 1) && ($str[0] === '*') && ($str[1] === '/')) {
}
// If comment is closing C style (*/), warning, it could conflicts with wildcard and a real opening C style.
// It would looks like the following valid SQL statement: "SELECT */* comment */ FROM...".
if (($len > 1) && ($str[0] === '*') && ($str[1] === '/')) {
return Token::FLAG_COMMENT_C;
} elseif (($len > 2) && ($str[0] === '-')
}
// If comment is SQL style (--\s?):
if (($len > 2) && ($str[0] === '-')
&& ($str[1] === '-') && static::isWhitespace($str[2])
) {
return Token::FLAG_COMMENT_SQL;
} elseif (($len === 2) && $end && ($str[0] === '-') && ($str[1] === '-')) {
}
if (($len === 2) && $end && ($str[0] === '-') && ($str[1] === '-')) {
return Token::FLAG_COMMENT_SQL;
}

Expand Down
13 changes: 13 additions & 0 deletions src/Lexer.php
Expand Up @@ -559,6 +559,19 @@ public function parseComment()
if (++$this->last < $this->len) {
$token .= $this->str[$this->last];
if (Context::isComment($token)) {
// There might be a conflict with "*" operator here, when string is "*/*".
// This can occurs in the following statements:
// - "SELECT */* comment */ FROM ..."
// - "SELECT 2*/* comment */3 AS `six`;"
$next = $this->last+1;
if (($next < $this->len) && $this->str[$next] === '*') {
// Conflict in "*/*": first "*" was not for ending a comment.
// Stop here and let other parsing method define the true behavior of that first star.
$this->last = $iBak;

return null;
}

$flags = Token::FLAG_COMMENT_C;

// This comment already ended. It may be a part of a
Expand Down
3 changes: 2 additions & 1 deletion tests/Lexer/LexerTest.php
Expand Up @@ -84,7 +84,8 @@ public function lexProvider()
array('lexer/lexWhitespace'),
array('lexer/lexLabel1'),
array('lexer/lexLabel2'),
array('lexer/lexNoLabel')
array('lexer/lexNoLabel'),
array('lexer/lexWildcardThenComment')
);
}
}
33 changes: 33 additions & 0 deletions tests/data/lexer/lexWildcardThenComment.in
@@ -0,0 +1,33 @@
SELECT */* comment */

SELECT /* comment */*

SELECT 2*/* comment */3

SELECT 2/* comment */*3

SELECT */*
comment
on
multiple
lines
*/FROM

DELETE foo.*/* foo */ USING

DELETE foo.*/* foo */,bar.*/*bar*/ USING

SELECT `*`/*with comment*/ AS star_field

SELECT `*`,*/*with comment*/

DELETE a.*/*multi
line /* with C open tag
comment inside */ USING

SELECT 2*/* operator */3 + 3/* operator */*2,/* start wildcard */*/* end wildcard */

SELECT `*`/*a*/*/*b*/`*`

-- invalid queries
/* SELECT */*

0 comments on commit 6b42052

Please sign in to comment.