@@ -500,6 +500,25 @@ int redis_zrange_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
500500#define IS_LIMIT_ARG (s , l ) \
501501 (l == sizeof("limit") && !strncasecmp(s,"limit",sizeof("limit")))
502502
503+ /* Helper to get the long value stored in a zval, whether it's actually stored
504+ * as a long or is a string that contains a long */
505+ static int zval_get_long (zval * zv , long * lval )
506+ {
507+ /* If it's already a long, just set and return success */
508+ if (Z_TYPE_P (zv ) == IS_LONG ) {
509+ * lval = Z_LVAL_P (zv );
510+ return SUCCESS ;
511+ }
512+
513+ /* If our zval isn't a string, or doesn't translate into a long, fail */
514+ if (Z_TYPE_P (zv ) != IS_STRING || is_numeric_string (Z_STRVAL_P (zv ), Z_STRLEN_P (zv ), lval , NULL , 0 ) != IS_LONG ) {
515+ return FAILURE ;
516+ }
517+
518+ /* Success */
519+ return SUCCESS ;
520+ }
521+
503522int redis_zrangebyscore_cmd (INTERNAL_FUNCTION_PARAMETERS , RedisSock * redis_sock ,
504523 char * kw , char * * cmd , int * cmd_len , int * withscores ,
505524 short * slot , void * * ctx )
@@ -509,7 +528,7 @@ int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
509528 char * start , * end , * optkey ;
510529 int start_len , end_len ;
511530 int has_limit = 0 , type ;
512- long limit_low , limit_high ;
531+ long offset , count ;
513532 zval * z_opt = NULL , * * z_ele ;
514533 unsigned long idx ;
515534 unsigned int optlen ;
@@ -544,13 +563,19 @@ int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
544563 {
545564 HashTable * htlimit = Z_ARRVAL_PP (z_ele );
546565 zval * * zoff , * * zcnt ;
566+
567+ /* We need two arguments (offset and count) */
547568 if (zend_hash_index_find (htlimit ,0 ,(void * * )& zoff )== SUCCESS &&
548- zend_hash_index_find (htlimit ,1 ,(void * * )& zcnt )== SUCCESS &&
549- Z_TYPE_PP (zoff ) == IS_LONG && Z_TYPE_PP (zcnt ) == IS_LONG )
569+ zend_hash_index_find (htlimit ,1 ,(void * * )& zcnt )== SUCCESS )
550570 {
551- has_limit = 1 ;
552- limit_low = Z_LVAL_PP (zoff );
553- limit_high = Z_LVAL_PP (zcnt );
571+ /* Set our limit if we can get valid longs from both args */
572+ has_limit = zval_get_long (* zoff , & offset ) == SUCCESS &&
573+ zval_get_long (* zcnt , & count ) == SUCCESS ;
574+
575+ /* Inform the user there is a problem if we don't have a limit */
576+ if (!has_limit ) {
577+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Offset and limit must be long values. Ignoring." );
578+ }
554579 }
555580 }
556581 }
@@ -564,17 +589,16 @@ int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
564589 if (* withscores ) {
565590 if (has_limit ) {
566591 * cmd_len = redis_cmd_format_static (cmd , kw , "ssssdds" , key , key_len ,
567- start , start_len , end , end_len , "LIMIT" , 5 , limit_low ,
568- limit_high , "WITHSCORES" , 10 );
592+ start , start_len , end , end_len , "LIMIT" , 5 , offset ,
593+ count , "WITHSCORES" , 10 );
569594 } else {
570595 * cmd_len = redis_cmd_format_static (cmd , kw , "ssss" , key , key_len ,
571596 start , start_len , end , end_len , "WITHSCORES" , 10 );
572597 }
573598 } else {
574599 if (has_limit ) {
575600 * cmd_len = redis_cmd_format_static (cmd , kw , "ssssdd" , key , key_len ,
576- start , start_len , end , end_len , "LIMIT" , 5 , limit_low ,
577- limit_high );
601+ start , start_len , end , end_len , "LIMIT" , 5 , offset , count );
578602 } else {
579603 * cmd_len = redis_cmd_format_static (cmd , kw , "sss" , key , key_len ,
580604 start , start_len , end , end_len );
@@ -3153,7 +3177,7 @@ void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
31533177 switch (option ) {
31543178 case REDIS_OPT_SERIALIZER :
31553179 val_long = atol (val_str );
3156- test_val = val_long == REDIS_SERIALIZER_NONE || val_long == REDIS_SERIALIZER_PHP ;
3180+ test_val = val_long == REDIS_SERIALIZER_NONE || val_long == REDIS_SERIALIZER_PHP ;
31573181#ifdef HAVE_REDIS_IGBINARY
31583182 test_val = test_val || val_long == REDIS_SERIALIZER_IGBINARY ;
31593183#endif
0 commit comments