Change attribute negation marker from '!' to '-'.

At the same time, we do not want to allow arbitrary strings for
attribute names, as we are likely to want to extend the syntax
later.  Allow only alnum, dash, underscore and dot for now.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano 2007-04-15 14:56:09 -07:00
Родитель fc2d07b05f
Коммит e4aee10a2e
3 изменённых файлов: 52 добавлений и 7 удалений

51
attr.c
Просмотреть файл

@ -36,6 +36,27 @@ static unsigned hash_name(const char *name, int namelen)
return val; return val;
} }
static int invalid_attr_name(const char *name, int namelen)
{
/*
* Attribute name cannot begin with '-' and from
* [-A-Za-z0-9_.]. We'd specifically exclude '=' for now,
* as we might later want to allow non-binary value for
* attributes, e.g. "*.svg merge=special-merge-program-for-svg"
*/
if (*name == '-')
return -1;
while (namelen--) {
char ch = *name++;
if (! (ch == '-' || ch == '.' || ch == '_' ||
('0' <= ch && ch <= '9') ||
('a' <= ch && ch <= 'z') ||
('A' <= ch && ch <= 'Z')) )
return -1;
}
return 0;
}
struct git_attr *git_attr(const char *name, int len) struct git_attr *git_attr(const char *name, int len)
{ {
unsigned hval = hash_name(name, len); unsigned hval = hash_name(name, len);
@ -48,6 +69,9 @@ struct git_attr *git_attr(const char *name, int len)
return a; return a;
} }
if (invalid_attr_name(name, len))
return NULL;
a = xmalloc(sizeof(*a) + len + 1); a = xmalloc(sizeof(*a) + len + 1);
memcpy(a->name, name, len); memcpy(a->name, name, len);
a->name[len] = 0; a->name[len] = 0;
@ -68,7 +92,7 @@ struct git_attr *git_attr(const char *name, int len)
* (1) glob pattern. * (1) glob pattern.
* (2) whitespace * (2) whitespace
* (3) whitespace separated list of attribute names, each of which * (3) whitespace separated list of attribute names, each of which
* could be prefixed with '!' to mean "not set". * could be prefixed with '-' to mean "not set".
*/ */
struct attr_state { struct attr_state {
@ -114,6 +138,12 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
name += strlen(ATTRIBUTE_MACRO_PREFIX); name += strlen(ATTRIBUTE_MACRO_PREFIX);
name += strspn(name, blank); name += strspn(name, blank);
namelen = strcspn(name, blank); namelen = strcspn(name, blank);
if (invalid_attr_name(name, namelen)) {
fprintf(stderr,
"%.*s is not a valid attribute name: %s:%d\n",
namelen, name, src, lineno);
return NULL;
}
} }
else else
is_macro = 0; is_macro = 0;
@ -126,11 +156,21 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
while (*cp) { while (*cp) {
const char *ep; const char *ep;
ep = cp + strcspn(cp, blank); ep = cp + strcspn(cp, blank);
if (pass) { if (!pass) {
if (*cp == '-')
cp++;
if (invalid_attr_name(cp, ep - cp)) {
fprintf(stderr,
"%.*s is not a valid attribute name: %s:%d\n",
(int)(ep - cp), cp,
src, lineno);
return NULL;
}
} else {
struct attr_state *e; struct attr_state *e;
e = &(res->state[num_attr]); e = &(res->state[num_attr]);
if (*cp == '!') { if (*cp == '-') {
e->unset = 1; e->unset = 1;
cp++; cp++;
} }
@ -146,8 +186,9 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
sizeof(*res) + sizeof(*res) +
sizeof(struct attr_state) * num_attr + sizeof(struct attr_state) * num_attr +
(is_macro ? 0 : namelen + 1)); (is_macro ? 0 : namelen + 1));
if (is_macro) if (is_macro) {
res->u.attr = git_attr(name, namelen); res->u.attr = git_attr(name, namelen);
}
else { else {
res->u.pattern = (char*)&(res->state[num_attr]); res->u.pattern = (char*)&(res->state[num_attr]);
memcpy(res->u.pattern, name, namelen); memcpy(res->u.pattern, name, namelen);
@ -194,7 +235,7 @@ static void free_attr_elem(struct attr_stack *e)
} }
static const char *builtin_attr[] = { static const char *builtin_attr[] = {
"[attr]binary !diff !crlf", "[attr]binary -diff -crlf",
NULL, NULL,
}; };

Просмотреть файл

@ -29,8 +29,12 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
check = xcalloc(cnt, sizeof(*check)); check = xcalloc(cnt, sizeof(*check));
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
const char *name; const char *name;
struct git_attr *a;
name = argv[i + 1]; name = argv[i + 1];
check[i].attr = git_attr(name, strlen(name)); a = git_attr(name, strlen(name));
if (!a)
return error("%s: not a valid attribute name", name);
check[i].attr = a;
} }
for (i = doubledash; i < argc; i++) { for (i = doubledash; i < argc; i++) {

Просмотреть файл

@ -216,7 +216,7 @@ test_expect_success 'apply patch --index (autocrlf=true)' '
test_expect_success '.gitattributes says two is binary' ' test_expect_success '.gitattributes says two is binary' '
echo "two !crlf" >.gitattributes && echo "two -crlf" >.gitattributes &&
rm -f tmp one dir/two && rm -f tmp one dir/two &&
git repo-config core.autocrlf true && git repo-config core.autocrlf true &&
git read-tree --reset -u HEAD && git read-tree --reset -u HEAD &&