MXS-2389 Handle MariaDB comment correctly

A non version specific executable comment, such as "/*! SELECT 1; */"
is during classification handled as if it would not be a comment. That
is, the contained statement will *always* be parsed.

A version specific executable comment, such as "/*!99999 CREATE PROCEDURE
 bypass BEGIN */ SELECT ... " is during classification handled as it would
be a general comment. That is, the contained statement will *never* be
parsed.

In addition, in the latter case the parse result will never be better than
QC_QUERY_PARTIALLY_PARSED. The rationale is that since the comment is version
specific, we cannot know how the server will actually interpret the statement.

This will have an impact on the masking filter and the database firewall that
now will reject statements containing _version specific_ executable comments.
This commit is contained in:
Johan Wikman
2019-03-20 15:56:16 +02:00
parent 9b27d7f24b
commit 65b4ac7c1b
2 changed files with 38 additions and 4 deletions

View File

@ -259,10 +259,18 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
// MySQL-specific code
for (i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if (c=='*' && z[i]=='/'){
char* znc = (char*) z;
znc[0]=znc[1]=znc[2]=znc[i-1]=znc[i]=' '; // Remove comment chars, i.e. "/*!" and "*/".
for (i=3; sqlite3Isdigit(z[i]); ++i){} // Jump over the MySQL version number.
for (; sqlite3Isspace(z[i]); ++i){} // Jump over any space.
if (sqlite3Isdigit(z[3])) {
// A version specific executable comment, e.g. "/*!99999 ..." => never parsed.
extern void maxscaleSetStatusCap(int);
maxscaleSetStatusCap(2); // QC_QUERY_PARTIALLY_PARSED, see query_classifier.h:qc_parse_result
++i; // Next after the trailing '/'
}
else {
// A non-version specific executable comment, e.g. "/*! select 1 */ => always parsed.
char* znc = (char*) z;
znc[0]=znc[1]=znc[2]=znc[i-1]=znc[i]=' '; // Remove comment chars, i.e. "/*!" and "*/".
for (i=3; sqlite3Isspace(z[i]); ++i){} // Jump over any space.
}
}
} else {
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}