summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--ext/mysqli/tests/bug77597.phpt27
-rw-r--r--ext/mysqlnd/mysqlnd_result.c24
3 files changed, 42 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index 3e7c589a66..2e83685ba2 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 7.3.4
+- MySQLi:
+ . Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita)
+
21 Feb 2019, PHP 7.3.3
- Core:
diff --git a/ext/mysqli/tests/bug77597.phpt b/ext/mysqli/tests/bug77597.phpt
new file mode 100644
index 0000000000..ef3cb0f952
--- /dev/null
+++ b/ext/mysqli/tests/bug77597.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #77597: mysqli_fetch_field hangs scripts
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+
+require_once("connect.inc");
+$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
+
+$mysqli->query('DROP TABLE IF EXISTS a');
+$mysqli->query('CREATE TABLE a (b int)');
+$mysqli->query('INSERT INTO a VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9)');
+
+$mysqli->real_query("SELECT * FROM a");
+
+$result = $mysqli->store_result(MYSQLI_STORE_RESULT_COPY_DATA);
+
+$field = $result->fetch_field();
+var_dump($field->name);
+
+?>
+--EXPECT--
+string(1) "b"
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c
index 201e314f7d..5e3b86e12d 100644
--- a/ext/mysqlnd/mysqlnd_result.c
+++ b/ext/mysqlnd/mysqlnd_result.c
@@ -91,7 +91,7 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RE
MYSQLND_STATS * stats,
zend_bool int_and_float_native)
{
- unsigned int i;
+ unsigned int row, field;
enum_func_status ret = PASS;
const unsigned int field_count = meta->field_count;
const uint64_t row_count = result->row_count;
@@ -106,33 +106,33 @@ MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RE
DBG_RETURN(FAIL);
}
- for (i = 0; i < result->row_count; i++) {
- /* (i / 8) & the_bit_for_i*/
- if (ZEND_BIT_TEST(initialized, i)) {
+ for (row = 0; row < result->row_count; row++) {
+ /* (row / 8) & the_bit_for_row*/
+ if (ZEND_BIT_TEST(initialized, row)) {
continue;
}
- rc = result->m.row_decoder(&result->row_buffers[i], current_row, field_count, meta->fields, int_and_float_native, stats);
+ rc = result->m.row_decoder(&result->row_buffers[row], current_row, field_count, meta->fields, int_and_float_native, stats);
if (rc != PASS) {
ret = FAIL;
break;
}
result->initialized_rows++;
- initialized[i >> 3] |= (1 << (i & 7));
- for (i = 0; i < field_count; i++) {
+ initialized[row >> 3] |= (1 << (row & 7));
+ for (field = 0; field < field_count; field++) {
/*
NULL fields are 0 length, 0 is not more than 0
String of zero size, definitely can't be the next max_length.
Thus for NULL and zero-length we are quite efficient.
*/
- if (Z_TYPE(current_row[i]) == IS_STRING) {
- const size_t len = Z_STRLEN(current_row[i]);
- if (meta->fields[i].max_length < len) {
- meta->fields[i].max_length = len;
+ if (Z_TYPE(current_row[field]) == IS_STRING) {
+ const size_t len = Z_STRLEN(current_row[field]);
+ if (meta->fields[field].max_length < len) {
+ meta->fields[field].max_length = len;
}
}
- zval_ptr_dtor_nogc(&current_row[i]);
+ zval_ptr_dtor_nogc(&current_row[field]);
}
}
mnd_efree(current_row);