234 lines
7.1 KiB
Diff
Executable file
234 lines
7.1 KiB
Diff
Executable file
From 00164b4a9821e82f513183035587bea9243a7d5e Mon Sep 17 00:00:00 2001
|
|
From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
|
|
Date: Tue, 1 Aug 2017 14:13:24 -0400
|
|
Subject: [PATCH 3/3] VS2015 Support: Backport of "Issue #23524: Replace
|
|
_PyVerify_fd function with calling
|
|
_set_thread_local_invalid_parameter_handler on every thread."
|
|
|
|
This commit is a partial backport of python/cpython@d81431f. It was
|
|
originally designed to work with python-cmake-buildsystem.
|
|
|
|
Implementation of "_PyVerify_fd" in "Python/fileutils.c" found only in
|
|
Python 3.x has been copied into "Modules/posixmodule.c"
|
|
|
|
The following modules have NOT been backported:
|
|
|
|
* PCbuild
|
|
---
|
|
Modules/posixmodule.c | 54 +++++++++++++++++++++++-------------------
|
|
PC/invalid_parameter_handler.c | 22 +++++++++++++++++
|
|
Python/pystate.c | 12 ++++++++++
|
|
PCbuild/pythoncore.vcxproj | 1 +
|
|
PCbuild/pythoncore.vcxproj.filters | 1 +
|
|
5 files changed, 65 insertions(+), 26 deletions(-)
|
|
create mode 100644 PC/invalid_parameter_handler.c
|
|
|
|
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
|
|
index 90d5318..6a180a0 100644
|
|
--- a/Modules/posixmodule.c
|
|
+++ b/Modules/posixmodule.c
|
|
@@ -277,6 +277,7 @@ extern int lstat(const char *, struct stat *);
|
|
#include "osdefs.h"
|
|
#include <malloc.h>
|
|
#include <windows.h>
|
|
+#include <malloc.h>
|
|
#include <shellapi.h> /* for ShellExecute() */
|
|
#define popen _popen
|
|
#define pclose _pclose
|
|
@@ -535,8 +534,28 @@ _PyInt_FromDev(PY_LONG_LONG v)
|
|
# define _PyInt_FromDev PyInt_FromLong
|
|
#endif
|
|
|
|
+#ifdef _MSC_VER
|
|
+#if _MSC_VER >= 1900
|
|
+
|
|
+/* This function lets the Windows CRT validate the file handle without
|
|
+ terminating the process if it's invalid. */
|
|
+int
|
|
+_PyVerify_fd(int fd)
|
|
+{
|
|
+ intptr_t osh;
|
|
+ /* Fast check for the only condition we know */
|
|
+ if (fd < 0) {
|
|
+ _set_errno(EBADF);
|
|
+ return 0;
|
|
+ }
|
|
+ osh = _get_osfhandle(fd);
|
|
+ return osh != (intptr_t)-1;
|
|
+}
|
|
+
|
|
+#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
|
|
+
|
|
+#elif _MSC_VER >= 1400
|
|
|
|
-#if defined _MSC_VER && _MSC_VER >= 1400
|
|
/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
|
|
* valid and raise an assertion if it isn't.
|
|
* Normally, an invalid fd is likely to be a C program error and therefore
|
|
@@ -601,35 +580,18 @@ _PyInt_FromDev(PY_LONG_LONG v)
|
|
* Only the first items must be present.
|
|
*/
|
|
|
|
-#if _MSC_VER >= 1900
|
|
-
|
|
-typedef struct {
|
|
- CRITICAL_SECTION lock;
|
|
- intptr_t osfhnd;
|
|
- __int64 startpos;
|
|
- char osfile;
|
|
-} my_ioinfo;
|
|
-
|
|
-#define IOINFO_L2E 6
|
|
-#define IOINFO_ARRAYS 128
|
|
-
|
|
-#else
|
|
-
|
|
typedef struct {
|
|
intptr_t osfhnd;
|
|
char osfile;
|
|
} my_ioinfo;
|
|
|
|
-#define IOINFO_L2E 5
|
|
-#define IOINFO_ARRAYS 64
|
|
-
|
|
-#endif
|
|
-
|
|
extern __declspec(dllimport) char * __pioinfo[];
|
|
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
|
|
#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
|
|
#define FOPEN 0x01
|
|
#define _NO_CONSOLE_FILENO (intptr_t)-2
|
|
+#define IOINFO_L2E 5
|
|
+#define IOINFO_ARRAYS 64
|
|
|
|
/* This function emulates what the windows CRT does to validate file handles */
|
|
int
|
|
@@ -653,6 +649,8 @@ _PyVerify_fd_dup2(int fd1, int fd2)
|
|
#define _PyVerify_fd_dup2(A, B) (1)
|
|
#endif
|
|
|
|
+#endif /* defined _MSC_VER */
|
|
+
|
|
/* Return a dictionary corresponding to the POSIX environment table */
|
|
#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
|
|
/* On Darwin/MacOSX a shared library or framework has no access to
|
|
@@ -1260,14 +1254,10 @@ win32_fstat(int file_number, struct win32_stat *result)
|
|
|
|
h = (HANDLE)_get_osfhandle(file_number);
|
|
|
|
- /* Protocol violation: we explicitly clear errno, instead of
|
|
- setting it to a POSIX error. Callers should use GetLastError. */
|
|
errno = 0;
|
|
|
|
if (h == INVALID_HANDLE_VALUE) {
|
|
- /* This is really a C library error (invalid file handle).
|
|
- We set the Win32 error to the closes one matching. */
|
|
- SetLastError(ERROR_INVALID_HANDLE);
|
|
+ errno = EBADF;
|
|
return -1;
|
|
}
|
|
memset(result, 0, sizeof(*result));
|
|
@@ -1268,6 +1266,7 @@ win32_fstat(int file_number, struct win32_stat *result)
|
|
if (type == FILE_TYPE_UNKNOWN) {
|
|
DWORD error = GetLastError();
|
|
if (error != 0) {
|
|
+ errno = EINVAL;
|
|
return -1;
|
|
}
|
|
/* else: valid but unknown file */
|
|
@@ -1284,6 +1281,7 @@ win32_fstat(int file_number, struct win32_stat *result)
|
|
}
|
|
|
|
if (!GetFileInformationByHandle(h, &info)) {
|
|
+ errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
diff --git a/PC/invalid_parameter_handler.c b/PC/invalid_parameter_handler.c
|
|
new file mode 100644
|
|
index 0000000..3bc0104
|
|
--- /dev/null
|
|
+++ b/PC/invalid_parameter_handler.c
|
|
@@ -0,0 +1,22 @@
|
|
+#ifdef _MSC_VER
|
|
+
|
|
+#include <stdlib.h>
|
|
+
|
|
+#if _MSC_VER >= 1900
|
|
+/* pyconfig.h uses this function in the _Py_BEGIN/END_SUPPRESS_IPH
|
|
+ * macros. It does not need to be defined when building using MSVC
|
|
+ * earlier than 14.0 (_MSC_VER == 1900).
|
|
+ */
|
|
+
|
|
+static void __cdecl _silent_invalid_parameter_handler(
|
|
+ wchar_t const* expression,
|
|
+ wchar_t const* function,
|
|
+ wchar_t const* file,
|
|
+ unsigned int line,
|
|
+ uintptr_t pReserved) { }
|
|
+
|
|
+void *_Py_silent_invalid_parameter_handler =
|
|
+ (void*)_silent_invalid_parameter_handler;
|
|
+#endif
|
|
+
|
|
+#endif
|
|
diff --git a/Python/pystate.c b/Python/pystate.c
|
|
index eb992c1..1c0f970 100644
|
|
--- a/Python/pystate.c
|
|
+++ b/Python/pystate.c
|
|
@@ -22,6 +22,12 @@ the expense of doing their own locking).
|
|
#endif
|
|
#endif
|
|
|
|
+#if defined _MSC_VER && _MSC_VER >= 1900
|
|
+/* Issue #23524: Temporary fix to disable termination due to invalid parameters */
|
|
+PyAPI_DATA(void*) _Py_silent_invalid_parameter_handler;
|
|
+#include <stdlib.h>
|
|
+#endif
|
|
+
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
@@ -202,6 +208,12 @@ new_threadstate(PyInterpreterState *interp, int init)
|
|
tstate->next = interp->tstate_head;
|
|
interp->tstate_head = tstate;
|
|
HEAD_UNLOCK();
|
|
+
|
|
+#if defined _MSC_VER && _MSC_VER >= 1900
|
|
+ /* Issue #23524: Temporary fix to disable termination due to invalid parameters */
|
|
+ _set_thread_local_invalid_parameter_handler((_invalid_parameter_handler)_Py_silent_invalid_parameter_handler);
|
|
+#endif
|
|
+
|
|
}
|
|
|
|
return tstate;
|
|
--
|
|
2.5.0
|
|
|
|
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
|
|
index 99291ea..af17762 100644
|
|
--- a/PCbuild/pythoncore.vcxproj
|
|
+++ b/PCbuild/pythoncore.vcxproj
|
|
@@ -333,6 +333,7 @@
|
|
<ClCompile Include="..\Parser\parser.c" />
|
|
<ClCompile Include="..\Parser\parsetok.c" />
|
|
<ClCompile Include="..\Parser\tokenizer.c" />
|
|
+ <ClCompile Include="..\PC\invalid_parameter_handler.c" />
|
|
<ClCompile Include="..\PC\_subprocess.c" />
|
|
<ClCompile Include="..\PC\_winreg.c" />
|
|
<ClCompile Include="..\PC\config.c" />
|
|
|
|
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
|
|
index 99291ea..af17762 100644
|
|
--- a/PCbuild/pythoncore.vcxproj.filters
|
|
+++ b/PCbuild/pythoncore.vcxproj.filters
|
|
@@ -794,6 +794,9 @@
|
|
<ClCompile Include="..\Parser\tokenizer.c">
|
|
<Filter>Parser</Filter>
|
|
</ClCompile>
|
|
+ <ClCompile Include="..\PC\invalid_parameter_handler.c">
|
|
+ <Filter>PC</Filter>
|
|
+ </ClCompile>
|
|
<ClCompile Include="..\PC\_subprocess.c">
|
|
<Filter>PC</Filter>
|
|
</ClCompile>
|