@@ -1664,7 +1664,7 @@ state_reset(SRE_STATE* state)
16641664}
16651665
16661666static void *
1667- getstring (PyObject * string , Py_ssize_t * p_length , int * p_charsize )
1667+ getstring (PyObject * string , Py_ssize_t * p_length , int * p_charsize , Py_buffer * view )
16681668{
16691669 /* given a python object, return a data pointer, a length (in
16701670 characters), and a character size. return NULL if the object
@@ -1674,7 +1674,6 @@ getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
16741674 Py_ssize_t size , bytes ;
16751675 int charsize ;
16761676 void * ptr ;
1677- Py_buffer view ;
16781677
16791678 /* Unicode objects do not support the buffer API. So, get the data
16801679 directly instead. */
@@ -1686,26 +1685,21 @@ getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
16861685 }
16871686
16881687 /* get pointer to string buffer */
1689- view . len = -1 ;
1688+ view -> len = -1 ;
16901689 buffer = Py_TYPE (string )-> tp_as_buffer ;
16911690 if (!buffer || !buffer -> bf_getbuffer ||
1692- (* buffer -> bf_getbuffer )(string , & view , PyBUF_SIMPLE ) < 0 ) {
1691+ (* buffer -> bf_getbuffer )(string , view , PyBUF_SIMPLE ) < 0 ) {
16931692 PyErr_SetString (PyExc_TypeError , "expected string or buffer" );
16941693 return NULL ;
16951694 }
16961695
16971696 /* determine buffer size */
1698- bytes = view .len ;
1699- ptr = view .buf ;
1700-
1701- /* Release the buffer immediately --- possibly dangerous
1702- but doing something else would require some re-factoring
1703- */
1704- PyBuffer_Release (& view );
1697+ bytes = view -> len ;
1698+ ptr = view -> buf ;
17051699
17061700 if (bytes < 0 ) {
17071701 PyErr_SetString (PyExc_TypeError , "buffer has negative size" );
1708- return NULL ;
1702+ goto err ;
17091703 }
17101704
17111705 /* determine character size */
@@ -1719,7 +1713,7 @@ getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
17191713#endif
17201714 else {
17211715 PyErr_SetString (PyExc_TypeError , "buffer size mismatch" );
1722- return NULL ;
1716+ goto err ;
17231717 }
17241718
17251719 * p_length = size ;
@@ -1728,8 +1722,13 @@ getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
17281722 if (ptr == NULL ) {
17291723 PyErr_SetString (PyExc_ValueError ,
17301724 "Buffer is NULL" );
1725+ goto err ;
17311726 }
17321727 return ptr ;
1728+ err :
1729+ PyBuffer_Release (view );
1730+ view -> buf = NULL ;
1731+ return NULL ;
17331732}
17341733
17351734LOCAL (PyObject * )
@@ -1747,20 +1746,21 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
17471746 state -> lastmark = -1 ;
17481747 state -> lastindex = -1 ;
17491748
1750- ptr = getstring (string , & length , & charsize );
1749+ state -> buffer .buf = NULL ;
1750+ ptr = getstring (string , & length , & charsize , & state -> buffer );
17511751 if (!ptr )
1752- return NULL ;
1752+ goto err ;
17531753
1754- if (charsize == 1 && pattern -> charsize > 1 ) {
1755- PyErr_SetString (PyExc_TypeError ,
1754+ if (charsize == 1 && pattern -> charsize > 1 ) {
1755+ PyErr_SetString (PyExc_TypeError ,
17561756 "can't use a string pattern on a bytes-like object" );
1757- return NULL ;
1758- }
1759- if (charsize > 1 && pattern -> charsize == 1 ) {
1760- PyErr_SetString (PyExc_TypeError ,
1757+ goto err ;
1758+ }
1759+ if (charsize > 1 && pattern -> charsize == 1 ) {
1760+ PyErr_SetString (PyExc_TypeError ,
17611761 "can't use a bytes pattern on a string-like object" );
1762- return NULL ;
1763- }
1762+ goto err ;
1763+ }
17641764
17651765 /* adjust boundaries */
17661766 if (start < 0 )
@@ -1797,11 +1797,17 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
17971797 state -> lower = sre_lower ;
17981798
17991799 return string ;
1800+ err :
1801+ if (state -> buffer .buf )
1802+ PyBuffer_Release (& state -> buffer );
1803+ return NULL ;
18001804}
18011805
18021806LOCAL (void )
18031807state_fini (SRE_STATE * state )
18041808{
1809+ if (state -> buffer .buf )
1810+ PyBuffer_Release (& state -> buffer );
18051811 Py_XDECREF (state -> string );
18061812 data_stack_dealloc (state );
18071813}
@@ -1863,6 +1869,8 @@ pattern_dealloc(PatternObject* self)
18631869{
18641870 if (self -> weakreflist != NULL )
18651871 PyObject_ClearWeakRefs ((PyObject * ) self );
1872+ if (self -> view .buf )
1873+ PyBuffer_Release (& self -> view );
18661874 Py_XDECREF (self -> pattern );
18671875 Py_XDECREF (self -> groupindex );
18681876 Py_XDECREF (self -> indexgroup );
@@ -2297,6 +2305,7 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
22972305 Py_ssize_t i , b , e ;
22982306 int bint ;
22992307 int filter_is_callable ;
2308+ Py_buffer view ;
23002309
23012310 if (PyCallable_Check (ptemplate )) {
23022311 /* sub/subn takes either a function or a template */
@@ -2306,7 +2315,8 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
23062315 } else {
23072316 /* if not callable, check if it's a literal string */
23082317 int literal ;
2309- ptr = getstring (ptemplate , & n , & bint );
2318+ view .buf = NULL ;
2319+ ptr = getstring (ptemplate , & n , & bint , & view );
23102320 b = bint ;
23112321 if (ptr ) {
23122322 if (b == 1 ) {
@@ -2320,6 +2330,8 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
23202330 PyErr_Clear ();
23212331 literal = 0 ;
23222332 }
2333+ if (view .buf )
2334+ PyBuffer_Release (& view );
23232335 if (literal ) {
23242336 filter = ptemplate ;
23252337 Py_INCREF (filter );
@@ -2661,6 +2673,7 @@ _compile(PyObject* self_, PyObject* args)
26612673 Py_ssize_t groups = 0 ;
26622674 PyObject * groupindex = NULL ;
26632675 PyObject * indexgroup = NULL ;
2676+
26642677 if (!PyArg_ParseTuple (args , "OiO!|nOO" , & pattern , & flags ,
26652678 & PyList_Type , & code , & groups ,
26662679 & groupindex , & indexgroup ))
@@ -2675,6 +2688,7 @@ _compile(PyObject* self_, PyObject* args)
26752688 self -> pattern = NULL ;
26762689 self -> groupindex = NULL ;
26772690 self -> indexgroup = NULL ;
2691+ self -> view .buf = NULL ;
26782692
26792693 self -> codesize = n ;
26802694
@@ -2694,15 +2708,15 @@ _compile(PyObject* self_, PyObject* args)
26942708 return NULL ;
26952709 }
26962710
2697- if (pattern == Py_None )
2698- self -> charsize = -1 ;
2699- else {
2700- Py_ssize_t p_length ;
2701- if (!getstring (pattern , & p_length , & self -> charsize )) {
2702- Py_DECREF (self );
2703- return NULL ;
2704- }
2705- }
2711+ if (pattern == Py_None )
2712+ self -> charsize = -1 ;
2713+ else {
2714+ Py_ssize_t p_length ;
2715+ if (!getstring (pattern , & p_length , & self -> charsize , & self -> view )) {
2716+ Py_DECREF (self );
2717+ return NULL ;
2718+ }
2719+ }
27062720
27072721 Py_INCREF (pattern );
27082722 self -> pattern = pattern ;
0 commit comments