Skip to content

Commit b5c0896

Browse files
authored
Merge pull request #208 from CESNET/pytrap-fix-getfieldtype
Bugfix - segmentation fault caused by getFieldType()
2 parents 66f88ef + 84b3700 commit b5c0896

File tree

4 files changed

+44
-92
lines changed

4 files changed

+44
-92
lines changed

pytrap/Makefile.am

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ TESTS = test.sh
1818
coverage:
1919
CFLAGS=-coverage python setup.py build_ext --inplace
2020
CFLAGS=-coverage python3 setup.py build_ext --inplace
21-
python3 setup.py test
2221
python3 setup.py test || echo "Skipped python3 tests"
2322
@lcov --capture --directory . --output-file coverage.info 2>/dev/null && \
2423
genhtml coverage.info --output-directory out 2>/dev/null || echo "Skipped coverage analysis"

pytrap/src/pytrapmodule.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ static PyTypeObject pytrap_TrapContext = {
747747
0, /* tp_dictoffset */
748748
0, /* tp_init */
749749
0, /* tp_alloc */
750-
0 /* tp_new */
750+
PyType_GenericNew /* tp_new */
751751
};
752752

753753
PyObject *
@@ -847,8 +847,6 @@ static PyMethodDef pytrap_methods[] = {
847847
"For more details, see the generated documentation:\n" \
848848
"https://nemea.liberouter.org/doc/pytrap/.\n"
849849

850-
#if PY_MAJOR_VERSION >= 3
851-
852850
static struct PyModuleDef pytrapmodule = {
853851
PyModuleDef_HEAD_INIT,
854852
"pytrap.pytrap", /* name of module */
@@ -861,28 +859,19 @@ static struct PyModuleDef pytrapmodule = {
861859

862860
PyMODINIT_FUNC
863861
PyInit_pytrap(void)
864-
#else
865-
# define INITERROR return
866-
867-
void
868-
initpytrap(void)
869-
#endif
870862
{
871863
PyObject *m;
872864

873-
#if PY_MAJOR_VERSION >= 3
874865
m = PyModule_Create(&pytrapmodule);
875-
#else
876-
m = Py_InitModule3("pytrap.pytrap", pytrap_methods, DOCSTRING_MODULE);
877-
#endif
878866
if (m == NULL) {
879867
INITERROR;
880868
}
881869

882-
pytrap_TrapContext.tp_new = PyType_GenericNew;
883870
if (PyType_Ready(&pytrap_TrapContext) < 0) {
884871
INITERROR;
885872
}
873+
Py_INCREF(&pytrap_TrapContext);
874+
PyModule_AddObject(m, "TrapCtx", (PyObject *) &pytrap_TrapContext);
886875

887876
/* Add Exceptions into pytrap module */
888877
TrapError = PyErr_NewException("pytrap.TrapError", NULL, NULL);
@@ -909,9 +898,6 @@ initpytrap(void)
909898
Py_INCREF(TrapHelp);
910899
PyModule_AddObject(m, "TrapHelp", TrapHelp);
911900

912-
Py_INCREF(&pytrap_TrapContext);
913-
PyModule_AddObject(m, "TrapCtx", (PyObject *) &pytrap_TrapContext);
914-
915901
/* Initialize UniRec part of pytrap */
916902
if (init_unirectemplate(m) == EXIT_FAILURE) {
917903
INITERROR;
@@ -943,8 +929,5 @@ initpytrap(void)
943929
PyModule_AddIntConstant(m, "VERB_VERBOSE2", 1);
944930
PyModule_AddIntConstant(m, "VERB_VERBOSE3", 2);
945931

946-
947-
#if PY_MAJOR_VERSION >= 3
948932
return m;
949-
#endif
950933
}

pytrap/src/unirecmodule.c

Lines changed: 31 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -521,9 +521,6 @@ static PyTypeObject pytrap_UnirecTime = {
521521
0, /* tp_setattro */
522522
0, /* tp_as_buffer */
523523
Py_TPFLAGS_DEFAULT |
524-
#if PY_MAJOR_VERSION < 3
525-
Py_TPFLAGS_CHECKTYPES |
526-
#endif
527524
Py_TPFLAGS_BASETYPE, /* tp_flags */
528525
"UnirecTime(int(seconds), [int(miliseconds)])\n"
529526
"UnirecTime(double(secs_and_msecs))\n"
@@ -810,11 +807,7 @@ UnirecTemplate_getByName(pytrap_unirectemplate *self, PyObject *args, PyObject *
810807
return NULL;
811808
}
812809

813-
#if PY_MAJOR_VERSION >= 3
814810
if (!PyUnicode_Check(field_name))
815-
#else
816-
if (!PyUnicode_Check(field_name) && !PyString_Check(field_name))
817-
#endif
818811
{
819812
PyErr_SetString(PyExc_TypeError, "Argument field_name must be string.");
820813
return NULL;
@@ -1424,12 +1417,7 @@ UnirecTemplate_set(pytrap_unirectemplate *self, PyObject *args, PyObject *keywds
14241417
return NULL;
14251418
}
14261419

1427-
#if PY_MAJOR_VERSION >= 3
1428-
if (!PyUnicode_Check(field_name))
1429-
#else
1430-
if (!PyUnicode_Check(field_name) && !PyString_Check(field_name))
1431-
#endif
1432-
{
1420+
if (!PyUnicode_Check(field_name)) {
14331421
PyErr_SetString(PyExc_TypeError, "Argument field_name must be string.");
14341422
return NULL;
14351423
}
@@ -1447,26 +1435,27 @@ UnirecTemplate_getFieldsDict_local(pytrap_unirectemplate *self, char byId)
14471435
{
14481436
PyObject *key, *num;
14491437
int i;
1438+
int result;
14501439
PyObject *d = PyDict_New();
14511440
if (d != NULL) {
14521441
for (i = 0; i < self->urtmplt->count; i++) {
1453-
#if PY_MAJOR_VERSION >= 3
14541442
key = PyUnicode_FromString(ur_get_name(self->urtmplt->ids[i]));
1455-
#else
1456-
key = PyString_FromString(ur_get_name(self->urtmplt->ids[i]));
1457-
#endif
14581443
num = PyLong_FromLong(self->urtmplt->ids[i]);
14591444
if (byId) {
1460-
PyDict_SetItem(d, num, key);
1445+
result = PyDict_SetItem(d, num, key);
14611446
} else {
1462-
PyDict_SetItem(d, key, num);
1447+
result = PyDict_SetItem(d, key, num);
14631448
}
1464-
Py_DECREF(num);
14651449
Py_DECREF(key);
1450+
Py_DECREF(num);
1451+
if (result == -1) {
1452+
fprintf(stderr, "failed to set item dict.\n");
1453+
Py_RETURN_NONE;
1454+
}
14661455
}
14671456
return d;
14681457
}
1469-
Py_DECREF(d);
1458+
Py_XDECREF(d);
14701459
Py_RETURN_NONE;
14711460
}
14721461

@@ -1764,21 +1753,12 @@ UnirecTemplate_getDict(pytrap_unirectemplate *self)
17641753
static PyObject *
17651754
UnirecTemplate_getFieldType(pytrap_unirectemplate *self, PyObject *args)
17661755
{
1767-
PyObject *name;
1756+
PyObject *name, *result = NULL;
17681757

1769-
if (!PyArg_ParseTuple(args, "O", &name)) {
1758+
if (!PyArg_ParseTuple(args, "O!", &PyUnicode_Type, &name)) {
17701759
return NULL;
17711760
}
17721761

1773-
#if PY_MAJOR_VERSION >= 3
1774-
if (!PyUnicode_Check(name))
1775-
#else
1776-
if (!PyUnicode_Check(name) && !PyString_Check(name))
1777-
#endif
1778-
{
1779-
PyErr_SetString(PyExc_TypeError, "Argument field_name must be string.");
1780-
return NULL;
1781-
}
17821762
int32_t field_id = UnirecTemplate_get_field_id(self, name);
17831763

17841764
switch (ur_get_type(field_id)) {
@@ -1791,27 +1771,26 @@ UnirecTemplate_getFieldType(pytrap_unirectemplate *self, PyObject *args)
17911771
case UR_TYPE_INT32:
17921772
case UR_TYPE_INT64:
17931773
case UR_TYPE_CHAR:
1794-
return (PyObject *) &PyLong_Type;
1774+
result = (PyObject *) &PyLong_Type;
17951775
break;
17961776
case UR_TYPE_FLOAT:
17971777
case UR_TYPE_DOUBLE:
1798-
return (PyObject *) &PyFloat_Type;
1778+
result = (PyObject *) &PyFloat_Type;
17991779
break;
18001780
case UR_TYPE_IP:
1801-
return (PyObject *) &pytrap_UnirecIPAddr;
1781+
result = (PyObject *) &pytrap_UnirecIPAddr;
1782+
break;
18021783
case UR_TYPE_MAC:
1803-
return (PyObject *) &pytrap_UnirecMACAddr;
1784+
result = (PyObject *) &pytrap_UnirecMACAddr;
1785+
break;
18041786
case UR_TYPE_TIME:
1805-
return (PyObject *) &pytrap_UnirecTime;
1787+
result = (PyObject *) &pytrap_UnirecTime;
1788+
break;
18061789
case UR_TYPE_STRING:
1807-
#if PY_MAJOR_VERSION >= 3
1808-
return (PyObject *) &PyUnicode_Type;
1809-
#else
1810-
return (PyObject *) &PyString_Type;
1811-
#endif
1790+
result = (PyObject *) &PyUnicode_Type;
18121791
break;
18131792
case UR_TYPE_BYTES:
1814-
return (PyObject *) &PyByteArray_Type;
1793+
result = (PyObject *) &PyByteArray_Type;
18151794
break;
18161795
case UR_TYPE_A_UINT8:
18171796
case UR_TYPE_A_INT8:
@@ -1826,12 +1805,17 @@ UnirecTemplate_getFieldType(pytrap_unirectemplate *self, PyObject *args)
18261805
case UR_TYPE_A_IP:
18271806
case UR_TYPE_A_MAC:
18281807
case UR_TYPE_A_TIME:
1829-
return (PyObject *) &PyList_Type;
1808+
result = (PyObject *) &PyList_Type;
18301809
break;
18311810
default:
18321811
PyErr_SetString(PyExc_NotImplementedError, "Unknown UniRec field type.");
18331812
return NULL;
18341813
} // case (field type)
1814+
1815+
if (result != NULL) {
1816+
Py_INCREF(result);
1817+
return result;
1818+
}
18351819
Py_RETURN_NONE;
18361820
}
18371821

@@ -2102,16 +2086,12 @@ UnirecTemplate_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
21022086

21032087
static void UnirecTemplate_dealloc(pytrap_unirectemplate *self)
21042088
{
2105-
if (self->urdict) {
2106-
Py_DECREF(self->urdict);
2107-
}
2108-
if (self->fields_dict) {
2109-
Py_DECREF(self->fields_dict);
2110-
}
2089+
Py_XDECREF(self->urdict);
2090+
Py_XDECREF(self->fields_dict);
21112091
if (self->urtmplt) {
21122092
ur_free_template(self->urtmplt);
21132093
}
2114-
Py_XDECREF(self->data_obj); // Allow to free the original data object
2094+
Py_XDECREF(self->data_obj);
21152095
Py_TYPE(self)->tp_free((PyObject *) self);
21162096
}
21172097

@@ -2120,11 +2100,7 @@ UnirecTemplate_str(pytrap_unirectemplate *self)
21202100
{
21212101
char *s = ur_template_string_delimiter(self->urtmplt, ',');
21222102
PyObject *result;
2123-
#if PY_MAJOR_VERSION >= 3
21242103
result = PyUnicode_FromFormat("(%s)", s);
2125-
#else
2126-
result = PyString_FromFormat("(%s)", s);
2127-
#endif
21282104
free(s);
21292105
return result;
21302106
}
@@ -2171,11 +2147,7 @@ UnirecTemplate_next(pytrap_unirectemplate *self)
21712147
PyObject *result;
21722148

21732149
if (self->iter_index < self->field_count) {
2174-
#if PY_MAJOR_VERSION >= 3
21752150
name = PyUnicode_FromString(ur_get_name(self->urtmplt->ids[self->iter_index]));
2176-
#else
2177-
name = PyString_FromString(ur_get_name(self->urtmplt->ids[self->iter_index]));
2178-
#endif
21792151
value = UnirecTemplate_get_local(self, self->data, self->urtmplt->ids[self->iter_index]);
21802152
self->iter_index++;
21812153
result = Py_BuildValue("(OO)", name, value);
@@ -2268,7 +2240,6 @@ init_unirectemplate(PyObject *m)
22682240
PyModule_AddObject(m, "UnirecTime", (PyObject *) &pytrap_UnirecTime);
22692241

22702242
/* Add IPAddr */
2271-
//pytrap_UnirecTemplate.tp_new = PyType_GenericNew;
22722243
if (PyType_Ready(&pytrap_UnirecIPAddr) < 0) {
22732244
return EXIT_FAILURE;
22742245
}
@@ -2283,7 +2254,6 @@ init_unirectemplate(PyObject *m)
22832254
PyModule_AddObject(m, "UnirecIPAddrRange", (PyObject *) &pytrap_UnirecIPAddrRange);
22842255

22852256
/* Add MACAddr */
2286-
//pytrap_UnirecTemplate.tp_new = PyType_GenericNew;
22872257
if (PyType_Ready(&pytrap_UnirecMACAddr) < 0) {
22882258
return EXIT_FAILURE;
22892259
}

pytrap/test/unirectemplate_unittest.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ class DataTypesArray(unittest.TestCase):
325325
def runTest(self):
326326
import pytrap
327327
a = pytrap.UnirecTemplate("uint32 FOO, uint32 BAR, ipaddr IP, string STR, int32* ARR1, ipaddr* IPs, macaddr* MACs, uint64* ARR2, time* TIMEs")
328-
data = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x61\x4e\xff\xff\xff\xff\x31\xd4\x00\x00\x39\x30\x00\x00\x00\x00\x0c\x00\x0c\x00\x28\x00\x34\x00\x12\x00\x46\x00\x50\x00\x96\x00\x18\x00\xae\x00\x50\x00\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\xf7\xff\xff\xff\xf8\xff\xff\xff\xf9\xff\xff\xff\xfa\xff\xff\xff\xfb\xff\xff\xff\xfc\xff\xff\xff\xfd\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11\x11\x11\x11\x11\x22\x22\x22\x22\x22\x22\x0a\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xc0\x33\x5b\x00\x00\x00\x80\xe6\xc0\x33\x5b\x00\x00\x00\x00\xe6\xc0\x33\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x01\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x61\x4e\xff\xff\xff\xff')
328+
data = bytes(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x61\x4e\xff\xff\xff\xff\x31\xd4\x00\x00\x39\x30\x00\x00\x00\x00\x0c\x00\x0c\x00\x28\x00\x34\x00\x12\x00\x46\x00\x50\x00\x96\x00\x18\x00\xae\x00\x50\x00\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\xf7\xff\xff\xff\xf8\xff\xff\xff\xf9\xff\xff\xff\xfa\xff\xff\xff\xfb\xff\xff\xff\xfc\xff\xff\xff\xfd\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11\x11\x11\x11\x11\x22\x22\x22\x22\x22\x22\x0a\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xc0\x33\x5b\x00\x00\x00\x80\xe6\xc0\x33\x5b\x00\x00\x00\x00\xe6\xc0\x33\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x01\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x02\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x61\x4e\xff\xff\xff\xff')
329329
a.setData(data)
330330
self.assertEqual(len(a), 9, "Number of fields differs, 9 expected.")
331331
self.assertEqual(str(a), "(ipaddr IP,uint32 BAR,uint32 FOO,string STR,int32* ARR1,macaddr* MACs,uint64* ARR2,time* TIMEs,ipaddr* IPs)")
@@ -339,39 +339,39 @@ def runTest(self):
339339
self.assertEqual(a.getFieldType("TIMEs"), list)
340340

341341
self.assertEqual(a.get(data, "FOO"), 12345)
342-
self.assertEqual(a.get(data, "FOO"), a.getByID(data, 6))
342+
self.assertEqual(a.get(data, "FOO"), a.getByID(data, d["FOO"]))
343343
self.assertEqual(a.get(data, "FOO"), a.FOO)
344344

345345
self.assertEqual(a.get(data, "BAR"), 54321)
346-
self.assertEqual(a.get(data, "BAR"), a.getByID(data, 7))
346+
self.assertEqual(a.get(data, "BAR"), a.getByID(data, d["BAR"]))
347347
self.assertEqual(a.get(data, "BAR"), a.BAR)
348348

349349
self.assertEqual(a.get(data, "IP"), pytrap.UnirecIPAddr("0.188.97.78"))
350-
self.assertEqual(a.get(data, "IP"), a.getByID(data, 8))
350+
self.assertEqual(a.get(data, "IP"), a.getByID(data, d["IP"]))
351351
self.assertEqual(a.get(data, "IP"), a.IP)
352352

353353
self.assertEqual(a.get(data, "STR"), "Hello World!")
354-
self.assertEqual(a.get(data, "STR"), a.getByID(data, 9))
354+
self.assertEqual(a.get(data, "STR"), a.getByID(data, d["STR"]))
355355
self.assertEqual(a.get(data, "STR"), a.STR)
356356

357357
self.assertEqual(a.get(data, "ARR1"), [-9, -8, -7, -6, -5, -4, -3, -2, -1, 0])
358-
self.assertEqual(a.get(data, "ARR1"), a.getByID(data, 10))
358+
self.assertEqual(a.get(data, "ARR1"), a.getByID(data, d["ARR1"]))
359359
self.assertEqual(a.get(data, "ARR1"), a.ARR1)
360360

361361
self.assertEqual(a.get(data, "IPs"), [pytrap.UnirecIPAddr("10.0.0.1"), pytrap.UnirecIPAddr("10.0.0.2"), pytrap.UnirecIPAddr("::1"), pytrap.UnirecIPAddr("127.0.0.1"), pytrap.UnirecIPAddr("0.188.97.78")])
362-
self.assertEqual(a.get(data, "IPs"), a.getByID(data, 11))
362+
self.assertEqual(a.get(data, "IPs"), a.getByID(data, d["IPs"]))
363363
self.assertEqual(a.get(data, "IPs"), a.IPs)
364364

365365
self.assertEqual(a.get(data, "MACs"), [pytrap.UnirecMACAddr("0:0:0:0:0:0"), pytrap.UnirecMACAddr("11:11:11:11:11:11"), pytrap.UnirecMACAddr("22:22:22:22:22:22")])
366-
self.assertEqual(a.get(data, "MACs"), a.getByID(data, 12))
366+
self.assertEqual(a.get(data, "MACs"), a.getByID(data, d["MACs"]))
367367
self.assertEqual(a.get(data, "MACs"), a.MACs)
368368

369369
self.assertEqual(a.get(data, "ARR2"), [10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
370-
self.assertEqual(a.get(data, "ARR2"), a.getByID(data, 13))
370+
self.assertEqual(a.get(data, "ARR2"), a.getByID(data, d["ARR2"]))
371371
self.assertEqual(a.get(data, "ARR2"), a.ARR2)
372372

373373
self.assertEqual(a.get(data, "TIMEs"), [pytrap.UnirecTime("2018-06-27T16:52:54"), pytrap.UnirecTime("2018-06-27T16:52:54.500"), pytrap.UnirecTime("2018-06-27T16:52:54Z"),])
374-
self.assertEqual(a.get(data, "TIMEs"), a.getByID(data, 14))
374+
self.assertEqual(a.get(data, "TIMEs"), a.getByID(data, d["TIMEs"]))
375375
self.assertEqual(a.get(data, "TIMEs"), a.TIMEs)
376376

377377
f_str = "Hello Unirec!"

0 commit comments

Comments
 (0)