Fixed bug #37496 (FastCGI output buffer overrun)

This commit is contained in:
Dmitry Stogov 2006-05-22 09:23:01 +00:00
parent 0e5ce38c04
commit dbf6f9b81c

View file

@ -764,15 +764,17 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l
if (req->out_hdr && req->out_hdr->type != type) { if (req->out_hdr && req->out_hdr->type != type) {
close_packet(req); close_packet(req);
} }
rest = len;
#if 0 #if 0
/* Unoptinmzed, but clear version */ /* Unoptimized, but clear version */
rest = len;
while (rest > 0) { while (rest > 0) {
limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf); limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf);
if (!req->out_hdr) { if (!req->out_hdr) {
if (limit < sizeof(fcgi_header)) { if (limit < sizeof(fcgi_header)) {
fcgi_flush(req, 0); if (!fcgi_flush(req, 0)) {
return -1;
}
} }
open_packet(req, type); open_packet(req, type);
} }
@ -786,32 +788,38 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l
req->out_pos += limit; req->out_pos += limit;
rest -= limit; rest -= limit;
str += limit; str += limit;
fcgi_flush(req, 0); if (!fcgi_flush(req, 0)) {
return -1;
}
} }
} }
#else #else
/* Optinmzed version */ /* Optimized version */
if (!req->out_hdr) {
rest += sizeof(fcgi_header);
}
limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf); limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf);
if (!req->out_hdr) {
limit -= sizeof(fcgi_header);
}
if (rest < limit) { if (len < limit) {
if (!req->out_hdr) { if (!req->out_hdr) {
open_packet(req, type); open_packet(req, type);
} }
memcpy(req->out_pos, str, len); memcpy(req->out_pos, str, len);
req->out_pos += len; req->out_pos += len;
} else if (rest - limit < sizeof(req->out_buf) - sizeof(fcgi_header)) { } else if (len - limit < sizeof(req->out_buf) - sizeof(fcgi_header)) {
if (!req->out_hdr) { if (!req->out_hdr) {
open_packet(req, type); open_packet(req, type);
} }
memcpy(req->out_pos, str, limit); memcpy(req->out_pos, str, limit);
req->out_pos += limit; req->out_pos += limit;
fcgi_flush(req, 0); if (!fcgi_flush(req, 0)) {
open_packet(req, type); return -1;
memcpy(req->out_pos, str + limit, len - limit); }
req->out_pos += len - limit; if (len > limit) {
open_packet(req, type);
memcpy(req->out_pos, str + limit, len - limit);
req->out_pos += len - limit;
}
} else { } else {
int pos = 0; int pos = 0;
int pad; int pad;
@ -821,7 +829,9 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l
open_packet(req, type); open_packet(req, type);
fcgi_make_header(req->out_hdr, type, req->id, 0xfff8); fcgi_make_header(req->out_hdr, type, req->id, 0xfff8);
req->out_hdr = NULL; req->out_hdr = NULL;
fcgi_flush(req, 0); if (!fcgi_flush(req, 0)) {
return -1;
}
if (safe_write(req, str + pos, 0xfff8) != 0xfff8) { if (safe_write(req, str + pos, 0xfff8) != 0xfff8) {
req->keep = 0; req->keep = 0;
return -1; return -1;
@ -835,7 +845,9 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l
open_packet(req, type); open_packet(req, type);
fcgi_make_header(req->out_hdr, type, req->id, (len - pos) - rest); fcgi_make_header(req->out_hdr, type, req->id, (len - pos) - rest);
req->out_hdr = NULL; req->out_hdr = NULL;
fcgi_flush(req, 0); if (!fcgi_flush(req, 0)) {
return -1;
}
if (safe_write(req, str + pos, (len - pos) - rest) != (len - pos) - rest) { if (safe_write(req, str + pos, (len - pos) - rest) != (len - pos) - rest) {
req->keep = 0; req->keep = 0;
return -1; return -1;