Bug #28833 /*!\0*/ truncates error-msg on parse-errors
Submitted: 1 Jun 2007 11:24 Modified: 19 Jun 2007 15:26
Reporter: Jan Kneschke Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.0.44-BK OS:Any
Assigned to: Marc ALFF CPU Architecture:Any

[1 Jun 2007 11:24] Jan Kneschke
Description:
Injecting /*!\0*/ into SQL query truncates the error-msg at the location of the \0 char.

How to repeat:
> SELECT /*!\0*/ I_AM_A_SQL_PARSE_ERROR

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1

Using the same statement in the MySQL client works, as the \ is encoded to \\

#include <stdio.h>
#include <mysql.h>

#define C(x) x, sizeof(x) - 1

int exec_select(MYSQL *mysql, const char *q, size_t q_len) {
        MYSQL_RES *res;

        if (mysql_real_query(mysql, q, q_len)) {
               fprintf(stderr, "%s.%d: mysql_real_query(%s) failed: %s",
                                __FILE__, __LINE__,
                                "",
                                mysql_error(mysql));
               return 0;
        }

        if (NULL != (res = mysql_store_result(mysql))) {
                mysql_free_result(res);
        }

        return 0;
}

int main() {
        MYSQL *mysql;

        mysql = mysql_init(NULL);

        if (!mysql_real_connect(mysql, "127.0.0.1", "root", "", "", 3306, NULL, 0)) {
                fprintf(stderr, "%s.%d: mysql_real_connect() failed: %s", __FILE__, __LINE__, mysql_error(mysql));
                return -1;
        }

        exec_select(mysql, C("SELECT /*!\0*/ I_AM_A_SQL_PARSE_ERROR"));

        mysql_close(mysql);

        return 0;
}

Suggested fix:
encode non-printable characters in the error-msg
[1 Jun 2007 12:07] Valeriy Kravchuk
Thank you for a bug report. Verified just as described with latest 5.0.44-BK on Linux:

openxs@suse:~/dbs/5.0> export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`
openxs@suse:~/dbs/5.0> export CFG=/home/openxs/dbs/5.0/bin/mysql_config
openxs@suse:~/dbs/5.0> gcc -o 28833 `$CFG --cflags` -DDEBUG 28833.c `$CFG --libs`
openxs@suse:~/dbs/5.0> ./28833
28833.c.11: mysql_real_query() failed: You have an error in your SQL syntax; che
ck the manual that corresponds to your MySQL server version for the right syntax
 to use near '' at line 1openxs@suse:~/dbs/5.0>
openxs@suse:~/dbs/5.0> bin/mysql -uroot test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.0.44-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SELECT /*!\0*/ I_AM_A_SQL_PARSE_ERROR;
ERROR:
Unknown command '\0'.
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near '\0*/
I_AM_A_SQL_PARSE_ERROR' at line 1
[19 Jun 2007 15:26] Marc ALFF
This is not a bug but the expected behavior.

In the MYSQL command line client, \0 means two characters : a back quote,
followed by a digit zero.

In C, \0 is an escape sequence that means the character of value 0.

Coding :

exec_select(mysql, C("SELECT /*!\0*/ I_AM_A_SQL_PARSE_ERROR"));

in C therefore does not produce the same query.

The code should have been written as

exec_select(mysql, C("SELECT /*!\\0*/ I_AM_A_SQL_PARSE_ERROR"));

to produce the character quote followed by a digit zero.

The parser behaves correctly when finding a character of value 0,
and the error reported is as expected.