Commits

Anonymous committed 0ff6925

Backport:
Remove all uses of alloca() from this module. The alloca() return value
isn't checked, and it *is* possible that a very large alloca() call is
made, e.g. when a large registry value is being read. I don't know if
alloca() in that case returns NULL or returns a pointer pointing outside
the stack, and I don't want to know -- I've simply replaced all calls to
alloca() with either PyMem_Malloc() or PyString_FromStringAndSize(NULL,)
as appropriate, followed by a size check. This addresses SF buf 851056.

Comments (0)

Files changed (1)

 	PyObject *obKey;
 	int index;
 	long rc;
+	PyObject *retStr;
 	char *retBuf;
 	DWORD len;
 
 		return PyErr_SetFromWindowsErrWithFunction(rc,
 							   "RegQueryInfoKey");
 	++len;    /* include null terminator */
-	retBuf = (char *)alloca(len);
+	retStr = PyString_FromStringAndSize(NULL, len);
+	if (retStr == NULL)
+		return NULL;
+	retBuf = PyString_AS_STRING(retStr);
 
-	if ((rc = RegEnumKey(hKey, index, retBuf, len)) != ERROR_SUCCESS)
+	if ((rc = RegEnumKey(hKey, index, retBuf, len)) != ERROR_SUCCESS) {
+		Py_DECREF(retStr);
 		return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKey");
-	return Py_BuildValue("s", retBuf);
+	}
+	_PyString_Resize(&retStr, strlen(retBuf));
+	return retStr;
 }
 
 static PyObject *
 							   "RegQueryInfoKey");
 	++retValueSize;    /* include null terminators */
 	++retDataSize;
-	retValueBuf = (char *)alloca(retValueSize);
-	retDataBuf = (char *)alloca(retDataSize);
+	retValueBuf = (char *)PyMem_Malloc(retValueSize);
+	if (retValueBuf == NULL)
+		return PyErr_NoMemory();
+	retDataBuf = (char *)PyMem_Malloc(retDataSize);
+	if (retDataBuf == NULL) {
+		PyMem_Free(retValueBuf);
+		return PyErr_NoMemory();
+	}
 
 	Py_BEGIN_ALLOW_THREADS
 	rc = RegEnumValue(hKey,
 			  &retDataSize);
 	Py_END_ALLOW_THREADS
 
-	if (rc != ERROR_SUCCESS)
-		return PyErr_SetFromWindowsErrWithFunction(rc,
-							   "PyRegEnumValue");
+	if (rc != ERROR_SUCCESS) {
+		retVal = PyErr_SetFromWindowsErrWithFunction(rc,
+							     "PyRegEnumValue");
+		goto fail;
+	}
 	obData = Reg2Py(retDataBuf, retDataSize, typ);
-	if (obData == NULL)
-		return NULL;
+	if (obData == NULL) {
+		retVal = NULL;
+		goto fail;
+	}
 	retVal = Py_BuildValue("sOi", retValueBuf, obData, typ);
 	Py_DECREF(obData);
+  fail:
+	PyMem_Free(retValueBuf);
+	PyMem_Free(retDataBuf);
 	return retVal;
 }
 
 	HKEY hKey;
 	PyObject *obKey;
 	char *subKey;
-
 	long rc;
+	PyObject *retStr;
 	char *retBuf;
 	long bufSize = 0;
+
 	if (!PyArg_ParseTuple(args, "Oz:QueryValue", &obKey, &subKey))
 		return NULL;
 
 	    != ERROR_SUCCESS)
 		return PyErr_SetFromWindowsErrWithFunction(rc,
 							   "RegQueryValue");
-	retBuf = (char *)alloca(bufSize);
+	retStr = PyString_FromStringAndSize(NULL, bufSize);
+	if (retStr == NULL)
+		return NULL;
+	retBuf = PyString_AS_STRING(retStr);
 	if ((rc = RegQueryValue(hKey, subKey, retBuf, &bufSize))
-	    != ERROR_SUCCESS)
+	    != ERROR_SUCCESS) {
+		Py_DECREF(retStr);
 		return PyErr_SetFromWindowsErrWithFunction(rc,
 							   "RegQueryValue");
-	return Py_BuildValue("s", retBuf);
+	}
+	_PyString_Resize(&retStr, strlen(retBuf));
+	return retStr;
 }
 
 static PyObject *
 	    != ERROR_SUCCESS)
 		return PyErr_SetFromWindowsErrWithFunction(rc,
 							   "RegQueryValueEx");
-	retBuf = (char *)alloca(bufSize);
+	retBuf = (char *)PyMem_Malloc(bufSize);
+	if (retBuf == NULL)
+		return PyErr_NoMemory();
 	if ((rc = RegQueryValueEx(hKey, valueName, NULL,
 				  &typ, (BYTE *)retBuf, &bufSize))
-	    != ERROR_SUCCESS)
+	    != ERROR_SUCCESS) {
+		PyMem_Free(retBuf);
 		return PyErr_SetFromWindowsErrWithFunction(rc,
 							   "RegQueryValueEx");
+	}
 	obData = Reg2Py(retBuf, bufSize, typ);
+	PyMem_Free((void *)retBuf);
 	if (obData == NULL)
 		return NULL;
 	result = Py_BuildValue("Oi", obData, typ);