Skip to content

Commit 275e5ff

Browse files
committed
Merge branch 'master' into bug/MSP-12834/crawler-choke-on-save
2 parents d53067b + bf7e069 commit 275e5ff

File tree

2 files changed

+49
-57
lines changed

2 files changed

+49
-57
lines changed

lib/rex/text.rb

Lines changed: 24 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,7 @@
44
require 'stringio'
55
require 'cgi'
66
require 'rex/powershell'
7-
8-
%W{ iconv zlib }.each do |libname|
9-
begin
10-
old_verbose = $VERBOSE
11-
$VERBOSE = nil
12-
require libname
13-
rescue ::LoadError
14-
ensure
15-
$VERBOSE = old_verbose
16-
end
17-
end
7+
require 'zlib'
188

199
module Rex
2010

@@ -55,7 +45,8 @@ module Text
5545

5646
DefaultPatternSets = [ Rex::Text::UpperAlpha, Rex::Text::LowerAlpha, Rex::Text::Numerals ]
5747

58-
# In case Iconv isn't loaded
48+
# The Iconv translation table. The Iconv gem is deprecated in favor of
49+
# String#encode, yet there is no encoding for EBCDIC. See #4525
5950
Iconv_EBCDIC = [
6051
"\x00", "\x01", "\x02", "\x03", "7", "-", ".", "/", "\x16", "\x05",
6152
"%", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12", "\x13",
@@ -374,31 +365,26 @@ def self.to_raw(str)
374365
return str
375366
end
376367

368+
# Converts US-ASCII to UTF-8, skipping over any characters which don't
369+
# convert cleanly. This is a convenience method that wraps
370+
# String#encode with non-raising default paramaters.
377371
#
378-
# Converts ISO-8859-1 to UTF-8
379-
#
372+
# @param str [String] An encodable ASCII string
373+
# @return [String] a UTF-8 equivalent
374+
# @note This method will discard invalid characters
380375
def self.to_utf8(str)
381-
382-
if str.respond_to?(:encode)
383-
# Skip over any bytes that fail to convert to UTF-8
384-
return str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' })
385-
end
386-
387-
begin
388-
Iconv.iconv("utf-8","iso-8859-1", str).join(" ")
389-
rescue
390-
raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)"
391-
end
376+
str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' })
392377
end
393378

394-
#
395-
# Converts ASCII to EBCDIC
396-
#
397379
class IllegalSequence < ArgumentError; end
398380

399-
# A native implementation of the ASCII->EBCDIC table, used to fall back from using
400-
# Iconv
401-
def self.to_ebcdic_rex(str)
381+
# A native implementation of the ASCII to EBCDIC conversion table, since
382+
# EBCDIC isn't available to String#encode as of Ruby 2.1
383+
#
384+
# @param str [String] An encodable ASCII string
385+
# @return [String] an EBCDIC encoded string
386+
# @note This method will raise in the event of invalid characters
387+
def self.to_ebcdic(str)
402388
new_str = []
403389
str.each_byte do |x|
404390
if Iconv_ASCII.index(x.chr)
@@ -410,9 +396,13 @@ def self.to_ebcdic_rex(str)
410396
new_str.join
411397
end
412398

413-
# A native implementation of the EBCDIC->ASCII table, used to fall back from using
414-
# Iconv
415-
def self.from_ebcdic_rex(str)
399+
# A native implementation of the EBCIDC to ASCII conversion table, since
400+
# EBCDIC isn't available to String#encode as of Ruby 2.1
401+
#
402+
# @param str [String] an EBCDIC encoded string
403+
# @return [String] An encodable ASCII string
404+
# @note This method will raise in the event of invalid characters
405+
def self.from_ebcdic(str)
416406
new_str = []
417407
str.each_byte do |x|
418408
if Iconv_EBCDIC.index(x.chr)
@@ -424,29 +414,6 @@ def self.from_ebcdic_rex(str)
424414
new_str.join
425415
end
426416

427-
def self.to_ebcdic(str)
428-
begin
429-
Iconv.iconv("EBCDIC-US", "ASCII", str).first
430-
rescue ::Iconv::IllegalSequence => e
431-
raise e
432-
rescue
433-
self.to_ebcdic_rex(str)
434-
end
435-
end
436-
437-
#
438-
# Converts EBCIDC to ASCII
439-
#
440-
def self.from_ebcdic(str)
441-
begin
442-
Iconv.iconv("ASCII", "EBCDIC-US", str).first
443-
rescue ::Iconv::IllegalSequence => e
444-
raise e
445-
rescue
446-
self.from_ebcdic_rex(str)
447-
end
448-
end
449-
450417
#
451418
# Returns the words in +str+ as an Array.
452419
#

spec/lib/rex/text_spec.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,31 @@
44
describe Rex::Text do
55
context "Class methods" do
66

7+
context ".to_ebcdic" do
8+
it "should convert ASCII to EBCDIC (both US standards)" do
9+
described_class.to_ebcdic("Hello, World!").should eq("\xc8\x85\x93\x93\x96\x6b\x40\xe6\x96\x99\x93\x84\x5a")
10+
end
11+
it "should raise on non-convertable characters" do
12+
lambda {described_class.to_ebcdic("\xff\xfe")}.should raise_exception(described_class::IllegalSequence)
13+
end
14+
end
15+
16+
context ".from_ebcdic" do
17+
it "should convert EBCDIC to ASCII (both US standards)" do
18+
described_class.from_ebcdic("\xc8\x85\x93\x93\x96\x6b\x40\xe6\x96\x99\x93\x84\x5a").should eq("Hello, World!")
19+
end
20+
it "should raise on non-convertable characters" do
21+
lambda {described_class.from_ebcdic("\xff\xfe")}.should raise_exception(described_class::IllegalSequence)
22+
end
23+
end
24+
25+
context ".to_utf8" do
26+
it "should convert a string to UTF-8, skipping badchars" do
27+
described_class.to_utf8("Hello, world!").should eq("Hello, world!")
28+
described_class.to_utf8("Oh no, \xff\xfe can't convert!").should eq("Oh no, can't convert!")
29+
end
30+
end
31+
732
context ".to_octal" do
833
it "should convert all chars 00 through ff" do
934
described_class.to_octal("\x7f"*100).should eq("\\177"*100)

0 commit comments

Comments
 (0)