name-hash: use expand_to_path()

A sparse-index loads the name-hash data for its entries, including the
sparse-directory entries. If a caller asks for a path that is contained
within a sparse-directory entry, we need to expand to a full index and
recalculate the name hash table before returning the result. Insert
calls to expand_to_path() to protect against this case.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Reviewed-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Derrick Stolee 2021-04-12 21:08:17 +00:00 committed by Junio C Hamano
parent 71f82d032f
commit 4589bca829

View File

@ -8,6 +8,7 @@
#include "cache.h" #include "cache.h"
#include "thread-utils.h" #include "thread-utils.h"
#include "trace2.h" #include "trace2.h"
#include "sparse-index.h"
struct dir_entry { struct dir_entry {
struct hashmap_entry ent; struct hashmap_entry ent;
@ -683,6 +684,7 @@ int index_dir_exists(struct index_state *istate, const char *name, int namelen)
struct dir_entry *dir; struct dir_entry *dir;
lazy_init_name_hash(istate); lazy_init_name_hash(istate);
expand_to_path(istate, name, namelen, 0);
dir = find_dir_entry(istate, name, namelen); dir = find_dir_entry(istate, name, namelen);
return dir && dir->nr; return dir && dir->nr;
} }
@ -693,6 +695,7 @@ void adjust_dirname_case(struct index_state *istate, char *name)
const char *ptr = startPtr; const char *ptr = startPtr;
lazy_init_name_hash(istate); lazy_init_name_hash(istate);
expand_to_path(istate, name, strlen(name), 0);
while (*ptr) { while (*ptr) {
while (*ptr && *ptr != '/') while (*ptr && *ptr != '/')
ptr++; ptr++;
@ -716,6 +719,7 @@ struct cache_entry *index_file_exists(struct index_state *istate, const char *na
unsigned int hash = memihash(name, namelen); unsigned int hash = memihash(name, namelen);
lazy_init_name_hash(istate); lazy_init_name_hash(istate);
expand_to_path(istate, name, namelen, icase);
ce = hashmap_get_entry_from_hash(&istate->name_hash, hash, NULL, ce = hashmap_get_entry_from_hash(&istate->name_hash, hash, NULL,
struct cache_entry, ent); struct cache_entry, ent);