aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-04-15 14:56:09 -0700
committerJunio C Hamano <junkio@cox.net>2007-04-15 15:49:41 -0700
commite4aee10a2eaf0937d86d046f85ee569a75cae9ac (patch)
tree23300fe84d1e3f9c2c6f0d873c103bb09fc491ed
parentfc2d07b05fb691f98b3a55c1499fae6fb25a7d31 (diff)
downloadgit-e4aee10a2eaf0937d86d046f85ee569a75cae9ac.tar.gz
git-e4aee10a2eaf0937d86d046f85ee569a75cae9ac.tar.xz
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>
-rw-r--r--attr.c51
-rw-r--r--builtin-check-attr.c6
-rwxr-xr-xt/t0020-crlf.sh2
3 files changed, 52 insertions, 7 deletions
diff --git a/attr.c b/attr.c
index 410bca613..60fe48f3b 100644
--- a/attr.c
+++ b/attr.c
@@ -36,6 +36,27 @@ static unsigned hash_name(const char *name, int namelen)
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)
{
unsigned hval = hash_name(name, len);
@@ -48,6 +69,9 @@ struct git_attr *git_attr(const char *name, int len)
return a;
}
+ if (invalid_attr_name(name, len))
+ return NULL;
+
a = xmalloc(sizeof(*a) + len + 1);
memcpy(a->name, name, len);
a->name[len] = 0;
@@ -68,7 +92,7 @@ struct git_attr *git_attr(const char *name, int len)
* (1) glob pattern.
* (2) whitespace
* (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 {
@@ -114,6 +138,12 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
name += strlen(ATTRIBUTE_MACRO_PREFIX);
name += strspn(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
is_macro = 0;
@@ -126,11 +156,21 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
while (*cp) {
const char *ep;
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;
e = &(res->state[num_attr]);
- if (*cp == '!') {
+ if (*cp == '-') {
e->unset = 1;
cp++;
}
@@ -146,8 +186,9 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
sizeof(*res) +
sizeof(struct attr_state) * num_attr +
(is_macro ? 0 : namelen + 1));
- if (is_macro)
+ if (is_macro) {
res->u.attr = git_attr(name, namelen);
+ }
else {
res->u.pattern = (char*)&(res->state[num_attr]);
memcpy(res->u.pattern, name, namelen);
@@ -194,7 +235,7 @@ static void free_attr_elem(struct attr_stack *e)
}
static const char *builtin_attr[] = {
- "[attr]binary !diff !crlf",
+ "[attr]binary -diff -crlf",
NULL,
};
diff --git a/builtin-check-attr.c b/builtin-check-attr.c
index 47b07210d..634be9ed2 100644
--- a/builtin-check-attr.c
+++ b/builtin-check-attr.c
@@ -29,8 +29,12 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
check = xcalloc(cnt, sizeof(*check));
for (i = 0; i < cnt; i++) {
const char *name;
+ struct git_attr *a;
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++) {
diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh
index 600dcd30a..cf84f0a1a 100755
--- a/t/t0020-crlf.sh
+++ b/t/t0020-crlf.sh
@@ -216,7 +216,7 @@ test_expect_success 'apply patch --index (autocrlf=true)' '
test_expect_success '.gitattributes says two is binary' '
- echo "two !crlf" >.gitattributes &&
+ echo "two -crlf" >.gitattributes &&
rm -f tmp one dir/two &&
git repo-config core.autocrlf true &&
git read-tree --reset -u HEAD &&