commit 2b5b58792b27164b1bbcbfb25180ce2ea5986e3f from: Omar Polo date: Sun Feb 19 09:29:28 2023 UTC gitconfig.c: fix read/write out of bounds conf_parse_line advances the `line' pointer without decrementing the line size `sz'. This makes the parsing code mistakingly reading from the next line (`line' is just a pointer in a bigger buffer that holds the whole file) and may mangle it by writing NUL bytes in it. Add also a new regress case to trigger this case. Reported by falsifian on IRC, thanks! ok stsp@ commit - cd0aa8caa26478b2cb3c60e889894de02e0eb921 commit + 2b5b58792b27164b1bbcbfb25180ce2ea5986e3f blob - 4b5de6124b792fc8fcfae5babf81e657a387f457 blob + 836551957b7ea94b0769a73ed8ac1f103def1278 --- lib/gitconfig.c +++ lib/gitconfig.c @@ -243,8 +243,10 @@ conf_parse_line(char **section, struct got_gitconfig * return got_error_from_errno("strndup"); return NULL; } - while (isspace((unsigned char)*line)) + while (sz > 0 && isspace((unsigned char)*line)) { line++; + sz--; + } /* Deal with assignments. */ for (i = 0; i < sz; i++) blob - 488cdaf04a738a2e6a11df99d0d5df6b7a604c83 blob + 62bcb9f3f02f060aa7096a6fd0d8eb9f6ded5382 --- regress/cmdline/commit.sh +++ regress/cmdline/commit.sh @@ -976,7 +976,40 @@ test_commit_gitconfig_author() { ret=$? if [ $ret -ne 0 ]; then diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 fi + + # retry with spaces in the git config + ed -s "$testroot/repo/.git/config" < $testroot/wt/alpha + + # unset in a subshell to avoid affecting our environment + (unset GOT_IGNORE_GITCONFIG && cd "$testroot/wt" && \ + got commit -m 'test gitconfig author again' >/dev/null) + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + (cd "$testroot/repo" && got log -l1 | grep ^from: > $testroot/stdout) + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo "from: Flan Luck " \ + > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi test_done "$testroot" "$ret" }