Skip to content

Commit db5ec79

Browse files
committed
Fixes ecma_uint32_to_utf8_string that fill \0 at the end of string
Closes: #5194 JerryScript-DCO-1.0-Signed-off-by: Yonggang Luo [email protected]
1 parent b9c0a58 commit db5ec79

File tree

8 files changed

+62
-35
lines changed

8 files changed

+62
-35
lines changed

jerry-core/api/jerry-snapshot.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -1502,11 +1502,13 @@ jerry_append_number_to_buffer (uint8_t *buffer_p, /**< buffer */
15021502
uint8_t *buffer_end_p, /**< the end of the buffer */
15031503
lit_utf8_size_t number) /**< number */
15041504
{
1505-
lit_utf8_byte_t uint32_to_str_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1505+
lit_utf8_byte_t uint32_to_str_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
15061506
lit_utf8_size_t utf8_str_size =
1507-
ecma_uint32_to_utf8_string (number, uint32_to_str_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1507+
ecma_uint32_to_utf8_string (number,
1508+
uint32_to_str_buffer,
1509+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
15081510

1509-
JERRY_ASSERT (utf8_str_size <= ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1511+
JERRY_ASSERT (utf8_str_size < ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
15101512

15111513
return jerry_append_chars_to_buffer (buffer_p,
15121514
buffer_end_p,

jerry-core/ecma/base/ecma-globals.h

+6
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,12 @@ typedef float ecma_number_t;
13791379
*/
13801380
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 10
13811381

1382+
/**
1383+
* Maximum number of characters in string representation of ecma-uint32 plus one.
1384+
* That is the '\0' terminator
1385+
*/
1386+
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED (ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 + 1)
1387+
13821388
/**
13831389
* String is not a valid array index.
13841390
*/

jerry-core/ecma/base/ecma-helpers-conversion.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,8 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
662662
lit_utf8_byte_t *out_buffer_p, /**< buffer for string */
663663
lit_utf8_size_t buffer_size) /**< size of buffer */
664664
{
665-
lit_utf8_byte_t *buf_p = out_buffer_p + buffer_size;
665+
lit_utf8_byte_t *buf_p_tail = out_buffer_p + buffer_size - 1;
666+
lit_utf8_byte_t *buf_p = buf_p_tail;
666667

667668
do
668669
{
@@ -675,12 +676,13 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
675676

676677
JERRY_ASSERT (buf_p >= out_buffer_p);
677678

678-
lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (out_buffer_p + buffer_size - buf_p);
679+
lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (buf_p_tail - buf_p);
679680

680681
if (JERRY_LIKELY (buf_p != out_buffer_p))
681682
{
682683
memmove (out_buffer_p, buf_p, bytes_copied);
683684
}
685+
buf_p[bytes_copied] = '\0';
684686

685687
return bytes_copied;
686688
} /* ecma_uint32_to_utf8_string */
@@ -868,7 +870,7 @@ ecma_number_to_utf8_string (ecma_number_t num, /**< ecma-number */
868870
if (((ecma_number_t) num_uint32) == num)
869871
{
870872
dst_p += ecma_uint32_to_utf8_string (num_uint32, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
871-
JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
873+
JERRY_ASSERT (dst_p < buffer_p + buffer_size);
872874
return (lit_utf8_size_t) (dst_p - buffer_p);
873875
}
874876

@@ -935,7 +937,7 @@ ecma_number_to_utf8_string (ecma_number_t num, /**< ecma-number */
935937

936938
dst_p += ecma_uint32_to_utf8_string (t, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
937939

938-
JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
940+
JERRY_ASSERT (dst_p < buffer_p + buffer_size);
939941

940942
return (lit_utf8_size_t) (dst_p - buffer_p);
941943
} /* ecma_number_to_utf8_string */

jerry-core/ecma/base/ecma-helpers-string.c

+21-17
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,8 @@ ecma_append_chars_to_string (ecma_string_t *string1_p, /**< base ecma-string */
746746
return ecma_get_magic_string (magic_string_id);
747747
}
748748

749-
if ((cesu8_string1_flags & ECMA_STRING_FLAG_IS_UINT32) && new_size < ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32)
749+
if ((cesu8_string1_flags & ECMA_STRING_FLAG_IS_UINT32)
750+
&& new_size < ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED)
750751
{
751752
memcpy (cesu8_string1_uint32_buffer + cesu8_string1.size, cesu8_string2_p, cesu8_string2_size);
752753

@@ -1061,8 +1062,9 @@ ecma_uint32_to_buffer (uint32_t num, /**< number */
10611062
lit_utf8_byte_t *buffer_p /**< destination buffer */,
10621063
lit_utf8_size_t buffer_size /**< buffer size */)
10631064
{
1064-
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1065-
lit_utf8_size_t digit_count = ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1065+
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1066+
lit_utf8_size_t digit_count =
1067+
ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
10661068

10671069
digit_count = JERRY_MIN (buffer_size, digit_count);
10681070
memcpy (buffer_p, digits, digit_count);
@@ -1170,7 +1172,7 @@ ecma_string_to_cesu8_bytes (const ecma_string_t *string_desc_p, /**< ecma-string
11701172
*
11711173
* @return size in bytes
11721174
*/
1173-
static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
1175+
extern inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
11741176
ecma_string_get_uint32_size (const uint32_t uint32_number) /**< number in the string-descriptor */
11751177
{
11761178
uint32_t prev_number = 1;
@@ -1268,11 +1270,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
12681270
}
12691271
else
12701272
{
1271-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1273+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
12721274
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
12731275
}
12741276

1275-
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size);
1277+
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
12761278

12771279
JERRY_ASSERT (length == size);
12781280
*flags_p |= ECMA_STRING_FLAG_IS_UINT32;
@@ -1319,11 +1321,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13191321
}
13201322
else
13211323
{
1322-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1324+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
13231325
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
13241326
}
13251327

1326-
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size);
1328+
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
13271329

13281330
JERRY_ASSERT (length == size);
13291331
*flags_p |= ECMA_STRING_FLAG_IS_UINT32 | ECMA_STRING_FLAG_REHASH_NEEDED;
@@ -1689,8 +1691,8 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
16891691
const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
16901692
lit_utf8_size_t utf8_string1_size, utf8_string2_size;
16911693

1692-
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1693-
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1694+
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1695+
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
16941696

16951697
if (ECMA_IS_DIRECT_STRING (string1_p))
16961698
{
@@ -1702,7 +1704,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17021704
{
17031705
utf8_string1_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string1_p),
17041706
uint32_to_string_buffer1,
1705-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1707+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17061708
utf8_string1_p = uint32_to_string_buffer1;
17071709
}
17081710
}
@@ -1718,7 +1720,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17181720
{
17191721
utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
17201722
uint32_to_string_buffer1,
1721-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1723+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17221724
utf8_string1_p = uint32_to_string_buffer1;
17231725
}
17241726
}
@@ -1733,7 +1735,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17331735
{
17341736
utf8_string2_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string2_p),
17351737
uint32_to_string_buffer2,
1736-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1738+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17371739
utf8_string2_p = uint32_to_string_buffer2;
17381740
}
17391741
}
@@ -1749,7 +1751,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17491751
{
17501752
utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
17511753
uint32_to_string_buffer2,
1752-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1754+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17531755
utf8_string2_p = uint32_to_string_buffer2;
17541756
}
17551757
}
@@ -2034,7 +2036,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20342036
{
20352037
JERRY_ASSERT (index < ecma_string_get_length (string_p));
20362038

2037-
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
2039+
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
20382040

20392041
if (ECMA_IS_DIRECT_STRING (string_p))
20402042
{
@@ -2059,7 +2061,9 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20592061
JERRY_ASSERT (ECMA_GET_DIRECT_STRING_TYPE (string_p) == ECMA_DIRECT_STRING_UINT);
20602062
uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);
20612063

2062-
ecma_uint32_to_utf8_string (uint32_number, uint32_to_string_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2064+
ecma_uint32_to_utf8_string (uint32_number,
2065+
uint32_to_string_buffer,
2066+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
20632067

20642068
return (ecma_char_t) uint32_to_string_buffer[index];
20652069
}
@@ -2105,7 +2109,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
21052109
{
21062110
ecma_uint32_to_utf8_string (string_p->u.uint32_number,
21072111
uint32_to_string_buffer,
2108-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2112+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
21092113

21102114
return (ecma_char_t) uint32_to_string_buffer[index];
21112115
}

jerry-core/ecma/base/ecma-helpers.h

+9-8
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ typedef enum
113113
utf8_str) /**< [out] lit_utf8_string_t to get */ \
114114
lit_utf8_string_t utf8_str; \
115115
uint8_t utf8_str##_flags = ECMA_STRING_FLAG_EMPTY; \
116-
lit_utf8_byte_t utf8_str##_uint32_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32]; \
116+
lit_utf8_byte_t utf8_str##_uint32_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED]; \
117117
(void) ecma_string_get_chars (ecma_str_ptr, &utf8_str, utf8_str##_uint32_buffer, &utf8_str##_flags); \
118118
JERRY_ASSERT (!(utf8_str##_flags & ECMA_STRING_FLAG_MUST_BE_FREED));
119119

@@ -125,13 +125,13 @@ typedef enum
125125
* The string length name is `utf8_str##_length`
126126
*
127127
*/
128-
#define ECMA_STRING_TO_UTF8_STRING_AND_LENGTH(ecma_str_ptr, /**< ecma string pointer */ \
129-
utf8_str) /**< [out] lit_utf8_string_t to get */ \
130-
lit_utf8_string_t utf8_str; \
131-
uint8_t utf8_str##_flags = ECMA_STRING_FLAG_IS_ASCII; \
132-
lit_utf8_byte_t utf8_str##_uint32_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32]; \
133-
lit_utf8_size_t utf8_str##_length = \
134-
ecma_string_get_chars (ecma_str_ptr, &utf8_str, utf8_str##_uint32_buffer, &utf8_str##_flags); \
128+
#define ECMA_STRING_TO_UTF8_STRING_AND_LENGTH(ecma_str_ptr, /**< ecma string pointer */ \
129+
utf8_str) /**< [out] lit_utf8_string_t to get */ \
130+
lit_utf8_string_t utf8_str; \
131+
uint8_t utf8_str##_flags = ECMA_STRING_FLAG_IS_ASCII; \
132+
lit_utf8_byte_t utf8_str##_uint32_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED]; \
133+
lit_utf8_size_t utf8_str##_length = \
134+
ecma_string_get_chars (ecma_str_ptr, &utf8_str, utf8_str##_uint32_buffer, &utf8_str##_flags); \
135135
JERRY_ASSERT (!(utf8_str##_flags & ECMA_STRING_FLAG_MUST_BE_FREED));
136136

137137
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
@@ -518,6 +518,7 @@ ecma_number_t ecma_utf8_string_to_number_by_radix (const lit_utf8_byte_t *str_p,
518518
lit_utf8_size_t str_size,
519519
uint32_t radix,
520520
uint32_t option);
521+
lit_utf8_size_t ecma_string_get_uint32_size (const uint32_t uint32_number);
521522
lit_utf8_size_t ecma_uint32_to_utf8_string (uint32_t value, lit_utf8_byte_t *out_buffer_p, lit_utf8_size_t buffer_size);
522523
uint32_t ecma_number_to_uint32 (ecma_number_t num);
523524
int32_t ecma_number_to_int32 (ecma_number_t num);

jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ ecma_builtin_number_prototype_object_to_number_convert (ecma_number_t this_num,
525525
}
526526

527527
/* Append exponent part */
528-
lit_utf8_size_t exp_size = ecma_uint32_to_utf8_string ((uint32_t) exponent, digits, 3);
528+
lit_utf8_size_t exp_size = ecma_uint32_to_utf8_string ((uint32_t) exponent, digits, 3 + 1);
529529
ecma_stringbuilder_append_raw (&builder, digits, exp_size);
530530

531531
return ecma_make_string_value (ecma_stringbuilder_finalize (&builder));

jerry-core/parser/js/js-parser.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -2418,12 +2418,12 @@ parser_parse_source (void *source_p, /**< source code */
24182418

24192419
if (context.global_status_flags & ECMA_PARSE_INTERNAL_FREE_SOURCE)
24202420
{
2421-
jmem_heap_free_block ((void *) context.source.ptr, context.source.size);
2421+
jmem_heap_free_block ((void *) context.source.ptr, context.source.size + 1);
24222422
}
24232423

24242424
if (context.global_status_flags & ECMA_PARSE_INTERNAL_FREE_ARG_LIST)
24252425
{
2426-
jmem_heap_free_block ((void *) context.arguments.ptr, context.arguments.size);
2426+
jmem_heap_free_block ((void *) context.arguments.ptr, context.arguments.size + 1);
24272427
}
24282428

24292429
if (compiled_code_p != NULL)

tests/unit-core/test-number-to-string.c

+12
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,17 @@ main (void)
5050
}
5151
}
5252

53+
lit_utf8_byte_t val_uint32_max_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED] = { 0 };
54+
memset (val_uint32_max_buffer, 0xFF, sizeof (val_uint32_max_buffer));
55+
56+
TEST_ASSERT (ecma_string_get_uint32_size (UINT32_MAX) == 10);
57+
TEST_ASSERT (ecma_string_get_uint32_size (0) == 1);
58+
TEST_ASSERT (ecma_string_get_uint32_size (10) == 2);
59+
lit_utf8_size_t digits = ecma_uint32_to_utf8_string (UINT32_MAX,
60+
val_uint32_max_buffer,
61+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
62+
TEST_ASSERT (digits == 10);
63+
TEST_ASSERT (val_uint32_max_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32] == 0);
64+
5365
return 0;
5466
} /* main */

0 commit comments

Comments
 (0)