Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
3.4
-
None
-
None
Description
https://mariadb.com/docs/connectors/mariadb-connector-c/api-functions/mysql_escape_string is documented as deprecated and it's probably not a good idea to build with default charset utf8 nowadays, but since this is a segfault it seemed better to report anyway.
This was observed with python mysqlclient https://github.com/PyMySQL/mysqlclient/blob/v2.2.8/src/MySQLdb/_mysql.c#L1099 and a custom build (slapos) of mariadb 11.8.6 .
A minimal reproduction can be something like this:
|
|
#include <stdio.h>
|
#include <string.h>
|
#include <mysql.h>
|
|
|
int main(void) { |
if (mysql_library_init(0, NULL, NULL)) { |
fprintf(stderr, "mysql_library_init failed\n"); |
return 1; |
}
|
|
|
const char *input = "hello 'world'"; |
unsigned long input_len = strlen(input); |
char output[input_len * 2 + 1]; |
|
|
unsigned long out_len = mysql_escape_string(output, input, input_len); |
printf("Result: \"%s\" (len=%lu)\n", output, out_len); |
|
|
mysql_library_end();
|
return 0; |
}
|
|
I used LLM to generate an explanation and a possible fix, it gave me the comment below, it might be completely wrong or it might be useful, I don't know mariadb internals and history to evaluate of this makes sense.
|
|
/*
|
* Segfault reproducer for mysql_escape_string in MariaDB >= 10.6.1.
|
*
|
* MDEV-8334 (commit 2f7230c6 in libmariadb, 2fdb556e045 in server) renamed
|
* the compiled charset csname from "utf8" to "utf8mb3" and added a compat
|
* mapping in mysql_find_charset_name(), but not in mysql_get_charset_by_name().
|
*
|
* When the server build sets DEFAULT_CHARSET="utf8", mysql_once_init() calls
|
* set_default_charset_by_name("utf8") which uses mysql_get_charset_by_name().
|
* The strict strcmp("utf8", "utf8mb3") fails, so ma_default_charset_info stays
|
* NULL. mysql_once_init() ignores this error and mysql_library_init() returns
|
* success. Any subsequent call to mysql_escape_string() passes the NULL
|
* charset pointer to mysql_cset_escape_slashes(), causing a segfault.
|
*
|
* Fix: in libmariadb/libmariadb/mariadb_charset.c, change
|
* set_default_charset_by_name() to use mysql_find_charset_name() (which
|
* already maps "utf8" -> "utf8mb3") instead of mysql_get_charset_by_name().
|
*/ |