@@ -100,9 +100,12 @@ static zend_always_inline long zend_dval_to_lval(double d)
100
100
* if the number was out of long range or contained a decimal point/exponent.
101
101
* The number's value is returned into the respective pointer, *lval or *dval,
102
102
* if that pointer is not NULL.
103
+ *
104
+ * This variant also gives information if a string that represents an integer
105
+ * could not be represented as such due to overflow. It writes 1 to oflow_info
106
+ * if the integer is larger than LONG_MAX and -1 if it's smaller than LONG_MIN.
103
107
*/
104
-
105
- static inline zend_uchar is_numeric_string (const char * str , int length , long * lval , double * dval , int allow_errors )
108
+ static inline zend_uchar is_numeric_string_ex (const char * str , int length , long * lval , double * dval , int allow_errors , int * oflow_info )
106
109
{
107
110
const char * ptr ;
108
111
int base = 10 , digits = 0 , dp_or_e = 0 ;
@@ -113,6 +116,10 @@ static inline zend_uchar is_numeric_string(const char *str, int length, long *lv
113
116
return 0 ;
114
117
}
115
118
119
+ if (oflow_info != NULL ) {
120
+ * oflow_info = 0 ;
121
+ }
122
+
116
123
/* Skip any whitespace
117
124
* This is much faster than the isspace() function */
118
125
while (* str == ' ' || * str == '\t' || * str == '\n' || * str == '\r' || * str == '\v' || * str == '\f' ) {
@@ -165,13 +172,19 @@ static inline zend_uchar is_numeric_string(const char *str, int length, long *lv
165
172
166
173
if (base == 10 ) {
167
174
if (digits >= MAX_LENGTH_OF_LONG ) {
175
+ if (oflow_info != NULL ) {
176
+ * oflow_info = * str == '-' ? -1 : 1 ;
177
+ }
168
178
dp_or_e = -1 ;
169
179
goto process_double ;
170
180
}
171
181
} else if (!(digits < SIZEOF_LONG * 2 || (digits == SIZEOF_LONG * 2 && ptr [- digits ] <= '7' ))) {
172
182
if (dval ) {
173
183
local_dval = zend_hex_strtod (str , & ptr );
174
184
}
185
+ if (oflow_info != NULL ) {
186
+ * oflow_info = 1 ;
187
+ }
175
188
type = IS_DOUBLE ;
176
189
}
177
190
} else if (* ptr == '.' && ZEND_IS_DIGIT (ptr [1 ])) {
@@ -207,6 +220,9 @@ static inline zend_uchar is_numeric_string(const char *str, int length, long *lv
207
220
if (dval ) {
208
221
* dval = zend_strtod (str , NULL );
209
222
}
223
+ if (oflow_info != NULL ) {
224
+ * oflow_info = * str == '-' ? -1 : 1 ;
225
+ }
210
226
211
227
return IS_DOUBLE ;
212
228
}
@@ -226,6 +242,10 @@ static inline zend_uchar is_numeric_string(const char *str, int length, long *lv
226
242
}
227
243
}
228
244
245
+ static inline zend_uchar is_numeric_string (const char * str , int length , long * lval , double * dval , int allow_errors ) {
246
+ return is_numeric_string_ex (str , length , lval , dval , allow_errors , NULL );
247
+ }
248
+
229
249
static inline char *
230
250
zend_memnstr (char * haystack , char * needle , int needle_len , char * end )
231
251
{
0 commit comments