summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--ext/mysqli/mysqli_api.c60
-rw-r--r--ext/mysqli/tests/mysqli_commit_oo.phpt55
-rw-r--r--ext/mysqlnd/mysqlnd.c59
4 files changed, 140 insertions, 37 deletions
diff --git a/NEWS b/NEWS
index 13c615d946..e8377e7a76 100644
--- a/NEWS
+++ b/NEWS
@@ -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);