Skip to content

Commit c212233

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

File tree

7 files changed

+52
-26
lines changed

7 files changed

+52
-26
lines changed

jerry-core/api/jerry-snapshot.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -1504,11 +1504,13 @@ jerry_append_number_to_buffer (uint8_t *buffer_p, /**< buffer */
15041504
uint8_t *buffer_end_p, /**< the end of the buffer */
15051505
lit_utf8_size_t number) /**< number */
15061506
{
1507-
lit_utf8_byte_t uint32_to_str_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1507+
lit_utf8_byte_t uint32_to_str_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
15081508
lit_utf8_size_t utf8_str_size =
1509-
ecma_uint32_to_utf8_string (number, uint32_to_str_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1509+
ecma_uint32_to_utf8_string (number,
1510+
uint32_to_str_buffer,
1511+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
15101512

1511-
JERRY_ASSERT (utf8_str_size <= ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1513+
JERRY_ASSERT (utf8_str_size < ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
15121514

15131515
return jerry_append_chars_to_buffer (buffer_p,
15141516
buffer_end_p,

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

+6
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,12 @@ typedef double ecma_number_t;
15011501
*/
15021502
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 10
15031503

1504+
/**
1505+
* Maximum number of characters in string representation of ecma-uint32 plus one.
1506+
* That is the '\0' terminator
1507+
*/
1508+
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED (ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 + 1)
1509+
15041510
/**
15051511
* String is not a valid array index.
15061512
*/

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
618618
lit_utf8_byte_t *out_buffer_p, /**< buffer for string */
619619
lit_utf8_size_t buffer_size) /**< size of buffer */
620620
{
621-
lit_utf8_byte_t *buf_p = out_buffer_p + buffer_size;
621+
lit_utf8_byte_t *buf_p_tail = out_buffer_p + buffer_size - 1;
622+
lit_utf8_byte_t *buf_p = buf_p_tail;
622623

623624
do
624625
{
@@ -631,12 +632,13 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
631632

632633
JERRY_ASSERT (buf_p >= out_buffer_p);
633634

634-
lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (out_buffer_p + buffer_size - buf_p);
635+
lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (buf_p_tail - buf_p);
635636

636637
if (JERRY_LIKELY (buf_p != out_buffer_p))
637638
{
638639
memmove (out_buffer_p, buf_p, bytes_copied);
639640
}
641+
buf_p[bytes_copied] = '\0';
640642

641643
return bytes_copied;
642644
} /* ecma_uint32_to_utf8_string */
@@ -824,7 +826,7 @@ ecma_number_to_utf8_string (ecma_number_t num, /**< ecma-number */
824826
if (((ecma_number_t) num_uint32) == num)
825827
{
826828
dst_p += ecma_uint32_to_utf8_string (num_uint32, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
827-
JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
829+
JERRY_ASSERT (dst_p < buffer_p + buffer_size);
828830
return (lit_utf8_size_t) (dst_p - buffer_p);
829831
}
830832

@@ -891,7 +893,7 @@ ecma_number_to_utf8_string (ecma_number_t num, /**< ecma-number */
891893

892894
dst_p += ecma_uint32_to_utf8_string (t, dst_p, (lit_utf8_size_t) (buffer_p + buffer_size - dst_p));
893895

894-
JERRY_ASSERT (dst_p <= buffer_p + buffer_size);
896+
JERRY_ASSERT (dst_p < buffer_p + buffer_size);
895897

896898
return (lit_utf8_size_t) (dst_p - buffer_p);
897899
} /* ecma_number_to_utf8_string */

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

+21-18
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ ecma_append_chars_to_string (ecma_string_t *string1_p, /**< base ecma-string */
726726
lit_utf8_size_t cesu8_string1_size;
727727
lit_utf8_size_t cesu8_string1_length;
728728
uint8_t flags = ECMA_STRING_FLAG_IS_ASCII;
729-
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
729+
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
730730

731731
const lit_utf8_byte_t *cesu8_string1_p =
732732
ecma_string_get_chars (string1_p, &cesu8_string1_size, &cesu8_string1_length, uint32_to_string_buffer, &flags);
@@ -831,7 +831,7 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
831831

832832
lit_utf8_size_t cesu8_string2_size;
833833
lit_utf8_size_t cesu8_string2_length;
834-
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
834+
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
835835
uint8_t flags = ECMA_STRING_FLAG_IS_ASCII;
836836

837837
const lit_utf8_byte_t *cesu8_string2_p =
@@ -1077,8 +1077,9 @@ ecma_uint32_to_buffer (uint32_t num, /**< number */
10771077
lit_utf8_byte_t *buffer_p /**< destination buffer */,
10781078
lit_utf8_size_t buffer_size /**< buffer size */)
10791079
{
1080-
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1081-
lit_utf8_size_t digit_count = ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1080+
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1081+
lit_utf8_size_t digit_count =
1082+
ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
10821083

10831084
digit_count = JERRY_MIN (buffer_size, digit_count);
10841085
memcpy (buffer_p, digits, digit_count);
@@ -1186,7 +1187,7 @@ ecma_string_to_cesu8_bytes (const ecma_string_t *string_desc_p, /**< ecma-string
11861187
*
11871188
* @return size in bytes
11881189
*/
1189-
static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
1190+
extern inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
11901191
ecma_string_get_uint32_size (const uint32_t uint32_number) /**< number in the string-descriptor */
11911192
{
11921193
uint32_t prev_number = 1;
@@ -1286,11 +1287,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
12861287
}
12871288
else
12881289
{
1289-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1290+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
12901291
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
12911292
}
12921293

1293-
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size);
1294+
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
12941295

12951296
JERRY_ASSERT (length == size);
12961297
*flags_p |= ECMA_STRING_FLAG_IS_UINT32;
@@ -1337,11 +1338,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13371338
}
13381339
else
13391340
{
1340-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1341+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
13411342
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
13421343
}
13431344

1344-
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size);
1345+
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
13451346

13461347
JERRY_ASSERT (length == size);
13471348
*flags_p |= ECMA_STRING_FLAG_IS_UINT32 | ECMA_STRING_FLAG_REHASH_NEEDED;
@@ -1711,8 +1712,8 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17111712
const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
17121713
lit_utf8_size_t utf8_string1_size, utf8_string2_size;
17131714

1714-
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1715-
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1715+
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1716+
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
17161717

17171718
if (ECMA_IS_DIRECT_STRING (string1_p))
17181719
{
@@ -1724,7 +1725,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17241725
{
17251726
utf8_string1_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string1_p),
17261727
uint32_to_string_buffer1,
1727-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1728+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17281729
utf8_string1_p = uint32_to_string_buffer1;
17291730
}
17301731
}
@@ -1740,7 +1741,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17401741
{
17411742
utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
17421743
uint32_to_string_buffer1,
1743-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1744+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17441745
utf8_string1_p = uint32_to_string_buffer1;
17451746
}
17461747
}
@@ -1755,7 +1756,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17551756
{
17561757
utf8_string2_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string2_p),
17571758
uint32_to_string_buffer2,
1758-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1759+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17591760
utf8_string2_p = uint32_to_string_buffer2;
17601761
}
17611762
}
@@ -1771,7 +1772,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17711772
{
17721773
utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
17731774
uint32_to_string_buffer2,
1774-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1775+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17751776
utf8_string2_p = uint32_to_string_buffer2;
17761777
}
17771778
}
@@ -2056,7 +2057,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20562057
{
20572058
JERRY_ASSERT (index < ecma_string_get_length (string_p));
20582059

2059-
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
2060+
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
20602061

20612062
if (ECMA_IS_DIRECT_STRING (string_p))
20622063
{
@@ -2081,7 +2082,9 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20812082
JERRY_ASSERT (ECMA_GET_DIRECT_STRING_TYPE (string_p) == ECMA_DIRECT_STRING_UINT);
20822083
uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);
20832084

2084-
ecma_uint32_to_utf8_string (uint32_number, uint32_to_string_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2085+
ecma_uint32_to_utf8_string (uint32_number,
2086+
uint32_to_string_buffer,
2087+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
20852088

20862089
return (ecma_char_t) uint32_to_string_buffer[index];
20872090
}
@@ -2127,7 +2130,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
21272130
{
21282131
ecma_uint32_to_utf8_string (string_p->u.uint32_number,
21292132
uint32_to_string_buffer,
2130-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2133+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
21312134

21322135
return (ecma_char_t) uint32_to_string_buffer[index];
21332136
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ ecma_number_t ecma_utf8_string_to_number_by_radix (const lit_utf8_byte_t *str_p,
509509
lit_utf8_size_t str_size,
510510
uint32_t radix,
511511
uint32_t option);
512+
lit_utf8_size_t ecma_string_get_uint32_size (const uint32_t uint32_number);
512513
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);
513514
uint32_t ecma_number_to_uint32 (ecma_number_t num);
514515
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));

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)