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.
Will backport to 2.3 next.
This commit is contained in:
Guido van Rossum 2003-11-30 22:01:43 +00:00
parent 457bf91a7f
commit a6a38ad55c
1 changed files with 48 additions and 16 deletions

View File

@ -1031,6 +1031,7 @@ PyEnumKey(PyObject *self, PyObject *args)
PyObject *obKey;
int index;
long rc;
PyObject *retStr;
char *retBuf;
DWORD len;
@ -1045,11 +1046,17 @@ PyEnumKey(PyObject *self, PyObject *args)
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 *
@ -1080,8 +1087,14 @@ PyEnumValue(PyObject *self, PyObject *args)
"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,
@ -1094,14 +1107,21 @@ PyEnumValue(PyObject *self, PyObject *args)
&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;
}
@ -1206,10 +1226,11 @@ PyQueryValue(PyObject *self, PyObject *args)
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;
@ -1219,12 +1240,18 @@ PyQueryValue(PyObject *self, PyObject *args)
!= 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 *
@ -1252,13 +1279,18 @@ PyQueryValueEx(PyObject *self, PyObject *args)
!= 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);