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