From f6cef916bc36e60c3c92e09e9264a0a28d24a30d Mon Sep 17 00:00:00 2001 From: Antony Dovgal Date: Sun, 22 Apr 2007 21:33:10 +0000 Subject: MFH: fix #41118 (PHP does not handle overflow of octal integers) --- Zend/tests/hex_overflow_32bit.phpt | 27 +++++++++++++++++++++++++++ Zend/tests/oct_overflow_32bit.phpt | 29 +++++++++++++++++++++++++++++ Zend/zend_language_scanner.l | 6 +++++- Zend/zend_strtod.c | 28 ++++++++++++++++++++++++++++ Zend/zend_strtod.h | 1 + 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/hex_overflow_32bit.phpt create mode 100644 Zend/tests/oct_overflow_32bit.phpt diff --git a/Zend/tests/hex_overflow_32bit.phpt b/Zend/tests/hex_overflow_32bit.phpt new file mode 100644 index 0000000000..34306ccc53 --- /dev/null +++ b/Zend/tests/hex_overflow_32bit.phpt @@ -0,0 +1,27 @@ +--TEST-- +testing integer overflow (32bit) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +float(4083360297110%d) +float(4.7223664828%dE+21) +float(1.3521606402%dE+31) +float(1.9807040628%dE+27) +Done diff --git a/Zend/tests/oct_overflow_32bit.phpt b/Zend/tests/oct_overflow_32bit.phpt new file mode 100644 index 0000000000..77befbaa7a --- /dev/null +++ b/Zend/tests/oct_overflow_32bit.phpt @@ -0,0 +1,29 @@ +--TEST-- +testing integer overflow (32bit) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +float(4308640384%d) +float(3545655%d) +float(262143) +float(549755813%d) +float(1884877076%d) +Done diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index bf76d9773c..ca0912323f 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1247,7 +1247,11 @@ NEWLINE ("\r"|"\n"|"\r\n") errno = 0; zendlval->value.lval = strtol(yytext, NULL, 0); if (errno == ERANGE) { /* Overflow */ - zendlval->value.dval = zend_strtod(yytext, NULL); + if (yytext[0] == '0') { /* octal overflow */ + zendlval->value.dval = zend_oct_strtod(yytext, NULL); + } else { + zendlval->value.dval = zend_strtod(yytext, NULL); + } zendlval->type = IS_DOUBLE; return T_DNUMBER; } diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c index 94d1383aa2..49b591da14 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -2604,6 +2604,34 @@ ZEND_API double zend_hex_strtod(const char *str, char **endptr) return value; } +ZEND_API double zend_oct_strtod(const char *str, char **endptr) +{ + const char *s = str; + char c; + double value = 0; + int any = 0; + + /* skip leading zero */ + s++; + + while ((c = *s++)) { + if (c > '7') { + /* break and return the current value if the number is not well-formed + * that's what Linux strtol() does + */ + break; + } + value = value * 8 + c - '0'; + any = 1; + } + + if (endptr != NULL) { + *endptr = (char *)(any ? s - 1 : str); + } + + return value; +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_strtod.h b/Zend/zend_strtod.h index 2dfe5a1a60..f4e066a58a 100644 --- a/Zend/zend_strtod.h +++ b/Zend/zend_strtod.h @@ -29,6 +29,7 @@ ZEND_API void zend_freedtoa(char *s); ZEND_API char * zend_dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve); ZEND_API double zend_strtod(const char *s00, char **se); ZEND_API double zend_hex_strtod(const char *str, char **endptr); +ZEND_API double zend_oct_strtod(const char *str, char **endptr); ZEND_API int zend_startup_strtod(void); ZEND_API int zend_shutdown_strtod(void); END_EXTERN_C() -- cgit v1.2.1