@@ -2225,27 +2225,39 @@ static inline void _zend_substr(zval *return_value, zend_string *str, zend_long
22252225 /* if "from" position is negative, count start position from the end
22262226 * of the string
22272227 */
2228- if (- (size_t )f > ZSTR_LEN (str )) {
2228+ f = (zend_long )ZSTR_LEN (str ) + f ;
2229+ if (f < 0 ) {
22292230 f = 0 ;
2230- } else {
2231- f = (zend_long )ZSTR_LEN (str ) + f ;
22322231 }
2233- } else if ((size_t )f > ZSTR_LEN (str )) {
2234- RETURN_EMPTY_STRING ();
2232+ } else {
2233+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2234+ if (UNEXPECTED (f > SIZE_MAX )) {
2235+ f = SIZE_MAX ;
2236+ }
2237+ #endif
2238+ if ((size_t )f > ZSTR_LEN (str )) {
2239+ RETURN_EMPTY_STRING ();
2240+ }
22352241 }
22362242
22372243 if (!len_is_null ) {
22382244 if (l < 0 ) {
22392245 /* if "length" position is negative, set it to the length
22402246 * needed to stop that many chars from the end of the string
22412247 */
2242- if (- (size_t )l > ZSTR_LEN (str ) - (size_t )f ) {
2248+ l = (zend_long )ZSTR_LEN (str ) - f + l ;
2249+ if (l < 0 ) {
22432250 l = 0 ;
2244- } else {
2245- l = (zend_long )ZSTR_LEN (str ) - f + l ;
22462251 }
2247- } else if ((size_t )l > ZSTR_LEN (str ) - (size_t )f ) {
2248- l = (zend_long )ZSTR_LEN (str ) - f ;
2252+ } else {
2253+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2254+ if (UNEXPECTED (l > SIZE_MAX )) {
2255+ l = SIZE_MAX ;
2256+ }
2257+ #endif
2258+ if ((size_t )l > ZSTR_LEN (str ) - (size_t )f ) {
2259+ l = (zend_long )ZSTR_LEN (str ) - f ;
2260+ }
22492261 }
22502262 } else {
22512263 l = (zend_long )ZSTR_LEN (str ) - f ;
@@ -2360,8 +2372,15 @@ PHP_FUNCTION(substr_replace)
23602372 if (f < 0 ) {
23612373 f = 0 ;
23622374 }
2363- } else if ((size_t )f > ZSTR_LEN (str )) {
2364- f = ZSTR_LEN (str );
2375+ } else {
2376+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2377+ if (UNEXPECTED (f > SIZE_MAX )) {
2378+ f = SIZE_MAX ;
2379+ }
2380+ #endif
2381+ if ((size_t )f > ZSTR_LEN (str )) {
2382+ f = ZSTR_LEN (str );
2383+ }
23652384 }
23662385 /* if "length" position is negative, set it to the length
23672386 * needed to stop that many chars from the end of the string
@@ -2373,6 +2392,12 @@ PHP_FUNCTION(substr_replace)
23732392 }
23742393 }
23752394
2395+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2396+ if (UNEXPECTED (l > SIZE_MAX )) {
2397+ l = SIZE_MAX ;
2398+ }
2399+ #endif
2400+
23762401 if ((size_t )l > ZSTR_LEN (str )) {
23772402 l = ZSTR_LEN (str );
23782403 }
@@ -2522,6 +2547,12 @@ PHP_FUNCTION(substr_replace)
25222547 }
25232548 }
25242549
2550+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2551+ if (UNEXPECTED (l > SIZE_MAX )) {
2552+ l = SIZE_MAX ;
2553+ }
2554+ #endif
2555+
25252556 ZEND_ASSERT (0 <= f && f <= ZEND_LONG_MAX );
25262557 ZEND_ASSERT (0 <= l && l <= ZEND_LONG_MAX );
25272558 if (((size_t ) f + l ) > ZSTR_LEN (orig_str )) {
@@ -5756,6 +5787,13 @@ PHP_FUNCTION(str_pad)
57565787 Z_PARAM_LONG (pad_type_val )
57575788 ZEND_PARSE_PARAMETERS_END ();
57585789
5790+ #if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
5791+ if (pad_length > SIZE_MAX /2 ) {
5792+ zend_argument_value_error (2 , "must be lower or equal to %zd" , SIZE_MAX /2 );
5793+ RETURN_THROWS ();
5794+ }
5795+ #endif
5796+
57595797 /* If resulting string turns out to be shorter than input string,
57605798 we simply copy the input and return. */
57615799 if (pad_length < 0 || (size_t )pad_length <= ZSTR_LEN (input )) {
0 commit comments