Use unsigned arithmetic in zend_atol

To avoid UB on overflow. I'm not really sure what the correct
overflow behavior here would be.
This commit is contained in:
Nikita Popov 2021-07-13 10:59:33 +02:00
parent 1cba7764b4
commit 26e8a3ba29

View File

@ -93,12 +93,16 @@ static const unsigned char tolower_map[256] = {
ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {{{ */ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {{{ */
{ {
zend_long retval;
if (!str_len) { if (!str_len) {
str_len = strlen(str); str_len = strlen(str);
} }
retval = ZEND_STRTOL(str, NULL, 0);
/* Perform following multiplications on unsigned to avoid overflow UB.
* For now overflow is silently ignored -- not clear what else can be
* done here, especially as the final result of this function may be
* used in an unsigned context (e.g. "memory_limit=3G", which overflows
* zend_long on 32-bit, but not size_t). */
zend_ulong retval = (zend_ulong) ZEND_STRTOL(str, NULL, 0);
if (str_len>0) { if (str_len>0) {
switch (str[str_len-1]) { switch (str[str_len-1]) {
case 'g': case 'g':
@ -115,7 +119,7 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len) /* {
break; break;
} }
} }
return retval; return (zend_long) retval;
} }
/* }}} */ /* }}} */