]> granicus.if.org Git - python/commitdiff
Fix the CRT argument error handling for VisualStudio .NET 2005. Install a CRT error...
authorKristján Valur Jónsson <kristjan@ccpgames.com>
Mon, 12 Jun 2006 15:45:12 +0000 (15:45 +0000)
committerKristján Valur Jónsson <kristjan@ccpgames.com>
Mon, 12 Jun 2006 15:45:12 +0000 (15:45 +0000)
This update fixes crash cases in the test suite where the default CRT error handler would cause process exit.

Modules/timemodule.c
Objects/exceptions.c
Objects/fileobject.c

index 23de1739629c295909ec09efeceb8212c93be935..2133273872544dad48c59188f80d9ddc0aed6c13 100644 (file)
@@ -467,6 +467,14 @@ time_strftime(PyObject *self, PyObject *args)
                        return ret;
                }
                free(outbuf);
+#if defined _MSC_VER && _MSC_VER >= 1400
+               /* VisualStudio .NET 2005 does this properly */
+               if (buflen == 0 && errno == EINVAL) {
+                       PyErr_SetString(PyExc_ValueError, "Invalid format string");
+                       return 0;
+               }
+#endif
+               
        }
 }
 
index 369365bf99da6502b478351c9c28e031df5bb619..38d7350cfe3e8da12b61020aed0bab77658a30a5 100644 (file)
@@ -1967,6 +1967,29 @@ static PyMethodDef functions[] = {
     if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \
         Py_FatalError("Module dictionary insertion problem.");
 
+#if defined _MSC_VER && _MSC_VER >= 1400
+/* crt variable checking in VisualStudio .NET 2005 */
+#include <crtdbg.h>
+
+static int     prevCrtReportMode;
+static _invalid_parameter_handler      prevCrtHandler;
+
+/* Invalid parameter handler.  Sets a ValueError exception */
+static void
+InvalidParameterHandler(
+    const wchar_t * expression,
+    const wchar_t * function,
+    const wchar_t * file,
+    unsigned int line,
+    uintptr_t pReserved)
+{
+    /* Do nothing, allow execution to continue.  Usually this
+     * means that the CRT will set errno to EINVAL
+     */
+}
+#endif
+
+
 PyMODINIT_FUNC
 _PyExc_Init(void)
 {
@@ -2096,6 +2119,13 @@ _PyExc_Init(void)
         Py_FatalError("Cannot pre-allocate MemoryError instance\n");
 
     Py_DECREF(bltinmod);
+
+#if defined _MSC_VER && _MSC_VER >= 1400
+    /* Set CRT argument error handler */
+    prevCrtHandler = _set_invalid_parameter_handler(InvalidParameterHandler);
+    /* turn off assertions in debug mode */
+    prevCrtReportMode = _CrtSetReportMode(_CRT_ASSERT, 0);
+#endif
 }
 
 void
@@ -2103,4 +2133,9 @@ _PyExc_Fini(void)
 {
     Py_XDECREF(PyExc_MemoryErrorInst);
     PyExc_MemoryErrorInst = NULL;
+#if defined _MSC_VER && _MSC_VER >= 1400
+    /* reset CRT error handling */
+    _set_invalid_parameter_handler(prevCrtHandler);
+    _CrtSetReportMode(_CRT_ASSERT, prevCrtReportMode);
+#endif
 }
index 2b37e7442f1c8b1bf48134e01feed4c5757bb457..050146ae7773ce68916acd5dd181f7dd4300f125 100644 (file)
@@ -241,13 +241,15 @@ open_the_file(PyFileObject *f, char *name, char *mode)
        }
 
        if (f->f_fp == NULL) {
-#ifdef _MSC_VER
+#if defined  _MSC_VER && _MSC_VER < 1400
                /* MSVC 6 (Microsoft) leaves errno at 0 for bad mode strings,
                 * across all Windows flavors.  When it sets EINVAL varies
                 * across Windows flavors, the exact conditions aren't
                 * documented, and the answer lies in the OS's implementation
                 * of Win32's CreateFile function (whose source is secret).
                 * Seems the best we can do is map EINVAL to ENOENT.
+                * Starting with Visual Studio .NET 2005, EINVAL is correctly
+                * set by our CRT error handler (set in exceptions.c.)
                 */
                if (errno == 0) /* bad mode string */
                        errno = EINVAL;