1 From 00164b4a9821e82f513183035587bea9243a7d5e Mon Sep 17 00:00:00 2001
2 From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
3 Date: Tue, 1 Aug 2017 14:13:24 -0400
4 Subject: [PATCH 3/3] VS2015 Support: Backport of "Issue #23524: Replace
5 _PyVerify_fd function with calling
6 _set_thread_local_invalid_parameter_handler on every thread."
8 This commit is a partial backport of python/cpython@d81431f. It was
9 originally designed to work with python-cmake-buildsystem.
11 Implementation of "_PyVerify_fd" in "Python/fileutils.c" found only in
12 Python 3.x has been copied into "Modules/posixmodule.c"
14 The following modules have NOT been backported:
18 Modules/posixmodule.c | 54 +++++++++++++++++++++++-------------------
19 PC/invalid_parameter_handler.c | 22 +++++++++++++++++
20 Python/pystate.c | 12 ++++++++++
21 PCbuild/pythoncore.vcxproj | 1 +
22 PCbuild/pythoncore.vcxproj.filters | 1 +
23 5 files changed, 65 insertions(+), 26 deletions(-)
24 create mode 100644 PC/invalid_parameter_handler.c
26 diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
27 index 90d5318..6a180a0 100644
28 --- a/Modules/posixmodule.c
29 +++ b/Modules/posixmodule.c
30 @@ -277,6 +277,7 @@ extern int lstat(const char *, struct stat *);
35 #include <shellapi.h> /* for ShellExecute() */
37 #define pclose _pclose
38 @@ -535,8 +534,28 @@ _PyInt_FromDev(PY_LONG_LONG v)
39 # define _PyInt_FromDev PyInt_FromLong
45 +/* This function lets the Windows CRT validate the file handle without
46 + terminating the process if it's invalid. */
51 + /* Fast check for the only condition we know */
56 + osh = _get_osfhandle(fd);
57 + return osh != (intptr_t)-1;
60 +#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
62 +#elif _MSC_VER >= 1400
64 -#if defined _MSC_VER && _MSC_VER >= 1400
65 /* Microsoft CRT in VS2005 and higher will verify that a filehandle is
66 * valid and raise an assertion if it isn't.
67 * Normally, an invalid fd is likely to be a C program error and therefore
68 @@ -601,35 +580,18 @@ _PyInt_FromDev(PY_LONG_LONG v)
69 * Only the first items must be present.
75 - CRITICAL_SECTION lock;
82 -#define IOINFO_ARRAYS 128
92 -#define IOINFO_ARRAYS 64
96 extern __declspec(dllimport) char * __pioinfo[];
97 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
98 #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
100 #define _NO_CONSOLE_FILENO (intptr_t)-2
101 +#define IOINFO_L2E 5
102 +#define IOINFO_ARRAYS 64
104 /* This function emulates what the windows CRT does to validate file handles */
106 @@ -653,6 +649,8 @@ _PyVerify_fd_dup2(int fd1, int fd2)
107 #define _PyVerify_fd_dup2(A, B) (1)
110 +#endif /* defined _MSC_VER */
112 /* Return a dictionary corresponding to the POSIX environment table */
113 #if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
114 /* On Darwin/MacOSX a shared library or framework has no access to
115 @@ -1260,14 +1254,10 @@ win32_fstat(int file_number, struct win32_stat *result)
117 h = (HANDLE)_get_osfhandle(file_number);
119 - /* Protocol violation: we explicitly clear errno, instead of
120 - setting it to a POSIX error. Callers should use GetLastError. */
123 if (h == INVALID_HANDLE_VALUE) {
124 - /* This is really a C library error (invalid file handle).
125 - We set the Win32 error to the closes one matching. */
126 - SetLastError(ERROR_INVALID_HANDLE);
130 memset(result, 0, sizeof(*result));
131 @@ -1268,6 +1266,7 @@ win32_fstat(int file_number, struct win32_stat *result)
132 if (type == FILE_TYPE_UNKNOWN) {
133 DWORD error = GetLastError();
138 /* else: valid but unknown file */
139 @@ -1284,6 +1281,7 @@ win32_fstat(int file_number, struct win32_stat *result)
142 if (!GetFileInformationByHandle(h, &info)) {
147 diff --git a/PC/invalid_parameter_handler.c b/PC/invalid_parameter_handler.c
149 index 0000000..3bc0104
151 +++ b/PC/invalid_parameter_handler.c
157 +#if _MSC_VER >= 1900
158 +/* pyconfig.h uses this function in the _Py_BEGIN/END_SUPPRESS_IPH
159 + * macros. It does not need to be defined when building using MSVC
160 + * earlier than 14.0 (_MSC_VER == 1900).
163 +static void __cdecl _silent_invalid_parameter_handler(
164 + wchar_t const* expression,
165 + wchar_t const* function,
166 + wchar_t const* file,
168 + uintptr_t pReserved) { }
170 +void *_Py_silent_invalid_parameter_handler =
171 + (void*)_silent_invalid_parameter_handler;
175 diff --git a/Python/pystate.c b/Python/pystate.c
176 index eb992c1..1c0f970 100644
177 --- a/Python/pystate.c
178 +++ b/Python/pystate.c
179 @@ -22,6 +22,12 @@ the expense of doing their own locking).
183 +#if defined _MSC_VER && _MSC_VER >= 1900
184 +/* Issue #23524: Temporary fix to disable termination due to invalid parameters */
185 +PyAPI_DATA(void*) _Py_silent_invalid_parameter_handler;
192 @@ -202,6 +208,12 @@ new_threadstate(PyInterpreterState *interp, int init)
193 tstate->next = interp->tstate_head;
194 interp->tstate_head = tstate;
197 +#if defined _MSC_VER && _MSC_VER >= 1900
198 + /* Issue #23524: Temporary fix to disable termination due to invalid parameters */
199 + _set_thread_local_invalid_parameter_handler((_invalid_parameter_handler)_Py_silent_invalid_parameter_handler);
208 diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
209 index 99291ea..af17762 100644
210 --- a/PCbuild/pythoncore.vcxproj
211 +++ b/PCbuild/pythoncore.vcxproj
213 <ClCompile Include="..\Parser\parser.c" />
214 <ClCompile Include="..\Parser\parsetok.c" />
215 <ClCompile Include="..\Parser\tokenizer.c" />
216 + <ClCompile Include="..\PC\invalid_parameter_handler.c" />
217 <ClCompile Include="..\PC\_subprocess.c" />
218 <ClCompile Include="..\PC\_winreg.c" />
219 <ClCompile Include="..\PC\config.c" />
221 diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
222 index 99291ea..af17762 100644
223 --- a/PCbuild/pythoncore.vcxproj.filters
224 +++ b/PCbuild/pythoncore.vcxproj.filters
226 <ClCompile Include="..\Parser\tokenizer.c">
227 <Filter>Parser</Filter>
229 + <ClCompile Include="..\PC\invalid_parameter_handler.c">
230 + <Filter>PC</Filter>
232 <ClCompile Include="..\PC\_subprocess.c">