@@ -138,7 +138,7 @@ struct reuc_entry_internal {
138138bool git_index__enforce_unsaved_safety = false;
139139
140140/* local declarations */
141- static size_t read_extension (git_index * index , const char * buffer , size_t buffer_size );
141+ static int read_extension (size_t * read_len , git_index * index , const char * buffer , size_t buffer_size );
142142static int read_header (struct index_header * dest , const void * buffer );
143143
144144static int parse_index (git_index * index , const char * buffer , size_t buffer_size );
@@ -2526,7 +2526,7 @@ static int read_header(struct index_header *dest, const void *buffer)
25262526 return 0 ;
25272527}
25282528
2529- static size_t read_extension (git_index * index , const char * buffer , size_t buffer_size )
2529+ static int read_extension (size_t * read_len , git_index * index , const char * buffer , size_t buffer_size )
25302530{
25312531 struct index_extension dest ;
25322532 size_t total_size ;
@@ -2539,31 +2539,36 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer
25392539
25402540 if (dest .extension_size > total_size ||
25412541 buffer_size < total_size ||
2542- buffer_size - total_size < INDEX_FOOTER_SIZE )
2543- return 0 ;
2542+ buffer_size - total_size < INDEX_FOOTER_SIZE ) {
2543+ index_error_invalid ("extension is truncated" );
2544+ return -1 ;
2545+ }
25442546
25452547 /* optional extension */
25462548 if (dest .signature [0 ] >= 'A' && dest .signature [0 ] <= 'Z' ) {
25472549 /* tree cache */
25482550 if (memcmp (dest .signature , INDEX_EXT_TREECACHE_SIG , 4 ) == 0 ) {
25492551 if (git_tree_cache_read (& index -> tree , buffer + 8 , dest .extension_size , & index -> tree_pool ) < 0 )
2550- return 0 ;
2552+ return -1 ;
25512553 } else if (memcmp (dest .signature , INDEX_EXT_UNMERGED_SIG , 4 ) == 0 ) {
25522554 if (read_reuc (index , buffer + 8 , dest .extension_size ) < 0 )
2553- return 0 ;
2555+ return -1 ;
25542556 } else if (memcmp (dest .signature , INDEX_EXT_CONFLICT_NAME_SIG , 4 ) == 0 ) {
25552557 if (read_conflict_names (index , buffer + 8 , dest .extension_size ) < 0 )
2556- return 0 ;
2558+ return -1 ;
25572559 }
25582560 /* else, unsupported extension. We cannot parse this, but we can skip
25592561 * it by returning `total_size */
25602562 } else {
25612563 /* we cannot handle non-ignorable extensions;
25622564 * in fact they aren't even defined in the standard */
2563- return 0 ;
2565+ git_error_set (GIT_ERROR_INDEX , "unsupported mandatory extension: '%.4s'" , dest .signature );
2566+ return -1 ;
25642567 }
25652568
2566- return total_size ;
2569+ * read_len = total_size ;
2570+
2571+ return 0 ;
25672572}
25682573
25692574static int parse_index (git_index * index , const char * buffer , size_t buffer_size )
@@ -2645,11 +2650,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
26452650 while (buffer_size > INDEX_FOOTER_SIZE ) {
26462651 size_t extension_size ;
26472652
2648- extension_size = read_extension (index , buffer , buffer_size );
2649-
2650- /* see if we have read any bytes from the extension */
2651- if (extension_size == 0 ) {
2652- error = index_error_invalid ("extension is truncated" );
2653+ if ((error = read_extension (& extension_size , index , buffer , buffer_size )) < 0 ) {
26532654 goto done ;
26542655 }
26552656
0 commit comments