Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 27f26ad

Browse files
committed
Issue #28161: Opening CON for write access fails
Issue #28162: WindowsConsoleIO readall() fails if first line starts with Ctrl+Z Issue #28163: WindowsConsoleIO fileno() passes wrong flags to _open_osfhandle Issue #28164: _PyIO_get_console_type fails for various paths
1 parent 5d625cf commit 27f26ad

2 files changed

Lines changed: 41 additions & 14 deletions

File tree

Misc/NEWS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ Library
7171
Windows
7272
-------
7373

74+
- Issue #28161: Opening CON for write access fails
75+
76+
- Issue #28162: WindowsConsoleIO readall() fails if first line starts with
77+
Ctrl+Z
78+
79+
- Issue #28163: WindowsConsoleIO fileno() passes wrong flags to
80+
_open_osfhandle
81+
82+
- Issue #28164: _PyIO_get_console_type fails for various paths
83+
7484
- Issue #28137: Renames Windows path file to ._pth
7585

7686
- Issue #28138: Windows ._pth file should allow import site

Modules/_io/winconsoleio.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#define WIN32_LEAN_AND_MEAN
2424
#include <windows.h>
25+
#include <fcntl.h>
2526

2627
#include "_iomodule.h"
2728

@@ -68,27 +69,34 @@ char _PyIO_get_console_type(PyObject *path_or_fd) {
6869
return _get_console_type(handle);
6970
}
7071

71-
PyObject *decoded = Py_None;
72-
Py_INCREF(decoded);
72+
PyObject *decoded, *decoded_upper;
7373

7474
int d = PyUnicode_FSDecoder(path_or_fd, &decoded);
7575
if (!d) {
7676
PyErr_Clear();
77+
return '\0';
78+
}
79+
if (!PyUnicode_Check(decoded)) {
7780
Py_CLEAR(decoded);
7881
return '\0';
7982
}
83+
decoded_upper = PyObject_CallMethod(decoded, "upper", "");
84+
Py_CLEAR(decoded);
85+
if (!decoded_upper) {
86+
PyErr_Clear();
87+
return '\0';
88+
}
8089

8190
char m = '\0';
82-
if (!PyUnicode_Check(decoded)) {
83-
return '\0';
84-
} else if (PyUnicode_CompareWithASCIIString(decoded, "CONIN$") == 0) {
91+
if (PyUnicode_CompareWithASCIIString(decoded_upper, "CONIN$") == 0) {
8592
m = 'r';
86-
} else if (PyUnicode_CompareWithASCIIString(decoded, "CONOUT$") == 0 ||
87-
PyUnicode_CompareWithASCIIString(decoded, "CON") == 0) {
93+
} else if (PyUnicode_CompareWithASCIIString(decoded_upper, "CONOUT$") == 0) {
8894
m = 'w';
95+
} else if (PyUnicode_CompareWithASCIIString(decoded_upper, "CON") == 0) {
96+
m = 'x';
8997
}
9098

91-
Py_CLEAR(decoded);
99+
Py_CLEAR(decoded_upper);
92100
return m;
93101
}
94102

@@ -227,6 +235,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
227235
{
228236
const char *s;
229237
wchar_t *name = NULL;
238+
char console_type = '\0';
230239
int ret = 0;
231240
int rwa = 0;
232241
int fd = -1;
@@ -270,6 +279,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
270279

271280
Py_ssize_t length;
272281
name = PyUnicode_AsWideCharString(decodedname, &length);
282+
console_type = _PyIO_get_console_type(decodedname);
273283
Py_CLEAR(decodedname);
274284
if (name == NULL)
275285
return -1;
@@ -294,12 +304,16 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
294304
goto bad_mode;
295305
rwa = 1;
296306
self->readable = 1;
307+
if (console_type == 'x')
308+
console_type = 'r';
297309
break;
298310
case 'w':
299311
if (rwa)
300312
goto bad_mode;
301313
rwa = 1;
302314
self->writable = 1;
315+
if (console_type == 'x')
316+
console_type = 'w';
303317
break;
304318
default:
305319
PyErr_Format(PyExc_ValueError,
@@ -327,7 +341,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
327341
}
328342

329343
if (self->writable)
330-
access |= GENERIC_WRITE;
344+
access = GENERIC_WRITE;
331345

332346
Py_BEGIN_ALLOW_THREADS
333347
/* Attempt to open for read/write initially, then fall back
@@ -347,12 +361,15 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
347361
}
348362
}
349363

350-
if (self->writable && _get_console_type(self->handle) != 'w') {
364+
if (console_type == '\0')
365+
console_type = _get_console_type(self->handle);
366+
367+
if (self->writable && console_type != 'w') {
351368
PyErr_SetString(PyExc_ValueError,
352369
"Cannot open console input buffer for writing");
353370
goto error;
354371
}
355-
if (self->readable && _get_console_type(self->handle) != 'r') {
372+
if (self->readable && console_type != 'r') {
356373
PyErr_SetString(PyExc_ValueError,
357374
"Cannot open console output buffer for reading");
358375
goto error;
@@ -440,9 +457,9 @@ _io__WindowsConsoleIO_fileno_impl(winconsoleio *self)
440457
if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) {
441458
_Py_BEGIN_SUPPRESS_IPH
442459
if (self->writable)
443-
self->fd = _open_osfhandle((intptr_t)self->handle, 'wb');
460+
self->fd = _open_osfhandle((intptr_t)self->handle, _O_WRONLY | _O_BINARY);
444461
else
445-
self->fd = _open_osfhandle((intptr_t)self->handle, 'rb');
462+
self->fd = _open_osfhandle((intptr_t)self->handle, _O_RDONLY | _O_BINARY);
446463
_Py_END_SUPPRESS_IPH
447464
}
448465
if (self->fd < 0)
@@ -776,7 +793,7 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self)
776793
len += n;
777794
}
778795

779-
if (len > 0 && buf[0] == '\x1a' && _buflen(self) == 0) {
796+
if (len == 0 || buf[0] == '\x1a' && _buflen(self) == 0) {
780797
/* when the result starts with ^Z we return an empty buffer */
781798
PyMem_Free(buf);
782799
return PyBytes_FromStringAndSize(NULL, 0);

0 commit comments

Comments
 (0)