@ -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 ) ;