From 34ece37f264061412e6970be65dbfd9ef323f64f Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 19 Jun 2015 12:17:43 -0500 Subject: [PATCH 1/5] First off, iconv is gone, and zlib is stdlib --- lib/rex/text.rb | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/rex/text.rb b/lib/rex/text.rb index d321b573d1..ac6bdb0906 100644 --- a/lib/rex/text.rb +++ b/lib/rex/text.rb @@ -4,17 +4,7 @@ require 'digest/sha1' require 'stringio' require 'cgi' require 'rex/powershell' - -%W{ iconv zlib }.each do |libname| - begin - old_verbose = $VERBOSE - $VERBOSE = nil - require libname - rescue ::LoadError - ensure - $VERBOSE = old_verbose - end -end +require 'zlib' module Rex From afe5bb54c30c2a0ba245022051ee69df911a6221 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 19 Jun 2015 12:24:07 -0500 Subject: [PATCH 2/5] Get rid of the fall through methods --- lib/rex/text.rb | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/lib/rex/text.rb b/lib/rex/text.rb index ac6bdb0906..4d9e140cd7 100644 --- a/lib/rex/text.rb +++ b/lib/rex/text.rb @@ -45,7 +45,8 @@ module Text DefaultPatternSets = [ Rex::Text::UpperAlpha, Rex::Text::LowerAlpha, Rex::Text::Numerals ] - # In case Iconv isn't loaded + # The Iconv translation table. The Iconv gem is deprecated in favor of + # String#encode, yet there is no encoding for EBCDIC. See #4525 Iconv_EBCDIC = [ "\x00", "\x01", "\x02", "\x03", "7", "-", ".", "/", "\x16", "\x05", "%", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12", "\x13", @@ -386,9 +387,9 @@ module Text # class IllegalSequence < ArgumentError; end - # A native implementation of the ASCII->EBCDIC table, used to fall back from using - # Iconv - def self.to_ebcdic_rex(str) + # A native implementation of the EBCDIC->ASCII table, since it's not available + # in String#encode + def self.to_ebcdic(str) new_str = [] str.each_byte do |x| if Iconv_ASCII.index(x.chr) @@ -400,9 +401,9 @@ module Text new_str.join end - # A native implementation of the EBCDIC->ASCII table, used to fall back from using - # Iconv - def self.from_ebcdic_rex(str) + # A native implementation of the EBCDIC->ASCII table, since it's not available + # in String#encode + def self.from_ebcdic(str) new_str = [] str.each_byte do |x| if Iconv_EBCDIC.index(x.chr) @@ -414,29 +415,6 @@ module Text new_str.join end - def self.to_ebcdic(str) - begin - Iconv.iconv("EBCDIC-US", "ASCII", str).first - rescue ::Iconv::IllegalSequence => e - raise e - rescue - self.to_ebcdic_rex(str) - end - end - - # - # Converts EBCIDC to ASCII - # - def self.from_ebcdic(str) - begin - Iconv.iconv("ASCII", "EBCDIC-US", str).first - rescue ::Iconv::IllegalSequence => e - raise e - rescue - self.from_ebcdic_rex(str) - end - end - # # Returns the words in +str+ as an Array. # From a004c72068ac106bf38c55cdcff687b1b1ddb154 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 19 Jun 2015 12:30:20 -0500 Subject: [PATCH 3/5] Get rid of the encode test and iconv fallback --- lib/rex/text.rb | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/lib/rex/text.rb b/lib/rex/text.rb index 4d9e140cd7..532bd370cb 100644 --- a/lib/rex/text.rb +++ b/lib/rex/text.rb @@ -366,20 +366,11 @@ module Text end # - # Converts ISO-8859-1 to UTF-8 + # Converts US-ASCII and ISO-8859-1 to UTF-8, skipping over + # any characters which don't convert cleanly. # def self.to_utf8(str) - - if str.respond_to?(:encode) - # Skip over any bytes that fail to convert to UTF-8 - return str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' }) - end - - begin - Iconv.iconv("utf-8","iso-8859-1", str).join(" ") - rescue - raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)" - end + str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' }) end # From 01e37386dd8027ed0be07b0938cf8e8ab1c65403 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 19 Jun 2015 12:59:47 -0500 Subject: [PATCH 4/5] Add some YARD docs to the ebcdic methods --- lib/rex/text.rb | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/rex/text.rb b/lib/rex/text.rb index 532bd370cb..b5dfe85fb9 100644 --- a/lib/rex/text.rb +++ b/lib/rex/text.rb @@ -365,21 +365,25 @@ module Text return str end + # Converts US-ASCII to UTF-8, skipping over any characters which don't + # convert cleanly. This is a convenience method that wraps + # String#encode with non-raising default paramaters. # - # Converts US-ASCII and ISO-8859-1 to UTF-8, skipping over - # any characters which don't convert cleanly. - # + # @param str [String] An encodable ASCII string + # @return [String] a UTF-8 equivalent + # @note This method will discard invalid characters def self.to_utf8(str) str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' }) end - # - # Converts ASCII to EBCDIC - # class IllegalSequence < ArgumentError; end - # A native implementation of the EBCDIC->ASCII table, since it's not available - # in String#encode + # A native implementation of the ASCII to EBCDIC conversion table, since + # EBCDIC isn't available to String#encode as of Ruby 2.1 + # + # @param str [String] An encodable ASCII string + # @return [String] an EBCDIC encoded string + # @note This method will raise in the event of invalid characters def self.to_ebcdic(str) new_str = [] str.each_byte do |x| @@ -392,8 +396,12 @@ module Text new_str.join end - # A native implementation of the EBCDIC->ASCII table, since it's not available - # in String#encode + # A native implementation of the EBCIDC to ASCII conversion table, since + # EBCDIC isn't available to String#encode as of Ruby 2.1 + # + # @param str [String] an EBCDIC encoded string + # @return [String] An encodable ASCII string + # @note This method will raise in the event of invalid characters def self.from_ebcdic(str) new_str = [] str.each_byte do |x| From 66fecb2832ecde2d61eeebe43d0d6cbe635dcd38 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 19 Jun 2015 13:22:31 -0500 Subject: [PATCH 5/5] Add some specs around changed methods See #4525 --- spec/lib/rex/text_spec.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/spec/lib/rex/text_spec.rb b/spec/lib/rex/text_spec.rb index 839270eba3..4609065457 100644 --- a/spec/lib/rex/text_spec.rb +++ b/spec/lib/rex/text_spec.rb @@ -4,6 +4,31 @@ require 'rex/text' describe Rex::Text do context "Class methods" do + context ".to_ebcdic" do + it "should convert ASCII to EBCDIC (both US standards)" do + described_class.to_ebcdic("Hello, World!").should eq("\xc8\x85\x93\x93\x96\x6b\x40\xe6\x96\x99\x93\x84\x5a") + end + it "should raise on non-convertable characters" do + lambda {described_class.to_ebcdic("\xff\xfe")}.should raise_exception(described_class::IllegalSequence) + end + end + + context ".from_ebcdic" do + it "should convert EBCDIC to ASCII (both US standards)" do + described_class.from_ebcdic("\xc8\x85\x93\x93\x96\x6b\x40\xe6\x96\x99\x93\x84\x5a").should eq("Hello, World!") + end + it "should raise on non-convertable characters" do + lambda {described_class.from_ebcdic("\xff\xfe")}.should raise_exception(described_class::IllegalSequence) + end + end + + context ".to_utf8" do + it "should convert a string to UTF-8, skipping badchars" do + described_class.to_utf8("Hello, world!").should eq("Hello, world!") + described_class.to_utf8("Oh no, \xff\xfe can't convert!").should eq("Oh no, can't convert!") + end + end + context ".to_octal" do it "should convert all chars 00 through ff" do described_class.to_octal("\x7f"*100).should eq("\\177"*100)