Commit 79c99a64af2fcd11a3c60a54f989167ef4a72310

Stefan Sperling 2019-05-23T22:24:13

don't leak objects which can't be cached

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;
 }