commit 40d0d6a4093ece4bee8d00d9d5c375de27f3792d from: Omar Polo via: Thomas Adam date: Mon Feb 20 16:18:17 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 - b6ac0d3606b6c6348cf2f250fc3b37189b023031 commit + 40d0d6a4093ece4bee8d00d9d5c375de27f3792d blob - 5f83dafcb51d4b45ea35cb4f759acdc55750a503 blob + 63b7043edc294ed7871a48d88c579243b94008cf --- lib/gitconfig.c +++ lib/gitconfig.c @@ -245,8 +245,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 - 0a8a77d70366aaadeb9bc53106ede7f24647fa2a blob + 249a74ed96e20bcfec2a5b7b1fc8b1c2230b05a8 --- 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" }