mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Add ZEND_THREEWAY_COMPARE() macro to fix casting underflowed unsigned to signed (#8220)
Casting a huge unsigned value to signed is implementation-defined behavior in C. By introducing the ZEND_THREEWAY_COMPARE() macro, we can sidestep this integer overflow/underflow/casting problem.
This commit is contained in:
parent
89688b115d
commit
c1a06704da
@ -24,6 +24,6 @@ int(0)
|
||||
int(-3)
|
||||
int(0)
|
||||
int(0)
|
||||
int(2)
|
||||
int(1)
|
||||
int(0)
|
||||
int(0)
|
||||
|
@ -2956,7 +2956,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const
|
||||
}
|
||||
retval = memcmp(s1, s2, MIN(len1, len2));
|
||||
if (!retval) {
|
||||
return (int)(len1 - len2);
|
||||
return ZEND_THREEWAY_COMPARE(len1, len2);
|
||||
} else {
|
||||
return retval;
|
||||
}
|
||||
@ -2972,7 +2972,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, cons
|
||||
}
|
||||
retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
|
||||
if (!retval) {
|
||||
return (int)(MIN(length, len1) - MIN(length, len2));
|
||||
return ZEND_THREEWAY_COMPARE(MIN(length, len1), MIN(length, len2));
|
||||
} else {
|
||||
return retval;
|
||||
}
|
||||
@ -2997,7 +2997,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, c
|
||||
}
|
||||
}
|
||||
|
||||
return (int)(len1 - len2);
|
||||
return ZEND_THREEWAY_COMPARE(len1, len2);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -3018,7 +3018,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1,
|
||||
}
|
||||
}
|
||||
|
||||
return (int)(MIN(length, len1) - MIN(length, len2));
|
||||
return ZEND_THREEWAY_COMPARE(MIN(length, len1), MIN(length, len2));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -3040,7 +3040,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1,
|
||||
}
|
||||
}
|
||||
|
||||
return (int)(len1 - len2);
|
||||
return ZEND_THREEWAY_COMPARE(len1, len2);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -3061,7 +3061,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1
|
||||
}
|
||||
}
|
||||
|
||||
return (int)(MIN(length, len1) - MIN(length, len2));
|
||||
return ZEND_THREEWAY_COMPARE(MIN(length, len1), MIN(length, len2));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -456,6 +456,12 @@ extern "C++" {
|
||||
#define ZEND_TRUTH(x) ((x) ? 1 : 0)
|
||||
#define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
|
||||
|
||||
/**
|
||||
* Do a three-way comparison of two integers and returns -1, 0 or 1
|
||||
* depending on whether #a is smaller, equal or larger than #b.
|
||||
*/
|
||||
#define ZEND_THREEWAY_COMPARE(a, b) ((a) == (b) ? 0 : ((a) < (b) ? -1 : 1))
|
||||
|
||||
#define ZEND_MAX_RESERVED_RESOURCES 6
|
||||
|
||||
/* excpt.h on Digital Unix 4.0 defines function_table */
|
||||
|
@ -90,6 +90,6 @@ stripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack)
|
||||
strrpos(): Argument #3 ($offset) must be contained in argument #1 ($haystack)
|
||||
strripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack)
|
||||
strripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack)
|
||||
int(2)
|
||||
int(1)
|
||||
string(8) "abcdeabc"
|
||||
string(0) ""
|
||||
|
@ -5,4 +5,4 @@ Bug #54454 (substr_compare incorrectly reports equality in some cases)
|
||||
var_dump(substr_compare('/', '/asd', 0, 4));
|
||||
?>
|
||||
--EXPECT--
|
||||
int(-3)
|
||||
int(-1)
|
||||
|
@ -17,6 +17,6 @@ echo "*** Done ***\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
*** Test strncasecmp() function: with null terminated strings and binary inputs ***
|
||||
int(5)
|
||||
int(1)
|
||||
int(-119)
|
||||
*** Done ***
|
||||
|
@ -71,9 +71,9 @@ echo "*** Done ***\n";
|
||||
--EXPECT--
|
||||
*** Test strncasecmp() function: with here-doc strings ***
|
||||
int(0)
|
||||
int(63)
|
||||
int(1)
|
||||
int(0)
|
||||
int(83)
|
||||
int(1)
|
||||
int(0)
|
||||
int(-1)
|
||||
int(0)
|
||||
|
@ -15,5 +15,5 @@ echo "*** Done ***\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
*** Test strncmp() function: Checking with the null terminated strings ***
|
||||
int(5)
|
||||
int(1)
|
||||
*** Done ***
|
||||
|
Loading…
Reference in New Issue
Block a user