Bug 1861751 Part 4: Add tests of invalid buffers in various usages. r=webgpu-reviewer...
[gecko.git] / toolkit / crashreporter / breakpad-patches / 09-json-upload.patch
blob8ad73bc681de0b113b1ec2919b861ffe1d81dc14
1 diff --git a/src/common/linux/http_upload.cc b/src/common/linux/http_upload.cc
2 index 702526af..0a1019dd 100644
3 --- a/src/common/linux/http_upload.cc
4 +++ b/src/common/linux/http_upload.cc
5 @@ -55,7 +55,7 @@ static const char kUserAgent[] = "Breakpad/1.0 (Linux)";
7 // static
8 bool HTTPUpload::SendRequest(const string &url,
9 - const map<string, string> &parameters,
10 + const string &parameters,
11 const map<string, string> &files,
12 const string &proxy,
13 const string &proxy_user_pwd,
14 @@ -66,9 +66,6 @@ bool HTTPUpload::SendRequest(const string &url,
15 if (response_code != NULL)
16 *response_code = 0;
18 - if (!CheckParameters(parameters))
19 - return false;
21 // We may have been linked statically; if curl_easy_init is in the
22 // current binary, no need to search for a dynamic version.
23 void* curl_lib = dlopen(NULL, RTLD_NOW);
24 @@ -133,14 +130,14 @@ bool HTTPUpload::SendRequest(const string &url,
25 // Add form data.
26 CURLFORMcode (*curl_formadd)(struct curl_httppost **, struct curl_httppost **, ...);
27 *(void**) (&curl_formadd) = dlsym(curl_lib, "curl_formadd");
28 - map<string, string>::const_iterator iter = parameters.begin();
29 - for (; iter != parameters.end(); ++iter)
30 - (*curl_formadd)(&formpost, &lastptr,
31 - CURLFORM_COPYNAME, iter->first.c_str(),
32 - CURLFORM_COPYCONTENTS, iter->second.c_str(),
33 - CURLFORM_END);
34 + (*curl_formadd)(&formpost, &lastptr, CURLFORM_COPYNAME, "extra",
35 + CURLFORM_BUFFER, "extra.json", CURLFORM_BUFFERPTR,
36 + parameters.c_str(), CURLFORM_BUFFERLENGTH,
37 + parameters.length(), CURLFORM_CONTENTTYPE, "application/json",
38 + CURLFORM_END);
40 // Add form files.
41 + map<string, string>::const_iterator iter = files.begin();
42 for (iter = files.begin(); iter != files.end(); ++iter) {
43 (*curl_formadd)(&formpost, &lastptr,
44 CURLFORM_COPYNAME, iter->first.c_str(),
45 @@ -210,21 +207,4 @@ bool HTTPUpload::CheckCurlLib(void* curl_lib) {
46 dlsym(curl_lib, "curl_easy_setopt");
49 -// static
50 -bool HTTPUpload::CheckParameters(const map<string, string> &parameters) {
51 - for (map<string, string>::const_iterator pos = parameters.begin();
52 - pos != parameters.end(); ++pos) {
53 - const string &str = pos->first;
54 - if (str.size() == 0)
55 - return false; // disallow empty parameter names
56 - for (unsigned int i = 0; i < str.size(); ++i) {
57 - int c = str[i];
58 - if (c < 32 || c == '"' || c > 127) {
59 - return false;
60 - }
61 - }
62 - }
63 - return true;
66 } // namespace google_breakpad
67 diff --git a/src/common/linux/http_upload.h b/src/common/linux/http_upload.h
68 index bc1d5d57..95dedebc 100644
69 --- a/src/common/linux/http_upload.h
70 +++ b/src/common/linux/http_upload.h
71 @@ -29,7 +29,7 @@
73 // HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST
74 // request using libcurl. It currently supports requests that contain
75 -// a set of string parameters (key/value pairs), and a file to upload.
76 +// parameters encoded in a JSON string, and a file to upload.
78 #ifndef COMMON_LINUX_HTTP_UPLOAD_H__
79 #define COMMON_LINUX_HTTP_UPLOAD_H__
80 @@ -49,8 +49,7 @@ class HTTPUpload {
81 // request to the given URL.
82 // Each key in |files| is the name of the file part of the request
83 // (i.e. it corresponds to the name= attribute on an <input type="file">.
84 - // Parameter names must contain only printable ASCII characters,
85 - // and may not contain a quote (") character.
86 + // Parameters are specified as a JSON-encoded string in |parameters|.
87 // Only HTTP(S) URLs are currently supported. Returns true on success.
88 // If the request is successful and response_body is non-NULL,
89 // the response body will be returned in response_body.
90 @@ -59,7 +58,7 @@ class HTTPUpload {
91 // If the send fails, a description of the error will be
92 // returned in error_description.
93 static bool SendRequest(const string &url,
94 - const map<string, string> &parameters,
95 + const string &parameters,
96 const map<string, string> &files,
97 const string &proxy,
98 const string &proxy_user_pwd,
99 @@ -69,11 +68,6 @@ class HTTPUpload {
100 string *error_description);
102 private:
103 - // Checks that the given list of parameters has only printable
104 - // ASCII characters in the parameter name, and does not contain
105 - // any quote (") characters. Returns true if so.
106 - static bool CheckParameters(const map<string, string> &parameters);
108 // Checks the curl_lib parameter points to a valid curl lib.
109 static bool CheckCurlLib(void* curl_lib);
111 diff --git a/src/common/mac/HTTPMultipartUpload.h b/src/common/mac/HTTPMultipartUpload.h
112 index 42e8fed3..0cea733e 100644
113 --- a/src/common/mac/HTTPMultipartUpload.h
114 +++ b/src/common/mac/HTTPMultipartUpload.h
115 @@ -37,7 +37,7 @@
116 @interface HTTPMultipartUpload : NSObject {
117 @protected
118 NSURL *url_; // The destination URL (STRONG)
119 - NSDictionary *parameters_; // The key/value pairs for sending data (STRONG)
120 + NSMutableString *parameters_; // The JSON payload for sending data (STRONG)
121 NSMutableDictionary *files_; // Dictionary of name/file-path (STRONG)
122 NSString *boundary_; // The boundary string (STRONG)
123 NSHTTPURLResponse *response_; // The response from the send (STRONG)
124 @@ -47,8 +47,8 @@
126 - (NSURL *)URL;
128 -- (void)setParameters:(NSDictionary *)parameters;
129 -- (NSDictionary *)parameters;
130 +- (void)setParameters:(NSMutableString *)parameters;
131 +- (NSMutableString *)parameters;
133 - (void)addFileAtPath:(NSString *)path name:(NSString *)name;
134 - (void)addFileContents:(NSData *)data name:(NSString *)name;
135 diff --git a/src/common/mac/HTTPMultipartUpload.m b/src/common/mac/HTTPMultipartUpload.m
136 index a3677f25..d2480493 100644
137 --- a/src/common/mac/HTTPMultipartUpload.m
138 +++ b/src/common/mac/HTTPMultipartUpload.m
139 @@ -93,7 +93,7 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
140 - (NSString *)multipartBoundary;
141 // Each of the following methods will append the starting multipart boundary,
142 // but not the ending one.
143 -- (NSData *)formDataForKey:(NSString *)key value:(NSString *)value;
144 +- (NSData *)formDataForJSON:(NSString *)json;
145 - (NSData *)formDataForFileContents:(NSData *)contents name:(NSString *)name;
146 - (NSData *)formDataForFile:(NSString *)file name:(NSString *)name;
147 @end
148 @@ -110,13 +110,16 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
151 //=============================================================================
152 -- (NSData *)formDataForKey:(NSString *)key value:(NSString *)value {
153 - NSString *escaped = PercentEncodeNSString(key);
154 - NSString *fmt =
155 - @"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n";
156 - NSString *form = [NSString stringWithFormat:fmt, boundary_, escaped, value];
157 +- (NSData *)formDataForJSON:(NSString *)json {
158 + NSMutableData *data = [NSMutableData data];
159 + NSString *fmt = @"--%@\r\nContent-Disposition: form-data; name=\"extra\"; "
160 + "filename=\"extra.json\"\r\nContent-Type: application/json\r\n\r\n";
161 + NSString *form = [NSString stringWithFormat:fmt, boundary_];
163 + [data appendData:[form dataUsingEncoding:NSUTF8StringEncoding]];
164 + [data appendData:[json dataUsingEncoding:NSUTF8StringEncoding]];
166 - return [form dataUsingEncoding:NSUTF8StringEncoding];
167 + return data;
170 //=============================================================================
171 @@ -171,15 +174,15 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
174 //=============================================================================
175 -- (void)setParameters:(NSDictionary *)parameters {
176 +- (void)setParameters:(NSMutableString *)parameters {
177 if (parameters != parameters_) {
178 [parameters_ release];
179 - parameters_ = [parameters copy];
180 + parameters_ = [parameters mutableCopy];
184 //=============================================================================
185 -- (NSDictionary *)parameters {
186 +- (NSMutableString *)parameters {
187 return parameters_;
190 @@ -210,16 +213,8 @@ static NSData *SendSynchronousNSURLRequest(NSURLRequest *req,
191 [req setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",
192 boundary_] forHTTPHeaderField:@"Content-type"];
194 - // Add any parameters to the message
195 - NSArray *parameterKeys = [parameters_ allKeys];
196 - NSString *key;
198 - NSInteger count = [parameterKeys count];
199 - for (NSInteger i = 0; i < count; ++i) {
200 - key = [parameterKeys objectAtIndex:i];
201 - [postBody appendData:[self formDataForKey:key
202 - value:[parameters_ objectForKey:key]]];
204 + // Add JSON parameters to the message
205 + [postBody appendData:[self formDataForJSON:parameters_]];
207 // Add any files to the message
208 NSArray *fileNames = [files_ allKeys];
209 diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc
210 index b0cc9078..5df17e1a 100644
211 --- a/src/common/windows/http_upload.cc
212 +++ b/src/common/windows/http_upload.cc
213 @@ -141,23 +141,6 @@ namespace {
214 return rv;
217 - bool CheckParameters(const map<wstring, wstring> &parameters) {
218 - for (map<wstring, wstring>::const_iterator pos = parameters.begin();
219 - pos != parameters.end(); ++pos) {
220 - const wstring &str = pos->first;
221 - if (str.size() == 0) {
222 - return false; // disallow empty parameter names
224 - for (unsigned int i = 0; i < str.size(); ++i) {
225 - wchar_t c = str[i];
226 - if (c < 32 || c == '"' || c > 127) {
227 - return false;
231 - return true;
234 // Converts a UTF16 string to UTF8.
235 string WideToUTF8(const wstring &wide) {
236 return WideToMBCP(wide, CP_UTF8);
237 @@ -390,7 +373,7 @@ namespace {
238 return true;
241 - bool GenerateRequestBody(const map<wstring, wstring> &parameters,
242 + bool GenerateRequestBody(const string &parameters,
243 const map<wstring, wstring> &files,
244 const wstring &boundary,
245 string *request_body) {
246 @@ -401,14 +384,19 @@ namespace {
248 request_body->clear();
250 - // Append each of the parameter pairs as a form-data part
251 - for (map<wstring, wstring>::const_iterator pos = parameters.begin();
252 - pos != parameters.end(); ++pos) {
253 - request_body->append("--" + boundary_str + "\r\n");
254 - request_body->append("Content-Disposition: form-data; name=\"" +
255 - WideToUTF8(pos->first) + "\"\r\n\r\n" +
256 - WideToUTF8(pos->second) + "\r\n");
257 + // Append the extra data as a single JSON form entry
258 + request_body->append("--" + boundary_str + "\r\n");
259 + request_body->append(
260 + "Content-Disposition: form-data; "
261 + "name=\"extra\"; "
262 + "filename=\"extra.json\"\r\n");
263 + request_body->append("Content-Type: application/json\r\n");
264 + request_body->append("\r\n");
266 + if (!parameters.empty()) {
267 + request_body->append(parameters);
269 + request_body->append("\r\n");
271 // Now append each upload file as a binary (octet-stream) part
272 for (map<wstring, wstring>::const_iterator pos = files.begin();
273 @@ -463,16 +451,11 @@ namespace google_breakpad {
275 bool HTTPUpload::SendMultipartPostRequest(
276 const wstring& url,
277 - const map<wstring, wstring>& parameters,
278 + const string& parameters,
279 const map<wstring, wstring>& files,
280 int* timeout_ms,
281 wstring* response_body,
282 int* response_code) {
283 - // TODO(bryner): support non-ASCII parameter names
284 - if (!CheckParameters(parameters)) {
285 - return false;
288 wstring boundary = GenerateMultipartBoundary();
289 wstring content_type_header = GenerateMultipartPostRequestHeader(boundary);
291 diff --git a/src/common/windows/http_upload.h b/src/common/windows/http_upload.h
292 index 57e526e3..1e47f582 100644
293 --- a/src/common/windows/http_upload.h
294 +++ b/src/common/windows/http_upload.h
295 @@ -29,7 +29,7 @@
297 // HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST
298 // request using wininet. It currently supports requests that contain
299 -// a set of string parameters (key/value pairs), and a file to upload.
300 +// parameters encoded in a JSON string, and a file to upload.
302 #ifndef COMMON_WINDOWS_HTTP_UPLOAD_H_
303 #define COMMON_WINDOWS_HTTP_UPLOAD_H_
304 @@ -45,9 +45,9 @@
306 namespace google_breakpad {
308 +using std::map;
309 using std::string;
310 using std::wstring;
311 -using std::map;
313 class HTTPUpload {
314 public:
315 @@ -81,8 +81,7 @@ class HTTPUpload {
316 // request to the given URL.
317 // Each key in |files| is the name of the file part of the request
318 // (i.e. it corresponds to the name= attribute on an <input type="file">.
319 - // Parameter names must contain only printable ASCII characters,
320 - // and may not contain a quote (") character.
321 + // Parameters are specified as a JSON-encoded string in |parameters|.
322 // Only HTTP(S) URLs are currently supported. Returns true on success.
323 // If the request is successful and response_body is non-NULL,
324 // the response body will be returned in response_body.
325 @@ -90,7 +89,7 @@ class HTTPUpload {
326 // received (or 0 if the request failed before getting an HTTP response).
327 static bool SendMultipartPostRequest(
328 const wstring& url,
329 - const map<wstring, wstring>& parameters,
330 + const string& parameters,
331 const map<wstring, wstring>& files,
332 int *timeout_ms,
333 wstring *response_body,