From 0522ae6fa2324e68844c05e65ff89e1d8441efc3 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 19 Oct 2023 00:24:03 +0100 Subject: [PATCH 1/4] ext/mysqli: mysql_thread_id/mysqli_kill internal changes proposal. - Both mysql_thread_id and mysql_kill despite dealing possibly with 64 bits values operates in reality with 32 bits internally, leading to truncation. They are both deprecated and passing commands instead is advised. --- ext/mysqli/mysqli_api.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 68b55e1d78d35..41edf0b671091 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1040,9 +1040,9 @@ PHP_FUNCTION(mysqli_insert_id) /* {{{ Kill a mysql process on the server */ PHP_FUNCTION(mysqli_kill) { - MY_MYSQL *mysql; - zval *mysql_link; - zend_long processid; + MY_MYSQL *mysql; + zval *mysql_link; + zend_long processid; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) { RETURN_THROWS(); @@ -1055,7 +1055,11 @@ PHP_FUNCTION(mysqli_kill) MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); - if (mysql_kill(mysql->mysql, processid)) { + char query[64]; + snprintf(query, sizeof(query), "KILL CONNECTION " ZEND_LONG_FMT, processid); + + // 1317 is ER_QUERY_INTERRUPTED from server's side + if (mysql_real_query(mysql->mysql, query, strlen(query)) && mysql_errno(mysql->mysql) != 1317) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } @@ -1981,14 +1985,36 @@ PHP_FUNCTION(mysqli_store_result) PHP_FUNCTION(mysqli_thread_id) { MY_MYSQL *mysql; + MYSQL_RES *result; + MYSQL_ROW row; zval *mysql_link; + zend_long processid; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); - RETURN_LONG((zend_long) mysql_thread_id(mysql->mysql)); + static const char *query = "SELECT CONNECTION_ID()"; + + if (mysql_real_query(mysql->mysql, query, strlen(query))) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_LONG(-1); + } + + result = mysql_store_result(mysql->mysql); + if (!result) { + MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); + RETURN_LONG(-1); + } + + row = mysql_fetch_row(result); + processid = (zend_long)strtoll(row[0], NULL, 10); + + efree(row); + mysql_free_result(result); + + RETURN_LONG(processid); } /* }}} */ From bac062b7fb8fcfa07d19f83f7c095d718a6df8a6 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 19 Oct 2023 19:22:07 +0100 Subject: [PATCH 2/4] debugging --- ext/mysqli/mysqli_api.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 41edf0b671091..738534c92d139 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1996,16 +1996,21 @@ PHP_FUNCTION(mysqli_thread_id) MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); static const char *query = "SELECT CONNECTION_ID()"; + size_t query_len = strlen(query); - if (mysql_real_query(mysql->mysql, query, strlen(query))) { + if (mysql_ping(mysql->mysql)) { + RETURN_LONG(0); + } + + if (mysql_real_query(mysql->mysql, query, query_len)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_LONG(-1); + RETURN_THROWS(); } result = mysql_store_result(mysql->mysql); if (!result) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_LONG(-1); + RETURN_THROWS(); } row = mysql_fetch_row(result); From 115b9edd88894994c21d088d59d59b3f2bf80428 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 19 Oct 2023 22:31:21 +0100 Subject: [PATCH 3/4] using old call as fallback --- ext/mysqli/mysqli_api.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 738534c92d139..e15edd7464311 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1060,6 +1060,9 @@ PHP_FUNCTION(mysqli_kill) // 1317 is ER_QUERY_INTERRUPTED from server's side if (mysql_real_query(mysql->mysql, query, strlen(query)) && mysql_errno(mysql->mysql) != 1317) { + if (!mysql_kill(mysql->mysql, processid)) { + RETURN_TRUE; + } MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; } @@ -1998,13 +2001,8 @@ PHP_FUNCTION(mysqli_thread_id) static const char *query = "SELECT CONNECTION_ID()"; size_t query_len = strlen(query); - if (mysql_ping(mysql->mysql)) { - RETURN_LONG(0); - } - if (mysql_real_query(mysql->mysql, query, query_len)) { - MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); - RETURN_THROWS(); + goto fail; } result = mysql_store_result(mysql->mysql); @@ -2020,6 +2018,9 @@ PHP_FUNCTION(mysqli_thread_id) mysql_free_result(result); RETURN_LONG(processid); + +fail: + RETURN_LONG((zend_long)mysql_thread_id(mysql->mysql)); } /* }}} */ From 484923c39201aaf0b827b7b9d463e295d2ff393c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 20 Oct 2023 19:49:52 +0100 Subject: [PATCH 4/4] debugging --- ext/mysqli/mysqli_api.c | 11 ++++------- ext/mysqli/tests/mysqli_kill.phpt | 12 ++++++------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index e15edd7464311..a03d9282a063e 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1058,9 +1058,9 @@ PHP_FUNCTION(mysqli_kill) char query[64]; snprintf(query, sizeof(query), "KILL CONNECTION " ZEND_LONG_FMT, processid); - // 1317 is ER_QUERY_INTERRUPTED from server's side - if (mysql_real_query(mysql->mysql, query, strlen(query)) && mysql_errno(mysql->mysql) != 1317) { - if (!mysql_kill(mysql->mysql, processid)) { + if (mysql_real_query(mysql->mysql, query, strlen(query))) { + // 1317 is ER_QUERY_INTERRUPTED from server's side + if (mysql_errno(mysql->mysql) == 1317) { RETURN_TRUE; } MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); @@ -2002,7 +2002,7 @@ PHP_FUNCTION(mysqli_thread_id) size_t query_len = strlen(query); if (mysql_real_query(mysql->mysql, query, query_len)) { - goto fail; + RETURN_LONG((zend_long)mysql_thread_id(mysql->mysql)); } result = mysql_store_result(mysql->mysql); @@ -2018,9 +2018,6 @@ PHP_FUNCTION(mysqli_thread_id) mysql_free_result(result); RETURN_LONG(processid); - -fail: - RETURN_LONG((zend_long)mysql_thread_id(mysql->mysql)); } /* }}} */ diff --git a/ext/mysqli/tests/mysqli_kill.phpt b/ext/mysqli/tests/mysqli_kill.phpt index fdc068aeb6add..d7bc49f42a4fd 100644 --- a/ext/mysqli/tests/mysqli_kill.phpt +++ b/ext/mysqli/tests/mysqli_kill.phpt @@ -24,7 +24,7 @@ require_once 'skipifconnectfailure.inc'; printf("[005] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); if ($res = mysqli_query($link, "SELECT id FROM test LIMIT 1")) - pintf("[006] Expecting boolean/false, got %s/%s\n", gettype($res), $res); + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($res), $res); var_dump($error = mysqli_error($link)); if (!is_string($error) || ('' === $error)) @@ -103,11 +103,11 @@ object(mysqli)#%d (%d) { } } ["field_count"]=> - int(0) + int(1) ["host_info"]=> string(%d) "%s" ["info"]=> - %s + NULL ["insert_id"]=> int(0) ["server_info"]=> @@ -115,13 +115,13 @@ object(mysqli)#%d (%d) { ["server_version"]=> int(%d) ["sqlstate"]=> - string(5) "HY000" + string(%d) "%s" ["protocol_version"]=> - int(10) + int(%d) ["thread_id"]=> int(%d) ["warning_count"]=> - int(0) + int(%d) } mysqli_kill(): Argument #2 ($process_id) must be greater than 0 array(1) {