Skip to content

Commit 4ac18b8

Browse files
author
Roland Takacs
committed
Fix assertion 'bytes_copied > 0 || !string_len' in JSON.stringify()
JerryScript-DCO-1.0-Signed-off-by: Roland Takacs rtakacs.u-szeged@partner.samsung.com
1 parent 2630048 commit 4ac18b8

File tree

2 files changed

+53
-65
lines changed

2 files changed

+53
-65
lines changed

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

Lines changed: 48 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -917,22 +917,22 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
917917
{
918918
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
919919

920-
stringify_context_t context_p;
920+
stringify_context_t context;
921921

922922
/* 1. */
923-
context_p.occurence_stack.block_start_p = NULL;
924-
context_p.occurence_stack.block_end_p = NULL;
925-
context_p.occurence_stack.current_p = NULL;
923+
context.occurence_stack.block_start_p = NULL;
924+
context.occurence_stack.block_end_p = NULL;
925+
context.occurence_stack.current_p = NULL;
926926

927927
/* 2. */
928-
context_p.indent_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
928+
context.indent_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
929929

930930
/* 3. */
931-
context_p.property_list.block_start_p = NULL;
932-
context_p.property_list.block_end_p = NULL;
933-
context_p.property_list.current_p = NULL;
931+
context.property_list.block_start_p = NULL;
932+
context.property_list.block_end_p = NULL;
933+
context.property_list.current_p = NULL;
934934

935-
context_p.replacer_function_p = NULL;
935+
context.replacer_function_p = NULL;
936936

937937
/* 4. */
938938
if (ecma_is_value_object (arg2))
@@ -942,7 +942,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
942942
/* 4.a */
943943
if (ecma_op_is_callable (arg2))
944944
{
945-
context_p.replacer_function_p = obj_p;
945+
context.replacer_function_p = obj_p;
946946
}
947947
/* 4.b */
948948
else if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
@@ -1013,9 +1013,9 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
10131013
{
10141014
ecma_string_t *item_str_p = ecma_get_string_from_value (item);
10151015

1016-
if (!list_has_ecma_string_element (&context_p.property_list, item_str_p))
1016+
if (!list_has_ecma_string_element (&context.property_list, item_str_p))
10171017
{
1018-
list_append (&context_p.property_list, item_str_p);
1018+
list_append (&context.property_list, item_str_p);
10191019
}
10201020
else
10211021
{
@@ -1085,7 +1085,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
10851085
/* 6.b */
10861086
if (space < 1)
10871087
{
1088-
context_p.gap_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
1088+
context.gap_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
10891089
}
10901090
else
10911091
{
@@ -1096,7 +1096,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
10961096
space_buff[i] = LIT_CHAR_SP;
10971097
}
10981098

1099-
context_p.gap_str_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) space_buff, (lit_utf8_size_t) space);
1099+
context.gap_str_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) space_buff, (lit_utf8_size_t) space);
11001100

11011101
MEM_FINALIZE_LOCAL_ARRAY (space_buff);
11021102
}
@@ -1111,38 +1111,17 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
11111111

11121112
if (num_of_chars < 10)
11131113
{
1114-
context_p.gap_str_p = ecma_copy_or_ref_ecma_string (space_str_p);
1114+
context.gap_str_p = ecma_copy_or_ref_ecma_string (space_str_p);
11151115
}
11161116
else
11171117
{
1118-
ecma_length_t string_len = ecma_string_get_length (space_str_p);
1119-
1120-
MEM_DEFINE_LOCAL_ARRAY (zt_string_buff, string_len, lit_utf8_byte_t);
1121-
1122-
size_t string_buf_size = (size_t) (string_len) * sizeof (lit_utf8_byte_t);
1123-
ssize_t bytes_copied = ecma_string_to_utf8_string (space_str_p,
1124-
zt_string_buff,
1125-
(ssize_t) string_buf_size);
1126-
JERRY_ASSERT (bytes_copied > 0);
1127-
1128-
/* Buffer for the first 10 characters. */
1129-
MEM_DEFINE_LOCAL_ARRAY (space_buff, 10, lit_utf8_byte_t);
1130-
1131-
for (uint32_t i = 0; i < 10; i++)
1132-
{
1133-
space_buff[i] = zt_string_buff[i];
1134-
}
1135-
1136-
context_p.gap_str_p = ecma_new_ecma_string_from_utf8 ((lit_utf8_byte_t *) space_buff, 10);
1137-
1138-
MEM_FINALIZE_LOCAL_ARRAY (space_buff);
1139-
MEM_FINALIZE_LOCAL_ARRAY (zt_string_buff);
1118+
context.gap_str_p = ecma_string_substr (space_str_p, 0, 10);
11401119
}
11411120
}
11421121
/* 8. */
11431122
else
11441123
{
1145-
context_p.gap_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
1124+
context.gap_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
11461125
}
11471126

