Skip to content

Commit 34de314

Browse files
committed
Modules/_io/bufferedio.c: protect macros expansion via do { ... } while (0) constructions
1 parent 330d797 commit 34de314

File tree

1 file changed

+66
-58
lines changed

1 file changed

+66
-58
lines changed

Modules/_io/bufferedio.c

+66-58
Original file line numberDiff line numberDiff line change
@@ -332,41 +332,49 @@ _enter_buffered_busy(buffered *self)
332332
PyThread_release_lock(self->lock); \
333333
} while(0);
334334

335-
#define CHECK_INITIALIZED(self) \
336-
if (self->ok <= 0) { \
337-
if (self->detached) { \
338-
PyErr_SetString(PyExc_ValueError, \
339-
"raw stream has been detached"); \
340-
} else { \
341-
PyErr_SetString(PyExc_ValueError, \
342-
"I/O operation on uninitialized object"); \
343-
} \
344-
return NULL; \
345-
}
346-
347-
#define CHECK_INITIALIZED_INT(self) \
348-
if (self->ok <= 0) { \
349-
if (self->detached) { \
350-
PyErr_SetString(PyExc_ValueError, \
351-
"raw stream has been detached"); \
352-
} else { \
353-
PyErr_SetString(PyExc_ValueError, \
354-
"I/O operation on uninitialized object"); \
355-
} \
356-
return -1; \
357-
}
335+
#define CHECK_INITIALIZED(self) \
336+
do { \
337+
if (self->ok <= 0) { \
338+
if (self->detached) { \
339+
PyErr_SetString(PyExc_ValueError, \
340+
"raw stream has been detached"); \
341+
} else { \
342+
PyErr_SetString(PyExc_ValueError, \
343+
"I/O operation on uninitialized object"); \
344+
} \
345+
return NULL; \
346+
} \
347+
} while (0)
348+
349+
#define CHECK_INITIALIZED_INT(self) \
350+
do { \
351+
if (self->ok <= 0) { \
352+
if (self->detached) { \
353+
PyErr_SetString(PyExc_ValueError, \
354+
"raw stream has been detached"); \
355+
} else { \
356+
PyErr_SetString(PyExc_ValueError, \
357+
"I/O operation on uninitialized object"); \
358+
} \
359+
return -1; \
360+
} \
361+
} while (0)
358362

359363
#define IS_CLOSED(self) \
360364
(!self->buffer || \
361365
(self->fast_closed_checks \
362366
? _PyFileIO_closed(self->raw) \
363367
: buffered_closed(self)))
364368

365-
#define CHECK_CLOSED(self, error_msg) \
366-
if (IS_CLOSED(self) && (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) { \
367-
PyErr_SetString(PyExc_ValueError, error_msg); \
368-
return NULL; \
369-
} \
369+
#define CHECK_CLOSED(self, error_msg) \
370+
do { \
371+
if (IS_CLOSED(self) \
372+
&& (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) \
373+
{ \
374+
PyErr_SetString(PyExc_ValueError, error_msg); \
375+
return NULL; \
376+
} \
377+
} while (0)
370378

371379
#define VALID_READ_BUFFER(self) \
372380
(self->readable && self->read_end != -1)
@@ -498,7 +506,7 @@ static PyObject *
498506
_io__Buffered_simple_flush_impl(buffered *self)
499507
/*[clinic end generated code: output=29ebb3820db1bdfd input=5248cb84a65f80bd]*/
500508
{
501-
CHECK_INITIALIZED(self)
509+
CHECK_INITIALIZED(self);
502510
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(flush));
503511
}
504512

@@ -507,7 +515,7 @@ buffered_closed(buffered *self)
507515
{
508516
int closed;
509517
PyObject *res;
510-
CHECK_INITIALIZED_INT(self)
518+
CHECK_INITIALIZED_INT(self);
511519
res = PyObject_GetAttr(self->raw, &_Py_ID(closed));
512520
if (res == NULL)
513521
return -1;
@@ -526,7 +534,7 @@ static PyObject *
526534
_io__Buffered_closed_get_impl(buffered *self)
527535
/*[clinic end generated code: output=f08ce57290703a1a input=18eddefdfe4a3d2f]*/
528536
{
529-
CHECK_INITIALIZED(self)
537+
CHECK_INITIALIZED(self);
530538
return PyObject_GetAttr(self->raw, &_Py_ID(closed));
531539
}
532540

@@ -542,7 +550,7 @@ _io__Buffered_close_impl(buffered *self)
542550
PyObject *res = NULL;
543551
int r;
544552

545-
CHECK_INITIALIZED(self)
553+
CHECK_INITIALIZED(self);
546554
if (!ENTER_BUFFERED(self)) {
547555
return NULL;
548556
}
@@ -603,7 +611,7 @@ _io__Buffered_detach_impl(buffered *self)
603611
/*[clinic end generated code: output=dd0fc057b8b779f7 input=d4ef1828a678be37]*/
604612
{
605613
PyObject *raw;
606-
CHECK_INITIALIZED(self)
614+
CHECK_INITIALIZED(self);
607615
if (_PyFile_Flush((PyObject *)self) < 0) {
608616
return NULL;
609617
}
@@ -625,7 +633,7 @@ static PyObject *
625633
_io__Buffered_seekable_impl(buffered *self)
626634
/*[clinic end generated code: output=90172abb5ceb6e8f input=e3a4fc1d297b2fd3]*/
627635
{
628-
CHECK_INITIALIZED(self)
636+
CHECK_INITIALIZED(self);
629637
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(seekable));
630638
}
631639

@@ -638,7 +646,7 @@ static PyObject *
638646
_io__Buffered_readable_impl(buffered *self)
639647
/*[clinic end generated code: output=92afa07661ecb698 input=abe54107d59bca9a]*/
640648
{
641-
CHECK_INITIALIZED(self)
649+
CHECK_INITIALIZED(self);
642650
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(readable));
643651
}
644652

@@ -651,7 +659,7 @@ static PyObject *
651659
_io__Buffered_writable_impl(buffered *self)
652660
/*[clinic end generated code: output=4e3eee8d6f9d8552 input=45eb76bf6a10e6f7]*/
653661
{
654-
CHECK_INITIALIZED(self)
662+
CHECK_INITIALIZED(self);
655663
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable));
656664
}
657665

@@ -666,7 +674,7 @@ static PyObject *
666674
_io__Buffered_name_get_impl(buffered *self)
667675
/*[clinic end generated code: output=d2adf384051d3d10 input=6b84a0e6126f545e]*/
668676
{
669-
CHECK_INITIALIZED(self)
677+
CHECK_INITIALIZED(self);
670678
return PyObject_GetAttr(self->raw, &_Py_ID(name));
671679
}
672680

@@ -680,7 +688,7 @@ static PyObject *
680688
_io__Buffered_mode_get_impl(buffered *self)
681689
/*[clinic end generated code: output=0feb205748892fa4 input=0762d5e28542fd8c]*/
682690
{
683-
CHECK_INITIALIZED(self)
691+
CHECK_INITIALIZED(self);
684692
return PyObject_GetAttr(self->raw, &_Py_ID(mode));
685693
}
686694

@@ -695,7 +703,7 @@ static PyObject *
695703
_io__Buffered_fileno_impl(buffered *self)
696704
/*[clinic end generated code: output=b717648d58a95ee3 input=1c4fead777bae20a]*/
697705
{
698-
CHECK_INITIALIZED(self)
706+
CHECK_INITIALIZED(self);
699707
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(fileno));
700708
}
701709

@@ -708,7 +716,7 @@ static PyObject *
708716
_io__Buffered_isatty_impl(buffered *self)
709717
/*[clinic end generated code: output=c20e55caae67baea input=e53d182d7e490e3a]*/
710718
{
711-
CHECK_INITIALIZED(self)
719+
CHECK_INITIALIZED(self);
712720
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(isatty));
713721
}
714722

