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

Skip to content

Commit 33d21a2

Browse files
committed
merge 3.2 (#14212)
2 parents 2fa0cbc + 1ae230a commit 33d21a2

4 files changed

Lines changed: 61 additions & 26 deletions

File tree

Lib/test/test_re.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from test.support import verbose, run_unittest
1+
from test.support import verbose, run_unittest, gc_collect
2+
import io
23
import re
34
from re import Scanner
45
import sys
@@ -16,6 +17,17 @@
1617

1718
class ReTests(unittest.TestCase):
1819

20+
def test_keep_buffer(self):
21+
# See bug 14212
22+
b = bytearray(b'x')
23+
it = re.finditer(b'a', b)
24+
with self.assertRaises(BufferError):
25+
b.extend(b'x'*400)
26+
list(it)
27+
del it
28+
gc_collect()
29+
b.extend(b'x'*400)
30+
1931
def test_weakref(self):
2032
s = 'QabbbcR'
2133
x = re.compile('ab+c')

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ Library
2727
data or close method) for the Python implementation as well.
2828
Drop the no-op TreeBuilder().xml() method from the C implementation.
2929

30+
Extension Modules
31+
-----------------
32+
33+
- Issue #14212: The re module didn't retain a reference to buffers it was
34+
scanning, resulting in segfaults.
35+
3036

3137
What's New in Python 3.3.0 Alpha 1?
3238
===================================

Modules/_sre.c

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,8 @@ state_reset(SRE_STATE* state)
16501650

