290
* hit max_request_buffer we die (we'd rather reject a
291
* maliciously large request than chew up infinite memory).
292
*/
293
-static ssize_t read_request(int fd, unsigned char **out)
293
+static ssize_t read_request_eof(int fd, unsigned char **out)
294
{
295
size_t len = 0, alloc = 8192;
296
unsigned char *buf = xmalloc(alloc);
327
}
328
}
329
330
-static void inflate_request(const char *prog_name, int out, int buffer_input)
330
+static ssize_t read_request_fixed_len(int fd, ssize_t req_len, unsigned char **out)
331
+{
332
+ unsigned char *buf = NULL;
333
+ ssize_t cnt = 0;
334
+
335
+ if (max_request_buffer < req_len) {
336
+ die("request was larger than our maximum size (%lu): "
337
+ "%" PRIuMAX "; try setting GIT_HTTP_MAX_REQUEST_BUFFER",
338
+ max_request_buffer, (uintmax_t)req_len);
339
+ }
340
+
341
+ buf = xmalloc(req_len);
342
+ cnt = read_in_full(fd, buf, req_len);
343
+ if (cnt < 0) {
344
+ free(buf);
345
+ return -1;
346
+ }
347
+ *out = buf;
348
+ return cnt;
349
+}
350
+
351
+static ssize_t get_content_length(void)
352
+{
353
+ ssize_t val = -1;
354
+ const char *str = getenv("CONTENT_LENGTH");
355
+
356
+ if (str && !git_parse_ssize_t(str, &val))
357
+ die("failed to parse CONTENT_LENGTH: %s", str);
358
+ return val;
359
+}
360
+
361
+static ssize_t read_request(int fd, unsigned char **out, ssize_t req_len)
362
+{
363
+ if (req_len < 0)
364
+ return read_request_eof(fd, out);
365
+ else
366
+ return read_request_fixed_len(fd, req_len, out);
367
+}
368
+
369
+static void inflate_request(const char *prog_name, int out, int buffer_input, ssize_t req_len)
370
{
371
git_zstream stream;
372
unsigned char *full_request = NULL;
384
if (full_request)
385
n = 0; /* nothing left to read */
386
else
348
- n = read_request(0, &full_request);
387
+ n = read_request(0, &full_request, req_len);
388
stream.next_in = full_request;
389
} else {
390
n = xread(0, in_buf, sizeof(in_buf));
420
free(full_request);
421
}
422
384
-static void copy_request(const char *prog_name, int out)
423
+static void copy_request(const char *prog_name, int out, ssize_t req_len)
424
{
425
unsigned char *buf;
387
- ssize_t n = read_request(0, &buf);
426
+ ssize_t n = read_request(0, &buf, req_len);
427
if (n < 0)
428
die_errno("error reading request body");
429
write_to_child(out, buf, n, prog_name);
438
const char *host = getenv("REMOTE_ADDR");
439
int gzipped_request = 0;
440
struct child_process cld = CHILD_PROCESS_INIT;
441
+ ssize_t req_len = get_content_length();
442
443
if (encoding && !strcmp(encoding, "gzip"))
444
gzipped_request = 1;
465
466
close(1);
467
if (gzipped_request)
428
- inflate_request(argv[0], cld.in, buffer_input);
468
+ inflate_request(argv[0], cld.in, buffer_input, req_len);
469
else if (buffer_input)
430
- copy_request(argv[0], cld.in);
470
+ copy_request(argv[0], cld.in, req_len);
471
else
472
close(0);
473