Unverified Commit 4110fc84 by Edward Thomson Committed by GitHub

Merge pull request #4285 from pks-t/pks/patches-with-whitespace

patch_parse: fix parsing unquoted filenames with spaces
parents d734466c 80226b5f
...@@ -53,11 +53,9 @@ static int header_path_len(git_patch_parse_ctx *ctx) ...@@ -53,11 +53,9 @@ static int header_path_len(git_patch_parse_ctx *ctx)
return len; return len;
} }
static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx) static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx, size_t path_len)
{ {
int path_len, error = 0; int error;
path_len = header_path_len(ctx);
if ((error = git_buf_put(path, ctx->parse_ctx.line, path_len)) < 0) if ((error = git_buf_put(path, ctx->parse_ctx.line, path_len)) < 0)
goto done; goto done;
...@@ -81,7 +79,7 @@ done: ...@@ -81,7 +79,7 @@ done:
static int parse_header_path(char **out, git_patch_parse_ctx *ctx) static int parse_header_path(char **out, git_patch_parse_ctx *ctx)
{ {
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
int error = parse_header_path_buf(&path, ctx); int error = parse_header_path_buf(&path, ctx, header_path_len(ctx));
*out = git_buf_detach(&path); *out = git_buf_detach(&path);
...@@ -91,13 +89,33 @@ static int parse_header_path(char **out, git_patch_parse_ctx *ctx) ...@@ -91,13 +89,33 @@ static int parse_header_path(char **out, git_patch_parse_ctx *ctx)
static int parse_header_git_oldpath( static int parse_header_git_oldpath(
git_patch_parsed *patch, git_patch_parse_ctx *ctx) git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{ {
return parse_header_path(&patch->old_path, ctx); git_buf old_path = GIT_BUF_INIT;
int error;
if ((error = parse_header_path_buf(&old_path, ctx, ctx->parse_ctx.line_len - 1)) < 0)
goto out;
patch->old_path = git_buf_detach(&old_path);
out:
git_buf_free(&old_path);
return error;
} }
static int parse_header_git_newpath( static int parse_header_git_newpath(
git_patch_parsed *patch, git_patch_parse_ctx *ctx) git_patch_parsed *patch, git_patch_parse_ctx *ctx)
{ {
return parse_header_path(&patch->new_path, ctx); git_buf new_path = GIT_BUF_INIT;
int error;
if ((error = parse_header_path_buf(&new_path, ctx, ctx->parse_ctx.line_len - 1)) < 0)
goto out;
patch->new_path = git_buf_detach(&new_path);
out:
git_buf_free(&new_path);
return error;
} }
static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx) static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx)
...@@ -213,7 +231,7 @@ static int parse_header_rename( ...@@ -213,7 +231,7 @@ static int parse_header_rename(
{ {
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
if (parse_header_path_buf(&path, ctx) < 0) if (parse_header_path_buf(&path, ctx, header_path_len(ctx)) < 0)
return -1; return -1;
/* Note: the `rename from` and `rename to` lines include the literal /* Note: the `rename from` and `rename to` lines include the literal
...@@ -303,6 +321,22 @@ static int parse_header_start(git_patch_parsed *patch, git_patch_parse_ctx *ctx) ...@@ -303,6 +321,22 @@ static int parse_header_start(git_patch_parsed *patch, git_patch_parse_ctx *ctx)
return git_parse_err("corrupt new path in git diff header at line %"PRIuZ, return git_parse_err("corrupt new path in git diff header at line %"PRIuZ,
ctx->parse_ctx.line_num); ctx->parse_ctx.line_num);
/*
* We cannot expect to be able to always parse paths correctly at this
* point. Due to the possibility of unquoted names, whitespaces in
* filenames and custom prefixes we have to allow that, though, and just
* proceeed here. We then hope for the "---" and "+++" lines to fix that
* for us.
*/
if (!git_parse_ctx_contains(&ctx->parse_ctx, "\n", 1)) {
git_parse_advance_chars(&ctx->parse_ctx, ctx->parse_ctx.line_len - 1);
git__free(patch->header_old_path);
patch->header_old_path = NULL;
git__free(patch->header_new_path);
patch->header_new_path = NULL;
}
return 0; return 0;
} }
......
...@@ -102,3 +102,9 @@ void test_patch_parse__invalid_patches_fails(void) ...@@ -102,3 +102,9 @@ void test_patch_parse__invalid_patches_fails(void)
strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER), NULL)); strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER), NULL));
} }
void test_patch_parse__files_with_whitespaces_succeeds(void)
{
git_patch *patch;
cl_git_pass(git_patch_from_buffer(&patch, PATCH_NAME_WHITESPACE, strlen(PATCH_NAME_WHITESPACE), NULL));
git_patch_free(patch);
}
...@@ -575,6 +575,16 @@ ...@@ -575,6 +575,16 @@
"+added line with no nl\n" \ "+added line with no nl\n" \
"\\ No newline at end of file\n" "\\ No newline at end of file\n"
#define PATCH_NAME_WHITESPACE \
"diff --git a/file with spaces.txt b/file with spaces.txt\n" \
"index 9432026..83759c0 100644\n" \
"--- a/file with spaces.txt\n" \
"+++ b/file with spaces.txt\n" \
"@@ -0,3 +0,2 @@\n" \
" and this\n" \
"-is additional context\n" \
" below it!\n" \
#define PATCH_CORRUPT_GIT_HEADER \ #define PATCH_CORRUPT_GIT_HEADER \
"diff --git a/file.txt\n" \ "diff --git a/file.txt\n" \
"index 9432026..0f39b9a 100644\n" \ "index 9432026..0f39b9a 100644\n" \
......
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