@@ -2227,27 +2227,39 @@ static inline void _zend_substr(zval *return_value, zend_string *str, zend_long
22272227 /* if "from" position is negative, count start position from the end
22282228 * of the string
22292229 */
2230- if (- (size_t )f > ZSTR_LEN (str )) {
2230+ f = (zend_long )ZSTR_LEN (str ) + f ;
2231+ if (f < 0 ) {
22312232 f = 0 ;
2232- } else {
2233- f = (zend_long )ZSTR_LEN (str ) + f ;
22342233 }
2235- } else if ((size_t )f > ZSTR_LEN (str )) {
2236- RETURN_EMPTY_STRING ();
2234+ } else {
2235+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2236+ if (UNEXPECTED (f > SIZE_MAX )) {
2237+ f = SIZE_MAX ;
2238+ }
2239+ #endif
2240+ if ((size_t )f > ZSTR_LEN (str )) {
2241+ RETURN_EMPTY_STRING ();
2242+ }
22372243 }
22382244
22392245 if (!len_is_null ) {
22402246 if (l < 0 ) {
22412247 /* if "length" position is negative, set it to the length
22422248 * needed to stop that many chars from the end of the string
22432249 */
2244- if (- (size_t )l > ZSTR_LEN (str ) - (size_t )f ) {
2250+ l = (zend_long )ZSTR_LEN (str ) - f + l ;
2251+ if (l < 0 ) {
22452252 l = 0 ;
2246- } else {
2247- l = (zend_long )ZSTR_LEN (str ) - f + l ;
22482253 }
2249- } else if ((size_t )l > ZSTR_LEN (str ) - (size_t )f ) {
2250- l = (zend_long )ZSTR_LEN (str ) - f ;
2254+ } else {
2255+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2256+ if (UNEXPECTED (l > SIZE_MAX )) {
2257+ l = SIZE_MAX ;
2258+ }
2259+ #endif
2260+ if ((size_t )l > ZSTR_LEN (str ) - (size_t )f ) {
2261+ l = (zend_long )ZSTR_LEN (str ) - f ;
2262+ }
22512263 }
22522264 } else {
22532265 l = (zend_long )ZSTR_LEN (str ) - f ;
@@ -2362,8 +2374,15 @@ PHP_FUNCTION(substr_replace)
23622374 if (f < 0 ) {
23632375 f = 0 ;
23642376 }
2365- } else if ((size_t )f > ZSTR_LEN (str )) {
2366- f = ZSTR_LEN (str );
2377+ } else {
2378+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2379+ if (UNEXPECTED (f > SIZE_MAX )) {
2380+ f = SIZE_MAX ;
2381+ }
2382+ #endif
2383+ if ((size_t )f > ZSTR_LEN (str )) {
2384+ f = ZSTR_LEN (str );
2385+ }
23672386 }
23682387 /* if "length" position is negative, set it to the length
23692388 * needed to stop that many chars from the end of the string
@@ -2375,6 +2394,12 @@ PHP_FUNCTION(substr_replace)
23752394 }
23762395 }
23772396
2397+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2398+ if (UNEXPECTED (l > SIZE_MAX )) {
2399+ l = SIZE_MAX ;
2400+ }
2401+ #endif
2402+
23782403 if ((size_t )l > ZSTR_LEN (str )) {
23792404 l = ZSTR_LEN (str );
23802405 }
@@ -2524,6 +2549,12 @@ PHP_FUNCTION(substr_replace)
25242549 }
25252550 }
25262551
2552+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2553+ if (UNEXPECTED (l > SIZE_MAX )) {
2554+ l = SIZE_MAX ;
2555+ }
2556+ #endif
2557+
25272558 ZEND_ASSERT (0 <= f && f <= ZEND_LONG_MAX );
25282559 ZEND_ASSERT (0 <= l && l <= ZEND_LONG_MAX );
25292560 if (((size_t ) f + l ) > ZSTR_LEN (orig_str )) {
@@ -5798,6 +5829,13 @@ PHP_FUNCTION(str_pad)
57985829 Z_PARAM_LONG (pad_type_val )
57995830 ZEND_PARSE_PARAMETERS_END ();
58005831
5832+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
5833+ if (pad_length > SIZE_MAX /2 ) {
5834+ zend_argument_value_error (2 , "must be lower or equal to %zd" , SIZE_MAX /2 );
5835+ RETURN_THROWS ();
5836+ }
5837+ #endif
5838+
58015839 /* If resulting string turns out to be shorter than input string,
58025840 we simply copy the input and return. */
58035841 if (pad_length < 0 || (size_t )pad_length <= ZSTR_LEN (input )) {
0 commit comments