Skip to content

Commit 126899c

Browse files
committed
Merge @HDMoore's Ruby 2.0 fixes (iconv)
2 parents 1446992 + ed93a79 commit 126899c

File tree

3 files changed

+103
-78
lines changed

3 files changed

+103
-78
lines changed

lib/rex/text.rb

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44
require 'stringio'
55
require 'cgi'
66

7-
begin
8-
old_verbose = $VERBOSE
9-
$VERBOSE = nil
10-
require 'iconv'
11-
require 'zlib'
12-
rescue ::LoadError
13-
ensure
14-
$VERBOSE = old_verbose
7+
%W{ iconv zlib }.each do |libname|
8+
begin
9+
old_verbose = $VERBOSE
10+
$VERBOSE = nil
11+
require libname
12+
rescue ::LoadError
13+
ensure
14+
$VERBOSE = old_verbose
15+
end
1516
end
1617

1718
module Rex
@@ -157,6 +158,12 @@ def self.to_raw(str)
157158
# Converts ISO-8859-1 to UTF-8
158159
#
159160
def self.to_utf8(str)
161+
162+
if str.respond_to?(:encode)
163+
# Skip over any bytes that fail to convert to UTF-8
164+
return str.encode('utf-8', { :invalid => :replace, :undef => :replace, :replace => '' })
165+
end
166+
160167
begin
161168
Iconv.iconv("utf-8","iso-8859-1", str).join(" ")
162169
rescue

lib/rkelly/visitors/evaluation_visitor.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# -*- coding: binary -*-
12
module RKelly
23
module Visitors
34
class EvaluationVisitor < Visitor

lib/zip/zip.rb

Lines changed: 87 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# encoding: ASCII-8BIT
22
require 'delegate'
3-
require 'iconv'
3+
4+
begin
5+
require 'iconv'
6+
rescue ::LoadError
7+
end
8+
49
require 'singleton'
510
require 'tempfile'
611
require 'fileutils'
@@ -140,15 +145,13 @@ def eof
140145
def open_entry
141146
@currentEntry = ZipEntry.read_local_entry(@archiveIO)
142147
if (@currentEntry == nil)
143-
@decompressor = NullDecompressor.instance
148+
@decompressor = NullDecompressor.instance
144149
elsif @currentEntry.compression_method == ZipEntry::STORED
145-
@decompressor = PassThruDecompressor.new(@archiveIO,
146-
@currentEntry.size)
150+
@decompressor = PassThruDecompressor.new(@archiveIO, @currentEntry.size)
147151
elsif @currentEntry.compression_method == ZipEntry::DEFLATED
148-
@decompressor = Inflater.new(@archiveIO)
152+
@decompressor = Inflater.new(@archiveIO)
149153
else
150-
raise ZipCompressionMethodError,
151-
"Unsupported compression method #{@currentEntry.compression_method}"
154+
raise ZipCompressionMethodError, "Unsupported compression method #{@currentEntry.compression_method}"
152155
end
153156
flush
154157
return @currentEntry
@@ -184,8 +187,8 @@ def initialize(inputStream)
184187
def sysread(numberOfBytes = nil, buf = nil)
185188
readEverything = (numberOfBytes == nil)
186189
while (readEverything || @outputBuffer.length < numberOfBytes)
187-
break if internal_input_finished?
188-
@outputBuffer << internal_produce_input(buf)
190+
break if internal_input_finished?
191+
@outputBuffer << internal_produce_input(buf)
189192
end
190193
return value_when_finished if @outputBuffer.length==0 && input_finished?
191194
endIndex= numberOfBytes==nil ? @outputBuffer.length : numberOfBytes
@@ -194,9 +197,9 @@ def sysread(numberOfBytes = nil, buf = nil)
194197

195198
def produce_input
196199
if (@outputBuffer.empty?)
197-
return internal_produce_input
200+
return internal_produce_input
198201
else
199-
return @outputBuffer.slice!(0...(@outputBuffer.length))
202+
return @outputBuffer.slice!(0...(@outputBuffer.length))
200203
end
201204
end
202205

