From 007635360a3b35ac1cf211488a82f7743b89a8f5 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 15:56:59 +0300 Subject: [PATCH] db.mysql: fix malformed error messages from real_query failing to encode to json (fixes #19842) --- vlib/db/mysql/utils.c.v | 12 ++++++++++-- vlib/db/mysql/utils_test.v | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 vlib/db/mysql/utils_test.v diff --git a/vlib/db/mysql/utils.c.v b/vlib/db/mysql/utils.c.v index ea48daa3b..ca0ef215e 100644 --- a/vlib/db/mysql/utils.c.v +++ b/vlib/db/mysql/utils.c.v @@ -2,7 +2,7 @@ module mysql // get_error_msg returns error message from MySQL instance. fn get_error_msg(conn &C.MYSQL) string { - return unsafe { C.mysql_error(conn).vstring() } + return clone_mysql_cstring(C.mysql_error(conn)) } // get_errno returns error number from MySQL instance. @@ -12,7 +12,7 @@ fn get_errno(conn &C.MYSQL) int { // get_stmt_error_msg returns error message from a MySQL statement instance. fn get_stmt_error_msg(stmt &C.MYSQL_STMT) string { - return unsafe { cstring_to_vstring(&char(C.mysql_stmt_error(stmt))) } + return clone_mysql_cstring(&u8(C.mysql_stmt_error(stmt))) } // get_stmt_errno returns error number from a MySQL statement instance. @@ -20,6 +20,14 @@ fn get_stmt_errno(stmt &C.MYSQL_STMT) int { return C.mysql_stmt_errno(stmt) } +@[inline] +fn clone_mysql_cstring(ptr &u8) string { + if isnil(ptr) { + return '' + } + return unsafe { tos_clone(ptr) } +} + // resolve_nil_str returns an empty string if passed value is a nil pointer. fn resolve_nil_str(ptr &u8) string { if isnil(ptr) { diff --git a/vlib/db/mysql/utils_test.v b/vlib/db/mysql/utils_test.v new file mode 100644 index 000000000..0760ff2be --- /dev/null +++ b/vlib/db/mysql/utils_test.v @@ -0,0 +1,20 @@ +module mysql + +import json + +struct MysqlErrorPayload { + data string +} + +fn test_clone_mysql_cstring_keeps_json_encodable_error_text() { + mut backing := "Incorrect string value: 'undefined' for function uuid_to_bin; code: 1411".bytes() + backing << u8(0) + msg := clone_mysql_cstring(backing.data) + + backing[0] = 0xff + + assert msg == "Incorrect string value: 'undefined' for function uuid_to_bin; code: 1411" + assert json.encode(MysqlErrorPayload{ + data: msg + }) == '{"data":"Incorrect string value: \'undefined\' for function uuid_to_bin; code: 1411"}' +} -- 2.39.5