Anonymous avatar Anonymous committed d2da681

Tim pointed out a remaining vulnerability in popitem(): the
PyTuple_New() could *conceivably* clear the dict, so move the test for
an empty dict after the tuple allocation. It means that we waste time
allocating and deallocating a 2-tuple when the dict is empty, but who
cares. It also means that when the dict is empty *and* there's no
memory to allocate a 2-tuple, we raise MemoryError, not KeyError --
but that may actually a good idea: if there's no room for a lousy
2-tuple, what are the chances that there's room for a KeyError
instance?

Comments (0)

Files changed (1)

Objects/dictobject.c

 
 	if (!PyArg_NoArgs(args))
 		return NULL;
-	if (mp->ma_used == 0) {
-		PyErr_SetString(PyExc_KeyError,
-				"popitem(): dictionary is empty");
-		return NULL;
-	}
 	/* Allocate the result tuple first.  Believe it or not,
 	 * this allocation could trigger a garbage collection which
 	 * could resize the dict, which would invalidate the pointer
 	res = PyTuple_New(2);
 	if (res == NULL)
 		return NULL;
+	if (mp->ma_used == 0) {
+		Py_DECREF(res);
+		PyErr_SetString(PyExc_KeyError,
+				"popitem(): dictionary is empty");
+		return NULL;
+	}
 	/* Set ep to "the first" dict entry with a value.  We abuse the hash
 	 * field of slot 0 to hold a search finger:
 	 * If slot 0 has a value, use slot 0.
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.