summaryrefslogtreecommitdiff
path: root/ext/mysqlnd/mysqlnd.c
diff options
context:
space:
mode:
authorAndrey Hristov <andrey@php.net>2014-03-20 16:23:40 +0200
committerAndrey Hristov <andrey@php.net>2014-03-20 16:23:40 +0200
commit41b4b84ddadee26445b14556b9fdd01758ea3632 (patch)
tree96a6256a206b3ee5f1ce1d58637c04d90c2eecd6 /ext/mysqlnd/mysqlnd.c
parent059bc99d941a9984c88b80562e39421850fb2690 (diff)
downloadphp-git-41b4b84ddadee26445b14556b9fdd01758ea3632.tar.gz
Emit a warning in case of unallowed characters. Fix another place this
code is used - reuse
Diffstat (limited to 'ext/mysqlnd/mysqlnd.c')
-rw-r--r--ext/mysqlnd/mysqlnd.c123
1 files changed, 71 insertions, 52 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index c138c50ed9..1222a7f302 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -2678,6 +2678,49 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string)(const MYSQLND_CONN_D
/* }}} */
+/* {{{ mysqlnd_escape_string_for_tx_name_in_comment */
+static char *
+mysqlnd_escape_string_for_tx_name_in_comment(const char * const name TSRMLS_DC)
+{
+ char * ret = NULL;
+ DBG_ENTER("mysqlnd_escape_string_for_tx_name_in_comment");
+ if (name) {
+ zend_bool warned = FALSE;
+ const char * p_orig = name;
+ char * p_copy;
+ p_copy = ret = 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 if (warned == FALSE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Transaction name truncated. Must be only [0-9A-Za-z\\-_=]+");
+ warned = TRUE;
+ }
+ ++p_orig;
+ }
+ *p_copy++ = '*';
+ *p_copy++ = '/';
+ *p_copy++ = 0;
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
/* {{{ mysqlnd_conn_data::tx_commit_ex */
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * conn, const zend_bool commit, const unsigned int flags, const char * const name TSRMLS_DC)
@@ -2695,49 +2738,20 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * con
{
char * query;
- 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;
- }
- ++p_orig;
- }
- *p_copy++ = '*';
- *p_copy++ = '/';
- *p_copy++ = 0;
- }
-
+ char * name_esc = mysqlnd_escape_string_for_tx_name_in_comment(name TSRMLS_CC);
+
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;
}
+ if (!query) {
+ SET_OOM_ERROR(*conn->error_info);
+ break;
+ }
ret = conn->m->query(conn, query, query_len TSRMLS_CC);
mnd_sprintf_free(query);
@@ -2768,36 +2782,41 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_begin)(MYSQLND_CONN_DATA * conn, const unsi
}
smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
}
- if (mode & TRANS_START_READ_WRITE) {
- if (tmp_str.len) {
- smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
- }
- smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
- }
- if (mode & TRANS_START_READ_ONLY) {
- if (tmp_str.len) {
- smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ if (mode & (TRANS_START_READ_WRITE | TRANS_START_READ_ONLY)) {
+ unsigned long server_version = conn->m->get_server_version(conn TSRMLS_CC);
+ if (server_version < 50605L) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required");
+ smart_str_free(&tmp_str);
+ break;
+ } else if (mode & TRANS_START_READ_WRITE) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
+ } else if (mode & TRANS_START_READ_ONLY) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
}
- smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
}
smart_str_0(&tmp_str);
{
- char * commented_name = NULL;
- unsigned int commented_name_len = name? mnd_sprintf(&commented_name, 0, " /*%s*/", name):0;
+ char * name_esc = mysqlnd_escape_string_for_tx_name_in_comment(name TSRMLS_CC);
char * query;
- unsigned int query_len = mnd_sprintf(&query, 0, "START TRANSACTION%s %s", commented_name? commented_name:"", tmp_str.c? tmp_str.c:"");
+ unsigned int query_len = mnd_sprintf(&query, 0, "START TRANSACTION%s %s", name_esc? name_esc:"", tmp_str.c? tmp_str.c:"");
smart_str_free(&tmp_str);
-
+ if (name_esc) {
+ mnd_efree(name_esc);
+ name_esc = NULL;
+ }
if (!query) {
SET_OOM_ERROR(*conn->error_info);
break;
}
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);