diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/mysqli/mysqli_api.c | 60 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_commit_oo.phpt | 55 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd.c | 59 |
4 files changed, 140 insertions, 37 deletions
@@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2014, PHP 5.5.12 +- SPL: + . Fixed problem in mysqli_commit()/mysqli_rollback() with second parameter + (extra comma) and third parameters (lack of escaping). (Andrey) ?? ??? 2014, PHP 5.5.11 diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 719dffff3d..d9e52b3d3a 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -643,24 +643,24 @@ static void mysqli_tx_cor_options_to_string(const MYSQL * const conn, smart_str { if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1); } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1); } if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1); } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1); } @@ -669,6 +669,7 @@ static void mysqli_tx_cor_options_to_string(const MYSQL * const conn, smart_str /* }}} */ + /* {{{ proto bool mysqli_commit_or_rollback_libmysql */ static int mysqli_commit_or_rollback_libmysql(MYSQL * conn, zend_bool commit, const unsigned int mode, const char * const name) { @@ -678,25 +679,60 @@ static int mysqli_commit_or_rollback_libmysql(MYSQL * conn, zend_bool commit, co smart_str_0(&tmp_str); { - char * commented_name = NULL; - unsigned int commented_name_len = name? spprintf(&commented_name, 0, " /*%s*/", name):0; char * query; - unsigned int query_len = spprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"), - commented_name? commented_name:"", tmp_str.c? tmp_str.c:""); + char * name_esc = NULL; + size_t query_len; + + if (name) { + const char * p_orig = name; + char * p_copy; + p_copy = name_esc = emalloc(strlen(name) + 1 + 2 + 2 + 1); /* space, open, close, NullS */ + *p_copy++ = ' '; + *p_copy++ = '/'; + *p_copy++ = '*'; + while (1) { + register char v = *p_orig; + if (v == 0) { + break; + } + if ((v >= '0' && v <= '9') || + (v >= 'a' && v <= 'z') || + (v >= 'A' && v <= 'Z') || + v == '-' || + v == '_' || + v == ' ' || + v == '=') + { + *p_copy = v; + } else { + *p_copy = '?'; + } + ++p_orig; + ++p_copy; + } + *p_copy++ = '*'; + *p_copy++ = '/'; + *p_copy++ = 0; + } + + query_len = spprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"), + name_esc? name_esc:"", tmp_str.c? tmp_str.c:""); smart_str_free(&tmp_str); + if (name_esc) { + efree(name_esc); + name_esc = NULL; + } ret = mysql_real_query(conn, query, query_len); efree(query); - if (commented_name) { - efree(commented_name); - } } + return ret; } /* }}} */ #endif -/* {{{ proto bool mysqli_commit(object link) +/* {{{ proto bool mysqli_commit(object link[, int flags [, string name ]]) Commit outstanding actions and close transaction */ PHP_FUNCTION(mysqli_commit) { diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt index e19f698e81..da9432facd 100644 --- a/ext/mysqli/tests/mysqli_commit_oo.phpt +++ b/ext/mysqli/tests/mysqli_commit_oo.phpt @@ -21,49 +21,78 @@ if (!have_innodb($link)) $link = NULL; $mysqli = new mysqli(); - if (!is_null($tmp = @$mysqli->commit())) + if (!is_null($tmp = @$mysqli->commit())) { printf("[013] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + } - if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); + } - if (true !== ($tmp = $mysqli->commit())) + if (true !== ($tmp = $mysqli->commit())) { printf("[002] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); + } - if (true !== ($tmp = $mysqli->autocommit(false))) + if (true !== ($tmp = $mysqli->autocommit(false))) { printf("[003] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp); + } - if (!$mysqli->query('DROP TABLE IF EXISTS test')) + if (!$mysqli->query('DROP TABLE IF EXISTS test')) { printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error); + } - if (!$mysqli->query('CREATE TABLE test(id INT) ENGINE = InnoDB')) + if (!$mysqli->query('CREATE TABLE test(id INT) ENGINE = InnoDB')) { printf("[005] Cannot create test table, [%d] %s\n", $mysqli->errno, $mysqli->error); + } - if (!$mysqli->query('INSERT INTO test(id) VALUES (1)')) + if (!$mysqli->query('INSERT INTO test(id) VALUES (1)')) { printf("[006] [%d] %s\n", $mysqli->errno, $mysqli->error); + } $tmp = $mysqli->commit(); - if ($tmp !== true) + if ($tmp !== true) { printf("[007] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); + } if (!$mysqli->query('ROLLBACK')) printf("[008] [%d] %s\n", $mysqli->errno, $mysqli->error); - if (!$res = $mysqli->query('SELECT COUNT(*) AS num FROM test')) + if (!$res = $mysqli->query('SELECT COUNT(*) AS num FROM test')) { printf("[009] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + $tmp = $res->fetch_assoc(); - if (1 != $tmp['num']) + if (1 != $tmp['num']) { printf("[010] Expecting 1 row in table test, found %d rows\n", $tmp['num']); + } $res->free(); - if (!$mysqli->query('DROP TABLE IF EXISTS test')) + if (!$mysqli->query('DROP TABLE IF EXISTS test')) { printf("[011] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + + if (!$mysqli->commit(0 , "tx_name0123")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + if (!$mysqli->commit(0 , "*/ nonsense")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + if (!$mysqli->commit(0 , "tx_name")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + if (!$mysqli->commit(0 , "tx_name")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } + if (!$mysqli->commit(MYSQLI_TRANS_COR_AND_CHAIN | MYSQLI_TRANS_COR_NO_RELEASE , "tx_name")) { + printf("[012] [%d] %s\n", $mysqli->errno, $mysqli->error); + } $mysqli->close(); - if (NULL !== ($tmp = @$mysqli->commit())) - printf("[012] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + if (NULL !== ($tmp = @$mysqli->commit())) { + printf("[013] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + } print "done!"; ?> diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 39813145ba..bbfc456896 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -2652,24 +2652,24 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string)(const MYSQLND_CONN_D { if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1); } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1); } if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1); } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) { if (str->len) { - smart_str_appendl(str, ", ", sizeof(", ") - 1); + smart_str_appendl(str, " ", sizeof(" ") - 1); } smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1); } @@ -2692,23 +2692,58 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * con conn->m->tx_cor_options_to_string(conn, &tmp_str, flags TSRMLS_CC); smart_str_0(&tmp_str); + { - char * commented_name = NULL; - unsigned int commented_name_len = name? mnd_sprintf(&commented_name, 0, " /*%s*/", name):0; char * query; - unsigned int query_len = mnd_sprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"), - commented_name? commented_name:"", tmp_str.c? tmp_str.c:""); - smart_str_free(&tmp_str); + char * name_esc = NULL; + size_t query_len; + + if (name) { + const char * p_orig = name; + char * p_copy; + p_copy = name_esc = mnd_emalloc(strlen(name) + 1 + 2 + 2 + 1); /* space, open, close, NullS */ + *p_copy++ = ' '; + *p_copy++ = '/'; + *p_copy++ = '*'; + while (1) { + register char v = *p_orig; + if (v == 0) { + break; + } + if ((v >= '0' && v <= '9') || + (v >= 'a' && v <= 'z') || + (v >= 'A' && v <= 'Z') || + v == '-' || + v == '_' || + v == ' ' || + v == '=') + { + *p_copy = v; + } else { + *p_copy = '?'; + } + ++p_orig; + ++p_copy; + } + *p_copy++ = '*'; + *p_copy++ = '/'; + *p_copy++ = 0; + } + query_len = mnd_sprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"), + name_esc? name_esc:"", tmp_str.c? tmp_str.c:""); + smart_str_free(&tmp_str); if (!query) { SET_OOM_ERROR(*conn->error_info); break; } + if (name_esc) { + mnd_efree(name_esc); + name_esc = NULL; + } + ret = conn->m->query(conn, query, query_len TSRMLS_CC); mnd_sprintf_free(query); - if (commented_name) { - mnd_sprintf_free(commented_name); - } } } while (0); conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); |