* add uri encoding as a text modifier
* add multibyte hex encoding. useful for %u git-svn-id: file:///home/svn/incoming/trunk@3544 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
940ad36f22
commit
64c7a2063f
|
@ -110,8 +110,14 @@ module Text
|
|||
#
|
||||
# Returns the hex version of the supplied string
|
||||
#
|
||||
def self.to_hex(str, prefix = "\\x")
|
||||
return str.gsub(/./) { |s| prefix + s.unpack('H*')[0] }
|
||||
def self.to_hex(str, prefix = "\\x", count = 1)
|
||||
raise RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
|
||||
|
||||
# XXX: Regexp.new is used here since using /.{#{count}}/o would compile
|
||||
# the regex the first time it is used and never check again. Since we
|
||||
# want to know how many to capture on every instance, we do it this
|
||||
# way.
|
||||
return str.gsub(Regexp.new(".{#{count}}")) { |s| prefix + s.unpack('H*')[0] }
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -257,7 +263,30 @@ module Text
|
|||
raise TypeError, 'invalid utf type'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Encode a string in a manor useful for HTTP URIs and URI Parameters.
|
||||
#
|
||||
def self.uri_encode(str, mode = 'hex-normal')
|
||||
return str if mode == 'none' # fast track no encoding
|
||||
|
||||
all = /[^\/\\]+/
|
||||
normal = /[^a-zA-Z1-9]+/
|
||||
|
||||
case mode
|
||||
when 'hex-normal'
|
||||
return str.gsub(normal) { |s| Rex::Text.to_hex(s, '%') }
|
||||
when 'hex-all'
|
||||
return str.gsub(all) { |s| Rex::Text.to_hex(s, '%') }
|
||||
when 'u-normal'
|
||||
return str.gsub(normal) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
|
||||
when 'u-all'
|
||||
return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
|
||||
else
|
||||
raise TypeError, 'invalid mode'
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Converts a hex string to a raw string
|
||||
#
|
||||
|
|
|
@ -7,6 +7,19 @@ require 'rex/text'
|
|||
|
||||
class Rex::Text::UnitTest < Test::Unit::TestCase
|
||||
|
||||
def test_uri_encode
|
||||
srand(0)
|
||||
assert_equal('A1%21', Rex::Text.uri_encode('A1!'), 'uri encode')
|
||||
assert_equal('A1%21', Rex::Text.uri_encode('A1!', 'hex-normal'), 'uri encode: hex-normal')
|
||||
assert_equal('%41%31%21', Rex::Text.uri_encode('A1!', 'hex-all'), 'uri encode: hex-all')
|
||||
assert_equal('A1%u01c3', Rex::Text.uri_encode('A1!', 'u-normal'), 'uri encode: u-normal')
|
||||
assert_equal('%uff21%u2081%uff01', Rex::Text.uri_encode('A1!', 'u-all'), 'uri encode: u-all')
|
||||
|
||||
assert_raises(TypeError) {
|
||||
Rex::Text.uri_encode('a', 'umpa lumpa')
|
||||
}
|
||||
end
|
||||
|
||||
def test_rand_text
|
||||
srand(0)
|
||||
assert_equal("\254/u\300C\373\303g\t\323", Rex::Text.rand_text(10), 'rand text 1')
|
||||
|
@ -95,13 +108,18 @@ class Rex::Text::UnitTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_hexify
|
||||
str = "\x01\x02\xff"
|
||||
str = "\x01\x02\xff\x00"
|
||||
|
||||
assert_equal("\\x01\\x02\\xff", Rex::Text.to_hex(str), 'to_hex')
|
||||
assert_equal("ABC01ABC02ABCff", Rex::Text.to_hex(str, 'ABC'), 'to_hex with prefix')
|
||||
assert_equal("\"\\x01\\x02\\xff\"\n", Rex::Text.to_ruby(str), 'to_ruby')
|
||||
assert_equal("\"\\x01\\x02\\xff\";\n", Rex::Text.to_perl(str), 'to_perl')
|
||||
assert_equal("unsigned char buf[] = \n\"\\x01\\x02\\xff\";\n", Rex::Text.to_c(str), 'to_c')
|
||||
assert_equal("\\x01\\x02\\xff\\x00", Rex::Text.to_hex(str), 'to_hex')
|
||||
assert_equal("ABC01ABC02ABCffABC00", Rex::Text.to_hex(str, 'ABC'), 'to_hex with prefix')
|
||||
assert_equal('%u0102%uff00', Rex::Text.to_hex(str, '%u', 2), 'to_hex with chunk size of 2')
|
||||
|
||||
# to_hex, without providing enouigh data to chunk on a given size
|
||||
assert_raises(RuntimeError){ Rex::Text.to_hex('a', '', 2) }
|
||||
|
||||
assert_equal("\"\\x01\\x02\\xff\\x00\"\n", Rex::Text.to_ruby(str), 'to_ruby')
|
||||
assert_equal("\"\\x01\\x02\\xff\\x00\";\n", Rex::Text.to_perl(str), 'to_perl')
|
||||
assert_equal("unsigned char buf[] = \n\"\\x01\\x02\\xff\\x00\";\n", Rex::Text.to_c(str), 'to_c')
|
||||
|
||||
# 0 -> 20
|
||||
str = "\000\001\002\003\004\005\006\a\010\t\n\v\f\r\016\017\020\021\022\023"
|
||||
|
|
Loading…
Reference in New Issue