Skip to content
Permalink
Browse files Browse the repository at this point in the history
Strictly interpret octal fields in tar headers
Any octal field that contains characters other that 0-7 will cause acn
exception to be raised.

This prevents a negative size from being set, which could cause an
infinite loop.
  • Loading branch information
segiddins committed Feb 16, 2018
1 parent f5042b8 commit 92e98bf
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
23 changes: 14 additions & 9 deletions lib/rubygems/package/tar_header.rb
Expand Up @@ -104,25 +104,30 @@ def self.from(stream)
fields = header.unpack UNPACK_FORMAT

new :name => fields.shift,
:mode => fields.shift.oct,
:uid => fields.shift.oct,
:gid => fields.shift.oct,
:size => fields.shift.oct,
:mtime => fields.shift.oct,
:checksum => fields.shift.oct,
:mode => strict_oct(fields.shift),
:uid => strict_oct(fields.shift),
:gid => strict_oct(fields.shift),
:size => strict_oct(fields.shift),
:mtime => strict_oct(fields.shift),
:checksum => strict_oct(fields.shift),
:typeflag => fields.shift,
:linkname => fields.shift,
:magic => fields.shift,
:version => fields.shift.oct,
:version => strict_oct(fields.shift),
:uname => fields.shift,
:gname => fields.shift,
:devmajor => fields.shift.oct,
:devminor => fields.shift.oct,
:devmajor => strict_oct(fields.shift),
:devminor => strict_oct(fields.shift),
:prefix => fields.shift,

:empty => empty
end

def self.strict_oct(str)
return str.oct if str =~ /\A[0-7]*\z/
raise ArgumentError, "#{str.inspect} is not an octal string"
end

##
# Creates a new TarHeader using +vals+

Expand Down
20 changes: 20 additions & 0 deletions test/rubygems/test_gem_package_tar_header.rb
Expand Up @@ -143,5 +143,25 @@ def test_update_checksum
assert_equal '012467', @tar_header.checksum
end

def test_from_bad_octal
test_cases = [
"00000006,44\000", # bogus character
"00000006789\000", # non-octal digit
"+0000001234\000", # positive sign
"-0000001000\000", # negative sign
"0x000123abc\000", # radix prefix
]

test_cases.each do |val|
header_s = @tar_header.to_s
# overwrite the size field
header_s[124, 12] = val
io = TempIO.new header_s
assert_raises ArgumentError do
new_header = Gem::Package::TarHeader.from io
end
end
end

end

0 comments on commit 92e98bf

Please sign in to comment.