Skip to content

Commit 22ad8e1

Browse files
committed
Merge branch 'PHP-5.5' into PHP-5.6
* PHP-5.5: 5.4.24-dev now merge fix add test Fix for Bug #66141 (mysqlnd quote function is wrong with NO_BACKSLASH_ESCAPES after failed query)
2 parents 834eaae + 5cd8ff9 commit 22ad8e1

File tree

5 files changed

+55
-4
lines changed

5 files changed

+55
-4
lines changed

ext/mysqlnd/mysqlnd.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_handle_response)(MYSQLND_CONN_D
257257
conn->persistent);
258258

259259
if (!ignore_upsert_status) {
260+
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
260261
conn->upsert_status->warning_count = ok_response->warning_count;
261262
conn->upsert_status->server_status = ok_response->server_status;
262263
conn->upsert_status->affected_rows = ok_response->affected_rows;
@@ -319,6 +320,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA
319320

320321
DBG_ENTER("mysqlnd_conn_data::simple_command_send_request");
321322
DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent);
323+
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
322324

323325
switch (CONN_GET_STATE(conn)) {
324326
case CONN_READY:
@@ -333,10 +335,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA
333335
DBG_RETURN(FAIL);
334336
}
335337

336-
/* clean UPSERT info */
337-
if (!ignore_upsert_status) {
338-
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
339-
}
340338
SET_ERROR_AFF_ROWS(conn);
341339
SET_EMPTY_ERROR(*conn->error_info);
342340

@@ -811,6 +809,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
811809
{
812810
goto err;
813811
}
812+
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
814813
conn->upsert_status->warning_count = 0;
815814
conn->upsert_status->server_status = greet_packet->server_status;
816815
conn->upsert_status->affected_rows = 0;
@@ -1183,6 +1182,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_query)(MYSQLND_CONN_DATA * conn, const ch
11831182
enum_func_status ret = FAIL;
11841183
DBG_ENTER("mysqlnd_conn_data::send_query");
11851184
DBG_INF_FMT("conn=%llu query=%s", conn->thread_id, query);
1185+
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
11861186

11871187
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
11881188
ret = conn->m->simple_command(conn, COM_QUERY, (zend_uchar *) query, query_len,
@@ -1193,6 +1193,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_query)(MYSQLND_CONN_DATA * conn, const ch
11931193
}
11941194
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
11951195
}
1196+
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
11961197
DBG_RETURN(ret);
11971198
}
11981199
/* }}} */
@@ -1208,6 +1209,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn TSRMLS_DC
12081209
DBG_ENTER("mysqlnd_conn_data::reap_query");
12091210
DBG_INF_FMT("conn=%llu", conn->thread_id);
12101211

