Skip to content

Commit b58853c

Browse files
committed
Serialize UTF-16LE and ISO-8859-1 encoded strings (rubyjs#332)
1 parent 3126189 commit b58853c

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

ext/mini_racer_extension/mini_racer_extension.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,25 @@ static int collect(VALUE k, VALUE v, VALUE a)
422422
return ST_CONTINUE;
423423
}
424424

425+
static void add_string(Ser *s, VALUE v)
426+
{
427+
rb_encoding *e;
428+
const void *p;
429+
size_t n;
430+
431+
Check_Type(v, T_STRING);
432+
e = rb_enc_get(v);
433+
p = RSTRING_PTR(v);
434+
n = RSTRING_LEN(v);
435+
if (e) {
436+
if (!strcmp(e->name, "ISO-8859-1"))
437+
return ser_string8(s, p, n);
438+
if (!strcmp(e->name, "UTF-16LE"))
439+
return ser_string16(s, p, n);
440+
}
441+
return ser_string(s, p, n);
442+
}
443+
425444
static int serialize1(Ser *s, VALUE refs, VALUE v)
426445
{
427446
unsigned long limbs[64];
@@ -525,7 +544,7 @@ static int serialize1(Ser *s, VALUE refs, VALUE v)
525544
v = rb_sym2str(v);
526545
// fallthru
527546
case T_STRING:
528-
ser_string(s, RSTRING_PTR(v), RSTRING_LENINT(v));
547+
add_string(s, v);
529548
break;
530549
default:
531550
snprintf(s->err, sizeof(s->err), "unsupported type %x", TYPE(v));
@@ -1062,7 +1081,7 @@ static VALUE context_attach(VALUE self, VALUE name, VALUE proc)
10621081
// request is (A)ttach, [name, id] array
10631082
ser_init1(&s, 'A');
10641083
ser_array_begin(&s, 2);
1065-
ser_string(&s, RSTRING_PTR(name), RSTRING_LENINT(name));
1084+
add_string(&s, name);
10661085
ser_int(&s, RARRAY_LENINT(c->procs));
10671086
ser_array_end(&s, 2);
10681087
rb_ary_push(c->procs, proc);
@@ -1159,8 +1178,8 @@ static VALUE context_eval(int argc, VALUE *argv, VALUE self)
11591178
// request is (E)val, [filename, source] array
11601179
ser_init1(&s, 'E');
11611180
ser_array_begin(&s, 2);
1162-
ser_string(&s, RSTRING_PTR(filename), RSTRING_LENINT(filename));
1163-
ser_string(&s, RSTRING_PTR(source), RSTRING_LENINT(source));
1181+
add_string(&s, filename);
1182+
add_string(&s, source);
11641183
ser_array_end(&s, 2);
11651184
// response is [result, errname] array
11661185
a = rendezvous(c, &s.b); // takes ownership of |s.b|
@@ -1462,7 +1481,7 @@ static VALUE snapshot_initialize(int argc, VALUE *argv, VALUE self)
14621481
TypedData_Get_Struct(cv, Context, &context_type, c);
14631482
// request is snapsho(T), "code"
14641483
ser_init1(&s, 'T');
1465-
ser_string(&s, RSTRING_PTR(code), RSTRING_LENINT(code));
1484+
add_string(&s, code);
14661485
// response is [arraybuffer, error]
14671486
a = rendezvous(c, &s.b);
14681487
e = rb_ary_pop(a);
@@ -1489,7 +1508,7 @@ static VALUE snapshot_warmup(VALUE self, VALUE arg)
14891508
ser_init1(&s, 'W');
14901509
ser_array_begin(&s, 2);
14911510
ser_string8(&s, (const uint8_t *)RSTRING_PTR(ss->blob), RSTRING_LENINT(ss->blob));
1492-
ser_string(&s, RSTRING_PTR(arg), RSTRING_LENINT(arg));
1511+
add_string(&s, arg);
14931512
ser_array_end(&s, 2);
14941513
// response is [arraybuffer, error]
14951514
a = rendezvous(c, &s.b);

ext/mini_racer_extension/serde.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,14 @@ static void ser_string8(Ser *s, const uint8_t *p, size_t n)
303303
w(s, p, n);
304304
}
305305

306+
// string must be utf16le; |n| is in bytes, not code points
307+
static void ser_string16(Ser *s, const void *p, size_t n)
308+
{
309+
w_byte(s, 'c');
310+
w_varint(s, n);
311+
w(s, p, n);
312+
}
313+
306314
static void ser_object_begin(Ser *s)
307315
{
308316
w_byte(s, 'o');

test/mini_racer_test.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,4 +1093,11 @@ def test_function_property
10931093
expected = {"error" => "Error: f() {} could not be cloned."}
10941094
assert_equal expected, context.eval("({ x: 42, f() {} })")
10951095
end
1096+
1097+
def test_string_encoding
1098+
context = MiniRacer::Context.new
1099+
assert_equal "ok", context.eval("'ok'".encode("ISO-8859-1"))
1100+
assert_equal "ok", context.eval("'ok'".encode("ISO8859-1"))
1101+
assert_equal "ok", context.eval("'ok'".encode("UTF-16LE"))
1102+
end
10961103
end

0 commit comments

Comments
 (0)