* Read a delta object's header at curpos in p (already inflated as needed) * and return the size of the result object (the post-application target). */
| 1168 | * and return the size of the result object (the post-application target). |
| 1169 | */ |
| 1170 | size_t get_size_from_delta(struct packed_git *p, |
| 1171 | struct pack_window **w_curs, |
| 1172 | off_t curpos) |
| 1173 | { |
| 1174 | const unsigned char *data; |
| 1175 | unsigned char delta_head[20], *in; |
| 1176 | git_zstream stream; |
| 1177 | int st; |
| 1178 | |
| 1179 | memset(&stream, 0, sizeof(stream)); |
| 1180 | stream.next_out = delta_head; |
| 1181 | stream.avail_out = sizeof(delta_head); |
| 1182 | |
| 1183 | git_inflate_init(&stream); |
| 1184 | do { |
| 1185 | in = use_pack(p, w_curs, curpos, &stream.avail_in); |
| 1186 | stream.next_in = in; |
| 1187 | /* |
| 1188 | * Note: the window section returned by use_pack() must be |
| 1189 | * available throughout git_inflate()'s unlocked execution. To |
| 1190 | * ensure no other thread will modify the window in the |
| 1191 | * meantime, we rely on the packed_window.inuse_cnt. This |
| 1192 | * counter is incremented before window reading and checked |
| 1193 | * before window disposal. |
| 1194 | * |
| 1195 | * Other worrying sections could be the call to close_pack_fd(), |
| 1196 | * which can close packs even with in-use windows, and to |
| 1197 | * odb_reprepare(). Regarding the former, mmap doc says: |
| 1198 | * "closing the file descriptor does not unmap the region". And |
| 1199 | * for the latter, it won't re-open already available packs. |
| 1200 | */ |
| 1201 | obj_read_unlock(); |
| 1202 | st = git_inflate(&stream, Z_FINISH); |
| 1203 | obj_read_lock(); |
| 1204 | curpos += stream.next_in - in; |
| 1205 | } while ((st == Z_OK || st == Z_BUF_ERROR) && |
| 1206 | stream.total_out < sizeof(delta_head)); |
| 1207 | git_inflate_end(&stream); |
| 1208 | if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) { |
| 1209 | error("delta data unpack-initial failed"); |
| 1210 | return 0; |
| 1211 | } |
| 1212 | |
| 1213 | /* Examine the initial part of the delta to figure out |
| 1214 | * the result size. |
| 1215 | */ |
| 1216 | data = delta_head; |
| 1217 | |
| 1218 | /* ignore base size */ |
| 1219 | get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); |
| 1220 | |
| 1221 | /* Read the result size */ |
| 1222 | return get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); |
| 1223 | } |
| 1224 | |
| 1225 | int unpack_object_header(struct packed_git *p, |
| 1226 | struct pack_window **w_curs, |
no test coverage detected