summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2015-02-05 06:53:28 (GMT)
committerJunio C Hamano <gitster@pobox.com>2015-02-05 20:37:36 (GMT)
commit5e0be134d35a31f41921f89331a95337bb38c152 (patch)
tree3e096bd96db28bf2c5130ab1fc68ad48ca209e66
parent282616c72d1d08a77ca4fe1186cb708c38408d87 (diff)
downloadgit-5e0be134d35a31f41921f89331a95337bb38c152.zip
git-5e0be134d35a31f41921f89331a95337bb38c152.tar.gz
git-5e0be134d35a31f41921f89331a95337bb38c152.tar.bz2
config: do not ungetc EOF
When we are parsing a config value, if we see a carriage return, we fgetc the next character to see if it is a line feed (in which case we silently drop the CR). If it isn't, we then ungetc the character, and take the literal CR. But we never check whether we in fact got a character at all. If the config file ends in CR, we will get EOF here, and try to ungetc EOF. This works OK for a real stdio stream. The ungetc returns an error, and the next fgetc will then return EOF again. However, our custom buffer-based stream is not so fortunate. It happily rewinds the position of the stream by one character, ignoring the fact that we fed it EOF. The next fgetc call returns the final CR again, over and over, and we end up in an infinite loop. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--config.c3
-rwxr-xr-xt/t1307-config-blob.sh9
2 files changed, 11 insertions, 1 deletions
diff --git a/config.c b/config.c
index 61a9c29..5eca17b 100644
--- a/config.c
+++ b/config.c
@@ -228,7 +228,8 @@ static int get_next_char(void)
/* DOS like systems */
c = cf->do_fgetc(cf);
if (c != '\n') {
- cf->do_ungetc(c, cf);
+ if (c != EOF)
+ cf->do_ungetc(c, cf);
c = '\r';
}
}
diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh
index fdc257e..3c6791e 100755
--- a/t/t1307-config-blob.sh
+++ b/t/t1307-config-blob.sh
@@ -67,4 +67,13 @@ test_expect_success 'parse errors in blobs are properly attributed' '
grep "HEAD:config" err
'
+test_expect_success 'can parse blob ending with CR' '
+ printf "[some]key = value\\r" >config &&
+ git add config &&
+ git commit -m CR &&
+ echo value >expect &&
+ git config --blob=HEAD:config some.key >actual &&
+ test_cmp expect actual
+'
+
test_done