diff options
Diffstat (limited to 'spec/ruby/core/string/unpack')
-rw-r--r-- | spec/ruby/core/string/unpack/a_spec.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/string/unpack/b_spec.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/string/unpack/h_spec.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/string/unpack/m_spec.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/string/unpack/p_spec.rb | 43 | ||||
-rw-r--r-- | spec/ruby/core/string/unpack/shared/taint.rb | 81 | ||||
-rw-r--r-- | spec/ruby/core/string/unpack/u_spec.rb | 3 | ||||
-rw-r--r-- | spec/ruby/core/string/unpack/z_spec.rb | 2 |
8 files changed, 135 insertions, 6 deletions
diff --git a/spec/ruby/core/string/unpack/a_spec.rb b/spec/ruby/core/string/unpack/a_spec.rb index 0adcf0ff80..3de338e2e1 100644 --- a/spec/ruby/core/string/unpack/a_spec.rb +++ b/spec/ruby/core/string/unpack/a_spec.rb @@ -3,12 +3,14 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative 'shared/basic' require_relative 'shared/string' +require_relative 'shared/taint' describe "String#unpack with format 'A'" do it_behaves_like :string_unpack_basic, 'A' it_behaves_like :string_unpack_no_platform, 'A' it_behaves_like :string_unpack_string, 'A' it_behaves_like :string_unpack_Aa, 'A' + it_behaves_like :string_unpack_taint, 'A' it "removes trailing space and NULL bytes from the decoded string" do [ ["a\x00 b \x00", ["a\x00 b", ""]], @@ -40,6 +42,7 @@ describe "String#unpack with format 'a'" do it_behaves_like :string_unpack_no_platform, 'a' it_behaves_like :string_unpack_string, 'a' it_behaves_like :string_unpack_Aa, 'a' + it_behaves_like :string_unpack_taint, 'a' it "does not remove trailing whitespace or NULL bytes from the decoded string" do [ ["a\x00 b \x00", ["a\x00 b \x00"]], diff --git a/spec/ruby/core/string/unpack/b_spec.rb b/spec/ruby/core/string/unpack/b_spec.rb index 332c85b5f8..a0bbc3d421 100644 --- a/spec/ruby/core/string/unpack/b_spec.rb +++ b/spec/ruby/core/string/unpack/b_spec.rb @@ -2,10 +2,12 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative 'shared/basic' +require_relative 'shared/taint' describe "String#unpack with format 'B'" do it_behaves_like :string_unpack_basic, 'B' it_behaves_like :string_unpack_no_platform, 'B' + it_behaves_like :string_unpack_taint, 'B' it "decodes one bit from each byte for each format character starting with the most significant bit" do [ ["\x00", "B", ["0"]], @@ -96,6 +98,7 @@ end describe "String#unpack with format 'b'" do it_behaves_like :string_unpack_basic, 'b' it_behaves_like :string_unpack_no_platform, 'b' + it_behaves_like :string_unpack_taint, 'b' it "decodes one bit from each byte for each format character starting with the least significant bit" do [ ["\x00", "b", ["0"]], diff --git a/spec/ruby/core/string/unpack/h_spec.rb b/spec/ruby/core/string/unpack/h_spec.rb index 7d0acf5718..07d52149d1 100644 --- a/spec/ruby/core/string/unpack/h_spec.rb +++ b/spec/ruby/core/string/unpack/h_spec.rb @@ -2,10 +2,12 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative 'shared/basic' +require_relative 'shared/taint' describe "String#unpack with format 'H'" do it_behaves_like :string_unpack_basic, 'H' it_behaves_like :string_unpack_no_platform, 'H' + it_behaves_like :string_unpack_taint, 'H' it "decodes one nibble from each byte for each format character starting with the most significant bit" do [ ["\x8f", "H", ["8"]], @@ -66,6 +68,7 @@ end describe "String#unpack with format 'h'" do it_behaves_like :string_unpack_basic, 'h' it_behaves_like :string_unpack_no_platform, 'h' + it_behaves_like :string_unpack_taint, 'h' it "decodes one nibble from each byte for each format character starting with the least significant bit" do [ ["\x8f", "h", ["f"]], diff --git a/spec/ruby/core/string/unpack/m_spec.rb b/spec/ruby/core/string/unpack/m_spec.rb index 0ae1118583..d714f6fbcb 100644 --- a/spec/ruby/core/string/unpack/m_spec.rb +++ b/spec/ruby/core/string/unpack/m_spec.rb @@ -2,10 +2,12 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative 'shared/basic' +require_relative 'shared/taint' describe "String#unpack with format 'M'" do it_behaves_like :string_unpack_basic, 'M' it_behaves_like :string_unpack_no_platform, 'M' + it_behaves_like :string_unpack_taint, 'M' it "decodes an empty string" do "".unpack("M").should == [""] @@ -100,6 +102,7 @@ end describe "String#unpack with format 'm'" do it_behaves_like :string_unpack_basic, 'm' it_behaves_like :string_unpack_no_platform, 'm' + it_behaves_like :string_unpack_taint, 'm' it "decodes an empty string" do "".unpack("m").should == [""] diff --git a/spec/ruby/core/string/unpack/p_spec.rb b/spec/ruby/core/string/unpack/p_spec.rb index 57b51fef00..136e32adfd 100644 --- a/spec/ruby/core/string/unpack/p_spec.rb +++ b/spec/ruby/core/string/unpack/p_spec.rb @@ -1,21 +1,52 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative 'shared/basic' +require_relative 'shared/taint' describe "String#unpack with format 'P'" do it_behaves_like :string_unpack_basic, 'P' + it_behaves_like :string_unpack_taint, 'P' - it "returns a random object after consuming a size-of a machine word bytes" do - str = "\0" * 1.size - str.unpack("P").should be_kind_of(Object) + it "round-trips a string through pack and unpack" do + ["hello"].pack("P").unpack("P5").should == ["hello"] + end + + it "cannot unpack a string except from the same object that created it, or a duplicate of it" do + packed = ["hello"].pack("P") + packed.unpack("P5").should == ["hello"] + packed.dup.unpack("P5").should == ["hello"] + lambda { packed.to_sym.to_s.unpack("P5") }.should raise_error(ArgumentError, /no associated pointer/) + end + + it "taints the unpacked string" do + ["hello"].pack("P").unpack("P5").first.tainted?.should be_true + end + + it "reads as many characters as specified" do + ["hello"].pack("P").unpack("P1").should == ["h"] + end + + it "reads only as far as a NUL character" do + ["hello"].pack("P").unpack("P10").should == ["hello"] end end describe "String#unpack with format 'p'" do it_behaves_like :string_unpack_basic, 'p' + it_behaves_like :string_unpack_taint, 'p' + + it "round-trips a string through pack and unpack" do + ["hello"].pack("p").unpack("p").should == ["hello"] + end + + it "cannot unpack a string except from the same object that created it, or a duplicate of it" do + packed = ["hello"].pack("p") + packed.unpack("p").should == ["hello"] + packed.dup.unpack("p").should == ["hello"] + lambda { packed.to_sym.to_s.unpack("p") }.should raise_error(ArgumentError, /no associated pointer/) + end - it "returns a random object after consuming a size-of a machine word bytes" do - str = "\0" * 1.size - str.unpack("p").should be_kind_of(Object) + it "taints the unpacked string" do + ["hello"].pack("p").unpack("p").first.tainted?.should be_true end end diff --git a/spec/ruby/core/string/unpack/shared/taint.rb b/spec/ruby/core/string/unpack/shared/taint.rb new file mode 100644 index 0000000000..391338192a --- /dev/null +++ b/spec/ruby/core/string/unpack/shared/taint.rb @@ -0,0 +1,81 @@ +describe :string_unpack_taint, shared: true do + it "does not taint returned arrays if given an untainted format string" do + "".unpack(unpack_format(2)).tainted?.should be_false + end + + it "does not taint returned arrays if given a tainted format string" do + format_string = unpack_format(2).dup + format_string.taint + "".unpack(format_string).tainted?.should be_false + end + + it "does not taint returned strings if given an untainted format string" do + "".unpack(unpack_format(2)).any?(&:tainted?).should be_false + end + + it "does not taint returned strings if given a tainted format string" do + format_string = unpack_format(2).dup + format_string.taint + "".unpack(format_string).any?(&:tainted?).should be_false + end + + it "does not taint returned arrays if given an untainted packed string" do + "".unpack(unpack_format(2)).tainted?.should be_false + end + + it "does not taint returned arrays if given a tainted packed string" do + packed_string = "" + packed_string.taint + packed_string.unpack(unpack_format(2)).tainted?.should be_false + end + + it "does not taint returned strings if given an untainted packed string" do + "".unpack(unpack_format(2)).any?(&:tainted?).should be_false + end + + it "taints returned strings if given a tainted packed string" do + packed_string = "" + packed_string.taint + packed_string.unpack(unpack_format(2)).all?(&:tainted?).should be_true + end + + it "does not untrust returned arrays if given an untrusted format string" do + "".unpack(unpack_format(2)).untrusted?.should be_false + end + + it "does not untrust returned arrays if given a untrusted format string" do + format_string = unpack_format(2).dup + format_string.untrust + "".unpack(format_string).untrusted?.should be_false + end + + it "does not untrust returned strings if given an untainted format string" do + "".unpack(unpack_format(2)).any?(&:untrusted?).should be_false + end + + it "does not untrust returned strings if given a untrusted format string" do + format_string = unpack_format(2).dup + format_string.untrust + "".unpack(format_string).any?(&:untrusted?).should be_false + end + + it "does not untrust returned arrays if given an trusted packed string" do + "".unpack(unpack_format(2)).untrusted?.should be_false + end + + it "does not untrust returned arrays if given a untrusted packed string" do + packed_string = "" + packed_string.untrust + packed_string.unpack(unpack_format(2)).untrusted?.should be_false + end + + it "does not untrust returned strings if given an trusted packed string" do + "".unpack(unpack_format(2)).any?(&:untrusted?).should be_false + end + + it "untrusts returned strings if given a untrusted packed string" do + packed_string = "" + packed_string.untrust + packed_string.unpack(unpack_format(2)).all?(&:untrusted?).should be_true + end +end diff --git a/spec/ruby/core/string/unpack/u_spec.rb b/spec/ruby/core/string/unpack/u_spec.rb index 6326bd7963..ee1d6c68e7 100644 --- a/spec/ruby/core/string/unpack/u_spec.rb +++ b/spec/ruby/core/string/unpack/u_spec.rb @@ -3,11 +3,13 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative 'shared/basic' require_relative 'shared/unicode' +require_relative 'shared/taint' describe "String#unpack with format 'U'" do it_behaves_like :string_unpack_basic, 'U' it_behaves_like :string_unpack_no_platform, 'U' it_behaves_like :string_unpack_unicode, 'U' + it_behaves_like :string_unpack_taint, 'U' it "raises ArgumentError on a malformed byte sequence" do lambda { "\xE3".unpack('U') }.should raise_error(ArgumentError) @@ -21,6 +23,7 @@ end describe "String#unpack with format 'u'" do it_behaves_like :string_unpack_basic, 'u' it_behaves_like :string_unpack_no_platform, 'u' + it_behaves_like :string_unpack_taint, 'u' it "decodes an empty string as an empty string" do "".unpack("u").should == [""] diff --git a/spec/ruby/core/string/unpack/z_spec.rb b/spec/ruby/core/string/unpack/z_spec.rb index 67d36ac8bf..2de624a74d 100644 --- a/spec/ruby/core/string/unpack/z_spec.rb +++ b/spec/ruby/core/string/unpack/z_spec.rb @@ -3,11 +3,13 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative 'shared/basic' require_relative 'shared/string' +require_relative 'shared/taint' describe "String#unpack with format 'Z'" do it_behaves_like :string_unpack_basic, 'Z' it_behaves_like :string_unpack_no_platform, 'Z' it_behaves_like :string_unpack_string, 'Z' + it_behaves_like :string_unpack_taint, 'Z' it "stops decoding at NULL bytes when passed the '*' modifier" do "a\x00\x00 b \x00c".unpack('Z*Z*Z*Z*').should == ["a", "", " b ", "c"] |