11481127
ecma_free_value (space, true);
@@ -1162,7 +1141,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
11621141

11631142
/* 11. */
11641143
ECMA_TRY_CATCH (str_val,
1165-
ecma_builtin_json_str (empty_str_p, obj_wrapper_p, &context_p),
1144+
ecma_builtin_json_str (empty_str_p, obj_wrapper_p, &context),
11661145
ret_value);
11671146

11681147
ret_value = ecma_make_normal_completion_value (ecma_copy_value (str_val, true));
@@ -1172,11 +1151,11 @@ ecma_builtin_json_stringify (ecma_value_t this_arg __attr_unused___, /**< 'this'
11721151
ecma_deref_object (obj_wrapper_p);
11731152
ecma_deref_ecma_string (empty_str_p);
11741153

1175-
ecma_deref_ecma_string (context_p.indent_str_p);
1176-
ecma_deref_ecma_string (context_p.gap_str_p);
1154+
ecma_deref_ecma_string (context.indent_str_p);
1155+
ecma_deref_ecma_string (context.gap_str_p);
11771156

1178-
free_list_with_ecma_string_content (&context_p.property_list);
1179-
free_list (&context_p.occurence_stack);
1157+
free_list_with_ecma_string_content (&context.property_list);
1158+
free_list (&context.occurence_stack);
11801159

11811160
return ret_value;
11821161
} /* ecma_builtin_json_stringify */
@@ -1198,23 +1177,24 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo
11981177
ecma_string_t *product_str_p = ecma_copy_or_ref_ecma_string (quote_str_p);
11991178
ecma_string_t *tmp_str_p;
12001179

1201-
ecma_length_t string_len = ecma_string_get_length (string_p);
1180+
ecma_length_t string_size = ecma_string_get_size (string_p);
12021181

1203-
MEM_DEFINE_LOCAL_ARRAY (zt_string_buff, string_len, lit_utf8_byte_t);
1182+
MEM_DEFINE_LOCAL_ARRAY (string_buff, string_size, lit_utf8_byte_t);
12041183

1205-
size_t string_buf_size = (size_t) (string_len) * sizeof (lit_utf8_byte_t);
12061184
ssize_t bytes_copied = ecma_string_to_utf8_string (string_p,
1207-
zt_string_buff,
1208-
(ssize_t) string_buf_size);
1209-
JERRY_ASSERT (bytes_copied > 0 || !string_len);
1185+
string_buff,
1186+
(ssize_t) string_size);
12101187

1211-
/* 2. */
1212-
for (ecma_length_t i = 0; i < string_len; i++)
1188+
JERRY_ASSERT (bytes_copied > 0 || !string_size);
1189+
1190+
lit_utf8_iterator_t iter = lit_utf8_iterator_create (string_buff, string_size);
1191+
1192+
while (!lit_utf8_iterator_is_eos (&iter))
12131193
{
1214-
lit_utf8_byte_t c = zt_string_buff[i];
1194+
ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
12151195

12161196
/* 2.a */
1217-
if (c == LIT_CHAR_BACKSLASH || c == LIT_CHAR_DOUBLE_QUOTE)
1197+
if (current_char == LIT_CHAR_BACKSLASH || current_char == LIT_CHAR_DOUBLE_QUOTE)
12181198
{
12191199
ecma_string_t *backslash_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BACKSLASH_CHAR);
12201200

@@ -1225,16 +1205,19 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo
12251205
product_str_p = tmp_str_p;
12261206

12271207
/* 2.a.ii */
1228-
ecma_string_t *c_str_p = ecma_new_ecma_string_from_utf8 (&c, 1);
1208+
ecma_string_t *current_char_str_p = ecma_new_ecma_string_from_code_unit (current_char);
12291209

1230-
tmp_str_p = ecma_concat_ecma_strings (product_str_p, c_str_p);
1210+
tmp_str_p = ecma_concat_ecma_strings (product_str_p, current_char_str_p);
12311211
ecma_deref_ecma_string (product_str_p);
1232-
ecma_deref_ecma_string (c_str_p);
1212+
ecma_deref_ecma_string (current_char_str_p);
12331213
product_str_p = tmp_str_p;
12341214
}
12351215
/* 2.b */
1236-
else if (c == LIT_CHAR_BS || c == LIT_CHAR_FF || c == LIT_CHAR_LF
1237-
|| c == LIT_CHAR_CR || c == LIT_CHAR_TAB)
1216+
else if (current_char == LIT_CHAR_BS
1217+
|| current_char == LIT_CHAR_FF
1218+
|| current_char == LIT_CHAR_LF
1219+
|| current_char == LIT_CHAR_CR
1220+
|| current_char == LIT_CHAR_TAB)
12381221
{
12391222
ecma_string_t *backslash_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BACKSLASH_CHAR);
12401223

