summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend-scanner.l4
-rw-r--r--Zend/zend_operators.c42
-rw-r--r--Zend/zend_operators.h2
3 files changed, 46 insertions, 2 deletions
diff --git a/Zend/zend-scanner.l b/Zend/zend-scanner.l
index d1ff0b28a5..3db1f7e96a 100644
--- a/Zend/zend-scanner.l
+++ b/Zend/zend-scanner.l
@@ -1133,7 +1133,7 @@ ESCAPED_AND_WHITESPACE [\n\t\r #'.:;,()|^&+-/*=%!~<>?@]+
errno = 0;
zendlval->value.lval = strtol(yytext, NULL, 0);
if (errno == ERANGE) { /* overflow */
- zendlval->value.dval = strtod(yytext,NULL);
+ zendlval->value.dval = zend_string_to_double(yytext, yyleng);
zendlval->type = IS_DOUBLE;
return T_DNUMBER;
} else {
@@ -1150,7 +1150,7 @@ ESCAPED_AND_WHITESPACE [\n\t\r #'.:;,()|^&+-/*=%!~<>?@]+
}
<ST_IN_SCRIPTING>{DNUM}|{EXPONENT_DNUM} {
- zendlval->value.dval = strtod(yytext,NULL);
+ zendlval->value.dval = zend_string_to_double(yytext, yyleng);
zendlval->type = IS_DOUBLE;
return T_DNUMBER;
}
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 95b682ee1b..a058083ef8 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -49,6 +49,48 @@
#include "ext/bcmath/number.h"
#endif
+ZEND_API double zend_string_to_double(const char *number, zend_uint length)
+{
+ zend_uint i=0;
+ double divisor = 10.0;
+ double result = 0.0;
+ double exponent;
+
+ if (!length) {
+ return result;
+ }
+
+ for (i=0; i<length; i++) {
+ if ((number[i] <= '9' && number[i] >= '0')) {
+ result *= 10;
+ result += number[i] - '0';
+ } else if (number[i] == '.') {
+ i++;
+ break;
+ } else if (toupper(number[i]) == 'E') {
+ exponent = (double) atoi(&number[i+1]);
+ result *= pow(10.0, exponent);
+ return result;
+ } else {
+ return result;
+ }
+ }
+
+ for (; i<length; i++) {
+ if ((number[i] <= '9' && number[i] >= '0')) {
+ result += (number[i] - '0') / divisor;
+ divisor *= 10;
+ } else if (toupper(number[i]) == 'E') {
+ exponent = (double) atoi(&number[i+1]);
+ result *= pow(10.0, exponent);
+ return result;
+ } else {
+ return result;
+ }
+ }
+ return result;
+}
+
ZEND_API void convert_scalar_to_number(zval *op)
{
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 9e1ced2c70..d906660a46 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -65,6 +65,8 @@ ZEND_API void convert_to_object(zval *op);
ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2);
ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2);
#define convert_to_string(op) _convert_to_string((op) ZEND_FILE_LINE_CC)
+
+ZEND_API double zend_string_to_double(const char *number, zend_uint length);
END_EXTERN_C()
ZEND_API int zval_is_true(zval *op);