File tree Expand file tree Collapse file tree 4 files changed +47
-4
lines changed
src/main/ruby/truffleruby/core Expand file tree Collapse file tree 4 files changed +47
-4
lines changed Original file line number Diff line number Diff line change @@ -45,6 +45,7 @@ Compatibility:
45
45
* Support refinements for ` #to_s ` called by string interpolation (#2110 , @ssnickolay )
46
46
* Module#using raises error in method scope (#2112 , @ssnickolay )
47
47
* ` File#path ` now returns a new mutable String on every call like MRI (#2115 ).
48
+ * Avoid infinite recursion when redefining ` Warning#warn ` and calling ` Kernel#warn ` (#2109 ).
48
49
49
50
Performance:
50
51
Original file line number Diff line number Diff line change @@ -197,4 +197,35 @@ def o.to_sym; :deprecated; end
197
197
-> { warn ( **h ) } . should_not complain ( verbose : true )
198
198
-> { warn ( 'foo' , **h ) } . should complain ( "foo\n " )
199
199
end
200
+
201
+ it "does not call Warning.warn if self is the Warning module" do
202
+ # RubyGems redefines Kernel#warn so we need to use a subprocess and disable RubyGems here
203
+ code = <<-RUBY
204
+ def Warning.warn(*args, **kwargs)
205
+ raise 'should not be called'
206
+ end
207
+ Kernel.instance_method(:warn).bind(Warning).call('Kernel#warn spec edge case')
208
+ RUBY
209
+ out = ruby_exe ( code , args : "2>&1" , options : "--disable-gems" )
210
+ out . should == "Kernel#warn spec edge case\n "
211
+ $?. should . success?
212
+ end
213
+
214
+ it "avoids recursion if Warning#warn is redefined and calls super" do
215
+ # This works because of the spec above, which is the workaround for it.
216
+ # Note that redefining Warning#warn is a mistake which would naturally end in infinite recursion,
217
+ # Warning.extend Module.new { def warn } should be used instead.
218
+ # RubyGems redefines Kernel#warn so we need to use a subprocess and disable RubyGems here
219
+ code = <<-RUBY
220
+ module Warning
221
+ def warn(*args)
222
+ super
223
+ end
224
+ end
225
+ warn "avoid infinite recursion"
226
+ RUBY
227
+ out = ruby_exe ( code , args : "2>&1" , options : "--disable-gems" )
228
+ out . should == "avoid infinite recursion\n "
229
+ $?. should . success?
230
+ end
200
231
end
Original file line number Diff line number Diff line change 1
1
slow:Kernel#warn :uplevel keyword argument shows the caller of #require and not #require itself without RubyGems
2
2
slow:Kernel#warn :uplevel keyword argument shows the caller of #require and not #require itself with RubyGems loaded
3
+ slow:Kernel#warn does not call Warning.warn if self is the Warning module
4
+ slow:Kernel#warn avoids recursion if Warning#warn is redefined and calls super
Original file line number Diff line number Diff line change @@ -643,7 +643,7 @@ def untrace_var(name, cmd=undefined)
643
643
def warn ( *messages , uplevel : undefined )
644
644
if !Primitive . nil? ( $VERBOSE) && !messages . empty?
645
645
prefix = if Primitive . undefined? ( uplevel )
646
- + ''
646
+ ''
647
647
else
648
648
uplevel = Primitive . rb_to_int ( uplevel )
649
649
raise ArgumentError , "negative level (#{ uplevel } )" unless uplevel >= 0
@@ -662,13 +662,22 @@ def warn(*messages, uplevel: undefined)
662
662
if caller
663
663
"#{ caller . path } :#{ caller . lineno } : warning: "
664
664
else
665
- + 'warning: '
665
+ 'warning: '
666
666
end
667
667
end
668
668
669
- stringio = Truffle ::StringOperations ::SimpleStringIO . new ( prefix )
669
+ stringio = Truffle ::StringOperations ::SimpleStringIO . new ( + prefix )
670
670
Truffle ::IOOperations . puts ( stringio , *messages )
671
- Warning . warn ( stringio . string )
671
+ message = stringio . string
672
+
673
+ if Primitive . object_equal ( self , Warning ) # avoid recursion when redefining Warning#warn
674
+ unless message . encoding . ascii_compatible?
675
+ raise Encoding ::CompatibilityError , "ASCII incompatible encoding: #{ message . encoding } "
676
+ end
677
+ $stderr. write message
678
+ else
679
+ Warning . warn ( message )
680
+ end
672
681
end
673
682
nil
674
683
end
You can’t perform that action at this time.
0 commit comments