Skip to content

Commit 0ad90c5

Browse files
committed
Fix parseInt when passing empty string.
Before allocating buffer for the string first we check that the length of it is greater then 0. If not then the result is a NaN. JerryScript-DCO-1.0-Signed-off-by: Peter Gal pgal.u-szeged@partner.samsung.com
1 parent c7a47c1 commit 0ad90c5

File tree

2 files changed

+118
-107
lines changed

2 files changed

+118
-107
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-global.cpp

Lines changed: 117 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -113,147 +113,157 @@ ecma_builtin_global_object_parse_int (ecma_value_t this_arg __attr_unused___, /*
113113
ecma_string_t *number_str_p = ecma_get_string_from_value (string_var);
114114
lit_utf8_size_t str_size = ecma_string_get_size (number_str_p);
115115

116-
MEM_DEFINE_LOCAL_ARRAY (utf8_string_buff, str_size, lit_utf8_byte_t);
117-
118-
ssize_t bytes_copied = ecma_string_to_utf8_string (number_str_p,
119-
utf8_string_buff,
120-
(ssize_t) str_size);
121-
JERRY_ASSERT (bytes_copied >= 0);
122-
utf8_string_buff[str_size] = LIT_BYTE_NULL;
123-
124-
/* 2. Remove leading whitespace. */
125-
ecma_length_t start = str_size;
126-
ecma_length_t end = str_size;
127-
for (ecma_length_t i = 0; i < end; i++)
116+
if (str_size > 0)
128117
{
129-
if (!lit_char_is_white_space (utf8_string_buff[i])
130-
&& !lit_char_is_line_terminator (utf8_string_buff[i]))
118+
MEM_DEFINE_LOCAL_ARRAY (utf8_string_buff, str_size, lit_utf8_byte_t);
119+
120+
ssize_t bytes_copied = ecma_string_to_utf8_string (number_str_p,
121+
utf8_string_buff,
122+
(ssize_t) str_size);
123+
JERRY_ASSERT (bytes_copied >= 0);
124+
utf8_string_buff[str_size] = LIT_BYTE_NULL;
125+
126+
/* 2. Remove leading whitespace. */
127+
ecma_length_t start = str_size;
128+
ecma_length_t end = str_size;
129+
for (ecma_length_t i = 0; i < end; i++)
131130
{
132-
start = i;
133-
break;
131+
if (!lit_char_is_white_space (utf8_string_buff[i])
132+
&& !lit_char_is_line_terminator (utf8_string_buff[i]))
133+
{
134+
start = i;
135+
break;
136+
}
134137
}
135-
}
136-
137-
/* 3. */
138-
int sign = 1;
139138

140-
/* 4. */
141-
if (utf8_string_buff[start] == '-')
142-
{
143-
sign = -1;
144-
}
139+
/* 3. */
140+
int sign = 1;
145141

146-
/* 5. */
147-
if (utf8_string_buff[start] == '-' || utf8_string_buff[start] == '+')
148-
{
149-
start++;
150-
}
151-
152-
/* 6. */
153-
ECMA_OP_TO_NUMBER_TRY_CATCH (radix_num, radix, ret_value);
154-
int32_t rad = ecma_number_to_int32 (radix_num);
155-
156-
/* 7.*/
157-
bool strip_prefix = true;
158-
159-
/* 8. */
160-
if (rad != 0)
161-
{
162-
/* 8.a */
163-
if (rad < 2 || rad > 36)
142+
/* 4. */
143+
if (utf8_string_buff[start] == '-')
164144
{
165-
ecma_number_t *ret_num_p = ecma_alloc_number ();
166-
*ret_num_p = ecma_number_make_nan ();
167-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
145+
sign = -1;
168146
}
169-
/* 8.b */
170-
else if (rad != 16)
147+
148+
/* 5. */
149+
if (utf8_string_buff[start] == '-' || utf8_string_buff[start] == '+')
171150
{
172-
strip_prefix = false;
151+
start++;
173152
}
174-
}
175-
/* 9. */
176-
else
177-
{
178-
rad = 10;
179-
}
180153

181-
if (ecma_is_completion_value_empty (ret_value))
182-
{
183-
/* 10. */
184-
if (strip_prefix)
185-
{
186-
if (end - start >= 2
187-
&& utf8_string_buff[start] == '0'
188-
&& (utf8_string_buff[start + 1] == 'x' || utf8_string_buff[start + 1] == 'X'))
189-
{
190-
start += 2;
154+
/* 6. */
155+
ECMA_OP_TO_NUMBER_TRY_CATCH (radix_num, radix, ret_value);
156+
int32_t rad = ecma_number_to_int32 (radix_num);
191157

192-
rad = 16;
193-
}
194-
}
158+
/* 7.*/
159+
bool strip_prefix = true;
195160

196-
/* 11. Check if characters are in [0, Radix - 1]. We also convert them to number values in the process. */
197-
for (lit_utf8_size_t i = start; i < end; i++)
161+
/* 8. */
162+
if (rad != 0)
198163
{
199-
if ((utf8_string_buff[i]) >= 'a' && utf8_string_buff[i] <= 'z')
164+
/* 8.a */
165+
if (rad < 2 || rad > 36)
200166
{
201-
utf8_string_buff[i] = (lit_utf8_byte_t) (utf8_string_buff[i] - 'a' + 10);
167+
ecma_number_t *ret_num_p = ecma_alloc_number ();
168+
*ret_num_p = ecma_number_make_nan ();
169+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
202170
}
203-
else if (utf8_string_buff[i] >= 'A' && utf8_string_buff[i] <= 'Z')
171+
/* 8.b */
172+
else if (rad != 16)
204173
{
205-
utf8_string_buff[i] = (lit_utf8_byte_t) (utf8_string_buff[i] - 'A' + 10);
174+
strip_prefix = false;
206175
}
207-
else if (lit_char_is_decimal_digit (utf8_string_buff[i]))
176+
}
177+
/* 9. */
178+
else
179+
{
180+
rad = 10;
181+
}
182+
183+
if (ecma_is_completion_value_empty (ret_value))
184+
{
185+
/* 10. */
186+
if (strip_prefix)
208187
{
209-
utf8_string_buff[i] = (lit_utf8_byte_t) (utf8_string_buff[i] - '0');
188+
if (end - start >= 2
189+
&& utf8_string_buff[start] == '0'
190+
&& (utf8_string_buff[start + 1] == 'x' || utf8_string_buff[start + 1] == 'X'))
191+
{
192+
start += 2;
193+
194+
rad = 16;
195+
}
210196
}
211-
else
197+
198+
/* 11. Check if characters are in [0, Radix - 1]. We also convert them to number values in the process. */
199+
for (lit_utf8_size_t i = start; i < end; i++)
212200
{
213-
/* Not a valid number char, set value to radix so it fails to pass as a valid character. */
214-
utf8_string_buff[i] = (lit_utf8_byte_t) rad;
201+
if ((utf8_string_buff[i]) >= 'a' && utf8_string_buff[i] <= 'z')
202+
{
203+
utf8_string_buff[i] = (lit_utf8_byte_t) (utf8_string_buff[i] - 'a' + 10);
204+
}
205+
else if (utf8_string_buff[i] >= 'A' && utf8_string_buff[i] <= 'Z')
206+
{
207+
utf8_string_buff[i] = (lit_utf8_byte_t) (utf8_string_buff[i] - 'A' + 10);
208+
}
209+
else if (lit_char_is_decimal_digit (utf8_string_buff[i]))
210+
{
211+
utf8_string_buff[i] = (lit_utf8_byte_t) (utf8_string_buff[i] - '0');
212+
}
213+
else
214+
{
215+
/* Not a valid number char, set value to radix so it fails to pass as a valid character. */
216+
utf8_string_buff[i] = (lit_utf8_byte_t) rad;
217+
}
218+
219+
if (!(utf8_string_buff[i] < rad))
220+
{
221+
end = i;
222+
break;
223+
}
215224
}
216225

217-
if (!(utf8_string_buff[i] < rad))
226+
/* 12. */
227+
if (end - start == 0)
218228
{
219-
end = i;
220-
break;
229+
ecma_number_t *ret_num_p = ecma_alloc_number ();
230+
*ret_num_p = ecma_number_make_nan ();
231+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
221232
}
222233
}
223234

224-
/* 12. */
225-
if (end - start == 0)
235+
if (ecma_is_completion_value_empty (ret_value))
226236
{
227-
ecma_number_t *ret_num_p = ecma_alloc_number ();
228-
*ret_num_p = ecma_number_make_nan ();
229-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
230-
}
231-
}
237+
ecma_number_t *value_p = ecma_alloc_number ();
238+
*value_p = 0;
239+
ecma_number_t multiplier = 1.0f;
232240

233-
if (ecma_is_completion_value_empty (ret_value))
234-
{
235-
ecma_number_t *value_p = ecma_alloc_number ();
236-
*value_p = 0;
237-
ecma_number_t multiplier = 1.0f;
241+
/* 13. and 14. */
242+
for (int32_t i = (int32_t) end - 1; i >= (int32_t) start; i--)
243+
{
244+
*value_p += (ecma_number_t) utf8_string_buff[i] * multiplier;
245+
multiplier *= (ecma_number_t) rad;
246+
}
238247

239-
/* 13. and 14. */
240-
for (int32_t i = (int32_t) end - 1; i >= (int32_t) start; i--)
241-
{
242-
*value_p += (ecma_number_t) utf8_string_buff[i] * multiplier;
243-
multiplier *= (ecma_number_t) rad;
244-
}
248+
/* 15. */
249+
if (sign < 0)
250+
{
251+
*value_p *= (ecma_number_t) sign;
252+
}
245253

246-
/* 15. */
247-
if (sign < 0)
248-
{
249-
*value_p *= (ecma_number_t) sign;
254+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (value_p));
250255
}
251256

252-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (value_p));
257+
ECMA_OP_TO_NUMBER_FINALIZE (radix_num);
258+
MEM_FINALIZE_LOCAL_ARRAY (utf8_string_buff);
259+
}
260+
else
261+
{
262+
ecma_number_t *ret_num_p = ecma_alloc_number ();
263+
*ret_num_p = ecma_number_make_nan ();
264+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
253265
}
254266

255-
ECMA_OP_TO_NUMBER_FINALIZE (radix_num);
256-
MEM_FINALIZE_LOCAL_ARRAY (utf8_string_buff);
257267
ECMA_FINALIZE (string_var);
258268
return ret_value;
259269
} /* ecma_builtin_global_object_parse_int */

tests/jerry/global-parseint.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ assert(parseInt("ABC", 16) === 2748);
2727
assert(parseInt("12A3") === 12);
2828
assert(parseInt("12.34") === 12);
2929
assert(isNaN(parseInt("AB")));
30+
assert(isNaN(parseInt("")));
3031

3132
var bool = true;
3233
var obj = new Object();

0 commit comments

Comments
 (0)