mark parsing in fast-import

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hallo Shawn,

Shawn O. Pearce schrieb am Mon 14. Apr, 19:29 (-0400):
> Jrg Sommer <joerg@xxxxxxxxxxxx> wrote:
> > The format of the marks is as close as possible to the format of the
> > marks used by fast-export and fast-import,
> 
> Yay.
> 
> > i.e. :001 == :1 and
> > “:12a” == :12. It differs from the format of fast-import in that point
> > that it requires a digit after the colon, i.e. “:abc” != :0 and “:-12”
> > and “:+12” aren't allowed.
> 
> Uh, that's a bug in fast-import.  ":4abc" is _not_ a mark if you
> read the language specification.  Only ":4" is a mark.  So we are
> accepting crap and reading it in odd ways.  Not good.

What about this:

diff --git a/fast-import.c b/fast-import.c
index 73e5439..f60e4ab 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1690,10 +1690,31 @@ static void skip_optional_lf(void)
 		ungetc(term_char, stdin);
 }
 
+static inline int parse_mark(const const char *str, uintmax_t* mark,
+	char **after_mark)
+{
+	if (!str || str[0] != ':' || !isdigit(str[1]))
+		return 1;
+
+	char *am;
+	const uintmax_t m = strtoumax(&str[1], &am, 10);
+	if (errno == 0) {
+		*mark = m;
+		*after_mark = am;
+		return 0;
+	}
+	return 1;
+}
+
 static void cmd_mark(void)
 {
-	if (!prefixcmp(command_buf.buf, "mark :")) {
-		next_mark = strtoumax(command_buf.buf + 6, NULL, 10);
+	uintmax_t mark = 0;
+	char *after_mark = NULL;
+
+	if (!prefixcmp(command_buf.buf, "mark ") &&
+		parse_mark(&command_buf.buf[5], &mark, &after_mark) &&
+		*after_mark == '\0') {
+		next_mark = mark;
 		read_next_command();
 	}
 	else
@@ -1878,7 +1899,10 @@ static void file_change_m(struct branch *b)
 
 	if (*p == ':') {
 		char *x;
-		oe = find_mark(strtoumax(p + 1, &x, 10));
+		uintmax_t m;
+		if (parse_mark(p, &m, &x))
+			die("Invalid mark: %s", p);
+		oe = find_mark(m);
 		hashcpy(sha1, oe->sha1);
 		p = x;
 	} else if (!prefixcmp(p, "inline")) {
@@ -2045,7 +2069,11 @@ static int cmd_from(struct branch *b)
 		hashcpy(b->branch_tree.versions[0].sha1, t);
 		hashcpy(b->branch_tree.versions[1].sha1, t);
 	} else if (*from == ':') {
-		uintmax_t idnum = strtoumax(from + 1, NULL, 10);
+		char *after_mark;
+		uintmax_t idnum;
+		if (parse_mark(from, &idnum, &after_mark) ||
+			*after_mark != '\0')
+			die("Not a valid mark: %s", from);
 		struct object_entry *oe = find_mark(idnum);
 		if (oe->type != OBJ_COMMIT)
 			die("Mark :%" PRIuMAX " not a commit", idnum);
@@ -2080,7 +2108,11 @@ static struct hash_list *cmd_merge(unsigned int *count)
 		if (s)
 			hashcpy(n->sha1, s->sha1);
 		else if (*from == ':') {
-			uintmax_t idnum = strtoumax(from + 1, NULL, 10);
+			char *after_mark;
+			uintmax_t idnum;
+			if (parse_mark(from, &idnum, &after_mark) ||
+				*after_mark != '\0')
+				die("Not a valid mark: %s", from);
 			struct object_entry *oe = find_mark(idnum);
 			if (oe->type != OBJ_COMMIT)
 				die("Mark :%" PRIuMAX " not a commit", idnum);
@@ -2228,7 +2260,10 @@ static void cmd_new_tag(void)
 		hashcpy(sha1, s->sha1);
 	} else if (*from == ':') {
 		struct object_entry *oe;
-		from_mark = strtoumax(from + 1, NULL, 10);
+		char *after_mark;
+		if (parse_mark(from, &from_mark, &after_mark) ||
+			*after_mark != '\0')
+			die("Not a valid mark: %s", from);
 		oe = find_mark(from_mark);
 		if (oe->type != OBJ_COMMIT)
 			die("Mark :%" PRIuMAX " not a commit", from_mark);
@@ -2333,9 +2368,8 @@ static void import_marks(const char *input_file)
 		if (line[0] != ':' || !end)
 			die("corrupt mark line: %s", line);
 		*end = 0;
-		mark = strtoumax(line + 1, &end, 10);
-		if (!mark || end == line + 1
-			|| *end != ' ' || get_sha1(end + 1, sha1))
+		if (parse_mark(line, &mark, &end) || !mark ||
+			*end != ' ' || get_sha1(end + 1, sha1))
 			die("corrupt mark line: %s", line);
 		e = find_object(sha1);
 		if (!e) {

Bye, Jörg.
-- 
Wer eher stirbt ist länger tot.
    	 	    	       			(Un B. Kant)

Attachment: signature.asc
Description: Digital signature http://en.wikipedia.org/wiki/OpenPGP


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux