From: Marcus Boerger Date: Sat, 27 Mar 2004 00:50:41 +0000 (+0000) Subject: Portable solution for bug #27646 that works correct on Windows, too X-Git-Tag: php-5.0.0RC2RC1~210 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc0373b8802e4eaf50b651de25a6b3817b4d0e2a;p=php Portable solution for bug #27646 that works correct on Windows, too --- diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 85292dcd3c..28a26b5948 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -950,7 +950,7 @@ static void basic_globals_dtor(php_basic_globals *basic_globals_p TSRMLS_DC) #define PHP_DOUBLE_INFINITY_HIGH 0x7ff00000 #define PHP_DOUBLE_QUIET_NAN_HIGH 0xfff80000 -static double php_get_nan() +PHPAPI double php_get_nan() { #if defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha) double val; @@ -963,7 +963,7 @@ static double php_get_nan() #endif } -static double php_get_inf() +PHPAPI double php_get_inf() { #if defined(__i386__) || defined(_X86_) || defined(ALPHA) || defined(_ALPHA) || defined(__alpha) double val; diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index aae3982161..468d27c444 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -231,4 +231,7 @@ typedef struct { #define SAFE_MODE_PROTECTED_ENV_VARS "LD_LIBRARY_PATH" #define SAFE_MODE_ALLOWED_ENV_VARS "PHP_" +PHPAPI double php_get_nan(); +PHPAPI double php_get_inf(); + #endif /* BASIC_FUNCTIONS_H */ diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index e00da92f60..b45ef8e7c0 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -326,6 +326,71 @@ int __tmp__() { mbstate_t a; } fi ]) +AC_CHECK_FUNCS(fpclass isinf isnan) + +AC_CACHE_CHECK(whether atof() accepts NAN, ac_cv_atof_accept_nan,[ + AC_TRY_RUN([ +#include +#include + +#ifdef HAVE_ISNAN +#define zend_isnan(a) isnan(a) +#elif defined(NAN) +#define zend_isnan(a) (((a)==NAN)?1:0) +#elif defined(HAVE_FPCLASS) +#define zend_isnan(a) ((fpclass(a) == FP_SNAN) || (fpclass(a) == FP_QNAN)) +#else +#define zend_isnan(a) 0 +#endif + +int main(int argc, char** argv) +{ + return zend_isnan(atof("NAN")) ? 0 : 1; +} + ],[ + ac_cv_atof_accept_nan=yes + ],[ + ac_cv_atof_accept_nan=no + ],[ + ac_cv_atof_accept_nan=no + ]) + if test "$ac_cv_atof_accept_nan" = "yes"; then + AC_DEFINE([HAVE_ATOF_ACCEPTS_NAN], 1, [whether atof() accepts NAN]) + fi +]) + +AC_CACHE_CHECK(whether atof() accepts INF, ac_cv_atof_accept_inf,[ + AC_TRY_RUN([ +#include +#include + +#ifdef HAVE_ISINF +#define zend_isinf(a) isinf(a) +#elif defined(INFINITY) +/* Might not work, but is required by ISO C99 */ +#define zend_isinf(a) (((a)==INFINITY)?1:0) +#elif defined(HAVE_FPCLASS) +#define zend_isinf(a) ((fpclass(a) == FP_PINF) || (fpclass(a) == FP_NINF)) +#else +#define zend_isinf(a) 0 +#endif + +int main(int argc, char** argv) +{ + return zend_isinf(atof("INF")) && zend_isinf(atof("-INF")) ? 0 : 1; +} + ],[ + ac_cv_atof_accept_inf=yes + ],[ + ac_cv_atof_accept_inf=no + ],[ + ac_cv_atof_accept_inf=no + ]) + if test "$ac_cv_atof_accept_inf" = "yes"; then + AC_DEFINE([HAVE_ATOF_ACCEPTS_INF], 1, [whether atof() accepts INF]) + fi +]) + PHP_CHECK_I18N_FUNCS PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32.c crypt.c \ diff --git a/ext/standard/tests/math/bug27646.phpt b/ext/standard/tests/math/bug27646.phpt index 064fc0a0fa..2df6d8f37a 100755 --- a/ext/standard/tests/math/bug27646.phpt +++ b/ext/standard/tests/math/bug27646.phpt @@ -3,6 +3,16 @@ Bug #27646 (Cannot serialize/unserialize non-finite numeric values) --FILE-- ---EXPECT-- +--EXPECTF-- +float(1%f) +string(%d) "d:1%s;" +float(1%f) +float(-1%f) +string(%d) "d:-1%s;" +float(-1%f) float(-INF) string(7) "d:-INF;" float(-INF) diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 9895a3b893..6ae7424b77 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -320,7 +320,24 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) return 1; } -"d:" (iv | nv | nvexp | "NAN" | "-"? "INF") ";" { +"d:" ("NAN" | "-"? "INF") ";" { + *p = YYCURSOR; + INIT_PZVAL(*rval); +#if defined(HAVE_ATOF_ACCEPTS_NAN) && defined(HAVE_ATOF_ACCEPTS_INF) + ZVAL_DOUBLE(*rval, atof(start + 2)); +#else + if (!strncmp(start + 2, "NAN", 3)) { + ZVAL_DOUBLE(*rval, php_get_nan()); + } else if (!strncmp(start + 2, "INF", 3)) { + ZVAL_DOUBLE(*rval, php_get_inf()); + } else if (!strncmp(start + 2, "-INF", 4)) { + ZVAL_DOUBLE(*rval, -php_get_inf()); + } +#endif + return 1; +} + +"d:" (iv | nv | nvexp) ";" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, atof(start + 2));