summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Burke <spraints@gmail.com>2015-09-24 09:24:10 -0400
committerMatt Burke <spraints@gmail.com>2015-09-24 09:24:10 -0400
commite60db3c79a82459aff9bd90fc97ff9d5fb886a04 (patch)
tree22c4c017710be92bb7a468c1d06a7969b919ea52
parent63cc57232cebab60ad193731582e24e83ea5b3b9 (diff)
downloadlibgit2-e60db3c79a82459aff9bd90fc97ff9d5fb886a04.tar.gz
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".
-rw-r--r--src/transports/smart.c84
1 files changed, 44 insertions, 40 deletions
diff --git a/src/transports/smart.c b/src/transports/smart.c
index fc7630c49..f0f212ca3 100644
--- a/src/transports/smart.c
+++ b/src/transports/smart.c
@@ -66,57 +66,55 @@ static int git_smart__set_callbacks(
return 0;
}
-static char *forbidden_custom_headers[] = {
- "User-Agent",
- "Host",
- "Accept",
- "Content-Type",
- "Transfer-Encoding",
- "Content-Length",
-};
+int http_header_name_length(const char *http_header)
+{
+ const char *colon = strchr(http_header, ':');
+ if (!colon)
+ return 0;
+ return colon - http_header;
+}
-bool is_valid_custom_header(const char *custom_header)
+bool is_malformed_http_header(const char *http_header)
{
const char *c;
int name_len;
- unsigned long i;
// Disallow \r and \n
- c = strchr(custom_header, '\r');
- if (c != NULL)
- return false;
- c = strchr(custom_header, '\n');
- if (c != NULL)
- return false;
+ c = strchr(http_header, '\r');
+ if (c)
+ return true;
+ c = strchr(http_header, '\n');
+ if (c)
+ return true;
// Require a header name followed by :
- c = strchr(custom_header, ':');
- if (c == NULL)
- return false;
- name_len = c - custom_header;
+ name_len = http_header_name_length(http_header);
if (name_len < 1)
- return false;
-
- // 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 true;
+ return false;
}
-const char *find_invalid_custom_header(const git_strarray *custom_headers)
-{
- size_t i;
+static char *forbidden_custom_headers[] = {
+ "User-Agent",
+ "Host",
+ "Accept",
+ "Content-Type",
+ "Transfer-Encoding",
+ "Content-Length",
+};
- if (custom_headers == NULL || custom_headers->count == 0)
- return NULL;
+bool is_forbidden_custom_header(const char *custom_header)
+{
+ unsigned long i;
+ int name_len = http_header_name_length(custom_header);
- for (i = 0; i < custom_headers->count; i++)
- if (!is_valid_custom_header(custom_headers->strings[i]))
- return custom_headers->strings[i];
+ // 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 true;
- return NULL;
+ return false;
}
static int git_smart__set_custom_headers(
@@ -124,11 +122,17 @@ static int git_smart__set_custom_headers(
const git_strarray *custom_headers)
{
transport_smart *t = (transport_smart *)transport;
- const char *invalid_header = find_invalid_custom_header(custom_headers);
+ size_t i;
- if (invalid_header != NULL) {
- giterr_set(GITERR_INVALID, "Illegal HTTP header '%s'", invalid_header);
- return -1;
+ for (i = 0; i < custom_headers->count; i++) {
+ if (is_malformed_http_header(custom_headers->strings[i])) {
+ 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;