Skip to content

bpo-32381: .pyc files with non-ASCII paths cannot be reopened on Windows#14699

Closed
ZackerySpytz wants to merge 1 commit into
python:masterfrom
ZackerySpytz:bpo-32381-pyc-non-ASCII-win
Closed

bpo-32381: .pyc files with non-ASCII paths cannot be reopened on Windows#14699
ZackerySpytz wants to merge 1 commit into
python:masterfrom
ZackerySpytz:bpo-32381-pyc-non-ASCII-win

Conversation

@ZackerySpytz

@ZackerySpytz ZackerySpytz commented Jul 11, 2019

Copy link
Copy Markdown
Contributor

Comment thread Python/fileutils.c
return NULL;
if (make_non_inheritable(fileno(f)) < 0) {
fclose(f);
PyObject *path = PyUnicode_DecodeFSDefault(pathname);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change should be conditionally defined just for Windows. In the Unix world a path is just a sequence of bytes, with only ASCII slash and null reserved.

@aeros aeros Jul 11, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed with @eryksun. Performing the change across all OS's wouldn't be necessary, since this is a windows specific issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @eryksun, for the comment. One issue is the fact that _Py_fopen_obj() calls set_inheritable() with raise == 1, but _Py_fopen() currently uses make_non_inheritable(), which calls set_inheritable() with raise == 0. I think, for non-Windows, the make_non_inheritable() call in _Py_fopen() should be replaced with set_inheritable(fileno(f), 0, 1, NULL).

@eryksun eryksun Jul 11, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a problem that _Py_fopen doesn't require the GIL to be held, but _Py_fopen_obj requires it. It may be better to modify PyRun_SimpleFileExFlags instead of tinkering with _Py_fopen.

(Another issue is with pymain_run_startup, which gets the ANSI encoded PYTHONSTARTUP filename via _Py_GetEnv and passes it to _Py_fopen. This is a problem for users with arbitrary Unicode usernames if the startup file is in their profile directory. In Windows we need to pass the filename from the native wide-character environment to _Py_wfopen.)

self.assertEqual(b"", out)
self.assertEqual(b"", err)

def test_issue32381(self):

@aeros aeros Jul 11, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of test_issue32381, I would recommend renaming the method to something more descriptive of the issue itself, such as test_windows_non_ascii_path.

Suggested change
def test_issue32381(self):
# tests bpo-32381
def test_windows_non_ascii_path(self):

Comment thread Python/fileutils.c
return NULL;
if (make_non_inheritable(fileno(f)) < 0) {
fclose(f);
PyObject *path = PyUnicode_DecodeFSDefault(pathname);

@aeros aeros Jul 11, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed with @eryksun. Performing the change across all OS's wouldn't be necessary, since this is a windows specific issue.

@brettcannon brettcannon added the type-bug An unexpected behavior, bug, or error label Jul 11, 2019
@vstinner

vstinner commented Dec 4, 2020

Copy link
Copy Markdown
Member

I'm not comfortable with changing _Py_fopen(), so I wrote PR #23642 to use _Py_fopen_obj() in pythonrun.c. Would you mind to review it?

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike the idea of calling PyUnicode_DecodeFSDefault() on any platform. On Unix, fopen() is the native API. It should only be done on Windows.

I fixed https://bugs.python.org/issue32381 differently. In general, I would suggest avoiding _Py_fopen() and prefer the variant accept a wide string (wchar_t*) or a Python object (PyObject*).

Should we close this PR?

pymain_run_startup() calls _Py_fopen() on Unix and _Py_wfopen() on Windows.

PyErr_ProgramText() calls _Py_fopen(), but Python no longer calls PyErr_ProgramText() anymore.

@vstinner

vstinner commented Dec 9, 2020

Copy link
Copy Markdown
Member

I removed _Py_fopen() in PR #23711, so this fix is not longer needed.

Moreover, I fixed https://bugs.python.org/issue32381 encoding issue differently: commit b6d98c1.

@vstinner vstinner closed this Dec 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting core review type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants