Skip to content

Commit 3aeff4f

Browse files
committed
[GR-32332] Backports for 21.2 batch 3
PullRequest: truffleruby/2793
2 parents f516172 + 18213b6 commit 3aeff4f

File tree

17 files changed

+211
-32
lines changed

17 files changed

+211
-32
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ Bug fixes:
1212
* Fix `File.{atime, mtime, ctime}` to include nanoseconds (#2337).
1313
* Fix `Array#[a, b] = "frozen string literal".freeze` (#2355).
1414
* `rb_funcall()` now releases the C-extension lock (similar to MRI).
15+
* Fix `rb_str_modify_expand` to preserve existing bytes (#2392).
16+
* Fix `Marshal.load` of multiple `Symbols` with an explicit encoding (#1624).
17+
* Fix `String#scrub` when replacement is frozen (#2398, @LillianZ).
1518

1619
Compatibility:
1720

@@ -37,6 +40,7 @@ Compatibility:
3740
* Implement `rb_backref_set`.
3841
* Fix `Float#<=>` when comparing `Infinity` to other `#infinite?` values.
3942
* Implement `date` library as a C extension to improve compatibility (#2344).
43+
* Update `rb_str_modify` and `rb_str_modify_expand` to raise a `FrozenError` when given a frozen string (#2392).
4044

4145
Performance:
4246

lib/cext/ABI_check.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2
1+
4

lib/cext/ABI_version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3
1+
21.2.0

lib/cext/include/truffleruby/truffleruby-pre.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ extern ID (*rb_tr_sym2id)(VALUE sym);
6969
#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
7070
#endif
7171

72+
// Defines
73+
74+
// To support racc releases before https://github.com/ruby/racc/pull/165
75+
#define HAVE_RB_BLOCK_CALL
76+
7277
#if defined(__cplusplus)
7378
}
7479
#endif

spec/ruby/core/marshal/dump_spec.rb

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,20 @@
7878
s = "\u2192".force_encoding("binary").to_sym
7979
Marshal.dump(s).should == "\x04\b:\b\xE2\x86\x92"
8080
end
81+
82+
it "dumps multiple Symbols sharing the same encoding" do
83+
# Note that the encoding is a link for the second Symbol
84+
symbol1 = "I:\t\xE2\x82\xACa\x06:\x06ET"
85+
symbol2 = "I:\t\xE2\x82\xACb\x06;\x06T"
86+
value = [
87+
"€a".force_encoding(Encoding::UTF_8).to_sym,
88+
"€b".force_encoding(Encoding::UTF_8).to_sym
89+
]
90+
Marshal.dump(value).should == "\x04\b[\a#{symbol1}#{symbol2}"
91+
92+
value = [*value, value[0]]
93+
Marshal.dump(value).should == "\x04\b[\b#{symbol1}#{symbol2};\x00"
94+
end
8195
end
8296

8397
describe "with an object responding to #marshal_dump" do
@@ -343,8 +357,13 @@
343357
end
344358

345359
it "dumps an extended Struct" do
346-
st = Struct.new("Extended", :a, :b).new
347-
Marshal.dump(st.extend(Meths)).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0"
360+
obj = Struct.new("Extended", :a, :b).new.extend(Meths)
361+
Marshal.dump(obj).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0"
362+
363+
s = 'hi'
364+
obj.a = [:a, s]
365+
obj.b = [:Meths, s]
366+
Marshal.dump(obj).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a"
348367
Struct.send(:remove_const, :Extended)
349368
end
350369
end

spec/ruby/core/marshal/fixtures/marshal_data.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class UserPreviouslyDefinedWithInitializedIvar
8383
end
8484

8585
class UserMarshal
86-
attr_reader :data
86+
attr_accessor :data
8787

8888
def initialize
8989
@data = 'stuff'

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

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@
309309

310310
it "loads an extended Array object containing a user-marshaled object" do
311311
obj = [UserMarshal.new, UserMarshal.new].extend(Meths)
312-
new_obj = Marshal.send(@method, "\x04\be:\nMeths[\ao:\x10UserMarshal\x06:\n@dataI\"\nstuff\x06:\x06ETo;\x06\x06;\aI\"\nstuff\x06;\bT")
312+
dump = "\x04\be:\nMeths[\ao:\x10UserMarshal\x06:\n@dataI\"\nstuff\x06:\x06ETo;\x06\x06;\aI\"\nstuff\x06;\bT"
313+
new_obj = Marshal.send(@method, dump)
313314

314315
new_obj.should == obj
315316
obj_ancestors = class << obj; ancestors[1..-1]; end
@@ -399,6 +400,24 @@
399400
sym.should == s
400401
sym.encoding.should == Encoding::BINARY
401402
end
403+
404+
it "loads multiple Symbols sharing the same encoding" do
405+
# Note that the encoding is a link for the second Symbol
406+
symbol1 = "I:\t\xE2\x82\xACa\x06:\x06ET"
407+
symbol2 = "I:\t\xE2\x82\xACb\x06;\x06T"
408+
dump = "\x04\b[\a#{symbol1}#{symbol2}"
409+
value = Marshal.send(@method, dump)
410+
value.map(&:encoding).should == [Encoding::UTF_8, Encoding::UTF_8]
411+
expected = [
412+
"€a".force_encoding(Encoding::UTF_8).to_sym,
413+
"€b".force_encoding(Encoding::UTF_8).to_sym
414+
]
415+
value.should == expected
416+
417+
value = Marshal.send(@method, "\x04\b[\b#{symbol1}#{symbol2};\x00")
418+
value.map(&:encoding).should == [Encoding::UTF_8, Encoding::UTF_8, Encoding::UTF_8]
419+
value.should == [*expected, expected[0]]
420+
end
402421
end
403422

404423
describe "for a String" do
@@ -460,20 +479,23 @@
460479
describe "for a Struct" do
461480
it "loads a extended_struct having fields with same objects" do
462481
s = 'hi'
463-
obj = Struct.new("Ure2", :a, :b).new.extend(Meths)
482+
obj = Struct.new("Extended", :a, :b).new.extend(Meths)
483+
dump = "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0"
484+
Marshal.send(@method, dump).should == obj
485+
464486
obj.a = [:a, s]
465487
obj.b = [:Meths, s]
466-
467-
Marshal.send(@method,
468-
"\004\be:\nMethsS:\021Struct::Ure2\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a"
469-
).should == obj
470-
Struct.send(:remove_const, :Ure2)
488+
dump = "\004\be:\nMethsS:\025Struct::Extended\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a"
489+
Marshal.send(@method, dump).should == obj
490+
Struct.send(:remove_const, :Extended)
471491
end
472492

473493
it "loads a struct having ivar" do
474494
obj = Struct.new("Thick").new
475495
obj.instance_variable_set(:@foo, 5)
476-
Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n").should == obj
496+
reloaded = Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n")
497+
reloaded.should == obj
498+
reloaded.instance_variable_get(:@foo).should == 5
477499
Struct.send(:remove_const, :Thick)
478500
end
479501

@@ -588,6 +610,18 @@
588610
end
589611
end
590612

613+
describe "for an object responding to #marshal_dump and #marshal_load" do
614+
it "loads a user-marshaled object" do
615+
obj = UserMarshal.new
616+
obj.data = :data
617+
value = [obj, :data]
618+
dump = Marshal.dump(value)
619+
dump.should == "\x04\b[\aU:\x10UserMarshal:\tdata;\x06"
620+
reloaded = Marshal.load(dump)
621+
reloaded.should == value
622+
end
623+
end
624+
591625
describe "for a user object" do
592626
it "loads a user-marshaled extended object" do
593627
obj = UserMarshal.new.extend(Meths)

spec/ruby/core/string/scrub_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,10 @@
119119
input.scrub!
120120
input.instance_variable_get(:@a).should == 'b'
121121
end
122+
123+
it "accepts a frozen string as a replacement" do
124+
input = "a\xE2"
125+
input.scrub!('.'.freeze)
126+
input.should == 'a.'
127+
end
122128
end

spec/ruby/optional/capi/ext/string_spec.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "ruby.h"
22
#include "rubyspec.h"
33

4+
#include <fcntl.h>
45
#include <string.h>
56
#include <stdarg.h>
67

@@ -279,6 +280,16 @@ VALUE string_spec_rb_str_resize_RSTRING_LEN(VALUE self, VALUE str, VALUE size) {
279280
return INT2FIX(RSTRING_LEN(modified));
280281
}
281282

283+
VALUE string_spec_rb_str_resize_copy(VALUE self, VALUE str) {
284+
rb_str_modify_expand(str, 5);
285+
char *buffer = RSTRING_PTR(str);
286+
buffer[1] = 'e';
287+
buffer[2] = 's';
288+
buffer[3] = 't';
289+
rb_str_resize(str, 4);
290+
return str;
291+
}
292+
282293
VALUE string_spec_rb_str_split(VALUE self, VALUE str) {
283294
return rb_str_split(str, ",");
284295
}
@@ -374,6 +385,20 @@ VALUE string_spec_RSTRING_PTR_after_yield(VALUE self, VALUE str) {
374385
return from_rstring_ptr;
375386
}
376387

388+
VALUE string_spec_RSTRING_PTR_read(VALUE self, VALUE str, VALUE path) {
389+
char *cpath = StringValueCStr(path);
390+
int fd = open(cpath, O_RDONLY);
391+
rb_str_modify_expand(str, 10);
392+
char *buffer = RSTRING_PTR(str);
393+
read(fd, buffer, 10);
394+
rb_str_modify_expand(str, 21);
395+
char *buffer2 = RSTRING_PTR(str);
396+
read(fd, buffer2 + 10, 11);
397+
rb_str_set_len(str, 21);
398+
close(fd);
399+
return str;
400+
}
401+
377402
VALUE string_spec_StringValue(VALUE self, VALUE str) {
378403
return StringValue(str);
379404
}
@@ -527,6 +552,7 @@ void Init_string_spec(void) {
527552
rb_define_method(cls, "rb_str_modify_expand", string_spec_rb_str_modify_expand, 2);
528553
rb_define_method(cls, "rb_str_resize", string_spec_rb_str_resize, 2);
529554
rb_define_method(cls, "rb_str_resize_RSTRING_LEN", string_spec_rb_str_resize_RSTRING_LEN, 2);
555+
rb_define_method(cls, "rb_str_resize_copy", string_spec_rb_str_resize_copy, 1);
530556
rb_define_method(cls, "rb_str_set_len", string_spec_rb_str_set_len, 2);
531557
rb_define_method(cls, "rb_str_set_len_RSTRING_LEN", string_spec_rb_str_set_len_RSTRING_LEN, 2);
532558
rb_define_method(cls, "rb_str_split", string_spec_rb_str_split, 1);
@@ -542,6 +568,7 @@ void Init_string_spec(void) {
542568
rb_define_method(cls, "RSTRING_PTR_set", string_spec_RSTRING_PTR_set, 3);
543569
rb_define_method(cls, "RSTRING_PTR_after_funcall", string_spec_RSTRING_PTR_after_funcall, 2);
544570
rb_define_method(cls, "RSTRING_PTR_after_yield", string_spec_RSTRING_PTR_after_yield, 1);
571+
rb_define_method(cls, "RSTRING_PTR_read", string_spec_RSTRING_PTR_read, 2);
545572
rb_define_method(cls, "StringValue", string_spec_StringValue, 1);
546573
rb_define_method(cls, "SafeStringValue", string_spec_SafeStringValue, 1);
547574
rb_define_method(cls, "rb_str_hash", string_spec_rb_str_hash, 1);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fixture file contents

0 commit comments

Comments
 (0)