mini_racer 0.17.0.pre7 → 0.17.0.pre9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|