Skip to content

Commit bf25b9f

Browse files
committed
Fix assertion fails in parseInt()
JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai.u-szeged@partner.samsung.com
1 parent af56cd8 commit bf25b9f

File tree

2 files changed

+135
-114
lines changed

2 files changed

+135
-114
lines changed

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

Lines changed: 131 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -236,160 +236,177 @@ ecma_builtin_global_object_parse_int (ecma_value_t this_arg __attr_unused___, /*
236236
}
237237
}
238238

239-
/* 3. */
240-
int sign = 1;
241-
242-
/* 4. */
243-
ecma_char_t current = lit_utf8_iterator_read_next (&iter);
244-
if (current == LIT_CHAR_MINUS)
239+
if (!lit_utf8_iterator_is_eos (&iter))
245240
{
246-
sign = -1;
247-
}
241+
/* 3. */
242+
int sign = 1;
248243

249-
/* 5. */
250-
if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
251-
{
252-
start = lit_utf8_iterator_get_pos (&iter);
253-
if (!lit_utf8_iterator_is_eos (&iter))
244+
/* 4. */
245+
ecma_char_t current = lit_utf8_iterator_read_next (&iter);
246+
if (current == LIT_CHAR_MINUS)
254247
{
255-
current = lit_utf8_iterator_read_next (&iter);
248+
sign = -1;
256249
}
257-
}
258250

259-
/* 6. */
260-
ECMA_OP_TO_NUMBER_TRY_CATCH (radix_num, radix, ret_value);
261-
int32_t rad = ecma_number_to_int32 (radix_num);
251+
/* 5. */
252+
if (current == LIT_CHAR_MINUS || current == LIT_CHAR_PLUS)
253+
{
254+
start = lit_utf8_iterator_get_pos (&iter);
255+
if (!lit_utf8_iterator_is_eos (&iter))
256+
{
257+
current = lit_utf8_iterator_read_next (&iter);
258+
}
259+
}
262260

263-
/* 7.*/
264-
bool strip_prefix = true;
261+
/* 6. */
262+
ECMA_OP_TO_NUMBER_TRY_CATCH (radix_num, radix, ret_value);
263+
int32_t rad = ecma_number_to_int32 (radix_num);
265264

266-
/* 8. */
267-
if (rad != 0)
268-
{
269-
/* 8.a */
270-
if (rad < 2 || rad > 36)
265+
/* 7.*/
266+
bool strip_prefix = true;
267+
268+
/* 8. */
269+
if (rad != 0)
271270
{
272-
ecma_number_t *ret_num_p = ecma_alloc_number ();
273-
*ret_num_p = ecma_number_make_nan ();
274-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
271+
/* 8.a */
272+
if (rad < 2 || rad > 36)
273+
{
274+
ecma_number_t *ret_num_p = ecma_alloc_number ();
275+
*ret_num_p = ecma_number_make_nan ();
276+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
277+
}
278+
/* 8.b */
279+
else if (rad != 16)
280+
{
281+
strip_prefix = false;
282+
}
275283
}
276-
/* 8.b */
277-
else if (rad != 16)
284+
/* 9. */
285+
else
278286
{
279-
strip_prefix = false;
287+
rad = 10;
280288
}
281-
}
282-
/* 9. */
283-
else
284-
{
285-
rad = 10;
286-
}
287289

288-
if (ecma_is_completion_value_empty (ret_value))
289-
{
290-
/* 10. */
291-
if (strip_prefix)
290+
if (ecma_is_completion_value_empty (ret_value))
292291
{
293-
if (end.offset - start.offset >= 2 && current == LIT_CHAR_0)
292+
/* 10. */
293+
if (strip_prefix)
294294
{
295-
ecma_char_t next = lit_utf8_iterator_peek_next (&iter);
296-
if (next == LIT_CHAR_LOWERCASE_X || next == LIT_CHAR_UPPERCASE_X)
295+
if (end.offset - start.offset >= 2 && current == LIT_CHAR_0)
297296
{
298-
/* Skip the 'x' or 'X' characters. */
299-
lit_utf8_iterator_incr (&iter);
300-
start = lit_utf8_iterator_get_pos (&iter);
301-
302-
rad = 16;
297+
ecma_char_t next = lit_utf8_iterator_peek_next (&iter);
298+
if (next == LIT_CHAR_LOWERCASE_X || next == LIT_CHAR_UPPERCASE_X)
299+
{
300+
/* Skip the 'x' or 'X' characters. */
301+
lit_utf8_iterator_incr (&iter);
302+
start = lit_utf8_iterator_get_pos (&iter);
303+
304+
rad = 16;
305+
}
303306
}
304307
}
305-
}
306308

307-
/* 11. Check if characters are in [0, Radix - 1]. We also convert them to number values in the process. */
308-
lit_utf8_iterator_seek (&iter, start);
309-
while (!lit_utf8_iterator_is_eos (&iter))
310-
{
311-
ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
312-
int32_t current_number;
313-
314-
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
315-
{
316-
current_number = current_char - LIT_CHAR_LOWERCASE_A + 10;
317-
}
318-
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
309+
/* 11. Check if characters are in [0, Radix - 1]. We also convert them to number values in the process. */
310+
lit_utf8_iterator_seek (&iter, start);
311+
while (!lit_utf8_iterator_is_eos (&iter))
319312
{
320-
current_number = current_char - LIT_CHAR_UPPERCASE_A + 10;
321-
}
322-
else if (lit_char_is_decimal_digit (current_char))
323-
{
324-
current_number = current_char - LIT_CHAR_0;
325-
}
326-
else
327-
{
328-
/* Not a valid number char, set value to radix so it fails to pass as a valid character. */
329-
current_number = rad;
313+
ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
314+
int32_t current_number;
315+
316+
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
317+
{
318+
current_number = current_char - LIT_CHAR_LOWERCASE_A + 10;
319+
}
320+
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
321+
{
322+
current_number = current_char - LIT_CHAR_UPPERCASE_A + 10;
323+
}
324+
else if (lit_char_is_decimal_digit (current_char))
325+
{
326+
current_number = current_char - LIT_CHAR_0;
327+
}
328+
else
329+
{
330+
/* Not a valid number char, set value to radix so it fails to pass as a valid character. */
331+
current_number = rad;
332+
}
333+
334+
if (!(current_number < rad))
335+
{
336+
lit_utf8_iterator_decr (&iter);
337+
end = lit_utf8_iterator_get_pos (&iter);
338+
break;
339+
}
330340
}
331341

332-
if (!(current_number < rad))
342+
/* 12. */
343+
if (end.offset - start.offset == 0)
333344
{
334-
lit_utf8_iterator_decr (&iter);
335-
end = lit_utf8_iterator_get_pos (&iter);
336-
break;
345+
ecma_number_t *ret_num_p = ecma_alloc_number ();
346+
*ret_num_p = ecma_number_make_nan ();
347+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
337348
}
338349
}
339350

340-
/* 12. */
341-
if (end.offset - start.offset == 0)
351+
if (ecma_is_completion_value_empty (ret_value))
342352
{
343-
ecma_number_t *ret_num_p = ecma_alloc_number ();
344-
*ret_num_p = ecma_number_make_nan ();
345-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
346-
}
347-
}
353+
ecma_number_t *value_p = ecma_alloc_number ();
354+
*value_p = 0;
355+
ecma_number_t multiplier = 1.0f;
348356

349-
if (ecma_is_completion_value_empty (ret_value))
350-
{
351-
ecma_number_t *value_p = ecma_alloc_number ();
352-
*value_p = 0;
353-
ecma_number_t multiplier = 1.0f;
354-
355-
/* 13. and 14. */
356-
lit_utf8_iterator_seek (&iter, end);
357-
while (lit_utf8_iterator_get_pos (&iter).offset > start.offset)
358-
{
359-
ecma_char_t current_char = lit_utf8_iterator_read_prev (&iter);
360-
ecma_number_t current_number;
361-
362-
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
357+
/* 13. and 14. */
358+
if (end.offset < str_size)
363359
{
364-
current_number = (ecma_number_t) current_char - LIT_CHAR_LOWERCASE_A + 10;
360+
lit_utf8_iterator_seek (&iter, end);
365361
}
366-
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
362+
else
367363
{
368-
current_number = (ecma_number_t) current_char - LIT_CHAR_UPPERCASE_A + 10;
364+
lit_utf8_iterator_seek_eos (&iter);
369365
}
370-
else if (lit_char_is_decimal_digit (current_char))
366+
while (lit_utf8_iterator_get_pos (&iter).offset > start.offset)
371367
{
372-
current_number = (ecma_number_t) current_char - LIT_CHAR_0;
368+
ecma_char_t current_char = lit_utf8_iterator_read_prev (&iter);
369+
ecma_number_t current_number;
370+
371+
if ((current_char >= LIT_CHAR_LOWERCASE_A && current_char <= LIT_CHAR_LOWERCASE_Z))
372+
{
373+
current_number = (ecma_number_t) current_char - LIT_CHAR_LOWERCASE_A + 10;
374+
}
375+
else if ((current_char >= LIT_CHAR_UPPERCASE_A && current_char <= LIT_CHAR_UPPERCASE_Z))
376+
{
377+
current_number = (ecma_number_t) current_char - LIT_CHAR_UPPERCASE_A + 10;
378+
}
379+
else if (lit_char_is_decimal_digit (current_char))
380+
{
381+
current_number = (ecma_number_t) current_char - LIT_CHAR_0;
382+
}
383+
else
384+
{
385+
JERRY_UNREACHABLE ();
386+
}
387+
388+
*value_p += current_number * multiplier;
389+
multiplier *= (ecma_number_t) rad;
373390
}
374-
else
391+
392+
/* 15. */
393+
if (sign < 0)
375394
{
376-
JERRY_UNREACHABLE ();
395+
*value_p *= (ecma_number_t) sign;
377396
}
378397

379-
*value_p += current_number * multiplier;
380-
multiplier *= (ecma_number_t) rad;
398+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (value_p));
381399
}
382400

383-
/* 15. */
384-
if (sign < 0)
385-
{
386-
*value_p *= (ecma_number_t) sign;
387-
}
388-
389-
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (value_p));
401+
ECMA_OP_TO_NUMBER_FINALIZE (radix_num);
402+
}
403+
else
404+
{
405+
ecma_number_t *ret_num_p = ecma_alloc_number ();
406+
*ret_num_p = ecma_number_make_nan ();
407+
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p));
390408
}
391409

392-
ECMA_OP_TO_NUMBER_FINALIZE (radix_num);
393410
MEM_FINALIZE_LOCAL_ARRAY (utf8_string_buff);
394411
}
395412
else

tests/jerry/global-parseint.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ assert(parseInt("\u00a0123") === 123);
3434
assert(parseInt("\u20291 123\u00D0") === 1);
3535
assert(parseInt("\u00a0123", 13) === 198);
3636
assert(parseInt("\u2029123 1\u00D0", 11) === 146);
37+
assert(isNaN(parseInt("\u0009")));
38+
assert(isNaN(parseInt("\u00A0")));
39+
assert(parseInt("\u00A0\u00A0-1") === parseInt("-1"));
40+
assert(parseInt("\u00A01") === parseInt("1"));
3741

3842
var bool = true;
3943
var obj = new Object();

0 commit comments

Comments
 (0)