@@ -118,6 +118,24 @@ def init_unsafe(isolate, snapshot)
118118 @js_symbol_to_symbol_func = eval_in_context "(x) => { var r = x.description; return r === undefined ? 'undefined' : r }"
119119 @js_new_date_func = eval_in_context "(x) => { return new Date(x) }"
120120 @js_new_array_func = eval_in_context "(x) => { return new Array(x) }"
121+ # looks up a (dotted) function name as properties from globalThis,
122+ # instead of evaluating the name as source code, so that names with
123+ # embedded NUL bytes or other invalid syntax resolve correctly
124+ @js_lookup_call_target_func = eval_in_context <<~JS
125+ (name) => {
126+ let target = globalThis;
127+ for (const key of name.split(".")) {
128+ if (target == null) {
129+ throw new ReferenceError(name + " is not defined");
130+ }
131+ target = target[key];
132+ }
133+ if (target === undefined) {
134+ throw new ReferenceError(name + " is not defined");
135+ }
136+ return target;
137+ }
138+ JS
121139 @js_new_uint8array_func = eval_in_context "(x) => { return new Uint8Array(x) }"
122140 end
123141
@@ -174,7 +192,7 @@ def call_unsafe(function_name, *arguments)
174192 raise RuntimeError , "TruffleRuby does not support call after stop" if @stopped
175193 begin
176194 translate do
177- function = eval_in_context ( function_name )
195+ function = @js_lookup_call_target_func . call ( convert_ruby_to_js ( encode ( function_name ) ) )
178196 function . call ( *convert_ruby_to_js ( arguments ) )
179197 end
180198 rescue Polyglot ::ForeignException => e
@@ -225,8 +243,11 @@ def translate
225243
226244 def convert_js_to_ruby ( value )
227245 case value
228- when true , false , Integer , Float
246+ when true , false , Integer
229247 value
248+ when Float
249+ # match the C extension: integral doubles convert to Ruby Integers
250+ value . finite? && value == value . truncate ? value . to_i : value
230251 else
231252 if value . nil?
232253 nil
@@ -370,6 +391,10 @@ def init_with_snapshot(snapshot)
370391 class Platform
371392 def self . set_flag_as_str! ( flag )
372393 raise TypeError , "wrong type argument #{ flag . class } (should be a string)" unless flag . is_a? ( String )
394+ raise ArgumentError , "flag contains NUL byte" if flag . include? ( "\0 " )
395+ # the C extension normalizes flags into a 256 byte "--flag" buffer
396+ normalized = flag . start_with? ( "--" ) ? flag : "--#{ flag } "
397+ raise ArgumentError , "flag too long" if normalized . bytesize >= 256
373398 raise MiniRacer ::PlatformAlreadyInitialized , "The platform is already initialized." if Context . instance_variable_get ( :@context_initialized )
374399 Context . instance_variable_set ( :@use_strict , true ) if "--use_strict" == flag
375400 end
0 commit comments