Skip to content

Commit 8722b31

Browse files
committed
MFZE1
1 parent e8f4e46 commit 8722b31

File tree

3 files changed

+58
-122
lines changed

3 files changed

+58
-122
lines changed

Zend/zend_API.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ static char *zend_parse_arg_impl(zval **arg, va_list *va, char **spec)
239239
double d;
240240
int type;
241241

242-
if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d)) == 0) {
242+
if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d, 0)) == 0) {
243243
return "long";
244244
} else if (type == IS_DOUBLE) {
245245
*p = (long) d;
@@ -273,7 +273,7 @@ static char *zend_parse_arg_impl(zval **arg, va_list *va, char **spec)
273273
long l;
274274
int type;
275275

276-
if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p)) == 0) {
276+
if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p, 0)) == 0) {
277277
return "double";
278278
} else if (type == IS_LONG) {
279279
*p = (double) l;

Zend/zend_operators.c

Lines changed: 6 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
114114
char *strval;
115115

116116
strval = op->value.str.val;
117-
switch ((op->type=is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval))) {
117+
switch ((op->type=is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval, 1))) {
118118
case IS_DOUBLE:
119119
case IS_LONG:
120120
break;
@@ -152,7 +152,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
152152
switch ((op)->type) { \
153153
case IS_STRING: \
154154
{ \
155-
switch (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval))) { \
155+
switch (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval, 1))) { \
156156
case IS_DOUBLE: \
157157
case IS_LONG: \
158158
break; \
@@ -1456,7 +1456,7 @@ ZEND_API int increment_function(zval *op1)
14561456
double dval;
14571457
char *strval = op1->value.str.val;
14581458

1459-
switch (is_numeric_string(strval, op1->value.str.len, &lval, &dval)) {
1459+
switch (is_numeric_string(strval, op1->value.str.len, &lval, &dval, 0)) {
14601460
case IS_LONG:
14611461
op1->value.lval = lval+1;
14621462
op1->type = IS_LONG;
@@ -1502,7 +1502,7 @@ ZEND_API int decrement_function(zval *op1)
15021502
op1->value.lval = -1;
15031503
op1->type = IS_LONG;
15041504
break;
1505-
} else if (is_numeric_string(op1->value.str.val, op1->value.str.len, &lval, NULL)==IS_LONG) { /* long */
1505+
} else if (is_numeric_string(op1->value.str.val, op1->value.str.len, &lval, NULL, 0)==IS_LONG) { /* long */
15061506
STR_FREE(op1->value.str.val);
15071507
op1->value.lval = lval-1;
15081508
op1->type = IS_LONG;
@@ -1627,8 +1627,8 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
16271627
long lval1, lval2;
16281628
double dval1, dval2;
16291629

1630-
if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1)) &&
1631-
(ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2))) {
1630+
if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1, 0)) &&
1631+
(ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2, 0))) {
16321632
#if 0&&WITH_BCMATH
16331633
if ((ret1==FLAG_IS_BC) || (ret2==FLAG_IS_BC)) {
16341634
bc_num first, second;
@@ -1703,83 +1703,3 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC)
17031703
}
17041704
zend_compare_symbol_tables(result, Z_OBJPROP_P(o1), Z_OBJPROP_P(o2) TSRMLS_CC);
17051705
}
1706-
1707-
1708-
/* returns 0 for non-numeric string
1709-
* returns IS_DOUBLE for floating point string, and assigns the value to *dval (if it's not NULL)
1710-
* returns IS_LONG for integer strings, and assigns the value to *lval (if it's not NULL)
1711-
* returns FLAG_IS_BC if the number might lose accuracy when converted to a double
1712-
*/
1713-
1714-
#if 0
1715-
1716-
static inline int is_numeric_string(char *str, int length, long *lval, double *dval)
1717-
{
1718-
register char *p=str, *end=str+length;
1719-
unsigned char had_period=0, had_exponent=0;
1720-
char *end_ptr;
1721-
1722-
if (!length) {
1723-
return 0;
1724-
}
1725-
switch (*p) {
1726-
case '-':
1727-
case '+':
1728-
while (*++p==' '); /* ignore spaces after the sign */
1729-
break;
1730-
default:
1731-
break;
1732-
}
1733-
while (p<end) {
1734-
if (isdigit((int)(unsigned char)*p)) {
1735-
p++;
1736-
} else if (*p=='.') {
1737-
if (had_period) {
1738-
return 0;
1739-
} else {
1740-
had_period=1;
1741-
p++;
1742-
}
1743-
} else if (*p=='e' || *p=='E') {
1744-
p++;
1745-
if (is_numeric_string(p, length - (int) (p-str), NULL, NULL)==IS_LONG) { /* valid exponent */
1746-
had_exponent=1;
1747-
break;
1748-
} else {
1749-
return 0;
1750-
}
1751-
} else {
1752-
return 0;
1753-
}
1754-
}
1755-
errno=0;
1756-
if (had_period || had_exponent) { /* floating point number */
1757-
double local_dval;
1758-
1759-
local_dval = strtod(str, &end_ptr);
1760-
if (errno==ERANGE || end_ptr != str+length) { /* overflow or bad string */
1761-
return 0;
1762-
} else {
1763-
if (dval) {
1764-
*dval = local_dval;
1765-
}
1766-
return IS_DOUBLE;
1767-
}
1768-
} else {
1769-
long local_lval;
1770-
1771-
local_lval = strtol(str, &end_ptr, 10);
1772-
if (errno==ERANGE || end_ptr != str+length) { /* overflow or bad string */
1773-
return 0;
1774-
} else {
1775-
if (lval) {
1776-
*lval = local_lval;
1777-
}
1778-
return IS_LONG;
1779-
}
1780-
}
1781-
}
1782-
1783-
1784-
1785-
#endif

