From 25e1726d311d506b63de15b2b88a5e5fde0eda76 Mon Sep 17 00:00:00 2001
From: Fred Drake <fdrake@acm.org>
Date: Fri, 30 Jun 2000 17:48:51 +0000
Subject: [*** Not tested as I don't have Windows running right now! ***]

Trent Mick <trentm@activestate.com>:

Fix PC/msvcrtmodule.c and PC/winreg.c for Win64. Basically:

- sizeof(HKEY) > sizeof(long) on Win64, so use PyLong_FromVoidPtr()
instead of PyInt_FromLong() to return HKEY values on Win64

- Check for string overflow of an arbitrary registry value (I know
that ensuring that a registry value does not overflow 2**31 characters
seems ridiculous but it is *possible*).

Closes SourceForge patch #100517.
---
 PC/_winreg.c      | 21 +++++++++++++++++++--
 PC/msvcrtmodule.c |  7 +++++--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/PC/_winreg.c b/PC/_winreg.c
index 4539959..75ceb8b 100644
--- a/PC/_winreg.c
+++ b/PC/_winreg.c
@@ -592,7 +592,6 @@ PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK)
 		*pHANDLE = (HKEY)PyLong_AsVoidPtr(ob);
 		if (PyErr_Occurred())
 			return FALSE;
-		*pHANDLE = (HKEY)PyInt_AsLong(ob);
 	}
 	else {
 		PyErr_SetString(
@@ -628,12 +627,21 @@ PyWinObject_CloseHKEY(PyObject *obHandle)
 	if (PyHKEY_Check(obHandle)) {
 		ok = PyHKEY_Close(obHandle);
 	}
+#if SIZEOF_LONG >= SIZEOF_HKEY
 	else if (PyInt_Check(obHandle)) {
 		long rc = RegCloseKey((HKEY)PyInt_AsLong(obHandle));
 		ok = (rc == ERROR_SUCCESS);
 		if (!ok)
 			PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
 	}
+#else
+	else if (PyLong_Check(obHandle)) {
+		long rc = RegCloseKey((HKEY)PyLong_AsVoidPtr(obHandle));
+		ok = (rc == ERROR_SUCCESS);
+		if (!ok)
+			PyErr_SetFromWindowsErrWithFunction(rc, "RegCloseKey");
+	}
+#endif
 	else {
 		PyErr_SetString(
 			PyExc_TypeError,
@@ -880,13 +888,22 @@ Reg2Py(char *retDataBuf, DWORD retDataSize, DWORD typ)
 
 				fixupMultiSZ(str, retDataBuf, retDataSize);
 				obData = PyList_New(s);
+				if (obData == NULL)
+					return NULL;
 				for (index = 0; index < s; index++)
 				{
+					size_t len = _mbstrlen(str[index]);
+					if (len > INT_MAX) {
+						PyErr_SetString(PyExc_OverflowError,
+							"registry string is too long for a Python string");
+						Py_DECREF(obData);
+						return NULL;
+					}
 					PyList_SetItem(obData,
 						       index,
 						       PyUnicode_DecodeMBCS(
 						            (const char *)str[index],
-							    _mbstrlen(str[index]),
+							   (int)len,
 							    NULL)
 						       );
 				}
diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c
index 21be21a..613e173 100755
--- a/PC/msvcrtmodule.c
+++ b/PC/msvcrtmodule.c
@@ -90,7 +90,7 @@ static PyObject *msvcrt_open_osfhandle(PyObject *self, PyObject *args)
 static PyObject *msvcrt_get_osfhandle(PyObject *self, PyObject *args)
 {
 	int fd;
-	long handle;
+	intptr_t handle;
 
 	if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
 		return NULL;
@@ -99,7 +99,10 @@ static PyObject *msvcrt_get_osfhandle(PyObject *self, PyObject *args)
 	if (handle == -1)
 		return PyErr_SetFromErrno(PyExc_IOError);
 
-	return PyInt_FromLong(handle);
+	/* technically 'handle' is not a pointer, but a integer as
+	   large as a pointer, Python's *VoidPtr interface is the
+	   most appropriate here */
+	return PyLong_FromVoidPtr((void*)handle);
 }
 
 /* Console I/O */
-- 
cgit v0.12

