commit - f69c5a468f5e08db053b390fc00d2e2e70bf4d53
commit + ec9b5f0bbac26b3fa439f7fe48c4bdf066545911
blob - 034dde68216bb0a706cedd6e96ebac3012ccb8ab
blob + fdedddacfa4bbde46e722c1066f24c0ff20ab7b1
--- got/got.c
+++ got/got.c
return NULL;
}
-static int
+static const struct got_error *
valid_author(const char *author)
{
+ const char *email = author;
+
/*
- * Really dumb email address check; we're only doing this to
- * avoid git's object parser breaking on commits we create.
+ * Git' expects the author (or committer) to be in the form
+ * "name <email>", which are mostly free form (see the
+ * "committer" description in git-fast-import(1)). We're only
+ * doing this to avoid git's object parser breaking on commits
+ * we create.
*/
- while (*author && *author != '<')
- author++;
- if (*author != '<')
- return 0;
- while (*author && *author != '@')
+
+ while (*author && *author != '\n' && *author != '<' && *author != '>')
author++;
- if (*author != '@')
- return 0;
- while (*author && *author != '>')
+ if (*author++ != '<')
+ return got_error_fmt(GOT_ERR_COMMIT_NO_EMAIL, "%s", email);
+ while (*author && *author != '\n' && *author != '<' && *author != '>')
author++;
- return *author == '>';
+ if (strcmp(author, ">") != 0)
+ return got_error_fmt(GOT_ERR_COMMIT_NO_EMAIL, "%s", email);
+ return NULL;
}
static const struct got_error *
if (*author == NULL)
return got_error_from_errno("strdup");
- if (!valid_author(*author)) {
- err = got_error_fmt(GOT_ERR_COMMIT_NO_EMAIL, "%s", *author);
+ err = valid_author(*author);
+ if (err) {
free(*author);
*author = NULL;
}
blob - 49458051f4c21c319a884feb707cc3aa39e543db
blob + cf2c3ea32defbab535ace771de28f684e7e74ff7
--- regress/cmdline/commit.sh
+++ regress/cmdline/commit.sh
test_commit_no_email() {
local testroot=`test_init commit_no_email`
+ local errmsg=""
+
+ errmsg="commit author's email address is required for"
+ errmsg="$errmsg compatibility with Git"
got checkout $testroot/repo $testroot/wt > /dev/null
ret=$?
got commit -m 'test no email' > $testroot/stdout \
2> $testroot/stderr)
- echo -n "got: :flan_hacker:: commit author's email address " \
- > $testroot/stderr.expected
- echo "is required for compatibility with Git" \
- >> $testroot/stderr.expected
+ printf "got: :flan_hacker:: %s\n" "$errmsg" > $testroot/stderr.expected
cmp -s $testroot/stderr.expected $testroot/stderr
ret=$?
if [ $ret -ne 0 ]; then
ret=$?
if [ $ret -ne 0 ]; then
diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" $ret
+ return 1
fi
- test_done "$testroot" "$ret"
+
+ # try again with a newline inside the email
+ (cd $testroot/wt \
+ && FS=' ' env GOT_AUTHOR="$(printf "Flan <hack\ner>")" \
+ got commit -m 'test invalid email' > $testroot/stdout \
+ 2> $testroot/stderr)
+
+ printf "got: Flan <hack\ner>: %s\n" "$errmsg" \
+ > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" $ret
+ return 1
+ fi
+
+ echo -n > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" $ret
+ return 1
+ fi
+
+ # try again with a < inside the email
+ (cd $testroot/wt && env GOT_AUTHOR="$(printf "Flan <ha<ker>")" \
+ got commit -m 'test invalid email' > $testroot/stdout \
+ 2> $testroot/stderr)
+
+ printf "got: Flan <ha<ker>: %s\n" "$errmsg" > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" $ret
+ return 1
+ fi
+
+ echo -n > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" $ret
}
test_commit_tree_entry_sorting() {