@@ -1381,47 +1381,39 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
1381
1381
SET_CONNECTION_STATE (connection_state , CONN_QUIT_SENT );
1382
1382
set_packet_error (error_info , CR_SERVER_GONE_ERROR , UNKNOWN_SQLSTATE , mysqlnd_server_gone );
1383
1383
} else {
1384
+ /* If the packet is split in multiple chunks, allocate a temporary buffer that we can
1385
+ * reallocate, and only afterwards copy it to the pool when we know the final size. */
1386
+ zend_uchar * buf = NULL ;
1387
+ while (header .size >= MYSQLND_MAX_PACKET_SIZE ) {
1388
+ buf = erealloc (buf , * data_size + header .size );
1389
+ p = buf + * data_size ;
1390
+ * data_size += header .size ;
1391
+
1392
+ if (UNEXPECTED (PASS != (ret = pfc -> data -> m .receive (pfc , vio , p , header .size , stats , error_info )))) {
1393
+ DBG_ERR ("Empty row packet body" );
1394
+ SET_CONNECTION_STATE (connection_state , CONN_QUIT_SENT );
1395
+ set_packet_error (error_info , CR_SERVER_GONE_ERROR , UNKNOWN_SQLSTATE , mysqlnd_server_gone );
1396
+ efree (buf );
1397
+ DBG_RETURN (FAIL );
1398
+ }
1399
+ if (FAIL == mysqlnd_read_header (pfc , vio , & header , stats , error_info )) {
1400
+ efree (buf );
1401
+ DBG_RETURN (FAIL );
1402
+ }
1403
+ }
1404
+
1405
+ buffer -> ptr = pool -> get_chunk (pool , * data_size + header .size + prealloc_more_bytes );
1406
+ if (buf ) {
1407
+ memcpy (buffer -> ptr , buf , * data_size );
1408
+ efree (buf );
1409
+ }
1410
+ p = buffer -> ptr + * data_size ;
1384
1411
* data_size += header .size ;
1385
- buffer -> ptr = pool -> get_chunk (pool , * data_size + prealloc_more_bytes );
1386
- p = buffer -> ptr ;
1387
1412
1388
1413
if (UNEXPECTED (PASS != (ret = pfc -> data -> m .receive (pfc , vio , p , header .size , stats , error_info )))) {
1389
1414
DBG_ERR ("Empty row packet body" );
1390
1415
SET_CONNECTION_STATE (connection_state , CONN_QUIT_SENT );
1391
1416
set_packet_error (error_info , CR_SERVER_GONE_ERROR , UNKNOWN_SQLSTATE , mysqlnd_server_gone );
1392
- } else {
1393
- while (header .size >= MYSQLND_MAX_PACKET_SIZE ) {
1394
- if (FAIL == mysqlnd_read_header (pfc , vio , & header , stats , error_info )) {
1395
- ret = FAIL ;
1396
- break ;
1397
- }
1398
-
1399
- * data_size += header .size ;
1400
-
1401
- /* Empty packet after MYSQLND_MAX_PACKET_SIZE packet. That's ok, break */
1402
- if (!header .size ) {
1403
- break ;
1404
- }
1405
-
1406
- /*
1407
- We have to realloc the buffer.
1408
- */
1409
- buffer -> ptr = pool -> resize_chunk (pool , buffer -> ptr , * data_size - header .size , * data_size + prealloc_more_bytes );
1410
- if (!buffer -> ptr ) {
1411
- SET_OOM_ERROR (error_info );
1412
- ret = FAIL ;
1413
- break ;
1414
- }
1415
- /* The position could have changed, recalculate */
1416
- p = (zend_uchar * ) buffer -> ptr + (* data_size - header .size );
1417
-
1418
- if (PASS != (ret = pfc -> data -> m .receive (pfc , vio , p , header .size , stats , error_info ))) {
1419
- DBG_ERR ("Empty row packet body" );
1420
- SET_CONNECTION_STATE (connection_state , CONN_QUIT_SENT );
1421
- set_packet_error (error_info , CR_SERVER_GONE_ERROR , UNKNOWN_SQLSTATE , mysqlnd_server_gone );
1422
- break ;
1423
- }
1424
- }
1425
1417
}
1426
1418
}
1427
1419
if (ret == FAIL && buffer -> ptr ) {
0 commit comments