16511651
static void*
16521652
getstring(PyObject* string, Py_ssize_t* p_length,
1653-
int* p_logical_charsize, int* p_charsize)
1653+
int* p_logical_charsize, int* p_charsize,
1654+
Py_buffer *view)
16541655
{
16551656
/* given a python object, return a data pointer, a length (in
16561657
characters), and a character size. return NULL if the object
@@ -1660,7 +1661,6 @@ getstring(PyObject* string, Py_ssize_t* p_length,
16601661
Py_ssize_t size, bytes;
16611662
int charsize;
16621663
void* ptr;
1663-
Py_buffer view;
16641664

16651665
/* Unicode objects do not support the buffer API. So, get the data
16661666
directly instead. */
@@ -1675,26 +1675,21 @@ getstring(PyObject* string, Py_ssize_t* p_length,
16751675
}
16761676

16771677
/* get pointer to byte string buffer */
1678-
view.len = -1;
1678+
view->len = -1;
16791679
buffer = Py_TYPE(string)->tp_as_buffer;
16801680
if (!buffer || !buffer->bf_getbuffer ||
1681-
(*buffer->bf_getbuffer)(string, &view, PyBUF_SIMPLE) < 0) {
1681+
(*buffer->bf_getbuffer)(string, view, PyBUF_SIMPLE) < 0) {
16821682
PyErr_SetString(PyExc_TypeError, "expected string or buffer");
16831683
return NULL;
16841684
}
16851685

16861686
/* determine buffer size */
1687-
bytes = view.len;
1688-
ptr = view.buf;
1689-
1690-
/* Release the buffer immediately --- possibly dangerous
1691-
but doing something else would require some re-factoring
1692-
*/
1693-
PyBuffer_Release(&view);
1687+
bytes = view->len;
1688+
ptr = view->buf;
16941689

16951690
if (bytes < 0) {
16961691
PyErr_SetString(PyExc_TypeError, "buffer has negative size");
1697-
return NULL;
1692+
goto err;
16981693
}
16991694

17001695
/* determine character size */
@@ -1704,7 +1699,7 @@ getstring(PyObject* string, Py_ssize_t* p_length,
17041699
charsize = 1;
17051700
else {
17061701
PyErr_SetString(PyExc_TypeError, "buffer size mismatch");
1707-
return NULL;
1702+
goto err;
17081703
}
17091704

17101705
*p_length = size;
@@ -1714,8 +1709,13 @@ getstring(PyObject* string, Py_ssize_t* p_length,
17141709
if (ptr == NULL) {
17151710
PyErr_SetString(PyExc_ValueError,
17161711
"Buffer is NULL");
1712+
goto err;
17171713
}
17181714
return ptr;
1715+
err:
1716+
PyBuffer_Release(view);
1717+
view->buf = NULL;
1718+
return NULL;
17191719
}
17201720

17211721
LOCAL(PyObject*)
@@ -1733,20 +1733,21 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
17331733
state->lastmark = -1;
17341734
state->lastindex = -1;
17351735

1736-
ptr = getstring(string, &length, &logical_charsize, &charsize);
1736+
state->buffer.buf = NULL;
1737+
ptr = getstring(string, &length, &logical_charsize, &charsize, &state->buffer);
17371738
if (!ptr)
1738-
return NULL;
1739+
goto err;
17391740

1740-
if (logical_charsize == 1 && pattern->logical_charsize > 1) {
1741-
PyErr_SetString(PyExc_TypeError,
1741+
if (logical_charsize == 1 && pattern->logical_charsize > 1) {
1742+
PyErr_SetString(PyExc_TypeError,
17421743
"can't use a string pattern on a bytes-like object");
1743-
return NULL;
1744-
}
1745-
if (logical_charsize > 1 && pattern->logical_charsize == 1) {
1746-
PyErr_SetString(PyExc_TypeError,
1744+
goto err;
1745+
}
1746+
if (logical_charsize > 1 && pattern->logical_charsize == 1) {
1747+
PyErr_SetString(PyExc_TypeError,
17471748
"can't use a bytes pattern on a string-like object");
1748-
return NULL;
1749-
}
1749+
goto err;
1750+
}
17501751

17511752
/* adjust boundaries */
17521753
if (start < 0)
@@ -1780,11 +1781,17 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
17801781
state->lower = sre_lower;
17811782

17821783
return string;
1784+
err:
1785+
if (state->buffer.buf)
1786+
PyBuffer_Release(&state->buffer);
1787+
return NULL;
17831788
}
17841789

17851790
LOCAL(void)
17861791
state_fini(SRE_STATE* state)
17871792
{
1793+
if (state->buffer.buf)
1794+
PyBuffer_Release(&state->buffer);
17881795
Py_XDECREF(state->string);
17891796
data_stack_dealloc(state);
17901797
}
@@ -1846,6 +1853,8 @@ pattern_dealloc(PatternObject* self)
18461853
{
18471854
if (self->weakreflist != NULL)
18481855
PyObject_ClearWeakRefs((PyObject *) self);
1856+
if (self->view.buf)
1857+
PyBuffer_Release(&self->view);
18491858
Py_XDECREF(self->pattern);
18501859
Py_XDECREF(self->groupindex);
18511860
Py_XDECREF(self->indexgroup);
@@ -2272,6 +2281,7 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
22722281
Py_ssize_t i, b, e;
22732282
int logical_charsize, charsize;
22742283
int filter_is_callable;
2284+
Py_buffer view;
22752285

22762286
if (PyCallable_Check(ptemplate)) {
22772287
/* sub/subn takes either a function or a template */
@@ -2281,14 +2291,17 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
22812291
} else {
22822292
/* if not callable, check if it's a literal string */
22832293
int literal;
2284-
ptr = getstring(ptemplate, &n, &logical_charsize, &charsize);
2294+
view.buf = NULL;
2295+
ptr = getstring(ptemplate, &n, &logical_charsize, &charsize, &view);
22852296
b = charsize;
22862297
if (ptr) {
22872298
literal = sre_literal_template(b, ptr, n);
22882299
} else {
22892300
PyErr_Clear();
22902301
literal = 0;
22912302
}
2303+
if (view.buf)
2304+
PyBuffer_Release(&view);
22922305
if (literal) {
22932306
filter = ptemplate;
22942307
Py_INCREF(filter);
@@ -2628,6 +2641,7 @@ _compile(PyObject* self_, PyObject* args)
26282641
Py_ssize_t groups = 0;
26292642
PyObject* groupindex = NULL;
26302643
PyObject* indexgroup = NULL;
2644+
26312645
if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags,
26322646
&PyList_Type, &code, &groups,
26332647
&groupindex, &indexgroup))
@@ -2642,6 +2656,7 @@ _compile(PyObject* self_, PyObject* args)
26422656
self->pattern = NULL;
26432657
self->groupindex = NULL;
26442658
self->indexgroup = NULL;
2659+
self->view.buf = NULL;
26452660

26462661
self->codesize = n;
26472662

@@ -2668,7 +2683,7 @@ _compile(PyObject* self_, PyObject* args)
26682683
else {
26692684
Py_ssize_t p_length;
26702685
if (!getstring(pattern, &p_length, &self->logical_charsize,
2671-
&self->charsize)) {
2686+
&self->charsize, &self->view)) {
26722687
Py_DECREF(self);
26732688
return NULL;
26742689
}

Modules/sre.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef struct {
3232
PyObject *weakreflist; /* List of weak references */
3333
int logical_charsize; /* pattern charsize (or -1) */
3434
int charsize;
35+
Py_buffer view;
3536
/* pattern code */
3637
Py_ssize_t codesize;
3738
SRE_CODE code[1];
@@ -82,6 +83,7 @@ typedef struct {
8283
char* data_stack;
8384
size_t data_stack_size;
8485
size_t data_stack_base;
86+
Py_buffer buffer;
8587
/* current repeat context */
8688
SRE_REPEAT *repeat;
8789
/* hooks */

0 commit comments

Comments
 (0)