[PATCH] git-config: Parse config files leniently

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently, git config dies as soon as there is a parsing error. This is
especially unfortunate in case a user tries to correct config mistakes
using git config -e.

Instead, issue a warning only and treat the rest of the line as a
comment (ignore it). This benefits not only git config -e users.

Signed-off-by: Michael J Gruber <git@xxxxxxxxxxxxxxxxxxxx>
Reported-by: David Reitter <david.reitter@xxxxxxxxx>
---
The diff and stat are overstatements. I had to shift that whole for loop
by one tab stop but diff (with or without --color-words) does not recognize
this. Nothing inside the loop is changed.
The outer while makes sure that
* we switch to comment mode after a parsing error
* we return eventually no matter whether the file ends with \n or not.

Test had to be adjusted as well.

 config.c                |   80 ++++++++++++++++++++++++----------------------
 t/t1303-wacky-config.sh |    4 +-
 2 files changed, 44 insertions(+), 40 deletions(-)

diff --git a/config.c b/config.c
index e87edea..5e0af5d 100644
--- a/config.c
+++ b/config.c
@@ -207,50 +207,54 @@ static int git_parse_file(config_fn_t fn, void *data)
 	static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
 	const unsigned char *bomptr = utf8_bom;
 
-	for (;;) {
-		int c = get_next_char();
-		if (bomptr && *bomptr) {
-			/* We are at the file beginning; skip UTF8-encoded BOM
-			 * if present. Sane editors won't put this in on their
-			 * own, but e.g. Windows Notepad will do it happily. */
-			if ((unsigned char) c == *bomptr) {
-				bomptr++;
+	while (!config_file_eof) {
+		for (;;) {
+			int c = get_next_char();
+			if (bomptr && *bomptr) {
+				/* We are at the file beginning; skip UTF8-encoded BOM
+				 * if present. Sane editors won't put this in on their
+				 * own, but e.g. Windows Notepad will do it happily. */
+				if ((unsigned char) c == *bomptr) {
+					bomptr++;
+					continue;
+				} else {
+					/* Do not tolerate partial BOM. */
+					if (bomptr != utf8_bom)
+						break;
+					/* No BOM at file beginning. Cool. */
+					bomptr = NULL;
+				}
+			}
+			if (c == '\n') {
+				if (config_file_eof)
+					return 0;
+				comment = 0;
 				continue;
-			} else {
-				/* Do not tolerate partial BOM. */
-				if (bomptr != utf8_bom)
+			}
+			if (comment || isspace(c))
+				continue;
+			if (c == '#' || c == ';') {
+				comment = 1;
+				continue;
+			}
+			if (c == '[') {
+				baselen = get_base_var(var);
+				if (baselen <= 0)
 					break;
-				/* No BOM at file beginning. Cool. */
-				bomptr = NULL;
+				var[baselen++] = '.';
+				var[baselen] = 0;
+				continue;
 			}
-		}
-		if (c == '\n') {
-			if (config_file_eof)
-				return 0;
-			comment = 0;
-			continue;
-		}
-		if (comment || isspace(c))
-			continue;
-		if (c == '#' || c == ';') {
-			comment = 1;
-			continue;
-		}
-		if (c == '[') {
-			baselen = get_base_var(var);
-			if (baselen <= 0)
+			if (!isalpha(c))
+				break;
+			var[baselen] = tolower(c);
+			if (get_value(fn, data, var, baselen+1) < 0)
 				break;
-			var[baselen++] = '.';
-			var[baselen] = 0;
-			continue;
 		}
-		if (!isalpha(c))
-			break;
-		var[baselen] = tolower(c);
-		if (get_value(fn, data, var, baselen+1) < 0)
-			break;
+		warning("bad config file line %d in %s", config_linenr, config_file_name);
+		comment = 1;
 	}
-	die("bad config file line %d in %s", config_linenr, config_file_name);
+	return -1;
 }
 
 static int parse_unit_factor(const char *end, unsigned long *val)
diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh
index 080117c..be850c5 100755
--- a/t/t1303-wacky-config.sh
+++ b/t/t1303-wacky-config.sh
@@ -9,7 +9,7 @@ setup() {
 }
 
 check() {
-	echo "$2" >expected
+	printf "$2\n" >expected
 	git config --get "$1" >actual 2>&1
 	test_cmp actual expected
 }
@@ -44,7 +44,7 @@ LONG_VALUE=$(printf "x%01021dx a" 7)
 test_expect_success 'do not crash on special long config line' '
 	setup &&
 	git config section.key "$LONG_VALUE" &&
-	check section.key "fatal: bad config file line 2 in .git/config"
+	check section.key "warning: bad config file line 2 in .git/config\nwarning: bad config file line 2 in .git/config"
 '
 
 test_done
-- 
1.6.4.225.gb589e

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]