Skip to content

Commit 7655b2d

Browse files
committed
commit: fix reading out of bounds when parsing encoding
The commit message encoding is currently being parsed by the `git__prefixcmp` function. As this function does not accept a buffer length, it will happily skip over a buffer's end if it is not `NUL` terminated. Fix the issue by using `git__prefixncmp` instead. Add a test that verifies that we are unable to parse the encoding field if it's cut off by the supplied buffer length.
1 parent c2e3d8e commit 7655b2d

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/commit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size)
444444
while (eoln < buffer_end && *eoln != '\n')
445445
++eoln;
446446

447-
if (git__prefixcmp(buffer, "encoding ") == 0) {
447+
if (git__prefixncmp(buffer, buffer_end - buffer, "encoding ") == 0) {
448448
buffer += strlen("encoding ");
449449

450450
commit->message_encoding = git__strndup(buffer, eoln - buffer);

tests/object/commit/parse.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,22 @@ void test_object_commit_parse__parsing_commit_without_committer_fails(void)
211211
"Message";
212212
assert_commit_fails(commit, 0);
213213
}
214+
215+
void test_object_commit_parse__parsing_encoding_will_not_cause_oob_read(void)
216+
{
217+
const char *commit =
218+
"tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n"
219+
"author <>\n"
220+
"committer <>\n"
221+
"encoding foo\n";
222+
/*
223+
* As we ignore unknown fields, the cut-off encoding field will be
224+
* parsed just fine.
225+
*/
226+
assert_commit_parses(commit, strlen(commit) - strlen("ncoding foo\n"),
227+
"3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8",
228+
"<>",
229+
"<>",
230+
NULL,
231+
"", 0);
232+
}

0 commit comments

Comments
 (0)