Commit d5a90aac91011cd4e3357e1bdcebf7449bb194c3

Stefan Sperling 2018-06-04T22:32:38

return existing data if existing object id is added to set

diff --git a/lib/got_lib_object_idset.h b/lib/got_lib_object_idset.h
index 193a271..129ff2f 100644
--- a/lib/got_lib_object_idset.h
+++ b/lib/got_lib_object_idset.h
@@ -19,8 +19,8 @@ struct got_object_idset;
 struct got_object_idset *got_object_idset_alloc(void);
 void got_object_idset_free(struct got_object_idset *);
 
-const struct got_error *got_object_idset_add(struct got_object_idset *,
-    struct got_object_id *, void *);
+const struct got_error *got_object_idset_add(void **,
+    struct got_object_idset *, struct got_object_id *, void *);
 void *got_object_idset_get_data(struct got_object_idset *,
     struct got_object_id *);
 const struct got_error *got_object_idset_remove(struct got_object_idset *,
diff --git a/lib/object_idset.c b/lib/object_idset.c
index 0f91478..01dbf25 100644
--- a/lib/object_idset.c
+++ b/lib/object_idset.c
@@ -86,12 +86,15 @@ got_object_idset_free(struct got_object_idset *set)
 }
 
 const struct got_error *
-got_object_idset_add(struct got_object_idset *set, struct got_object_id *id,
-    void *data)
+got_object_idset_add(void **existing_data,
+    struct got_object_idset *set, struct got_object_id *id, void *data)
 {
 	struct got_object_idset_element *new, *entry;
 	uint8_t i = id->sha1[0];
 
+	if (existing_data)
+		*existing_data = NULL;
+
 	if (set->nelem >= GOT_OBJECT_IDSET_MAX_ELEM)
 		return got_error(GOT_ERR_NO_SPACE);
 
@@ -118,6 +121,8 @@ got_object_idset_add(struct got_object_idset *set, struct got_object_id *id,
 
 		if (cmp == 0) {
 			free(new);
+			if (existing_data)
+				*existing_data = entry->data;
 			return got_error(GOT_ERR_OBJ_EXISTS);
 		} else if (cmp < 0) {
 			TAILQ_INSERT_BEFORE(entry, new, entry);
diff --git a/regress/idset/idset_test.c b/regress/idset/idset_test.c
index 3490429..dceb48a 100644
--- a/regress/idset/idset_test.c
+++ b/regress/idset/idset_test.c
@@ -71,6 +71,7 @@ idset_add_remove_iter(void)
 {
 	const struct got_error *err = NULL;
 	struct got_object_idset *set;
+	void *existing_data;
 
 	set = got_object_idset_alloc();
 	if (set == NULL) {
@@ -95,9 +96,13 @@ idset_add_remove_iter(void)
 		goto done;
 	}
 
-	err = got_object_idset_add(set, &id1, (void *)data1);
+	err = got_object_idset_add(&existing_data, set, &id1, (void *)data1);
 	if (err)
 		goto done;
+	if (existing_data != NULL) {
+		err = got_error(GOT_ERR_BAD_OBJ_DATA);
+		goto done;
+	}
 	if (got_object_idset_num_elements(set) != 1) {
 		err = got_error(GOT_ERR_BAD_OBJ_DATA);
 		goto done;
@@ -108,16 +113,23 @@ idset_add_remove_iter(void)
 		goto done;
 	}
 
-	err = got_object_idset_add(set, &id2, (void *)data2);
+	err = got_object_idset_add(&existing_data, set, &id2, (void *)data2);
 	if (err)
 		goto done;
-	err = got_object_idset_add(set, &id2, NULL);
-	if (err == NULL) {
+	if (existing_data != NULL) {
+		err = got_error(GOT_ERR_BAD_OBJ_DATA);
+		goto done;
+	}
+	err = got_object_idset_add(&existing_data, set, &id2, NULL);
+	if (existing_data == NULL) {
 		err = got_error(GOT_ERR_BAD_OBJ_DATA);
 		goto done;
 	}
 	if (err->code != GOT_ERR_OBJ_EXISTS)
 		goto done;
+	err = got_object_idset_add(NULL, set, &id2, NULL);
+	if (err->code != GOT_ERR_OBJ_EXISTS)
+		goto done;
 	err = NULL;
 
 	if (!got_object_idset_contains(set, &id1)) {
@@ -133,7 +145,7 @@ idset_add_remove_iter(void)
 		goto done;
 	}
 
-	err = got_object_idset_add(set, &id3, (void *)data3);
+	err = got_object_idset_add(NULL, set, &id3, (void *)data3);
 	if (err)
 		goto done;