@@ -244,14 +247,14 @@ def initialize(inputStream, charsToRead)
244247
# TODO: Specialize to handle different behaviour in ruby > 1.7.0 ?
245248
def sysread(numberOfBytes = nil, buf = nil)
246249
if input_finished?
247-
hasReturnedEmptyStringVal=@hasReturnedEmptyString
248-
@hasReturnedEmptyString=true
249-
return "" unless hasReturnedEmptyStringVal
250-
return nil
250+
hasReturnedEmptyStringVal=@hasReturnedEmptyString
251+
@hasReturnedEmptyString=true
252+
return "" unless hasReturnedEmptyStringVal
253+
return nil
251254
end
252255

253256
if (numberOfBytes == nil || @readSoFar+numberOfBytes > @charsToRead)
254-
numberOfBytes = @charsToRead-@readSoFar
257+
numberOfBytes = @charsToRead-@readSoFar
255258
end
256259
@readSoFar += numberOfBytes
257260
@inputStream.read(numberOfBytes, buf)
@@ -356,14 +359,28 @@ def name_encoding
356359
(@gp_flags & 0b100000000000) != 0 ? "utf8" : "CP437//"
357360
end
358361

362+
363+
# Converts string encoding
364+
def encode_string(str, src, dst)
365+
if str.respond_to?(:encode)
366+
str.encode(dst, { :invalid => :replace, :undef => :replace, :replace => '' })
367+
else
368+
begin
369+
Iconv.conv(dst, src, str)
370+
rescue
371+
raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)"
372+
end
373+
end
374+
end
375+
359376
# Returns the name in the encoding specified by enc
360377
def name_in(enc)
361-
Iconv.conv(enc, name_encoding, @name)
378+
encode_string(@name, name_encoding, enc)
362379
end
363380

364-
# Returns the name in the encoding specified by enc
381+
# Returns the comment in the encoding specified by enc
365382
def comment_in(enc)
366-
Iconv.conv(enc, name_encoding, @name)
383+
encode_string(@comment, name_encoding, enc)
367384
end
368385

