Skip to content

Commit 92e98bf

Browse files
committed
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.
1 parent f5042b8 commit 92e98bf

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

Diff for: lib/rubygems/package/tar_header.rb

+14-9
Original file line numberDiff line numberDiff line change
@@ -104,25 +104,30 @@ def self.from(stream)
104104
fields = header.unpack UNPACK_FORMAT
105105

106106
new :name => fields.shift,
107-
:mode => fields.shift.oct,
108-
:uid => fields.shift.oct,
109-
:gid => fields.shift.oct,
110-
:size => fields.shift.oct,
111-
:mtime => fields.shift.oct,
112-
:checksum => fields.shift.oct,
107+
:mode => strict_oct(fields.shift),
108+
:uid => strict_oct(fields.shift),
109+
:gid => strict_oct(fields.shift),
110+
:size => strict_oct(fields.shift),
111+
:mtime => strict_oct(fields.shift),
112+
:checksum => strict_oct(fields.shift),
113113
:typeflag => fields.shift,
114114
:linkname => fields.shift,
115115
:magic => fields.shift,
116-
:version => fields.shift.oct,
116+
:version => strict_oct(fields.shift),
117117
:uname => fields.shift,
118118
:gname => fields.shift,
119-
:devmajor => fields.shift.oct,
120-
:devminor => fields.shift.oct,
119+
:devmajor => strict_oct(fields.shift),
120+
:devminor => strict_oct(fields.shift),
121121
:prefix => fields.shift,
122122

123123
:empty => empty
124124
end
125125

126+
def self.strict_oct(str)
127+
return str.oct if str =~ /\A[0-7]*\z/
128+
raise ArgumentError, "#{str.inspect} is not an octal string"
129+
end
130+
126131
##
127132
# Creates a new TarHeader using +vals+
128133

Diff for: test/rubygems/test_gem_package_tar_header.rb

+20
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,25 @@ def test_update_checksum
143143
assert_equal '012467', @tar_header.checksum
144144
end
145145

146+
def test_from_bad_octal
147+
test_cases = [
148+
"00000006,44\000", # bogus character
149+
"00000006789\000", # non-octal digit
150+
"+0000001234\000", # positive sign
151+
"-0000001000\000", # negative sign
152+
"0x000123abc\000", # radix prefix
153+
]
154+
155+
test_cases.each do |val|
156+
header_s = @tar_header.to_s
157+
# overwrite the size field
158+
header_s[124, 12] = val
159+
io = TempIO.new header_s
160+
assert_raises ArgumentError do
161+
new_header = Gem::Package::TarHeader.from io
162+
end
163+
end
164+
end
165+
146166
end
147167

0 commit comments

Comments
 (0)