@@ -2207,6 +2207,59 @@ static uintmax_t change_note_fanout(struct tree_entry *root,
2207
2207
return do_change_note_fanout (root , root , hex_sha1 , 0 , path , 0 , fanout );
2208
2208
}
2209
2209
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
+
2210
2263
static void file_change_m (struct branch * b )
2211
2264
{
2212
2265
const char * p = command_buf .buf + 2 ;
@@ -2235,21 +2288,21 @@ static void file_change_m(struct branch *b)
2235
2288
}
2236
2289
2237
2290
if (* p == ':' ) {
2238
- char * x ;
2239
- oe = find_mark (strtoumax (p + 1 , & x , 10 ));
2291
+ oe = find_mark (parse_mark_ref_space (& p ));
2240
2292
hashcpy (sha1 , oe -> idx .sha1 );
2241
- p = x ;
2242
- } else if (!prefixcmp (p , "inline" )) {
2293
+ } else if (!prefixcmp (p , "inline " )) {
2243
2294
inline_data = 1 ;
2244
- p += 6 ;
2295
+ p += strlen ( "inline" ); /* advance to space */
2245
2296
} else {
2246
2297
if (get_sha1_hex (p , sha1 ))
2247
- die ("Invalid SHA1 : %s" , command_buf .buf );
2298
+ die ("Invalid dataref : %s" , command_buf .buf );
2248
2299
oe = find_object (sha1 );
2249
2300
p += 40 ;
2301
+ if (* p != ' ' )
2302
+ die ("Missing space after SHA1: %s" , command_buf .buf );
2250
2303
}
2251
- if (* p ++ != ' ' )
2252
- die ( "Missing space after SHA1: %s" , command_buf . buf );
2304
+ assert (* p == ' ' );
2305
+ p ++ ; /* skip space */
2253
2306
2254
2307
strbuf_reset (& uq );
2255
2308
if (!unquote_c_style (& uq , p , & endp )) {
@@ -2407,21 +2460,21 @@ static void note_change_n(struct branch *b, unsigned char *old_fanout)
2407
2460
/* Now parse the notemodify command. */
2408
2461
/* <dataref> or 'inline' */
2409
2462
if (* p == ':' ) {
2410
- char * x ;
2411
- oe = find_mark (strtoumax (p + 1 , & x , 10 ));
2463
+ oe = find_mark (parse_mark_ref_space (& p ));
2412
2464
hashcpy (sha1 , oe -> idx .sha1 );
2413
- p = x ;
2414
- } else if (!prefixcmp (p , "inline" )) {
2465
+ } else if (!prefixcmp (p , "inline " )) {
2415
2466
inline_data = 1 ;
2416
- p += 6 ;
2467
+ p += strlen ( "inline" ); /* advance to space */
2417
2468
} else {
2418
2469
if (get_sha1_hex (p , sha1 ))
2419
- die ("Invalid SHA1 : %s" , command_buf .buf );
2470
+ die ("Invalid dataref : %s" , command_buf .buf );
2420
2471
oe = find_object (sha1 );
2421
2472
p += 40 ;
2473
+ if (* p != ' ' )
2474
+ die ("Missing space after SHA1: %s" , command_buf .buf );
2422
2475
}
2423
- if (* p ++ != ' ' )
2424
- die ( "Missing space after SHA1: %s" , command_buf . buf );
2476
+ assert (* p == ' ' );
2477
+ p ++ ; /* skip space */
2425
2478
2426
2479
/* <committish> */
2427
2480
s = lookup_branch (p );
@@ -2430,7 +2483,7 @@ static void note_change_n(struct branch *b, unsigned char *old_fanout)
2430
2483
die ("Can't add a note on empty branch." );
2431
2484
hashcpy (commit_sha1 , s -> sha1 );
2432
2485
} else if (* p == ':' ) {
2433
- uintmax_t commit_mark = strtoumax ( p + 1 , NULL , 10 );
2486
+ uintmax_t commit_mark = parse_mark_ref_eol ( p );
2434
2487
struct object_entry * commit_oe = find_mark (commit_mark );
2435
2488
if (commit_oe -> type != OBJ_COMMIT )
2436
2489
die ("Mark :%" PRIuMAX " not a commit" , commit_mark );
@@ -2537,7 +2590,7 @@ static int parse_from(struct branch *b)
2537
2590
hashcpy (b -> branch_tree .versions [0 ].sha1 , t );
2538
2591
hashcpy (b -> branch_tree .versions [1 ].sha1 , t );
2539
2592
} else if (* from == ':' ) {
2540
- uintmax_t idnum = strtoumax (from + 1 , NULL , 10 );
2593
+ uintmax_t idnum = parse_mark_ref_eol (from );
2541
2594
struct object_entry * oe = find_mark (idnum );
2542
2595
if (oe -> type != OBJ_COMMIT )
2543
2596
die ("Mark :%" PRIuMAX " not a commit" , idnum );
@@ -2572,7 +2625,7 @@ static struct hash_list *parse_merge(unsigned int *count)
2572
2625
if (s )
2573
2626
hashcpy (n -> sha1 , s -> sha1 );
2574
2627
else if (* from == ':' ) {
2575
- uintmax_t idnum = strtoumax (from + 1 , NULL , 10 );
2628
+ uintmax_t idnum = parse_mark_ref_eol (from );
2576
2629
struct object_entry * oe = find_mark (idnum );
2577
2630
if (oe -> type != OBJ_COMMIT )
2578
2631
die ("Mark :%" PRIuMAX " not a commit" , idnum );
@@ -2735,7 +2788,7 @@ static void parse_new_tag(void)
2735
2788
type = OBJ_COMMIT ;
2736
2789
} else if (* from == ':' ) {
2737
2790
struct object_entry * oe ;
2738
- from_mark = strtoumax (from + 1 , NULL , 10 );
2791
+ from_mark = parse_mark_ref_eol (from );
2739
2792
oe = find_mark (from_mark );
2740
2793
type = oe -> type ;
2741
2794
hashcpy (sha1 , oe -> idx .sha1 );
@@ -2867,18 +2920,13 @@ static void parse_cat_blob(void)
2867
2920
/* cat-blob SP <object> LF */
2868
2921
p = command_buf .buf + strlen ("cat-blob " );
2869
2922
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 ));
2874
2924
if (!oe )
2875
2925
die ("Unknown mark: %s" , command_buf .buf );
2876
- if (* x )
2877
- die ("Garbage after mark: %s" , command_buf .buf );
2878
2926
hashcpy (sha1 , oe -> idx .sha1 );
2879
2927
} else {
2880
2928
if (get_sha1_hex (p , sha1 ))
2881
- die ("Invalid SHA1 : %s" , command_buf .buf );
2929
+ die ("Invalid dataref : %s" , command_buf .buf );
2882
2930
if (p [40 ])
2883
2931
die ("Garbage after SHA1: %s" , command_buf .buf );
2884
2932
oe = find_object (sha1 );
@@ -2944,17 +2992,13 @@ static struct object_entry *parse_treeish_dataref(const char **p)
2944
2992
struct object_entry * e ;
2945
2993
2946
2994
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 ));
2951
2996
if (!e )
2952
2997
die ("Unknown mark: %s" , command_buf .buf );
2953
- * p = endptr ;
2954
2998
hashcpy (sha1 , e -> idx .sha1 );
2955
2999
} else { /* <sha1> */
2956
3000
if (get_sha1_hex (* p , sha1 ))
2957
- die ("Invalid SHA1 : %s" , command_buf .buf );
3001
+ die ("Invalid dataref : %s" , command_buf .buf );
2958
3002
e = find_object (sha1 );
2959
3003
* p += 40 ;
2960
3004
}
0 commit comments