fix segfault with git log -c --follow
In diff_tree_combined we make a copy of diffopts. In try_to_follow_renames, called via diff_tree_sha1, we free and re-initialize diffopts->pathspec->items. Since we did not make a deep copy of diffopts in diff_tree_combined, the original diffopts does not get the update. By the time we return from diff_tree_combined, rev->diffopt->pathspec->items points to an invalid memory address. We get a segfault next time we try to access that pathspec. Instead, along with the copy of diffopts, make a copy pathspec->items as well. We would also have to make a copy of pathspec->raw to keep it consistent with pathspec->items, but nobody seems to rely on that. Signed-off-by: Clemens Buchacher <drizzd@aon.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									04a74b6cfa
								
							
						
					
					
						commit
						46ec510ac0
					
				|  | @ -1120,6 +1120,7 @@ void diff_tree_combined(const unsigned char *sha1, | ||||||
| 	int i, num_paths, needsep, show_log_first, num_parent = parents->nr; | 	int i, num_paths, needsep, show_log_first, num_parent = parents->nr; | ||||||
|  |  | ||||||
| 	diffopts = *opt; | 	diffopts = *opt; | ||||||
|  | 	diff_tree_setup_paths(diffopts.pathspec.raw, &diffopts); | ||||||
| 	diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; | 	diffopts.output_format = DIFF_FORMAT_NO_OUTPUT; | ||||||
| 	DIFF_OPT_SET(&diffopts, RECURSIVE); | 	DIFF_OPT_SET(&diffopts, RECURSIVE); | ||||||
| 	DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL); | 	DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL); | ||||||
|  | @ -1187,6 +1188,8 @@ void diff_tree_combined(const unsigned char *sha1, | ||||||
| 		paths = paths->next; | 		paths = paths->next; | ||||||
| 		free(tmp); | 		free(tmp); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	diff_tree_release_paths(&diffopts); | ||||||
| } | } | ||||||
|  |  | ||||||
| void diff_tree_combined_merge(const struct commit *commit, int dense, | void diff_tree_combined_merge(const struct commit *commit, int dense, | ||||||
|  |  | ||||||
|  | @ -542,6 +542,20 @@ test_expect_success 'show added path under "--follow -M"' ' | ||||||
| 	) | 	) | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'git log -c --follow' ' | ||||||
|  | 	test_create_repo follow-c && | ||||||
|  | 	( | ||||||
|  | 		cd follow-c && | ||||||
|  | 		test_commit initial file original && | ||||||
|  | 		git rm file && | ||||||
|  | 		test_commit rename file2 original && | ||||||
|  | 		git reset --hard initial && | ||||||
|  | 		test_commit modify file foo && | ||||||
|  | 		git merge -m merge rename && | ||||||
|  | 		git log -c --follow file2 | ||||||
|  | 	) | ||||||
|  | ' | ||||||
|  |  | ||||||
| cat >expect <<\EOF | cat >expect <<\EOF | ||||||
| *   commit COMMIT_OBJECT_NAME | *   commit COMMIT_OBJECT_NAME | ||||||
| |\  Merge: MERGE_PARENTS | |\  Merge: MERGE_PARENTS | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Clemens Buchacher
						Clemens Buchacher