mini_racer 0.17.0.pre4 → 0.17.0.pre5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 877bcc1b7a601bcd6ef672cc17caeb7e21df723a440b1d07a2a4931e2a4d118a
4
- data.tar.gz: e8ea952ea537c94d1c05998d521555d78349755ab1172925b24a4135d6691d99
3
+ metadata.gz: bd92c74de497ca8b317cb32e02345d204081c50ef44c11a61b0cfef3e32e2cff
4
+ data.tar.gz: b2074ffd330b91006c28e0d6b9a4b346a9a0e6d9de30cffd83bb426189262c4d
5
5
  SHA512:
6
- metadata.gz: d1f45fb9e917632eff3131c9399710fad8f7ef47228e02f72a139122efd13565055b2851dc9348e6852cf009e1c5c93f0adf970544983f7713457f482a976a8d
7
- data.tar.gz: 8ede15ef0dbe8a2b16ad9567d584ef57fcd2e0a2e801931476d7b4107d3c05154f70a5d1d96d7960919b939a4ea496d6d101a994b625d9a8000b79c7ee49bcc9
6
+ metadata.gz: 36dd26be30d9e22f5c227f8864a03e6f55224b9265799d604bf933b7458ead17960fef48de19a8d33f6c3c1578f83740c9c8c704541beb7964f6de23f4ec1fb9
7
+ data.tar.gz: 89067b89d2dbd6cf7b2af79991f30e53c6df8cc7d08e35623f730eb7010c287ccb98a29444375a7593f4494e11ad25b2c74a3d0b73ce104f7fc64edf22fb9e7e
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ - 0.17.0.pre5 - 30-09-2024
2
+
3
+ - Handle segfault from JSON.stringify
4
+ - Fix segfaults around symbol conversion
5
+ - Fix crash on invalid date object
6
+
7
+
1
8
  - 0.17.0.pre4 - 18-09-2024
2
9
 
3
10
  - Attempt to change compilation flags to disable strict aliasing to see if it resolves stability issues
@@ -429,14 +429,17 @@ static void prepare_result(MaybeLocal<Value> v8res,
429
429
  Local<Object> object = local_value->ToObject(context).ToLocalChecked();
430
430
  const unsigned argc = 1;
431
431
  Local<Value> argv[argc] = { object };
432
- MaybeLocal<Value> json = stringify->Call(context, JSON, argc, argv);
432
+ MaybeLocal<Value> maybe_json = stringify->Call(context, JSON, argc, argv);
433
+ Local<Value> json;
433
434
 
434
- if (json.IsEmpty()) {
435
+ if (!maybe_json.ToLocal(&json)) {
435
436
  evalRes.executed = false;
436
437
  } else {
437
- evalRes.json = true;
438
+ // JSON.stringify() returns undefined for inputs that
439
+ // are exotic objects, like WASM function or string refs
440
+ evalRes.json = !json->IsUndefined();
438
441
  Persistent<Value>* persistent = new Persistent<Value>();
439
- persistent->Reset(isolate, json.ToLocalChecked());
442
+ persistent->Reset(isolate, json);
440
443
  evalRes.value = persistent;
441
444
  }
442
445
  }
@@ -565,6 +568,7 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
565
568
 
566
569
  Isolate::Scope isolate_scope(isolate);
567
570
  HandleScope scope(isolate);
571
+ Context::Scope context_scope(context);
568
572
 
569
573
  StackCounter stackCounter(isolate);
570
574
 
@@ -586,10 +590,6 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
586
590
  return INT2FIX(value->Int32Value(context).ToChecked());
587
591
  }
588
592
 
589
- if (value->IsNumber()) {
590
- return rb_float_new(value->NumberValue(context).ToChecked());
591
- }
592
-
593
593
  if (value->IsTrue()) {
594
594
  return Qtrue;
595
595
  }
@@ -598,81 +598,108 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
598
598
  return Qfalse;
599
599
  }
600
600
 
