From fbb32ebb50e1540296b1f161f25f29acd2edad1f Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 21:28:23 +0200 Subject: [PATCH 01/12] First commit to fix line endings and extra spaces on the end of a line. So these changes don't polute the pull request --- ext/pdo/pdo_dbh.c | 110 +++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index c7d7e0774ff8c..d260cdf1341ff 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -52,7 +52,7 @@ void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate return; #endif } - + if (stmt) { pdo_err = &stmt->error_code; } @@ -82,7 +82,7 @@ void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate zend_update_property_string(def_ex, ex, "message", sizeof("message")-1, message TSRMLS_CC); zend_update_property_string(def_ex, ex, "code", sizeof("code")-1, *pdo_err TSRMLS_CC); - + MAKE_STD_ZVAL(info); array_init(info); @@ -94,7 +94,7 @@ void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate zend_throw_exception_object(ex TSRMLS_CC); } - + if (message) { efree(message); } @@ -113,7 +113,7 @@ PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ if (dbh == NULL || dbh->error_mode == PDO_ERRMODE_SILENT) { return; } - + if (stmt) { pdo_err = &stmt->error_code; } @@ -129,14 +129,14 @@ PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ array_init(info); add_next_index_string(info, *pdo_err, 1); - + if (dbh->methods->fetch_err(dbh, stmt, info TSRMLS_CC)) { zval **item; if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(info), 1, (void**)&item)) { native_code = Z_LVAL_PP(item); } - + if (SUCCESS == zend_hash_index_find(Z_ARRVAL_P(info), 2, (void**)&item)) { supp = estrndup(Z_STRVAL_PP(item), Z_STRLEN_PP(item)); } @@ -160,7 +160,7 @@ PDO_API void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ zend_update_property_string(def_ex, ex, "message", sizeof("message")-1, message TSRMLS_CC); zend_update_property_string(def_ex, ex, "code", sizeof("code")-1, *pdo_err TSRMLS_CC); - + if (info) { zend_update_property(pdo_ex, ex, "errorInfo", sizeof("errorInfo")-1, info TSRMLS_CC); } @@ -236,7 +236,7 @@ static PHP_METHOD(PDO, dbh_constructor) data_source = ini_dsn; colon = strchr(data_source, ':'); - + if (!colon) { zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source name (via INI: %s)", alt_dsn); ZVAL_NULL(object); @@ -269,7 +269,7 @@ static PHP_METHOD(PDO, dbh_constructor) ZVAL_NULL(object); return; } - + dbh = (pdo_dbh_t *) zend_object_store_get_object(object TSRMLS_CC); /* is this supposed to be a persistent connection ? */ @@ -342,7 +342,7 @@ static PHP_METHOD(PDO, dbh_constructor) if (pdbh) { /* let's copy the emalloc bits over from the other handle */ if (pdbh->std.properties) { - zend_hash_destroy(dbh->std.properties); + zend_hash_destroy(dbh->std.properties); efree(dbh->std.properties); if (dbh->std.properties_table) { efree(dbh->std.properties_table); @@ -366,14 +366,14 @@ static PHP_METHOD(PDO, dbh_constructor) efree(hashkey); } } - + if (call_factory) { dbh->data_source_len = strlen(colon + 1); dbh->data_source = (const char*)pestrdup(colon + 1, is_persistent); dbh->username = username ? pestrdup(username, is_persistent) : NULL; dbh->password = password ? pestrdup(password, is_persistent) : NULL; dbh->default_fetch_type = PDO_FETCH_BOTH; - } + } dbh->auto_commit = pdo_attr_lval(options, PDO_ATTR_AUTOCOMMIT, 1 TSRMLS_CC); @@ -412,11 +412,11 @@ static PHP_METHOD(PDO, dbh_constructor) zval **attr_value; char *str_key; ulong long_key; - + zend_hash_internal_pointer_reset(Z_ARRVAL_P(options)); - while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(options), (void**)&attr_value) + while (SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(options), (void**)&attr_value) && HASH_KEY_IS_LONG == zend_hash_get_current_key(Z_ARRVAL_P(options), &str_key, &long_key, 0)) { - + pdo_dbh_attribute_set(dbh, long_key, *attr_value TSRMLS_CC); zend_hash_move_forward(Z_ARRVAL_P(options)); } @@ -448,12 +448,12 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry object_init_ex(object, dbstmt_ce); Z_SET_REFCOUNT_P(object, 1); Z_SET_ISREF_P(object); - + return object; } /* }}} */ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args TSRMLS_DC) /* {{{ */ -{ +{ zval *query_string; zval z_key; @@ -492,7 +492,7 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry } else if (retval) { zval_ptr_dtor(&retval); } - + if (fci.params) { efree(fci.params); } @@ -515,7 +515,7 @@ static PHP_METHOD(PDO, prepare) &statement_len, &options)) { RETURN_FALSE; } - + PDO_DBH_CLEAR_ERR(); PDO_CONSTRUCT_CHECK; @@ -524,7 +524,7 @@ static PHP_METHOD(PDO, prepare) || Z_TYPE_PP(item) != IS_STRING || zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE ) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); " "the classname must be a string specifying an existing class" TSRMLS_CC); @@ -533,20 +533,20 @@ static PHP_METHOD(PDO, prepare) } dbstmt_ce = *pce; if (!instanceof_function(dbstmt_ce, pdo_dbstmt_ce TSRMLS_CC)) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "user-supplied statement class must be derived from PDOStatement" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } if (dbstmt_ce->constructor && !(dbstmt_ce->constructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED))) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "user-supplied statement class cannot have a public constructor" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } if (zend_hash_index_find(Z_ARRVAL_PP(opt), 1, (void**)&item) == SUCCESS) { if (Z_TYPE_PP(item) != IS_ARRAY) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "PDO::ATTR_STATEMENT_CLASS requires format array(classname, ctor_args); " "ctor_args must be an array" TSRMLS_CC); @@ -563,14 +563,14 @@ static PHP_METHOD(PDO, prepare) } if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, ctor_args TSRMLS_CC)) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "failed to instantiate user-supplied statement class" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } stmt = (pdo_stmt_t*)zend_object_store_get_object(return_value TSRMLS_CC); - + /* unconditionally keep this for later reference */ stmt->query_string = estrndup(statement, statement_len); stmt->query_stringlen = statement_len; @@ -612,7 +612,7 @@ static PHP_METHOD(PDO, beginTransaction) zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "There is already an active transaction"); RETURN_FALSE; } - + if (!dbh->methods->begin) { /* TODO: this should be an exception; see the auto-commit mode * comments below */ @@ -650,7 +650,7 @@ static PHP_METHOD(PDO, commit) dbh->in_txn = 0; RETURN_TRUE; } - + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } @@ -676,7 +676,7 @@ static PHP_METHOD(PDO, rollBack) dbh->in_txn = 0; RETURN_TRUE; } - + PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } @@ -695,7 +695,7 @@ static PHP_METHOD(PDO, inTransaction) if (!dbh->methods->in_transaction) { RETURN_BOOL(dbh->in_txn); - } + } RETURN_BOOL(dbh->methods->in_transaction(dbh TSRMLS_CC)); } @@ -775,14 +775,14 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D convert_to_long(value); dbh->stringify = Z_LVAL_P(value) ? 1 : 0; return SUCCESS; - + case PDO_ATTR_STATEMENT_CLASS: { /* array(string classname, array(mixed ctor_args)) */ zend_class_entry **pce; zval **item; if (dbh->is_persistent) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "PDO::ATTR_STATEMENT_CLASS cannot be used with persistent PDO instances" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); @@ -793,7 +793,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D || Z_TYPE_PP(item) != IS_STRING || zend_lookup_class(Z_STRVAL_PP(item), Z_STRLEN_PP(item), &pce TSRMLS_CC) == FAILURE ) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); " "the classname must be a string specifying an existing class" TSRMLS_CC); @@ -801,13 +801,13 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D return FAILURE; } if (!instanceof_function(*pce, pdo_dbstmt_ce TSRMLS_CC)) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "user-supplied statement class must be derived from PDOStatement" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); return FAILURE; } if ((*pce)->constructor && !((*pce)->constructor->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED))) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "user-supplied statement class cannot have a public constructor" TSRMLS_CC); PDO_HANDLE_DBH_ERR(); return FAILURE; @@ -819,7 +819,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D } if (zend_hash_index_find(Z_ARRVAL_P(value), 1, (void**)&item) == SUCCESS) { if (Z_TYPE_PP(item) != IS_ARRAY) { - pdo_raise_impl_error(dbh, NULL, "HY000", + pdo_raise_impl_error(dbh, NULL, "HY000", "PDO::ATTR_STATEMENT_CLASS requires format array(classname, array(ctor_args)); " "ctor_args must be an array" TSRMLS_CC); @@ -831,7 +831,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D } return SUCCESS; } - + default: ; } @@ -856,7 +856,7 @@ static int pdo_dbh_attribute_set(pdo_dbh_t *dbh, long attr, zval *value TSRMLS_D return FAILURE; } /* }}} */ - + /* {{{ proto bool PDO::setAttribute(long attribute, mixed value) Set an attribute */ static PHP_METHOD(PDO, setAttribute) @@ -897,7 +897,7 @@ static PHP_METHOD(PDO, getAttribute) switch (attr) { case PDO_ATTR_PERSISTENT: RETURN_BOOL(dbh->is_persistent); - + case PDO_ATTR_CASE: RETURN_LONG(dbh->desired_case); @@ -922,7 +922,7 @@ static PHP_METHOD(PDO, getAttribute) RETURN_LONG(dbh->default_fetch_type); } - + if (!dbh->methods->get_attribute) { pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support getting attributes" TSRMLS_CC); RETURN_FALSE; @@ -1016,7 +1016,7 @@ static PHP_METHOD(PDO, errorCode) if (dbh->query_stmt) { RETURN_STRING(dbh->query_stmt->error_code, 1); } - + if (dbh->error_code[0] == '\0') { RETURN_NULL(); } @@ -1056,7 +1056,7 @@ static PHP_METHOD(PDO, errorInfo) if (dbh->methods->fetch_err) { dbh->methods->fetch_err(dbh, dbh->query_stmt, return_value TSRMLS_CC); } - + /** * In order to be consistent, we have to make sure we add the good amount * of nulls depending on the current number of elements. We make a simple @@ -1089,12 +1089,12 @@ static PHP_METHOD(PDO, query) zend_parse_parameters(0 TSRMLS_CC, "z|z", NULL, NULL); RETURN_FALSE; } - + if (FAILURE == zend_parse_parameters(1 TSRMLS_CC, "s", &statement, &statement_len)) { RETURN_FALSE; } - + PDO_DBH_CLEAR_ERR(); PDO_CONSTRUCT_CHECK; @@ -1103,7 +1103,7 @@ static PHP_METHOD(PDO, query) return; } stmt = (pdo_stmt_t*)zend_object_store_get_object(return_value TSRMLS_CC); - + /* unconditionally keep this for later reference */ stmt->query_string = estrndup(statement, statement_len); stmt->query_stringlen = statement_len; @@ -1166,7 +1166,7 @@ static PHP_METHOD(PDO, quote) if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, ¶mtype)) { RETURN_FALSE; } - + PDO_DBH_CLEAR_ERR(); PDO_CONSTRUCT_CHECK; if (!dbh->methods->quoter) { @@ -1208,7 +1208,7 @@ static PHP_METHOD(PDO, getAvailableDrivers) if (zend_parse_parameters_none() == FAILURE) { return; } - + array_init(return_value); zend_hash_internal_pointer_reset_ex(&pdo_driver_hash, &pos); @@ -1404,7 +1404,7 @@ void pdo_dbh_init(TSRMLS_D) memcpy(&pdo_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); pdo_dbh_object_handlers.get_method = dbh_method_get; pdo_dbh_object_handlers.compare_objects = dbh_compare; - + REGISTER_PDO_CLASS_CONST_LONG("PARAM_BOOL", (long)PDO_PARAM_BOOL); REGISTER_PDO_CLASS_CONST_LONG("PARAM_NULL", (long)PDO_PARAM_NULL); REGISTER_PDO_CLASS_CONST_LONG("PARAM_INT", (long)PDO_PARAM_INT); @@ -1462,7 +1462,7 @@ void pdo_dbh_init(TSRMLS_D) REGISTER_PDO_CLASS_CONST_LONG("ATTR_MAX_COLUMN_LEN",(long)PDO_ATTR_MAX_COLUMN_LEN); REGISTER_PDO_CLASS_CONST_LONG("ATTR_EMULATE_PREPARES",(long)PDO_ATTR_EMULATE_PREPARES); REGISTER_PDO_CLASS_CONST_LONG("ATTR_DEFAULT_FETCH_MODE",(long)PDO_ATTR_DEFAULT_FETCH_MODE); - + REGISTER_PDO_CLASS_CONST_LONG("ERRMODE_SILENT", (long)PDO_ERRMODE_SILENT); REGISTER_PDO_CLASS_CONST_LONG("ERRMODE_WARNING", (long)PDO_ERRMODE_WARNING); REGISTER_PDO_CLASS_CONST_LONG("ERRMODE_EXCEPTION", (long)PDO_ERRMODE_EXCEPTION); @@ -1474,7 +1474,7 @@ void pdo_dbh_init(TSRMLS_D) REGISTER_PDO_CLASS_CONST_LONG("NULL_NATURAL", (long)PDO_NULL_NATURAL); REGISTER_PDO_CLASS_CONST_LONG("NULL_EMPTY_STRING", (long)PDO_NULL_EMPTY_STRING); REGISTER_PDO_CLASS_CONST_LONG("NULL_TO_STRING", (long)PDO_NULL_TO_STRING); - + REGISTER_PDO_CLASS_CONST_STRING("ERR_NONE", PDO_ERR_NONE); REGISTER_PDO_CLASS_CONST_LONG("FETCH_ORI_NEXT", (long)PDO_FETCH_ORI_NEXT); @@ -1483,7 +1483,7 @@ void pdo_dbh_init(TSRMLS_D) REGISTER_PDO_CLASS_CONST_LONG("FETCH_ORI_LAST", (long)PDO_FETCH_ORI_LAST); REGISTER_PDO_CLASS_CONST_LONG("FETCH_ORI_ABS", (long)PDO_FETCH_ORI_ABS); REGISTER_PDO_CLASS_CONST_LONG("FETCH_ORI_REL", (long)PDO_FETCH_ORI_REL); - + REGISTER_PDO_CLASS_CONST_LONG("CURSOR_FWDONLY", (long)PDO_CURSOR_FWDONLY); REGISTER_PDO_CLASS_CONST_LONG("CURSOR_SCROLL", (long)PDO_CURSOR_SCROLL); @@ -1527,7 +1527,7 @@ static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) if (dbh->password) { pefree(dbh->password, dbh->is_persistent); } - + if (dbh->persistent_id) { pefree((char *)dbh->persistent_id, dbh->is_persistent); } @@ -1535,7 +1535,7 @@ static void dbh_free(pdo_dbh_t *dbh TSRMLS_DC) if (dbh->def_stmt_ctor_args) { zval_ptr_dtor(&dbh->def_stmt_ctor_args); } - + for (i = 0; i < PDO_DBH_DRIVER_METHOD_KIND__MAX; i++) { if (dbh->cls_methods[i]) { zend_hash_destroy(dbh->cls_methods[i]); @@ -1562,7 +1562,7 @@ static void pdo_dbh_free_storage(pdo_dbh_t *dbh TSRMLS_DC) dbh->methods->rollback(dbh TSRMLS_CC); dbh->in_txn = 0; } - + if (dbh->is_persistent && dbh->methods && dbh->methods->persistent_shutdown) { dbh->methods->persistent_shutdown(dbh TSRMLS_CC); } @@ -1584,10 +1584,10 @@ zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC) rebuild_object_properties(&dbh->std); dbh->refcount = 1; dbh->def_stmt_ce = pdo_dbstmt_ce; - + retval.handle = zend_objects_store_put(dbh, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbh_free_storage, NULL TSRMLS_CC); retval.handlers = &pdo_dbh_object_handlers; - + return retval; } From 127a894a123aa94151c18041c538829f3c1736dc Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 21:37:22 +0200 Subject: [PATCH 02/12] Check if the SQLSTATE error code is equal to PDO_ERR_NONE before we ask the driver. And if no error is reported skip the extra call to the driver. --- ext/pdo/pdo_dbh.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index d260cdf1341ff..bdc1817e8c74e 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1049,8 +1049,18 @@ static PHP_METHOD(PDO, errorInfo) if (dbh->query_stmt) { add_next_index_string(return_value, dbh->query_stmt->error_code, 1); + if(!strncmp(dbh->query_stmt->error_code, PDO_ERR_NONE, 5)) { + add_next_index_null(return_value); + add_next_index_null(return_value); + return; + } } else { add_next_index_string(return_value, dbh->error_code, 1); + if(!strncmp(dbh->error_code, PDO_ERR_NONE, 5)) { + add_next_index_null(return_value); + add_next_index_null(return_value); + return; + } } if (dbh->methods->fetch_err) { From dc5f869f6173778902d51c7d2ae55f1034828eae Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 21:38:00 +0200 Subject: [PATCH 03/12] Added a test to check that errorInfo is not filled with the old statement error message. --- ext/pdo/tests/bug_64172.phpt | 74 ++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 ext/pdo/tests/bug_64172.phpt diff --git a/ext/pdo/tests/bug_64172.phpt b/ext/pdo/tests/bug_64172.phpt new file mode 100644 index 0000000000000..d8facc0cb29d4 --- /dev/null +++ b/ext/pdo/tests/bug_64172.phpt @@ -0,0 +1,74 @@ +--TEST-- +PDO Common: Bug #64172 errorInfo is not properly cleaned up +--SKIPIF-- + +--FILE-- +exec("SELECT * FROM test"); +var_dump($db->errorInfo()); +echo "===GOOD===\n"; +$db->exec("SELECT 123"); +var_dump($db->errorInfo()); + +echo "===FAIL===\n"; +$db->query('SELECT * FROM test'); +var_dump($db->errorInfo()); +echo "===GOOD===\n"; +$db->query('SELECT 123'); +var_dump($db->errorInfo()); +?> +===DONE=== +--EXPECTF-- +===FAIL=== + +Warning: PDO::exec(): SQLSTATE[HY000]: General error: 1 no such table: test in /home/danielp/phpwork/php-src5/ext/pdo/tests/bug_64172.php on line 8 +array(3) { + [0]=> + string(5) "HY000" + [1]=> + int(1) + [2]=> + string(19) "no such table: test" +} +===GOOD=== +array(3) { + [0]=> + string(5) "00000" + [1]=> + NULL + [2]=> + NULL +} +===FAIL=== + +Warning: PDO::query(): SQLSTATE[HY000]: General error: 1 no such table: test in /home/danielp/phpwork/php-src5/ext/pdo/tests/bug_64172.php on line 15 +array(3) { + [0]=> + string(5) "HY000" + [1]=> + int(1) + [2]=> + string(19) "no such table: test" +} +===GOOD=== +array(3) { + [0]=> + string(5) "00000" + [1]=> + NULL + [2]=> + NULL +} +===DONE=== \ No newline at end of file From 3a9e2395ae3cc9c946cde9f9af4709eb9aaa328f Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 21:38:48 +0200 Subject: [PATCH 04/12] Added a test to check that errorInfo is not filled with the old statement error message. --- ext/pdo/pdo_dbh.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index bdc1817e8c74e..43966bd0ef837 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1049,24 +1049,17 @@ static PHP_METHOD(PDO, errorInfo) if (dbh->query_stmt) { add_next_index_string(return_value, dbh->query_stmt->error_code, 1); - if(!strncmp(dbh->query_stmt->error_code, PDO_ERR_NONE, 5)) { - add_next_index_null(return_value); - add_next_index_null(return_value); - return; - } + if(!strncmp(dbh->error_code, PDO_ERR_NONE, 5)) goto fill_array; } else { add_next_index_string(return_value, dbh->error_code, 1); - if(!strncmp(dbh->error_code, PDO_ERR_NONE, 5)) { - add_next_index_null(return_value); - add_next_index_null(return_value); - return; - } + if(!strncmp(dbh->error_code, PDO_ERR_NONE, 5)) goto fill_array; } if (dbh->methods->fetch_err) { dbh->methods->fetch_err(dbh, dbh->query_stmt, return_value TSRMLS_CC); } +fill_array: /** * In order to be consistent, we have to make sure we add the good amount * of nulls depending on the current number of elements. We make a simple From d4e8d33418fc6dc45b8dff6c3bcbb2b237c0f9a7 Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 21:55:19 +0200 Subject: [PATCH 05/12] Removed local path from test --- ext/pdo/tests/bug_64172.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/pdo/tests/bug_64172.phpt b/ext/pdo/tests/bug_64172.phpt index d8facc0cb29d4..841226e0d9c80 100644 --- a/ext/pdo/tests/bug_64172.phpt +++ b/ext/pdo/tests/bug_64172.phpt @@ -33,7 +33,7 @@ var_dump($db->errorInfo()); --EXPECTF-- ===FAIL=== -Warning: PDO::exec(): SQLSTATE[HY000]: General error: 1 no such table: test in /home/danielp/phpwork/php-src5/ext/pdo/tests/bug_64172.php on line 8 +Warning: PDO::exec(): SQLSTATE[HY000]: General error: 1 no such table: test in %s on line %d array(3) { [0]=> string(5) "HY000" @@ -53,7 +53,7 @@ array(3) { } ===FAIL=== -Warning: PDO::query(): SQLSTATE[HY000]: General error: 1 no such table: test in /home/danielp/phpwork/php-src5/ext/pdo/tests/bug_64172.php on line 15 +Warning: PDO::query(): SQLSTATE[HY000]: General error: 1 no such table: test in %s on line %d array(3) { [0]=> string(5) "HY000" From e0a28fd1032576dc90df3d2105cdef87466dcb8b Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 21:56:03 +0200 Subject: [PATCH 06/12] Changed to use size of PDO_ERR_NONE instead of hardcoded value. --- ext/pdo/pdo_dbh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 43966bd0ef837..1eebbe92e2340 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1049,10 +1049,10 @@ static PHP_METHOD(PDO, errorInfo) if (dbh->query_stmt) { add_next_index_string(return_value, dbh->query_stmt->error_code, 1); - if(!strncmp(dbh->error_code, PDO_ERR_NONE, 5)) goto fill_array; + if(!strncmp(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE))) goto fill_array; } else { add_next_index_string(return_value, dbh->error_code, 1); - if(!strncmp(dbh->error_code, PDO_ERR_NONE, 5)) goto fill_array; + if(!strncmp(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE))) goto fill_array; } if (dbh->methods->fetch_err) { From ea987c9d75a7df3ebf12e40bb1ab3f472f1099df Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 22:44:17 +0200 Subject: [PATCH 07/12] Make tests more generic so we don't fail on different driver messages. --- ext/pdo/tests/bug_64172.phpt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/pdo/tests/bug_64172.phpt b/ext/pdo/tests/bug_64172.phpt index 841226e0d9c80..c8f111fd3c953 100644 --- a/ext/pdo/tests/bug_64172.phpt +++ b/ext/pdo/tests/bug_64172.phpt @@ -33,14 +33,14 @@ var_dump($db->errorInfo()); --EXPECTF-- ===FAIL=== -Warning: PDO::exec(): SQLSTATE[HY000]: General error: 1 no such table: test in %s on line %d +Warning: PDO::exec(): SQLSTATE[%s]: %s array(3) { [0]=> - string(5) "HY000" + string(5) "%s" [1]=> int(1) [2]=> - string(19) "no such table: test" + string(%d) "%s" } ===GOOD=== array(3) { @@ -53,14 +53,14 @@ array(3) { } ===FAIL=== -Warning: PDO::query(): SQLSTATE[HY000]: General error: 1 no such table: test in %s on line %d +Warning: PDO::query(): SQLSTATE[%s]: %s array(3) { [0]=> - string(5) "HY000" + string(5) "%s" [1]=> int(1) [2]=> - string(19) "no such table: test" + string(%d) "%s" } ===GOOD=== array(3) { From b7b5b1c99c8be0bc2782a7c8190cc60e9ac41629 Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sat, 26 Sep 2015 23:43:44 +0200 Subject: [PATCH 08/12] More changes to test so it is even more generic --- ext/pdo/tests/bug_64172.phpt | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/ext/pdo/tests/bug_64172.phpt b/ext/pdo/tests/bug_64172.phpt index c8f111fd3c953..9e3776b4b22f8 100644 --- a/ext/pdo/tests/bug_64172.phpt +++ b/ext/pdo/tests/bug_64172.phpt @@ -17,14 +17,18 @@ $db = PDOTest::factory(); echo "===FAIL===\n"; $db->exec("SELECT * FROM test"); -var_dump($db->errorInfo()); +var_dump(is_string($db->errorInfo()[0])) . "\n"; +var_dump(is_int($db->errorInfo()[1])) . "\n"; +var_dump(is_string($db->errorInfo()[2])) . "\n"; echo "===GOOD===\n"; $db->exec("SELECT 123"); var_dump($db->errorInfo()); echo "===FAIL===\n"; $db->query('SELECT * FROM test'); -var_dump($db->errorInfo()); +var_dump(is_string($db->errorInfo()[0])) . "\n"; +var_dump(is_int($db->errorInfo()[1])) . "\n"; +var_dump(is_string($db->errorInfo()[2])) . "\n"; echo "===GOOD===\n"; $db->query('SELECT 123'); var_dump($db->errorInfo()); @@ -34,14 +38,9 @@ var_dump($db->errorInfo()); ===FAIL=== Warning: PDO::exec(): SQLSTATE[%s]: %s -array(3) { - [0]=> - string(5) "%s" - [1]=> - int(1) - [2]=> - string(%d) "%s" -} +bool(true) +bool(true) +bool(true) ===GOOD=== array(3) { [0]=> @@ -54,14 +53,9 @@ array(3) { ===FAIL=== Warning: PDO::query(): SQLSTATE[%s]: %s -array(3) { - [0]=> - string(5) "%s" - [1]=> - int(1) - [2]=> - string(%d) "%s" -} +bool(true) +bool(true) +bool(true) ===GOOD=== array(3) { [0]=> From 016bcf2933cb3606c380a36f9640e44d5e8e680a Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sun, 27 Sep 2015 06:31:09 +0200 Subject: [PATCH 09/12] Fixing copy/paste bug --- ext/pdo/pdo_dbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 1eebbe92e2340..9e085abd14ee4 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1049,7 +1049,7 @@ static PHP_METHOD(PDO, errorInfo) if (dbh->query_stmt) { add_next_index_string(return_value, dbh->query_stmt->error_code, 1); - if(!strncmp(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE))) goto fill_array; + if(!strncmp(dbh->query_stmt->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE))) goto fill_array; } else { add_next_index_string(return_value, dbh->error_code, 1); if(!strncmp(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE))) goto fill_array; From 95f589007244ea185e395739023ecd5a992cc1ff Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sun, 27 Sep 2015 06:32:03 +0200 Subject: [PATCH 10/12] Changed test to run on more different drivers. mysql, pgsql and sqlite tested --- ext/pdo/tests/bug_64172.phpt | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ext/pdo/tests/bug_64172.phpt b/ext/pdo/tests/bug_64172.phpt index 9e3776b4b22f8..c4ef6b0406191 100644 --- a/ext/pdo/tests/bug_64172.phpt +++ b/ext/pdo/tests/bug_64172.phpt @@ -15,29 +15,37 @@ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $db = PDOTest::factory(); + echo "===FAIL===\n"; -$db->exec("SELECT * FROM test"); +$db->query('SELECT * FROM bad_table'); +echo "\n"; +echo "===TEST===\n"; var_dump(is_string($db->errorInfo()[0])) . "\n"; var_dump(is_int($db->errorInfo()[1])) . "\n"; var_dump(is_string($db->errorInfo()[2])) . "\n"; echo "===GOOD===\n"; -$db->exec("SELECT 123"); +$stmt = $db->query('SELECT 123'); +$stmt->fetchAll(); var_dump($db->errorInfo()); echo "===FAIL===\n"; -$db->query('SELECT * FROM test'); +$db->exec("SELECT * FROM bad_table"); +echo "\n"; +echo "===TEST===\n"; var_dump(is_string($db->errorInfo()[0])) . "\n"; var_dump(is_int($db->errorInfo()[1])) . "\n"; var_dump(is_string($db->errorInfo()[2])) . "\n"; echo "===GOOD===\n"; -$db->query('SELECT 123'); +$db->exec("SELECT 123"); var_dump($db->errorInfo()); ?> ===DONE=== --EXPECTF-- ===FAIL=== -Warning: PDO::exec(): SQLSTATE[%s]: %s +Warning: PDO::query(): SQLSTATE[%s]: %s +%A +===TEST=== bool(true) bool(true) bool(true) @@ -52,7 +60,9 @@ array(3) { } ===FAIL=== -Warning: PDO::query(): SQLSTATE[%s]: %s +Warning: PDO::exec(): SQLSTATE[%s]: %s +%A +===TEST=== bool(true) bool(true) bool(true) From 3ba4e7d464066630c9a02eba47d5f62f52380b7b Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Sun, 27 Sep 2015 07:47:50 +0200 Subject: [PATCH 11/12] Changed test to check for NULL returns when error code is PDO_ERR_NONE --- ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt index d5a348957fe4c..9028f0b49ff40 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_errorinfo.phpt @@ -129,8 +129,8 @@ array(3) { [0]=> %unicode|string%(5) "00000" [1]=> - int(1146) + NULL [2]=> - %unicode|string%(%d) "Table '%s.ihopeitdoesnotexist' doesn't exist" + NULL } done! From 89261b9ec5fd98e5c7864154694ac43a343a08d4 Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Mon, 5 Oct 2015 22:07:15 +0200 Subject: [PATCH 12/12] Changed to pass all tests --- ext/pdo/tests/bug_64172.phpt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ext/pdo/tests/bug_64172.phpt b/ext/pdo/tests/bug_64172.phpt index c4ef6b0406191..e8949fe597b6d 100644 --- a/ext/pdo/tests/bug_64172.phpt +++ b/ext/pdo/tests/bug_64172.phpt @@ -15,6 +15,9 @@ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $db = PDOTest::factory(); +@$db->exec("DROP TABLE test"); +$db->exec("CREATE TABLE test (x int)"); +$db->exec("INSERT INTO test VALUES (1)"); echo "===FAIL===\n"; $db->query('SELECT * FROM bad_table'); @@ -24,20 +27,23 @@ var_dump(is_string($db->errorInfo()[0])) . "\n"; var_dump(is_int($db->errorInfo()[1])) . "\n"; var_dump(is_string($db->errorInfo()[2])) . "\n"; echo "===GOOD===\n"; -$stmt = $db->query('SELECT 123'); +$stmt = $db->query('SELECT * FROM test'); $stmt->fetchAll(); +$stmt = null; var_dump($db->errorInfo()); echo "===FAIL===\n"; -$db->exec("SELECT * FROM bad_table"); +$db->exec("INSERT INTO bad_table VALUES(1)"); echo "\n"; echo "===TEST===\n"; var_dump(is_string($db->errorInfo()[0])) . "\n"; var_dump(is_int($db->errorInfo()[1])) . "\n"; var_dump(is_string($db->errorInfo()[2])) . "\n"; echo "===GOOD===\n"; -$db->exec("SELECT 123"); +$db->exec("INSERT INTO test VALUES (2)"); var_dump($db->errorInfo()); + +$db->exec("DROP TABLE test"); ?> ===DONE=== --EXPECTF--