@@ -1202,71 +1202,61 @@ int read_index(struct index_state *istate)
12021202 return read_index_from (istate , get_index_file ());
12031203}
12041204
1205- static void convert_from_disk ( struct ondisk_cache_entry * ondisk , struct cache_entry * ce )
1205+ static struct cache_entry * create_from_disk ( struct ondisk_cache_entry * ondisk )
12061206{
1207+ struct cache_entry * ce ;
12071208 size_t len ;
12081209 const char * name ;
1210+ unsigned int flags ;
12091211
1210- ce -> ce_ctime .sec = ntohl (ondisk -> ctime .sec );
1211- ce -> ce_mtime .sec = ntohl (ondisk -> mtime .sec );
1212- ce -> ce_ctime .nsec = ntohl (ondisk -> ctime .nsec );
1213- ce -> ce_mtime .nsec = ntohl (ondisk -> mtime .nsec );
1214- ce -> ce_dev = ntohl (ondisk -> dev );
1215- ce -> ce_ino = ntohl (ondisk -> ino );
1216- ce -> ce_mode = ntohl (ondisk -> mode );
1217- ce -> ce_uid = ntohl (ondisk -> uid );
1218- ce -> ce_gid = ntohl (ondisk -> gid );
1219- ce -> ce_size = ntohl (ondisk -> size );
12201212 /* On-disk flags are just 16 bits */
1221- ce -> ce_flags = ntohs (ondisk -> flags );
1222-
1223- hashcpy (ce -> sha1 , ondisk -> sha1 );
1213+ flags = ntohs (ondisk -> flags );
1214+ len = flags & CE_NAMEMASK ;
12241215
1225- len = ce -> ce_flags & CE_NAMEMASK ;
1226-
1227- if (ce -> ce_flags & CE_EXTENDED ) {
1216+ if (flags & CE_EXTENDED ) {
12281217 struct ondisk_cache_entry_extended * ondisk2 ;
12291218 int extended_flags ;
12301219 ondisk2 = (struct ondisk_cache_entry_extended * )ondisk ;
12311220 extended_flags = ntohs (ondisk2 -> flags2 ) << 16 ;
12321221 /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
12331222 if (extended_flags & ~CE_EXTENDED_FLAGS )
12341223 die ("Unknown index entry format %08x" , extended_flags );
1235- ce -> ce_flags |= extended_flags ;
1224+ flags |= extended_flags ;
12361225 name = ondisk2 -> name ;
12371226 }
12381227 else
12391228 name = ondisk -> name ;
12401229
12411230 if (len == CE_NAMEMASK )
12421231 len = strlen (name );
1243- /*
1244- * NEEDSWORK: If the original index is crafted, this copy could
1245- * go unchecked.
1246- */
1247- memcpy (ce -> name , name , len + 1 );
1248- }
12491232
1250- static inline size_t estimate_cache_size (size_t ondisk_size , unsigned int entries )
1251- {
1252- long per_entry ;
1233+ ce = xmalloc (cache_entry_size (len ));
12531234
1254- per_entry = sizeof (struct cache_entry ) - sizeof (struct ondisk_cache_entry );
1235+ ce -> ce_ctime .sec = ntohl (ondisk -> ctime .sec );
1236+ ce -> ce_mtime .sec = ntohl (ondisk -> mtime .sec );
1237+ ce -> ce_ctime .nsec = ntohl (ondisk -> ctime .nsec );
1238+ ce -> ce_mtime .nsec = ntohl (ondisk -> mtime .nsec );
1239+ ce -> ce_dev = ntohl (ondisk -> dev );
1240+ ce -> ce_ino = ntohl (ondisk -> ino );
1241+ ce -> ce_mode = ntohl (ondisk -> mode );
1242+ ce -> ce_uid = ntohl (ondisk -> uid );
1243+ ce -> ce_gid = ntohl (ondisk -> gid );
1244+ ce -> ce_size = ntohl (ondisk -> size );
1245+ ce -> ce_flags = flags ;
12551246
1256- /*
1257- * Alignment can cause differences. This should be "alignof", but
1258- * since that's a gcc'ism, just use the size of a pointer.
1259- */
1260- per_entry += sizeof (void * );
1261- return ondisk_size + entries * per_entry ;
1247+ hashcpy (ce -> sha1 , ondisk -> sha1 );
1248+
1249+ memcpy (ce -> name , name , len );
1250+ ce -> name [len ] = '\0' ;
1251+ return ce ;
12621252}
12631253
12641254/* remember to discard_cache() before reading a different cache! */
12651255int read_index_from (struct index_state * istate , const char * path )
12661256{
12671257 int fd , i ;
12681258 struct stat st ;
1269- unsigned long src_offset , dst_offset ;
1259+ unsigned long src_offset ;
12701260 struct cache_header * hdr ;
12711261 void * mmap ;
12721262 size_t mmap_size ;
@@ -1305,29 +1295,18 @@ int read_index_from(struct index_state *istate, const char *path)
13051295 istate -> cache_nr = ntohl (hdr -> hdr_entries );
13061296 istate -> cache_alloc = alloc_nr (istate -> cache_nr );
13071297 istate -> cache = xcalloc (istate -> cache_alloc , sizeof (struct cache_entry * ));
1308-
1309- /*
1310- * The disk format is actually larger than the in-memory format,
1311- * due to space for nsec etc, so even though the in-memory one
1312- * has room for a few more flags, we can allocate using the same
1313- * index size
1314- */
1315- istate -> alloc = xmalloc (estimate_cache_size (mmap_size , istate -> cache_nr ));
13161298 istate -> initialized = 1 ;
13171299
13181300 src_offset = sizeof (* hdr );
1319- dst_offset = 0 ;
13201301 for (i = 0 ; i < istate -> cache_nr ; i ++ ) {
13211302 struct ondisk_cache_entry * disk_ce ;
13221303 struct cache_entry * ce ;
13231304
13241305 disk_ce = (struct ondisk_cache_entry * )((char * )mmap + src_offset );
1325- ce = (struct cache_entry * )((char * )istate -> alloc + dst_offset );
1326- convert_from_disk (disk_ce , ce );
1306+ ce = create_from_disk (disk_ce );
13271307 set_index_entry (istate , i , ce );
13281308
13291309 src_offset += ondisk_ce_size (ce );
1330- dst_offset += ce_size (ce );
13311310 }
13321311 istate -> timestamp .sec = st .st_mtime ;
13331312 istate -> timestamp .nsec = ST_MTIME_NSEC (st );
@@ -1361,11 +1340,15 @@ int read_index_from(struct index_state *istate, const char *path)
13611340
13621341int is_index_unborn (struct index_state * istate )
13631342{
1364- return (!istate -> cache_nr && !istate -> alloc && ! istate -> timestamp .sec );
1343+ return (!istate -> cache_nr && !istate -> timestamp .sec );
13651344}
13661345
13671346int discard_index (struct index_state * istate )
13681347{
1348+ int i ;
1349+
1350+ for (i = 0 ; i < istate -> cache_nr ; i ++ )
1351+ free (istate -> cache [i ]);
13691352 resolve_undo_clear_index (istate );
13701353 istate -> cache_nr = 0 ;
13711354 istate -> cache_changed = 0 ;
@@ -1374,8 +1357,6 @@ int discard_index(struct index_state *istate)
13741357 istate -> name_hash_initialized = 0 ;
13751358 free_hash (& istate -> name_hash );
13761359 cache_tree_free (& (istate -> cache_tree ));
1377- free (istate -> alloc );
1378- istate -> alloc = NULL ;
13791360 istate -> initialized = 0 ;
13801361
13811362 /* no need to throw away allocated active_cache */
0 commit comments