Zend/zend_operators.h

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
5858
ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
5959
ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
6060

61-
static inline int is_numeric_string(char *str, int length, long *lval, double *dval)
61+
static inline int is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors)
6262
{
6363
long local_lval;
6464
double local_dval;
65-
char *end_ptr;
65+
char *end_ptr_long, *end_ptr_double;
6666
int conv_base=10;
6767

6868
if (!length) {
@@ -74,53 +74,69 @@ static inline int is_numeric_string(char *str, int length, long *lval, double *d
7474
conv_base=16;
7575
}
7676
errno=0;
77-
local_lval = strtol(str, &end_ptr, conv_base);
78-
if (errno!=ERANGE && end_ptr == str+length) { /* integer string */
79-
if (lval) {
80-
*lval = local_lval;
77+
local_lval = strtol(str, &end_ptr_long, conv_base);
78+
if (errno!=ERANGE) {
79+
if (end_ptr_long == str+length) { /* integer string */
80+
if (lval) {
81+
*lval = local_lval;
82+
}
83+
return IS_LONG;
8184
}
82-
return IS_LONG;
85+
} else {
86+
end_ptr_long=NULL;
8387
}
8488

8589
if (conv_base==16) { /* hex string, under UNIX strtod() messes it up */
8690
return 0;
8791
}
8892

8993
errno=0;
90-
local_dval = strtod(str, &end_ptr);
91-
if (errno!=ERANGE && end_ptr == str+length) { /* floating point string */
92-
if (! zend_finite(local_dval)) {
93-
/* "inf","nan" and maybe other weird ones */
94-
return 0;
95-
}
94+
local_dval = strtod(str, &end_ptr_double);
95+
if (errno!=ERANGE) {
96+
if (end_ptr_double == str+length) { /* floating point string */
97+
if (! zend_finite(local_dval)) {
98+
/* "inf","nan" and maybe other weird ones */
99+
return 0;
100+
}
96101

97-
if (dval) {
98-
*dval = local_dval;
99-
}
102+
if (dval) {
103+
*dval = local_dval;
104+
}
100105
#if 0&&WITH_BCMATH
101-
if (length>16) {
102-
register char *ptr=str, *end=str+length;
103-
104-
while (ptr<end) {
105-
switch(*ptr++) {
106-
case 'e':
107-
case 'E':
108-
/* scientific notation, not handled by the BC library */
109-
return IS_DOUBLE;
110-
break;
111-
default:
112-
break;
106+
if (length>16) {
107+
register char *ptr=str, *end=str+length;
108+
109+
while (ptr<end) {
110+
switch(*ptr++) {
111+
case 'e':
112+
case 'E':
113+
/* scientific notation, not handled by the BC library */
114+
return IS_DOUBLE;
115+
break;
116+
default:
117+
break;
118+
}
113119
}
120+
return FLAG_IS_BC;
121+
} else {
122+
return IS_DOUBLE;
114123
}
115-
return FLAG_IS_BC;
116-
} else {
117-
return IS_DOUBLE;
118-
}
119124
#else
120-
return IS_DOUBLE;
125+
return IS_DOUBLE;
121126
#endif
127+
}
128+
} else {
129+
end_ptr_double=NULL;
130+
}
131+
if (allow_errors) {
132+
if (end_ptr_double>end_ptr_long && dval) {
133+
*dval = local_dval;
134+
return IS_DOUBLE;
135+
} else if (end_ptr_long && lval) {
136+
*lval = local_lval;
137+
return IS_LONG;
138+
}
122139
}
123-
124140
return 0;
125141
}
126142

0 commit comments

Comments
 (0)