Visitar URL original
Custom push headers by srajko · Pull Request #4 · nodegit/libgit2 · GitHub
Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
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".
  • Loading branch information
spraints authored and srajko committed Jan 26, 2016
commit e6f33459365d313dac85fc9b389837e9bae6ce54
84 changes: 44 additions & 40 deletions src/transports/smart.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,69 +66,73 @@ 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(
git_transport *transport,
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;
Expand Down