1212+
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
12111213
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
12121214
if (state <= CONN_READY || state == CONN_QUIT_SENT) {
12131215
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not opened, clear or has been closed");
@@ -1218,6 +1220,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn TSRMLS_DC
12181220

12191221
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
12201222
}
1223+
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
12211224
DBG_RETURN(ret);
12221225
}
12231226
/* }}} */
@@ -1603,6 +1606,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, escape_string)(MYSQLND_CONN_DATA * const conn,
16031606
DBG_INF_FMT("conn=%llu", conn->thread_id);
16041607

16051608
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
1609+
DBG_INF_FMT("server_status=%u", conn->upsert_status->server_status);
16061610
if (conn->upsert_status->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) {
16071611
ret = mysqlnd_cset_escape_quotes(conn->charset, newstr, escapestr, escapestr_len TSRMLS_CC);
16081612
} else {

ext/mysqlnd/mysqlnd_ps.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC)
486486
ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC);
487487
if (ret == FAIL) {
488488
COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info);
489+
memset(stmt->upsert_status, 0, sizeof(*stmt->upsert_status));
489490
stmt->upsert_status->affected_rows = conn->upsert_status->affected_rows;
490491
if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) {
491492
/* close the statement here, the connection has been closed */
@@ -905,6 +906,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
905906
DBG_INF("EOF");
906907
/* Mark the connection as usable again */
907908
result->unbuf->eof_reached = TRUE;
909+
memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status));
908910
result->conn->upsert_status->warning_count = row_packet->warning_count;
909911
result->conn->upsert_status->server_status = row_packet->server_status;
910912
/*
@@ -1014,6 +1016,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
10141016

10151017
row_packet->skip_extraction = stmt->result_bind? FALSE:TRUE;
10161018

1019+
memset(stmt->upsert_status, 0, sizeof(*stmt->upsert_status));
10171020
if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) {
10181021
unsigned int i, field_count = result->field_count;
10191022

ext/mysqlnd/mysqlnd_result.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s
415415
DBG_INF("UPSERT");
416416
conn->last_query_type = QUERY_UPSERT;
417417
conn->field_count = rset_header->field_count;
418+
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
418419
conn->upsert_status->warning_count = rset_header->warning_count;
419420
conn->upsert_status->server_status = rset_header->server_status;
420421
conn->upsert_status->affected_rows = rset_header->affected_rows;
@@ -702,6 +703,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
702703
/* Mark the connection as usable again */
703704
DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status);
704705
result->unbuf->eof_reached = TRUE;
706+
memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status));
705707
result->conn->upsert_status->warning_count = row_packet->warning_count;
706708
result->conn->upsert_status->server_status = row_packet->server_status;
707709
/*
@@ -828,6 +830,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
828830
/* Mark the connection as usable again */
829831
DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status);
830832
result->unbuf->eof_reached = TRUE;
833+
memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status));
831834
result->conn->upsert_status->warning_count = row_packet->warning_count;
832835
result->conn->upsert_status->server_status = row_packet->server_status;
833836
/*
@@ -1175,6 +1178,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
11751178

11761179
/* Finally clean */
11771180
if (row_packet->eof) {
1181+
memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
11781182
conn->upsert_status->warning_count = row_packet->warning_count;
11791183
conn->upsert_status->server_status = row_packet->server_status;
11801184
}

ext/mysqlnd/mysqlnd_wireprotocol.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ php_mysqlnd_ok_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
827827
packet->error, sizeof(packet->error),
828828
&packet->error_no, packet->sqlstate
829829
TSRMLS_CC);
830+
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
830831
DBG_RETURN(PASS);
831832
}
832833
/* Everything was fine! */
@@ -1069,6 +1070,7 @@ php_mysqlnd_rset_header_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
10691070
packet->error_info.error, sizeof(packet->error_info.error),
10701071
&packet->error_info.error_no, packet->error_info.sqlstate
10711072
TSRMLS_CC);
1073+
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
10721074
DBG_RETURN(PASS);
10731075
}
10741076

ext/pdo_mysql/tests/bug66141.phpt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Bug #66141 (mysqlnd quote function is wrong with NO_BACKSLASH_ESCAPES after failed query)
3+
--SKIPIF--
4+
<?php
5+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
6+
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
7+
MySQLPDOTest::skip();
8+
?>
9+
--FILE--
10+
<?php
11+
include __DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc';
12+
$db = MySQLPDOTest::factory();
13+
14+
$input = 'Something\', 1 as one, 2 as two FROM dual; -- f';
15+
16+
$quotedInput0 = $db->quote($input);
17+
18+
$db->query('set session sql_mode="NO_BACKSLASH_ESCAPES"');
19+
20+
// injection text from some user input
21+
22+
$quotedInput1 = $db->quote($input);
23+
24+
$db->query('something that throws an exception');
25+
26+
$quotedInput2 = $db->quote($input);
27+
28+
var_dump($quotedInput0);
29+
var_dump($quotedInput1);
30+
var_dump($quotedInput2);
31+
?>
32+
done
33+
--EXPECTF--
34+
Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'something that throws an exception' at line %d in %s on line %d
35+
string(50) "'Something\', 1 as one, 2 as two FROM dual; -- f'"
36+
string(50) "'Something'', 1 as one, 2 as two FROM dual; -- f'"
37+
string(50) "'Something'', 1 as one, 2 as two FROM dual; -- f'"
38+
done

0 commit comments

Comments
 (0)