fast-import: check committer name more strictly

The documentation declares following identity format: (<name> SP)? LT <email> GT where name is any string without LF and LT characters. But fast-import just accepts any string up to first GT instead of checking the whole format, and moreover just writes it as is to the commit object. git-fsck checks for [^<\n]* <[^<>\n]*> format. Note that the space is mandatory. And the space quirk is already handled via extending the string to the left when needed. Modify fast-import input identity format to a slightly stricter one - deny LF, LT and GT in both <name> and <email>. And check for it. This is stricter then git-fsck as fsck accepts "Name> <email>" currently, but soon fsck check will be adjusted likewise. Signed-off-by: Dmitry Ivankov <divanorama@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Dmitry Ivankov committed Aug 11, 2011 at 16:21 UTC 4b4963c0e1aa094900951df9e66459443111ccc9
3 files changed +24 -19
Documentation/git-fast-import.txt
+2 -2
@@ -413,8 +413,8 @@ Here `<name>` is the person's display name (for example
413 (``cm@example.com''). `LT` and `GT` are the literal less-than (\x3c)
414 and greater-than (\x3e) symbols. These are required to delimit
415 the email address from the other fields in the line. Note that
416 -`<name>` is free-form and may contain any sequence of bytes, except
417 -`LT` and `LF`. It is typically UTF-8 encoded.
416 +`<name>` and `<email>` are free-form and may contain any sequence
417 +of bytes, except `LT`, `GT` and `LF`. `<name>` is typically UTF-8 encoded.
418
419 The time of the change is specified by `<when>` using the date format
420 that was selected by the \--date-format=<fmt> command line option.
fast-import.c
+17 -12
@@ -1967,7 +1967,7 @@ static int validate_raw_date(const char *src, char *result, int maxlen)
1967
1968 static char *parse_ident(const char *buf)
1969 {
1970 - const char *gt;
1970 + const char *ltgt;
1971 size_t name_len;
1972 char *ident;
1973
@@ -1975,28 +1975,33 @@ static char *parse_ident(const char *buf)
1975 if (*buf == '<')
1976 --buf;
1977
1978 - gt = strrchr(buf, '>');
1979 - if (!gt)
1978 + ltgt = buf + strcspn(buf, "<>");
1979 + if (*ltgt != '<')
1980 + die("Missing < in ident string: %s", buf);
1981 + if (ltgt != buf && ltgt[-1] != ' ')
1982 + die("Missing space before < in ident string: %s", buf);
1983 + ltgt = ltgt + 1 + strcspn(ltgt + 1, "<>");
1984 + if (*ltgt != '>')
1985 die("Missing > in ident string: %s", buf);
1981 - gt++;
1982 - if (*gt != ' ')
1986 + ltgt++;
1987 + if (*ltgt != ' ')
1988 die("Missing space after > in ident string: %s", buf);
1984 - gt++;
1985 - name_len = gt - buf;
1989 + ltgt++;
1990 + name_len = ltgt - buf;
1991 ident = xmalloc(name_len + 24);
1992 strncpy(ident, buf, name_len);
1993
1994 switch (whenspec) {
1995 case WHENSPEC_RAW:
1991 - if (validate_raw_date(gt, ident + name_len, 24) < 0)
1992 - die("Invalid raw date \"%s\" in ident: %s", gt, buf);
1996 + if (validate_raw_date(ltgt, ident + name_len, 24) < 0)
1997 + die("Invalid raw date \"%s\" in ident: %s", ltgt, buf);
1998 break;
1999 case WHENSPEC_RFC2822:
1995 - if (parse_date(gt, ident + name_len, 24) < 0)
1996 - die("Invalid rfc2822 date \"%s\" in ident: %s", gt, buf);
2000 + if (parse_date(ltgt, ident + name_len, 24) < 0)
2001 + die("Invalid rfc2822 date \"%s\" in ident: %s", ltgt, buf);
2002 break;
2003 case WHENSPEC_NOW:
1999 - if (strcmp("now", gt))
2004 + if (strcmp("now", ltgt))
2005 die("Date in ident must be 'now': %s", buf);
2006 datestamp(ident + name_len, 24);
2007 break;
t/t9300-fast-import.sh
+5 -5
@@ -370,7 +370,7 @@ data <<COMMIT
370 empty commit
371 COMMIT
372 INPUT_END
373 -test_expect_failure 'B: fail on invalid committer (1)' '
373 +test_expect_success 'B: fail on invalid committer (1)' '
374 test_must_fail git fast-import <input
375 '
376 git update-ref -d refs/heads/invalid-committer || true
@@ -382,7 +382,7 @@ data <<COMMIT
382 empty commit
383 COMMIT
384 INPUT_END
385 -test_expect_failure 'B: fail on invalid committer (2)' '
385 +test_expect_success 'B: fail on invalid committer (2)' '
386 test_must_fail git fast-import <input
387 '
388 git update-ref -d refs/heads/invalid-committer || true
@@ -394,7 +394,7 @@ data <<COMMIT
394 empty commit
395 COMMIT
396 INPUT_END
397 -test_expect_failure 'B: fail on invalid committer (3)' '
397 +test_expect_success 'B: fail on invalid committer (3)' '
398 test_must_fail git fast-import <input
399 '
400 git update-ref -d refs/heads/invalid-committer || true
@@ -406,7 +406,7 @@ data <<COMMIT
406 empty commit
407 COMMIT
408 INPUT_END
409 -test_expect_failure 'B: fail on invalid committer (4)' '
409 +test_expect_success 'B: fail on invalid committer (4)' '
410 test_must_fail git fast-import <input
411 '
412 git update-ref -d refs/heads/invalid-committer || true
@@ -418,7 +418,7 @@ data <<COMMIT
418 empty commit
419 COMMIT
420 INPUT_END
421 -test_expect_failure 'B: fail on invalid committer (5)' '
421 +test_expect_success 'B: fail on invalid committer (5)' '
422 test_must_fail git fast-import <input
423 '
424 git update-ref -d refs/heads/invalid-committer || true