Skip to content

Fix #80152: odbc_execute() moves internal pointer of $params #6219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

cmb69
Copy link
Member

@cmb69 cmb69 commented Sep 26, 2020

As least intrusive fix, we separate the passed array argument.


For the "master" branch, the following fix seems to be preferable:

 ext/odbc/php_odbc.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index bfb72bcff7..a8a8042c12 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.c
@@ -991,25 +991,13 @@ PHP_FUNCTION(odbc_execute)
 			RETURN_FALSE;
 		}
 
-		zend_hash_internal_pointer_reset(pv_param_ht);
 		params = (params_t *)safe_emalloc(sizeof(params_t), result->numparams, 0);
 		for(i = 0; i < result->numparams; i++) {
 			params[i].fp = -1;
 		}
 
-		for(i = 1; i <= result->numparams; i++) {
-			if ((tmp = zend_hash_get_current_data(pv_param_ht)) == NULL) {
-				php_error_docref(NULL, E_WARNING,"Error getting parameter");
-				SQLFreeStmt(result->stmt,SQL_RESET_PARAMS);
-				for (i = 0; i < result->numparams; i++) {
-					if (params[i].fp != -1) {
-						close(params[i].fp);
-					}
-				}
-				efree(params);
-				RETURN_FALSE;
-			}
-
+		i = 1;
+		ZEND_HASH_FOREACH_VAL(pv_param_ht, tmp) {
 			otype = Z_TYPE_P(tmp);
 			if (!try_convert_to_string(tmp)) {
 				SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
@@ -1099,8 +1087,11 @@ PHP_FUNCTION(odbc_execute)
 				efree(params);
 				RETURN_FALSE;
 			}
-			zend_hash_move_forward(pv_param_ht);
-		}
+			if (i > result->numparams) {
+				break;
+			}
+			i++;
+		} ZEND_HASH_FOREACH_END();
 	}
 	/* Close cursor, needed for doing multiple selects */
 	rc = SQLFreeStmt(result->stmt, SQL_CLOSE);

As least intrusive fix, we separate the passed array argument.
@cmb69 cmb69 added the Bug label Sep 26, 2020
@cmb69
Copy link
Member Author

cmb69 commented Sep 26, 2020

The AppVeyor failure is unrelated (flaky test).

Copy link
Member

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG. Using ZEND_HASH_FOREACH_VAL is definitely preferred for master, but isn't your suggested diff missing some kind of check that the array has sufficient elements? That is, the "Error getting parameter" error condition seems to get lost.

@cmb69
Copy link
Member Author

cmb69 commented Sep 29, 2020

There is already a check immediately before the loop:

php-src/ext/odbc/php_odbc.c

Lines 1327 to 1329 in f6cda06

if ((ne = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr))) < result->numparams) {
php_error_docref(NULL, E_WARNING,"Not enough parameters (%d should be %d) given", ne, result->numparams);
RETURN_FALSE;

Isn't that sufficient?

@nikic
Copy link
Member

nikic commented Sep 29, 2020

@cmb69 Ah yes, that does look sufficient.

@php-pulls php-pulls closed this in bf5f07c Sep 29, 2020
@cmb69 cmb69 deleted the cmb/80152 branch September 29, 2020 09:38
@cmb69
Copy link
Member Author

cmb69 commented Sep 29, 2020

"master" improved with a6ecafe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants