@@ -2207,6 +2207,59 @@ static uintmax_t change_note_fanout(struct tree_entry *root,
22072207 return do_change_note_fanout (root , root , hex_sha1 , 0 , path , 0 , fanout );
22082208}
22092209
2210+ /*
2211+ * Given a pointer into a string, parse a mark reference:
2212+ *
2213+ * idnum ::= ':' bigint;
2214+ *
2215+ * Return the first character after the value in *endptr.
2216+ *
2217+ * Complain if the following character is not what is expected,
2218+ * either a space or end of the string.
2219+ */
2220+ static uintmax_t parse_mark_ref (const char * p , char * * endptr )
2221+ {
2222+ uintmax_t mark ;
2223+
2224+ assert (* p == ':' );
2225+ p ++ ;
2226+ mark = strtoumax (p , endptr , 10 );
2227+ if (* endptr == p )
2228+ die ("No value after ':' in mark: %s" , command_buf .buf );
2229+ return mark ;
2230+ }
2231+
2232+ /*
2233+ * Parse the mark reference, and complain if this is not the end of
2234+ * the string.
2235+ */
2236+ static uintmax_t parse_mark_ref_eol (const char * p )
2237+ {
2238+ char * end ;
2239+ uintmax_t mark ;
2240+
2241+ mark = parse_mark_ref (p , & end );
2242+ if (* end != '\0' )
2243+ die ("Garbage after mark: %s" , command_buf .buf );
2244+ return mark ;
2245+ }
2246+
2247+ /*
2248+ * Parse the mark reference, demanding a trailing space. Return a
2249+ * pointer to the space.
2250+ */
2251+ static uintmax_t parse_mark_ref_space (const char * * p )
2252+ {
2253+ uintmax_t mark ;
2254+ char * end ;
2255+
2256+ mark = parse_mark_ref (* p , & end );
2257+ if (* end != ' ' )
2258+ die ("Missing space after mark: %s" , command_buf .buf );
2259+ * p = end ;
2260+ return mark ;
2261+ }
2262+
22102263static void file_change_m (struct branch * b )
22112264{
22122265 const char * p = command_buf .buf + 2 ;
@@ -2235,21 +2288,21 @@ static void file_change_m(struct branch *b)
22352288 }
22362289
22372290 if (* p == ':' ) {
2238- char * x ;
2239- oe = find_mark (strtoumax (p + 1 , & x , 10 ));
2291+ oe = find_mark (parse_mark_ref_space (& p ));
22402292 hashcpy (sha1 , oe -> idx .sha1 );
2241- p = x ;
2242- } else if (!prefixcmp (p , "inline" )) {
2293+ } else if (!prefixcmp (p , "inline " )) {
22432294 inline_data = 1 ;
2244- p += 6 ;
2295+ p += strlen ( "inline" ); /* advance to space */
22452296 } else {
22462297 if (get_sha1_hex (p , sha1 ))
2247- die ("Invalid SHA1 : %s" , command_buf .buf );
2298+ die ("Invalid dataref : %s" , command_buf .buf );
22482299 oe = find_object (sha1 );
22492300 p += 40 ;
2301+ if (* p != ' ' )
2302+ die ("Missing space after SHA1: %s" , command_buf .buf );
22502303 }
2251- if (* p ++ != ' ' )
2252- die ( "Missing space after SHA1: %s" , command_buf . buf );
2304+ assert (* p == ' ' );
2305+ p ++ ; /* skip space */
22532306
22542307 strbuf_reset (& uq );
22552308 if (!unquote_c_style (& uq , p , & endp )) {
@@ -2407,21 +2460,21 @@ static void note_change_n(struct branch *b, unsigned char *old_fanout)
24072460 /* Now parse the notemodify command. */
24082461 /* <dataref> or 'inline' */
24092462 if (* p == ':' ) {
2410- char * x ;
2411- oe = find_mark (strtoumax (p + 1 , & x , 10 ));
2463+ oe = find_mark (parse_mark_ref_space (& p ));
24122464 hashcpy (sha1 , oe -> idx .sha1 );
2413- p = x ;
2414- } else if (!prefixcmp (p , "inline" )) {
2465+ } else if (!prefixcmp (p , "inline " )) {
24152466 inline_data = 1 ;
2416- p += 6 ;
2467+ p += strlen ( "inline" ); /* advance to space */
24172468 } else {
24182469 if (get_sha1_hex (p , sha1 ))
2419- die ("Invalid SHA1 : %s" , command_buf .buf );
2470+ die ("Invalid dataref : %s" , command_buf .buf );
24202471 oe = find_object (sha1 );
24212472 p += 40 ;
2473+ if (* p != ' ' )
2474+ die ("Missing space after SHA1: %s" , command_buf .buf );
24222475 }
2423- if (* p ++ != ' ' )
2424- die ( "Missing space after SHA1: %s" , command_buf . buf );
2476+ assert (* p == ' ' );
2477+ p ++ ; /* skip space */
24252478
24262479 /* <committish> */
24272480 s = lookup_branch (p );
@@ -2430,7 +2483,7 @@ static void note_change_n(struct branch *b, unsigned char *old_fanout)
24302483 die ("Can't add a note on empty branch." );
24312484 hashcpy (commit_sha1 , s -> sha1 );
24322485 } else if (* p == ':' ) {
2433- uintmax_t commit_mark = strtoumax ( p + 1 , NULL , 10 );
2486+ uintmax_t commit_mark = parse_mark_ref_eol ( p );
24342487 struct object_entry * commit_oe = find_mark (commit_mark );
24352488 if (commit_oe -> type != OBJ_COMMIT )
24362489 die ("Mark :%" PRIuMAX " not a commit" , commit_mark );
@@ -2537,7 +2590,7 @@ static int parse_from(struct branch *b)
25372590 hashcpy (b -> branch_tree .versions [0 ].sha1 , t );
25382591 hashcpy (b -> branch_tree .versions [1 ].sha1 , t );
25392592 } else if (* from == ':' ) {
2540- uintmax_t idnum = strtoumax (from + 1 , NULL , 10 );
2593+ uintmax_t idnum = parse_mark_ref_eol (from );
25412594 struct object_entry * oe = find_mark (idnum );
25422595 if (oe -> type != OBJ_COMMIT )
25432596 die ("Mark :%" PRIuMAX " not a commit" , idnum );
@@ -2572,7 +2625,7 @@ static struct hash_list *parse_merge(unsigned int *count)
25722625 if (s )
25732626 hashcpy (n -> sha1 , s -> sha1 );
25742627 else if (* from == ':' ) {
2575- uintmax_t idnum = strtoumax (from + 1 , NULL , 10 );
2628+ uintmax_t idnum = parse_mark_ref_eol (from );
25762629 struct object_entry * oe = find_mark (idnum );
25772630 if (oe -> type != OBJ_COMMIT )
25782631 die ("Mark :%" PRIuMAX " not a commit" , idnum );
@@ -2735,7 +2788,7 @@ static void parse_new_tag(void)
27352788 type = OBJ_COMMIT ;
27362789 } else if (* from == ':' ) {
27372790 struct object_entry * oe ;
2738- from_mark = strtoumax (from + 1 , NULL , 10 );
2791+ from_mark = parse_mark_ref_eol (from );
27392792 oe = find_mark (from_mark );
27402793 type = oe -> type ;
27412794 hashcpy (sha1 , oe -> idx .sha1 );
@@ -2867,18 +2920,13 @@ static void parse_cat_blob(void)
28672920 /* cat-blob SP <object> LF */
28682921 p = command_buf .buf + strlen ("cat-blob " );
28692922 if (* p == ':' ) {
2870- char * x ;
2871- oe = find_mark (strtoumax (p + 1 , & x , 10 ));
2872- if (x == p + 1 )
2873- die ("Invalid mark: %s" , command_buf .buf );
2923+ oe = find_mark (parse_mark_ref_eol (p ));
28742924 if (!oe )
28752925 die ("Unknown mark: %s" , command_buf .buf );
2876- if (* x )
2877- die ("Garbage after mark: %s" , command_buf .buf );
28782926 hashcpy (sha1 , oe -> idx .sha1 );
28792927 } else {
28802928 if (get_sha1_hex (p , sha1 ))
2881- die ("Invalid SHA1 : %s" , command_buf .buf );
2929+ die ("Invalid dataref : %s" , command_buf .buf );
28822930 if (p [40 ])
28832931 die ("Garbage after SHA1: %s" , command_buf .buf );
28842932 oe = find_object (sha1 );
@@ -2944,17 +2992,13 @@ static struct object_entry *parse_treeish_dataref(const char **p)
29442992 struct object_entry * e ;
29452993
29462994 if (* * p == ':' ) { /* <mark> */
2947- char * endptr ;
2948- e = find_mark (strtoumax (* p + 1 , & endptr , 10 ));
2949- if (endptr == * p + 1 )
2950- die ("Invalid mark: %s" , command_buf .buf );
2995+ e = find_mark (parse_mark_ref_space (p ));
29512996 if (!e )
29522997 die ("Unknown mark: %s" , command_buf .buf );
2953- * p = endptr ;
29542998 hashcpy (sha1 , e -> idx .sha1 );
29552999 } else { /* <sha1> */
29563000 if (get_sha1_hex (* p , sha1 ))
2957- die ("Invalid SHA1 : %s" , command_buf .buf );
3001+ die ("Invalid dataref : %s" , command_buf .buf );
29583002 e = find_object (sha1 );
29593003 * p += 40 ;
29603004 }
0 commit comments