From c329e9ad8a0ca2f404e43416fb41382cf1c7fb44 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Mon, 23 Jun 2014 16:15:32 -0600 Subject: [PATCH] A couple bugfixes --- CHANGES | 5 +++++ eris.c | 26 +++++++++++++++++++------- strings.c | 2 +- test.sh | 21 +++++++++++++++++++-- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 9d339eb..3f8ce1a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +4.2: + Remove some bugs in CGI's "Status:" code (reported by Alyssa Milburn). + Make extract_header_field less fragile (reported by Alyssa Milburn). + Possibly fix fake_sendfile (reported by Alyssa Milburn). + 4.1: Fix 0.9 not detected with query_string (Alyssa Milburn). diff --git a/eris.c b/eris.c index 90df5f6..5554ce4 100644 --- a/eris.c +++ b/eris.c @@ -111,7 +111,6 @@ time_t ims; #define BUFFER_SIZE 8192 -char stdout_buf[BUFFER_SIZE]; /** Log a request */ @@ -404,9 +403,20 @@ cgi_parent(int cin, int cout, int passthru) dolog(302, 0); exit(0); } else if (! strcasecmp(cgiheader, "Status")) { - char *txt = val + 4; + char *txt; - code = atoi(val); + if (val) { + code = (int)strtol(val, &txt, 10); + } else { + code = 0; + } + if (code < 100) { + header(500, "Internal Error"); + printf("CGI returned Status: %d\n", code); + dolog(500, 0); + exit(0); + } + for (; *txt == ' '; txt += 1); header(code, txt); } else { header(200, "OK"); @@ -451,7 +461,7 @@ cgi_parent(int cin, int cout, int passthru) } fflush(stdout); - dolog(200, size); + dolog(code, size); } void @@ -500,11 +510,11 @@ serve_cgi(char *relpath) * Main HTTPd */ -void +ssize_t fake_sendfile(int out_fd, int in_fd, off_t *offset, size_t count) { char buf[BUFFER_SIZE]; - ssize_t l, m; + ssize_t l, sent; /* is mmap quicker? does it matter? */ if (-1 == lseek(in_fd, *offset, SEEK_SET)) { @@ -529,6 +539,8 @@ fake_sendfile(int out_fd, int in_fd, off_t *offset, size_t count) } l -= m; } + + return l; } void @@ -580,7 +592,7 @@ serve_file(int fd, char *filename, struct stat *st) alarm(SENDFILE_TIMEOUT); sent = sendfile(1, fd, &range_start, count); if (-1 == sent) { - fake_sendfile(1, fd, &range_start, count); + sent = fake_sendfile(1, fd, &range_start, count); } remain -= sent; } diff --git a/strings.c b/strings.c index f13670b..a9f254c 100644 --- a/strings.c +++ b/strings.c @@ -75,7 +75,7 @@ extract_header_field(char *buf, char **val, int cgi) } } - for (; (buf[len-1] == '\n') || (buf[len-1] == '\r'); len -= 1); + for (; (len > 0) && ((buf[len-1] == '\n') || (buf[len-1] == '\r')); len -= 1); buf[len] = 0; return len; diff --git a/test.sh b/test.sh index 403979a..3b51b89 100755 --- a/test.sh +++ b/test.sh @@ -64,7 +64,18 @@ chmod +x default/redir.cgi cat <<'EOD' > default/status.cgi #! /bin/sh -echo "Status: 300 wat" +case "$PATH_INFO" in +/empty) + echo "Status" + exit 0 + ;; +/nostat) + echo "Status: " + ;; +*) + echo "Status: 300 wat" + ;; +esac echo "Merf: merf" echo echo "james" @@ -240,7 +251,13 @@ title "Redirect" printf 'GET /redir.cgi HTTP/1.0\r\n\r\n' | $HTTPD_CGI 2>/dev/null | grep -Fq 'Location: http://example.com/froot' && pass || fail title "Status" -printf 'GET /status.cgi HTTP/1.0\r\n\r\n' | $HTTPD_CGI 2>/dev/null | d | grep -q '^HTTP/1.0 300 wat#%' && pass || fail +printf 'GET /status.cgi HTTP/1.0\r\n\r\n' | $HTTPD_CGI 2>&1 | d | grep -q '^HTTP/1.0 300 wat#%.*.null. 300 6' && pass || fail + +title "Status bug" +printf 'GET /status.cgi/empty HTTP/1.0\r\n\r\n' | $HTTPD_CGI 2>/dev/null | d | grep -q '^HTTP/1.0 500 ' && pass || fail + +title "No status" +printf 'GET /status.cgi/nostat HTTP/1.0\r\n\r\n' | $HTTPD_CGI 2>/dev/null | d | grep -q '^HTTP/1.0 500 ' && pass || fail H "Timeouts"