Skip to content

Commit f03f55a

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 c509a06 commit f03f55a

File tree

7 files changed

+46
-26
lines changed

7 files changed

+46
-26
lines changed

jerry-core/api/jerry-snapshot.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1507,11 +1507,11 @@ jerry_append_number_to_buffer (uint8_t *buffer_p, /**< buffer */
15071507
uint8_t *buffer_end_p, /**< the end of the buffer */
15081508
lit_utf8_size_t number) /**< number */
15091509
{
1510-
lit_utf8_byte_t uint32_to_str_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1510+
lit_utf8_byte_t uint32_to_str_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
15111511
lit_utf8_size_t utf8_str_size =
1512-
ecma_uint32_to_utf8_string (number, uint32_to_str_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1512+
ecma_uint32_to_utf8_string (number, uint32_to_str_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
15131513

1514-
JERRY_ASSERT (utf8_str_size <= ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1514+
JERRY_ASSERT (utf8_str_size < ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
15151515

15161516
return jerry_append_chars_to_buffer (buffer_p,
15171517
buffer_end_p,

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

+5
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,11 @@ 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
1384+
*/
1385+
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED (ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 + 1)
1386+
13821387
/**
13831388
* String is not a valid array index.
13841389
*/

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

+18-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 =
@@ -1081,8 +1081,8 @@ ecma_uint32_to_buffer (uint32_t num, /**< number */
10811081
lit_utf8_byte_t *buffer_p /**< destination buffer */,
10821082
lit_utf8_size_t buffer_size /**< buffer size */)
10831083
{
1084-
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1085-
lit_utf8_size_t digit_count = ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1084+
lit_utf8_byte_t digits[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1085+
lit_utf8_size_t digit_count = ecma_uint32_to_utf8_string (num, digits, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
10861086

10871087
digit_count = JERRY_MIN (buffer_size, digit_count);
10881088
memcpy (buffer_p, digits, digit_count);
@@ -1192,7 +1192,7 @@ ecma_string_to_cesu8_bytes (const ecma_string_t *string_desc_p, /**< ecma-string
11921192
*
11931193
* @return size in bytes
11941194
*/
1195-
static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
1195+
extern inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
11961196
ecma_string_get_uint32_size (const uint32_t uint32_number) /**< number in the string-descriptor */
11971197
{
11981198
uint32_t prev_number = 1;
@@ -1292,11 +1292,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
12921292
}
12931293
else
12941294
{
1295-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1295+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
12961296
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
12971297
}
12981298

1299-
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size);
1299+
length = ecma_uint32_to_utf8_string (uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
13001300

13011301
JERRY_ASSERT (length == size);
13021302
*flags_p |= ECMA_STRING_FLAG_IS_UINT32;
@@ -1343,11 +1343,11 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
13431343
}
13441344
else
13451345
{
1346-
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size);
1346+
result_p = (const lit_utf8_byte_t *) jmem_heap_alloc_block (size + 1);
13471347
*flags_p |= ECMA_STRING_FLAG_MUST_BE_FREED;
13481348
}
13491349

1350-
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size);
1350+
length = ecma_uint32_to_utf8_string (string_p->u.uint32_number, (lit_utf8_byte_t *) result_p, size + 1);
13511351

13521352
JERRY_ASSERT (length == size);
13531353
*flags_p |= ECMA_STRING_FLAG_IS_UINT32 | ECMA_STRING_FLAG_REHASH_NEEDED;
@@ -1716,8 +1716,8 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17161716
const lit_utf8_byte_t *utf8_string1_p, *utf8_string2_p;
17171717
lit_utf8_size_t utf8_string1_size, utf8_string2_size;
17181718

1719-
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1720-
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
1719+
lit_utf8_byte_t uint32_to_string_buffer1[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
1720+
lit_utf8_byte_t uint32_to_string_buffer2[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
17211721

17221722
if (ECMA_IS_DIRECT_STRING (string1_p))
17231723
{
@@ -1729,7 +1729,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17291729
{
17301730
utf8_string1_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string1_p),
17311731
uint32_to_string_buffer1,
1732-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1732+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17331733
utf8_string1_p = uint32_to_string_buffer1;
17341734
}
17351735
}
@@ -1745,7 +1745,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17451745
{
17461746
utf8_string1_size = ecma_uint32_to_utf8_string (string1_p->u.uint32_number,
17471747
uint32_to_string_buffer1,
1748-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1748+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17491749
utf8_string1_p = uint32_to_string_buffer1;
17501750
}
17511751
}
@@ -1760,7 +1760,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17601760
{
17611761
utf8_string2_size = ecma_uint32_to_utf8_string ((uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string2_p),
17621762
uint32_to_string_buffer2,
1763-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1763+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17641764
utf8_string2_p = uint32_to_string_buffer2;
17651765
}
17661766
}
@@ -1776,7 +1776,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
17761776
{
17771777
utf8_string2_size = ecma_uint32_to_utf8_string (string2_p->u.uint32_number,
17781778
uint32_to_string_buffer2,
1779-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
1779+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
17801780
utf8_string2_p = uint32_to_string_buffer2;
17811781
}
17821782
}
@@ -2061,7 +2061,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20612061
{
20622062
JERRY_ASSERT (index < ecma_string_get_length (string_p));
20632063

2064-
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
2064+
lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED];
20652065

20662066
if (ECMA_IS_DIRECT_STRING (string_p))
20672067
{
@@ -2086,7 +2086,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
20862086
JERRY_ASSERT (ECMA_GET_DIRECT_STRING_TYPE (string_p) == ECMA_DIRECT_STRING_UINT);
20872087
uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);
20882088

2089-
ecma_uint32_to_utf8_string (uint32_number, uint32_to_string_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2089+
ecma_uint32_to_utf8_string (uint32_number, uint32_to_string_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
20902090

20912091
return (ecma_char_t) uint32_to_string_buffer[index];
20922092
}
@@ -2132,7 +2132,7 @@ ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
21322132
{
21332133
ecma_uint32_to_utf8_string (string_p->u.uint32_number,
21342134
uint32_to_string_buffer,
2135-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2135+
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32_WITH_ZERO_TERMINATED);
21362136

21372137
return (ecma_char_t) uint32_to_string_buffer[index];
21382138
}

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

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