Skip to content

Commit eafb1b1

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 789a914 commit eafb1b1

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
@@ -659,7 +659,8 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
659659
lit_utf8_byte_t *out_buffer_p, /**< buffer for string */
660660
lit_utf8_size_t buffer_size) /**< size of buffer */
661661
{
662-
lit_utf8_byte_t *buf_p = out_buffer_p + buffer_size;
662+
lit_utf8_byte_t *buf_p_tail = out_buffer_p + buffer_size - 1;
663+
lit_utf8_byte_t *buf_p = buf_p_tail;
663664

664665
do
665666
{
@@ -672,12 +673,13 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
672673

673674
JERRY_ASSERT (buf_p >= out_buffer_p);
674675

675-
lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (out_buffer_p + buffer_size - buf_p);
676+
lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (buf_p_tail - buf_p);
676677

677678
if (JERRY_LIKELY (buf_p != out_buffer_p))
678679
{
679680
memmove (out_buffer_p, buf_p, bytes_copied);
680681
}
682+
buf_p[bytes_copied] = '\0';
681683

682684
return bytes_copied;
683685
} /* ecma_uint32_to_utf8_string */
@@ -865,7 +867,7 @@ ecma_number_to_utf8_string (ecma_number_t num, /**< ecma-number */
865867
if (((ecma_number_t) num_uint32) == num)
866868
{
867869
dst_p += ecma_uint32_to_utf8_string (num_uint32, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
868-
JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
870+
JERRY_ASSERT (dst_p < buffer_p + buffer_size);
869871
return (lit_utf8_size_t) (dst_p - buffer_p);
870872
}
871873

@@ -932,7 +934,7 @@ ecma_number_to_utf8_string (ecma_number_t num, /**< ecma-number */
932934

933935
dst_p += ecma_uint32_to_utf8_string (t, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
934936

935-
JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
937+
JERRY_ASSERT (dst_p < buffer_p + buffer_size);
936938

937939
return (lit_utf8_size_t) (dst_p - buffer_p);
938940
} /* 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

@@ -1065,8 +1066,9 @@ ecma_uint32_to_buffer (uint32_t num, /**< number */
10651066
lit_utf8_byte_t *buffer_p /**< destination buffer */,
10661067
lit_utf8_size_t buffer_size /**< buffer size */)
10671068
{
1068-
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1069-
lit_utf8_size_t digit_count = ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1069+
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1070+
lit_utf8_size_t digit_count =
1071+
ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
10701072

10711073
digit_count = JERRY_MIN (buffer_size, digit_count);
10721074
memcpy (buffer_p, digits, digit_count);
@@ -1176,7 +1178,7 @@ ecma_string_to_cesu8_bytes (const ecma_string_t *string_desc_p, /**< ecma-string
11761178
*
11771179
* @return size in bytes
11781180
*/
1179-
static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
1181+
extern inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
11801182
ecma_string_get_uint32_size (const uint32_t uint32_number) /**< number in the string-descriptor */
11811183
{
11821184
uint32_t prev_number = 1;
@@ -1274,11 +1276,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
12741276
}
12751277
else
12761278
{
1277-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1279+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
12781280
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
12791281
}
12801282

1281-
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size);
1283+
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
12821284

12831285
JERRY_ASSERT (length == size);
12841286
*flags_p |= ECMA_STRING_FLAG_IS_UINT32;
@@ -1325,11 +1327,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13251327
}
13261328
else
13271329
{
1328-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1330+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
13291331
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
13301332
}
13311333

1332-
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size);
1334+
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
13331335

13341336
JERRY_ASSERT (length == size);
13351337
*flags_p |= ECMA_STRING_FLAG_IS_UINT32 | ECMA_STRING_FLAG_REHASH_NEEDED;
@@ -1694,8 +1696,8 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
16941696
const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
16951697
lit_utf8_size_t utf8_string1_size, utf8_string2_size;
16961698

1697-
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1698-
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1699+
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1700+
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
16991701

17001702
if (ECMA_IS_DIRECT_STRING (string1_p))
17011703
{
@@ -1707,7 +1709,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17071709
{
17081710
utf8_string1_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string1_p),
17091711
uint32_to_string_buffer1,
1710-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1712+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17111713
utf8_string1_p = uint32_to_string_buffer1;
17121714
}
17131715
}
@@ -1723,7 +1725,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17231725
{
17241726
utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
17251727
uint32_to_string_buffer1,
1726-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1728+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17271729
utf8_string1_p = uint32_to_string_buffer1;
17281730
}
17291731
}
@@ -1738,7 +1740,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17381740
{
17391741
utf8_string2_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string2_p),
17401742
uint32_to_string_buffer2,
1741-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1743+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17421744
utf8_string2_p = uint32_to_string_buffer2;
17431745
}
17441746
}
@@ -1754,7 +1756,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17541756
{
17551757
utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
17561758
uint32_to_string_buffer2,
1757-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1759+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17581760
utf8_string2_p = uint32_to_string_buffer2;
17591761
}
17601762
}
@@ -2039,7 +2041,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20392041
{
20402042
JERRY_ASSERT (index < ecma_string_get_length (string_p));
20412043

2042-
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
2044+
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
20432045

20442046
if (ECMA_IS_DIRECT_STRING (string_p))
20452047
{
@@ -2064,7 +2066,9 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20642066
JERRY_ASSERT (ECMA_GET_DIRECT_STRING_TYPE (string_p) == ECMA_DIRECT_STRING_UINT);
20652067
uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);
20662068

2067-
ecma_uint32_to_utf8_string (uint32_number, uint32_to_string_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2069+
ecma_uint32_to_utf8_string (uint32_number,
2070+
uint32_to_string_buffer,
2071+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
20682072

20692073
return (ecma_char_t) uint32_to_string_buffer[index];
20702074
}
@@ -2110,7 +2114,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
21102114
{
21112115
ecma_uint32_to_utf8_string (string_p->u.uint32_number,
21122116
uint32_to_string_buffer,
2113-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2117+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
21142118

21152119
return (ecma_char_t) uint32_to_string_buffer[index];
21162120
}

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

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

@@ -120,13 +120,13 @@ typedef enum
120120
* No allocation needed by providing a uint32 string buffer
121121
*
122122
*/
123-
#define ECMA_STRING_TO_UTF8_STRING_AND_LENGTH(ecma_str_ptr, /**< ecma string pointer */ \
124-
utf8_str) /**< [out] lit_utf8_string_t to get */ \
125-
lit_utf8_string_t utf8_str; \
126-
uint8_t utf8_str##_flags = ECMA_STRING_FLAG_IS_ASCII; \
127-
lit_utf8_byte_t utf8_str##_uint32_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32]; \
128-
lit_utf8_size_t utf8_str##_length = \
129-
ecma_string_get_chars (ecma_str_ptr, &utf8_str, utf8_str##_uint32_buffer, &utf8_str##_flags); \
123+
#define ECMA_STRING_TO_UTF8_STRING_AND_LENGTH(ecma_str_ptr, /**< ecma string pointer */ \
124+
utf8_str) /**< [out] lit_utf8_string_t to get */ \
125+
lit_utf8_string_t utf8_str; \
126+
uint8_t utf8_str##_flags = ECMA_STRING_FLAG_IS_ASCII; \
127+
lit_utf8_byte_t utf8_str##_uint32_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED]; \
128+
lit_utf8_size_t utf8_str##_length = \
129+
ecma_string_get_chars (ecma_str_ptr, &utf8_str, utf8_str##_uint32_buffer, &utf8_str##_flags); \
130130
JERRY_ASSERT (!(utf8_str##_flags & ECMA_STRING_FLAG_MUST_BE_FREED));
131131

132132
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
@@ -513,6 +513,7 @@ ecma_number_t ecma_utf8_string_to_number_by_radix (const lit_utf8_byte_t *str_p,
513513
lit_utf8_size_t str_size,
514514
uint32_t radix,
515515
uint32_t option);
516+
lit_utf8_size_t ecma_string_get_uint32_size (const uint32_t uint32_number);
516517
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);
517518
uint32_t ecma_number_to_uint32 (ecma_number_t num);
518519
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)