@@ -2655,8 +2655,8 @@ PHP_FUNCTION(array_fill_keys)
2655
2655
zend_hash_real_init_packed(Z_ARRVAL_P(return_value)); \
2656
2656
} while (0)
2657
2657
2658
- #define RANGE_CHECK_LONG_INIT_ARRAY (start , end ) do { \
2659
- zend_ulong __calc_size = ((zend_ulong) start - end) / lstep ; \
2658
+ #define RANGE_CHECK_LONG_INIT_ARRAY (start , end , _step ) do { \
2659
+ zend_ulong __calc_size = ((zend_ulong) start - end) / (_step) ; \
2660
2660
if (__calc_size >= HT_MAX_SIZE - 1) { \
2661
2661
zend_value_error(\
2662
2662
"The supplied range exceeds the maximum array size: start=" ZEND_LONG_FMT " end=" ZEND_LONG_FMT, end, start); \
@@ -2673,6 +2673,7 @@ PHP_FUNCTION(range)
2673
2673
zval * zlow , * zhigh , * user_step = NULL , tmp ;
2674
2674
bool err = 0 , is_step_double = false;
2675
2675
double step_double = 1.0 ;
2676
+ zend_long step = 1 ;
2676
2677
2677
2678
ZEND_PARSE_PARAMETERS_START (2 , 3 )
2678
2679
Z_PARAM_NUMBER_OR_STR (zlow )
@@ -2684,25 +2685,32 @@ PHP_FUNCTION(range)
2684
2685
if (user_step ) {
2685
2686
if (UNEXPECTED (Z_TYPE_P (user_step ) == IS_DOUBLE )) {
2686
2687
step_double = Z_DVAL_P (user_step );
2687
- is_step_double = true;
2688
+ /* We only want positive step values. */
2689
+ if (step_double < 0.0 ) {
2690
+ step_double *= -1 ;
2691
+ }
2692
+ step = zend_dval_to_lval (step_double );
2693
+ if (!zend_is_long_compatible (step_double , step )) {
2694
+ is_step_double = true;
2695
+ }
2688
2696
} else {
2689
- step_double = (double ) Z_LVAL_P (user_step );
2697
+ step = Z_LVAL_P (user_step );
2698
+ /* We only want positive step values. */
2699
+ if (step < 0 ) {
2700
+ step *= -1 ;
2701
+ }
2702
+ step_double = (double ) step ;
2690
2703
}
2691
2704
if (step_double == 0.0 ) {
2692
2705
zend_argument_value_error (3 , "cannot be 0" );
2693
2706
RETURN_THROWS ();
2694
2707
}
2695
- /* We only want positive step values. */
2696
- if (step_double < 0.0 ) {
2697
- step_double *= -1 ;
2698
- }
2699
2708
}
2700
2709
2701
2710
/* If the range is given as strings, generate an array of characters. */
2702
2711
if (Z_TYPE_P (zlow ) == IS_STRING && Z_TYPE_P (zhigh ) == IS_STRING && Z_STRLEN_P (zlow ) >= 1 && Z_STRLEN_P (zhigh ) >= 1 ) {
2703
2712
int type1 , type2 ;
2704
2713
unsigned char low , high ;
2705
- zend_long lstep = (zend_long ) step_double ;
2706
2714
2707
2715
type1 = is_numeric_string (Z_STRVAL_P (zlow ), Z_STRLEN_P (zlow ), NULL , NULL , 0 );
2708
2716
type2 = is_numeric_string (Z_STRVAL_P (zhigh ), Z_STRLEN_P (zhigh ), NULL , NULL , 0 );
@@ -2717,34 +2725,34 @@ PHP_FUNCTION(range)
2717
2725
high = (unsigned char )Z_STRVAL_P (zhigh )[0 ];
2718
2726
2719
2727
if (low > high ) { /* Negative Steps */
2720
- if (low - high < lstep ) {
2728
+ if (low - high < step ) {
2721
2729
err = 1 ;
2722
2730
goto err ;
2723
2731
}
2724
2732
/* Initialize the return_value as an array. */
2725
- array_init_size (return_value , (uint32_t )(((low - high ) / lstep ) + 1 ));
2733
+ array_init_size (return_value , (uint32_t )(((low - high ) / step ) + 1 ));
2726
2734
zend_hash_real_init_packed (Z_ARRVAL_P (return_value ));
2727
2735
ZEND_HASH_FILL_PACKED (Z_ARRVAL_P (return_value )) {
2728
- for (; low >= high ; low -= (unsigned int )lstep ) {
2736
+ for (; low >= high ; low -= (unsigned int )step ) {
2729
2737
ZEND_HASH_FILL_SET_INTERNED_STR (ZSTR_CHAR (low ));
2730
2738
ZEND_HASH_FILL_NEXT ();
2731
- if (((signed int )low - lstep ) < 0 ) {
2739
+ if (((signed int )low - step ) < 0 ) {
2732
2740
break ;
2733
2741
}
2734
2742
}
2735
2743
} ZEND_HASH_FILL_END ();
2736
2744
} else if (high > low ) { /* Positive Steps */
2737
- if (high - low < lstep ) {
2745
+ if (high - low < step ) {
2738
2746
err = 1 ;
2739
2747
goto err ;
2740
2748
}
2741
- array_init_size (return_value , (uint32_t )(((high - low ) / lstep ) + 1 ));
2749
+ array_init_size (return_value , (uint32_t )(((high - low ) / step ) + 1 ));
2742
2750
zend_hash_real_init_packed (Z_ARRVAL_P (return_value ));
2743
2751
ZEND_HASH_FILL_PACKED (Z_ARRVAL_P (return_value )) {
2744
- for (; low <= high ; low += (unsigned int )lstep ) {
2752
+ for (; low <= high ; low += (unsigned int )step ) {
2745
2753
ZEND_HASH_FILL_SET_INTERNED_STR (ZSTR_CHAR (low ));
2746
2754
ZEND_HASH_FILL_NEXT ();
2747
- if (((signed int )low + lstep ) > 255 ) {
2755
+ if (((signed int )low + step ) > 255 ) {
2748
2756
break ;
2749
2757
}
2750
2758
}
@@ -2801,40 +2809,40 @@ PHP_FUNCTION(range)
2801
2809
}
2802
2810
} else {
2803
2811
zend_long low , high ;
2804
- /* lstep is a zend_ulong so that comparisons to it don't overflow, i.e. low - high < lstep */
2805
- zend_ulong lstep ;
2812
+ /* unsigned_step is a zend_ulong so that comparisons to it don't overflow, i.e. low - high < lstep */
2813
+ zend_ulong unsigned_step ;
2806
2814
uint32_t i , size ;
2807
2815
long_str :
2808
2816
low = zval_get_long (zlow );
2809
2817
high = zval_get_long (zhigh );
2810
2818
2811
- lstep = (zend_ulong )step_double ;
2819
+ unsigned_step = (zend_ulong )step ;
2812
2820
2813
2821
if (low > high ) { /* Negative steps */
2814
- if ((zend_ulong )low - high < lstep ) {
2822
+ if ((zend_ulong )low - high < unsigned_step ) {
2815
2823
err = 1 ;
2816
2824
goto err ;
2817
2825
}
2818
2826
2819
- RANGE_CHECK_LONG_INIT_ARRAY (low , high );
2827
+ RANGE_CHECK_LONG_INIT_ARRAY (low , high , unsigned_step );
2820
2828
2821
2829
ZEND_HASH_FILL_PACKED (Z_ARRVAL_P (return_value )) {
2822
2830
for (i = 0 ; i < size ; ++ i ) {
2823
- ZEND_HASH_FILL_SET_LONG (low - (i * lstep ));
2831
+ ZEND_HASH_FILL_SET_LONG (low - (i * unsigned_step ));
2824
2832
ZEND_HASH_FILL_NEXT ();
2825
2833
}
2826
2834
} ZEND_HASH_FILL_END ();
2827
2835
} else if (high > low ) { /* Positive steps */
2828
- if ((zend_ulong )high - low < lstep ) {
2836
+ if ((zend_ulong )high - low < unsigned_step ) {
2829
2837
err = 1 ;
2830
2838
goto err ;
2831
2839
}
2832
2840
2833
- RANGE_CHECK_LONG_INIT_ARRAY (high , low );
2841
+ RANGE_CHECK_LONG_INIT_ARRAY (high , low , unsigned_step );
2834
2842
2835
2843
ZEND_HASH_FILL_PACKED (Z_ARRVAL_P (return_value )) {
2836
2844
for (i = 0 ; i < size ; ++ i ) {
2837
- ZEND_HASH_FILL_SET_LONG (low + (i * lstep ));
2845
+ ZEND_HASH_FILL_SET_LONG (low + (i * unsigned_step ));
2838
2846
ZEND_HASH_FILL_NEXT ();
2839
2847
}
2840
2848
} ZEND_HASH_FILL_END ();
0 commit comments