index: be careful when handling long names
We currently use lower 12-bit (masked with CE_NAMEMASK) in the ce_flags field to store the length of the name in cache_entry, without checking the length parameter given to create_ce_flags(). This can make us store incorrect length. Currently we are mostly protected by the fact that many codepaths first copy the path in a variable of size PATH_MAX, which typically is 4096 that happens to match the limit, but that feels like a bug waiting to happen. Besides, that would not allow us to shorten the width of CE_NAMEMASK to use the bits for new flags. This redefines the meaning of the name length stored in the cache_entry. A name that does not fit is represented by storing CE_NAMEMASK in the field, and the actual length needs to be computed by actually counting the bytes in the name[] field. This way, only the unusually long paths need to suffer. Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
7a51ed66f6
commit
7fec10b7f4
17
cache.h
17
cache.h
@ -131,8 +131,21 @@ struct cache_entry {
|
||||
#define CE_UPDATE (0x10000)
|
||||
#define CE_REMOVE (0x20000)
|
||||
|
||||
#define create_ce_flags(len, stage) ((len) | ((stage) << CE_STAGESHIFT))
|
||||
#define ce_namelen(ce) (CE_NAMEMASK & (ce)->ce_flags)
|
||||
static inline unsigned create_ce_flags(size_t len, unsigned stage)
|
||||
{
|
||||
if (len >= CE_NAMEMASK)
|
||||
len = CE_NAMEMASK;
|
||||
return (len | (stage << CE_STAGESHIFT));
|
||||
}
|
||||
|
||||
static inline size_t ce_namelen(const struct cache_entry *ce)
|
||||
{
|
||||
size_t len = ce->ce_flags & CE_NAMEMASK;
|
||||
if (len < CE_NAMEMASK)
|
||||
return len;
|
||||
return strlen(ce->name + CE_NAMEMASK) + CE_NAMEMASK;
|
||||
}
|
||||
|
||||
#define ce_size(ce) cache_entry_size(ce_namelen(ce))
|
||||
#define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce))
|
||||
#define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT)
|
||||
|
Reference in New Issue
Block a user