Skip to content

Commit 41863a0

Browse files
committed
strntol: fix out-of-bounds read when skipping leading spaces
The `git__strntol` family of functions accepts leading spaces and will simply skip them. The skipping will not honor the provided buffer's length, though, which may lead it to read outside of the provided buffer's bounds if it is not a simple NUL-terminated string. Furthermore, if leading space is trimmed, the function will further advance the pointer but not update the number of remaining bytes, which may also lead to out-of-bounds reads. Fix the issue by properly paying attention to the buffer length and updating it when stripping leading whitespace characters. Add a test that verifies that we won't read past the provided buffer length.
1 parent b5ae83b commit 41863a0

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

src/util.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
8383
/*
8484
* White space
8585
*/
86-
while (git__isspace(*p))
87-
p++;
86+
while (nptr_len && git__isspace(*p))
87+
p++, nptr_len--;
88+
89+
if (!nptr_len)
90+
goto Return;
8891

8992
/*
9093
* Sign

tests/core/strtol.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ void test_core_strtol__buffer_length_truncates(void)
7676
cl_assert_equal_i(i64, 1);
7777
}
7878

79+
void test_core_strtol__buffer_length_with_leading_ws_truncates(void)
80+
{
81+
int64_t i64;
82+
83+
cl_git_fail(git__strntol64(&i64, " 1", 1, NULL, 10));
84+
85+
cl_git_pass(git__strntol64(&i64, " 11", 2, NULL, 10));
86+
cl_assert_equal_i(i64, 1);
87+
}
88+
7989
void test_core_strtol__error_message_cuts_off(void)
8090
{
8191
assert_l32_fails("2147483657foobar", 10);

0 commit comments

Comments
 (0)