@@ -64,7 +64,7 @@ struct non_note {
6464#define CLR_PTR_TYPE (ptr ) ((void *) ((uintptr_t) (ptr) & ~3))
6565#define SET_PTR_TYPE (ptr , type ) ((void *) ((uintptr_t) (ptr) | (type)))
6666
67- #define GET_NIBBLE (n , sha1 ) (((sha1[(n) >> 1]) >> ((~(n) & 0x01) << 2)) & 0x0f)
67+ #define GET_NIBBLE (n , sha1 ) (((( sha1) [(n) >> 1]) >> ((~(n) & 0x01) << 2)) & 0x0f)
6868
6969#define KEY_INDEX (GIT_SHA1_RAWSZ - 1)
7070#define FANOUT_PATH_SEPARATORS ((GIT_SHA1_HEXSZ / 2) - 1)
@@ -335,31 +335,20 @@ static void note_tree_free(struct int_node *tree)
335335}
336336
337337/*
338- * Convert a partial SHA1 hex string to the corresponding partial SHA1 value.
339- * - hex - Partial SHA1 segment in ASCII hex format
340- * - hex_len - Length of above segment. Must be multiple of 2 between 0 and 40
341- * - sha1 - Partial SHA1 value is written here
342- * - sha1_len - Max #bytes to store in sha1, Must be >= hex_len / 2, and < 20
343- * Returns -1 on error (invalid arguments or invalid SHA1 (not in hex format)).
344- * Otherwise, returns number of bytes written to sha1 (i.e. hex_len / 2).
345- * Pads sha1 with NULs up to sha1_len (not included in returned length).
338+ * Read `len` pairs of hexadecimal digits from `hex` and write the
339+ * values to `binary` as `len` bytes. Return 0 on success, or -1 if
340+ * the input does not consist of hex digits).
346341 */
347- static int get_oid_hex_segment (const char * hex , unsigned int hex_len ,
348- unsigned char * oid , unsigned int oid_len )
342+ static int hex_to_bytes (unsigned char * binary , const char * hex , size_t len )
349343{
350- unsigned int i , len = hex_len >> 1 ;
351- if (hex_len % 2 != 0 || len > oid_len )
352- return -1 ;
353- for (i = 0 ; i < len ; i ++ ) {
344+ for (; len ; len -- , hex += 2 ) {
354345 unsigned int val = (hexval (hex [0 ]) << 4 ) | hexval (hex [1 ]);
346+
355347 if (val & ~0xff )
356348 return -1 ;
357- * oid ++ = val ;
358- hex += 2 ;
349+ * binary ++ = val ;
359350 }
360- for (; i < oid_len ; i ++ )
361- * oid ++ = 0 ;
362- return len ;
351+ return 0 ;
363352}
364353
365354static int non_note_cmp (const struct non_note * a , const struct non_note * b )
@@ -417,80 +406,90 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree,
417406 struct int_node * node , unsigned int n )
418407{
419408 struct object_id object_oid ;
420- unsigned int prefix_len ;
409+ size_t prefix_len ;
421410 void * buf ;
422411 struct tree_desc desc ;
423412 struct name_entry entry ;
424- int len , path_len ;
425- unsigned char type ;
426- struct leaf_node * l ;
427413
428414 buf = fill_tree_descriptor (& desc , & subtree -> val_oid );
429415 if (!buf )
430416 die ("Could not read %s for notes-index" ,
431417 oid_to_hex (& subtree -> val_oid ));
432418
433419 prefix_len = subtree -> key_oid .hash [KEY_INDEX ];
434- assert (prefix_len * 2 >= n );
420+ if (prefix_len >= GIT_SHA1_RAWSZ )
421+ BUG ("prefix_len (%" PRIuMAX ") is out of range" , (uintmax_t )prefix_len );
422+ if (prefix_len * 2 < n )
423+ BUG ("prefix_len (%" PRIuMAX ") is too small" , (uintmax_t )prefix_len );
435424 memcpy (object_oid .hash , subtree -> key_oid .hash , prefix_len );
436425 while (tree_entry (& desc , & entry )) {
437- path_len = strlen (entry .path );
438- len = get_oid_hex_segment (entry .path , path_len ,
439- object_oid .hash + prefix_len , GIT_SHA1_RAWSZ - prefix_len );
440- if (len < 0 )
441- goto handle_non_note ; /* entry.path is not a SHA1 */
442- len += prefix_len ;
426+ unsigned char type ;
427+ struct leaf_node * l ;
428+ size_t path_len = strlen (entry .path );
429+
430+ if (path_len == 2 * (GIT_SHA1_RAWSZ - prefix_len )) {
431+ /* This is potentially the remainder of the SHA-1 */
432+
433+ if (!S_ISREG (entry .mode ))
434+ /* notes must be blobs */
435+ goto handle_non_note ;
436+
437+ if (hex_to_bytes (object_oid .hash + prefix_len , entry .path ,
438+ GIT_SHA1_RAWSZ - prefix_len ))
439+ goto handle_non_note ; /* entry.path is not a SHA1 */
443440
444- /*
445- * If object SHA1 is complete (len == 20), assume note object
446- * If object SHA1 is incomplete (len < 20), and current
447- * component consists of 2 hex chars, assume note subtree
448- */
449- if (len <= GIT_SHA1_RAWSZ ) {
450441 type = PTR_TYPE_NOTE ;
451- l = (struct leaf_node * )
452- xcalloc (1 , sizeof (struct leaf_node ));
453- oidcpy (& l -> key_oid , & object_oid );
454- oidcpy (& l -> val_oid , entry .oid );
455- if (len < GIT_SHA1_RAWSZ ) {
456- if (!S_ISDIR (entry .mode ) || path_len != 2 )
457- goto handle_non_note ; /* not subtree */
458- l -> key_oid .hash [KEY_INDEX ] = (unsigned char ) len ;
459- type = PTR_TYPE_SUBTREE ;
460- }
461- if (note_tree_insert (t , node , n , l , type ,
462- combine_notes_concatenate ))
463- die ("Failed to load %s %s into notes tree "
464- "from %s" ,
465- type == PTR_TYPE_NOTE ? "note" : "subtree" ,
466- oid_to_hex (& l -> key_oid ), t -> ref );
442+ } else if (path_len == 2 ) {
443+ /* This is potentially an internal node */
444+ size_t len = prefix_len ;
445+
446+ if (!S_ISDIR (entry .mode ))
447+ /* internal nodes must be trees */
448+ goto handle_non_note ;
449+
450+ if (hex_to_bytes (object_oid .hash + len ++ , entry .path , 1 ))
451+ goto handle_non_note ; /* entry.path is not a SHA1 */
452+
453+ /*
454+ * Pad the rest of the SHA-1 with zeros,
455+ * except for the last byte, where we write
456+ * the length:
457+ */
458+ memset (object_oid .hash + len , 0 , GIT_SHA1_RAWSZ - len - 1 );
459+ object_oid .hash [KEY_INDEX ] = (unsigned char )len ;
460+
461+ type = PTR_TYPE_SUBTREE ;
462+ } else {
463+ /* This can't be part of a note */
464+ goto handle_non_note ;
467465 }
466+
467+ l = xcalloc (1 , sizeof (* l ));
468+ oidcpy (& l -> key_oid , & object_oid );
469+ oidcpy (& l -> val_oid , entry .oid );
470+ if (note_tree_insert (t , node , n , l , type ,
471+ combine_notes_concatenate ))
472+ die ("Failed to load %s %s into notes tree "
473+ "from %s" ,
474+ type == PTR_TYPE_NOTE ? "note" : "subtree" ,
475+ oid_to_hex (& l -> key_oid ), t -> ref );
476+
468477 continue ;
469478
470479handle_non_note :
471480 /*
472- * Determine full path for this non-note entry:
473- * The filename is already found in entry.path, but the
474- * directory part of the path must be deduced from the subtree
475- * containing this entry. We assume here that the overall notes
476- * tree follows a strict byte-based progressive fanout
477- * structure (i.e. using 2/38, 2/2/36, etc. fanouts, and not
478- * e.g. 4/36 fanout). This means that if a non-note is found at
479- * path "dead/beef", the following code will register it as
480- * being found on "de/ad/beef".
481- * On the other hand, if you use such non-obvious non-note
482- * paths in the middle of a notes tree, you deserve what's
483- * coming to you ;). Note that for non-notes that are not
484- * SHA1-like at the top level, there will be no problems.
485- *
486- * To conclude, it is strongly advised to make sure non-notes
487- * have at least one non-hex character in the top-level path
488- * component.
481+ * Determine full path for this non-note entry. The
482+ * filename is already found in entry.path, but the
483+ * directory part of the path must be deduced from the
484+ * subtree containing this entry based on our
485+ * knowledge that the overall notes tree follows a
486+ * strict byte-based progressive fanout structure
487+ * (i.e. using 2/38, 2/2/36, etc. fanouts).
489488 */
490489 {
491490 struct strbuf non_note_path = STRBUF_INIT ;
492491 const char * q = oid_to_hex (& subtree -> key_oid );
493- int i ;
492+ size_t i ;
494493 for (i = 0 ; i < prefix_len ; i ++ ) {
495494 strbuf_addch (& non_note_path , * q ++ );
496495 strbuf_addch (& non_note_path , * q ++ );
0 commit comments