From 9f3af0b2f0b2ce4cfc86b222cf3442bc72d13f55 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Fri, 9 Aug 2024 14:33:56 +0200 Subject: [PATCH 1/4] ext/mysqli: Deprecate passing the parameter to mysqli_store_result() And deprecate the MYSQLI_STORE_RESULT_COPY_DATA constant. RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_the_second_parameter_to_mysqli_store_result --- ext/mysqli/mysqli.stub.php | 1 + ext/mysqli/mysqli_api.c | 8 ++++++++ .../tests/mysqli_store_result_buffered_c.phpt | 2 +- ext/mysqli/tests/mysqli_store_result_copy.phpt | 18 +++++++++--------- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 04d667d5b466f..167dd882b3d23 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -138,6 +138,7 @@ /** * @var int * @cvalue MYSQLI_STORE_RESULT_COPY_DATA + * @deprecated */ const MYSQLI_STORE_RESULT_COPY_DATA = UNKNOWN; diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index a10c34335719b..c6d78c005b686 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1957,6 +1957,14 @@ PHP_FUNCTION(mysqli_store_result) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_link, mysqli_link_class_entry, &flags) == FAILURE) { RETURN_THROWS(); } + + if (hasThis() && ZEND_NUM_ARGS() == 1 || ZEND_NUM_ARGS() == 2) { + zend_error(E_DEPRECATED, "Passing the $mode parameter is deprecated since 8.4, as it has been ignored since 8.1"); + if (UNEXPECTED(EG(exception))) { + RETURN_THROWS(); + } + } + MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); result = mysql_store_result(mysql->mysql); if (!result) { diff --git a/ext/mysqli/tests/mysqli_store_result_buffered_c.phpt b/ext/mysqli/tests/mysqli_store_result_buffered_c.phpt index f68d01a62dba9..18ca399af36c4 100644 --- a/ext/mysqli/tests/mysqli_store_result_buffered_c.phpt +++ b/ext/mysqli/tests/mysqli_store_result_buffered_c.phpt @@ -13,7 +13,7 @@ require_once 'skipifconnectfailure.inc'; if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) + if (!is_object($res = mysqli_store_result($link))) printf("[004] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/mysqli_store_result_copy.phpt b/ext/mysqli/tests/mysqli_store_result_copy.phpt index 637d0895a7bfc..f04e7f20d2c7e 100644 --- a/ext/mysqli/tests/mysqli_store_result_copy.phpt +++ b/ext/mysqli/tests/mysqli_store_result_copy.phpt @@ -18,7 +18,7 @@ mysqlnd.fetch_data_copy=0 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) + if (!is_object($res = mysqli_store_result($link))) printf("[004] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); @@ -48,7 +48,7 @@ mysqlnd.fetch_data_copy=0 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) + if (!is_object($res = mysqli_store_result($link))) printf("[009] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); @@ -86,7 +86,7 @@ mysqlnd.fetch_data_copy=0 if (!$res = mysqli_real_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2")) printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) + if (!is_object($res = mysqli_store_result($link))) printf("[013] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); @@ -113,7 +113,7 @@ mysqlnd.fetch_data_copy=0 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) + if (!is_object($res = mysqli_store_result($link))) printf("[016] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); @@ -124,7 +124,7 @@ mysqlnd.fetch_data_copy=0 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) + if (!is_object($res = mysqli_store_result($link))) printf("[018] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); @@ -137,7 +137,7 @@ mysqlnd.fetch_data_copy=0 if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2")) printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA))) + if (!is_object($res = mysqli_store_result($link))) printf("[021] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); @@ -154,7 +154,7 @@ mysqlnd.fetch_data_copy=0 if (!$res = mysqli_real_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')")) printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA); + mysqli_store_result($link); if (mysqli_get_server_version($link) > 50000) { // let's try to play with stored procedures @@ -163,7 +163,7 @@ mysqlnd.fetch_data_copy=0 END;')) { mysqli_multi_query($link, "CALL p(@version)"); do { - if ($res = $link->store_result(MYSQLI_STORE_RESULT_COPY_DATA)) { + if ($res = $link->store_result()) { printf("---\n"); var_dump($res->fetch_all()); $res->free(); @@ -174,7 +174,7 @@ END;')) { } } while ($link->more_results() && $link->next_result()); mysqli_real_query($link, 'SELECT @version AS p_version'); - $res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA); + $res = mysqli_store_result($link); $tmp = mysqli_fetch_assoc($res); if (!is_array($tmp) || empty($tmp) || !isset($tmp['p_version']) || ('' == $tmp['p_version'])) { From ee8e339309748497455c01312012af9bc5abd7fd Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 11 Aug 2024 15:13:20 +0200 Subject: [PATCH 2/4] Fixes + review --- ext/mysqli/tests/bug77597.phpt | 2 +- .../tests/mysqli_store_result_copy.phpt | 281 ------------------ 2 files changed, 1 insertion(+), 282 deletions(-) delete mode 100644 ext/mysqli/tests/mysqli_store_result_copy.phpt diff --git a/ext/mysqli/tests/bug77597.phpt b/ext/mysqli/tests/bug77597.phpt index 406403acec771..c9ff2a994e928 100644 --- a/ext/mysqli/tests/bug77597.phpt +++ b/ext/mysqli/tests/bug77597.phpt @@ -18,7 +18,7 @@ $mysqli->query('INSERT INTO test VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9)'); $mysqli->real_query("SELECT * FROM test"); -$result = $mysqli->store_result(MYSQLI_STORE_RESULT_COPY_DATA); +$result = $mysqli->store_result(); $field = $result->fetch_field(); var_dump($field->name); diff --git a/ext/mysqli/tests/mysqli_store_result_copy.phpt b/ext/mysqli/tests/mysqli_store_result_copy.phpt deleted file mode 100644 index f04e7f20d2c7e..0000000000000 --- a/ext/mysqli/tests/mysqli_store_result_copy.phpt +++ /dev/null @@ -1,281 +0,0 @@ ---TEST-- -mysqli_store_result() ---EXTENSIONS-- -mysqli ---SKIPIF-- - ---INI-- -mysqlnd.debug="d:t:O,{TMP}/mysqlnd.trace" -mysqlnd.net_read_buffer_size=1 -mysqlnd.mempool_default_size=1 -mysqlnd.fetch_data_copy=0 ---FILE-- -fetch_assoc()); - - if (true !== ($tmp = mysqli_data_seek($res, 0))) - printf("[006] Expecting boolean/true, got %s/%s. [%d] %s\n", - gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); - - while ($row = $res->fetch_assoc()) { - printf("id = %d, label = %s\n", $row['id'], $row['label']); - } - - mysqli_free_result($res); - mysqli_close($link); - - if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { - printf("[007] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", - $host, $user, $db, $port, $socket); - } - - - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id")) - printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!is_object($res = mysqli_store_result($link))) - printf("[009] Expecting object, got %s/%s. [%d] %s\n", - gettype($res), $res, mysqli_errno($link), mysqli_error($link)); - - $no_result = 0; - for ($i = 0; $i < 1000; $i++) { - $idx = mt_rand(-100, 100); - try { - if (true === @mysqli_data_seek($res, $idx)) { - $row = $res->fetch_assoc(); - if (!isset($row['id']) || !isset($row['label'])) { - printf("[010] Brute force seek %d returned %d\n", $idx, var_export($row, true)); - } - } else { - $no_result++; - } - } catch (\ValueError $e) { - $no_result++; - } - } - printf("No result: %d\n", $no_result); - - /* implicit free, implicit store */ - /* meta and fetch lengths code */ - if (!$res = mysqli_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2")) - printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - printf("Default\n"); - var_dump(mysqli_fetch_lengths($res)); - $fields = $res->fetch_fields(); - while ($row = $res->fetch_assoc()) { - var_dump(mysqli_fetch_lengths($res)); - } - var_dump(mysqli_fetch_lengths($res)); - - if (!$res = mysqli_real_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2")) - printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!is_object($res = mysqli_store_result($link))) - printf("[013] Expecting object, got %s/%s. [%d] %s\n", - gettype($res), $res, mysqli_errno($link), mysqli_error($link)); - - printf("Copy\n"); - var_dump(mysqli_fetch_lengths($res)); - $fields_copy = $res->fetch_fields(); - while ($row = $res->fetch_assoc()) { - var_dump(mysqli_fetch_lengths($res)); - } - var_dump(mysqli_fetch_lengths($res)); - - /* There's no need for in-depth testing here. If you want in-depth switch mysqlnd - globally to copy mode and run all the tests */ - foreach ($fields as $k => $field_info) { - if ($fields_copy[$k] != $field_info) { - printf("[014] Metadata seems to differ, dumping\n"); - var_dump($field_info); - var_dump($fields_copy[$k]); - } - } - - /* fetch all */ - - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) - printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!is_object($res = mysqli_store_result($link))) - printf("[016] Expecting object, got %s/%s. [%d] %s\n", - gettype($res), $res, mysqli_errno($link), mysqli_error($link)); - - foreach (mysqli_fetch_all($res, MYSQLI_ASSOC) as $row) { - printf("id = %d label = %s\n", $row['id'], $row['label']); - } - - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) - printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!is_object($res = mysqli_store_result($link))) - printf("[018] Expecting object, got %s/%s. [%d] %s\n", - gettype($res), $res, mysqli_errno($link), mysqli_error($link)); - - /* provoke out of sync */ - if (!mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2")) - printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - var_dump($res->fetch_assoc()); - - if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2")) - printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - if (!is_object($res = mysqli_store_result($link))) - printf("[021] Expecting object, got %s/%s. [%d] %s\n", - gettype($res), $res, mysqli_errno($link), mysqli_error($link)); - - /* user conn killed, res associated with conn, fetch from res */ - unset($link); - var_dump($res->fetch_assoc()); - - - if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { - printf("[022] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", - $host, $user, $db, $port, $socket); - } - - if (!$res = mysqli_real_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')")) - printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - mysqli_store_result($link); - - if (mysqli_get_server_version($link) > 50000) { - // let's try to play with stored procedures - mysqli_real_query($link, 'DROP PROCEDURE IF EXISTS p'); - if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) READS SQL DATA BEGIN SELECT id FROM test WHERE id >= 100 ORDER BY id; SELECT id + 1, label FROM test WHERE id > 0 AND id < 3 ORDER BY id; SELECT VERSION() INTO ver_param; -END;')) { - mysqli_multi_query($link, "CALL p(@version)"); - do { - if ($res = $link->store_result()) { - printf("---\n"); - var_dump($res->fetch_all()); - $res->free(); - } else { - if ($link->errno) { - echo "Store failed: (" . $link->errno . ") " . $link->error; - } - } - } while ($link->more_results() && $link->next_result()); - mysqli_real_query($link, 'SELECT @version AS p_version'); - $res = mysqli_store_result($link); - - $tmp = mysqli_fetch_assoc($res); - if (!is_array($tmp) || empty($tmp) || !isset($tmp['p_version']) || ('' == $tmp['p_version'])) { - printf("[024] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - var_dump($tmp); - } - - mysqli_free_result($res); - } else { - printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } - } - - print "done!"; -?> ---CLEAN-- - ---EXPECTF-- -array(2) { - ["id"]=> - string(1) "3" - ["label"]=> - string(1) "c" -} -id = 1, label = a -id = 2, label = b -id = 3, label = c -id = 4, label = d -id = 5, label = e -id = 6, label = f -No result: %d -Default -bool(false) -array(2) { - [0]=> - int(2) - [1]=> - int(1) -} -array(2) { - [0]=> - int(2) - [1]=> - int(1) -} -bool(false) -Copy -bool(false) -array(2) { - [0]=> - int(2) - [1]=> - int(1) -} -array(2) { - [0]=> - int(2) - [1]=> - int(1) -} -bool(false) -id = 6 label = f -id = 5 label = e -array(2) { - ["id"]=> - string(1) "6" - ["label"]=> - string(1) "f" -} -[020] [2014] %s -array(2) { - ["id"]=> - string(1) "6" - ["label"]=> - string(1) "f" -} ---- -array(1) { - [0]=> - array(1) { - [0]=> - string(3) "100" - } -} ---- -array(2) { - [0]=> - array(2) { - [0]=> - string(1) "2" - [1]=> - string(1) "a" - } - [1]=> - array(2) { - [0]=> - string(1) "3" - [1]=> - string(1) "b" - } -} -done! From e0fb31c88ff1be839efbc78577551c873c25cd8b Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 11 Aug 2024 15:15:56 +0200 Subject: [PATCH 3/4] NEWS/UPGRADING --- NEWS | 3 +++ UPGRADING | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 25c0abf74a322..1656b8bba2683 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,9 @@ PHP NEWS . The mysqli_refresh() function and mysqli::refresh() method are now deprecated. If this functionality is needed a SQL "FLUSH" command can be used instead. (Kamil Tekiela) + . Passing explicitly the $mode parameter to mysqli_store_result() has been + deprecated. As the MYSQLI_STORE_RESULT_COPY_DATA constant was only used in + conjunction with this function it has also been deprecated. (Girgias) - PHPDBG: . array out of bounds, stack overflow handled for segfault handler on windows. diff --git a/UPGRADING b/UPGRADING index c0ecc518b0701..544a25c6fbeb8 100644 --- a/UPGRADING +++ b/UPGRADING @@ -457,6 +457,10 @@ PHP 8.4 UPGRADE NOTES . The mysqli_refresh() function and mysqli::refresh() method are now deprecated. If this functionality is needed a SQL "FLUSH" command can be used instead. RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_mysqli_refresh + . Passing explicitly the $mode parameter to mysqli_store_result() has been + deprecated. As the MYSQLI_STORE_RESULT_COPY_DATA constant was only used in + conjunction with this function it has also been deprecated. + RFC: https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_the_second_parameter_to_mysqli_store_result - PDO_PGSQL: . Using escaped question marks (??) inside dollar-quoted strings is deprecated. From 35ec9ef6c89943248a1df3678de77b0606a67245 Mon Sep 17 00:00:00 2001 From: Gina Peter Bnayard Date: Sun, 11 Aug 2024 15:55:39 +0200 Subject: [PATCH 4/4] fix --- ext/mysqli/mysqli_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index c6d78c005b686..0a153087923e8 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1958,7 +1958,7 @@ PHP_FUNCTION(mysqli_store_result) RETURN_THROWS(); } - if (hasThis() && ZEND_NUM_ARGS() == 1 || ZEND_NUM_ARGS() == 2) { + if ((hasThis() && ZEND_NUM_ARGS() == 1) || ZEND_NUM_ARGS() == 2) { zend_error(E_DEPRECATED, "Passing the $mode parameter is deprecated since 8.4, as it has been ignored since 8.1"); if (UNEXPECTED(EG(exception))) { RETURN_THROWS();