{"thread":{"id":"11400","subject":"[PATCH] Improve error messages when int/long cannot be parsed from config","startedAt":"2007-12-25T07:18:05Z","lastAt":"2007-12-25T07:18:05Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"64088","messageId":"20071225071805.GA13552@spearce.org","threadId":"11400","inReplyTo":null,"subject":"[PATCH] Improve error messages when int/long cannot be parsed from config","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-12-25T07:18:05Z","receivedAt":"2007-12-25T07:18:05Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"If a config file has become mildly corrupted due to a missing LF\nwe may discover some other option joined up against the end of a\nnumeric value.  For example:\n\n\t[section]\n\tnumber = 1auto\n\nwhere the \"auto\" flag was meant to occur on the next line, below\n\"number\", but the missing LF has caused it to no longer be its\nown option.  Instead the word \"auto\" is parsed as a 'unit factor'\nfor the value of \"number\".\n\nBefore this change we got the confusing error message:\n\n  fatal: unknown unit: 'auto'\n\nwhich told us nothing about where the problem appeared.  Now we get:\n\n  fatal: bad config value for 'aninvalid.unit'\n\nwhich at least points the user in the right direction of where to\nsearch for the incorrectly formatted configuration file.\n\nNoticed by erikh on #git, which received the original error from\na simple `git checkout -b` due to a midly corrupted config.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n config.c               |   31 +++++++++++++++++++++----------\n t/t1300-repo-config.sh |   17 +++++++++++++++++\n 2 files changed, 38 insertions(+), 10 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex 22ff4ce..fa56c70 100644\n--- a/config.c\n+++ b/config.c\n@@ -234,17 +234,23 @@ static int git_parse_file(config_fn_t fn)\n \tdie(\"bad config file line %d in %s\", config_linenr, config_file_name);\n }\n \n-static unsigned long get_unit_factor(const char *end)\n+static int parse_unit_factor(const char *end, unsigned long *val)\n {\n \tif (!*end)\n \t\treturn 1;\n-\telse if (!strcasecmp(end, \"k\"))\n-\t\treturn 1024;\n-\telse if (!strcasecmp(end, \"m\"))\n-\t\treturn 1024 * 1024;\n-\telse if (!strcasecmp(end, \"g\"))\n-\t\treturn 1024 * 1024 * 1024;\n-\tdie(\"unknown unit: '%s'\", end);\n+\telse if (!strcasecmp(end, \"k\")) {\n+\t\t*val *= 1024;\n+\t\treturn 1;\n+\t}\n+\telse if (!strcasecmp(end, \"m\")) {\n+\t\t*val *= 1024 * 1024;\n+\t\treturn 1;\n+\t}\n+\telse if (!strcasecmp(end, \"g\")) {\n+\t\t*val *= 1024 * 1024 * 1024;\n+\t\treturn 1;\n+\t}\n+\treturn 0;\n }\n \n int git_parse_long(const char *value, long *ret)\n@@ -252,7 +258,10 @@ int git_parse_long(const char *value, long *ret)\n \tif (value && *value) {\n \t\tchar *end;\n \t\tlong val = strtol(value, &end, 0);\n-\t\t*ret = val * get_unit_factor(end);\n+\t\tunsigned long factor = 1;\n+\t\tif (!parse_unit_factor(end, &factor))\n+\t\t\treturn 0;\n+\t\t*ret = val * factor;\n \t\treturn 1;\n \t}\n \treturn 0;\n@@ -263,7 +272,9 @@ int git_parse_ulong(const char *value, unsigned long *ret)\n \tif (value && *value) {\n \t\tchar *end;\n \t\tunsigned long val = strtoul(value, &end, 0);\n-\t\t*ret = val * get_unit_factor(end);\n+\t\tif (!parse_unit_factor(end, &val))\n+\t\t\treturn 0;\n+\t\t*ret = val;\n \t\treturn 1;\n \t}\n \treturn 0;\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex e894629..42eac2a 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -448,6 +448,23 @@ test_expect_success numbers '\n \ttest z1048576 = \"z$m\"\n '\n \n+cat > expect <<EOF\n+fatal: bad config value for 'aninvalid.unit' in .git/config\n+EOF\n+\n+test_expect_success 'invalid unit' '\n+\n+\tgit config aninvalid.unit \"1auto\" &&\n+\ts=$(git config aninvalid.unit) &&\n+\ttest \"z1auto\" = \"z$s\" &&\n+\tif git config --int --get aninvalid.unit 2>actual\n+\tthen\n+\t\techo config should have failed\n+\t\tfalse\n+\tfi &&\n+\tcmp actual expect\n+'\n+\n cat > expect << EOF\n true\n false\n-- \n1.5.4.rc1.1119.g1e6bc\n"}]}