Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Side by Side Diff: chrome/browser/extensions/api/web_request/form_data_parser_unittest.cc

Issue 584163004: Move web_request directory to //extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase again Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/logging.h"
7 #include "base/strings/string_piece.h"
8 #include "chrome/browser/extensions/api/web_request/form_data_parser.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace extensions {
12
13 namespace {
14
15 // Attempts to create a parser corresponding to the |content_type_header|.
16 // On success, returns the parser.
17 scoped_ptr<FormDataParser> InitParser(const std::string& content_type_header) {
18 scoped_ptr<FormDataParser> parser(
19 FormDataParser::CreateFromContentTypeHeader(&content_type_header));
20 if (parser.get() == NULL)
21 return scoped_ptr<FormDataParser>();
22 return parser.Pass();
23 }
24
25 // Attempts to run the parser corresponding to the |content_type_header|
26 // on the source represented by the concatenation of blocks from |bytes|.
27 // On success, returns true and the parsed |output|, else false.
28 // Parsed |output| has names on even positions (0, 2, ...), values on odd ones.
29 bool RunParser(const std::string& content_type_header,
30 const std::vector<const base::StringPiece*>& bytes,
31 std::vector<std::string>* output) {
32 DCHECK(output);
33 output->clear();
34 scoped_ptr<FormDataParser> parser(InitParser(content_type_header));
35 if (!parser.get())
36 return false;
37 FormDataParser::Result result;
38 for (size_t block = 0; block < bytes.size(); ++block) {
39 if (!parser->SetSource(*(bytes[block])))
40 return false;
41 while (parser->GetNextNameValue(&result)) {
42 output->push_back(result.name());
43 output->push_back(result.value());
44 }
45 }
46 return parser->AllDataReadOK();
47 }
48
49 // Attempts to run the parser corresponding to the |content_type_header|
50 // on the source represented by the concatenation of blocks from |bytes|.
51 // Checks that the parser fails parsing.
52 bool CheckParserFails(const std::string& content_type_header,
53 const std::vector<const base::StringPiece*>& bytes) {
54 std::vector<std::string> output;
55 scoped_ptr<FormDataParser> parser(InitParser(content_type_header));
56 if (!parser.get())
57 return false;
58 FormDataParser::Result result;
59 for (size_t block = 0; block < bytes.size(); ++block) {
60 if (!parser->SetSource(*(bytes[block])))
61 break;
62 while (parser->GetNextNameValue(&result)) {
63 output.push_back(result.name());
64 output.push_back(result.value());
65 }
66 }
67 return !parser->AllDataReadOK();
68 }
69
70 } // namespace
71
72 TEST(WebRequestFormDataParserTest, Parsing) {
73 // We verify that POST data parsers cope with various formats of POST data.
74 // Construct the test data.
75 const std::string kBoundary = "THIS_IS_A_BOUNDARY";
76 const std::string kBlockStr1 =
77 std::string("--") + kBoundary +
78 "\r\n"
79 "Content-Disposition: form-data; name=\"text\"\r\n"
80 "\r\n"
81 "test\rtext\nwith non-CRLF line breaks\r\n"
82 "--" +
83 kBoundary +
84 "\r\n"
85 "Content-Disposition: form-data; name=\"file\"; filename=\"test\"\r\n"
86 "Content-Type: application/octet-stream\r\n"
87 "\r\n";
88 const std::string kBlockStr2 =
89 std::string("\r\n--") + kBoundary +
90 "\r\n"
91 "Content-Disposition: form-data; name=\"password\"\r\n"
92 "\r\n"
93 "test password\r\n"
94 "--" +
95 kBoundary +
96 "\r\n"
97 "Content-Disposition: form-data; name=\"radio\"\r\n"
98 "\r\n"
99 "Yes\r\n"
100 "--" +
101 kBoundary +
102 "\r\n"
103 "Content-Disposition: form-data; name=\"check\"\r\n"
104 "\r\n"
105 "option A\r\n"
106 "--" +
107 kBoundary +
108 "\r\n"
109 "Content-Disposition: form-data; name=\"check\"\r\n"
110 "\r\n"
111 "option B\r\n"
112 "--" +
113 kBoundary +
114 "\r\n"
115 "Content-Disposition: form-data; name=\"txtarea\"\r\n"
116 "\r\n"
117 "Some text.\r\n"
118 "Other.\r\n"
119 "\r\n"
120 "--" +
121 kBoundary +
122 "\r\n"
123 "Content-Disposition: form-data; name=\"select\"\r\n"
124 "\r\n"
125 "one\r\n"
126 "--" +
127 kBoundary + "--";
128 // POST data input.
129 const std::string kBigBlock = kBlockStr1 + kBlockStr2;
130 const std::string kUrlEncodedBlock =
131 "text=test%0Dtext%0Awith+non-CRLF+line+breaks"
132 "&file=test&password=test+password&radio=Yes&check=option+A"
133 "&check=option+B&txtarea=Some+text.%0D%0AOther.%0D%0A&select=one";
134 const base::StringPiece kMultipartBytes(kBigBlock);
135 const base::StringPiece kMultipartBytesSplit1(kBlockStr1);
136 const base::StringPiece kMultipartBytesSplit2(kBlockStr2);
137 const base::StringPiece kUrlEncodedBytes(kUrlEncodedBlock);
138 const std::string kPlainBlock = "abc";
139 const base::StringPiece kTextPlainBytes(kPlainBlock);
140 // Headers.
141 const std::string kUrlEncoded = "application/x-www-form-urlencoded";
142 const std::string kTextPlain = "text/plain";
143 const std::string kMultipart =
144 std::string("multipart/form-data; boundary=") + kBoundary;
145 // Expected output.
146 const char* kPairs[] = {
147 "text", "test\rtext\nwith non-CRLF line breaks",
148 "file", "test",
149 "password", "test password",
150 "radio", "Yes",
151 "check", "option A",
152 "check", "option B",
153 "txtarea", "Some text.\r\nOther.\r\n",
154 "select", "one"
155 };
156 const std::vector<std::string> kExpected(kPairs, kPairs + arraysize(kPairs));
157
158 std::vector<const base::StringPiece*> input;
159 std::vector<std::string> output;
160
161 // First test: multipart POST data in one lump.
162 input.push_back(&kMultipartBytes);
163 EXPECT_TRUE(RunParser(kMultipart, input, &output));
164 EXPECT_EQ(kExpected, output);
165
166 // Second test: multipart POST data in several lumps.
167 input.clear();
168 input.push_back(&kMultipartBytesSplit1);
169 input.push_back(&kMultipartBytesSplit2);
170 EXPECT_TRUE(RunParser(kMultipart, input, &output));
171 EXPECT_EQ(kExpected, output);
172
173 // Third test: URL-encoded POST data.
174 input.clear();
175 input.push_back(&kUrlEncodedBytes);
176 EXPECT_TRUE(RunParser(kUrlEncoded, input, &output));
177 EXPECT_EQ(kExpected, output);
178
179 // Fourth test: text/plain POST data in one lump.
180 input.clear();
181 input.push_back(&kTextPlainBytes);
182 // This should fail, text/plain is ambiguous and thus unparseable.
183 EXPECT_FALSE(RunParser(kTextPlain, input, &output));
184 }
185
186 TEST(WebRequestFormDataParserTest, MalformedPayload) {
187 // We verify that POST data parsers reject malformed data.
188 // Construct the test data.
189 const std::string kBoundary = "THIS_IS_A_BOUNDARY";
190 const std::string kBlockStr =
191 std::string("--") + kBoundary +
192 "\r\n"
193 "Content-Disposition: form-data; name=\"text\"\r\n"
194 "\r\n"
195 "test\rtext\nwith non-CRLF line breaks\r\n"
196 "-" +
197 kBoundary +
198 "\r\n" /* Missing '-'. */
199 "Content-Disposition: form-data; name=\"file\"; filename=\"test\"\r\n"
200 "Content-Type: application/octet-stream\r\n"
201 /* Two CRLF missing. */
202 "--" +
203 kBoundary +
204 "\r\n"
205 "Content-Disposition: form-data; name=\"select\"\r\n"
206 "\r\n"
207 "one\r\n"
208 "--" +
209 kBoundary + "-" /* Missing '-' at the end. */;
210 // POST data input.
211 // The following block is corrupted -- contains a "==" substring.
212 const std::string kUrlEncodedBlock =
213 "text=test%0Dtext%0Awith+non-CRLF+line+breaks"
214 "&file==test&password=test+password&radio=Yes&check=option+A"
215 "&check=option+B&txtarea=Some+text.%0D%0AOther.%0D%0A&select=one";
216 const base::StringPiece kMultipartBytes(kBlockStr);
217 const base::StringPiece kMultipartBytesEmpty("");
218 const base::StringPiece kUrlEncodedBytes(kUrlEncodedBlock);
219 const base::StringPiece kUrlEncodedBytesEmpty("");
220 // Headers.
221 const std::string kUrlEncoded = "application/x-www-form-urlencoded";
222 const std::string kMultipart =
223 std::string("multipart/form-data; boundary=") + kBoundary;
224
225 std::vector<const base::StringPiece*> input;
226
227 // First test: malformed multipart POST data.
228 input.push_back(&kMultipartBytes);
229 EXPECT_TRUE(CheckParserFails(kMultipart, input));
230
231 // Second test: empty multipart POST data.
232 input.clear();
233 input.push_back(&kMultipartBytesEmpty);
234 EXPECT_TRUE(CheckParserFails(kMultipart, input));
235
236 // Third test: malformed URL-encoded POST data.
237 input.clear();
238 input.push_back(&kUrlEncodedBytes);
239 EXPECT_TRUE(CheckParserFails(kUrlEncoded, input));
240
241 // Fourth test: empty URL-encoded POST data. Note that an empty string is a
242 // valid url-encoded value, so this should parse correctly.
243 std::vector<std::string> output;
244 input.clear();
245 input.push_back(&kUrlEncodedBytesEmpty);
246 EXPECT_TRUE(RunParser(kUrlEncoded, input, &output));
247 EXPECT_EQ(0u, output.size());
248 }
249
250 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698