369386
def initialize(zipfile = "", name = "", comment = "", extra = "",
@@ -372,7 +389,7 @@ def initialize(zipfile = "", name = "", comment = "", extra = "",
372389
time = Time.now)
373390
super()
374391
if name.starts_with("/")
375-
raise ZipEntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
392+
raise ZipEntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
376393
end
377394
@localHeaderOffset = 0
378395
@local_header_size = 0
@@ -484,9 +501,9 @@ def extract(destPath = @name, &onExistsProc)
484501
onExistsProc ||= proc { false }
485502

486503
if directory?
487-
create_directory(destPath, &onExistsProc)
504+
create_directory(destPath, &onExistsProc)
488505
elsif file?
489-
write_file(destPath, &onExistsProc)
506+
write_file(destPath, &onExistsProc)
490507
elsif symlink?
491508
create_symlink(destPath, &onExistsProc)
492509
else
@@ -520,24 +537,24 @@ def read_local_entry(io) #:nodoc:all
520537
@localHeaderOffset = io.tell
521538
staticSizedFieldsBuf = io.read(LOCAL_ENTRY_STATIC_HEADER_LENGTH)
522539
unless (staticSizedFieldsBuf.size==LOCAL_ENTRY_STATIC_HEADER_LENGTH)
523-
raise ZipError, "Premature end of file. Not enough data for zip entry local header"
540+
raise ZipError, "Premature end of file. Not enough data for zip entry local header"
524541
end
525542

526543
@header_signature ,
527-
@version ,
528-
@fstype ,
529-
@gp_flags ,
530-
@compression_method,
531-
lastModTime ,
532-
lastModDate ,
533-
@crc ,
534-
@compressed_size ,
535-
@size ,
536-
nameLength ,
537-
extraLength = staticSizedFieldsBuf.unpack('VCCvvvvVVVvv')
544+
@version ,
545+
@fstype ,
546+
@gp_flags ,
547+
@compression_method,
548+
lastModTime ,
549+
lastModDate ,
550+
@crc ,
551+
@compressed_size ,
552+
@size ,
553+
nameLength ,
554+
extraLength = staticSizedFieldsBuf.unpack('VCCvvvvVVVvv')
538555

539556
unless (@header_signature == LOCAL_ENTRY_SIGNATURE)
540-
raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
557+
raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
541558
end
542559
set_time(lastModDate, lastModTime)
543560

@@ -546,7 +563,7 @@ def read_local_entry(io) #:nodoc:all
546563
extra = io.read(extraLength)
547564

548565
if (extra && extra.length != extraLength)
549-
raise ZipError, "Truncated local zip entry header"
566+
raise ZipError, "Truncated local zip entry header"
550567
else
551568
if ZipExtraField === @extra
552569
@extra.merge(extra)
@@ -569,17 +586,17 @@ def write_local_entry(io) #:nodoc:all
569586
@localHeaderOffset = io.tell
570587

571588
io <<
572-
[LOCAL_ENTRY_SIGNATURE ,
573-
VERSION_NEEDED_TO_EXTRACT , # version needed to extract
574-
0 , # @gp_flags ,
575-
@compression_method ,
576-
@time.to_binary_dos_time , # @lastModTime ,
577-
@time.to_binary_dos_date , # @lastModDate ,
578-
@crc ,
579-
@compressed_size ,
580-
@size ,
581-
@name ? @name.length : 0,
582-
@extra? @extra.local_length : 0 ].pack('VvvvvvVVVvv')
589+
[LOCAL_ENTRY_SIGNATURE ,
590+
VERSION_NEEDED_TO_EXTRACT , # version needed to extract
591+
0 , # @gp_flags ,
592+
@compression_method ,
593+
@time.to_binary_dos_time , # @lastModTime ,
594+
@time.to_binary_dos_date , # @lastModDate ,
595+
@crc ,
596+
@compressed_size ,
597+
@size ,
598+
@name ? @name.length : 0,
599+
@extra? @extra.local_length : 0 ].pack('VvvvvvVVVvv')
583600
io << @name
584601
io << (@extra ? @extra.to_local_bin : "")
585602
end
@@ -590,33 +607,33 @@ def write_local_entry(io) #:nodoc:all
590607
def read_c_dir_entry(io) #:nodoc:all
591608
staticSizedFieldsBuf = io.read(CDIR_ENTRY_STATIC_HEADER_LENGTH)
592609
unless (staticSizedFieldsBuf.size == CDIR_ENTRY_STATIC_HEADER_LENGTH)
593-
raise ZipError, "Premature end of file. Not enough data for zip cdir entry header"
610+
raise ZipError, "Premature end of file. Not enough data for zip cdir entry header"
594611
end
595612

596613
@header_signature ,
597-
@version , # version of encoding software
598-
@fstype , # filesystem type
599-
@versionNeededToExtract,
600-
@gp_flags ,
601-
@compression_method ,
602-
lastModTime ,
603-
lastModDate ,
604-
@crc ,
605-
@compressed_size ,
606-
@size ,
607-
nameLength ,
608-
extraLength ,
609-
commentLength ,
610-
diskNumberStart ,
611-
@internalFileAttributes,
612-
@externalFileAttributes,
613-
@localHeaderOffset ,
614-
@name ,
615-
@extra ,
616-
@comment = staticSizedFieldsBuf.unpack('VCCvvvvvVVVvvvvvVV')
614+
@version , # version of encoding software
615+
@fstype , # filesystem type
616+
@versionNeededToExtract,
617+
@gp_flags ,
618+
@compression_method ,
619+
lastModTime ,
620+
lastModDate ,
621+
@crc ,
622+
@compressed_size ,
623+
@size ,
624+
nameLength ,
625+
extraLength ,
626+
commentLength ,
627+
diskNumberStart ,
628+
@internalFileAttributes,
629+
@externalFileAttributes,
630+
@localHeaderOffset ,
631+
@name ,
632+
@extra ,
633+
@comment = staticSizedFieldsBuf.unpack('VCCvvvvvVVVvvvvvVV')
617634

618635
unless (@header_signature == CENTRAL_DIRECTORY_ENTRY_SIGNATURE)
619-
raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
636+
raise ZipError, "Zip local header magic not found at location '#{localHeaderOffset}'"
620637
end
621638
set_time(lastModDate, lastModTime)
622639

@@ -628,7 +645,7 @@ def read_c_dir_entry(io) #:nodoc:all
628645
end
629646
@comment = io.read(commentLength)
630647
unless (@comment && @comment.length == commentLength)
631-
raise ZipError, "Truncated cdir zip entry header"
648+
raise ZipError, "Truncated cdir zip entry header"
632649
end
633650

634651
case @fstype

0 commit comments

Comments
 (0)