Changeset 11171

Show
Ignore:
Timestamp:
2008-09-03 15:40:34 (3 months ago)
Author:
olly
Message:

Backport change from trunk:
python/util.i: Fix memory leaks in query constructor typemaps.
Also, remove old, commented out, code which almost certainly had
similar memory leaks - I don't think we're going to want this
code, but if we do, rewriting it by copying the maintained and
working code for the query constructor is less likely to lead to
subtle errors.

Location:
branches/1.0/xapian-bindings
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • branches/1.0/xapian-bindings/ChangeLog

    r11170 r11171  
     1Wed Sep 03 14:40:26 GMT 2008  Olly Betts <olly@survex.com> 
     2 
     3        * Backport change from trunk: 
     4        * python/util.i: Fix memory leaks in query constructor typemaps. 
     5          Also, remove old, commented out, code which almost certainly had 
     6          similar memory leaks - I don't think we're going to want this 
     7          code, but if we do, rewriting it by copying the maintained and 
     8          working code for the query constructor is less likely to lead to 
     9          subtle errors. 
     10 
    111Wed Sep 03 14:26:50 GMT 2008  Olly Betts <olly@survex.com> 
    212 
  • branches/1.0/xapian-bindings/python/util.i

    r9769 r11171  
    7878        PyObject * mythis = PyObject_GetAttrString(obj, "this"); 
    7979#endif 
     80        if (!mythis) 
     81            return 0; 
     82 
    8083        Query * retval = 0; 
    81         if (!mythis || SWIG_ConvertPtr(mythis, (void **)&retval, 
    82                                        SWIGTYPE_p_Xapian__Query, 0) < 0) { 
     84        int res = SWIG_ConvertPtr(mythis, (void **)&retval, 
     85                                  SWIGTYPE_p_Xapian__Query, 0); 
     86        if (!SWIG_IsOK(res)) { 
    8387            retval = 0; 
    8488        } 
     89        Py_DECREF(mythis); 
    8590        return retval; 
    8691    } 
    87  
    88 #if 0 // Currently unused 
    89     RSet *get_py_rset(PyObject *obj) { 
    90         PyObject * mythis = PyObject_GetAttrString(obj, "this"); 
    91         Rset * retval = 0; 
    92         if (!mythis || SWIG_ConvertPtr(mythis, (void **)&retval, 
    93                                        SWIGTYPE_p_Xapian__RSet, 0) < 0) { 
    94             retval = 0; 
    95         } 
    96         return retval; 
    97     } 
    98 #endif 
    99  
    100 #if 0 // FIXME 
    101     MatchDecider *get_py_matchdecider(PyObject *obj) { 
    102         PyObject * mythis = PyObject_GetAttrString(obj, "this"); 
    103         MatchDecider * retval = 0; 
    104         if (!mythis || SWIG_ConvertPtr(mythis, (void **)&retval, 
    105                                        SWIGTYPE_p_Xapian__MatchDecider, 0) < 0) { 
    106             retval = 0; 
    107         } 
    108         return retval; 
    109     } 
    110 #endif 
    111  
    112 #if 0 
    113     int get_py_int(PyObject *obj) { 
    114         if (!PyNumber_Check(obj)) { 
    115             throw PythonProblem(); 
    116         } 
    117         return PyInt_AsLong(PyNumber_Int(obj)); 
    118     } 
    119 #endif 
    12092} 
    12193%} 
     
    12799    } else { 
    128100        $1 = 1; 
    129         int numitems = PySequence_Size($input); 
     101        PyObject * fastseq = PySequence_Fast($input, "expected sequence of strings or queries"); 
     102        if (!fastseq) { 
     103            // We've already checked that we have a sequence, so the failure of 
     104            // PySequence_Fast() is a serious error, not just a failure of 
     105            // typecheck. 
     106            SWIG_fail; 
     107        } 
     108        int numitems = PySequence_Fast_GET_SIZE(fastseq); 
    130109        for (int i = 0; i < numitems; ++i) { 
    131             PyObject *obj = PySequence_GetItem($input, i); 
     110            PyObject *obj = PySequence_Fast_GET_ITEM(fastseq, i); 
    132111            if (!PyUnicode_Check(obj) && !PyString_Check(obj) && !Xapian::get_py_query(obj)) { 
    133112                $1 = 0; 
     
    135114            } 
    136115        } 
     116        Py_DECREF(fastseq); 
    137117    } 
    138118} 
    139119 
    140120%typemap(in) const vector<Xapian::Query> & (vector<Xapian::Query> v) { 
    141     if (!PySequence_Check($input)) { 
    142         PyErr_SetString(PyExc_TypeError, "expected list of strings or queries"); 
    143         return NULL; 
    144     } 
    145  
    146     int numitems = PySequence_Size($input); 
     121    PyObject * fastseq = PySequence_Fast($input, "expected sequence of strings or queries"); 
     122    if (!fastseq) { 
     123        SWIG_fail; 
     124    } 
     125 
     126    int numitems = PySequence_Fast_GET_SIZE(fastseq); 
    147127    v.reserve(numitems); 
    148128    for (int i = 0; i < numitems; ++i) { 
    149         PyObject *obj = PySequence_GetItem($input, i); 
     129        PyObject *obj = PySequence_Fast_GET_ITEM(fastseq, i); 
     130        PyObject *decrefme = NULL; 
    150131        if (PyUnicode_Check(obj)) { 
    151132            PyObject *strobj = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(obj), PyUnicode_GET_SIZE(obj), "ignore"); 
    152133            if (!strobj) SWIG_fail; 
    153             Py_DECREF(obj); 
    154134            obj = strobj; 
     135            decrefme = strobj; 
    155136        } 
    156137        if (PyString_Check(obj)) { 
     
    164145            if (!subqp) { 
    165146                PyErr_SetString(PyExc_TypeError, "expected string or query"); 
     147                Py_XDECREF(decrefme); 
    166148                SWIG_fail; 
    167149            } 
    168150            v.push_back(*subqp); 
    169151        } 
     152        Py_XDECREF(decrefme); 
    170153    } 
    171154    $1 = &v; 
     155    Py_DECREF(fastseq); 
    172156} 
    173157