Commit 783c82c7 authored by Victor Stinner's avatar Victor Stinner

Close #11619: write_compiled_module() doesn't encode the filename

Reimplement open_exclusive() using _wopen() to avoid encoding the filename to
the filesystem encoding: use the Unicode version of the Windows API.
parent f48ac300
...@@ -1198,6 +1198,7 @@ parse_source_module(PyObject *pathname, FILE *fp) ...@@ -1198,6 +1198,7 @@ parse_source_module(PyObject *pathname, FILE *fp)
/* Helper to open a bytecode file for writing in exclusive mode */ /* Helper to open a bytecode file for writing in exclusive mode */
#ifndef MS_WINDOWS
static FILE * static FILE *
open_exclusive(char *filename, mode_t mode) open_exclusive(char *filename, mode_t mode)
{ {
...@@ -1228,6 +1229,7 @@ open_exclusive(char *filename, mode_t mode) ...@@ -1228,6 +1229,7 @@ open_exclusive(char *filename, mode_t mode)
return fopen(filename, "wb"); return fopen(filename, "wb");
#endif #endif
} }
#endif
/* Write a compiled module to a file, placing the time of last /* Write a compiled module to a file, placing the time of last
...@@ -1250,7 +1252,12 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname, ...@@ -1250,7 +1252,12 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname,
S_IWUSR | S_IWGRP | S_IWOTH); S_IWUSR | S_IWGRP | S_IWOTH);
PyObject *dirbytes; PyObject *dirbytes;
#endif #endif
PyObject *cpathbytes, *dirname; #ifdef MS_WINDOWS
int fd;
#else
PyObject *cpathbytes;
#endif
PyObject *dirname;
Py_UNICODE *dirsep; Py_UNICODE *dirsep;
int res, ok; int res, ok;
...@@ -1294,6 +1301,16 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname, ...@@ -1294,6 +1301,16 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname,
} }
Py_DECREF(dirname); Py_DECREF(dirname);
#ifdef MS_WINDOWS
(void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname));
fd = _wopen(PyUnicode_AS_UNICODE(cpathname),
O_EXCL | O_CREAT | O_WRONLY | O_TRUNC | O_BINARY,
mode);
if (0 <= fd)
fp = fdopen(fd, "wb");
else
fp = NULL;
#else
cpathbytes = PyUnicode_EncodeFSDefault(cpathname); cpathbytes = PyUnicode_EncodeFSDefault(cpathname);
if (cpathbytes == NULL) { if (cpathbytes == NULL) {
PyErr_Clear(); PyErr_Clear();
...@@ -1301,11 +1318,14 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname, ...@@ -1301,11 +1318,14 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname,
} }
fp = open_exclusive(PyBytes_AS_STRING(cpathbytes), mode); fp = open_exclusive(PyBytes_AS_STRING(cpathbytes), mode);
#endif
if (fp == NULL) { if (fp == NULL) {
if (Py_VerboseFlag) if (Py_VerboseFlag)
PySys_FormatStderr( PySys_FormatStderr(
"# can't create %R\n", cpathname); "# can't create %R\n", cpathname);
#ifndef MS_WINDOWS
Py_DECREF(cpathbytes); Py_DECREF(cpathbytes);
#endif
return; return;
} }
PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION); PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION);
...@@ -1321,11 +1341,13 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname, ...@@ -1321,11 +1341,13 @@ write_compiled_module(PyCodeObject *co, PyObject *cpathname,
(void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname)); (void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname));
#else #else
(void) unlink(PyBytes_AS_STRING(cpathbytes)); (void) unlink(PyBytes_AS_STRING(cpathbytes));
#endif
Py_DECREF(cpathbytes); Py_DECREF(cpathbytes);
#endif
return; return;
} }
#ifndef MS_WINDOWS
Py_DECREF(cpathbytes); Py_DECREF(cpathbytes);
#endif
/* Now write the true mtime */ /* Now write the true mtime */
fseek(fp, 4L, 0); fseek(fp, 4L, 0);
assert(mtime < LONG_MAX); assert(mtime < LONG_MAX);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment