Skip to content

Commit 6bd3675

Browse files
author
HD Moore
committed
Land rapid7#3680, add specs for Rex::MIME
2 parents 6a2a85d + fd05e63 commit 6bd3675

File tree

6 files changed

+691
-4
lines changed

6 files changed

+691
-4
lines changed

lib/rex/mime/header.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ def parse(data)
2525
next
2626
end
2727

28-
var,val = line.split(':')
29-
next if not val
28+
var, val = line.split(':', 2)
29+
next if val.nil?
30+
3031
self.headers << [ var.to_s.strip, val.to_s.strip ]
3132
prev = self.headers.length - 1
3233
end

lib/rex/mime/message.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ def initialize(data=nil)
2424
self.header.parse(head)
2525
ctype = self.header.find('Content-Type')
2626

27-
if ctype and ctype[1] and ctype[1] =~ /multipart\/mixed;\s*boundary=([^\s]+)/
27+
if ctype and ctype[1] and ctype[1] =~ /multipart\/mixed;\s*boundary="?([A-Za-z0-9'\(\)\+\_,\-\.\/:=\?^\s]+)"?/
2828
self.bound = $1
29-
3029
chunks = body.to_s.split(/--#{self.bound}(--)?\r?\n/)
3130
self.content = chunks.shift.to_s.gsub(/\s+$/, '')
3231
self.content << "\r\n" if not self.content.empty?

spec/lib/rex/mime/encoding_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# -*- coding:binary -*-
2+
require 'spec_helper'
3+
4+
require 'rex/mime'
5+
6+
describe Rex::MIME::Encoding do
7+
8+
subject do
9+
mod = Class.new
10+
mod.extend described_class
11+
mod
12+
end
13+
14+
describe "#force_crlf" do
15+
it "deletes \\r characters" do
16+
expect(subject.force_crlf("Test\r1\r")).to_not include("\\r")
17+
end
18+
19+
it "substitutes \\n characters by \\r\\n sequences" do
20+
expect(subject.force_crlf("Test 2\n")).to end_with("\r\n")
21+
end
22+
23+
it "preserves \r\n sequences" do
24+
expect(subject.force_crlf("\r\nTest 3\r\n")).to eq("\r\nTest 3\r\n")
25+
end
26+
27+
it "first deletes \\r characters, then substitutes \\n characters" do
28+
expect(subject.force_crlf("\rTest 4\r\n\r\r\n")).to eq("Test 4\r\n\r\n")
29+
end
30+
end
31+
32+
end

spec/lib/rex/mime/header_spec.rb

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# -*- coding:binary -*-
2+
require 'spec_helper'
3+
4+
require 'rex/mime'
5+
6+
describe Rex::MIME::Header do
7+
8+
let(:mime_headers_test) do
9+
<<-EOS
10+
Content-Type: text/plain;
11+
Content-Disposition: attachment; filename="test.txt"
12+
EOS
13+
end
14+
15+
subject do
16+
described_class.new
17+
end
18+
19+
describe "#initialize" do
20+
subject(:header_class) do
21+
described_class.allocate
22+
end
23+
24+
it "returns an Array" do
25+
expect(header_class.send(:initialize)).to be_a(Array)
26+
end
27+
28+
it "creates an empty headers array by default" do
29+
expect(header_class.send(:initialize)).to be_empty
30+
end
31+
32+
it "populates headers array with data from argument" do
33+
header_class.send(:initialize, mime_headers_test)
34+
expect(header_class.headers.length).to be(2)
35+
end
36+
end
37+
38+
describe "#add" do
39+
it "returns the added entry" do
40+
expect(subject.add('var', 'val')).to eq(['var', 'val'])
41+
end
42+
43+
it "adds a new entry into the headers array" do
44+
subject.add('var', 'val')
45+
expect(subject.headers.length).to eq(1)
46+
end
47+
end
48+
49+
describe "#set" do
50+
it "returns the set value" do
51+
expect(subject.set('var', 'val')).to eq('val')
52+
end
53+
54+
it "modifies the header entry if it exists" do
55+
subject.add('var', 'val')
56+
subject.set('var', 'val2')
57+
expect(subject.headers.length).to eq(1)
58+
expect(subject.headers[0]).to eq(['var', 'val2'])
59+
end
60+
61+
it "creates the header entry if doesn't exist" do
62+
subject.set('var2', 'val2')
63+
expect(subject.headers.length).to eq(1)
64+
expect(subject.headers[0]).to eq(['var2', 'val2'])
65+
end
66+
end
67+
68+
describe "#remove" do
69+
it "doesn't remove any header if index doesn't exist" do
70+
subject.add('var', 'val')
71+
subject.remove(10000)
72+
expect(subject.headers.length).to eq(1)
73+
end
74+
75+
it "doesn't remove any header if var name doesn't exist" do
76+
subject.add('var', 'val')
77+
subject.remove('var2')
78+
expect(subject.headers.length).to eq(1)
79+
end
80+
81+
it "removes header entry if index exists" do
82+
subject.add('var', 'val')
83+
subject.remove(0)
84+
expect(subject.headers.length).to eq(0)
85+
end
86+
87+
it "removes any header entry with var name" do
88+
subject.add('var', 'val')
89+
subject.add('var2', 'val2')
90+
subject.add('var', 'val3')
91+
subject.remove('var')
92+
expect(subject.headers.length).to eq(1)
93+
end
94+
end
95+
96+
describe "#find" do
97+
it "returns nil if header index doesn't exist" do
98+
expect(subject.find(1)).to be_nil
99+
end
100+
101+
it "returns nil if header var name doesn't exist" do
102+
expect(subject.find('var')).to be_nil
103+
end
104+
105+
it "returns the header at index if exists" do
106+
subject.add('var', 'val')
107+
expect(subject.find(0)).to eq(['var', 'val'])
108+
end
109+
110+
it "returns the first header with var name if exists" do
111+
subject.add('var', 'val')
112+
subject.add('var', 'val2')
113+
subject.add('var', 'val3')
114+
expect(subject.find('var')).to eq(['var', 'val'])
115+
end
116+
end
117+
118+
describe "#to_s" do
119+
it "returns empty String if there aren't headers" do
120+
expect(subject.to_s).to be_empty
121+
end
122+
123+
it "returns string with headers separated by \\r\\n sequences" do
124+
subject.add('var', 'val')
125+
subject.add('var', 'val2')
126+
subject.add('var3', 'val3')
127+
expect(subject.to_s).to eq("var: val\r\nvar: val2\r\nvar3: val3\r\n")
128+
end
129+
end
130+
131+
describe "#parse" do
132+
let(:complex_header) do
133+
'Date: Wed,20 Aug 2014 08:45:38 -0500'
134+
end
135+
136+
it "parses headers separated by lines" do
137+
subject.parse(mime_headers_test)
138+
expect(subject.headers.length).to eq(2)
139+
end
140+
141+
it "parses headers names and values separated by :" do
142+
subject.parse(mime_headers_test)
143+
expect(subject.headers).to eq([['Content-Type', 'text/plain;'], ['Content-Disposition', 'attachment; filename="test.txt"']])
144+
end
145+
146+
it "parses headers with ':' characters in the value" do
147+
subject.parse(complex_header)
148+
expect(subject.headers).to eq([['Date', 'Wed,20 Aug 2014 08:45:38 -0500']])
149+
end
150+
end
151+
end

0 commit comments

Comments
 (0)