@@ -56,8 +56,8 @@ struct git_indexer {
5656 git_vector deltas ;
5757 unsigned int fanout [256 ];
5858 git_hash_ctx hash_ctx ;
59- unsigned char checksum [GIT_HASH_SHA1_SIZE ];
60- char name [(GIT_HASH_SHA1_SIZE * 2 ) + 1 ];
59+ unsigned char checksum [GIT_HASH_MAX_SIZE ];
60+ char name [(GIT_HASH_MAX_SIZE * 2 ) + 1 ];
6161 git_indexer_progress_cb progress_cb ;
6262 void * progress_payload ;
6363 char objbuf [8 * 1024 ];
@@ -69,7 +69,7 @@ struct git_indexer {
6969 git_odb * odb ;
7070
7171 /* Fields for calculating the packfile trailer (hash of everything before it) */
72- char inbuf [GIT_OID_MAX_SIZE ];
72+ char inbuf [GIT_HASH_MAX_SIZE ];
7373 size_t inbuf_len ;
7474 git_hash_ctx trailer ;
7575};
@@ -137,6 +137,20 @@ int git_indexer_init_options(git_indexer_options *opts, unsigned int version)
137137}
138138#endif
139139
140+ GIT_INLINE (git_hash_algorithm_t ) indexer_hash_algorithm (git_indexer * idx )
141+ {
142+ switch (idx -> oid_type ) {
143+ case GIT_OID_SHA1 :
144+ return GIT_HASH_ALGORITHM_SHA1 ;
145+ #ifdef GIT_EXPERIMENTAL_SHA256
146+ case GIT_OID_SHA256 :
147+ return GIT_HASH_ALGORITHM_SHA256 ;
148+ #endif
149+ }
150+
151+ return GIT_HASH_ALGORITHM_NONE ;
152+ }
153+
140154static int indexer_new (
141155 git_indexer * * out ,
142156 const char * prefix ,
@@ -149,6 +163,7 @@ static int indexer_new(
149163 git_indexer * idx ;
150164 git_str path = GIT_STR_INIT , tmp_path = GIT_STR_INIT ;
151165 static const char suff [] = "/pack" ;
166+ git_hash_algorithm_t checksum_type ;
152167 int error , fd = -1 ;
153168
154169 if (in_opts )
@@ -163,8 +178,10 @@ static int indexer_new(
163178 idx -> mode = mode ? mode : GIT_PACK_FILE_MODE ;
164179 git_str_init (& idx -> entry_data , 0 );
165180
166- if ((error = git_hash_ctx_init (& idx -> hash_ctx , GIT_HASH_ALGORITHM_SHA1 )) < 0 ||
167- (error = git_hash_ctx_init (& idx -> trailer , GIT_HASH_ALGORITHM_SHA1 )) < 0 ||
181+ checksum_type = indexer_hash_algorithm (idx );
182+
183+ if ((error = git_hash_ctx_init (& idx -> hash_ctx , checksum_type )) < 0 ||
184+ (error = git_hash_ctx_init (& idx -> trailer , checksum_type )) < 0 ||
168185 (error = git_oidmap_new (& idx -> expected_oids )) < 0 )
169186 goto cleanup ;
170187
@@ -182,8 +199,7 @@ static int indexer_new(
182199 if (fd < 0 )
183200 goto cleanup ;
184201
185- /* TODO: SHA256 */
186- error = git_packfile_alloc (& idx -> pack , git_str_cstr (& tmp_path ), 0 );
202+ error = git_packfile_alloc (& idx -> pack , git_str_cstr (& tmp_path ), oid_type );
187203 git_str_dispose (& tmp_path );
188204
189205 if (error < 0 )
@@ -614,7 +630,7 @@ static int do_progress_callback(git_indexer *idx, git_indexer_progress *stats)
614630 return 0 ;
615631}
616632
617- /* Hash everything but the last 20B of input */
633+ /* Hash everything but the checksum trailer */
618634static void hash_partially (git_indexer * idx , const uint8_t * data , size_t size )
619635{
620636 size_t to_expell , to_keep ;
@@ -623,7 +639,10 @@ static void hash_partially(git_indexer *idx, const uint8_t *data, size_t size)
623639 if (size == 0 )
624640 return ;
625641
626- /* Easy case, dump the buffer and the data minus the last 20 bytes */
642+ /*
643+ * Easy case, dump the buffer and the data minus the trailing
644+ * checksum (SHA1 or SHA256).
645+ */
627646 if (size >= oid_size ) {
628647 git_hash_update (& idx -> trailer , idx -> inbuf , idx -> inbuf_len );
629648 git_hash_update (& idx -> trailer , data , size - oid_size );
@@ -761,12 +780,14 @@ static int read_stream_object(git_indexer *idx, git_indexer_progress *stats)
761780{
762781 git_packfile_stream * stream = & idx -> stream ;
763782 off64_t entry_start = idx -> off ;
764- size_t entry_size ;
783+ size_t oid_size , entry_size ;
765784 git_object_t type ;
766785 git_mwindow * w = NULL ;
767786 int error ;
768787
769- if (idx -> pack -> mwf .size <= idx -> off + 20 )
788+ oid_size = git_oid_size (idx -> oid_type );
789+
790+ if (idx -> pack -> mwf .size <= idx -> off + (long long )oid_size )
770791 return GIT_EBUFS ;
771792
772793 if (!idx -> have_stream ) {
@@ -963,15 +984,17 @@ static int inject_object(git_indexer *idx, git_oid *id)
963984 git_odb_object * obj = NULL ;
964985 struct entry * entry = NULL ;
965986 struct git_pack_entry * pentry = NULL ;
966- unsigned char empty_checksum [GIT_HASH_SHA1_SIZE ] = {0 };
987+ unsigned char empty_checksum [GIT_HASH_MAX_SIZE ] = {0 };
967988 unsigned char hdr [64 ];
968989 git_str buf = GIT_STR_INIT ;
969990 off64_t entry_start ;
970991 const void * data ;
971992 size_t len , hdr_len ;
972- size_t checksum_size = GIT_HASH_SHA1_SIZE ;
993+ size_t checksum_size ;
973994 int error ;
974995
996+ checksum_size = git_hash_size (indexer_hash_algorithm (idx ));
997+
975998 if ((error = seek_back_trailer (idx )) < 0 )
976999 goto cleanup ;
9771000
@@ -1205,17 +1228,20 @@ int git_indexer_commit(git_indexer *idx, git_indexer_progress *stats)
12051228 struct git_pack_idx_header hdr ;
12061229 git_str filename = GIT_STR_INIT ;
12071230 struct entry * entry ;
1208- unsigned char checksum [GIT_HASH_SHA1_SIZE ];
1231+ unsigned char checksum [GIT_HASH_MAX_SIZE ];
12091232 git_filebuf index_file = {0 };
12101233 void * packfile_trailer ;
1211- size_t checksum_size = GIT_HASH_SHA1_SIZE ;
1234+ size_t checksum_size ;
12121235 bool mismatch ;
12131236
12141237 if (!idx -> parsed_header ) {
12151238 git_error_set (GIT_ERROR_INDEXER , "incomplete pack header" );
12161239 return -1 ;
12171240 }
12181241
1242+ checksum_size = git_hash_size (indexer_hash_algorithm (idx ));
1243+ GIT_ASSERT (checksum_size );
1244+
12191245 /* Test for this before resolve_deltas(), as it plays with idx->off */
12201246 if (idx -> off + (ssize_t )checksum_size < idx -> pack -> mwf .size ) {
12211247 git_error_set (GIT_ERROR_INDEXER , "unexpected data at the end of the pack" );
0 commit comments