summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-13 21:41:45 +0000
committereregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-13 21:41:45 +0000
commit67078e81f57523fdf65ba7a9d919a146763363a5 (patch)
tree795ec86c6a90842d9168b0900d058c46244249f3
parent78890babe74e87aea79d1022ab455aeddf8a3310 (diff)
Update to ruby/spec@4bc7a2b
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--spec/ruby/appveyor.yml18
-rw-r--r--spec/ruby/core/enumerable/all_spec.rb101
-rw-r--r--spec/ruby/core/enumerable/any_spec.rb42
-rw-r--r--spec/ruby/core/enumerable/fixtures/classes.rb14
-rw-r--r--spec/ruby/core/enumerable/none_spec.rb185
-rw-r--r--spec/ruby/core/enumerable/one_spec.rb159
-rw-r--r--spec/ruby/core/kernel/autoload_spec.rb38
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_from_included_module.rb9
-rw-r--r--spec/ruby/core/kernel/fixtures/autoload_from_included_module2.rb9
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb43
-rw-r--r--spec/ruby/core/kernel/shared/then.rb20
-rw-r--r--spec/ruby/core/kernel/then_spec.rb8
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb56
-rw-r--r--spec/ruby/core/kernel/yield_self_spec.rb25
-rw-r--r--spec/ruby/core/string/dump_spec.rb25
-rw-r--r--spec/ruby/core/string/uminus_spec.rb17
-rw-r--r--spec/ruby/core/string/undump_spec.rb451
-rw-r--r--spec/ruby/core/thread/backtrace/location/base_label_spec.rb10
-rw-r--r--spec/ruby/core/tracepoint/parameters_spec.rb30
-rw-r--r--spec/ruby/language/super_spec.rb10
-rw-r--r--spec/ruby/security/cve_2011_4815_spec.rb13
-rw-r--r--spec/ruby/security/cve_2017_17742_spec.rb54
-rw-r--r--spec/ruby/security/cve_2018_6914_spec.rb78
-rw-r--r--spec/ruby/security/cve_2018_8780_spec.rb68
24 files changed, 1195 insertions, 288 deletions
diff --git a/spec/ruby/appveyor.yml b/spec/ruby/appveyor.yml
index 8ee5abd8b4..88dd753070 100644
--- a/spec/ruby/appveyor.yml
+++ b/spec/ruby/appveyor.yml
@@ -3,16 +3,20 @@ version: "{build}"
clone_depth: 5
init:
# To avoid duplicated executables in PATH, see https://github.com/ruby/spec/pull/468
- - set PATH=C:\ruby%RUBY_VERSION%\bin;C:\Program Files\7-Zip;C:\Program Files\AppVeyor\BuildAgent;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Program Files;C:\Windows
+ - set PATH=C:\Ruby%ruby_version%\bin;C:\Program Files\7-Zip;C:\Program Files\AppVeyor\BuildAgent;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Program Files;C:\Windows
# Loads trunk build and updates MSYS2 / MinGW to most recent gcc compiler
- - if %ruby_version%==_trunk (
- appveyor DownloadFile https://ci.appveyor.com/api/projects/MSP-Greg/ruby-loco/artifacts/ruby_trunk.7z -FileName C:\ruby_trunk.7z &
- 7z x C:\ruby_trunk.7z -oC:\ruby_trunk & C:\ruby_trunk\trunk_msys2.cmd)
+ - ps: |
+ if ($env:ruby_version -eq '_trunk') {
+ $trunk_uri = 'https://ci.appveyor.com/api/projects/MSP-Greg/ruby-loco/artifacts/ruby_trunk.7z'
+ (New-Object Net.WebClient).DownloadFile($trunk_uri, 'C:\ruby_trunk.7z')
+ 7z.exe x C:\ruby_trunk.7z -oC:\Ruby_trunk
+ }
+
environment:
matrix:
- - RUBY_VERSION: 23-x64
- - RUBY_VERSION: 24-x64
- - RUBY_VERSION: _trunk # So the folder name is ruby_trunk
+ - ruby_version: 24-x64
+ - ruby_version: 25-x64
+ - ruby_version: _trunk # So the folder name is ruby_trunk
install:
- git clone https://github.com/ruby/mspec.git ../mspec
build: off
diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb
index 1c96cdea17..b0edb14532 100644
--- a/spec/ruby/core/enumerable/all_spec.rb
+++ b/spec/ruby/core/enumerable/all_spec.rb
@@ -2,12 +2,11 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Enumerable#all?" do
-
before :each do
@enum = EnumerableSpecs::Numerous.new
@empty = EnumerableSpecs::Empty.new()
- @enum1 = [0, 1, 2, -1]
- @enum2 = [nil, false, true]
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
end
it "always returns true on empty enumeration" do
@@ -21,6 +20,21 @@ describe "Enumerable#all?" do
{}.all? { nil }.should == true
end
+ it "raises an ArgumentError when more than 1 argument is provided" do
+ lambda { @enum.all?(1, 2, 3) }.should raise_error(ArgumentError)
+ lambda { [].all?(1, 2, 3) }.should raise_error(ArgumentError)
+ lambda { {}.all?(1, 2, 3) }.should raise_error(ArgumentError)
+ end
+
+ ruby_version_is ""..."2.5" do
+ it "raises an ArgumentError when any arguments provided" do
+ lambda { @enum.all?(Proc.new {}) }.should raise_error(ArgumentError)
+ lambda { @enum.all?(nil) }.should raise_error(ArgumentError)
+ lambda { @empty.all?(1) }.should raise_error(ArgumentError)
+ lambda { @enum1.all?(1) {} }.should raise_error(ArgumentError)
+ end
+ end
+
it "does not hide exceptions out of #each" do
lambda {
EnumerableSpecs::ThrowingEach.new.all?
@@ -58,16 +72,6 @@ describe "Enumerable#all?" do
multi = EnumerableSpecs::YieldsMultiWithFalse.new
multi.all?.should be_true
end
-
- ruby_version_is "2.5" do
- describe "given a pattern argument" do
- # This spec should be replaced by more extensive ones
- it "returns true iff all match that pattern" do
- @enum.all?(Integer).should == true
- @enum2.all?(NilClass).should == false
- end
- end
- end
end
describe "with block" do
@@ -117,14 +121,79 @@ describe "Enumerable#all?" do
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
- multi.all? {|e| !(Array === e) }.should be_true
+ yielded = []
+ multi.all? { |e| yielded << e }.should == true
+ yielded.should == [1, 3, 6]
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
- multi.all? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2], [3, 4], [6, 7]]
+ multi.all? { |*args| yielded << args }.should == true
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
+ end
+ end
+
+ ruby_version_is "2.5" do
+ describe 'when given a pattern argument' do
+ it "calls `===` on the pattern the return value " do
+ pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
+ @enum1.all?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+ end
+
+ it "ignores block" do
+ @enum2.all?(NilClass) { raise }.should == false
+ [1, 2, nil].all?(NilClass) { raise }.should == false
+ {a: 1}.all?(Array) { raise }.should == true
+ end
+
+ it "always returns true on empty enumeration" do
+ @empty.all?(Integer).should == true
+ [].all?(Integer).should == true
+ {}.all?(NilClass).should == true
+ end
+
+ it "does not hide exceptions out of #each" do
+ lambda {
+ EnumerableSpecs::ThrowingEach.new.all?(Integer)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "returns true if the pattern never returns false or nil" do
+ pattern = EnumerableSpecs::Pattern.new { |x| 42 }
+ @enum.all?(pattern).should == true
+
+ [1, 42, 3].all?(pattern).should == true
+
+ pattern = EnumerableSpecs::Pattern.new { |x| Array === x }
+ {a: 1, b: 2}.all?(pattern).should == true
+ end
+
+ it "returns false if the pattern ever returns false or nil" do
+ pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
+ @enum1.all?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+
+ [1, 2, 3, -1].all?(pattern).should == false
+
+ pattern = EnumerableSpecs::Pattern.new { |x| x[1] >= 0 }
+ {a: 1, b: -1}.all?(pattern).should == false
+ end
+
+ it "does not hide exceptions out of pattern#===" do
+ pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
+ lambda {
+ @enum.all?(pattern)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ pattern = EnumerableSpecs::Pattern.new { true }
+ multi.all?(pattern).should == true
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
+ end
end
end
end
diff --git a/spec/ruby/core/enumerable/any_spec.rb b/spec/ruby/core/enumerable/any_spec.rb
index cd25f1440c..a4e98df736 100644
--- a/spec/ruby/core/enumerable/any_spec.rb
+++ b/spec/ruby/core/enumerable/any_spec.rb
@@ -4,9 +4,9 @@ require_relative 'fixtures/classes'
describe "Enumerable#any?" do
before :each do
@enum = EnumerableSpecs::Numerous.new
- @empty = EnumerableSpecs::Empty.new()
- @enum1 = [0, 1, 2, -1]
- @enum2 = [nil, false, true]
+ @empty = EnumerableSpecs::Empty.new
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
end
it "always returns false on empty enumeration" do
@@ -86,7 +86,7 @@ describe "Enumerable#any?" do
@enum2.any? { |i| i == nil }.should == true
end
- it "any? should return false if the block never returns other than false or nil" do
+ it "returns false if the block never returns other than false or nil" do
@enum.any? { false }.should == false
@enum.any? { nil }.should == false
@@ -134,32 +134,21 @@ describe "Enumerable#any?" do
it "gathers initial args as elements when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
- multi.any? {|e| e == 1 }.should be_true
+ yielded = []
+ multi.any? { |e| yielded << e; false }.should == false
+ yielded.should == [1, 3, 6]
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
- multi.any? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2]]
+ multi.any? { |*args| yielded << args; false }.should == false
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
-
end
ruby_version_is "2.5" do
describe 'when given a pattern argument' do
- class EnumerableSpecs::Pattern
- attr_reader :yielded
- def initialize(&block)
- @block = block
- @yielded = []
- end
- def ===(*args)
- @yielded << args
- @block.call(*args)
- end
- end
-
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
@enum1.any?(pattern).should == true
@@ -195,7 +184,7 @@ describe "Enumerable#any?" do
{a: 1, b: 2}.any?(pattern).should == true
end
- it "any? should return false if the block never returns other than false or nil" do
+ it "returns false if the block never returns other than false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| nil }
@enum1.any?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
@@ -204,7 +193,7 @@ describe "Enumerable#any?" do
{a: 1}.any?(pattern).should == false
end
- it "does not hide exceptions out of the block" do
+ it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
lambda {
@enum.any?(pattern)
@@ -212,13 +201,10 @@ describe "Enumerable#any?" do
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { false }
- EnumerableSpecs::YieldsMixed2.new.any?(pattern).should == false
- pattern.yielded.should == EnumerableSpecs::YieldsMixed2.gathered_yields.map { |x| [x] }
-
- pattern = EnumerableSpecs::Pattern.new { false }
- {a: 1, b: 2}.any?(pattern).should == false
- pattern.yielded.should == [[[:a, 1]], [[:b, 2]]]
+ multi.any?(pattern).should == false
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
end
end
diff --git a/spec/ruby/core/enumerable/fixtures/classes.rb b/spec/ruby/core/enumerable/fixtures/classes.rb
index 26a8aff8e2..e50bf34779 100644
--- a/spec/ruby/core/enumerable/fixtures/classes.rb
+++ b/spec/ruby/core/enumerable/fixtures/classes.rb
@@ -328,4 +328,18 @@ module EnumerableSpecs
EnumerableMapping.new(self, block)
end
end
+
+ class Pattern
+ attr_reader :yielded
+
+ def initialize(&block)
+ @block = block
+ @yielded = []
+ end
+
+ def ===(*args)
+ @yielded << args
+ @block.call(*args)
+ end
+ end
end # EnumerableSpecs utility classes
diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb
index 4425875f4b..04fb64e089 100644
--- a/spec/ruby/core/enumerable/none_spec.rb
+++ b/spec/ruby/core/enumerable/none_spec.rb
@@ -2,67 +2,164 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Enumerable#none?" do
- it "returns true if none of the elements in self are true" do
- e = EnumerableSpecs::Numerous.new(false, nil, false)
- e.none?.should be_true
+ before :each do
+ @empty = EnumerableSpecs::Empty.new
+ @enum = EnumerableSpecs::Numerous.new
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
end
- it "returns false if at least one of the elements in self are true" do
- e = EnumerableSpecs::Numerous.new(false, nil, true, false)
- e.none?.should be_false
+ it "always returns true on empty enumeration" do
+ @empty.none?.should == true
+ @empty.none? { true }.should == true
end
- it "gathers whole arrays as elements when each yields multiple" do
- # This spec doesn't spec what it says it does
- multi = EnumerableSpecs::YieldsMultiWithFalse.new
- multi.none?.should be_false
+ it "raises an ArgumentError when more than 1 argument is provided" do
+ lambda { @enum.none?(1, 2, 3) }.should raise_error(ArgumentError)
+ lambda { [].none?(1, 2, 3) }.should raise_error(ArgumentError)
+ lambda { {}.none?(1, 2, 3) }.should raise_error(ArgumentError)
end
- ruby_version_is "2.5" do
- describe "given a pattern argument" do
- # This spec should be replaced by more extensive ones
- it "returns true iff none match that pattern" do
- EnumerableSpecs::Numerous.new.none?(Float).should == true
- [nil, false, true].none?(NilClass).should == false
- end
+ ruby_version_is ""..."2.5" do
+ it "raises an ArgumentError when any arguments provided" do
+ lambda { @enum.none?(Proc.new {}) }.should raise_error(ArgumentError)
+ lambda { @enum.none?(nil) }.should raise_error(ArgumentError)
+ lambda { @empty.none?(1) }.should raise_error(ArgumentError)
+ lambda { @enum.none?(1) {} }.should raise_error(ArgumentError)
end
end
-end
-describe "Enumerable#none? with a block" do
- before :each do
- @e = EnumerableSpecs::Numerous.new(1,1,2,3,4)
- end
+ it "does not hide exceptions out of #each" do
+ lambda {
+ EnumerableSpecs::ThrowingEach.new.none?
+ }.should raise_error(RuntimeError)
- it "passes each element to the block in turn until it returns true" do
- acc = []
- @e.none? {|e| acc << e; false }
- acc.should == [1,1,2,3,4]
+ lambda {
+ EnumerableSpecs::ThrowingEach.new.none? { false }
+ }.should raise_error(RuntimeError)
end
- it "stops passing elements to the block when it returns true" do
- acc = []
- @e.none? {|e| acc << e; e == 3 ? true : false }
- acc.should == [1,1,2,3]
- end
+ describe "with no block" do
+ it "returns true if none of the elements in self are true" do
+ e = EnumerableSpecs::Numerous.new(false, nil, false)
+ e.none?.should be_true
+ end
- it "returns true if the block never returns true" do
- @e.none? {|e| false }.should be_true
- end
+ it "returns false if at least one of the elements in self are true" do
+ e = EnumerableSpecs::Numerous.new(false, nil, true, false)
+ e.none?.should be_false
+ end
- it "returns false if the block ever returns true" do
- @e.none? {|e| e == 3 ? true : false }.should be_false
+ it "gathers whole arrays as elements when each yields multiple" do
+ # This spec doesn't spec what it says it does
+ multi = EnumerableSpecs::YieldsMultiWithFalse.new
+ multi.none?.should be_false
+ end
end
- it "gathers initial args as elements when each yields multiple" do
- multi = EnumerableSpecs::YieldsMulti.new
- multi.none? {|e| e == [1, 2] }.should be_true
+ describe "with a block" do
+ before :each do
+ @e = EnumerableSpecs::Numerous.new(1,1,2,3,4)
+ end
+
+ it "passes each element to the block in turn until it returns true" do
+ acc = []
+ @e.none? {|e| acc << e; false }
+ acc.should == [1,1,2,3,4]
+ end
+
+ it "stops passing elements to the block when it returns true" do
+ acc = []
+ @e.none? {|e| acc << e; e == 3 ? true : false }
+ acc.should == [1,1,2,3]
+ end
+
+ it "returns true if the block never returns true" do
+ @e.none? {|e| false }.should be_true
+ end
+
+ it "returns false if the block ever returns true" do
+ @e.none? {|e| e == 3 ? true : false }.should be_false
+ end
+
+ it "does not hide exceptions out of the block" do
+ lambda {
+ @enum.none? { raise "from block" }
+ }.should raise_error(RuntimeError)
+ end
+
+ it "gathers initial args as elements when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ yielded = []
+ multi.none? { |e| yielded << e; false }
+ yielded.should == [1, 3, 6]
+ end
+
+ it "yields multiple arguments when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ yielded = []
+ multi.none? { |*args| yielded << args; false }
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
+ end
end
- it "yields multiple arguments when each yields multiple" do
- multi = EnumerableSpecs::YieldsMulti.new
- yielded = []
- multi.none? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2]]
+ ruby_version_is "2.5" do
+ describe 'when given a pattern argument' do
+ it "calls `===` on the pattern the return value " do
+ pattern = EnumerableSpecs::Pattern.new { |x| x == 3 }
+ @enum1.none?(pattern).should == true
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+ end
+
+ it "ignores block" do
+ @enum2.none?(Integer) { raise }.should == true
+ [1, 2, nil].none?(TrueClass) { raise }.should == true
+ {a: 1}.none?(Hash) { raise }.should == true
+ end
+
+ it "always returns true on empty enumeration" do
+ @empty.none?(Integer).should == true
+ [].none?(Integer).should == true
+ {}.none?(NilClass).should == true
+ end
+
+ it "does not hide exceptions out of #each" do
+ lambda {
+ EnumerableSpecs::ThrowingEach.new.none?(Integer)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "returns true if the pattern never returns a truthy value" do
+ @enum2.none?(Integer).should == true
+ pattern = EnumerableSpecs::Pattern.new { |x| nil }
+ @enum.none?(pattern).should == true
+
+ [1, 42, 3].none?(pattern).should == true
+ {a: 1, b: 2}.none?(pattern).should == true
+ end
+
+ it "returns false if the pattern ever returns other than false or nil" do
+ pattern = EnumerableSpecs::Pattern.new { |x| x < 0 }
+ @enum1.none?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+
+ [1, 2, 3, -1].none?(pattern).should == false
+ {a: 1}.none?(Array).should == false
+ end
+
+ it "does not hide exceptions out of pattern#===" do
+ pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
+ lambda {
+ @enum.none?(pattern)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ pattern = EnumerableSpecs::Pattern.new { false }
+ multi.none?(pattern).should == true
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
+ end
+ end
end
end
diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb
index facaad7670..67653749dd 100644
--- a/spec/ruby/core/enumerable/one_spec.rb
+++ b/spec/ruby/core/enumerable/one_spec.rb
@@ -2,7 +2,63 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Enumerable#one?" do
- describe "when passed a block" do
+ before :each do
+ @empty = EnumerableSpecs::Empty.new
+ @enum = EnumerableSpecs::Numerous.new
+ @enum1 = EnumerableSpecs::Numerous.new(0, 1, 2, -1)
+ @enum2 = EnumerableSpecs::Numerous.new(nil, false, true)
+ end
+
+ it "always returns false on empty enumeration" do
+ @empty.one?.should == false
+ @empty.one? { true }.should == false
+ end
+
+ it "raises an ArgumentError when more than 1 argument is provided" do
+ lambda { @enum.one?(1, 2, 3) }.should raise_error(ArgumentError)
+ lambda { [].one?(1, 2, 3) }.should raise_error(ArgumentError)
+ lambda { {}.one?(1, 2, 3) }.should raise_error(ArgumentError)
+ end
+
+ ruby_version_is ""..."2.5" do
+ it "raises an ArgumentError when any arguments provided" do
+ lambda { @enum.one?(Proc.new {}) }.should raise_error(ArgumentError)
+ lambda { @enum.one?(nil) }.should raise_error(ArgumentError)
+ lambda { @empty.one?(1) }.should raise_error(ArgumentError)
+ lambda { @enum.one?(1) {} }.should raise_error(ArgumentError)
+ end
+ end
+
+ it "does not hide exceptions out of #each" do
+ lambda {
+ EnumerableSpecs::ThrowingEach.new.one?
+ }.should raise_error(RuntimeError)
+
+ lambda {
+ EnumerableSpecs::ThrowingEach.new.one? { false }
+ }.should raise_error(RuntimeError)
+ end
+
+ describe "with no block" do
+ it "returns true if only one element evaluates to true" do
+ [false, nil, true].one?.should be_true
+ end
+
+ it "returns false if two elements evaluate to true" do
+ [false, :value, nil, true].one?.should be_false
+ end
+
+ it "returns false if all elements evaluate to false" do
+ [false, nil, false].one?.should be_false
+ end
+
+ it "gathers whole arrays as elements when each yields multiple" do
+ multi = EnumerableSpecs::YieldsMultiWithSingleTrue.new
+ multi.one?.should be_false
+ end
+ end
+
+ describe "with a block" do
it "returns true if block returns true once" do
[:a, :b, :c].one? { |s| s == :a }.should be_true
end
@@ -15,46 +71,97 @@ describe "Enumerable#one?" do
[:a, :b, :c].one? { |s| s == :d }.should be_false
end
+ it "does not hide exceptions out of the block" do
+ lambda {
+ @enum.one? { raise "from block" }
+ }.should raise_error(RuntimeError)
+ end
+
it "gathers initial args as elements when each yields multiple" do
# This spec doesn't spec what it says it does
multi = EnumerableSpecs::YieldsMulti.new
- multi.one? {|e| e == 1 }.should be_true
+ yielded = []
+ multi.one? { |e| yielded << e; false }.should == false
+ yielded.should == [1, 3, 6]
end
it "yields multiple arguments when each yields multiple" do
multi = EnumerableSpecs::YieldsMulti.new
yielded = []
- multi.one? {|e, i| yielded << [e, i] }
- yielded.should == [[1, 2], [3, 4]]
+ multi.one? { |*args| yielded << args; false }.should == false
+ yielded.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]]
end
+ end
+
- ruby_version_is "2.5" do
- describe "given a pattern argument" do
- # This spec should be replaced by more extensive ones
- it "returns true iff none match that pattern" do
- EnumerableSpecs::Numerous.new.one?(Integer).should == false
- [nil, false, true].one?(NilClass).should == true
- end
+ ruby_version_is "2.5" do
+ describe 'when given a pattern argument' do
+ it "calls `===` on the pattern the return value " do
+ pattern = EnumerableSpecs::Pattern.new { |x| x == 1 }
+ @enum1.one?(pattern).should == true
+ pattern.yielded.should == [[0], [1], [2], [-1]]
end
- end
- end
- describe "when not passed a block" do
- it "returns true if only one element evaluates to true" do
- [false, nil, true].one?.should be_true
- end
+ it "ignores block" do
+ @enum2.one?(NilClass) { raise }.should == true
+ [1, 2, nil].one?(NilClass) { raise }.should == true
+ {a: 1}.one?(Array) { raise }.should == true
+ end
- it "returns false if two elements evaluate to true" do
- [false, :value, nil, true].one?.should be_false
- end
+ it "always returns false on empty enumeration" do
+ @empty.one?(Integer).should == false
+ [].one?(Integer).should == false
+ {}.one?(NilClass).should == false
+ end
- it "returns false if all elements evaluate to false" do
- [false, nil, false].one?.should be_false
- end
+ it "does not hide exceptions out of #each" do
+ lambda {
+ EnumerableSpecs::ThrowingEach.new.one?(Integer)
+ }.should raise_error(RuntimeError)
+ end
- it "gathers whole arrays as elements when each yields multiple" do
- multi = EnumerableSpecs::YieldsMultiWithSingleTrue.new
- multi.one?.should be_false
+ it "returns true if the pattern returns a truthy value only once" do
+ @enum2.one?(NilClass).should == true
+ pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
+ @enum1.one?(pattern).should == true
+
+ [1, 2, 42, 3].one?(pattern).should == true
+
+ pattern = EnumerableSpecs::Pattern.new { |x| x == [:b, 2] }
+ {a: 1, b: 2}.one?(pattern).should == true
+ end
+
+ it "returns false if the pattern returns a truthy value more than once" do
+ pattern = EnumerableSpecs::Pattern.new { |x| !x }
+ @enum2.one?(pattern).should == false
+ pattern.yielded.should == [[nil], [false]]
+
+ [1, 2, 3].one?(Integer).should == false
+ {a: 1, b: 2}.one?(Array).should == false
+ end
+
+ it "returns false if the pattern never returns a truthy value" do
+ pattern = EnumerableSpecs::Pattern.new { |x| nil }
+ @enum1.one?(pattern).should == false
+ pattern.yielded.should == [[0], [1], [2], [-1]]
+
+ [1, 2, 3].one?(pattern).should == false
+ {a: 1}.one?(pattern).should == false
+ end
+
+ it "does not hide exceptions out of pattern#===" do
+ pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
+ lambda {
+ @enum.one?(pattern)
+ }.should raise_error(RuntimeError)
+ end
+
+ it "calls the pattern with gathered array when yielded with multiple arguments" do
+ multi = EnumerableSpecs::YieldsMulti.new
+ pattern = EnumerableSpecs::Pattern.new { false }
+ multi.one?(pattern).should == false
+ pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
+ end
end
end
end
diff --git a/spec/ruby/core/kernel/autoload_spec.rb b/spec/ruby/core/kernel/autoload_spec.rb
index 038dfd1db1..c2573ffac6 100644
--- a/spec/ruby/core/kernel/autoload_spec.rb
+++ b/spec/ruby/core/kernel/autoload_spec.rb
@@ -60,6 +60,25 @@ describe "Kernel#autoload" do
ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "#{frozen_error_class} - nil"
end
end
+
+ describe "when called from included module's method" do
+ before :all do
+ @path = fixture(__FILE__, "autoload_from_included_module.rb")
+ KernelSpecs::AutoloadMethodIncluder.new.setup_autoload(@path)
+ end
+
+ it "setups the autoload on the included module" do
+ KernelSpecs::AutoloadMethod.autoload?(:AutoloadFromIncludedModule).should == @path
+ end
+
+ it "the autoload is reacheable from the class too" do
+ KernelSpecs::AutoloadMethodIncluder.autoload?(:AutoloadFromIncludedModule).should == @path
+ end
+
+ it "the autoload relative to the included module works" do
+ KernelSpecs::AutoloadMethod::AutoloadFromIncludedModule.loaded.should == :autoload_from_included_module
+ end
+ end
end
describe "Kernel#autoload?" do
@@ -107,6 +126,25 @@ describe "Kernel.autoload" do
p.should_receive(:to_path).and_return @non_existent
Kernel.autoload :KSAutoloadAA, p
end
+
+ describe "when called from included module's method" do
+ before :all do
+ @path = fixture(__FILE__, "autoload_from_included_module2.rb")
+ KernelSpecs::AutoloadMethodIncluder2.new.setup_autoload(@path)
+ end
+
+ it "setups the autoload on the included module" do
+ KernelSpecs::AutoloadMethod2.autoload?(:AutoloadFromIncludedModule2).should == @path
+ end
+
+ it "the autoload is reacheable from the class too" do
+ KernelSpecs::AutoloadMethodIncluder2.autoload?(:AutoloadFromIncludedModule2).should == @path
+ end
+
+ it "the autoload relative to the included module works" do
+ KernelSpecs::AutoloadMethod2::AutoloadFromIncludedModule2.loaded.should == :autoload_from_included_module2
+ end
+ end
end
describe "Kernel.autoload?" do
diff --git a/spec/ruby/core/kernel/fixtures/autoload_from_included_module.rb b/spec/ruby/core/kernel/fixtures/autoload_from_included_module.rb
new file mode 100644
index 0000000000..f5bedc6992
--- /dev/null
+++ b/spec/ruby/core/kernel/fixtures/autoload_from_included_module.rb
@@ -0,0 +1,9 @@
+module KernelSpecs
+ module AutoloadMethod
+ module AutoloadFromIncludedModule
+ def self.loaded
+ :autoload_from_included_module
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/kernel/fixtures/autoload_from_included_module2.rb b/spec/ruby/core/kernel/fixtures/autoload_from_included_module2.rb
new file mode 100644
index 0000000000..f4f1cfbf7c
--- /dev/null
+++ b/spec/ruby/core/kernel/fixtures/autoload_from_included_module2.rb
@@ -0,0 +1,9 @@
+module KernelSpecs
+ module AutoloadMethod2
+ module AutoloadFromIncludedModule2
+ def self.loaded
+ :autoload_from_included_module2
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/kernel/fixtures/classes.rb b/spec/ruby/core/kernel/fixtures/classes.rb
index afa2bec12f..cc475ed758 100644
--- a/spec/ruby/core/kernel/fixtures/classes.rb
+++ b/spec/ruby/core/kernel/fixtures/classes.rb
@@ -378,6 +378,49 @@ module KernelSpecs
[3, 4]
end
end
+
+ module AutoloadMethod
+ def setup_autoload(file)
+ autoload :AutoloadFromIncludedModule, file
+ end
+ end
+
+ class AutoloadMethodIncluder
+ include AutoloadMethod
+ end
+
+ module AutoloadMethod2
+ def setup_autoload(file)
+ Kernel.autoload :AutoloadFromIncludedModule2, file
+ end
+ end
+
+ class AutoloadMethodIncluder2
+ include AutoloadMethod2
+ end
+
+ class WarnInNestedCall
+ def f4(s = "", n)
+ f3(s, n)
+ end
+
+ def f3(s, n)
+ f2(s, n)
+ end
+
+ def f2(s, n)
+ f1(s, n)
+ end
+
+ def f1(s, n)
+ warn(s, uplevel: n)
+ end
+
+ def warn_call_lineno; method(:f1).source_location[1] + 1; end
+ def f1_call_lineno; method(:f2).source_location[1] + 1; end
+ def f2_call_lineno; method(:f3).source_location[1] + 1; end
+ def f3_call_lineno; method(:f4).source_location[1] + 1; end
+ end
end
class EvalSpecs
diff --git a/spec/ruby/core/kernel/shared/then.rb b/spec/ruby/core/kernel/shared/then.rb
new file mode 100644
index 0000000000..b52075371f
--- /dev/null
+++ b/spec/ruby/core/kernel/shared/then.rb
@@ -0,0 +1,20 @@
+describe :kernel_then, shared: true do
+ it "yields self" do
+ object = Object.new
+ object.send(@method) { |o| o.should equal object }
+ end
+
+ it "returns the block return value" do
+ object = Object.new
+ object.send(@method) { 42 }.should equal 42
+ end
+
+ it "returns a sized Enumerator when no block given" do
+ object = Object.new
+ enum = object.send(@method)
+ enum.should be_an_instance_of Enumerator
+ enum.size.should equal 1
+ enum.peek.should equal object
+ enum.first.should equal object
+ end
+end
diff --git a/spec/ruby/core/kernel/then_spec.rb b/spec/ruby/core/kernel/then_spec.rb
new file mode 100644
index 0000000000..fa896b52b1
--- /dev/null
+++ b/spec/ruby/core/kernel/then_spec.rb
@@ -0,0 +1,8 @@
+require_relative '../../spec_helper'
+require_relative 'shared/then'
+
+ruby_version_is "2.6" do
+ describe "Kernel#then" do
+ it_behaves_like :kernel_then, :then
+ end
+end
diff --git a/spec/ruby/core/kernel/warn_spec.rb b/spec/ruby/core/kernel/warn_spec.rb
index f1dcdf5949..7a0c431ff0 100644
--- a/spec/ruby/core/kernel/warn_spec.rb
+++ b/spec/ruby/core/kernel/warn_spec.rb
@@ -76,4 +76,60 @@ describe "Kernel#warn" do
warn("")
}.should output(nil, /\n/)
end
+
+ ruby_version_is "2.5" do
+ describe ":uplevel keyword argument" do
+ before :each do
+ $VERBOSE = true
+ end
+
+ it "prepends a message with specified line from the backtrace" do
+ w = KernelSpecs::WarnInNestedCall.new
+
+ -> { w.f4("foo", 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: foo|)
+ -> { w.f4("foo", 1) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f1_call_lineno}: warning: foo|)
+ -> { w.f4("foo", 2) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f2_call_lineno}: warning: foo|)
+ -> { w.f4("foo", 3) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f3_call_lineno}: warning: foo|)
+ end
+
+ ruby_bug "#14846", "2.5"..."2.6" do
+ it "does not prepend caller information if line number is too big" do
+ w = KernelSpecs::WarnInNestedCall.new
+ -> { w.f4("foo", 100) }.should output(nil, "warning: foo\n")
+ end
+ end
+
+ it "prepends even if a message is empty or nil" do
+ w = KernelSpecs::WarnInNestedCall.new
+
+ -> { w.f4("", 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: \n$|)
+ -> { w.f4(nil, 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: \n$|)
+ end
+
+ it "converts value to Integer" do
+ w = KernelSpecs::WarnInNestedCall.new
+
+ -> { w.f4(0.1) }.should output(nil, %r|classes.rb:#{w.warn_call_lineno}:|)
+ -> { w.f4(Rational(1, 2)) }.should output(nil, %r|classes.rb:#{w.warn_call_lineno}:|)
+ end
+
+ it "raises ArgumentError if passed negative value" do
+ -> { warn "", uplevel: -2 }.should raise_error(ArgumentError)
+ -> { warn "", uplevel: -100 }.should raise_error(ArgumentError)
+ end
+
+ ruby_bug "#14846", "2.5"..."2.6" do
+ it "raises ArgumentError if passed -1" do
+ -> { warn "", uplevel: -1 }.should raise_error(ArgumentError)
+ end
+ end
+
+ it "raises TypeError if passed not Integer" do
+ -> { warn "", uplevel: "" }.should raise_error(TypeError)
+ -> { warn "", uplevel: [] }.should raise_error(TypeError)
+ -> { warn "", uplevel: {} }.should raise_error(TypeError)
+ -> { warn "", uplevel: Object.new }.should raise_error(TypeError)
+ end
+ end
+ end
end
diff --git a/spec/ruby/core/kernel/yield_self_spec.rb b/spec/ruby/core/kernel/yield_self_spec.rb
index 0bcf0660c2..affedae144 100644
--- a/spec/ruby/core/kernel/yield_self_spec.rb
+++ b/spec/ruby/core/kernel/yield_self_spec.rb
@@ -1,29 +1,8 @@
require_relative '../../spec_helper'
+require_relative 'shared/then'
ruby_version_is "2.5" do
describe "Kernel#yield_self" do
- it "yields self" do
- object = Object.new
- object.yield_self { |o| o.should equal object }
- end
-
- it "returns the block return value" do
- object = Object.new
- object.yield_self { 42 }.should equal 42
- end
-
- it "returns a sized Enumerator when no block given" do
- object = Object.new
- enum = object.yield_self
- enum.should be_an_instance_of Enumerator
- enum.size.should equal 1
- enum.peek.should equal object
- enum.first.should equal object
- end
-
- it "has an alias `then`" do
- object = Object.new
- object.then { 42 }.should equal 42
- end
+ it_behaves_like :kernel_then, :yield_self
end
end
diff --git a/spec/ruby/core/string/dump_spec.rb b/spec/ruby/core/string/dump_spec.rb
index cfe7bea6f0..e67367b5b0 100644
--- a/spec/ruby/core/string/dump_spec.rb
+++ b/spec/ruby/core/string/dump_spec.rb
@@ -13,10 +13,18 @@ describe "String#dump" do
"foo\n".untrust.dump.untrusted?.should == true
end
+ it "does not take into account if a string is frozen" do
+ "foo".freeze.dump.frozen?.should == false
+ end
+
it "returns a subclass instance" do
StringSpecs::MyString.new.dump.should be_an_instance_of(StringSpecs::MyString)
end
+ it "wraps string with \"" do
+ "foo".dump.should == '"foo"'
+ end
+
it "returns a string with special characters replaced with \\<char> notation" do
[ ["\a", '"\\a"'],
["\b", '"\\b"'],
@@ -35,10 +43,11 @@ describe "String#dump" do
].should be_computed_by(:dump)
end
- it "returns a string with \\#<char> when # is followed by $, @, {" do
- [ ["\#$", '"\\#$"'],
- ["\#@", '"\\#@"'],
- ["\#{", '"\\#{"']
+ it "returns a string with \\#<char> when # is followed by $, @, @@, {" do
+ [ ["\#$PATH", '"\\#$PATH"'],
+ ["\#@a", '"\\#@a"'],
+ ["\#@@a", '"\\#@@a"'],
+ ["\#{a}", '"\\#{a}"']
].should be_computed_by(:dump)
end
@@ -381,7 +390,7 @@ describe "String#dump" do
end
ruby_version_is '2.4' do
- it "returns a string with multi-byte UTF-8 characters replaced by \\u{} notation with lower-case hex digits" do
+ it "returns a string with multi-byte UTF-8 characters replaced by \\u{} notation with upper-case hex digits" do
[ [0200.chr('utf-8'), '"\u0080"'],
[0201.chr('utf-8'), '"\u0081"'],
[0202.chr('utf-8'), '"\u0082"'],
@@ -421,4 +430,10 @@ describe "String#dump" do
"\u{876}".encode('utf-16be').dump.end_with?(".force_encoding(\"UTF-16BE\")").should be_true
"\u{876}".encode('utf-16le').dump.end_with?(".force_encoding(\"UTF-16LE\")").should be_true
end
+
+ it "keeps origin encoding" do
+ "foo".encode("ISO-8859-1").dump.encoding.should == Encoding::ISO_8859_1
+ "foo".encode('windows-1251').dump.encoding.should == Encoding::Windows_1251
+ 1.chr.dump.encoding.should == Encoding::US_ASCII
+ end
end
diff --git a/spec/ruby/core/string/uminus_spec.rb b/spec/ruby/core/string/uminus_spec.rb
index f5f77f0d2e..fd9e8c1d52 100644
--- a/spec/ruby/core/string/uminus_spec.rb
+++ b/spec/ruby/core/string/uminus_spec.rb
@@ -5,7 +5,7 @@ describe 'String#-@' do
input = 'foo'.freeze
output = -input
- output.equal?(input).should == true
+ output.should equal(input)
output.frozen?.should == true
end
@@ -14,6 +14,7 @@ describe 'String#-@' do
output = -input
output.frozen?.should == true
+ output.should_not equal(input)
output.should == 'foo'
end
@@ -30,11 +31,25 @@ describe 'String#-@' do
(-"unfrozen string").should equal(-"unfrozen string")
(-"unfrozen string").should_not equal(-"another unfrozen string")
end
+ end
+
+ ruby_version_is "2.5"..."2.6" do
+ it "does not deduplicate already frozen strings" do
+ dynamic = %w(this string is frozen).join(' ').freeze
+
+ dynamic.should_not equal("this string is frozen".freeze)
+ (-dynamic).should_not equal("this string is frozen".freeze)
+ (-dynamic).should_not equal(-"this string is frozen".freeze)
+ end
+ end
+
+ ruby_version_is "2.6" do
it "deduplicates frozen strings" do
dynamic = %w(this string is frozen).join(' ').freeze
dynamic.should_not equal("this string is frozen".freeze)
+
(-dynamic).should equal("this string is frozen".freeze)
(-dynamic).should equal(-"this string is frozen".freeze)
end
diff --git a/spec/ruby/core/string/undump_spec.rb b/spec/ruby/core/string/undump_spec.rb
new file mode 100644
index 0000000000..ec13308c16
--- /dev/null
+++ b/spec/ruby/core/string/undump_spec.rb
@@ -0,0 +1,451 @@
+# encoding: utf-8
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is '2.5' do
+ describe "String#undump" do
+ it "taints the result if self is tainted" do
+ '"foo"'.taint.undump.tainted?.should == true
+ end
+
+ it "untrusts the result if self is untrusted" do
+ '"foo"'.untrust.undump.untrusted?.should == true
+ end
+
+ it "does not take into account if a string is frozen" do
+ '"foo"'.freeze.undump.frozen?.should == false
+ end
+
+ it "always returns String instance" do
+ StringSpecs::MyString.new('"foo"').undump.should be_an_instance_of(String)
+ end
+
+ it "strips outer \"" do
+ '"foo"'.undump.should == 'foo'
+ end
+
+ it "returns a string with special characters in \\<char> notation replaced with the characters" do
+ [ ['"\\a"', "\a"],
+ ['"\\b"', "\b"],
+ ['"\\t"', "\t"],
+ ['"\\n"', "\n"],
+ ['"\\v"', "\v"],
+ ['"\\f"', "\f"],
+ ['"\\r"', "\r"],
+ ['"\\e"', "\e"]
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with unescaped sequencies \" and \\" do
+ [ ['"\\""' , "\""],
+ ['"\\\\"', "\\"]
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with unescaped sequences \\#<char> when # is followed by $, @, {" do
+ [ ['"\\#$PATH"', "\#$PATH"],
+ ['"\\#@a"', "\#@a"],
+ ['"\\#@@a"', "\#@@a"],
+ ['"\\#{a}"', "\#{a}"]
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with # not escaped when followed by any other character" do
+ [ ['"#"', '#'],
+ ['"#1"', '#1']
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with printable non-alphanumeric characters" do
+ [ ['" "', ' '],
+ ['"!"', '!'],
+ ['"$"', '$'],
+ ['"%"', '%'],
+ ['"&"', '&'],
+ ['"\'"', '\''],
+ ['"("', '('],
+ ['")"', ')'],
+ ['"*"', '*'],
+ ['"+"', '+'],
+ ['","', ','],
+ ['"-"', '-'],
+ ['"."', '.'],
+ ['"/"', '/'],
+ ['":"', ':'],
+ ['";"', ';'],
+ ['"<"', '<'],
+ ['"="', '='],
+ ['">"', '>'],
+ ['"?"', '?'],
+ ['"@"', '@'],
+ ['"["', '['],
+ ['"]"', ']'],
+ ['"^"', '^'],
+ ['"_"', '_'],
+ ['"`"', '`'],
+ ['"{"', '{'],
+ ['"|"', '|'],
+ ['"}"', '}'],
+ ['"~"', '~']
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with numeric characters unescaped" do
+ [ ['"0"', "0"],
+ ['"1"', "1"],
+ ['"2"', "2"],
+ ['"3"', "3"],
+ ['"4"', "4"],
+ ['"5"', "5"],
+ ['"6"', "6"],
+ ['"7"', "7"],
+ ['"8"', "8"],
+ ['"9"', "9"],
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with upper-case alpha characters unescaped" do
+ [ ['"A"', 'A'],
+ ['"B"', 'B'],
+ ['"C"', 'C'],
+ ['"D"', 'D'],
+ ['"E"', 'E'],
+ ['"F"', 'F'],
+ ['"G"', 'G'],
+ ['"H"', 'H'],
+ ['"I"', 'I'],
+ ['"J"', 'J'],
+ ['"K"', 'K'],
+ ['"L"', 'L'],
+ ['"M"', 'M'],
+ ['"N"', 'N'],
+ ['"O"', 'O'],
+ ['"P"', 'P'],
+ ['"Q"', 'Q'],
+ ['"R"', 'R'],
+ ['"S"', 'S'],
+ ['"T"', 'T'],
+ ['"U"', 'U'],
+ ['"V"', 'V'],
+ ['"W"', 'W'],
+ ['"X"', 'X'],
+ ['"Y"', 'Y'],
+ ['"Z"', 'Z']
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with lower-case alpha characters unescaped" do
+ [ ['"a"', 'a'],
+ ['"b"', 'b'],
+ ['"c"', 'c'],
+ ['"d"', 'd'],
+ ['"e"', 'e'],
+ ['"f"', 'f'],
+ ['"g"', 'g'],
+ ['"h"', 'h'],
+ ['"i"', 'i'],
+ ['"j"', 'j'],
+ ['"k"', 'k'],
+ ['"l"', 'l'],
+ ['"m"', 'm'],
+ ['"n"', 'n'],
+ ['"o"', 'o'],
+ ['"p"', 'p'],
+ ['"q"', 'q'],
+ ['"r"', 'r'],
+ ['"s"', 's'],
+ ['"t"', 't'],
+ ['"u"', 'u'],
+ ['"v"', 'v'],
+ ['"w"', 'w'],
+ ['"x"', 'x'],
+ ['"y"', 'y'],
+ ['"z"', 'z']
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with \\x notation replaced with non-printing ASCII character" do
+ [ ['"\\x00"', 0000.chr.force_encoding('utf-8')],
+ ['"\\x01"', 0001.chr.force_encoding('utf-8')],
+ ['"\\x02"', 0002.chr.force_encoding('utf-8')],
+ ['"\\x03"', 0003.chr.force_encoding('utf-8')],
+ ['"\\x04"', 0004.chr.force_encoding('utf-8')],
+ ['"\\x05"', 0005.chr.force_encoding('utf-8')],
+ ['"\\x06"', 0006.chr.force_encoding('utf-8')],
+ ['"\\x0E"', 0016.chr.force_encoding('utf-8')],
+ ['"\\x0F"', 0017.chr.force_encoding('utf-8')],
+ ['"\\x10"', 0020.chr.force_encoding('utf-8')],
+ ['"\\x11"', 0021.chr.force_encoding('utf-8')],
+ ['"\\x12"', 0022.chr.force_encoding('utf-8')],
+ ['"\\x13"', 0023.chr.force_encoding('utf-8')],
+ ['"\\x14"', 0024.chr.force_encoding('utf-8')],
+ ['"\\x15"', 0025.chr.force_encoding('utf-8')],
+ ['"\\x16"', 0026.chr.force_encoding('utf-8')],
+ ['"\\x17"', 0027.chr.force_encoding('utf-8')],
+ ['"\\x18"', 0030.chr.force_encoding('utf-8')],
+ ['"\\x19"', 0031.chr.force_encoding('utf-8')],
+ ['"\\x1A"', 0032.chr.force_encoding('utf-8')],
+ ['"\\x1C"', 0034.chr.force_encoding('utf-8')],
+ ['"\\x1D"', 0035.chr.force_encoding('utf-8')],
+ ['"\\x1E"', 0036.chr.force_encoding('utf-8')],
+ ['"\\x1F"', 0037.chr.force_encoding('utf-8')],
+ ['"\\x7F"', 0177.chr.force_encoding('utf-8')],
+ ['"\\x80"', 0200.chr.force_encoding('utf-8')],
+ ['"\\x81"', 0201.chr.force_encoding('utf-8')],
+ ['"\\x82"', 0202.chr.force_encoding('utf-8')],
+ ['"\\x83"', 0203.chr.force_encoding('utf-8')],
+ ['"\\x84"', 0204.chr.force_encoding('utf-8')],
+ ['"\\x85"', 0205.chr.force_encoding('utf-8')],
+ ['"\\x86"', 0206.chr.force_encoding('utf-8')],
+ ['"\\x87"', 0207.chr.force_encoding('utf-8')],
+ ['"\\x88"', 0210.chr.force_encoding('utf-8')],
+ ['"\\x89"', 0211.chr.force_encoding('utf-8')],
+ ['"\\x8A"', 0212.chr.force_encoding('utf-8')],
+ ['"\\x8B"', 0213.chr.force_encoding('utf-8')],
+ ['"\\x8C"', 0214.chr.force_encoding('utf-8')],
+ ['"\\x8D"', 0215.chr.force_encoding('utf-8')],
+ ['"\\x8E"', 0216.chr.force_encoding('utf-8')],
+ ['"\\x8F"', 0217.chr.force_encoding('utf-8')],
+ ['"\\x90"', 0220.chr.force_encoding('utf-8')],
+ ['"\\x91"', 0221.chr.force_encoding('utf-8')],
+ ['"\\x92"', 0222.chr.force_encoding('utf-8')],
+ ['"\\x93"', 0223.chr.force_encoding('utf-8')],
+ ['"\\x94"', 0224.chr.force_encoding('utf-8')],
+ ['"\\x95"', 0225.chr.force_encoding('utf-8')],
+ ['"\\x96"', 0226.chr.force_encoding('utf-8')],
+ ['"\\x97"', 0227.chr.force_encoding('utf-8')],
+ ['"\\x98"', 0230.chr.force_encoding('utf-8')],
+ ['"\\x99"', 0231.chr.force_encoding('utf-8')],
+ ['"\\x9A"', 0232.chr.force_encoding('utf-8')],
+ ['"\\x9B"', 0233.chr.force_encoding('utf-8')],
+ ['"\\x9C"', 0234.chr.force_encoding('utf-8')],
+ ['"\\x9D"', 0235.chr.force_encoding('utf-8')],
+ ['"\\x9E"', 0236.chr.force_encoding('utf-8')],
+ ['"\\x9F"', 0237.chr.force_encoding('utf-8')],
+ ['"\\xA0"', 0240.chr.force_encoding('utf-8')],
+ ['"\\xA1"', 0241.chr.force_encoding('utf-8')],
+ ['"\\xA2"', 0242.chr.force_encoding('utf-8')],
+ ['"\\xA3"', 0243.chr.force_encoding('utf-8')],
+ ['"\\xA4"', 0244.chr.force_encoding('utf-8')],
+ ['"\\xA5"', 0245.chr.force_encoding('utf-8')],
+ ['"\\xA6"', 0246.chr.force_encoding('utf-8')],
+ ['"\\xA7"', 0247.chr.force_encoding('utf-8')],
+ ['"\\xA8"', 0250.chr.force_encoding('utf-8')],
+ ['"\\xA9"', 0251.chr.force_encoding('utf-8')],
+ ['"\\xAA"', 0252.chr.force_encoding('utf-8')],
+ ['"\\xAB"', 0253.chr.force_encoding('utf-8')],
+ ['"\\xAC"', 0254.chr.force_encoding('utf-8')],
+ ['"\\xAD"', 0255.chr.force_encoding('utf-8')],
+ ['"\\xAE"', 0256.chr.force_encoding('utf-8')],
+ ['"\\xAF"', 0257.chr.force_encoding('utf-8')],
+ ['"\\xB0"', 0260.chr.force_encoding('utf-8')],
+ ['"\\xB1"', 0261.chr.force_encoding('utf-8')],
+ ['"\\xB2"', 0262.chr.force_encoding('utf-8')],
+ ['"\\xB3"', 0263.chr.force_encoding('utf-8')],
+ ['"\\xB4"', 0264.chr.force_encoding('utf-8')],
+ ['"\\xB5"', 0265.chr.force_encoding('utf-8')],
+ ['"\\xB6"', 0266.chr.force_encoding('utf-8')],
+ ['"\\xB7"', 0267.chr.force_encoding('utf-8')],
+ ['"\\xB8"', 0270.chr.force_encoding('utf-8')],
+ ['"\\xB9"', 0271.chr.force_encoding('utf-8')],
+ ['"\\xBA"', 0272.chr.force_encoding('utf-8')],
+ ['"\\xBB"', 0273.chr.force_encoding('utf-8')],
+ ['"\\xBC"', 0274.chr.force_encoding('utf-8')],
+ ['"\\xBD"', 0275.chr.force_encoding('utf-8')],
+ ['"\\xBE"', 0276.chr.force_encoding('utf-8')],
+ ['"\\xBF"', 0277.chr.force_encoding('utf-8')],
+ ['"\\xC0"', 0300.chr.force_encoding('utf-8')],
+ ['"\\xC1"', 0301.chr.force_encoding('utf-8')],
+ ['"\\xC2"', 0302.chr.force_encoding('utf-8')],
+ ['"\\xC3"', 0303.chr.force_encoding('utf-8')],
+ ['"\\xC4"', 0304.chr.force_encoding('utf-8')],
+ ['"\\xC5"', 0305.chr.force_encoding('utf-8')],
+ ['"\\xC6"', 0306.chr.force_encoding('utf-8')],
+ ['"\\xC7"', 0307.chr.force_encoding('utf-8')],
+ ['"\\xC8"', 0310.chr.force_encoding('utf-8')],
+ ['"\\xC9"', 0311.chr.force_encoding('utf-8')],
+ ['"\\xCA"', 0312.chr.force_encoding('utf-8')],
+ ['"\\xCB"', 0313.chr.force_encoding('utf-8')],
+ ['"\\xCC"', 0314.chr.force_encoding('utf-8')],
+ ['"\\xCD"', 0315.chr.force_encoding('utf-8')],
+ ['"\\xCE"', 0316.chr.force_encoding('utf-8')],
+ ['"\\xCF"', 0317.chr.force_encoding('utf-8')],
+ ['"\\xD0"', 0320.chr.force_encoding('utf-8')],
+ ['"\\xD1"', 0321.chr.force_encoding('utf-8')],
+ ['"\\xD2"', 0322.chr.force_encoding('utf-8')],
+ ['"\\xD3"', 0323.chr.force_encoding('utf-8')],
+ ['"\\xD4"', 0324.chr.force_encoding('utf-8')],
+ ['"\\xD5"', 0325.chr.force_encoding('utf-8')],
+ ['"\\xD6"', 0326.chr.force_encoding('utf-8')],
+ ['"\\xD7"', 0327.chr.force_encoding('utf-8')],
+ ['"\\xD8"', 0330.chr.force_encoding('utf-8')],
+ ['"\\xD9"', 0331.chr.force_encoding('utf-8')],
+ ['"\\xDA"', 0332.chr.force_encoding('utf-8')],
+ ['"\\xDB"', 0333.chr.force_encoding('utf-8')],
+ ['"\\xDC"', 0334.chr.force_encoding('utf-8')],
+ ['"\\xDD"', 0335.chr.force_encoding('utf-8')],
+ ['"\\xDE"', 0336.chr.force_encoding('utf-8')],
+ ['"\\xDF"', 0337.chr.force_encoding('utf-8')],
+ ['"\\xE0"', 0340.chr.force_encoding('utf-8')],
+ ['"\\xE1"', 0341.chr.force_encoding('utf-8')],
+ ['"\\xE2"', 0342.chr.force_encoding('utf-8')],
+ ['"\\xE3"', 0343.chr.force_encoding('utf-8')],
+ ['"\\xE4"', 0344.chr.force_encoding('utf-8')],
+ ['"\\xE5"', 0345.chr.force_encoding('utf-8')],
+ ['"\\xE6"', 0346.chr.force_encoding('utf-8')],
+ ['"\\xE7"', 0347.chr.force_encoding('utf-8')],
+ ['"\\xE8"', 0350.chr.force_encoding('utf-8')],
+ ['"\\xE9"', 0351.chr.force_encoding('utf-8')],
+ ['"\\xEA"', 0352.chr.force_encoding('utf-8')],
+ ['"\\xEB"', 0353.chr.force_encoding('utf-8')],
+ ['"\\xEC"', 0354.chr.force_encoding('utf-8')],
+ ['"\\xED"', 0355.chr.force_encoding('utf-8')],
+ ['"\\xEE"', 0356.chr.force_encoding('utf-8')],
+ ['"\\xEF"', 0357.chr.force_encoding('utf-8')],
+ ['"\\xF0"', 0360.chr.force_encoding('utf-8')],
+ ['"\\xF1"', 0361.chr.force_encoding('utf-8')],
+ ['"\\xF2"', 0362.chr.force_encoding('utf-8')],
+ ['"\\xF3"', 0363.chr.force_encoding('utf-8')],
+ ['"\\xF4"', 0364.chr.force_encoding('utf-8')],
+ ['"\\xF5"', 0365.chr.force_encoding('utf-8')],
+ ['"\\xF6"', 0366.chr.force_encoding('utf-8')],
+ ['"\\xF7"', 0367.chr.force_encoding('utf-8')],
+ ['"\\xF8"', 0370.chr.force_encoding('utf-8')],
+ ['"\\xF9"', 0371.chr.force_encoding('utf-8')],
+ ['"\\xFA"', 0372.chr.force_encoding('utf-8')],
+ ['"\\xFB"', 0373.chr.force_encoding('utf-8')],
+ ['"\\xFC"', 0374.chr.force_encoding('utf-8')],
+ ['"\\xFD"', 0375.chr.force_encoding('utf-8')],
+ ['"\\xFE"', 0376.chr.force_encoding('utf-8')],
+ ['"\\xFF"', 0377.chr.force_encoding('utf-8')]
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with \\u{} notation replaced with multi-byte UTF-8 characters" do
+ [ ['"\u{80}"', 0200.chr('utf-8')],
+ ['"\u{81}"', 0201.chr('utf-8')],
+ ['"\u{82}"', 0202.chr('utf-8')],
+ ['"\u{83}"', 0203.chr('utf-8')],
+ ['"\u{84}"', 0204.chr('utf-8')],
+ ['"\u{86}"', 0206.chr('utf-8')],
+ ['"\u{87}"', 0207.chr('utf-8')],
+ ['"\u{88}"', 0210.chr('utf-8')],
+ ['"\u{89}"', 0211.chr('utf-8')],
+ ['"\u{8a}"', 0212.chr('utf-8')],
+ ['"\u{8b}"', 0213.chr('utf-8')],
+ ['"\u{8c}"', 0214.chr('utf-8')],
+ ['"\u{8d}"', 0215.chr('utf-8')],
+ ['"\u{8e}"', 0216.chr('utf-8')],
+ ['"\u{8f}"', 0217.chr('utf-8')],
+ ['"\u{90}"', 0220.chr('utf-8')],
+ ['"\u{91}"', 0221.chr('utf-8')],
+ ['"\u{92}"', 0222.chr('utf-8')],
+ ['"\u{93}"', 0223.chr('utf-8')],
+ ['"\u{94}"', 0224.chr('utf-8')],
+ ['"\u{95}"', 0225.chr('utf-8')],
+ ['"\u{96}"', 0226.chr('utf-8')],
+ ['"\u{97}"', 0227.chr('utf-8')],
+ ['"\u{98}"', 0230.chr('utf-8')],
+ ['"\u{99}"', 0231.chr('utf-8')],
+ ['"\u{9a}"', 0232.chr('utf-8')],
+ ['"\u{9b}"', 0233.chr('utf-8')],
+ ['"\u{9c}"', 0234.chr('utf-8')],
+ ['"\u{9d}"', 0235.chr('utf-8')],
+ ['"\u{9e}"', 0236.chr('utf-8')],
+ ['"\u{9f}"', 0237.chr('utf-8')],
+ ].should be_computed_by(:undump)
+ end
+
+ it "returns a string with \\uXXXX notation replaced with multi-byte UTF-8 characters" do
+ [ ['"\u0080"', 0200.chr('utf-8')],
+ ['"\u0081"', 0201.chr('utf-8')],
+ ['"\u0082"', 0202.chr('utf-8')],
+ ['"\u0083"', 0203.chr('utf-8')],
+ ['"\u0084"', 0204.chr('utf-8')],
+ ['"\u0086"', 0206.chr('utf-8')],
+ ['"\u0087"', 0207.chr('utf-8')],
+ ['"\u0088"', 0210.chr('utf-8')],
+ ['"\u0089"', 0211.chr('utf-8')],
+ ['"\u008a"', 0212.chr('utf-8')],
+ ['"\u008b"', 0213.chr('utf-8')],
+ ['"\u008c"', 0214.chr('utf-8')],
+ ['"\u008d"', 0215.chr('utf-8')],
+ ['"\u008e"', 0216.chr('utf-8')],
+ ['"\u008f"', 0217.chr('utf-8')],
+ ['"\u0090"', 0220.chr('utf-8')],
+ ['"\u0091"', 0221.chr('utf-8')],
+ ['"\u0092"', 0222.chr('utf-8')],
+ ['"\u0093"', 0223.chr('utf-8')],
+ ['"\u0094"', 0224.chr('utf-8')],
+ ['"\u0095"', 0225.chr('utf-8')],
+ ['"\u0096"', 0226.chr('utf-8')],
+ ['"\u0097"', 0227.chr('utf-8')],
+ ['"\u0098"', 0230.chr('utf-8')],
+ ['"\u0099"', 0231.chr('utf-8')],
+ ['"\u009a"', 0232.chr('utf-8')],
+ ['"\u009b"', 0233.chr('utf-8')],
+ ['"\u009c"', 0234.chr('utf-8')],
+ ['"\u009d"', 0235.chr('utf-8')],
+ ['"\u009e"', 0236.chr('utf-8')],
+ ['"\u009f"', 0237.chr('utf-8')],
+ ].should be_computed_by(:undump)
+ end
+
+ it "undumps correctly string produced from non ASCII-compatible one" do
+ s = "\u{876}".encode('utf-16be')
+ s.dump.undump.should == s
+
+ '"\\bv".force_encoding("UTF-16BE")'.undump.should == "\u0876".encode('utf-16be')
+ end
+
+ it "keeps origin encoding" do
+ '"foo"'.encode("ISO-8859-1").undump.encoding.should == Encoding::ISO_8859_1
+ '"foo"'.encode('windows-1251').undump.encoding.should == Encoding::Windows_1251
+ end
+
+ describe "Limitations" do
+ it "cannot undump non ASCII-compatible string" do
+ -> { '"foo"'.encode('utf-16le').undump }.should raise_error(Encoding::CompatibilityError)
+ end
+ end
+
+ describe "invalid dump" do
+ it "raises RuntimeError exception if wrapping \" are missing" do
+ -> { 'foo'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
+ -> { '"foo'.undump }.should raise_error(RuntimeError, /unterminated dumped string/)
+ -> { 'foo"'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
+ -> { "'foo'".undump }.should raise_error(RuntimeError, /invalid dumped string/)
+ end
+
+ it "raises RuntimeError if there is incorrect \\x sequence" do
+ -> { '"\x"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
+ -> { '"\\x3y"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
+ end
+
+ it "raises RuntimeError in there is incorrect \\u sequence" do
+ -> { '"\\u"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
+ -> { '"\\u{"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
+ -> { '"\\u{3042"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
+ -> { '"\\u"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
+ end
+
+ it "raises RuntimeError if there is malformed dump of non ASCII-compatible string" do
+ -> { '"".force_encoding("ASCII-8BIT"'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
+ -> { '"".force_encoding("Unknown")'.undump }.should raise_error(RuntimeError, /dumped string has unknown encoding name/)
+ -> { '"".force_encoding()'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
+ end
+
+ it "raises RuntimeError if string contains \0 character" do
+ -> { "\"foo\0\"".undump }.should raise_error(RuntimeError, /string contains null byte/)
+ end
+
+ it "raises RuntimeError if string contains non ASCII character" do
+ -> { "\"\u3042\"".undump }.should raise_error(RuntimeError, /non-ASCII character detected/)
+ end
+
+ it "raises RuntimeError if there are some excessive \"" do
+ -> { '" "" "'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/thread/backtrace/location/base_label_spec.rb b/spec/ruby/core/thread/backtrace/location/base_label_spec.rb
index d7302c26be..139a68e2c8 100644
--- a/spec/ruby/core/thread/backtrace/location/base_label_spec.rb
+++ b/spec/ruby/core/thread/backtrace/location/base_label_spec.rb
@@ -9,4 +9,14 @@ describe 'Thread::Backtrace::Location#base_label' do
it 'returns the base label of the call frame' do
@frame.base_label.should == '<top (required)>'
end
+
+ describe 'when call frame is inside a block' do
+ before :each do
+ @frame = ThreadBacktraceLocationSpecs.block_location[0]
+ end
+
+ it 'returns the name of the method that contains the block' do
+ @frame.base_label.should == 'block_location'
+ end
+ end
end
diff --git a/spec/ruby/core/tracepoint/parameters_spec.rb b/spec/ruby/core/tracepoint/parameters_spec.rb
index 4728b0a448..550b9572c0 100644
--- a/spec/ruby/core/tracepoint/parameters_spec.rb
+++ b/spec/ruby/core/tracepoint/parameters_spec.rb
@@ -1,21 +1,23 @@
require_relative '../../spec_helper'
-describe 'TracePoint#parameters' do
- it 'returns the parameters of block' do
- f = proc {|x, y, z| }
- parameters = nil
- TracePoint.new(:b_call) {|tp| parameters = tp.parameters }.enable do
- f.call
- parameters.should == [[:opt, :x], [:opt, :y], [:opt, :z]]
+ruby_version_is "2.6" do
+ describe 'TracePoint#parameters' do
+ it 'returns the parameters of block' do
+ f = proc {|x, y, z| }
+ parameters = nil
+ TracePoint.new(:b_call) {|tp| parameters = tp.parameters }.enable do
+ f.call
+ parameters.should == [[:opt, :x], [:opt, :y], [:opt, :z]]
+ end
end
- end
- it 'returns the parameters of lambda block' do
- f = lambda {|x, y, z| }
- parameters = nil
- TracePoint.new(:b_call) {|tp| parameters = tp.parameters }.enable do
- f.call(1, 2, 3)
- parameters.should == [[:req, :x], [:req, :y], [:req, :z]]
+ it 'returns the parameters of lambda block' do
+ f = lambda {|x, y, z| }
+ parameters = nil
+ TracePoint.new(:b_call) {|tp| parameters = tp.parameters }.enable do
+ f.call(1, 2, 3)
+ parameters.should == [[:req, :x], [:req, :y], [:req, :z]]
+ end
end
end
end
diff --git a/spec/ruby/language/super_spec.rb b/spec/ruby/language/super_spec.rb
index a86fb1df33..c6071f21f0 100644
--- a/spec/ruby/language/super_spec.rb
+++ b/spec/ruby/language/super_spec.rb
@@ -196,13 +196,9 @@ describe "The super keyword" do
Super::ZSuperWithRestReassigned::B.new.a("bar").should == ["foo"]
end
- # Don't run this spec on Appveyor because it uses old Ruby versions
- # The specs ends with segfault on old versions so let's just disable it
- platform_is_not :windows do
- # https://bugs.ruby-lang.org/issues/14279
- it "wraps into array and passes along reassigned rest args with non-array scalar value" do
- Super::ZSuperWithRestReassignedWithScalar::B.new.a("bar").should == ["foo"]
- end
+ # https://bugs.ruby-lang.org/issues/14279
+ it "wraps into array and passes along reassigned rest args with non-array scalar value" do
+ Super::ZSuperWithRestReassignedWithScalar::B.new.a("bar").should == ["foo"]
end
it "invokes methods from a chain of anonymous modules" do
diff --git a/spec/ruby/security/cve_2011_4815_spec.rb b/spec/ruby/security/cve_2011_4815_spec.rb
index 44543e6206..02ef10d562 100644
--- a/spec/ruby/security/cve_2011_4815_spec.rb
+++ b/spec/ruby/security/cve_2011_4815_spec.rb
@@ -22,15 +22,12 @@ describe "Float#hash" do
it_behaves_like :resists_cve_2011_4815, '3.14'
end
-# https://bugs.ruby-lang.org/issues/14420
-guard_not -> { platform_is :windows and PlatformGuard.implementation?(:ruby) } do
- describe "Rational#hash" do
- it_behaves_like :resists_cve_2011_4815, 'Rational(1, 2)'
- end
+describe "Rational#hash" do
+ it_behaves_like :resists_cve_2011_4815, 'Rational(1, 2)'
+end
- describe "Complex#hash" do
- it_behaves_like :resists_cve_2011_4815, 'Complex(1, 2)'
- end
+describe "Complex#hash" do
+ it_behaves_like :resists_cve_2011_4815, 'Complex(1, 2)'
end
describe "String#hash" do
diff --git a/spec/ruby/security/cve_2017_17742_spec.rb b/spec/ruby/security/cve_2017_17742_spec.rb
index f1205412c6..72776cb497 100644
--- a/spec/ruby/security/cve_2017_17742_spec.rb
+++ b/spec/ruby/security/cve_2017_17742_spec.rb
@@ -4,37 +4,31 @@ require "webrick"
require "stringio"
require "net/http"
-guard -> {
- ruby_version_is "2.3.7"..."2.4" or
- ruby_version_is "2.4.4"..."2.5" or
- ruby_version_is "2.5.1"
-} do
- describe "WEBrick" do
- describe "resists CVE-2017-17742" do
- it "for a response splitting headers" do
- config = WEBrick::Config::HTTP
- res = WEBrick::HTTPResponse.new config
- res['X-header'] = "malicious\r\nCookie: hack"
- io = StringIO.new
- res.send_response io
- io.rewind
- res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io))
- res.code.should == '500'
- io.string.should_not =~ /hack/
- end
+describe "WEBrick" do
+ describe "resists CVE-2017-17742" do
+ it "for a response splitting headers" do
+ config = WEBrick::Config::HTTP
+ res = WEBrick::HTTPResponse.new config
+ res['X-header'] = "malicious\r\nCookie: hack"
+ io = StringIO.new
+ res.send_response io
+ io.rewind
+ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io))
+ res.code.should == '500'
+ io.string.should_not =~ /hack/
+ end
- it "for a response splitting cookie headers" do
- user_input = "malicious\r\nCookie: hack"
- config = WEBrick::Config::HTTP
- res = WEBrick::HTTPResponse.new config
- res.cookies << WEBrick::Cookie.new('author', user_input)
- io = StringIO.new
- res.send_response io
- io.rewind
- res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io))
- res.code.should == '500'
- io.string.should_not =~ /hack/
- end
+ it "for a response splitting cookie headers" do
+ user_input = "malicious\r\nCookie: hack"
+ config = WEBrick::Config::HTTP
+ res = WEBrick::HTTPResponse.new config
+ res.cookies << WEBrick::Cookie.new('author', user_input)
+ io = StringIO.new
+ res.send_response io
+ io.rewind
+ res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io))
+ res.code.should == '500'
+ io.string.should_not =~ /hack/
end
end
end
diff --git a/spec/ruby/security/cve_2018_6914_spec.rb b/spec/ruby/security/cve_2018_6914_spec.rb
index 657341e474..1837ca0cef 100644
--- a/spec/ruby/security/cve_2018_6914_spec.rb
+++ b/spec/ruby/security/cve_2018_6914_spec.rb
@@ -2,58 +2,52 @@ require_relative '../spec_helper'
require 'tempfile'
-guard -> {
- ruby_version_is "2.3.7"..."2.4" or
- ruby_version_is "2.4.4"..."2.5" or
- ruby_version_is "2.5.1"
-} do
- describe "CVE-2018-6914 is resisted by" do
- before :all do
- @traversal_path = Array.new(Dir.pwd.split('/').count, '..').join('/') + Dir.pwd + '/'
- @traversal_path.delete!(':') if /mswin|mingw/ =~ RUBY_PLATFORM
- end
-
- it "Tempfile.open by deleting separators" do
- begin
- expect = Dir.glob(@traversal_path + '*').count
- t = Tempfile.open([@traversal_path, 'foo'])
- actual = Dir.glob(@traversal_path + '*').count
- actual.should == expect
- ensure
- t.close!
- end
- end
-
- it "Tempfile.new by deleting separators" do
- begin
- expect = Dir.glob(@traversal_path + '*').count
- t = Tempfile.new(@traversal_path + 'foo')
- actual = Dir.glob(@traversal_path + '*').count
- actual.should == expect
- ensure
- t.close!
- end
- end
+describe "CVE-2018-6914 is resisted by" do
+ before :all do
+ @traversal_path = Array.new(Dir.pwd.split('/').count, '..').join('/') + Dir.pwd + '/'
+ @traversal_path.delete!(':') if /mswin|mingw/ =~ RUBY_PLATFORM
+ end
- it "Tempfile.create by deleting separators" do
+ it "Tempfile.open by deleting separators" do
+ begin
expect = Dir.glob(@traversal_path + '*').count
- Tempfile.create(@traversal_path + 'foo')
+ t = Tempfile.open([@traversal_path, 'foo'])
actual = Dir.glob(@traversal_path + '*').count
actual.should == expect
+ ensure
+ t.close!
end
+ end
- it "Dir.mktmpdir by deleting separators" do
+ it "Tempfile.new by deleting separators" do
+ begin
expect = Dir.glob(@traversal_path + '*').count
- Dir.mktmpdir(@traversal_path + 'foo')
+ t = Tempfile.new(@traversal_path + 'foo')
actual = Dir.glob(@traversal_path + '*').count
actual.should == expect
+ ensure
+ t.close!
end
+ end
- it "Dir.mktmpdir with an array by deleting separators" do
- expect = Dir.glob(@traversal_path + '*').count
- Dir.mktmpdir([@traversal_path, 'foo'])
- actual = Dir.glob(@traversal_path + '*').count
- actual.should == expect
- end
+ it "Tempfile.create by deleting separators" do
+ expect = Dir.glob(@traversal_path + '*').count
+ Tempfile.create(@traversal_path + 'foo')
+ actual = Dir.glob(@traversal_path + '*').count
+ actual.should == expect
+ end
+
+ it "Dir.mktmpdir by deleting separators" do
+ expect = Dir.glob(@traversal_path + '*').count
+ Dir.mktmpdir(@traversal_path + 'foo')
+ actual = Dir.glob(@traversal_path + '*').count
+ actual.should == expect
+ end
+
+ it "Dir.mktmpdir with an array by deleting separators" do
+ expect = Dir.glob(@traversal_path + '*').count
+ Dir.mktmpdir([@traversal_path, 'foo'])
+ actual = Dir.glob(@traversal_path + '*').count
+ actual.should == expect
end
end
diff --git a/spec/ruby/security/cve_2018_8780_spec.rb b/spec/ruby/security/cve_2018_8780_spec.rb
index 44be29bf22..febb1de51d 100644
--- a/spec/ruby/security/cve_2018_8780_spec.rb
+++ b/spec/ruby/security/cve_2018_8780_spec.rb
@@ -1,53 +1,47 @@
require_relative '../spec_helper'
-guard -> {
- ruby_version_is "2.3.7"..."2.4" or
- ruby_version_is "2.4.4"..."2.5" or
- ruby_version_is "2.5.1"
-} do
- describe "CVE-2018-8780 is resisted by" do
- before :all do
- @root = File.realpath(tmp(""))
- end
+describe "CVE-2018-8780 is resisted by" do
+ before :all do
+ @root = File.realpath(tmp(""))
+ end
+
+ it "Dir.glob by raising an exception when there is a NUL byte" do
+ lambda {
+ Dir.glob([[@root, File.join(@root, "*")].join("\0")])
+ }.should raise_error(ArgumentError, /(path name|string) contains null byte/)
+ end
+
+ it "Dir.entries by raising an exception when there is a NUL byte" do
+ lambda {
+ Dir.entries(@root+"\0")
+ }.should raise_error(ArgumentError, /(path name|string) contains null byte/)
+ end
+
+ it "Dir.foreach by raising an exception when there is a NUL byte" do
+ lambda {
+ Dir.foreach(@root+"\0").to_a
+ }.should raise_error(ArgumentError, /(path name|string) contains null byte/)
+ end
- it "Dir.glob by raising an exception when there is a NUL byte" do
+ ruby_version_is "2.4" do
+ it "Dir.empty? by raising an exception when there is a NUL byte" do
lambda {
- Dir.glob([[@root, File.join(@root, "*")].join("\0")])
+ Dir.empty?(@root+"\0")
}.should raise_error(ArgumentError, /(path name|string) contains null byte/)
end
+ end
- it "Dir.entries by raising an exception when there is a NUL byte" do
+ ruby_version_is "2.5" do
+ it "Dir.children by raising an exception when there is a NUL byte" do
lambda {
- Dir.entries(@root+"\0")
+ Dir.children(@root+"\0")
}.should raise_error(ArgumentError, /(path name|string) contains null byte/)
end
- it "Dir.foreach by raising an exception when there is a NUL byte" do
+ it "Dir.each_child by raising an exception when there is a NUL byte" do
lambda {
- Dir.foreach(@root+"\0").to_a
+ Dir.each_child(@root+"\0").to_a
}.should raise_error(ArgumentError, /(path name|string) contains null byte/)
end
-
- ruby_version_is "2.5" do
- it "Dir.children by raising an exception when there is a NUL byte" do
- lambda {
- Dir.children(@root+"\0")
- }.should raise_error(ArgumentError, /(path name|string) contains null byte/)
- end
-
- it "Dir.each_child by raising an exception when there is a NUL byte" do
- lambda {
- Dir.each_child(@root+"\0").to_a
- }.should raise_error(ArgumentError, /(path name|string) contains null byte/)
- end
- end
-
- ruby_version_is "2.4" do
- it "Dir.empty? by raising an exception when there is a NUL byte" do
- lambda {
- Dir.empty?(@root+"\0")
- }.should raise_error(ArgumentError, /(path name|string) contains null byte/)
- end
- end
end
end