@@ -53,11 +53,9 @@ static int header_path_len(git_patch_parse_ctx *ctx)
5353 return len ;
5454}
5555
56- static int parse_header_path_buf (git_buf * path , git_patch_parse_ctx * ctx )
56+ static int parse_header_path_buf (git_buf * path , git_patch_parse_ctx * ctx , size_t path_len )
5757{
58- int path_len , error = 0 ;
59-
60- path_len = header_path_len (ctx );
58+ int error ;
6159
6260 if ((error = git_buf_put (path , ctx -> parse_ctx .line , path_len )) < 0 )
6361 goto done ;
@@ -81,7 +79,7 @@ static int parse_header_path_buf(git_buf *path, git_patch_parse_ctx *ctx)
8179static int parse_header_path (char * * out , git_patch_parse_ctx * ctx )
8280{
8381 git_buf path = GIT_BUF_INIT ;
84- int error = parse_header_path_buf (& path , ctx );
82+ int error = parse_header_path_buf (& path , ctx , header_path_len ( ctx ) );
8583
8684 * out = git_buf_detach (& path );
8785
@@ -91,13 +89,33 @@ static int parse_header_path(char **out, git_patch_parse_ctx *ctx)
9189static int parse_header_git_oldpath (
9290 git_patch_parsed * patch , git_patch_parse_ctx * ctx )
9391{
94- return parse_header_path (& patch -> old_path , ctx );
92+ git_buf old_path = GIT_BUF_INIT ;
93+ int error ;
94+
95+ if ((error = parse_header_path_buf (& old_path , ctx , ctx -> parse_ctx .line_len - 1 )) < 0 )
96+ goto out ;
97+
98+ patch -> old_path = git_buf_detach (& old_path );
99+
100+ out :
101+ git_buf_free (& old_path );
102+ return error ;
95103}
96104
97105static int parse_header_git_newpath (
98106 git_patch_parsed * patch , git_patch_parse_ctx * ctx )
99107{
100- return parse_header_path (& patch -> new_path , ctx );
108+ git_buf new_path = GIT_BUF_INIT ;
109+ int error ;
110+
111+ if ((error = parse_header_path_buf (& new_path , ctx , ctx -> parse_ctx .line_len - 1 )) < 0 )
112+ goto out ;
113+
114+ patch -> new_path = git_buf_detach (& new_path );
115+
116+ out :
117+ git_buf_free (& new_path );
118+ return error ;
101119}
102120
103121static int parse_header_mode (uint16_t * mode , git_patch_parse_ctx * ctx )
@@ -213,7 +231,7 @@ static int parse_header_rename(
213231{
214232 git_buf path = GIT_BUF_INIT ;
215233
216- if (parse_header_path_buf (& path , ctx ) < 0 )
234+ if (parse_header_path_buf (& path , ctx , header_path_len ( ctx ) ) < 0 )
217235 return -1 ;
218236
219237 /* 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)
303321 return git_parse_err ("corrupt new path in git diff header at line %" PRIuZ ,
304322 ctx -> parse_ctx .line_num );
305323
324+ /*
325+ * We cannot expect to be able to always parse paths correctly at this
326+ * point. Due to the possibility of unquoted names, whitespaces in
327+ * filenames and custom prefixes we have to allow that, though, and just
328+ * proceeed here. We then hope for the "---" and "+++" lines to fix that
329+ * for us.
330+ */
331+ if (!git_parse_ctx_contains (& ctx -> parse_ctx , "\n" , 1 )) {
332+ git_parse_advance_chars (& ctx -> parse_ctx , ctx -> parse_ctx .line_len - 1 );
333+
334+ git__free (patch -> header_old_path );
335+ patch -> header_old_path = NULL ;
336+ git__free (patch -> header_new_path );
337+ patch -> header_new_path = NULL ;
338+ }
339+
306340 return 0 ;
307341}
308342
0 commit comments