@@ -1499,6 +1499,7 @@ struct ondisk_cache_entry_extended {
14991499};
15001500
15011501/* These are only used for v3 or lower */
1502+ #define align_padding_size (size , len ) ((size + (len) + 8) & ~7) - (size + len)
15021503#define align_flex_name (STRUCT ,len ) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7)
15031504#define ondisk_cache_entry_size (len ) align_flex_name(ondisk_cache_entry,len)
15041505#define ondisk_cache_entry_extended_size (len ) align_flex_name(ondisk_cache_entry_extended,len)
@@ -2032,7 +2033,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
20322033}
20332034
20342035/* Copy miscellaneous fields but not the name */
2035- static char * copy_cache_entry_to_ondisk (struct ondisk_cache_entry * ondisk ,
2036+ static void copy_cache_entry_to_ondisk (struct ondisk_cache_entry * ondisk ,
20362037 struct cache_entry * ce )
20372038{
20382039 short flags ;
@@ -2056,32 +2057,35 @@ static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
20562057 struct ondisk_cache_entry_extended * ondisk2 ;
20572058 ondisk2 = (struct ondisk_cache_entry_extended * )ondisk ;
20582059 ondisk2 -> flags2 = htons ((ce -> ce_flags & CE_EXTENDED_FLAGS ) >> 16 );
2059- return ondisk2 -> name ;
2060- }
2061- else {
2062- return ondisk -> name ;
20632060 }
20642061}
20652062
20662063static int ce_write_entry (git_SHA_CTX * c , int fd , struct cache_entry * ce ,
2067- struct strbuf * previous_name )
2064+ struct strbuf * previous_name , struct ondisk_cache_entry * ondisk )
20682065{
20692066 int size ;
2070- struct ondisk_cache_entry * ondisk ;
20712067 int saved_namelen = saved_namelen ; /* compiler workaround */
2072- char * name ;
20732068 int result ;
2069+ static unsigned char padding [8 ] = { 0x00 };
20742070
20752071 if (ce -> ce_flags & CE_STRIP_NAME ) {
20762072 saved_namelen = ce_namelen (ce );
20772073 ce -> ce_namelen = 0 ;
20782074 }
20792075
2076+ if (ce -> ce_flags & CE_EXTENDED )
2077+ size = offsetof(struct ondisk_cache_entry_extended , name );
2078+ else
2079+ size = offsetof(struct ondisk_cache_entry , name );
2080+
20802081 if (!previous_name ) {
2081- size = ondisk_ce_size (ce );
2082- ondisk = xcalloc (1 , size );
2083- name = copy_cache_entry_to_ondisk (ondisk , ce );
2084- memcpy (name , ce -> name , ce_namelen (ce ));
2082+ int len = ce_namelen (ce );
2083+ copy_cache_entry_to_ondisk (ondisk , ce );
2084+ result = ce_write (c , fd , ondisk , size );
2085+ if (!result )
2086+ result = ce_write (c , fd , ce -> name , len );
2087+ if (!result )
2088+ result = ce_write (c , fd , padding , align_padding_size (size , len ));
20852089 } else {
20862090 int common , to_remove , prefix_size ;
20872091 unsigned char to_remove_vi [16 ];
@@ -2094,16 +2098,12 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
20942098 to_remove = previous_name -> len - common ;
20952099 prefix_size = encode_varint (to_remove , to_remove_vi );
20962100
2097- if (ce -> ce_flags & CE_EXTENDED )
2098- size = offsetof(struct ondisk_cache_entry_extended , name );
2099- else
2100- size = offsetof(struct ondisk_cache_entry , name );
2101- size += prefix_size + (ce_namelen (ce ) - common + 1 );
2102-
2103- ondisk = xcalloc (1 , size );
2104- name = copy_cache_entry_to_ondisk (ondisk , ce );
2105- memcpy (name , to_remove_vi , prefix_size );
2106- memcpy (name + prefix_size , ce -> name + common , ce_namelen (ce ) - common );
2101+ copy_cache_entry_to_ondisk (ondisk , ce );
2102+ result = ce_write (c , fd , ondisk , size );
2103+ if (!result )
2104+ result = ce_write (c , fd , to_remove_vi , prefix_size );
2105+ if (!result )
2106+ result = ce_write (c , fd , ce -> name + common , ce_namelen (ce ) - common + 1 );
21072107
21082108 strbuf_splice (previous_name , common , to_remove ,
21092109 ce -> name + common , ce_namelen (ce ) - common );
@@ -2113,8 +2113,6 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
21132113 ce -> ce_flags &= ~CE_STRIP_NAME ;
21142114 }
21152115
2116- result = ce_write (c , fd , ondisk , size );
2117- free (ondisk );
21182116 return result ;
21192117}
21202118
@@ -2192,10 +2190,11 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
21922190 int newfd = tempfile -> fd ;
21932191 git_SHA_CTX c ;
21942192 struct cache_header hdr ;
2195- int i , err , removed , extended , hdr_version ;
2193+ int i , err = 0 , removed , extended , hdr_version ;
21962194 struct cache_entry * * cache = istate -> cache ;
21972195 int entries = istate -> cache_nr ;
21982196 struct stat st ;
2197+ struct ondisk_cache_entry_extended ondisk ;
21992198 struct strbuf previous_name_buf = STRBUF_INIT , * previous_name ;
22002199 int drop_cache_tree = 0 ;
22012200
@@ -2232,6 +2231,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
22322231 return -1 ;
22332232
22342233 previous_name = (hdr_version == 4 ) ? & previous_name_buf : NULL ;
2234+
22352235 for (i = 0 ; i < entries ; i ++ ) {
22362236 struct cache_entry * ce = cache [i ];
22372237 if (ce -> ce_flags & CE_REMOVE )
@@ -2247,15 +2247,21 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
22472247 if (allow )
22482248 warning (msg , ce -> name );
22492249 else
2250- return error (msg , ce -> name );
2250+ err = error (msg , ce -> name );
22512251
22522252 drop_cache_tree = 1 ;
22532253 }
2254- if (ce_write_entry (& c , newfd , ce , previous_name ) < 0 )
2255- return -1 ;
2254+ if (ce_write_entry (& c , newfd , ce , previous_name , (struct ondisk_cache_entry * )& ondisk ) < 0 )
2255+ err = -1 ;
2256+
2257+ if (err )
2258+ break ;
22562259 }
22572260 strbuf_release (& previous_name_buf );
22582261
2262+ if (err )
2263+ return err ;
2264+
22592265 /* Write extension data here */
22602266 if (!strip_extensions && istate -> split_index ) {
22612267 struct strbuf sb = STRBUF_INIT ;
0 commit comments