@@ -1873,17 +1873,28 @@ static int read_index_extension(struct index_state *istate,
1873
1873
return 0 ;
1874
1874
}
1875
1875
1876
+ /*
1877
+ * Parses the contents of the cache entry contained within the 'ondisk' buffer
1878
+ * into a new incore 'cache_entry'.
1879
+ *
1880
+ * Note that 'char *ondisk' may not be aligned to a 4-byte address interval in
1881
+ * index v4, so we cannot cast it to 'struct ondisk_cache_entry *' and access
1882
+ * its members. Instead, we use the byte offsets of members within the struct to
1883
+ * identify where 'get_be16()', 'get_be32()', and 'oidread()' (which can all
1884
+ * read from an unaligned memory buffer) should read from the 'ondisk' buffer
1885
+ * into the corresponding incore 'cache_entry' members.
1886
+ */
1876
1887
static struct cache_entry * create_from_disk (struct mem_pool * ce_mem_pool ,
1877
1888
unsigned int version ,
1878
- struct ondisk_cache_entry * ondisk ,
1889
+ const char * ondisk ,
1879
1890
unsigned long * ent_size ,
1880
1891
const struct cache_entry * previous_ce )
1881
1892
{
1882
1893
struct cache_entry * ce ;
1883
1894
size_t len ;
1884
1895
const char * name ;
1885
1896
const unsigned hashsz = the_hash_algo -> rawsz ;
1886
- const uint16_t * flagsp = ( const uint16_t * )( ondisk -> data + hashsz ) ;
1897
+ const char * flagsp = ondisk + offsetof( struct ondisk_cache_entry , data ) + hashsz ;
1887
1898
unsigned int flags ;
1888
1899
size_t copy_len = 0 ;
1889
1900
/*
@@ -1901,15 +1912,15 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
1901
1912
1902
1913
if (flags & CE_EXTENDED ) {
1903
1914
int extended_flags ;
1904
- extended_flags = get_be16 (flagsp + 1 ) << 16 ;
1915
+ extended_flags = get_be16 (flagsp + sizeof ( uint16_t ) ) << 16 ;
1905
1916
/* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
1906
1917
if (extended_flags & ~CE_EXTENDED_FLAGS )
1907
1918
die (_ ("unknown index entry format 0x%08x" ), extended_flags );
1908
1919
flags |= extended_flags ;
1909
- name = (const char * )(flagsp + 2 );
1920
+ name = (const char * )(flagsp + 2 * sizeof ( uint16_t ) );
1910
1921
}
1911
1922
else
1912
- name = (const char * )(flagsp + 1 );
1923
+ name = (const char * )(flagsp + sizeof ( uint16_t ) );
1913
1924
1914
1925
if (expand_name_field ) {
1915
1926
const unsigned char * cp = (const unsigned char * )name ;
@@ -1935,20 +1946,32 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
1935
1946
1936
1947
ce = mem_pool__ce_alloc (ce_mem_pool , len );
1937
1948
1938
- ce -> ce_stat_data .sd_ctime .sec = get_be32 (& ondisk -> ctime .sec );
1939
- ce -> ce_stat_data .sd_mtime .sec = get_be32 (& ondisk -> mtime .sec );
1940
- ce -> ce_stat_data .sd_ctime .nsec = get_be32 (& ondisk -> ctime .nsec );
1941
- ce -> ce_stat_data .sd_mtime .nsec = get_be32 (& ondisk -> mtime .nsec );
1942
- ce -> ce_stat_data .sd_dev = get_be32 (& ondisk -> dev );
1943
- ce -> ce_stat_data .sd_ino = get_be32 (& ondisk -> ino );
1944
- ce -> ce_mode = get_be32 (& ondisk -> mode );
1945
- ce -> ce_stat_data .sd_uid = get_be32 (& ondisk -> uid );
1946
- ce -> ce_stat_data .sd_gid = get_be32 (& ondisk -> gid );
1947
- ce -> ce_stat_data .sd_size = get_be32 (& ondisk -> size );
1949
+ /*
1950
+ * NEEDSWORK: using 'offsetof()' is cumbersome and should be replaced
1951
+ * with something more akin to 'load_bitmap_entries_v1()'s use of
1952
+ * 'read_be16'/'read_be32'. For consistency with the corresponding
1953
+ * ondisk entry write function ('copy_cache_entry_to_ondisk()'), this
1954
+ * should be done at the same time as removing references to
1955
+ * 'ondisk_cache_entry' there.
1956
+ */
1957
+ ce -> ce_stat_data .sd_ctime .sec = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , ctime )
1958
+ + offsetof(struct cache_time , sec ));
1959
+ ce -> ce_stat_data .sd_mtime .sec = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , mtime )
1960
+ + offsetof(struct cache_time , sec ));
1961
+ ce -> ce_stat_data .sd_ctime .nsec = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , ctime )
1962
+ + offsetof(struct cache_time , nsec ));
1963
+ ce -> ce_stat_data .sd_mtime .nsec = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , mtime )
1964
+ + offsetof(struct cache_time , nsec ));
1965
+ ce -> ce_stat_data .sd_dev = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , dev ));
1966
+ ce -> ce_stat_data .sd_ino = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , ino ));
1967
+ ce -> ce_mode = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , mode ));
1968
+ ce -> ce_stat_data .sd_uid = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , uid ));
1969
+ ce -> ce_stat_data .sd_gid = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , gid ));
1970
+ ce -> ce_stat_data .sd_size = get_be32 (ondisk + offsetof(struct ondisk_cache_entry , size ));
1948
1971
ce -> ce_flags = flags & ~CE_NAMEMASK ;
1949
1972
ce -> ce_namelen = len ;
1950
1973
ce -> index = 0 ;
1951
- oidread (& ce -> oid , ondisk -> data );
1974
+ oidread (& ce -> oid , ( const unsigned char * ) ondisk + offsetof( struct ondisk_cache_entry , data ) );
1952
1975
1953
1976
if (expand_name_field ) {
1954
1977
if (copy_len )
@@ -2117,12 +2140,12 @@ static unsigned long load_cache_entry_block(struct index_state *istate,
2117
2140
unsigned long src_offset = start_offset ;
2118
2141
2119
2142
for (i = offset ; i < offset + nr ; i ++ ) {
2120
- struct ondisk_cache_entry * disk_ce ;
2121
2143
struct cache_entry * ce ;
2122
2144
unsigned long consumed ;
2123
2145
2124
- disk_ce = (struct ondisk_cache_entry * )(mmap + src_offset );
2125
- ce = create_from_disk (ce_mem_pool , istate -> version , disk_ce , & consumed , previous_ce );
2146
+ ce = create_from_disk (ce_mem_pool , istate -> version ,
2147
+ mmap + src_offset ,
2148
+ & consumed , previous_ce );
2126
2149
set_index_entry (istate , i , ce );
2127
2150
2128
2151
src_offset += consumed ;
0 commit comments