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