1111MemTracker memTracker;
1212
1313// Used to store references to the Pyobjects instanced in String() and
14- // ItemAt() methods. Those can't be DECREF'ed to 0 because libuast uses the
14+ // ItemAt() methods. Those can't be DECREF'ed to 0 because libuast uses them
1515// so we pass ownership to these lists and free them at the end of filter()
1616
1717static PyObject *Attribute (const void *node, const char *prop) {
@@ -29,7 +29,7 @@ static const char *String(const void *node, const char *prop) {
2929 PyObject *o = Attribute (node, prop);
3030 if (o != NULL ) {
3131 retval = PyUnicode_AsUTF8 (o);
32- memTracker.TrackStr (o);
32+ memTracker.TrackItem (o);
3333 }
3434 return retval;
3535}
@@ -39,6 +39,7 @@ static size_t Size(const void *node, const char *prop) {
3939 PyObject *o = Attribute (node, prop);
4040 if (o != NULL ) {
4141 retval = PySequence_Size (o);
42+ Py_DECREF (o);
4243 }
4344
4445 return retval;
@@ -69,21 +70,37 @@ static size_t ChildrenSize(const void *node) {
6970
7071static void *ChildAt (const void *node, int index) {
7172 PyObject *children = AttributeValue (node, " children" );
72- return children ? ItemAt (children, index) : NULL ;
73+ void *retval = nullptr ;
74+ if (children) {
75+ retval = ItemAt (children, index);
76+ Py_DECREF (children);
77+ }
78+
79+ return retval;
7380}
7481
7582static size_t RolesSize (const void *node) {
7683 return Size (node, " roles" );
7784}
7885
7986static uint16_t RoleAt (const void *node, int index) {
87+ uint16_t retval = 0 ;
8088 PyObject *roles = AttributeValue (node, " roles" );
81- return roles ? (uint16_t )PyLong_AsUnsignedLong (ItemAt (roles, index)) : 0 ;
89+ if (roles) {
90+ retval = (uint16_t )PyLong_AsUnsignedLong (ItemAt (roles, index));
91+ Py_DECREF (roles);
92+ }
93+ return retval;
8294}
8395
8496static size_t PropertiesSize (const void *node) {
97+ size_t retval = 0 ;
8598 PyObject *properties = AttributeValue (node, " properties" );
86- return properties ? PyMapping_Size (properties) : 0 ;
99+ if (properties) {
100+ retval = PyMapping_Size (properties);
101+ Py_DECREF (properties);
102+ }
103+ return retval;
87104}
88105
89106static const char *PropertyKeyAt (const void *node, int index) {
@@ -94,6 +111,7 @@ static const char *PropertyKeyAt(const void *node, int index) {
94111
95112 const char *retval = NULL ;
96113 PyObject *keys = PyMapping_Keys (properties);
114+ Py_DECREF (properties);
97115 if (keys != NULL ) {
98116 retval = PyUnicode_AsUTF8 (ItemAt (keys, index));
99117 Py_DECREF (keys);
@@ -103,7 +121,11 @@ static const char *PropertyKeyAt(const void *node, int index) {
103121
104122static const char *PropertyValueAt (const void *node, int index) {
105123 PyObject *properties = AttributeValue (node, " properties" );
106- if (!properties || !PyMapping_Check (properties)) {
124+ if (!properties)
125+ return NULL ;
126+
127+ if (!PyMapping_Check (properties)) {
128+ Py_DECREF (properties);
107129 return NULL ;
108130 }
109131
@@ -113,6 +135,7 @@ static const char *PropertyValueAt(const void *node, int index) {
113135 retval = PyUnicode_AsUTF8 (ItemAt (values, index));
114136 Py_DECREF (values);
115137 }
138+ Py_DECREF (properties);
116139 return retval;
117140}
118141
@@ -123,7 +146,14 @@ static uint32_t PositionValue(const void* node, const char *prop, const char *fi
123146 }
124147
125148 PyObject *offset = AttributeValue (position, field);
126- return offset ? (uint32_t )PyLong_AsUnsignedLong (offset) : 0 ;
149+ Py_DECREF (position);
150+ uint32_t retval = 0 ;
151+
152+ if (offset) {
153+ retval = (uint32_t )PyLong_AsUnsignedLong (offset);
154+ Py_DECREF (offset);
155+ }
156+ return retval;
127157}
128158
129159// ///////////////////////////////////
@@ -337,6 +367,7 @@ static PyObject *PyFilter(PyObject *self, PyObject *args)
337367 cleanupFilter ();
338368 return NULL ;
339369 }
370+
340371 size_t len = NodesSize (nodes);
341372 PyObject *list = PyList_New (len);
342373
0 commit comments