diff options
| -rw-r--r-- | ext/oci8/oci8_interface.c | 14 | ||||
| -rw-r--r-- | ext/oci8/package.xml | 23 | ||||
| -rw-r--r-- | ext/oci8/php_oci8.h | 2 | ||||
| -rw-r--r-- | ext/oci8/tests/bug71600.phpt | 96 |
4 files changed, 126 insertions, 9 deletions
diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index e3bd509216..bb8828b746 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -1380,15 +1380,17 @@ PHP_FUNCTION(oci_fetch_all) PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); zval_dtor(array); - array_init(array); while (skip--) { if (php_oci_statement_fetch(statement, nrows)) { + array_init(array); RETURN_LONG(0); } } if (flags & PHP_OCI_FETCHSTATEMENT_BY_ROW) { + /* Fetch by Row: array will contain one sub-array per query row */ + array_init(array); columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0); for (i = 0; i < statement->ncolumns; i++) { @@ -1398,7 +1400,7 @@ PHP_FUNCTION(oci_fetch_all) while (!php_oci_statement_fetch(statement, nrows)) { zval row; - array_init(&row); + array_init_size(&row, statement->ncolumns); for (i = 0; i < statement->ncolumns; i++) { php_oci_column_to_zval(columns[ i ], &element, PHP_OCI_RETURN_LOBS); @@ -1409,7 +1411,7 @@ PHP_FUNCTION(oci_fetch_all) zend_string *zvtmp; zvtmp = zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0); zend_symtable_update(Z_ARRVAL(row), zvtmp, &element); - zend_string_release(zvtmp); + zend_string_release(zvtmp); } } @@ -1424,6 +1426,8 @@ PHP_FUNCTION(oci_fetch_all) efree(columns); } else { /* default to BY_COLUMN */ + /* Fetch by columns: array will contain one sub-array per query column */ + array_init_size(array, statement->ncolumns); columns = safe_emalloc(statement->ncolumns, sizeof(php_oci_out_column *), 0); outarrs = safe_emalloc(statement->ncolumns, sizeof(zval*), 0); @@ -1440,9 +1444,9 @@ PHP_FUNCTION(oci_fetch_all) columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0); array_init(&tmp); - zvtmp = zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0); + zvtmp = zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0); outarrs[ i ] = zend_symtable_update(Z_ARRVAL_P(array), zvtmp, &tmp); - zend_string_release(zvtmp); + zend_string_release(zvtmp); } } diff --git a/ext/oci8/package.xml b/ext/oci8/package.xml index 6bb6f901a5..88462415cb 100644 --- a/ext/oci8/package.xml +++ b/ext/oci8/package.xml @@ -50,8 +50,8 @@ Interoperability Support" (ID 207303.1) for details. <time>12:00:00</time> <version> - <release>2.1.0</release> - <api>2.1.0</api> + <release>2.1.1</release> + <api>2.1.1</api> </version> <stability> <release>stable</release> @@ -60,7 +60,7 @@ Interoperability Support" (ID 207303.1) for details. <license uri="http://www.php.net/license">PHP</license> <notes> This version is for PHP 7 only. -Updated driver name format. +Fixed bug #71600 (oci_fetch_all segfaults when selecting more than 8 columns) </notes> <contents> <dir name="/"> @@ -162,6 +162,7 @@ Updated driver name format. <file name="bug51291_2.phpt" role="test" /> <file name="bug68298.phpt" role="test" /> <file name="bug71422.phpt" role="test" /> + <file name="bug71600.phpt" role="test" /> <file name="clientversion.phpt" role="test" /> <file name="close.phpt" role="test" /> <file name="coll_001.phpt" role="test" /> @@ -468,6 +469,22 @@ Updated driver name format. <release> <version> + <release>2.1.0</release> + <api>2.1.0</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <license uri="http://www.php.net/license">PHP</license> + <notes> +This version is for PHP 7 only. +Updated driver name format. + </notes> +</release> + +<release> + <version> <release>2.0.10</release> <api>2.0.10</api> </version> diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h index 7f1fba0353..da62aabac6 100644 --- a/ext/oci8/php_oci8.h +++ b/ext/oci8/php_oci8.h @@ -45,7 +45,7 @@ */ #undef PHP_OCI8_VERSION #endif -#define PHP_OCI8_VERSION "2.1.0" +#define PHP_OCI8_VERSION "2.1.1" extern zend_module_entry oci8_module_entry; #define phpext_oci8_ptr &oci8_module_entry diff --git a/ext/oci8/tests/bug71600.phpt b/ext/oci8/tests/bug71600.phpt new file mode 100644 index 0000000000..102c59f81a --- /dev/null +++ b/ext/oci8/tests/bug71600.phpt @@ -0,0 +1,96 @@ +--TEST-- +Bug #71600 (oci_fetch_all result in segfault when select more than 8 columns) +--SKIPIF-- +<?php +$target_dbs = array('oracledb' => true, 'timesten' => true); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +?> +--FILE-- +<?php + +require(dirname(__FILE__).'/connect.inc'); + +// Initialize + +$stmtarray = array( + "create table bug71600_tab (col1 number, col2 number, col3 number, + col4 number, col5 number, col6 number, + col7 number, col8 number, col9 number)", + "insert into bug71600_tab values(1, 2, 3, 4, 5, 6, 7, 8, 9)", + "insert into bug71600_tab values(11, 12, 13, 14, 15, 16, 17, 18, 19)" +); + +oci8_test_sql_execute($c, $stmtarray); + +// Run test + +$sql = "select col1,col2,col3,col4,col5,col6,col7,col8,col9 from bug71600_tab"; + +echo "Test 1\n"; +$stmt = oci_parse($c, $sql); + +echo "Executing SELECT statament...\n"; +oci_execute($stmt,OCI_DEFAULT); + +echo "Fetching data by columns...\n"; +oci_fetch_all($stmt, $result); +oci_free_statement($stmt); + +$rsRows=(count($result,1)/($rows = count($result,0)))-1; +echo "$rsRows Records Found\n"; +$rsCount=0; +while($rsCount < $rsRows) +{ + $col1 =$result['COL1'][$rsCount]; + $col9 =$result['COL9'][$rsCount]; + echo "$rsCount|$col1|$col9\n"; + $rsCount++; +} + +echo "Test 2\n"; +$stmt = oci_parse($c, $sql); + +echo "Re-executing SELECT statament...\n"; +oci_execute($stmt,OCI_DEFAULT); + +echo "Fetching data by rows...\n"; +oci_fetch_all($stmt, $result, 0, -1, OCI_FETCHSTATEMENT_BY_ROW); +oci_free_statement($stmt); + +$rsRows=count($result,0); +echo "$rsRows Records Found\n"; +$rsCount=0; +while($rsCount < $rsRows) +{ + $col1 = $result[$rsCount]['COL1']; + $col9 = $result[$rsCount]['COL9']; + echo "$rsCount|$col1|$col9\n"; + $rsCount++; +} + + +// Cleanup + +$stmtarray = array( + "drop table bug71600_tab" +); + +oci8_test_sql_execute($c, $stmtarray); + +?> +===DONE=== +<?php exit(0); ?> +--EXPECT-- +Test 1 +Executing SELECT statament... +Fetching data by columns... +2 Records Found +0|1|9 +1|11|19 +Test 2 +Re-executing SELECT statament... +Fetching data by rows... +2 Records Found +0|1|9 +1|11|19 +===DONE=== |
