Skip to content

Commit 10947dc

Browse files
andrykonchineregon
authored andcommitted
Fix Marshal.load and preserves Regexp source encoding
1 parent a69c0c4 commit 10947dc

File tree

5 files changed

+26
-15
lines changed

5 files changed

+26
-15
lines changed

spec/ruby/core/marshal/shared/load.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@
776776
[Meths, MethsMore, Regexp]
777777
end
778778

779-
it "loads a extended_user_regexp having ivar" do
779+
it "loads a Regexp subclass instance variables when it is extended with a module" do
780780
obj = UserRegexp.new('').extend(Meths)
781781
obj.instance_variable_set(:@noise, 'much')
782782

@@ -799,6 +799,14 @@
799799
new_obj.instance_variable_get(:@regexp_ivar).should == [42]
800800
end
801801
end
802+
803+
it "preserves Regexp encoding" do
804+
source_object = Regexp.new("a".encode("utf-32le"))
805+
regexp = Marshal.send(@method, Marshal.dump(source_object))
806+
807+
regexp.encoding.should == Encoding::UTF_32LE
808+
regexp.source.should == "a".encode("utf-32le")
809+
end
802810
end
803811

804812
describe "for a Float" do

spec/tags/core/marshal/load_tags.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
fails:Marshal.load loads an array containing objects having _dump method, and with proc
2-
fails:Marshal.load loads an array containing objects having marshal_dump method, and with proc
31
fails:Marshal.load loads a Random
42
fails:Marshal.load when called with a proc returns the value of the proc
5-
fails:Marshal.load when called with a proc calls the proc for recursively visited data
63
fails:Marshal.load when called with a proc loads an Array with proc
74
fails:Marshal.load for an Array loads an array containing the same objects
85
fails:Marshal.load for an Object raises ArgumentError if the object from an 'o' stream is not dumpable as 'o' type user class
@@ -23,3 +20,4 @@ fails:Marshal.load when called with freeze: true when called with a proc does no
2320
fails:Marshal.load when called with freeze: true does freeze extended objects
2421
fails:Marshal.load when called with freeze: true does freeze extended objects with instance variables
2522
fails:Marshal.load for a Regexp restore the regexp instance variables
23+
fails:Marshal.load for a Regexp loads a Regexp subclass instance variables when it is extended with a module

spec/tags/core/marshal/restore_tags.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
fails:Marshal.restore loads an array containing objects having _dump method, and with proc
2-
fails:Marshal.restore loads an array containing objects having marshal_dump method, and with proc
31
fails:Marshal.restore loads a Random
42
fails:Marshal.restore when called with a proc returns the value of the proc
5-
fails:Marshal.restore when called with a proc calls the proc for recursively visited data
63
fails:Marshal.restore when called with a proc loads an Array with proc
74
fails:Marshal.restore for an Array loads an array containing the same objects
85
fails:Marshal.restore for an Object raises ArgumentError if the object from an 'o' stream is not dumpable as 'o' type user class
@@ -23,3 +20,4 @@ fails:Marshal.restore when called with freeze: true when called with a proc does
2320
fails:Marshal.restore when called with freeze: true does freeze extended objects
2421
fails:Marshal.restore when called with freeze: true does freeze extended objects with instance variables
2522
fails:Marshal.restore for a Regexp restore the regexp instance variables
23+
fails:Marshal.restore for a Regexp loads a Regexp subclass instance variables when it is extended with a module

src/main/java/org/truffleruby/core/regexp/RubyRegexp.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@ public static RubyRegexp create(RubyLanguage language,
7575
public final TRegexCache tregexCache;
7676

7777
private RubyRegexp(Regex regex, RegexpOptions options) {
78-
// The RegexpNodes.compile operation may modify the encoding of the source rope. This modified copy is stored
79-
// in the Regex object as the "user object". Since ropes are immutable, we need to take this updated copy when
80-
// constructing the final regexp.
8178
this.regex = regex;
8279
final TStringWithEncoding tstringWithEncoding = (TStringWithEncoding) regex.getUserObject();
8380
this.source = tstringWithEncoding.tstring;

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ def construct(ivar_index = nil, call_proc = true)
641641
when 34 # ?"
642642
construct_string
643643
when 47 # ?/
644-
construct_regexp
644+
construct_regexp(ivar_index)
645645
when 91 # ?[
646646
construct_array
647647
when 123 # ?{
@@ -903,13 +903,23 @@ def construct_integer
903903
end
904904
end
905905

906-
def construct_regexp
907-
s = get_byte_sequence
906+
def construct_regexp(ivar_index)
907+
source = get_byte_sequence
908+
options = consume_byte
909+
910+
# A Regexp instance variables are ignored by CRuby,
911+
# but we need to know the encoding before building the Regexp
912+
if ivar_index and @has_ivar[ivar_index]
913+
# This sets the encoding of the String
914+
set_instance_variables source
915+
@has_ivar[ivar_index] = false
916+
end
917+
908918
if user_class?
909-
obj = user_class.new s, consume_byte
919+
obj = user_class.new source, options
910920
clear_user_class
911921
else
912-
obj = Regexp.new s, consume_byte
922+
obj = Regexp.new source, options
913923
end
914924

915925
store_unique_object obj

0 commit comments

Comments
 (0)