attr: change validity check for attribute names to use positive logic

Convert 'invalid_attr_name()' to 'attr_name_valid()' and use positive logic for the return value. In addition create a helper function that prints out an error message when an invalid attribute name is used. We could later update the message to exactly spell out what the rules for a good attribute name are, etc. Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jan 27, 2017 at 18:02 UTC 428103c7f1a0cb8bb1432214efa60abc5bd5f198
1 file changed +20 -14
attr.c
+20 -14
@@ -74,23 +74,33 @@ static unsigned hash_name(const char *name, int namelen)
74 return val;
75 }
76
77 -static int invalid_attr_name(const char *name, int namelen)
77 +static int attr_name_valid(const char *name, size_t namelen)
78 {
79 /*
80 * Attribute name cannot begin with '-' and must consist of
81 * characters from [-A-Za-z0-9_.].
82 */
83 if (namelen <= 0 || *name == '-')
84 - return -1;
84 + return 0;
85 while (namelen--) {
86 char ch = *name++;
87 if (! (ch == '-' || ch == '.' || ch == '_' ||
88 ('0' <= ch && ch <= '9') ||
89 ('a' <= ch && ch <= 'z') ||
90 ('A' <= ch && ch <= 'Z')) )
91 - return -1;
91 + return 0;
92 }
93 - return 0;
93 + return 1;
94 +}
95 +
96 +static void report_invalid_attr(const char *name, size_t len,
97 + const char *src, int lineno)
98 +{
99 + struct strbuf err = STRBUF_INIT;
100 + strbuf_addf(&err, _("%.*s is not a valid attribute name"),
101 + (int) len, name);
102 + fprintf(stderr, "%s: %s:%d\n", err.buf, src, lineno);
103 + strbuf_release(&err);
104 }
105
106 static struct git_attr *git_attr_internal(const char *name, int len)
@@ -105,7 +115,7 @@ static struct git_attr *git_attr_internal(const char *name, int len)
115 return a;
116 }
117
108 - if (invalid_attr_name(name, len))
118 + if (!attr_name_valid(name, len))
119 return NULL;
120
121 FLEX_ALLOC_MEM(a, name, name, len);
@@ -196,17 +206,15 @@ static const char *parse_attr(const char *src, int lineno, const char *cp,
206 cp++;
207 len--;
208 }
199 - if (invalid_attr_name(cp, len)) {
200 - fprintf(stderr,
201 - "%.*s is not a valid attribute name: %s:%d\n",
202 - len, cp, src, lineno);
209 + if (!attr_name_valid(cp, len)) {
210 + report_invalid_attr(cp, len, src, lineno);
211 return NULL;
212 }
213 } else {
214 /*
215 * As this function is always called twice, once with
216 * e == NULL in the first pass and then e != NULL in
209 - * the second pass, no need for invalid_attr_name()
217 + * the second pass, no need for attr_name_valid()
218 * check here.
219 */
220 if (*cp == '-' || *cp == '!') {
@@ -258,10 +266,8 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
266 name += strlen(ATTRIBUTE_MACRO_PREFIX);
267 name += strspn(name, blank);
268 namelen = strcspn(name, blank);
261 - if (invalid_attr_name(name, namelen)) {
262 - fprintf(stderr,
263 - "%.*s is not a valid attribute name: %s:%d\n",
264 - namelen, name, src, lineno);
269 + if (!attr_name_valid(name, namelen)) {
270 + report_invalid_attr(name, namelen, src, lineno);
271 goto fail_return;
272 }
273 }