Am 05.02.24 um 18:21 schrieb Chandra Pratap via GitGitGadget: > From: Chandra Pratap <chandrapratap3519@xxxxxxxxx> > > Signed-off-by: Chandra Pratap <chandrapratap3519@xxxxxxxxx> > --- > commit.c: ensure strchrnul() doesn't scan beyond range > > Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1652%2FChand-ra%2Fstrchrnul-v1 > Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1652/Chand-ra/strchrnul-v1 > Pull-Request: https://github.com/gitgitgadget/git/pull/1652 > > commit.c | 8 +------- > 1 file changed, 1 insertion(+), 7 deletions(-) > > diff --git a/commit.c b/commit.c > index ef679a0b939..a65b8e92e94 100644 > --- a/commit.c > +++ b/commit.c > @@ -1743,15 +1743,9 @@ const char *find_header_mem(const char *msg, size_t len, > int key_len = strlen(key); > const char *line = msg; > > - /* > - * NEEDSWORK: It's possible for strchrnul() to scan beyond the range > - * given by len. However, current callers are safe because they compute > - * len by scanning a NUL-terminated block of memory starting at msg. > - * Nonetheless, it would be better to ensure the function does not look > - * at msg beyond the len provided by the caller. > - */ > while (line && line < msg + len) { > const char *eol = strchrnul(line, '\n'); > + assert(eol - line <= len); Something like this might work in Verse, but C is more simple-minded. You can't undo an out-of-bounds access after the fact, and assert() would be compiled out if the code is built with NDEBUG anyway. If you want to make the code work with buffers that lack a terminating NUL then you need to replace the strchrnul() call with something that respects buffer lengths. You could e.g. call memchr(). Don't forget to check for NUL to preserve the original behavior. Or you could roll your own custom replacement, perhaps like this: char *strnchrnul(const char *s, int c, size_t len) { while (len-- && *s && *s != c) s++; return (char *)s; } A test with the new unit-test framework would be nice. It should be possible to show that the current code runs over the passed len, without causing undefined behavior. E.g. find_header_mem("foo bar", 2, "foo", &len) is safe, but returns "bar" instead of NULL. > > if (line == eol) > return NULL; > > base-commit: a54a84b333adbecf7bc4483c0e36ed5878cac17b