mini_racer 0.17.0.pre7 → 0.17.0.pre9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +7 -0
- data/ext/mini_racer_extension/mini_racer_extension.c +93 -27
- data/ext/mini_racer_extension/serde.c +12 -1
- data/lib/mini_racer/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3be215eb4d4e72b01480ffa28863ea7ff1947b3f8cf0b6dcd860ffde2e48799
|
4
|
+
data.tar.gz: adcae327e54c2c372871c255e4bfd19a07b28964cd4c7c51cbc1cc251d1f71db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98bdc234f17c0e16ae995c8fe3566f6ec80cbd92c569e4aa31ac1999d309ae2a197b0c7cb1c5de62f542f25b4f73287d0a34ab7967e1e24c32d02fc73ade33f2
|
7
|
+
data.tar.gz: 7ade32c683f240c3e19eaa58b6a044192f57b1e651966c042654d401f1f5dae1aff20d1c545dd7fd05afb2b0f70659080825b5a788ab82379b119c497ac31e47
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
- 0.17.0.pre9 - 13-01-2025
|
2
|
+
- For backwards compatibility convert v8 return values to UTF-8 (invalidly encoded string still get returned using V8 encoding)
|
3
|
+
|
4
|
+
- 0.17.0.pre8 - 11-01-2025
|
5
|
+
- Fix handling of UTF 32 LE and Ascii encoding strings - Ben Noordhuis
|
6
|
+
- Handle rare edge case in V8 serialization - Ben Noordhuis
|
7
|
+
|
1
8
|
- 0.17.0.pre7 - 10-01-2025
|
2
9
|
|
3
10
|
- Objects containing non serializable properties will return an Error object vs raising an exception. Ben Noordhuis
|
@@ -164,12 +164,6 @@ static VALUE js_function_class;
|
|
164
164
|
static pthread_mutex_t flags_mtx = PTHREAD_MUTEX_INITIALIZER;
|
165
165
|
static Buf flags; // protected by |flags_mtx|
|
166
166
|
|
167
|
-
struct rendezvous_nogvl
|
168
|
-
{
|
169
|
-
Context *context;
|
170
|
-
Buf *req, *res;
|
171
|
-
};
|
172
|
-
|
173
167
|
// arg == &(struct rendezvous_nogvl){...}
|
174
168
|
static void *rendezvous_callback(void *arg);
|
175
169
|
|
@@ -184,16 +178,30 @@ typedef struct DesCtx
|
|
184
178
|
{
|
185
179
|
State *tos;
|
186
180
|
VALUE refs; // array
|
181
|
+
uint8_t transcode_latin1:1;
|
187
182
|
char err[64];
|
188
183
|
State stack[512];
|
189
184
|
} DesCtx;
|
190
185
|
|
186
|
+
struct rendezvous_nogvl
|
187
|
+
{
|
188
|
+
Context *context;
|
189
|
+
Buf *req, *res;
|
190
|
+
};
|
191
|
+
|
192
|
+
struct rendezvous_des
|
193
|
+
{
|
194
|
+
DesCtx *d;
|
195
|
+
Buf *res;
|
196
|
+
};
|
197
|
+
|
191
198
|
static void DesCtx_init(DesCtx *c)
|
192
199
|
{
|
193
200
|
c->tos = c->stack;
|
194
201
|
c->refs = rb_ary_new();
|
195
202
|
*c->tos = (State){Qundef, Qundef};
|
196
203
|
*c->err = '\0';
|
204
|
+
c->transcode_latin1 = 1; // convert to utf8
|
197
205
|
}
|
198
206
|
|
199
207
|
static void put(DesCtx *c, VALUE v)
|
@@ -321,9 +329,22 @@ static void des_string(void *arg, const char *s, size_t n)
|
|
321
329
|
put(arg, rb_utf8_str_new(s, n));
|
322
330
|
}
|
323
331
|
|
332
|
+
static VALUE str_encode_bang(VALUE v)
|
333
|
+
{
|
334
|
+
// TODO cache these? this function can get called often
|
335
|
+
return rb_funcall(v, rb_intern("encode!"), 1, rb_str_new_cstr("UTF-8"));
|
336
|
+
}
|
337
|
+
|
324
338
|
static void des_string8(void *arg, const uint8_t *s, size_t n)
|
325
339
|
{
|
326
|
-
|
340
|
+
DesCtx *c;
|
341
|
+
VALUE v;
|
342
|
+
|
343
|
+
c = arg;
|
344
|
+
v = rb_enc_str_new((char *)s, n, rb_ascii8bit_encoding());
|
345
|
+
if (c->transcode_latin1)
|
346
|
+
v = str_encode_bang(v); // cannot fail
|
347
|
+
put(c, v);
|
327
348
|
}
|
328
349
|
|
329
350
|
// des_string16: |s| is not word aligned
|
@@ -331,7 +352,9 @@ static void des_string8(void *arg, const uint8_t *s, size_t n)
|
|
331
352
|
static void des_string16(void *arg, const void *s, size_t n)
|
332
353
|
{
|
333
354
|
rb_encoding *e;
|
355
|
+
VALUE v, r;
|
334
356
|
DesCtx *c;
|
357
|
+
int exc;
|
335
358
|
|
336
359
|
c = arg;
|
337
360
|
if (*c->err)
|
@@ -344,7 +367,15 @@ static void des_string16(void *arg, const void *s, size_t n)
|
|
344
367
|
snprintf(c->err, sizeof(c->err), "no UTF16-LE encoding");
|
345
368
|
return;
|
346
369
|
}
|
347
|
-
|
370
|
+
v = rb_enc_str_new((char *)s, n, e);
|
371
|
+
// JS strings can contain unmatched or illegal surrogate pairs
|
372
|
+
// that Ruby won't decode; return the string as-is in that case
|
373
|
+
r = rb_protect(str_encode_bang, v, &exc);
|
374
|
+
if (exc) {
|
375
|
+
rb_set_errinfo(Qnil);
|
376
|
+
r = v;
|
377
|
+
}
|
378
|
+
put(c, r);
|
348
379
|
}
|
349
380
|
|
350
381
|
// ruby doesn't really have a concept of a byte array so store it as
|
@@ -422,6 +453,25 @@ static int collect(VALUE k, VALUE v, VALUE a)
|
|
422
453
|
return ST_CONTINUE;
|
423
454
|
}
|
424
455
|
|
456
|
+
static void add_string(Ser *s, VALUE v)
|
457
|
+
{
|
458
|
+
rb_encoding *e;
|
459
|
+
const void *p;
|
460
|
+
size_t n;
|
461
|
+
|
462
|
+
Check_Type(v, T_STRING);
|
463
|
+
e = rb_enc_get(v);
|
464
|
+
p = RSTRING_PTR(v);
|
465
|
+
n = RSTRING_LEN(v);
|
466
|
+
if (e) {
|
467
|
+
if (!strcmp(e->name, "ISO-8859-1"))
|
468
|
+
return ser_string8(s, p, n);
|
469
|
+
if (!strcmp(e->name, "UTF-16LE"))
|
470
|
+
return ser_string16(s, p, n);
|
471
|
+
}
|
472
|
+
return ser_string(s, p, n);
|
473
|
+
}
|
474
|
+
|
425
475
|
static int serialize1(Ser *s, VALUE refs, VALUE v)
|
426
476
|
{
|
427
477
|
unsigned long limbs[64];
|
@@ -525,7 +575,7 @@ static int serialize1(Ser *s, VALUE refs, VALUE v)
|
|
525
575
|
v = rb_sym2str(v);
|
526
576
|
// fallthru
|
527
577
|
case T_STRING:
|
528
|
-
|
578
|
+
add_string(s, v);
|
529
579
|
break;
|
530
580
|
default:
|
531
581
|
snprintf(s->err, sizeof(s->err), "unsupported type %x", TYPE(v));
|
@@ -721,25 +771,25 @@ static void *v8_thread_start(void *arg)
|
|
721
771
|
return NULL;
|
722
772
|
}
|
723
773
|
|
724
|
-
static VALUE deserialize1(const uint8_t *p, size_t n)
|
774
|
+
static VALUE deserialize1(DesCtx *d, const uint8_t *p, size_t n)
|
725
775
|
{
|
726
776
|
char err[64];
|
727
|
-
DesCtx d;
|
728
777
|
|
729
|
-
|
730
|
-
if (des(&err, p, n, &d))
|
778
|
+
if (des(&err, p, n, d))
|
731
779
|
rb_raise(runtime_error, "%s", err);
|
732
|
-
if (d
|
780
|
+
if (d->tos != d->stack) // should not happen
|
733
781
|
rb_raise(runtime_error, "parse stack not empty");
|
734
|
-
return d
|
782
|
+
return d->tos->a;
|
735
783
|
}
|
736
784
|
|
737
785
|
static VALUE deserialize(VALUE arg)
|
738
786
|
{
|
787
|
+
struct rendezvous_des *a;
|
739
788
|
Buf *b;
|
740
789
|
|
741
|
-
|
742
|
-
|
790
|
+
a = (void *)arg;
|
791
|
+
b = a->res;
|
792
|
+
return deserialize1(a->d, b->buf, b->len);
|
743
793
|
}
|
744
794
|
|
745
795
|
// called with |rr_mtx| and GVL held; can raise exception
|
@@ -748,6 +798,7 @@ static VALUE rendezvous_callback_do(VALUE arg)
|
|
748
798
|
struct rendezvous_nogvl *a;
|
749
799
|
VALUE func, args;
|
750
800
|
Context *c;
|
801
|
+
DesCtx d;
|
751
802
|
Buf *b;
|
752
803
|
|
753
804
|
a = (void *)arg;
|
@@ -755,7 +806,8 @@ static VALUE rendezvous_callback_do(VALUE arg)
|
|
755
806
|
c = a->context;
|
756
807
|
assert(b->len > 0);
|
757
808
|
assert(*b->buf == 'c');
|
758
|
-
|
809
|
+
DesCtx_init(&d);
|
810
|
+
args = deserialize1(&d, b->buf+1, b->len-1); // skip 'c' marker
|
759
811
|
func = rb_ary_pop(args); // callback id
|
760
812
|
func = rb_ary_entry(c->procs, FIX2LONG(func));
|
761
813
|
return rb_funcall2(func, rb_intern("call"), RARRAY_LENINT(args), RARRAY_PTR(args));
|
@@ -847,14 +899,14 @@ static void rendezvous_no_des(Context *c, Buf *req, Buf *res)
|
|
847
899
|
|
848
900
|
// send request to & receive reply from v8 thread; takes ownership of |req|
|
849
901
|
// can raise exceptions and longjmp away but won't leak |req|
|
850
|
-
static VALUE
|
902
|
+
static VALUE rendezvous1(Context *c, Buf *req, DesCtx *d)
|
851
903
|
{
|
852
904
|
VALUE r;
|
853
905
|
Buf res;
|
854
906
|
int exc;
|
855
907
|
|
856
908
|
rendezvous_no_des(c, req, &res); // takes ownership of |req|
|
857
|
-
r = rb_protect(deserialize, (VALUE)&res, &exc);
|
909
|
+
r = rb_protect(deserialize, (VALUE)&(struct rendezvous_des){d, &res}, &exc);
|
858
910
|
buf_reset(&res);
|
859
911
|
if (exc) {
|
860
912
|
r = rb_errinfo();
|
@@ -869,6 +921,14 @@ static VALUE rendezvous(Context *c, Buf *req)
|
|
869
921
|
return r;
|
870
922
|
}
|
871
923
|
|
924
|
+
static VALUE rendezvous(Context *c, Buf *req)
|
925
|
+
{
|
926
|
+
DesCtx d;
|
927
|
+
|
928
|
+
DesCtx_init(&d);
|
929
|
+
return rendezvous1(c, req, &d);
|
930
|
+
}
|
931
|
+
|
872
932
|
static void handle_exception(VALUE e)
|
873
933
|
{
|
874
934
|
const char *s;
|
@@ -1062,7 +1122,7 @@ static VALUE context_attach(VALUE self, VALUE name, VALUE proc)
|
|
1062
1122
|
// request is (A)ttach, [name, id] array
|
1063
1123
|
ser_init1(&s, 'A');
|
1064
1124
|
ser_array_begin(&s, 2);
|
1065
|
-
|
1125
|
+
add_string(&s, name);
|
1066
1126
|
ser_int(&s, RARRAY_LENINT(c->procs));
|
1067
1127
|
ser_array_end(&s, 2);
|
1068
1128
|
rb_ary_push(c->procs, proc);
|
@@ -1159,8 +1219,8 @@ static VALUE context_eval(int argc, VALUE *argv, VALUE self)
|
|
1159
1219
|
// request is (E)val, [filename, source] array
|
1160
1220
|
ser_init1(&s, 'E');
|
1161
1221
|
ser_array_begin(&s, 2);
|
1162
|
-
|
1163
|
-
|
1222
|
+
add_string(&s, filename);
|
1223
|
+
add_string(&s, source);
|
1164
1224
|
ser_array_end(&s, 2);
|
1165
1225
|
// response is [result, errname] array
|
1166
1226
|
a = rendezvous(c, &s.b); // takes ownership of |s.b|
|
@@ -1450,6 +1510,7 @@ static VALUE snapshot_initialize(int argc, VALUE *argv, VALUE self)
|
|
1450
1510
|
VALUE a, e, code, cv;
|
1451
1511
|
Snapshot *ss;
|
1452
1512
|
Context *c;
|
1513
|
+
DesCtx d;
|
1453
1514
|
Ser s;
|
1454
1515
|
|
1455
1516
|
TypedData_Get_Struct(self, Snapshot, &snapshot_type, ss);
|
@@ -1462,9 +1523,11 @@ static VALUE snapshot_initialize(int argc, VALUE *argv, VALUE self)
|
|
1462
1523
|
TypedData_Get_Struct(cv, Context, &context_type, c);
|
1463
1524
|
// request is snapsho(T), "code"
|
1464
1525
|
ser_init1(&s, 'T');
|
1465
|
-
|
1526
|
+
add_string(&s, code);
|
1466
1527
|
// response is [arraybuffer, error]
|
1467
|
-
|
1528
|
+
DesCtx_init(&d);
|
1529
|
+
d.transcode_latin1 = 0; // don't mangle snapshot binary data
|
1530
|
+
a = rendezvous1(c, &s.b, &d);
|
1468
1531
|
e = rb_ary_pop(a);
|
1469
1532
|
context_dispose(cv);
|
1470
1533
|
if (*RSTRING_PTR(e))
|
@@ -1478,6 +1541,7 @@ static VALUE snapshot_warmup(VALUE self, VALUE arg)
|
|
1478
1541
|
VALUE a, e, cv;
|
1479
1542
|
Snapshot *ss;
|
1480
1543
|
Context *c;
|
1544
|
+
DesCtx d;
|
1481
1545
|
Ser s;
|
1482
1546
|
|
1483
1547
|
TypedData_Get_Struct(self, Snapshot, &snapshot_type, ss);
|
@@ -1489,10 +1553,12 @@ static VALUE snapshot_warmup(VALUE self, VALUE arg)
|
|
1489
1553
|
ser_init1(&s, 'W');
|
1490
1554
|
ser_array_begin(&s, 2);
|
1491
1555
|
ser_string8(&s, (const uint8_t *)RSTRING_PTR(ss->blob), RSTRING_LENINT(ss->blob));
|
1492
|
-
|
1556
|
+
add_string(&s, arg);
|
1493
1557
|
ser_array_end(&s, 2);
|
1494
1558
|
// response is [arraybuffer, error]
|
1495
|
-
|
1559
|
+
DesCtx_init(&d);
|
1560
|
+
d.transcode_latin1 = 0; // don't mangle snapshot binary data
|
1561
|
+
a = rendezvous1(c, &s.b, &d);
|
1496
1562
|
e = rb_ary_pop(a);
|
1497
1563
|
context_dispose(cv);
|
1498
1564
|
if (*RSTRING_PTR(e))
|
@@ -303,6 +303,14 @@ static void ser_string8(Ser *s, const uint8_t *p, size_t n)
|
|
303
303
|
w(s, p, n);
|
304
304
|
}
|
305
305
|
|
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
|
+
|
306
314
|
static void ser_object_begin(Ser *s)
|
307
315
|
{
|
308
316
|
w_byte(s, 'o');
|
@@ -362,6 +370,7 @@ static int des1(char (*err)[64], const uint8_t **p, const uint8_t *pe,
|
|
362
370
|
|
363
371
|
if (depth < 0)
|
364
372
|
return bail(err, "too much recursion");
|
373
|
+
again:
|
365
374
|
if (*p >= pe)
|
366
375
|
goto too_short;
|
367
376
|
switch ((c = *(*p)++)) {
|
@@ -372,7 +381,9 @@ static int des1(char (*err)[64], const uint8_t **p, const uint8_t *pe,
|
|
372
381
|
snprintf(*err, sizeof(*err), "bad tag: %02x", c);
|
373
382
|
}
|
374
383
|
return -1;
|
375
|
-
case '\0': // padding
|
384
|
+
case '\0': // skip alignment padding for two-byte strings
|
385
|
+
if (*p < pe)
|
386
|
+
goto again;
|
376
387
|
break;
|
377
388
|
case '^':
|
378
389
|
if (r_varint(p, pe, &u))
|
data/lib/mini_racer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_racer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.17.0.
|
4
|
+
version: 0.17.0.pre9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-01-
|
11
|
+
date: 2025-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -123,9 +123,9 @@ licenses:
|
|
123
123
|
- MIT
|
124
124
|
metadata:
|
125
125
|
bug_tracker_uri: https://github.com/discourse/mini_racer/issues
|
126
|
-
changelog_uri: https://github.com/discourse/mini_racer/blob/v0.17.0.
|
127
|
-
documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.17.0.
|
128
|
-
source_code_uri: https://github.com/discourse/mini_racer/tree/v0.17.0.
|
126
|
+
changelog_uri: https://github.com/discourse/mini_racer/blob/v0.17.0.pre9/CHANGELOG
|
127
|
+
documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.17.0.pre9
|
128
|
+
source_code_uri: https://github.com/discourse/mini_racer/tree/v0.17.0.pre9
|
129
129
|
post_install_message:
|
130
130
|
rdoc_options: []
|
131
131
|
require_paths:
|