Skip to content

Commit 7102d5c

Browse files
committed
Convert pattern argument to String with #to_str
1 parent 6e38470 commit 7102d5c

File tree

4 files changed

+49
-14
lines changed

4 files changed

+49
-14
lines changed

spec/ruby/core/regexp/compile_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@
1313
describe "Regexp.compile given a Regexp" do
1414
it_behaves_like :regexp_new_regexp, :compile
1515
end
16+
17+
describe "Regexp.new given a non-String/Regexp" do
18+
it_behaves_like :regexp_new_non_string_or_regexp, :compile
19+
end

spec/ruby/core/regexp/new_spec.rb

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,6 @@
1414
it_behaves_like :regexp_new_string_binary, :compile
1515
end
1616

17-
describe "Regexp.new given an Integer" do
18-
it "raises a TypeError" do
19-
-> { Regexp.new(1) }.should raise_error(TypeError)
20-
end
21-
end
22-
23-
describe "Regexp.new given a Float" do
24-
it "raises a TypeError" do
25-
-> { Regexp.new(1.0) }.should raise_error(TypeError)
26-
end
27-
end
17+
describe "Regexp.new given a non-String/Regexp" do
18+
it_behaves_like :regexp_new_non_string_or_regexp, :new
19+
end

spec/ruby/core/regexp/shared/new.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,32 @@ class RegexpSpecsSubclassTwo < Regexp; end
2424
end
2525
end
2626

27+
describe :regexp_new_non_string_or_regexp, shared: true do
28+
it "calls #to_str method for non-String/Regexp argument" do
29+
obj = Object.new
30+
def obj.to_str() "a" end
31+
32+
Regexp.send(@method, obj).should == /a/
33+
end
34+
35+
it "raises TypeError if there is no #to_str method for non-String/Regexp argument" do
36+
obj = Object.new
37+
-> { Regexp.send(@method, obj) }.should raise_error(TypeError, "no implicit conversion of Object into String")
38+
39+
-> { Regexp.send(@method, 1) }.should raise_error(TypeError, "no implicit conversion of Integer into String")
40+
-> { Regexp.send(@method, 1.0) }.should raise_error(TypeError, "no implicit conversion of Float into String")
41+
-> { Regexp.send(@method, :symbol) }.should raise_error(TypeError, "no implicit conversion of Symbol into String")
42+
-> { Regexp.send(@method, []) }.should raise_error(TypeError, "no implicit conversion of Array into String")
43+
end
44+
45+
it "raises TypeError if #to_str returns non-String value" do
46+
obj = Object.new
47+
def obj.to_str() [] end
48+
49+
-> { Regexp.send(@method, obj) }.should raise_error(TypeError, /can't convert Object to String/)
50+
end
51+
end
52+
2753
describe :regexp_new_string, shared: true do
2854
it "uses the String argument as an unescaped literal to construct a Regexp object" do
2955
Regexp.send(@method, "^hi{2,3}fo.o$").should == /^hi{2,3}fo.o$/
@@ -97,6 +123,16 @@ class RegexpSpecsSubclassTwo < Regexp; end
97123
(r.options & Regexp::EXTENDED).should_not == 0
98124
end
99125

126+
it "does not try to convert the second argument to Integer with #to_int method call" do
127+
ScratchPad.clear
128+
obj = Object.new
129+
def obj.to_int() ScratchPad.record(:called) end
130+
131+
Regexp.send(@method, "Hi", obj)
132+
133+
ScratchPad.recorded.should == nil
134+
end
135+
100136
ruby_version_is ""..."3.2" do
101137
it "treats any non-Integer, non-nil, non-false second argument as IGNORECASE" do
102138
r = Regexp.send(@method, 'Hi', Object.new)

src/main/ruby/truffleruby/core/regexp.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ def self.new(pattern, opts=nil, lang=nil)
134134
if Primitive.object_kind_of?(pattern, Regexp)
135135
opts = pattern.options
136136
pattern = pattern.source
137-
elsif Primitive.object_kind_of?(pattern, Integer) or Primitive.object_kind_of?(pattern, Float)
138-
raise TypeError, "can't convert #{pattern.class} into String"
139-
elsif Primitive.object_kind_of?(opts, Integer)
137+
elsif Primitive.object_kind_of?(pattern, String)
138+
else
139+
pattern = Truffle::Type.rb_convert_type pattern, String, :to_str
140+
end
141+
142+
if Primitive.object_kind_of?(opts, Integer)
140143
opts = opts & (OPTION_MASK | KCODE_MASK) if opts > 0
141144
elsif opts
142145
opts = IGNORECASE

0 commit comments

Comments
 (0)