@@ -463,32 +463,40 @@ redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
463
463
/**
464
464
* redis_sock_read_bulk_reply
465
465
*/
466
- PHP_REDIS_API char * redis_sock_read_bulk_reply (RedisSock * redis_sock , int bytes TSRMLS_DC )
466
+ PHP_REDIS_API char *
467
+ redis_sock_read_bulk_reply (RedisSock * redis_sock , int bytes TSRMLS_DC )
467
468
{
468
469
int offset = 0 ;
469
- size_t got ;
470
-
471
470
char * reply , c [2 ];
471
+ size_t got ;
472
472
473
473
if (-1 == bytes || -1 == redis_check_eof (redis_sock , 0 TSRMLS_CC )) {
474
474
return NULL ;
475
475
}
476
- reply = emalloc (bytes + 1 );
477
476
478
- while (offset < bytes ) {
479
- got = php_stream_read (redis_sock -> stream , reply + offset ,
480
- bytes - offset );
481
- if (got <= 0 ) {
482
- /* Error or EOF */
483
- zend_throw_exception (redis_exception_ce ,
484
- "socket error on read socket" , 0 TSRMLS_CC );
485
- break ;
486
- }
487
- offset += got ;
488
- }
489
- php_stream_read (redis_sock -> stream , c , 2 );
477
+ /* Allocate memory for string */
478
+ reply = emalloc (bytes + 1 );
479
+
480
+ /* Consume bulk string */
481
+ while (offset < bytes ) {
482
+ got = php_stream_read (redis_sock -> stream , reply + offset , bytes - offset );
483
+ if (got == 0 ) break ;
484
+ offset += got ;
485
+ }
486
+
487
+ /* Protect against reading too few bytes */
488
+ if (offset < bytes ) {
489
+ /* Error or EOF */
490
+ zend_throw_exception (redis_exception_ce ,
491
+ "socket error on read socket" , 0 TSRMLS_CC );
492
+ efree (reply );
493
+ return NULL ;
494
+ }
495
+
496
+ /* Consume \r\n and null terminate reply string */
497
+ php_stream_read (redis_sock -> stream , c , 2 );
498
+ reply [bytes ] = '\0' ;
490
499
491
- reply [bytes ] = 0 ;
492
500
return reply ;
493
501
}
494
502
0 commit comments