diff options
author | Jacques Germishuys <jacquesg@striata.com> | 2014-04-11 22:57:15 +0200 |
---|---|---|
committer | Jacques Germishuys <jacquesg@striata.com> | 2014-04-15 17:22:17 +0200 |
commit | a56b418d8541e04f02be1227772b13762bfebaed (patch) | |
tree | f70e5f9f04b75b7fe8049a135fb2ea979299a19c | |
parent | d8cc1fb653387d9acc28b075147084cf452c43dc (diff) | |
download | libgit2-a56b418d8541e04f02be1227772b13762bfebaed.tar.gz |
Sanitize git_diff_format_email_options' summary parameter
It will form part of the subject line and should thus be one line.
-rw-r--r-- | src/diff.c | 20 | ||||
-rw-r--r-- | tests/diff/format_email.c | 68 |
2 files changed, 87 insertions, 1 deletions
diff --git a/src/diff.c b/src/diff.c index ba3cd26b5..cb05a5faf 100644 --- a/src/diff.c +++ b/src/diff.c @@ -1544,6 +1544,7 @@ int git_diff_format_email( const git_diff_format_email_options *opts) { git_diff_stats *stats = NULL; + char *summary = NULL, *loc = NULL; bool ignore_marker; unsigned int format_flags = 0; int error; @@ -1565,8 +1566,24 @@ int git_diff_format_email( } } + /* the summary we receive may not be clean. + * it could potentially contain new line characters + * or not be set, sanitize, */ + if ((loc = strpbrk(opts->summary, "\r\n")) != NULL) { + size_t offset = 0; + + if ((offset = (loc - opts->summary)) == 0) { + giterr_set(GITERR_INVALID, "summary is empty"); + error = -1; + } + + summary = git__calloc(offset + 1, sizeof(char)); + GITERR_CHECK_ALLOC(summary); + strncpy(summary, opts->summary, offset); + } + error = git_diff_format_email__append_header_tobuf(out, - opts->id, opts->author, opts->summary, + opts->id, opts->author, summary == NULL ? opts->summary : summary, opts->patch_no, opts->total_patches, ignore_marker); if (error < 0) @@ -1583,6 +1600,7 @@ int git_diff_format_email( error = git_buf_puts(out, "--\nlibgit2 " LIBGIT2_VERSION "\n\n"); on_error: + git__free(summary); git_diff_stats_free(stats); return error; diff --git a/tests/diff/format_email.c b/tests/diff/format_email.c index ff0209e6f..dbd41552f 100644 --- a/tests/diff/format_email.c +++ b/tests/diff/format_email.c @@ -443,3 +443,71 @@ void test_diff_format_email__rename_add_remove(void) git_buf_free(&buf); } +void test_diff_format_email__multiline_summary(void) +{ + git_oid oid; + git_commit *commit = NULL; + git_diff *diff = NULL; + git_diff_format_email_options opts = GIT_DIFF_FORMAT_EMAIL_OPTIONS_INIT; + git_buf buf = GIT_BUF_INIT; + + const char *email = + "From 9264b96c6d104d0e07ae33d3007b6a48246c6f92 Mon Sep 17 00:00:00 2001\n" \ + "From: Jacques Germishuys <jacquesg@striata.com>\n" \ + "Date: Wed, 9 Apr 2014 20:57:01 +0200\n" \ + "Subject: [PATCH] Modify some content\n" \ + "\n" \ + "---\n" \ + " file1.txt | 8 +++++---\n" \ + " 1 file changed, 5 insertions(+), 3 deletions(-)\n" \ + "\n" \ + "diff --git a/file1.txt b/file1.txt\n" \ + "index 94aaae8..af8f41d 100644\n" \ + "--- a/file1.txt\n" \ + "+++ b/file1.txt\n" \ + "@@ -1,15 +1,17 @@\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "+_file1.txt_\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "+\n" \ + "+\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + " file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "-file1.txt\n" \ + "+_file1.txt_\n" \ + "+_file1.txt_\n" \ + " file1.txt\n" \ + "--\n" \ + "libgit2 " LIBGIT2_VERSION "\n" \ + "\n"; + + git_oid_fromstr(&oid, "9264b96c6d104d0e07ae33d3007b6a48246c6f92"); + + cl_git_pass(git_commit_lookup(&commit, repo, &oid)); + + opts.id = git_commit_id(commit); + opts.author = git_commit_author(commit); + opts.summary = "Modify some content\nSome extra stuff here"; + + cl_git_pass(git_diff__commit(&diff, repo, commit, NULL)); + cl_git_pass(git_diff_format_email(&buf, diff, &opts)); + cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); + + git_buf_clear(&buf); + cl_git_pass(git_diff_commit_as_email(&buf, repo, commit, 1, 1, 0, NULL)); + cl_assert(strcmp(git_buf_cstr(&buf), email) == 0); + + git_diff_free(diff); + git_commit_free(commit); + git_buf_free(&buf); +} + |