Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.

Commit b07ac39

Browse files
author
Juanjo Alvarez
committed
Fix memory leaks (thanks @amlweems)
Signed-off-by: Juanjo Alvarez <juanjo@sourced.tech>
1 parent d0fba32 commit b07ac39

3 files changed

Lines changed: 44 additions & 7 deletions

File tree

bblfsh/pyuast.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@ static PyObject *AttributeValue(const void *node, const char *prop) {
1616
}
1717

1818
static const char *String(const void *node, const char *prop) {
19+
const char *retval = NULL;
1920
PyObject *o = Attribute(node, prop);
20-
return o ? PyUnicode_AsUTF8(o) : NULL;
21+
if (o != NULL) {
22+
retval = PyUnicode_AsUTF8(o);
23+
Py_DECREF(o);
24+
}
25+
return retval;
2126
}
2227

2328
static size_t Size(const void *node, const char *prop) {
@@ -26,8 +31,14 @@ static size_t Size(const void *node, const char *prop) {
2631
}
2732

2833
static PyObject *ItemAt(PyObject *object, int index) {
34+
PyObject *retval = NULL;
2935
PyObject *seq = PySequence_Fast(object, "expected a sequence");
30-
return PyList_GET_ITEM(seq, index);
36+
if (seq != NULL) {
37+
retval = PyList_GET_ITEM(seq, index);
38+
Py_DECREF(seq);
39+
}
40+
41+
return retval;
3142
}
3243

3344

@@ -68,8 +79,13 @@ static const char *PropertyKeyAt(const void *node, int index) {
6879
return NULL;
6980
}
7081

82+
const char *retval = NULL;
7183
PyObject *keys = PyMapping_Keys(properties);
72-
return keys ? PyUnicode_AsUTF8(ItemAt(keys, index)) : NULL;
84+
if (keys != NULL) {
85+
retval = PyUnicode_AsUTF8(ItemAt(keys, index));
86+
Py_DECREF(keys);
87+
}
88+
return retval;
7389
}
7490

7591
static const char *PropertyValueAt(const void *node, int index) {
@@ -78,8 +94,13 @@ static const char *PropertyValueAt(const void *node, int index) {
7894
return NULL;
7995
}
8096

97+
const char *retval = NULL;
8198
PyObject *values = PyMapping_Values(properties);
82-
return values ? PyUnicode_AsUTF8(ItemAt(values, index)) : NULL;
99+
if (values != NULL) {
100+
retval = PyUnicode_AsUTF8(ItemAt(values, index));
101+
Py_DECREF(values);
102+
}
103+
return retval;
83104
}
84105

85106
static uint32_t PositionValue(const void* node, const char *prop, const char *field) {
@@ -275,7 +296,9 @@ static PyObject *PyFilter(PyObject *self, PyObject *args)
275296
PyList_SET_ITEM(list, i, node);
276297
}
277298
NodesFree(nodes);
278-
return PySeqIter_New(list);
299+
PyObject *iter = PySeqIter_New(list);
300+
Py_DECREF(list);
301+
return iter;
279302
}
280303

281304
static PyMethodDef extension_methods[] = {

bblfsh/test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,20 @@ def _validate_resp(self, resp):
188188
# Sometimes its fully qualified, sometimes is just "Node"... ditto
189189
assert(resp.uast.__class__.__name__.endswith('Node'))
190190

191+
def testManyFilters(self):
192+
root = self.client.parse(__file__).uast
193+
root.properties['k1'] = 'v2'
194+
root.properties['k2'] = 'v1'
195+
196+
import resource
197+
before = resource.getrusage(resource.RUSAGE_SELF)
198+
for _ in range(100):
199+
filter(root, "//*[@roleIdentifier]")
200+
after = resource.getrusage(resource.RUSAGE_SELF)
201+
202+
# Check that memory usage has not doubled after running the filter
203+
self.assertLess(after[2] / before[2], 2.0)
204+
191205
def _validate_filter(self, resp):
192206
results = filter(resp.uast, "//Import[@roleImport and @roleDeclaration]//alias")
193207
self.assertEqual(next(results).token, "os")

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from setuptools import setup, find_packages, Extension
66
from setuptools.command.build_ext import build_ext
77

8-
LIBUAST_VERSION = "v1.6.0"
8+
LIBUAST_VERSION = "v1.8.2"
99
SDK_VERSION = "v1.8.0"
1010
SDK_MAJOR = SDK_VERSION.split('.')[0]
1111
PYTHON = "python3"
@@ -134,7 +134,7 @@ def main():
134134
},
135135
name="bblfsh",
136136
description="Fetches Universal Abstract Syntax Trees from Babelfish.",
137-
version="2.8.1",
137+
version="2.8.2",
138138
license="Apache 2.0",
139139
author="source{d}",
140140
author_email="language-analysis@sourced.tech",

0 commit comments

Comments
 (0)