@@ -922,8 +930,8 @@ _io__Buffered_flush_impl(buffered *self)
922930
{
923931
PyObject *res;
924932

925-
CHECK_INITIALIZED(self)
926-
CHECK_CLOSED(self, "flush of closed file")
933+
CHECK_INITIALIZED(self);
934+
CHECK_CLOSED(self, "flush of closed file");
927935

928936
if (!ENTER_BUFFERED(self))
929937
return NULL;
@@ -947,8 +955,8 @@ _io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
947955
{
948956
PyObject *res = NULL;
949957

950-
CHECK_INITIALIZED(self)
951-
CHECK_CLOSED(self, "peek of closed file")
958+
CHECK_INITIALIZED(self);
959+
CHECK_CLOSED(self, "peek of closed file");
952960

953961
if (!ENTER_BUFFERED(self))
954962
return NULL;
@@ -979,14 +987,14 @@ _io__Buffered_read_impl(buffered *self, Py_ssize_t n)
979987
{
980988
PyObject *res;
981989

982-
CHECK_INITIALIZED(self)
990+
CHECK_INITIALIZED(self);
983991
if (n < -1) {
984992
PyErr_SetString(PyExc_ValueError,
985993
"read length must be non-negative or -1");
986994
return NULL;
987995
}
988996

989-
CHECK_CLOSED(self, "read of closed file")
997+
CHECK_CLOSED(self, "read of closed file");
990998

991999
if (n == -1) {
9921000
/* The number of bytes is unspecified, read until the end of stream */
@@ -1022,12 +1030,12 @@ _io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
10221030
Py_ssize_t have, r;
10231031
PyObject *res = NULL;
10241032

1025-
CHECK_INITIALIZED(self)
1033+
CHECK_INITIALIZED(self);
10261034
if (n < 0) {
10271035
n = self->buffer_size;
10281036
}
10291037

1030-
CHECK_CLOSED(self, "read of closed file")
1038+
CHECK_CLOSED(self, "read of closed file");
10311039

10321040
if (n == 0)
10331041
return PyBytes_FromStringAndSize(NULL, 0);
@@ -1079,8 +1087,8 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
10791087
Py_ssize_t n, written = 0, remaining;
10801088
PyObject *res = NULL;
10811089

1082-
CHECK_INITIALIZED(self)
1083-
CHECK_CLOSED(self, "readinto of closed file")
1090+
CHECK_INITIALIZED(self);
1091+
CHECK_CLOSED(self, "readinto of closed file");
10841092

10851093
n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
10861094
if (n > 0) {
@@ -1192,7 +1200,7 @@ _buffered_readline(buffered *self, Py_ssize_t limit)
11921200
Py_ssize_t n;
11931201
const char *start, *s, *end;
11941202

1195-
CHECK_CLOSED(self, "readline of closed file")
1203+
CHECK_CLOSED(self, "readline of closed file");
11961204

11971205
/* First, try to find a line in the buffer. This can run unlocked because
11981206
the calls to the C API are simple enough that they can't trigger
@@ -1303,7 +1311,7 @@ static PyObject *
13031311
_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
13041312
/*[clinic end generated code: output=24dd2aa6e33be83c input=e81ca5abd4280776]*/
13051313
{
1306-
CHECK_INITIALIZED(self)
1314+
CHECK_INITIALIZED(self);
13071315
return _buffered_readline(self, size);
13081316
}
13091317

@@ -1319,7 +1327,7 @@ _io__Buffered_tell_impl(buffered *self)
13191327
{
13201328
Py_off_t pos;
13211329

1322-
CHECK_INITIALIZED(self)
1330+
CHECK_INITIALIZED(self);
13231331
pos = _buffered_raw_tell(self);
13241332
if (pos == -1)
13251333
return NULL;
@@ -1347,7 +1355,7 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
13471355
Py_off_t target, n;
13481356
PyObject *res = NULL;
13491357

1350-
CHECK_INITIALIZED(self)
1358+
CHECK_INITIALIZED(self);
13511359

13521360
/* Do some error checking instead of trusting OS 'seek()'
13531361
** error detection, just in case.
@@ -1365,7 +1373,7 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
13651373
return NULL;
13661374
}
13671375

1368-
CHECK_CLOSED(self, "seek of closed file")
1376+
CHECK_CLOSED(self, "seek of closed file");
13691377

13701378
_PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
13711379
if (_PyIOBase_check_seekable(state, self->raw, Py_True) == NULL) {
@@ -1449,8 +1457,8 @@ _io__Buffered_truncate_impl(buffered *self, PyTypeObject *cls, PyObject *pos)
14491457
{
14501458
PyObject *res = NULL;
14511459

1452-
CHECK_INITIALIZED(self)
1453-
CHECK_CLOSED(self, "truncate of closed file")
1460+
CHECK_INITIALIZED(self);
1461+
CHECK_CLOSED(self, "truncate of closed file");
14541462
if (!self->writable) {
14551463
_PyIO_State *state = get_io_state_by_cls(cls);
14561464
return bufferediobase_unsupported(state, "truncate");
@@ -2073,7 +2081,7 @@ _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
20732081
Py_ssize_t written, avail, remaining;
20742082
Py_off_t offset;
20752083

2076-
CHECK_INITIALIZED(self)
2084+
CHECK_INITIALIZED(self);
20772085

20782086
if (!ENTER_BUFFERED(self))
20792087
return NULL;

0 commit comments

Comments
 (0)