@@ -1247,7 +1230,7 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo
12471230
/* 2.b.ii */
12481231
lit_utf8_byte_t abbrev = LIT_CHAR_SP;
12491232

1250-
switch (c)
1233+
switch (current_char)
12511234
{
12521235
case LIT_CHAR_BS:
12531236
{
@@ -1285,7 +1268,7 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo
12851268
product_str_p = tmp_str_p;
12861269
}
12871270
/* 2.c */
1288-
else if (c < LIT_CHAR_SP)
1271+
else if (current_char < LIT_CHAR_SP)
12891272
{
12901273
ecma_string_t *backslash_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_BACKSLASH_CHAR);
12911274

@@ -1305,7 +1288,7 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo
13051288
product_str_p = tmp_str_p;
13061289

13071290
/* 2.c.iii */
1308-
ecma_string_t *hex_str_p = ecma_builtin_helper_json_create_hex_digit_ecma_string (c);
1291+
ecma_string_t *hex_str_p = ecma_builtin_helper_json_create_hex_digit_ecma_string ((uint8_t) current_char);
13091292

13101293
/* 2.c.iv */
13111294
tmp_str_p = ecma_concat_ecma_strings (product_str_p, hex_str_p);
@@ -1316,16 +1299,16 @@ ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quo
13161299
/* 2.d */
13171300
else
13181301
{
1319-
ecma_string_t *c_str_p = ecma_new_ecma_string_from_utf8 (&c, 1);
1302+
ecma_string_t *current_char_str_p = ecma_new_ecma_string_from_code_unit (current_char);
13201303

1321-
tmp_str_p = ecma_concat_ecma_strings (product_str_p, c_str_p);
1304+
tmp_str_p = ecma_concat_ecma_strings (product_str_p, current_char_str_p);
13221305
ecma_deref_ecma_string (product_str_p);
1323-
ecma_deref_ecma_string (c_str_p);
1306+
ecma_deref_ecma_string (current_char_str_p);
13241307
product_str_p = tmp_str_p;
13251308
}
13261309
}
13271310

1328-
MEM_FINALIZE_LOCAL_ARRAY (zt_string_buff);
1311+
MEM_FINALIZE_LOCAL_ARRAY (string_buff);
13291312

13301313
/* 3. */
13311314
tmp_str_p = ecma_concat_ecma_strings (product_str_p, quote_str_p);

tests/jerry/json-stringify.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ assert (JSON.stringify (ctl_string) == '"asd\\u001fasd"');
2828
escpad_string = "\"asda\sd";
2929
assert (JSON.stringify (escpad_string) == '"\\"asdasd"');
3030

31+
assert (JSON.stringify('\u2040') == '"⁀"');
32+
assert (JSON.stringify('abc\u2040\u2030cba') == '"abc⁀‰cba"');
33+
3134
// Checking primitive types
3235
assert (JSON.stringify (1) === '1');
3336
assert (JSON.stringify (true) === 'true');
@@ -165,13 +168,15 @@ object = {"a": 2};
165168
assert (JSON.stringify (object, null, " ") == '{\n "a": 2\n}');
166169
assert (JSON.stringify (object, null, "asd") == '{\nasd"a": 2\n}');
167170
assert (JSON.stringify (object, null, "asd0123456789") == '{\nasd0123456"a": 2\n}');
171+
assert (JSON.stringify (object, null, "asd\u20400123456789") == '{\nasd⁀012345"a": 2\n}');
168172
assert (JSON.stringify (object, null, 100) == '{\n "a": 2\n}');
169173
assert (JSON.stringify (object, null, -5) == '{"a":2}');
170174

171175
array = [2];
172176
assert (JSON.stringify (array, null, " ") == '[\n 2\n]');
173177
assert (JSON.stringify (array, null, "asd") == '[\nasd2\n]');
174178
assert (JSON.stringify (array, null, "asd0123456789") == '[\nasd01234562\n]');
179+
assert (JSON.stringify (array, null, "asd\u20400123456789") == '[\nasd⁀0123452\n]');
175180
assert (JSON.stringify (array, null, 100) == '[\n 2\n]');
176181
assert (JSON.stringify (array, null, -5) == '[2]');
177182

0 commit comments

Comments
 (0)