Skip to content

Commit 7f9fb0f

Browse files
authored
bpo-33954: Rewrite FILL() macro of unicodeobject.c (GH-10738)
Copy code from master: add assertions on start and value, replace 'i' iterator with 'end' pointer for the loop stop condition. _PyUnicode_FastFill(): fix type of 'data', it must not be constant, since data is modified by FILL().
1 parent 716a808 commit 7f9fb0f

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

Objects/unicodeobject.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,22 +220,30 @@ static PyObject *unicode_empty = NULL;
220220

221221
#define FILL(kind, data, value, start, length) \
222222
do { \
223-
Py_ssize_t i_ = 0; \
223+
assert(0 <= start); \
224224
assert(kind != PyUnicode_WCHAR_KIND); \
225-
switch ((kind)) { \
225+
switch (kind) { \
226226
case PyUnicode_1BYTE_KIND: { \
227-
unsigned char * to_ = (unsigned char *)((data)) + (start); \
228-
memset(to_, (unsigned char)value, (length)); \
227+
assert(value <= 0xff); \
228+
Py_UCS1 ch = (unsigned char)value; \
229+
Py_UCS1 *to = (Py_UCS1 *)data + start; \
230+
memset(to, ch, length); \
229231
break; \
230232
} \
231233
case PyUnicode_2BYTE_KIND: { \
232-
Py_UCS2 * to_ = (Py_UCS2 *)((data)) + (start); \
233-
for (; i_ < (length); ++i_, ++to_) *to_ = (value); \
234+
assert(value <= 0xffff); \
235+
Py_UCS2 ch = (Py_UCS2)value; \
236+
Py_UCS2 *to = (Py_UCS2 *)data + start; \
237+
const Py_UCS2 *end = to + length; \
238+
for (; to < end; ++to) *to = ch; \
234239
break; \
235240
} \
236241
case PyUnicode_4BYTE_KIND: { \
237-
Py_UCS4 * to_ = (Py_UCS4 *)((data)) + (start); \
238-
for (; i_ < (length); ++i_, ++to_) *to_ = (value); \
242+
assert(value <= MAX_UNICODE); \
243+
Py_UCS4 ch = value; \
244+
Py_UCS4 * to = (Py_UCS4 *)data + start; \
245+
const Py_UCS4 *end = to + length; \
246+
for (; to < end; ++to) *to = ch; \
239247
break; \
240248
} \
241249
default: Py_UNREACHABLE(); \
@@ -10079,7 +10087,7 @@ _PyUnicode_FastFill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length,
1007910087
Py_UCS4 fill_char)
1008010088
{
1008110089
const enum PyUnicode_Kind kind = PyUnicode_KIND(unicode);
10082-
const void *data = PyUnicode_DATA(unicode);
10090+
void *data = PyUnicode_DATA(unicode);
1008310091
assert(PyUnicode_IS_READY(unicode));
1008410092
assert(unicode_modifiable(unicode));
1008510093
assert(fill_char <= PyUnicode_MAX_CHAR_VALUE(unicode));

0 commit comments

Comments
 (0)