@@ -463,32 +463,40 @@ redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAMETERS,
463463/**
464464 * redis_sock_read_bulk_reply
465465 */
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 )
467468{
468469 int offset = 0 ;
469- size_t got ;
470-
471470 char * reply , c [2 ];
471+ size_t got ;
472472
473473 if (-1 == bytes || -1 == redis_check_eof (redis_sock , 0 TSRMLS_CC )) {
474474 return NULL ;
475475 }
476- reply = emalloc (bytes + 1 );
477476
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' ;
490499
491- reply [bytes ] = 0 ;
492500 return reply ;
493501}
494502
0 commit comments