validate return values from strtol, strtoul (fixes #2564)

From: Glenn Strauss <gstrauss@gluelogic.com>

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3122 152afb58-edef-0310-8abb-c4023f1b3aa9
This commit is contained in:
Glenn Strauss 2016-03-26 10:58:49 +00:00 committed by Stefan Bühler
parent 733ce38203
commit f5453290b7
7 changed files with 54 additions and 17 deletions

View File

@ -9,6 +9,8 @@
#include "array.h"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
@ -267,8 +269,16 @@ value(A) ::= STRING(B). {
}
value(A) ::= INTEGER(B). {
char *endptr;
A = (data_unset *)data_integer_init();
((data_integer *)(A))->value = strtol(B->ptr, NULL, 10);
errno = 0;
((data_integer *)(A))->value = strtol(B->ptr, &endptr, 10);
/* skip trailing whitespace */
if (endptr != B->ptr) while (isspace(*endptr)) endptr++;
if (0 != errno || *endptr != '\0') {
fprintf(stderr, "error parsing number: '%s'\n", B->ptr);
ctx->ok = 0;
}
buffer_free(B);
B = NULL;
}

View File

@ -307,8 +307,13 @@ static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buff
break;
case 6:
if (0 == strncasecmp(key, "Status", key_len)) {
con->http_status = strtol(value, NULL, 10);
con->parsed_response |= HTTP_STATUS;
int status = strtol(value, NULL, 10);
if (status >= 100 && status < 1000) {
con->http_status = status;
con->parsed_response |= HTTP_STATUS;
} else {
con->http_status = 502;
}
}
break;
case 8:
@ -324,7 +329,7 @@ static int cgi_response_parse(server *srv, connection *con, plugin_data *p, buff
break;
case 14:
if (0 == strncasecmp(key, "Content-Length", key_len)) {
con->response.content_length = strtol(value, NULL, 10);
con->response.content_length = strtoul(value, NULL, 10);
con->parsed_response |= HTTP_CONTENT_LENGTH;
}
break;

View File

@ -245,6 +245,8 @@ int f_memcache_get_long(lua_State *L) {
char *value;
const char *key;
memcached_st *memc;
char *endptr;
long v;
if (!lua_islightuserdata(L, lua_upvalueindex(1))) {
lua_pushstring(L, "where is my userdata ?");
@ -264,7 +266,13 @@ int f_memcache_get_long(lua_State *L) {
return 1;
}
lua_pushinteger(L, strtol(value, NULL, 10));
errno = 0;
v = strtol(value, &endptr, 10);
if (0 == errno && *endptr == '\0') {
lua_pushinteger(L, v);
} else {
lua_pushnil(L);
}
free(value);

View File

@ -2133,8 +2133,13 @@ static int fcgi_response_parse(server *srv, connection *con, plugin_data *p, buf
break;
case 6:
if (0 == strncasecmp(key, "Status", key_len)) {
con->http_status = strtol(value, NULL, 10);
con->parsed_response |= HTTP_STATUS;
int status = strtol(value, NULL, 10);
if (status >= 100 && status < 1000) {
con->http_status = status;
con->parsed_response |= HTTP_STATUS;
} else {
con->http_status = 502;
}
}
break;
case 8:
@ -2236,7 +2241,7 @@ range_success: ;
break;
case 14:
if (0 == strncasecmp(key, "Content-Length", key_len)) {
con->response.content_length = strtol(value, NULL, 10);
con->response.content_length = strtoul(value, NULL, 10);
con->parsed_response |= HTTP_CONTENT_LENGTH;
if (con->response.content_length < 0) con->response.content_length = 0;

View File

@ -552,7 +552,7 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
if (*key) {
http_response_status = (int) strtol(key, NULL, 10);
if (http_response_status <= 0) http_response_status = 502;
if (http_response_status < 100 || http_response_status >= 1000) http_response_status = 502;
} else {
http_response_status = 502;
}
@ -595,7 +595,7 @@ static int proxy_response_parse(server *srv, connection *con, plugin_data *p, bu
break;
case 14:
if (0 == strncasecmp(key, "Content-Length", key_len)) {
con->response.content_length = strtol(value, NULL, 10);
con->response.content_length = strtoul(value, NULL, 10);
con->parsed_response |= HTTP_CONTENT_LENGTH;
}
break;

View File

@ -1713,8 +1713,13 @@ static int scgi_response_parse(server *srv, connection *con, plugin_data *p, buf
break;
case 6:
if (0 == strncasecmp(key, "Status", key_len)) {
con->http_status = strtol(value, NULL, 10);
con->parsed_response |= HTTP_STATUS;
int status = strtol(value, NULL, 10);
if (status >= 100 && status < 1000) {
con->http_status = status;
con->parsed_response |= HTTP_STATUS;
} else {
con->http_status = 502;
}
}
break;
case 8:
@ -1730,7 +1735,7 @@ static int scgi_response_parse(server *srv, connection *con, plugin_data *p, buf
break;
case 14:
if (0 == strncasecmp(key, "Content-Length", key_len)) {
con->response.content_length = strtol(value, NULL, 10);
con->response.content_length = strtoul(value, NULL, 10);
con->parsed_response |= HTTP_CONTENT_LENGTH;
}
break;

View File

@ -1204,7 +1204,7 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
buffer *b;
DIR *dir;
data_string *ds;
int depth = -1;
int depth = -1; /* (Depth: infinity) */
struct stat st;
buffer *prop_200;
buffer *prop_404;
@ -1218,9 +1218,13 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
/* PROPFIND need them */
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Depth"))) {
depth = strtol(ds->value->ptr, NULL, 10);
}
if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Depth")) && 1 == buffer_string_length(ds->value)) {
if ('0' == *ds->value->ptr) {
depth = 0;
} else if ('1' == *ds->value->ptr) {
depth = 1;
}
} /* else treat as Depth: infinity */
switch (con->request.http_method) {
case HTTP_METHOD_PROPFIND: