don't leak objects which can't be cached
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
diff --git a/include/got_error.h b/include/got_error.h
index ea6e03a..21b84de 100644
--- a/include/got_error.h
+++ b/include/got_error.h
@@ -91,6 +91,7 @@
#define GOT_ERR_DIR_NOT_EMPTY 75
#define GOT_ERR_COMMIT_NO_CHANGES 76
#define GOT_ERR_BRANCH_MOVED 77
+#define GOT_ERR_OBJ_TOO_LARGE 78
static const struct got_error {
int code;
@@ -175,6 +176,7 @@ static const struct got_error {
{ GOT_ERR_COMMIT_NO_CHANGES, "no changes to commit" },
{ GOT_ERR_BRANCH_MOVED, "work tree's branch reference has moved; "
"new branch reference or rebase required" },
+ { GOT_ERR_OBJ_TOO_LARGE, "object too large" },
};
/*
diff --git a/lib/object_cache.c b/lib/object_cache.c
index 5c1d8d2..0c1a60f 100644
--- a/lib/object_cache.c
+++ b/lib/object_cache.c
@@ -184,7 +184,7 @@ got_object_cache_add(struct got_object_cache *cache, struct got_object_id *id, v
free(id_str);
#endif
cache->cache_toolarge++;
- return NULL;
+ return got_error(GOT_ERR_OBJ_TOO_LARGE);
}
nelem = got_object_idset_num_elements(cache->idset);
@@ -231,12 +231,8 @@ got_object_cache_add(struct got_object_cache *cache, struct got_object_id *id, v
}
err = got_object_idset_add(cache->idset, id, ce);
- if (err) {
- if (err->code == GOT_ERR_OBJ_EXISTS) {
- free(ce);
- err = NULL;
- }
- }
+ if (err)
+ free(ce);
return err;
}
diff --git a/lib/repository.c b/lib/repository.c
index bff89f5..0277a44 100644
--- a/lib/repository.c
+++ b/lib/repository.c
@@ -180,8 +180,12 @@ got_repo_cache_object(struct got_repository *repo, struct got_object_id *id,
#ifndef GOT_NO_OBJ_CACHE
const struct got_error *err = NULL;
err = got_object_cache_add(&repo->objcache, id, obj);
- if (err)
+ if (err) {
+ if (err->code == GOT_ERR_OBJ_EXISTS ||
+ err->code == GOT_ERR_OBJ_TOO_LARGE)
+ err = NULL;
return err;
+ }
obj->refcnt++;
#endif
return NULL;
@@ -201,8 +205,12 @@ got_repo_cache_tree(struct got_repository *repo, struct got_object_id *id,
#ifndef GOT_NO_OBJ_CACHE
const struct got_error *err = NULL;
err = got_object_cache_add(&repo->treecache, id, tree);
- if (err)
+ if (err) {
+ if (err->code == GOT_ERR_OBJ_EXISTS ||
+ err->code == GOT_ERR_OBJ_TOO_LARGE)
+ err = NULL;
return err;
+ }
tree->refcnt++;
#endif
return NULL;
@@ -223,8 +231,12 @@ got_repo_cache_commit(struct got_repository *repo, struct got_object_id *id,
#ifndef GOT_NO_OBJ_CACHE
const struct got_error *err = NULL;
err = got_object_cache_add(&repo->commitcache, id, commit);
- if (err)
+ if (err) {
+ if (err->code == GOT_ERR_OBJ_EXISTS ||
+ err->code == GOT_ERR_OBJ_TOO_LARGE)
+ err = NULL;
return err;
+ }
commit->refcnt++;
#endif
return NULL;
@@ -245,8 +257,12 @@ got_repo_cache_tag(struct got_repository *repo, struct got_object_id *id,
#ifndef GOT_NO_OBJ_CACHE
const struct got_error *err = NULL;
err = got_object_cache_add(&repo->tagcache, id, tag);
- if (err)
+ if (err) {
+ if (err->code == GOT_ERR_OBJ_EXISTS ||
+ err->code == GOT_ERR_OBJ_TOO_LARGE)
+ err = NULL;
return err;
+ }
tag->refcnt++;
#endif
return NULL;
diff --git a/libexec/got-read-pack/got-read-pack.c b/libexec/got-read-pack/got-read-pack.c
index 842624e..0f2d28d 100644
--- a/libexec/got-read-pack/got-read-pack.c
+++ b/libexec/got-read-pack/got-read-pack.c
@@ -63,10 +63,13 @@ open_object(struct got_object **obj, struct got_pack *pack,
(*obj)->refcnt++;
err = got_object_cache_add(objcache, id, *obj);
- if (err)
+ if (err) {
+ if (err->code == GOT_ERR_OBJ_EXISTS ||
+ err->code == GOT_ERR_OBJ_TOO_LARGE)
+ err = NULL;
return err;
+ }
(*obj)->refcnt++;
-
return NULL;
}