601
- if (value->IsArray()) {
602
- VALUE rb_array = rb_ary_new();
603
- Local<Array> arr = Local<Array>::Cast(value);
604
- for(uint32_t i=0; i < arr->Length(); i++) {
605
- MaybeLocal<Value> element = arr->Get(context, i);
606
- if (element.IsEmpty()) {
607
- continue;
608
- }
609
- VALUE rb_elem = convert_v8_to_ruby(isolate, context, element.ToLocalChecked());
610
- if (rb_funcall(rb_elem, rb_intern("class"), 0) == rb_cFailedV8Conversion) {
611
- return rb_elem;
612
- }
613
- rb_ary_push(rb_array, rb_elem);
614
- }
615
- return rb_array;
616
- }
617
-
618
- if (value->IsFunction()){
619
- return rb_funcall(rb_cJavaScriptFunction, rb_intern("new"), 0);
620
- }
621
-
622
- if (value->IsDate()){
623
- double ts = Local<Date>::Cast(value)->ValueOf();
624
- double secs = ts/1000;
625
- long nanos = round((secs - floor(secs)) * 1000000);
626
-
627
- return rb_time_new(secs, nanos);
628
- }
629
-
630
- if (value->IsObject()) {
631
- VALUE rb_hash = rb_hash_new();
632
- TryCatch trycatch(isolate);
633
-
634
- Local<Object> object = value->ToObject(context).ToLocalChecked();
635
- auto maybe_props = object->GetOwnPropertyNames(context);
636
- if (!maybe_props.IsEmpty()) {
637
- Local<Array> props = maybe_props.ToLocalChecked();
638
- for(uint32_t i=0; i < props->Length(); i++) {
639
- MaybeLocal<Value> key = props->Get(context, i);
640
- if (key.IsEmpty()) {
641
- return rb_funcall(rb_cFailedV8Conversion, rb_intern("new"), 1, rb_str_new2(""));
642
- }
643
- VALUE rb_key = convert_v8_to_ruby(isolate, context, key.ToLocalChecked());
644
-
645
- MaybeLocal<Value> prop_value = object->Get(context, key.ToLocalChecked());
646
- // this may have failed due to Get raising
647
- if (prop_value.IsEmpty() || trycatch.HasCaught()) {
648
- return new_empty_failed_conv_obj();
649
- }
650
-
651
- VALUE rb_value = convert_v8_to_ruby(
652
- isolate, context, prop_value.ToLocalChecked());
653
- rb_hash_aset(rb_hash, rb_key, rb_value);
601
+ struct State {
602
+ Isolate* isolate;
603
+ Local<Value> value;
604
+ Local<Context> context;
605
+ } state = {isolate, value, context};
606
+
607
+ // calls to rb_*() functions can raise exceptions and longjmp,
608
+ // and therefore must be inside this protected block
609
+ auto can_raise = [](VALUE arg) -> VALUE {
610
+ State* state =
611
+ reinterpret_cast<State*>(static_cast<uintptr_t>(RB_NUM2ULL(arg)));
612
+ Isolate* isolate = state->isolate;
613
+ Local<Value> value = state->value;
614
+ Local<Context> context = state->context;
615
+
616
+ if (value->IsNumber()) {
617
+ return rb_float_new(value->NumberValue(context).ToChecked());
618
+ }
619
+
620
+ if (value->IsArray()) {
621
+ VALUE rb_array = rb_ary_new();
622
+ Local<Array> arr = Local<Array>::Cast(value);
623
+ for(uint32_t i = 0; i < arr->Length(); i++) {
624
+ MaybeLocal<Value> element = arr->Get(context, i);
625
+ if (element.IsEmpty()) {
626
+ continue;
627
+ }
628
+ VALUE rb_elem = convert_v8_to_ruby(isolate, context, element.ToLocalChecked());
629
+ if (rb_funcall(rb_elem, rb_intern("class"), 0) == rb_cFailedV8Conversion) {
630
+ return rb_elem;
631
+ }
632
+ rb_ary_push(rb_array, rb_elem);
654
633
  }
634
+ return rb_array;
655
635
  }
656
- return rb_hash;
657
- }
658
636
 
659
- if (value->IsSymbol()) {
660
- v8::String::Utf8Value symbol_name(isolate,
661
- Local<Symbol>::Cast(value)->Description(isolate));
637
+ if (value->IsFunction()){
638
+ return rb_funcall(rb_cJavaScriptFunction, rb_intern("new"), 0);
639
+ }
662
640
 
663
- VALUE str_symbol = rb_utf8_str_new(*symbol_name, symbol_name.length());
641
+ if (value->IsDate()){
642
+ double ts = Local<Date>::Cast(value)->ValueOf();
643
+ double secs = ts/1000;
644
+ long nanos = round((secs - floor(secs)) * 1000000);
664
645
 
665
- return rb_str_intern(str_symbol);
666
- }
646
+ return rb_time_new(secs, nanos);
647
+ }
667
648
 
668
- MaybeLocal<String> rstr_maybe = value->ToString(context);
649
+ if (value->IsObject()) {
650
+ VALUE rb_hash = rb_hash_new();
651
+ TryCatch trycatch(isolate);
652
+
653
+ Local<Object> object = value->ToObject(context).ToLocalChecked();
654
+ auto maybe_props = object->GetOwnPropertyNames(context);
655
+ if (!maybe_props.IsEmpty()) {
656
+ Local<Array> props = maybe_props.ToLocalChecked();
657
+ for (uint32_t i = 0; i < props->Length(); i++) {
658
+ MaybeLocal<Value> key = props->Get(context, i);
659
+ if (key.IsEmpty()) {
660
+ return rb_funcall(rb_cFailedV8Conversion, rb_intern("new"), 1, rb_str_new2(""));
661
+ }
662
+ VALUE rb_key = convert_v8_to_ruby(isolate, context, key.ToLocalChecked());
669
663
 
670
- if (rstr_maybe.IsEmpty()) {
671
- return Qnil;
672
- } else {
673
- Local<String> rstr = rstr_maybe.ToLocalChecked();
674
- return rb_utf8_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(isolate));
675
- }
664
+ MaybeLocal<Value> prop_value = object->Get(context, key.ToLocalChecked());
665
+ // this may have failed due to Get raising
666
+ if (prop_value.IsEmpty() || trycatch.HasCaught()) {
667
+ return new_empty_failed_conv_obj();
668
+ }
669
+
670
+ VALUE rb_value = convert_v8_to_ruby(
671
+ isolate, context, prop_value.ToLocalChecked());
672
+ rb_hash_aset(rb_hash, rb_key, rb_value);
673
+ }
674
+ }
675
+ return rb_hash;
676
+ }
677
+
678
+ if (value->IsSymbol()) {
679
+ Local<Symbol> symbol = Local<Symbol>::Cast(value);
680
+ Local<Value> description = symbol->Description(isolate);
681
+ v8::String::Utf8Value symbol_name(isolate, description);
682
+
683
+ VALUE str_symbol = rb_utf8_str_new(*symbol_name, symbol_name.length());
684
+
685
+ return rb_str_intern(str_symbol);
686
+ }
687
+
688
+ MaybeLocal<String> rstr_maybe = value->ToString(context);
689
+
690
+ if (rstr_maybe.IsEmpty()) {
691
+ return Qnil;
692
+ } else {
693
+ Local<String> rstr = rstr_maybe.ToLocalChecked();
694
+ return rb_utf8_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(isolate));
695
+ }
696
+ };
697
+
698
+ // this is kind of slow because RB_ULL2NUM allocs when the pointer
699
+ // doesn't fit in a fixnum but yolo'ing and reinterpret_casting the
700
+ // pointer to a VALUE is probably not very sound
701
+ VALUE arg = RB_ULL2NUM(reinterpret_cast<uintptr_t>(&state));
702
+ return rb_protect(can_raise, arg, nullptr);
676
703
  }
677
704
 
678
705
  static VALUE convert_v8_to_ruby(Isolate* isolate,
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniRacer
4
- VERSION = "0.17.0.pre4"
4
+ VERSION = "0.17.0.pre5"
5
5
  LIBV8_NODE_VERSION = "~> 22.7.0.4"
6
6
  end
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.pre4
4
+ version: 0.17.0.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-17 00:00:00.000000000 Z
11
+ date: 2024-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -119,9 +119,9 @@ licenses:
119
119
  - MIT
120
120
  metadata:
121
121
  bug_tracker_uri: https://github.com/discourse/mini_racer/issues
122
- changelog_uri: https://github.com/discourse/mini_racer/blob/v0.17.0.pre4/CHANGELOG
123
- documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.17.0.pre4
124
- source_code_uri: https://github.com/discourse/mini_racer/tree/v0.17.0.pre4
122
+ changelog_uri: https://github.com/discourse/mini_racer/blob/v0.17.0.pre5/CHANGELOG
123
+ documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.17.0.pre5
124
+ source_code_uri: https://github.com/discourse/mini_racer/tree/v0.17.0.pre5
125
125
  post_install_message:
126
126
  rdoc_options: []
127
127
  require_paths: