Commit e60db3c7 by Matt Burke

Revise custom header error messages

If the header doesn't look like a header (e.g. if it doesn't have a ":"
or if it has newlines), report "custom HTTP header '%s' is malformed".

If the header has the same name as a header already set by libgit2 (e.g.
"Host"), report "HTTP header '%s' is already set by libgit2".
parent 63cc5723
...@@ -66,57 +66,55 @@ static int git_smart__set_callbacks( ...@@ -66,57 +66,55 @@ static int git_smart__set_callbacks(
return 0; return 0;
} }
static char *forbidden_custom_headers[] = { int http_header_name_length(const char *http_header)
"User-Agent", {
"Host", const char *colon = strchr(http_header, ':');
"Accept", if (!colon)
"Content-Type", return 0;
"Transfer-Encoding", return colon - http_header;
"Content-Length", }
};
bool is_valid_custom_header(const char *custom_header) bool is_malformed_http_header(const char *http_header)
{ {
const char *c; const char *c;
int name_len; int name_len;
unsigned long i;
// Disallow \r and \n // Disallow \r and \n
c = strchr(custom_header, '\r'); c = strchr(http_header, '\r');
if (c != NULL) if (c)
return false; return true;
c = strchr(custom_header, '\n'); c = strchr(http_header, '\n');
if (c != NULL) if (c)
return false; return true;
// Require a header name followed by : // Require a header name followed by :
c = strchr(custom_header, ':'); name_len = http_header_name_length(http_header);
if (c == NULL)
return false;
name_len = c - custom_header;
if (name_len < 1) if (name_len < 1)
return false; return true;
// Disallow headers that we set
for (i = 0; i < ARRAY_SIZE(forbidden_custom_headers); i++)
if (strncmp(forbidden_custom_headers[i], custom_header, name_len) == 0)
return false;
return true; return false;
} }
const char *find_invalid_custom_header(const git_strarray *custom_headers) static char *forbidden_custom_headers[] = {
{ "User-Agent",
size_t i; "Host",
"Accept",
"Content-Type",
"Transfer-Encoding",
"Content-Length",
};
if (custom_headers == NULL || custom_headers->count == 0) bool is_forbidden_custom_header(const char *custom_header)
return NULL; {
unsigned long i;
int name_len = http_header_name_length(custom_header);
for (i = 0; i < custom_headers->count; i++) // Disallow headers that we set
if (!is_valid_custom_header(custom_headers->strings[i])) for (i = 0; i < ARRAY_SIZE(forbidden_custom_headers); i++)
return custom_headers->strings[i]; if (strncmp(forbidden_custom_headers[i], custom_header, name_len) == 0)
return true;
return NULL; return false;
} }
static int git_smart__set_custom_headers( static int git_smart__set_custom_headers(
...@@ -124,11 +122,17 @@ static int git_smart__set_custom_headers( ...@@ -124,11 +122,17 @@ static int git_smart__set_custom_headers(
const git_strarray *custom_headers) const git_strarray *custom_headers)
{ {
transport_smart *t = (transport_smart *)transport; transport_smart *t = (transport_smart *)transport;
const char *invalid_header = find_invalid_custom_header(custom_headers); size_t i;
if (invalid_header != NULL) { for (i = 0; i < custom_headers->count; i++) {
giterr_set(GITERR_INVALID, "Illegal HTTP header '%s'", invalid_header); if (is_malformed_http_header(custom_headers->strings[i])) {
return -1; giterr_set(GITERR_INVALID, "custom HTTP header '%s' is malformed", custom_headers->strings[i]);
return -1;
}
if (is_forbidden_custom_header(custom_headers->strings[i])) {
giterr_set(GITERR_INVALID, "custom HTTP header '%s' is already set by libgit2", custom_headers->strings[i]);
return -1;
}
} }
t->custom_headers = custom_headers; t->custom_headers = custom_headers;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment