aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--spec/ruby/core/process/clock_getres_spec.rb6
-rw-r--r--spec/ruby/core/string/crypt_spec.rb157
-rw-r--r--spec/ruby/library/socket/socket/connect_nonblock_spec.rb12
-rw-r--r--spec/ruby/library/socket/udpsocket/initialize_spec.rb10
4 files changed, 118 insertions, 67 deletions
diff --git a/spec/ruby/core/process/clock_getres_spec.rb b/spec/ruby/core/process/clock_getres_spec.rb
index cadb5b7e8c..7112b0520a 100644
--- a/spec/ruby/core/process/clock_getres_spec.rb
+++ b/spec/ruby/core/process/clock_getres_spec.rb
@@ -4,7 +4,7 @@ require_relative 'fixtures/clocks'
describe "Process.clock_getres" do
# clock_getres() seems completely buggy on FreeBSD:
# https://rubyci.org/logs/rubyci.s3.amazonaws.com/freebsd11zfs/ruby-trunk/log/20190428T093003Z.fail.html.gz
- platform_is_not :freebsd do
+ platform_is_not :freebsd, :openbsd do
# NOTE: Look at fixtures/clocks.rb for clock and OS-specific exclusions
ProcessSpecs.clock_constants_for_resolution_checks.each do |name, value|
it "matches the clock in practice for Process::#{name}" do
@@ -50,13 +50,13 @@ describe "Process.clock_getres" do
# These are observed
- platform_is_not :solaris, :aix do
+ platform_is_not :solaris, :aix, :openbsd do
it "with Process::CLOCK_REALTIME reports at least 1 microsecond" do
Process.clock_getres(Process::CLOCK_REALTIME, :nanosecond).should <= 1_000
end
end
- platform_is_not :aix do
+ platform_is_not :aix, :openbsd do
it "with Process::CLOCK_MONOTONIC reports at least 1 microsecond" do
Process.clock_getres(Process::CLOCK_MONOTONIC, :nanosecond).should <= 1_000
end
diff --git a/spec/ruby/core/string/crypt_spec.rb b/spec/ruby/core/string/crypt_spec.rb
index 01d3830892..66161b280f 100644
--- a/spec/ruby/core/string/crypt_spec.rb
+++ b/spec/ruby/core/string/crypt_spec.rb
@@ -2,72 +2,117 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "String#crypt" do
- # Note: MRI's documentation just says that the C stdlib function crypt() is
- # called.
- #
- # I'm not sure if crypt() is guaranteed to produce the same result across
- # different platforms. It seems that there is one standard UNIX implementation
- # of crypt(), but that alternative implementations are possible. See
- # http://www.unix.org.ua/orelly/networking/puis/ch08_06.htm
- it "returns a cryptographic hash of self by applying the UNIX crypt algorithm with the specified salt" do
- "".crypt("aa").should == "aaQSqAReePlq6"
- "nutmeg".crypt("Mi").should == "MiqkFWCm1fNJI"
- "ellen1".crypt("ri").should == "ri79kNd7V6.Sk"
- "Sharon".crypt("./").should == "./UY9Q7TvYJDg"
- "norahs".crypt("am").should == "amfIADT2iqjA."
- "norahs".crypt("7a").should == "7azfT5tIdyh0I"
-
- # Only uses first 8 chars of string
- "01234567".crypt("aa").should == "aa4c4gpuvCkSE"
- "012345678".crypt("aa").should == "aa4c4gpuvCkSE"
- "0123456789".crypt("aa").should == "aa4c4gpuvCkSE"
-
- # Only uses first 2 chars of salt
- "hello world".crypt("aa").should == "aayPz4hyPS1wI"
- "hello world".crypt("aab").should == "aayPz4hyPS1wI"
- "hello world".crypt("aabc").should == "aayPz4hyPS1wI"
- end
+ platform_is :openbsd do
+ it "returns a cryptographic hash of self by applying the bcrypt algorithm with the specified salt" do
+ "mypassword".crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWuBQGbkjzgtSc3gJbmdy0GAGMa45MFM2."
- it "raises an ArgumentError when the salt is shorter than two characters" do
- lambda { "hello".crypt("") }.should raise_error(ArgumentError)
- lambda { "hello".crypt("f") }.should raise_error(ArgumentError)
- lambda { "hello".crypt("\x00\x00") }.should raise_error(ArgumentError)
- lambda { "hello".crypt("\x00a") }.should raise_error(ArgumentError)
- lambda { "hello".crypt("a\x00") }.should raise_error(ArgumentError)
- end
+ # Only uses first 72 characters of string
+ ("12345678"*9).crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWukj/ORBnsMjCGpST/zCJnAypc7eAbutK"
+ ("12345678"*10).crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWukj/ORBnsMjCGpST/zCJnAypc7eAbutK"
- it "raises an ArgumentError when the string contains NUL character" do
- lambda { "poison\0null".crypt("aa") }.should raise_error(ArgumentError)
- end
+ # Only uses first 29 characters of salt
+ "mypassword".crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWuB").should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWuBQGbkjzgtSc3gJbmdy0GAGMa45MFM2."
+ end
- it "calls #to_str to converts the salt arg to a String" do
- obj = mock('aa')
- obj.should_receive(:to_str).and_return("aa")
+ it "raises Errno::EINVAL when the salt is shorter than 29 characters" do
+ lambda { "mypassword".crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHW") }.should raise_error(Errno::EINVAL)
+ end
- "".crypt(obj).should == "aaQSqAReePlq6"
- end
+ it "calls #to_str to converts the salt arg to a String" do
+ obj = mock('$2a$04$0WVaz0pV3jzfZ5G5tpmHWu')
+ obj.should_receive(:to_str).and_return("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu")
- it "raises a type error when the salt arg can't be converted to a string" do
- lambda { "".crypt(5) }.should raise_error(TypeError)
- lambda { "".crypt(mock('x')) }.should raise_error(TypeError)
+ "mypassword".crypt(obj).should == "$2a$04$0WVaz0pV3jzfZ5G5tpmHWuBQGbkjzgtSc3gJbmdy0GAGMa45MFM2."
+ end
+
+ it "taints the result if either salt or self is tainted" do
+ tainted_salt = "$2a$04$0WVaz0pV3jzfZ5G5tpmHWu"
+ tainted_str = "mypassword"
+
+ tainted_salt.taint
+ tainted_str.taint
+
+ "mypassword".crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").tainted?.should == false
+ tainted_str.crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").tainted?.should == true
+ "mypassword".crypt(tainted_salt).tainted?.should == true
+ tainted_str.crypt(tainted_salt).tainted?.should == true
+ end
+
+ it "doesn't return subclass instances" do
+ StringSpecs::MyString.new("mypassword").crypt("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu").should be_an_instance_of(String)
+ "mypassword".crypt(StringSpecs::MyString.new("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu")).should be_an_instance_of(String)
+ StringSpecs::MyString.new("mypassword").crypt(StringSpecs::MyString.new("$2a$04$0WVaz0pV3jzfZ5G5tpmHWu")).should be_an_instance_of(String)
+ end
end
- it "taints the result if either salt or self is tainted" do
- tainted_salt = "aa"
- tainted_str = "hello"
+ platform_is_not :openbsd do
+ # Note: MRI's documentation just says that the C stdlib function crypt() is
+ # called.
+ #
+ # I'm not sure if crypt() is guaranteed to produce the same result across
+ # different platforms. It seems that there is one standard UNIX implementation
+ # of crypt(), but that alternative implementations are possible. See
+ # http://www.unix.org.ua/orelly/networking/puis/ch08_06.htm
+ it "returns a cryptographic hash of self by applying the UNIX crypt algorithm with the specified salt" do
+ "".crypt("aa").should == "aaQSqAReePlq6"
+ "nutmeg".crypt("Mi").should == "MiqkFWCm1fNJI"
+ "ellen1".crypt("ri").should == "ri79kNd7V6.Sk"
+ "Sharon".crypt("./").should == "./UY9Q7TvYJDg"
+ "norahs".crypt("am").should == "amfIADT2iqjA."
+ "norahs".crypt("7a").should == "7azfT5tIdyh0I"
- tainted_salt.taint
- tainted_str.taint
+ # Only uses first 8 chars of string
+ "01234567".crypt("aa").should == "aa4c4gpuvCkSE"
+ "012345678".crypt("aa").should == "aa4c4gpuvCkSE"
+ "0123456789".crypt("aa").should == "aa4c4gpuvCkSE"
- "hello".crypt("aa").tainted?.should == false
- tainted_str.crypt("aa").tainted?.should == true
- "hello".crypt(tainted_salt).tainted?.should == true
- tainted_str.crypt(tainted_salt).tainted?.should == true
+ # Only uses first 2 chars of salt
+ "hello world".crypt("aa").should == "aayPz4hyPS1wI"
+ "hello world".crypt("aab").should == "aayPz4hyPS1wI"
+ "hello world".crypt("aabc").should == "aayPz4hyPS1wI"
+ end
+
+ it "raises an ArgumentError when the string contains NUL character" do
+ lambda { "poison\0null".crypt("aa") }.should raise_error(ArgumentError)
+ end
+
+ it "calls #to_str to converts the salt arg to a String" do
+ obj = mock('aa')
+ obj.should_receive(:to_str).and_return("aa")
+
+ "".crypt(obj).should == "aaQSqAReePlq6"
+ end
+
+ it "taints the result if either salt or self is tainted" do
+ tainted_salt = "aa"
+ tainted_str = "hello"
+
+ tainted_salt.taint
+ tainted_str.taint
+
+ "hello".crypt("aa").tainted?.should == false
+ tainted_str.crypt("aa").tainted?.should == true
+ "hello".crypt(tainted_salt).tainted?.should == true
+ tainted_str.crypt(tainted_salt).tainted?.should == true
+ end
+
+ it "doesn't return subclass instances" do
+ StringSpecs::MyString.new("hello").crypt("aa").should be_an_instance_of(String)
+ "hello".crypt(StringSpecs::MyString.new("aa")).should be_an_instance_of(String)
+ StringSpecs::MyString.new("hello").crypt(StringSpecs::MyString.new("aa")).should be_an_instance_of(String)
+ end
+
+ it "raises an ArgumentError when the salt is shorter than two characters" do
+ lambda { "hello".crypt("") }.should raise_error(ArgumentError)
+ lambda { "hello".crypt("f") }.should raise_error(ArgumentError)
+ lambda { "hello".crypt("\x00\x00") }.should raise_error(ArgumentError)
+ lambda { "hello".crypt("\x00a") }.should raise_error(ArgumentError)
+ lambda { "hello".crypt("a\x00") }.should raise_error(ArgumentError)
+ end
end
- it "doesn't return subclass instances" do
- StringSpecs::MyString.new("hello").crypt("aa").should be_an_instance_of(String)
- "hello".crypt(StringSpecs::MyString.new("aa")).should be_an_instance_of(String)
- StringSpecs::MyString.new("hello").crypt(StringSpecs::MyString.new("aa")).should be_an_instance_of(String)
+ it "raises a type error when the salt arg can't be converted to a string" do
+ lambda { "".crypt(5) }.should raise_error(TypeError)
+ lambda { "".crypt(mock('x')) }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/library/socket/socket/connect_nonblock_spec.rb b/spec/ruby/library/socket/socket/connect_nonblock_spec.rb
index c56bebee62..b5f416d96f 100644
--- a/spec/ruby/library/socket/socket/connect_nonblock_spec.rb
+++ b/spec/ruby/library/socket/socket/connect_nonblock_spec.rb
@@ -114,24 +114,24 @@ describe 'Socket#connect_nonblock' do
platform_is_not :windows do
it 'raises Errno::EISCONN when already connected' do
@server.listen(1)
- @client.connect(@server.getsockname).should == 0
+ @client.connect(@server.connect_address).should == 0
lambda {
- @client.connect_nonblock(@server.getsockname)
+ @client.connect_nonblock(@server.connect_address)
# A second call needed if non-blocking sockets become default
# XXX honestly I don't expect any real code to care about this spec
# as it's too implementation-dependent and checking for connect()
# errors is futile anyways because of TOCTOU
- @client.connect_nonblock(@server.getsockname)
+ @client.connect_nonblock(@server.connect_address)
}.should raise_error(Errno::EISCONN)
end
it 'returns 0 when already connected in exceptionless mode' do
@server.listen(1)
- @client.connect(@server.getsockname).should == 0
+ @client.connect(@server.connect_address).should == 0
- @client.connect_nonblock(@server.getsockname, exception: false).should == 0
+ @client.connect_nonblock(@server.connect_address, exception: false).should == 0
end
end
@@ -140,7 +140,7 @@ describe 'Socket#connect_nonblock' do
@server.bind(@sockaddr)
lambda {
- @client.connect_nonblock(@server.getsockname)
+ @client.connect_nonblock(@server.connect_address)
}.should raise_error(IO::EINPROGRESSWaitWritable)
end
end
diff --git a/spec/ruby/library/socket/udpsocket/initialize_spec.rb b/spec/ruby/library/socket/udpsocket/initialize_spec.rb
index 06f7b5ef1c..9497d0dcbc 100644
--- a/spec/ruby/library/socket/udpsocket/initialize_spec.rb
+++ b/spec/ruby/library/socket/udpsocket/initialize_spec.rb
@@ -30,7 +30,13 @@ describe 'UDPSocket#initialize' do
@socket.binmode?.should be_true
end
- it 'raises Errno::EAFNOSUPPORT when given an invalid address family' do
- lambda { UDPSocket.new(666) }.should raise_error(Errno::EAFNOSUPPORT)
+ it 'raises Errno::EAFNOSUPPORT or Errno::EPROTONOSUPPORT when given an invalid address family' do
+ begin
+ UDPSocket.new(666)
+ rescue Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT => e
+ [Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT].should include(e.class)
+ else
+ raise "expected Errno::EAFNOSUPPORT or Errno::EPROTONOSUPPORT exception raised"
+ end
end
end