@@ -80,10 +80,8 @@ void pack_report(void)
80
80
static int check_packed_git_idx (const char * path , struct packed_git * p )
81
81
{
82
82
void * idx_map ;
83
- struct pack_idx_header * hdr ;
84
83
size_t idx_size ;
85
- uint32_t version , nr , i , * index ;
86
- int fd = git_open (path );
84
+ int fd = git_open (path ), ret ;
87
85
struct stat st ;
88
86
const unsigned int hashsz = the_hash_algo -> rawsz ;
89
87
@@ -101,16 +99,32 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
101
99
idx_map = xmmap (NULL , idx_size , PROT_READ , MAP_PRIVATE , fd , 0 );
102
100
close (fd );
103
101
104
- hdr = idx_map ;
102
+ ret = load_idx (path , hashsz , idx_map , idx_size , p );
103
+
104
+ if (ret )
105
+ munmap (idx_map , idx_size );
106
+
107
+ return ret ;
108
+ }
109
+
110
+ int load_idx (const char * path , const unsigned int hashsz , void * idx_map ,
111
+ size_t idx_size , struct packed_git * p )
112
+ {
113
+ struct pack_idx_header * hdr = idx_map ;
114
+ uint32_t version , nr , i , * index ;
115
+
116
+ if (idx_size < 4 * 256 + hashsz + hashsz )
117
+ return error ("index file %s is too small" , path );
118
+ if (idx_map == NULL )
119
+ return error ("empty data" );
120
+
105
121
if (hdr -> idx_signature == htonl (PACK_IDX_SIGNATURE )) {
106
122
version = ntohl (hdr -> idx_version );
107
- if (version < 2 || version > 2 ) {
108
- munmap (idx_map , idx_size );
123
+ if (version < 2 || version > 2 )
109
124
return error ("index file %s is version %" PRIu32
110
125
" and is not supported by this binary"
111
126
" (try upgrading GIT to a newer version)" ,
112
127
path , version );
113
- }
114
128
} else
115
129
version = 1 ;
116
130
@@ -120,10 +134,8 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
120
134
index += 2 ; /* skip index header */
121
135
for (i = 0 ; i < 256 ; i ++ ) {
122
136
uint32_t n = ntohl (index [i ]);
123
- if (n < nr ) {
124
- munmap (idx_map , idx_size );
137
+ if (n < nr )
125
138
return error ("non-monotonic index %s" , path );
126
- }
127
139
nr = n ;
128
140
}
129
141
@@ -135,10 +147,8 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
135
147
* - hash of the packfile
136
148
* - file checksum
137
149
*/
138
- if (idx_size != 4 * 256 + nr * (hashsz + 4 ) + hashsz + hashsz ) {
139
- munmap (idx_map , idx_size );
150
+ if (idx_size != 4 * 256 + nr * (hashsz + 4 ) + hashsz + hashsz )
140
151
return error ("wrong index v1 file size in %s" , path );
141
- }
142
152
} else if (version == 2 ) {
143
153
/*
144
154
* Minimum size:
@@ -157,20 +167,16 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
157
167
unsigned long max_size = min_size ;
158
168
if (nr )
159
169
max_size += (nr - 1 )* 8 ;
160
- if (idx_size < min_size || idx_size > max_size ) {
161
- munmap (idx_map , idx_size );
170
+ if (idx_size < min_size || idx_size > max_size )
162
171
return error ("wrong index v2 file size in %s" , path );
163
- }
164
172
if (idx_size != min_size &&
165
173
/*
166
174
* make sure we can deal with large pack offsets.
167
175
* 31-bit signed offset won't be enough, neither
168
176
* 32-bit unsigned one will be.
169
177
*/
170
- (sizeof (off_t ) <= 4 )) {
171
- munmap (idx_map , idx_size );
178
+ (sizeof (off_t ) <= 4 ))
172
179
return error ("pack too large for current definition of off_t in %s" , path );
173
- }
174
180
}
175
181
176
182
p -> index_version = version ;
0 commit comments