Commits

Georg Brandl committed 891e332

Backport rev. 51798 from trunk:
fix setobject.c refcounts and error checks.

Comments (0)

Files changed (1)

Objects/setobject.c

 	assert(so->fill <= so->mask);  /* at least one empty slot */
 	n_used = so->used;
 	Py_INCREF(entry->key);
-	if (set_insert_key(so, entry->key, entry->hash) == -1)
+	if (set_insert_key(so, entry->key, entry->hash) == -1) {
+		Py_DECREF(entry->key);
 		return -1;
+	}
 	if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
 		return 0;
 	return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
 		}
 
 		while (set_next((PySetObject *)other, &pos, &entry)) {
-			if (set_contains_entry(so, entry)) {
+			int rv = set_contains_entry(so, entry);
+			if (rv == -1) {
+				Py_DECREF(result);
+				return NULL;
+			}
+			if (rv) {
 				if (set_add_entry(result, entry) == -1) {
 					Py_DECREF(result);
 					return NULL;
 	}
 
 	while ((key = PyIter_Next(it)) != NULL) {
-		if (set_contains_key(so, key)) {
+		int rv = set_contains_key(so, key);
+		if (rv == -1) {
+			Py_DECREF(it);
+			Py_DECREF(result);
+			Py_DECREF(key);
+			return NULL;
+		}
+		if (rv) {
 			if (set_add_key(result, key) == -1) {
 				Py_DECREF(it);
 				Py_DECREF(result);
 		Py_ssize_t pos = 0;
 
 		while (set_next((PySetObject *)other, &pos, &entry))
-			set_discard_entry(so, entry);
+			if (set_discard_entry(so, entry) == -1)
+				return -1;
 	} else {
 		PyObject *key, *it;
 		it = PyObject_GetIter(other);
 			entrycopy.hash = entry->hash;
 			entrycopy.key = entry->key;
 			if (!PyDict_Contains(other, entry->key)) {
-				if (set_add_entry((PySetObject *)result, &entrycopy) == -1)
+				if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
+					Py_DECREF(result);
 					return NULL;
+				}
 			}
 		}
 		return result;
 	}
 
 	while (set_next(so, &pos, &entry)) {
-		if (!set_contains_entry((PySetObject *)other, entry)) {
-			if (set_add_entry((PySetObject *)result, entry) == -1)
+		int rv = set_contains_entry((PySetObject *)other, entry);
+		if (rv == -1) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		if (!rv) {
+			if (set_add_entry((PySetObject *)result, entry) == -1) {
+				Py_DECREF(result);
 				return NULL;
+			}
 		}
 	}
 	return result;
 		Py_RETURN_FALSE;
 
 	while (set_next(so, &pos, &entry)) {
-		if (!set_contains_entry((PySetObject *)other, entry))
+		int rv = set_contains_entry((PySetObject *)other, entry);
+		if (rv == -1)
+			return NULL;
+		if (!rv)
 			Py_RETURN_FALSE;
 	}
 	Py_RETURN_TRUE;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.