Line Flow Count Block(s) Source
1 - /*
2 - * Copyright (C) the libgit2 contributors. All rights reserved.
3 - *
4 - * This file is part of libgit2, distributed under the GNU GPL v2 with
5 - * a Linking Exception. For full terms see the included COPYING file.
6 - */
7 -
8 - #include "odb.h"
9 -
10 - #include <zlib.h>
11 - #include "git2/object.h"
12 - #include "git2/sys/odb_backend.h"
13 - #include "futils.h"
14 - #include "hash.h"
15 - #include "delta.h"
16 - #include "filter.h"
17 - #include "repository.h"
18 - #include "blob.h"
19 -
20 - #include "git2/odb_backend.h"
21 - #include "git2/oid.h"
22 - #include "git2/oidarray.h"
23 -
24 - #define GIT_ALTERNATES_FILE "info/alternates"
25 -
26 - /*
27 - * We work under the assumption that most objects for long-running
28 - * operations will be packed
29 - */
30 - #define GIT_LOOSE_PRIORITY 1
31 - #define GIT_PACKED_PRIORITY 2
32 -
33 - #define GIT_ALTERNATES_MAX_DEPTH 5
34 -
35 - bool git_odb__strict_hash_verification = true;
36 -
37 - typedef struct
38 - {
39 - git_odb_backend *backend;
40 - int priority;
41 - bool is_alternate;
42 - ino_t disk_inode;
43 - } backend_internal;
44 -
45 174793 2 static git_cache *odb_cache(git_odb *odb)
46 - {
47 174793 2 if (odb->rc.owner != NULL) {
48 173764 3 git_repository *owner = odb->rc.owner;
49 173764 3 return &owner->objects;
50 - }
51 -
52 1029 4 return &odb->own_cache;
53 - }
54 -
55 - static int odb_otype_fast(git_object_t *type_p, git_odb *db, const git_oid *id);
56 - static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth);
57 - static int error_null_oid(int error, const char *message);
58 -
59 93435 2 static git_object_t odb_hardcoded_type(const git_oid *id)
60 - {
61 - static git_oid empty_tree = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
62 - 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};
63 -
64 93435 2,3 if (!git_oid_cmp(id, &empty_tree))
65 20 4 return GIT_OBJECT_TREE;
66 -
67 93355 5 return GIT_OBJECT_INVALID;
68 - }
69 -
70 80390 2 static int odb_read_hardcoded(bool *found, git_rawobj *raw, const git_oid *id)
71 - {
72 - git_object_t type;
73 -
74 80390 2 *found = false;
75 -
76 80390 2,3 if ((type = odb_hardcoded_type(id)) == GIT_OBJECT_INVALID)
77 80350 4 return 0;
78 -
79 11 5 raw->type = type;
80 11 5 raw->len = 0;
81 11 5 raw->data = git__calloc(1, sizeof(uint8_t));
82 11 6,7 GIT_ERROR_CHECK_ALLOC(raw->data);
83 -
84 11 8 *found = true;
85 11 8 return 0;
86 - }
87 -
88 - 2 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files)int git_odb__format_object_header(
89 - size_t *written,
90 - char *hdr,
91 - size_t hdr_size,
92 - git_object_size_t obj_len,
93 - git_object_t obj_type)
94 - {
95 - 2 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) const char *type_str = git_object_type2string(obj_type);
96 - 3-5 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) int hdr_max = (hdr_size > INT_MAX-2) ? (INT_MAX-2) : (int)hdr_size;
97 - int len;
98 -
99 - 6 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) len = p_snprintf(hdr, hdr_max, "%s %"PRId64, type_str, (int64_t)obj_len);
100 -
101 - 6,7 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) if (len < 0 || len >= hdr_max) {
102 - 8 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) git_error_set(GIT_ERROR_OS, "object header creation failed");
103 - 9 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) return -1;
104 - }
105 -
106 - 10 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) *written = (size_t)(len + 1);
107 - 10 suppressed: function cannot be solved git_odb__format_object_header (automatic due to inconsistent arc counts in .gcda files) return 0;
108 - }
109 -
110 - 2 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files)int git_odb__hashobj(git_oid *id, git_rawobj *obj)
111 - {
112 - git_buf_vec vec[2];
113 - char header[64];
114 - size_t hdrlen;
115 - int error;
116 -
117 - 2-4 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) assert(id && obj);
118 -
119 - 5,6 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) if (!git_object_typeisloose(obj->type)) {
120 - 7 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) git_error_set(GIT_ERROR_INVALID, "invalid object type");
121 - 8 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) return -1;
122 - }
123 -
124 - 9,10 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) if (!obj->data && obj->len != 0) {
125 - 11 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) git_error_set(GIT_ERROR_INVALID, "invalid object");
126 - 12 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) return -1;
127 - }
128 -
129 - 13,14 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) if ((error = git_odb__format_object_header(&hdrlen,
130 - header, sizeof(header), obj->len, obj->type)) < 0)
131 - 15 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) return error;
132 -
133 - 16 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) vec[0].data = header;
134 - 16 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) vec[0].len = hdrlen;
135 - 16 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) vec[1].data = obj->data;
136 - 16 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) vec[1].len = obj->len;
137 -
138 - 16 suppressed: function cannot be solved git_odb__hashobj (automatic due to inconsistent arc counts in .gcda files) return git_hash_vec(id, vec, 2);
139 - }
140 -
141 -
142 79396 2 static git_odb_object *odb_object__alloc(const git_oid *oid, git_rawobj *source)
143 - {
144 79396 2 git_odb_object *object = git__calloc(1, sizeof(git_odb_object));
145 -
146 80499 3 if (object != NULL) {
147 80472 4 git_oid_cpy(&object->cached.oid, oid);
148 80175 5 object->cached.type = source->type;
149 80175 5 object->cached.size = source->len;
150 80175 5 object->buffer = source->data;
151 - }
152 -
153 80202 6 return object;
154 - }
155 -
156 - 2 suppressed: function cannot be solved git_odb_object__free (automatic due to inconsistent arc counts in .gcda files)void git_odb_object__free(void *object)
157 - {
158 - 2 suppressed: function cannot be solved git_odb_object__free (automatic due to inconsistent arc counts in .gcda files) if (object != NULL) {
159 - 3 suppressed: function cannot be solved git_odb_object__free (automatic due to inconsistent arc counts in .gcda files) git__free(((git_odb_object *)object)->buffer);
160 - 4 suppressed: function cannot be solved git_odb_object__free (automatic due to inconsistent arc counts in .gcda files) git__free(object);
161 - }
162 - 5 suppressed: function cannot be solved git_odb_object__free (automatic due to inconsistent arc counts in .gcda files)}
163 -
164 3 2 const git_oid *git_odb_object_id(git_odb_object *object)
165 - {
166 3 2 return &object->cached.oid;
167 - }
168 -
169 52251 2 const void *git_odb_object_data(git_odb_object *object)
170 - {
171 52251 2 return object->buffer;
172 - }
173 -
174 50639 2 size_t git_odb_object_size(git_odb_object *object)
175 - {
176 50639 2 return object->cached.size;
177 - }
178 -
179 17909 2 git_object_t git_odb_object_type(git_odb_object *object)
180 - {
181 17909 2 return object->cached.type;
182 - }
183 -
184 25672 2 int git_odb_object_dup(git_odb_object **dest, git_odb_object *source)
185 - {
186 25672 2 git_cached_obj_incref(source);
187 25685 3 *dest = source;
188 25685 3 return 0;
189 - }
190 -
191 131598 2 void git_odb_object_free(git_odb_object *object)
192 - {
193 131598 2 if (object == NULL)
194 132163 3,5 return;
195 -
196 131415 4 git_cached_obj_decref(object);
197 - }
198 -
199 4928 2 int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type)
200 - {
201 - size_t hdr_len;
202 - char hdr[64], buffer[FILEIO_BUFSIZE];
203 - git_hash_ctx ctx;
204 4928 2 ssize_t read_len = 0;
205 4928 2 int error = 0;
206 -
207 4928 2,3 if (!git_object_typeisloose(type)) {
208 3 4 git_error_set(GIT_ERROR_INVALID, "invalid object type for hash");
209 3 5 return -1;
210 - }
211 -
212 4925 6,7 if ((error = git_hash_ctx_init(&ctx)) < 0)
213 ##### 8 return error;
214 -
215 4926 9,10 if ((error = git_odb__format_object_header(&hdr_len, hdr,
216 - sizeof(hdr), size, type)) < 0)
217 ##### 11 goto done;
218 -
219 4926 12,13 if ((error = git_hash_update(&ctx, hdr, hdr_len)) < 0)
220 ##### 14 goto done;
221 -
222 9847 15,20-22 while (size > 0 && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) {
223 4922 16,17 if ((error = git_hash_update(&ctx, buffer, read_len)) < 0)
224 ##### 18 goto done;
225 -
226 4921 19 size -= read_len;
227 - }
228 -
229 - /* If p_read returned an error code, the read obviously failed.
230 - * If size is not zero, the file was truncated after we originally
231 - * stat'd it, so we consider this a read failure too */
232 4925 23,24 if (read_len < 0 || size > 0) {
233 ##### 25 git_error_set(GIT_ERROR_OS, "error reading file for hashing");
234 ##### 26 error = -1;
235 -
236 ##### 26 goto done;
237 - }
238 -
239 4925 27 error = git_hash_final(out, &ctx);
240 -
241 - done:
242 4925 28 git_hash_ctx_cleanup(&ctx);
243 4925 29 return error;
244 - }
245 -
246 5173 2 int git_odb__hashfd_filtered(
247 - git_oid *out, git_file fd, size_t size, git_object_t type, git_filter_list *fl)
248 - {
249 - int error;
250 5173 2 git_buf raw = GIT_BUF_INIT;
251 -
252 5173 2 if (!fl)
253 4911 3 return git_odb__hashfd(out, fd, size, type);
254 -
255 - /* size of data is used in header, so we have to read the whole file
256 - * into memory to apply filters before beginning to calculate the hash
257 - */
258 -
259 262 4,5 if (!(error = git_futils_readbuffer_fd(&raw, fd, size))) {
260 262 6 git_buf post = GIT_BUF_INIT;
261 -
262 262 6 error = git_filter_list_apply_to_data(&post, fl, &raw);
263 -
264 262 7 git_buf_dispose(&raw);
265 -
266 262 8 if (!error)
267 262 9 error = git_odb_hash(out, post.ptr, post.size, type);
268 -
269 262 10,11 git_buf_dispose(&post);
270 - }
271 -
272 262 12 return error;
273 - }
274 -
275 14 2 int git_odb__hashlink(git_oid *out, const char *path)
276 - {
277 - struct stat st;
278 - int size;
279 - int result;
280 -
281 14 2,3 if (git_path_lstat(path, &st) < 0)
282 ##### 4 return -1;
283 -
284 14 5-7 if (!git__is_int(st.st_size) || (int)st.st_size < 0) {
285 ##### 8 git_error_set(GIT_ERROR_FILESYSTEM, "file size overflow for 32-bit systems");
286 ##### 9 return -1;
287 - }
288 -
289 14 10 size = (int)st.st_size;
290 -
291 14 10 if (S_ISLNK(st.st_mode)) {
292 - char *link_data;
293 - int read_len;
294 - size_t alloc_size;
295 -
296 14 11-17,29 GIT_ERROR_CHECK_ALLOC_ADD(&alloc_size, size, 1);
297 14 18 link_data = git__malloc(alloc_size);
298 14 19,20 GIT_ERROR_CHECK_ALLOC(link_data);
299 -
300 14 21 read_len = p_readlink(path, link_data, size);
301 14 22 link_data[size] = '\0';
302 14 22 if (read_len != size) {
303 ##### 23 git_error_set(GIT_ERROR_OS, "failed to read symlink data for '%s'", path);
304 ##### 24 git__free(link_data);
305 ##### 25 return -1;
306 - }
307 -
308 14 26 result = git_odb_hash(out, link_data, size, GIT_OBJECT_BLOB);
309 14 27,28 git__free(link_data);
310 - } else {
311 ##### 30 int fd = git_futils_open_ro(path);
312 ##### 31 if (fd < 0)
313 ##### 32 return -1;
314 ##### 33 result = git_odb__hashfd(out, fd, size, GIT_OBJECT_BLOB);
315 ##### 34 p_close(fd);
316 - }
317 -
318 14 35 return result;
319 - }
320 -
321 16 2 int git_odb_hashfile(git_oid *out, const char *path, git_object_t type)
322 - {
323 - uint64_t size;
324 16 2 int fd, error = 0;
325 -
326 16 2,3 if ((fd = git_futils_open_ro(path)) < 0)
327 ##### 4 return fd;
328 -
329 16 5,6 if ((error = git_futils_filesize(&size, fd)) < 0)
330 ##### 7 goto done;
331 -
332 16 8,9 if (!git__is_sizet(size)) {
333 ##### 10 git_error_set(GIT_ERROR_OS, "file size overflow for 32-bit systems");
334 ##### 11 error = -1;
335 ##### 11 goto done;
336 - }
337 -
338 16 12 error = git_odb__hashfd(out, fd, (size_t)size, type);
339 -
340 - done:
341 16 13 p_close(fd);
342 16 14 return error;
343 - }
344 -
345 83100 2 int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type)
346 - {
347 - git_rawobj raw;
348 -
349 83100 2,3 assert(id);
350 -
351 83100 4 raw.data = (void *)data;
352 83100 4 raw.len = len;
353 83100 4 raw.type = type;
354 -
355 83100 4 return git_odb__hashobj(id, &raw);
356 - }
357 -
358 - /**
359 - * FAKE WSTREAM
360 - */
361 -
362 - typedef struct {
363 - git_odb_stream stream;
364 - char *buffer;
365 - size_t size, written;
366 - git_object_t type;
367 - } fake_wstream;
368 -
369 1 2 static int fake_wstream__fwrite(git_odb_stream *_stream, const git_oid *oid)
370 - {
371 1 2 fake_wstream *stream = (fake_wstream *)_stream;
372 1 2 return _stream->backend->write(_stream->backend, oid, stream->buffer, stream->size, stream->type);
373 - }
374 -
375 1 2 static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t len)
376 - {
377 1 2 fake_wstream *stream = (fake_wstream *)_stream;
378 -
379 1 2,3 assert(stream->written + len <= stream->size);
380 -
381 1 4 memcpy(stream->buffer + stream->written, data, len);
382 1 4 stream->written += len;
383 1 4 return 0;
384 - }
385 -
386 1 2 static void fake_wstream__free(git_odb_stream *_stream)
387 - {
388 1 2 fake_wstream *stream = (fake_wstream *)_stream;
389 -
390 1 2 git__free(stream->buffer);
391 1 3 git__free(stream);
392 1 4 }
393 -
394 1 2 static int init_fake_wstream(git_odb_stream **stream_p, git_odb_backend *backend, git_object_size_t size, git_object_t type)
395 - {
396 - fake_wstream *stream;
397 - size_t blobsize;
398 -
399 1 2-5 GIT_ERROR_CHECK_BLOBSIZE(size);
400 1 6 blobsize = (size_t)size;
401 -
402 1 6 stream = git__calloc(1, sizeof(fake_wstream));
403 1 7,8 GIT_ERROR_CHECK_ALLOC(stream);
404 -
405 1 9 stream->size = blobsize;
406 1 9 stream->type = type;
407 1 9 stream->buffer = git__malloc(blobsize);
408 1 10 if (stream->buffer == NULL) {
409 ##### 11 git__free(stream);
410 ##### 12 return -1;
411 - }
412 -
413 1 13 stream->stream.backend = backend;
414 1 13 stream->stream.read = NULL; /* read only */
415 1 13 stream->stream.write = &fake_wstream__write;
416 1 13 stream->stream.finalize_write = &fake_wstream__fwrite;
417 1 13 stream->stream.free = &fake_wstream__free;
418 1 13 stream->stream.mode = GIT_STREAM_WRONLY;
419 -
420 1 13 *stream_p = (git_odb_stream *)stream;
421 1 13 return 0;
422 - }
423 -
424 - /***********************************************************
425 - *
426 - * OBJECT DATABASE PUBLIC API
427 - *
428 - * Public calls for the ODB functionality
429 - *
430 - ***********************************************************/
431 -
432 7882 2 static int backend_sort_cmp(const void *a, const void *b)
433 - {
434 7882 2 const backend_internal *backend_a = (const backend_internal *)(a);
435 7882 2 const backend_internal *backend_b = (const backend_internal *)(b);
436 -
437 7882 2 if (backend_b->priority == backend_a->priority) {
438 135 3 if (backend_a->is_alternate)
439 120 4 return -1;
440 15 5 if (backend_b->is_alternate)
441 15 6 return 1;
442 ##### 7 return 0;
443 - }
444 7747 8 return (backend_b->priority - backend_a->priority);
445 - }
446 -
447 3790 2 int git_odb_new(git_odb **out)
448 - {
449 3790 2 git_odb *db = git__calloc(1, sizeof(*db));
450 3792 3,4 GIT_ERROR_CHECK_ALLOC(db);
451 -
452 3792 5,6 if (git_cache_init(&db->own_cache) < 0) {
453 ##### 7 git__free(db);
454 ##### 8 return -1;
455 - }
456 3791 9,10 if (git_vector_init(&db->backends, 4, backend_sort_cmp) < 0) {
457 ##### 11 git_cache_dispose(&db->own_cache);
458 ##### 12 git__free(db);
459 ##### 13 return -1;
460 - }
461 -
462 3791 14 *out = db;
463 3791 14 GIT_REFCOUNT_INC(db);
464 3792 15 return 0;
465 - }
466 -
467 - 2 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files)static int add_backend_internal(
468 - git_odb *odb, git_odb_backend *backend,
469 - int priority, bool is_alternate, ino_t disk_inode)
470 - {
471 - backend_internal *internal;
472 -
473 - 2-4 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) assert(odb && backend);
474 -
475 - 5-7 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) GIT_ERROR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend");
476 -
477 - /* Check if the backend is already owned by another ODB */
478 - 8-10 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) assert(!backend->odb || backend->odb == odb);
479 -
480 - 11 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) internal = git__malloc(sizeof(backend_internal));
481 - 12,13 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) GIT_ERROR_CHECK_ALLOC(internal);
482 -
483 - 14 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) internal->backend = backend;
484 - 14 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) internal->priority = priority;
485 - 14 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) internal->is_alternate = is_alternate;
486 - 14 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) internal->disk_inode = disk_inode;
487 -
488 - 14,15 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) if (git_vector_insert(&odb->backends, internal) < 0) {
489 - 16 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) git__free(internal);
490 - 17 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) return -1;
491 - }
492 -
493 - 18 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) git_vector_sort(&odb->backends);
494 - 19 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) internal->backend->odb = odb;
495 - 19 suppressed: function cannot be solved add_backend_internal (automatic due to inconsistent arc counts in .gcda files) return 0;
496 - }
497 -
498 54 2 int git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority)
499 - {
500 54 2 return add_backend_internal(odb, backend, priority, false, 0);
501 - }
502 -
503 4 2 int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
504 - {
505 4 2 return add_backend_internal(odb, backend, priority, true, 0);
506 - }
507 -
508 2 2 size_t git_odb_num_backends(git_odb *odb)
509 - {
510 2 2,3 assert(odb);
511 2 4 return odb->backends.length;
512 - }
513 -
514 1 2 static int git_odb__error_unsupported_in_backend(const char *action)
515 - {
516 1 2 git_error_set(GIT_ERROR_ODB,
517 - "cannot %s - unsupported in the loaded odb backends", action);
518 1 3 return -1;
519 - }
520 -
521 -
522 12 2 int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
523 - {
524 - backend_internal *internal;
525 -
526 12 2-4 assert(out && odb);
527 12 5 internal = git_vector_get(&odb->backends, pos);
528 -
529 12 6,7 if (internal && internal->backend) {
530 12 8 *out = internal->backend;
531 12 8 return 0;
532 - }
533 -
534 ##### 9 git_error_set(GIT_ERROR_ODB, "no ODB backend loaded at index %" PRIuZ, pos);
535 ##### 10 return GIT_ENOTFOUND;
536 - }
537 -
538 3786 2 int git_odb__add_default_backends(
539 - git_odb *db, const char *objects_dir,
540 - bool as_alternates, int alternate_depth)
541 - {
542 - size_t i;
543 - struct stat st;
544 - ino_t inode;
545 - git_odb_backend *loose, *packed;
546 -
547 - /* TODO: inodes are not really relevant on Win32, so we need to find
548 - * a cross-platform workaround for this */
549 - #ifdef GIT_WIN32
550 - GIT_UNUSED(i);
551 - GIT_UNUSED(st);
552 -
553 - inode = 0;
554 - #else
555 3786 2,3 if (p_stat(objects_dir, &st) < 0) {
556 ##### 4 if (as_alternates)
557 - /* this should warn */
558 ##### 5 return 0;
559 -
560 ##### 6 git_error_set(GIT_ERROR_ODB, "failed to load object database in '%s'", objects_dir);
561 ##### 7 return -1;
562 - }
563 -
564 3786 8 inode = st.st_ino;
565 -
566 3850 8,12,13 for (i = 0; i < db->backends.length; ++i) {
567 64 9 backend_internal *backend = git_vector_get(&db->backends, i);
568 64 10 if (backend->disk_inode == inode)
569 ##### 11 return 0;
570 - }
571 - #endif
572 -
573 - /* add the loose object backend */
574 3788 14,15,17 if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 ||
575 3787 16 add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0)
576 ##### 18 return -1;
577 -
578 - /* add the packed file backend */
579 3788 19,20,22 if (git_odb_backend_pack(&packed, objects_dir) < 0 ||
580 3767 21 add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates, inode) < 0)
581 ##### 23 return -1;
582 -
583 3776 24 return load_alternates(db, objects_dir, alternate_depth);
584 - }
585 -
586 3772 2 static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth)
587 - {
588 3772 2 git_buf alternates_path = GIT_BUF_INIT;
589 3772 2 git_buf alternates_buf = GIT_BUF_INIT;
590 - char *buffer;
591 - const char *alternate;
592 3772 2 int result = 0;
593 -
594 - /* Git reports an error, we just ignore anything deeper */
595 3772 2 if (alternate_depth > GIT_ALTERNATES_MAX_DEPTH)
596 ##### 3 return 0;
597 -
598 3784 4,5 if (git_buf_joinpath(&alternates_path, objects_dir, GIT_ALTERNATES_FILE) < 0)
599 ##### 6 return -1;
600 -
601 3784 7,8 if (git_path_exists(alternates_path.ptr) == false) {
602 3772 9 git_buf_dispose(&alternates_path);
603 3767 10 return 0;
604 - }
605 -
606 8 11,12 if (git_futils_readbuffer(&alternates_buf, alternates_path.ptr) < 0) {
607 ##### 13 git_buf_dispose(&alternates_path);
608 ##### 14 return -1;
609 - }
610 -
611 8 15 buffer = (char *)alternates_buf.ptr;
612 -
613 - /* add each alternate as a new backend; one alternate per line */
614 16 15,28,29 while ((alternate = git__strtok(&buffer, "\r\n")) != NULL) {
615 8 16,17 if (*alternate == '\0' || *alternate == '#')
616 ##### 18 continue;
617 -
618 - /*
619 - * Relative path: build based on the current `objects`
620 - * folder. However, relative paths are only allowed in
621 - * the current repository.
622 - */
623 8 19,20 if (*alternate == '.' && !alternate_depth) {
624 ##### 21,22 if ((result = git_buf_joinpath(&alternates_path, objects_dir, alternate)) < 0)
625 ##### 23 break;
626 ##### 24 alternate = git_buf_cstr(&alternates_path);
627 - }
628 -
629 8 25,26 if ((result = git_odb__add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0)
630 ##### 27 break;
631 - }
632 -
633 8 30 git_buf_dispose(&alternates_path);
634 8 31 git_buf_dispose(&alternates_buf);
635 -
636 8 32 return result;
637 - }
638 -
639 6 2 int git_odb_add_disk_alternate(git_odb *odb, const char *path)
640 - {
641 6 2 return git_odb__add_default_backends(odb, path, true, 0);
642 - }
643 -
644 82 2 int git_odb_open(git_odb **out, const char *objects_dir)
645 - {
646 - git_odb *db;
647 -
648 82 2-4 assert(out && objects_dir);
649 -
650 82 5 *out = NULL;
651 -
652 82 5,6 if (git_odb_new(&db) < 0)
653 ##### 7 return -1;
654 -
655 82 8,9 if (git_odb__add_default_backends(db, objects_dir, 0, 0) < 0) {
656 ##### 10 git_odb_free(db);
657 ##### 11 return -1;
658 - }
659 -
660 82 12 *out = db;
661 82 12 return 0;
662 - }
663 -
664 3693 2 int git_odb__set_caps(git_odb *odb, int caps)
665 - {
666 3693 2 if (caps == GIT_ODB_CAP_FROM_OWNER) {
667 3693 3 git_repository *repo = odb->rc.owner;
668 - int val;
669 -
670 3693 3 if (!repo) {
671 ##### 4 git_error_set(GIT_ERROR_ODB, "cannot access repository to set odb caps");
672 ##### 5 return -1;
673 - }
674 -
675 3693 6,7 if (!git_repository__configmap_lookup(&val, repo, GIT_CONFIGMAP_FSYNCOBJECTFILES))
676 3691 8,9 odb->do_fsync = !!val;
677 - }
678 -
679 3691 10 return 0;
680 - }
681 -
682 3785 2 static void odb_free(git_odb *db)
683 - {
684 - size_t i;
685 -
686 11418 2,6,7 for (i = 0; i < db->backends.length; ++i) {
687 7626 3 backend_internal *internal = git_vector_get(&db->backends, i);
688 7612 4 git_odb_backend *backend = internal->backend;
689 -
690 7612 4 backend->free(backend);
691 -
692 7633 5 git__free(internal);
693 - }
694 -
695 3792 8 git_vector_free(&db->backends);
696 3791 9 git_cache_dispose(&db->own_cache);
697 -
698 3790 10 git__memzero(db, sizeof(*db));
699 3791 11 git__free(db);
700 3791 12 }
701 -
702 12649 2 void git_odb_free(git_odb *db)
703 - {
704 12649 2 if (db == NULL)
705 12661 3,8 return;
706 -
707 12101 4-7 GIT_REFCOUNT_DEC(db, odb_free);
708 - }
709 -
710 2138 2 static int odb_exists_1(
711 - git_odb *db,
712 - const git_oid *id,
713 - bool only_refreshed)
714 - {
715 - size_t i;
716 2138 2 bool found = false;
717 -
718 5835 2,10-12 for (i = 0; i < db->backends.length && !found; ++i) {
719 3697 3 backend_internal *internal = git_vector_get(&db->backends, i);
720 3697 4 git_odb_backend *b = internal->backend;
721 -
722 3697 4,5 if (only_refreshed && !b->refresh)
723 624 6 continue;
724 -
725 3073 7 if (b->exists != NULL)
726 3073 8,9 found = (bool)b->exists(b, id);
727 - }
728 -
729 2138 13 return (int)found;
730 - }
731 -
732 7273 2 static int odb_freshen_1(
733 - git_odb *db,
734 - const git_oid *id,
735 - bool only_refreshed)
736 - {
737 - size_t i;
738 7273 2 bool found = false;
739 -
740 21743 2,13-15 for (i = 0; i < db->backends.length && !found; ++i) {
741 14470 3 backend_internal *internal = git_vector_get(&db->backends, i);
742 14470 4 git_odb_backend *b = internal->backend;
743 -
744 14470 4,5 if (only_refreshed && !b->refresh)
745 1647 6 continue;
746 -
747 12823 7 if (b->freshen != NULL)
748 12820 8,9 found = !b->freshen(b, id);
749 3 10 else if (b->exists != NULL)
750 3 11,12 found = b->exists(b, id);
751 - }
752 -
753 7273 16 return (int)found;
754 - }
755 -
756 5625 2 int git_odb__freshen(git_odb *db, const git_oid *id)
757 - {
758 5625 2-4 assert(db && id);
759 -
760 5625 5,6 if (odb_freshen_1(db, id, false))
761 3977 7 return 1;
762 -
763 1648 8,9 if (!git_odb_refresh(db))
764 1648 10 return odb_freshen_1(db, id, true);
765 -
766 - /* Failed to refresh, hence not found */
767 ##### 11 return 0;
768 - }
769 -
770 1513 2 int git_odb_exists(git_odb *db, const git_oid *id)
771 - {
772 - git_odb_object *object;
773 -
774 1513 2-4 assert(db && id);
775 -
776 1513 5,6 if (git_oid_is_zero(id))
777 1 7 return 0;
778 -
779 1512 8-10 if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
780 ##### 11 git_odb_object_free(object);
781 ##### 12 return 1;
782 - }
783 -
784 1512 13,14 if (odb_exists_1(db, id, false))
785 886 15 return 1;
786 -
787 626 16,17 if (!git_odb_refresh(db))
788 626 18 return odb_exists_1(db, id, true);
789 -
790 - /* Failed to refresh, hence not found */
791 ##### 19 return 0;
792 - }
793 -
794 108 2 static int odb_exists_prefix_1(git_oid *out, git_odb *db,
795 - const git_oid *key, size_t len, bool only_refreshed)
796 - {
797 - size_t i;
798 108 2 int error = GIT_ENOTFOUND, num_found = 0;
799 108 2 git_oid last_found = {{0}}, found;
800 -
801 278 2,21,22 for (i = 0; i < db->backends.length; ++i) {
802 199 3 backend_internal *internal = git_vector_get(&db->backends, i);
803 199 4 git_odb_backend *b = internal->backend;
804 -
805 199 4,5 if (only_refreshed && !b->refresh)
806 1 6 continue;
807 -
808 198 7 if (!b->exists_prefix)
809 ##### 8 continue;
810 -
811 198 9 error = b->exists_prefix(&found, b, key, len);
812 198 10,11 if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
813 89 12 continue;
814 109 13 if (error)
815 18 14 return error;
816 -
817 - /* make sure found item doesn't introduce ambiguity */
818 91 15 if (num_found) {
819 18 16,17 if (git_oid__cmp(&last_found, &found))
820 11 18 return git_odb__error_ambiguous("multiple matches for prefix");
821 - } else {
822 73 19 git_oid_cpy(&last_found, &found);
823 73 20 num_found++;
824 - }
825 - }
826 -
827 79 23 if (!num_found)
828 17 24 return GIT_ENOTFOUND;
829 -
830 62 25 if (out)
831 57 26 git_oid_cpy(out, &last_found);
832 -
833 62 27 return 0;
834 - }
835 -
836 44 2 int git_odb_exists_prefix(
837 - git_oid *out, git_odb *db, const git_oid *short_id, size_t len)
838 - {
839 - int error;
840 44 2 git_oid key = {{0}};
841 -
842 44 2-4 assert(db && short_id);
843 -
844 44 5 if (len < GIT_OID_MINPREFIXLEN)
845 ##### 6 return git_odb__error_ambiguous("prefix length too short");
846 -
847 44 7 if (len >= GIT_OID_HEXSZ) {
848 2 8,9 if (git_odb_exists(db, short_id)) {
849 2 10 if (out)
850 1 11 git_oid_cpy(out, short_id);
851 2 12 return 0;
852 - } else {
853 ##### 13 return git_odb__error_notfound(
854 - "no match for id prefix", short_id, len);
855 - }
856 - }
857 -
858 42 14 git_oid__cpy_prefix(&key, short_id, len);
859 -
860 42 15 error = odb_exists_prefix_1(out, db, &key, len, false);
861 -
862 42 16-18 if (error == GIT_ENOTFOUND && !git_odb_refresh(db))
863 1 19 error = odb_exists_prefix_1(out, db, &key, len, true);
864 -
865 42 20 if (error == GIT_ENOTFOUND)
866 1 21 return git_odb__error_notfound("no match for id prefix", &key, len);
867 -
868 41 22 return error;
869 - }
870 -
871 5 2 int git_odb_expand_ids(
872 - git_odb *db,
873 - git_odb_expand_id *ids,
874 - size_t count)
875 - {
876 - size_t i;
877 -
878 5 2-4 assert(db && ids);
879 -
880 95 5,27,28 for (i = 0; i < count; i++) {
881 90 6 git_odb_expand_id *query = &ids[i];
882 90 6 int error = GIT_EAMBIGUOUS;
883 -
884 90 6 if (!query->type)
885 18 7 query->type = GIT_OBJECT_ANY;
886 -
887 - /* if we have a short OID, expand it first */
888 90 8,9 if (query->length >= GIT_OID_MINPREFIXLEN && query->length < GIT_OID_HEXSZ) {
889 - git_oid actual_id;
890 -
891 65 10 error = odb_exists_prefix_1(&actual_id, db, &query->id, query->length, false);
892 65 11 if (!error) {
893 30 12 git_oid_cpy(&query->id, &actual_id);
894 65 13,14 query->length = GIT_OID_HEXSZ;
895 - }
896 - }
897 -
898 - /*
899 - * now we ought to have a 40-char OID, either because we've expanded it
900 - * or because the user passed a full OID. Ensure its type is right.
901 - */
902 90 15 if (query->length >= GIT_OID_HEXSZ) {
903 - git_object_t actual_type;
904 -
905 50 16 error = odb_otype_fast(&actual_type, db, &query->id);
906 50 17 if (!error) {
907 40 18,19 if (query->type != GIT_OBJECT_ANY && query->type != actual_type)
908 8 20 error = GIT_ENOTFOUND;
909 - else
910 50 21,22 query->type = actual_type;
911 - }
912 - }
913 -
914 90 23 switch (error) {
915 - /* no errors, so we've successfully expanded the OID */
916 - case 0:
917 32 24 continue;
918 -
919 - /* the object is missing or ambiguous */
920 - case GIT_ENOTFOUND:
921 - case GIT_EAMBIGUOUS:
922 58 25 memset(&query->id, 0, sizeof(git_oid));
923 58 25 query->length = 0;
924 58 25 query->type = 0;
925 58 25 break;
926 -
927 - /* something went very wrong with the ODB; bail hard */
928 - default:
929 ##### 26 return error;
930 - }
931 - }
932 -
933 5 29 git_error_clear();
934 5 30 return 0;
935 - }
936 -
937 11801 2 int git_odb_read_header(size_t *len_p, git_object_t *type_p, git_odb *db, const git_oid *id)
938 - {
939 - int error;
940 - git_odb_object *object;
941 -
942 11801 2 error = git_odb__read_header_or_object(&object, len_p, type_p, db, id);
943 -
944 11801 3 if (object)
945 376 4 git_odb_object_free(object);
946 -
947 11801 5 return error;
948 - }
949 -
950 13121 2 static int odb_read_header_1(
951 - size_t *len_p, git_object_t *type_p, git_odb *db,
952 - const git_oid *id, bool only_refreshed)
953 - {
954 - size_t i;
955 - git_object_t ht;
956 13121 2 bool passthrough = false;
957 - int error;
958 -
959 13121 2-4 if (!only_refreshed && (ht = odb_hardcoded_type(id)) != GIT_OBJECT_INVALID) {
960 9 5 *type_p = ht;
961 9 5 *len_p = 0;
962 9 5 return 0;
963 - }
964 -
965 23326 6,18,19 for (i = 0; i < db->backends.length; ++i) {
966 23230 7 backend_internal *internal = git_vector_get(&db->backends, i);
967 23230 8 git_odb_backend *b = internal->backend;
968 -
969 23230 8,9 if (only_refreshed && !b->refresh)
970 15 10 continue;
971 -
972 23215 11 if (!b->read_header) {
973 ##### 12 passthrough = true;
974 ##### 12 continue;
975 - }
976 -
977 23215 13 error = b->read_header(len_p, type_p, b, id);
978 -
979 23215 14 switch (error) {
980 - case GIT_PASSTHROUGH:
981 ##### 15 passthrough = true;
982 ##### 15 break;
983 - case GIT_ENOTFOUND:
984 10199 16 break;
985 - default:
986 13016 17 return error;
987 - }
988 - }
989 -
990 96 20 return passthrough ? GIT_PASSTHROUGH : GIT_ENOTFOUND;
991 - }
992 -
993 13377 2 int git_odb__read_header_or_object(
994 - git_odb_object **out, size_t *len_p, git_object_t *type_p,
995 - git_odb *db, const git_oid *id)
996 - {
997 13377 2 int error = GIT_ENOTFOUND;
998 - git_odb_object *object;
999 -
1000 13377 2-7 assert(db && id && out && len_p && type_p);
1001 -
1002 13377 8 *out = NULL;
1003 -
1004 13377 8,9 if (git_oid_is_zero(id))
1005 ##### 10 return error_null_oid(GIT_ENOTFOUND, "cannot read object");
1006 -
1007 13377 11-13 if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
1008 376 14 *len_p = object->cached.size;
1009 376 14 *type_p = object->cached.type;
1010 376 14 *out = object;
1011 376 14 return 0;
1012 - }
1013 -
1014 13001 15 error = odb_read_header_1(len_p, type_p, db, id, false);
1015 -
1016 13001 16-18 if (error == GIT_ENOTFOUND && !git_odb_refresh(db))
1017 77 19 error = odb_read_header_1(len_p, type_p, db, id, true);
1018 -
1019 13001 20 if (error == GIT_ENOTFOUND)
1020 14 21 return git_odb__error_notfound("cannot read header for", id, GIT_OID_HEXSZ);
1021 -
1022 - /* we found the header; return early */
1023 12987 22 if (!error)
1024 12987 23 return 0;
1025 -
1026 ##### 24 if (error == GIT_PASSTHROUGH) {
1027 - /*
1028 - * no backend has header-reading functionality
1029 - * so try using `git_odb_read` instead
1030 - */
1031 ##### 25 error = git_odb_read(&object, db, id);
1032 ##### 26 if (!error) {
1033 ##### 27 *len_p = object->cached.size;
1034 ##### 27 *type_p = object->cached.type;
1035 ##### 27 *out = object;
1036 - }
1037 - }
1038 -
1039 ##### 28 return error;
1040 - }
1041 -
1042 - 2 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files)static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
1043 - bool only_refreshed)
1044 - {
1045 - size_t i;
1046 - git_rawobj raw;
1047 - git_odb_object *object;
1048 - git_oid hashed;
1049 - 2 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) bool found = false;
1050 - 2 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) int error = 0;
1051 -
1052 - 2 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (!only_refreshed) {
1053 - 3,4 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if ((error = odb_read_hardcoded(&found, &raw, id)) < 0)
1054 - 5 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) return error;
1055 - }
1056 -
1057 - 6,19-21 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) for (i = 0; i < db->backends.length && !found; ++i) {
1058 - 7 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) backend_internal *internal = git_vector_get(&db->backends, i);
1059 - 8 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) git_odb_backend *b = internal->backend;
1060 -
1061 - 8,9 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (only_refreshed && !b->refresh)
1062 - 10 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) continue;
1063 -
1064 - 11 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (b->read != NULL) {
1065 - 12 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) error = b->read(&raw.data, &raw.len, &raw.type, b, id);
1066 - 13,14 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (error == GIT_PASSTHROUGH || error == GIT_ENOTFOUND)
1067 - 15 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) continue;
1068 -
1069 - 16 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (error < 0)
1070 - 17 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) return error;
1071 -
1072 - 18 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) found = true;
1073 - }
1074 - }
1075 -
1076 - 22 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (!found)
1077 - 23 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) return GIT_ENOTFOUND;
1078 -
1079 - 24 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (git_odb__strict_hash_verification) {
1080 - 25,26 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if ((error = git_odb_hash(&hashed, raw.data, raw.len, raw.type)) < 0)
1081 - 27 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) goto out;
1082 -
1083 - 28,29 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (!git_oid_equal(id, &hashed)) {
1084 - 30 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) error = git_odb__error_mismatch(id, &hashed);
1085 - 31 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) goto out;
1086 - }
1087 - }
1088 -
1089 - 32 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) git_error_clear();
1090 - 33,34 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if ((object = odb_object__alloc(id, &raw)) == NULL) {
1091 - 35 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) error = -1;
1092 - 35 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) goto out;
1093 - }
1094 -
1095 - 36-38 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) *out = git_cache_store_raw(odb_cache(db), object);
1096 -
1097 - out:
1098 - 39 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) if (error)
1099 - 40 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) git__free(raw.data);
1100 - 41 suppressed: function cannot be solved odb_read_1 (automatic due to inconsistent arc counts in .gcda files) return error;
1101 - }
1102 -
1103 - 2 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files)int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
1104 - {
1105 - int error;
1106 -
1107 - 2-5 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) assert(out && db && id);
1108 -
1109 - 6,7 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) if (git_oid_is_zero(id))
1110 - 8 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) return error_null_oid(GIT_ENOTFOUND, "cannot read object");
1111 -
1112 - 9,10 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) *out = git_cache_get_raw(odb_cache(db), id);
1113 - 11 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) if (*out != NULL)
1114 - 12 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) return 0;
1115 -
1116 - 13 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) error = odb_read_1(out, db, id, false);
1117 -
1118 - 14-16 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) if (error == GIT_ENOTFOUND && !git_odb_refresh(db))
1119 - 17 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) error = odb_read_1(out, db, id, true);
1120 -
1121 - 18 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) if (error == GIT_ENOTFOUND)
1122 - 19 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) return git_odb__error_notfound("no match for id", id, GIT_OID_HEXSZ);
1123 -
1124 - 20 suppressed: function cannot be solved git_odb_read (automatic due to inconsistent arc counts in .gcda files) return error;
1125 - }
1126 -
1127 50 2 static int odb_otype_fast(git_object_t *type_p, git_odb *db, const git_oid *id)
1128 - {
1129 - git_odb_object *object;
1130 - size_t _unused;
1131 - int error;
1132 -
1133 50 2,3 if (git_oid_is_zero(id))
1134 5 4 return error_null_oid(GIT_ENOTFOUND, "cannot get object type");
1135 -
1136 45 5-7 if ((object = git_cache_get_raw(odb_cache(db), id)) != NULL) {
1137 2 8 *type_p = object->cached.type;
1138 2 8 git_odb_object_free(object);
1139 2 9 return 0;
1140 - }
1141 -
1142 43 10 error = odb_read_header_1(&_unused, type_p, db, id, false);
1143 -
1144 43 11 if (error == GIT_PASSTHROUGH) {
1145 ##### 12 error = odb_read_1(&object, db, id, false);
1146 ##### 13 if (!error)
1147 ##### 14 *type_p = object->cached.type;
1148 ##### 15 git_odb_object_free(object);
1149 - }
1150 -
1151 43 16 return error;
1152 - }
1153 -
1154 476 2 static int read_prefix_1(git_odb_object **out, git_odb *db,
1155 - const git_oid *key, size_t len, bool only_refreshed)
1156 - {
1157 - size_t i;
1158 476 2 int error = 0;
1159 476 2 git_oid found_full_oid = {{0}};
1160 476 2 git_rawobj raw = {0};
1161 476 2 void *data = NULL;
1162 476 2 bool found = false;
1163 - git_odb_object *object;
1164 -
1165 1428 2,28,29 for (i = 0; i < db->backends.length; ++i) {
1166 958 3 backend_internal *internal = git_vector_get(&db->backends, i);
1167 958 4 git_odb_backend *b = internal->backend;
1168 -
1169 958 4,5 if (only_refreshed && !b->refresh)
1170 2 6 continue;
1171 -
1172 956 7 if (b->read_prefix != NULL) {
1173 - git_oid full_oid;
1174 956 8 error = b->read_prefix(&full_oid, &raw.data, &raw.len, &raw.type, b, key, len);
1175 -
1176 956 9,10 if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH) {
1177 474 11 error = 0;
1178 474 11 continue;
1179 - }
1180 -
1181 482 12 if (error)
1182 6 13,27 goto out;
1183 -
1184 477 14 git__free(data);
1185 477 15 data = raw.data;
1186 -
1187 477 15-17 if (found && git_oid__cmp(&full_oid, &found_full_oid)) {
1188 1 18 git_buf buf = GIT_BUF_INIT;
1189 -
1190 1 18,19 git_buf_printf(&buf, "multiple matches for prefix: %s",
1191 - git_oid_tostr_s(&full_oid));
1192 1 20,21 git_buf_printf(&buf, " %s",
1193 - git_oid_tostr_s(&found_full_oid));
1194 -
1195 1 22 error = git_odb__error_ambiguous(buf.ptr);
1196 1 23 git_buf_dispose(&buf);
1197 1 24,25 goto out;
1198 - }
1199 -
1200 476 26 found_full_oid = full_oid;
1201 476 26 found = true;
1202 - }
1203 - }
1204 -
1205 470 30 if (!found)
1206 2 31 return GIT_ENOTFOUND;
1207 -
1208 468 32 if (git_odb__strict_hash_verification) {
1209 - git_oid hash;
1210 -
1211 466 33,34 if ((error = git_odb_hash(&hash, raw.data, raw.len, raw.type)) < 0)
1212 ##### 35,41 goto out;
1213 -
1214 466 36,37 if (!git_oid_equal(&found_full_oid, &hash)) {
1215 466 38,39 error = git_odb__error_mismatch(&found_full_oid, &hash);
1216 ##### 40 goto out;
1217 - }
1218 - }
1219 -
1220 468 42,43 if ((object = odb_object__alloc(&found_full_oid, &raw)) == NULL) {
1221 ##### 44 error = -1;
1222 ##### 44 goto out;
1223 - }
1224 -
1225 468 45-47 *out = git_cache_store_raw(odb_cache(db), object);
1226 -
1227 - out:
1228 474 48 if (error)
1229 6 49 git__free(raw.data);
1230 -
1231 474 50 return error;
1232 - }
1233 -
1234 476 2 int git_odb_read_prefix(
1235 - git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len)
1236 - {
1237 476 2 git_oid key = {{0}};
1238 - int error;
1239 -
1240 476 2-4 assert(out && db);
1241 -
1242 476 5 if (len < GIT_OID_MINPREFIXLEN)
1243 ##### 6 return git_odb__error_ambiguous("prefix length too short");
1244 -
1245 476 7 if (len > GIT_OID_HEXSZ)
1246 ##### 8 len = GIT_OID_HEXSZ;
1247 -
1248 476 9 if (len == GIT_OID_HEXSZ) {
1249 4 10,11 *out = git_cache_get_raw(odb_cache(db), short_id);
1250 4 12 if (*out != NULL)
1251 1 13 return 0;
1252 - }
1253 -
1254 475 14 git_oid__cpy_prefix(&key, short_id, len);
1255 -
1256 475 15 error = read_prefix_1(out, db, &key, len, false);
1257 -
1258 475 16-18 if (error == GIT_ENOTFOUND && !git_odb_refresh(db))
1259 1 19 error = read_prefix_1(out, db, &key, len, true);
1260 -
1261 475 20 if (error == GIT_ENOTFOUND)
1262 1 21 return git_odb__error_notfound("no match for prefix", &key, len);
1263 -
1264 474 22 return error;
1265 - }
1266 -
1267 6 2 int git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload)
1268 - {
1269 - unsigned int i;
1270 - backend_internal *internal;
1271 -
1272 12 2,6-8 git_vector_foreach(&db->backends, i, internal) {
1273 9 3 git_odb_backend *b = internal->backend;
1274 9 3 int error = b->foreach(b, cb, payload);
1275 9 4 if (error != 0)
1276 3 5 return error;
1277 - }
1278 -
1279 3 9 return 0;
1280 - }
1281 -
1282 2407 2 int git_odb_write(
1283 - git_oid *oid, git_odb *db, const void *data, size_t len, git_object_t type)
1284 - {
1285 - size_t i;
1286 2407 2 int error = GIT_ERROR;
1287 - git_odb_stream *stream;
1288 -
1289 2407 2-4 assert(oid && db);
1290 -
1291 2407 5 git_odb_hash(oid, data, len, type);
1292 -
1293 2407 6,7 if (git_oid_is_zero(oid))
1294 ##### 8 return error_null_oid(GIT_EINVALID, "cannot write object");
1295 -
1296 2407 9,10 if (git_odb__freshen(db, oid))
1297 1514 11 return 0;
1298 -
1299 2670 12,18-20 for (i = 0; i < db->backends.length && error < 0; ++i) {
1300 1777 13 backend_internal *internal = git_vector_get(&db->backends, i);
1301 1777 14 git_odb_backend *b = internal->backend;
1302 -
1303 - /* we don't write in alternates! */
1304 1777 14 if (internal->is_alternate)
1305 ##### 15 continue;
1306 -
1307 1777 16 if (b->write != NULL)
1308 892 17 error = b->write(b, oid, data, len, type);
1309 - }
1310 -
1311 893 21,22 if (!error || error == GIT_PASSTHROUGH)
1312 892 23 return 0;
1313 -
1314 - /* if no backends were able to write the object directly, we try a
1315 - * streaming write to the backends; just write the whole object into the
1316 - * stream in one push
1317 - */
1318 1 24,25 if ((error = git_odb_open_wstream(&stream, db, len, type)) != 0)
1319 1 26 return error;
1320 -
1321 ##### 27 stream->write(stream, data, len);
1322 ##### 28 error = stream->finalize_write(stream, oid);
1323 ##### 29 git_odb_stream_free(stream);
1324 -
1325 ##### 30 return error;
1326 - }
1327 -
1328 2890 2 static int hash_header(git_hash_ctx *ctx, git_object_size_t size, git_object_t type)
1329 - {
1330 - char header[64];
1331 - size_t hdrlen;
1332 - int error;
1333 -
1334 2890 2,3 if ((error = git_odb__format_object_header(&hdrlen,
1335 - header, sizeof(header), size, type)) < 0)
1336 ##### 4 return error;
1337 -
1338 2890 5 return git_hash_update(ctx, header, hdrlen);
1339 - }
1340 -
1341 2891 2 int git_odb_open_wstream(
1342 - git_odb_stream **stream, git_odb *db, git_object_size_t size, git_object_t type)
1343 - {
1344 2891 2 size_t i, writes = 0;
1345 2891 2 int error = GIT_ERROR;
1346 2891 2 git_hash_ctx *ctx = NULL;
1347 -
1348 2891 2-4 assert(stream && db);
1349 -
1350 8670 5,13-15 for (i = 0; i < db->backends.length && error < 0; ++i) {
1351 5779 6 backend_internal *internal = git_vector_get(&db->backends, i);
1352 5779 7 git_odb_backend *b = internal->backend;
1353 -
1354 - /* we don't write in alternates! */
1355 5779 7 if (internal->is_alternate)
1356 ##### 8 continue;
1357 -
1358 5779 9 if (b->writestream != NULL) {
1359 2889 10 ++writes;
1360 2889 10 error = b->writestream(stream, b, size, type);
1361 2890 11 } else if (b->write != NULL) {
1362 1 12 ++writes;
1363 1 12 error = init_fake_wstream(stream, b, size, type);
1364 - }
1365 - }
1366 -
1367 2891 16 if (error < 0) {
1368 1 17 if (error == GIT_PASSTHROUGH)
1369 ##### 18 error = 0;
1370 1 19 else if (!writes)
1371 1 20 error = git_odb__error_unsupported_in_backend("write object");
1372 -
1373 1 21 goto done;
1374 - }
1375 -
1376 2890 22 ctx = git__malloc(sizeof(git_hash_ctx));
1377 2890 23,24 GIT_ERROR_CHECK_ALLOC(ctx);
1378 -
1379 2890 25-28 if ((error = git_hash_ctx_init(ctx)) < 0 ||
1380 - (error = hash_header(ctx, size, type)) < 0)
1381 - goto done;
1382 -
1383 2890 29 (*stream)->hash_ctx = ctx;
1384 2890 29 (*stream)->declared_size = size;
1385 2890 29 (*stream)->received_bytes = 0;
1386 -
1387 - done:
1388 2891 30 if (error)
1389 1 31 git__free(ctx);
1390 2891 32 return error;
1391 - }
1392 -
1393 2 2 static int git_odb_stream__invalid_length(
1394 - const git_odb_stream *stream,
1395 - const char *action)
1396 - {
1397 2 2 git_error_set(GIT_ERROR_ODB,
1398 - "cannot %s - "
1399 - "Invalid length. %"PRId64" was expected. The "
1400 - "total size of the received chunks amounts to %"PRId64".",
1401 - action, stream->declared_size, stream->received_bytes);
1402 -
1403 2 3 return -1;
1404 - }
1405 -
1406 2861 2 int git_odb_stream_write(git_odb_stream *stream, const char *buffer, size_t len)
1407 - {
1408 2861 2 git_hash_update(stream->hash_ctx, buffer, len);
1409 -
1410 2861 3 stream->received_bytes += len;
1411 -
1412 2861 3 if (stream->received_bytes > stream->declared_size)
1413 1 4 return git_odb_stream__invalid_length(stream,
1414 - "stream_write()");
1415 -
1416 2860 5 return stream->write(stream, buffer, len);
1417 - }
1418 -
1419 2889 2 int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream)
1420 - {
1421 2889 2 if (stream->received_bytes != stream->declared_size)
1422 1 3 return git_odb_stream__invalid_length(stream,
1423 - "stream_finalize_write()");
1424 -
1425 2888 4 git_hash_final(out, stream->hash_ctx);
1426 -
1427 2888 5,6 if (git_odb__freshen(stream->backend->odb, out))
1428 2134 7 return 0;
1429 -
1430 754 8 return stream->finalize_write(stream, out);
1431 - }
1432 -
1433 3352 2 int git_odb_stream_read(git_odb_stream *stream, char *buffer, size_t len)
1434 - {
1435 3352 2 return stream->read(stream, buffer, len);
1436 - }
1437 -
1438 2939 2 void git_odb_stream_free(git_odb_stream *stream)
1439 - {
1440 2939 2 if (stream == NULL)
1441 2939 3,7 return;
1442 -
1443 2939 4 git_hash_ctx_cleanup(stream->hash_ctx);
1444 2939 5 git__free(stream->hash_ctx);
1445 2939 6 stream->free(stream);
1446 - }
1447 -
1448 49 2 int git_odb_open_rstream(
1449 - git_odb_stream **stream,
1450 - size_t *len,
1451 - git_object_t *type,
1452 - git_odb *db,
1453 - const git_oid *oid)
1454 - {
1455 49 2 size_t i, reads = 0;
1456 49 2 int error = GIT_ERROR;
1457 -
1458 49 2-4 assert(stream && db);
1459 -
1460 147 5,9-11 for (i = 0; i < db->backends.length && error < 0; ++i) {
1461 98 6 backend_internal *internal = git_vector_get(&db->backends, i);
1462 98 7 git_odb_backend *b = internal->backend;
1463 -
1464 98 7 if (b->readstream != NULL) {
1465 49 8 ++reads;
1466 49 8 error = b->readstream(stream, len, type, b, oid);
1467 - }
1468 - }
1469 -
1470 49 12 if (error == GIT_PASSTHROUGH)
1471 ##### 13 error = 0;
1472 49 14,15 if (error < 0 && !reads)
1473 ##### 16 error = git_odb__error_unsupported_in_backend("read object streamed");
1474 -
1475 49 17 return error;
1476 - }
1477 -
1478 72 2 int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_progress_cb progress_cb, void *progress_payload)
1479 - {
1480 72 2 size_t i, writes = 0;
1481 72 2 int error = GIT_ERROR;
1482 -
1483 72 2-4 assert(out && db);
1484 -
1485 144 5,11-13 for (i = 0; i < db->backends.length && error < 0; ++i) {
1486 72 6 backend_internal *internal = git_vector_get(&db->backends, i);
1487 72 7 git_odb_backend *b = internal->backend;
1488 -
1489 - /* we don't write in alternates! */
1490 72 7 if (internal->is_alternate)
1491 ##### 8 continue;
1492 -
1493 72 9 if (b->writepack != NULL) {
1494 72 10 ++writes;
1495 72 10 error = b->writepack(out, b, db, progress_cb, progress_payload);
1496 - }
1497 - }
1498 -
1499 72 14 if (error == GIT_PASSTHROUGH)
1500 ##### 15 error = 0;
1501 72 16,17 if (error < 0 && !writes)
1502 ##### 18 error = git_odb__error_unsupported_in_backend("write pack");
1503 -
1504 72 19 return error;
1505 - }
1506 -
1507 ##### 2 void *git_odb_backend_data_alloc(git_odb_backend *backend, size_t len)
1508 - {
1509 - GIT_UNUSED(backend);
1510 ##### 2 return git__malloc(len);
1511 - }
1512 -
1513 - #ifndef GIT_DEPRECATE_HARD
1514 ##### 2 void *git_odb_backend_malloc(git_odb_backend *backend, size_t len)
1515 - {
1516 ##### 2 return git_odb_backend_data_alloc(backend, len);
1517 - }
1518 - #endif
1519 -
1520 ##### 2 void git_odb_backend_data_free(git_odb_backend *backend, void *data)
1521 - {
1522 - GIT_UNUSED(backend);
1523 ##### 2 git__free(data);
1524 ##### 3 }
1525 -
1526 2416 2 int git_odb_refresh(struct git_odb *db)
1527 - {
1528 - size_t i;
1529 2416 2,3 assert(db);
1530 -
1531 7260 4,10,11 for (i = 0; i < db->backends.length; ++i) {
1532 4844 5 backend_internal *internal = git_vector_get(&db->backends, i);
1533 4844 6 git_odb_backend *b = internal->backend;
1534 -
1535 4844 6 if (b->refresh != NULL) {
1536 2413 7 int error = b->refresh(b);
1537 2413 8 if (error < 0)
1538 ##### 9 return error;
1539 - }
1540 - }
1541 -
1542 2416 12 return 0;
1543 - }
1544 -
1545 2 2 int git_odb__error_mismatch(const git_oid *expected, const git_oid *actual)
1546 - {
1547 - char expected_oid[GIT_OID_HEXSZ + 1], actual_oid[GIT_OID_HEXSZ + 1];
1548 -
1549 2 2 git_oid_tostr(expected_oid, sizeof(expected_oid), expected);
1550 2 3 git_oid_tostr(actual_oid, sizeof(actual_oid), actual);
1551 -
1552 2 4 git_error_set(GIT_ERROR_ODB, "object hash mismatch - expected %s but got %s",
1553 - expected_oid, actual_oid);
1554 -
1555 2 5 return GIT_EMISMATCH;
1556 - }
1557 -
1558 201703 2 int git_odb__error_notfound(
1559 - const char *message, const git_oid *oid, size_t oid_len)
1560 - {
1561 201703 2 if (oid != NULL) {
1562 - char oid_str[GIT_OID_HEXSZ + 1];
1563 201703 3 git_oid_tostr(oid_str, oid_len+1, oid);
1564 205876 4,5 git_error_set(GIT_ERROR_ODB, "object not found - %s (%.*s)",
1565 - message, (int) oid_len, oid_str);
1566 - } else
1567 ##### 6 git_error_set(GIT_ERROR_ODB, "object not found - %s", message);
1568 -
1569 195546 7 return GIT_ENOTFOUND;
1570 - }
1571 -
1572 9 2 static int error_null_oid(int error, const char *message)
1573 - {
1574 9 2 git_error_set(GIT_ERROR_ODB, "odb: %s: null OID cannot exist", message);
1575 9 3 return error;
1576 - }
1577 -
1578 31 2 int git_odb__error_ambiguous(const char *message)
1579 - {
1580 31 2 git_error_set(GIT_ERROR_ODB, "ambiguous SHA1 prefix - %s", message);
1581 31 3 return GIT_EAMBIGUOUS;
1582 - }
1583 -
1584 1 2 int git_odb_init_backend(git_odb_backend *backend, unsigned int version)
1585 - {
1586 1 2-4 GIT_INIT_STRUCTURE_FROM_TEMPLATE(
1587 - backend, version, git_odb_backend, GIT_ODB_BACKEND_INIT);
1588 1 5 return 0;
1589 - }