diff --git a/netsnmp/client_intf.c b/netsnmp/client_intf.c index 14f943d..62aabf8 100644 --- a/netsnmp/client_intf.c +++ b/netsnmp/client_intf.c @@ -1535,8 +1535,12 @@ netsnmp_get(PyObject *self, PyObject *args) if (varlist) { PyObject *varlist_iter = PyObject_GetIter(varlist); + if (!varlist_iter) { + snmp_free_pdu(pdu); + goto done; + } - while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + while ((varbind = PyIter_Next(varlist_iter))) { if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) { @@ -1682,6 +1686,10 @@ netsnmp_get(PyObject *self, PyObject *args) done: SAFE_FREE(oid_arr); + if (PyErr_Occurred()) { + Py_XDECREF(val_tuple); + return NULL; + } return (val_tuple ? val_tuple : Py_BuildValue("")); } @@ -1753,8 +1761,12 @@ netsnmp_getnext(PyObject *self, PyObject *args) if (varlist) { PyObject *varlist_iter = PyObject_GetIter(varlist); + if (!varlist_iter) { + snmp_free_pdu(pdu); + goto done; + } - while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + while ((varbind = PyIter_Next(varlist_iter))) { if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) { @@ -1902,6 +1914,10 @@ netsnmp_getnext(PyObject *self, PyObject *args) done: SAFE_FREE(oid_arr); + if (PyErr_Occurred()) { + Py_XDECREF(val_tuple); + return NULL; + } return (val_tuple ? val_tuple : Py_BuildValue("")); } @@ -1991,8 +2007,12 @@ netsnmp_walk(PyObject *self, PyObject *args) /* we need an initial count for memory allocation */ varlist_iter = PyObject_GetIter(varlist); + if (!varlist_iter) { + snmp_free_pdu(pdu); + goto done; + } varlist_len = 0; - while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + while ((varbind = PyIter_Next(varlist_iter))) { varlist_len++; } Py_DECREF(varlist_iter); @@ -2523,14 +2543,16 @@ netsnmp_getbulk(PyObject *self, PyObject *args) /* propagate error */ if (verbose) printf("error: getbulk response processing: unknown python error"); - if (val_tuple) - Py_DECREF(val_tuple); - val_tuple = NULL; + Py_CLEAR(val_tuple); } } done: SAFE_FREE(oid_arr); + if (PyErr_Occurred()) { + Py_XDECREF(val_tuple); + return NULL; + } return (val_tuple ? val_tuple : Py_BuildValue("")); } @@ -2539,7 +2561,7 @@ netsnmp_set(PyObject *self, PyObject *args) { PyObject *session; PyObject *varlist; - PyObject *varbind; + PyObject *varbind = NULL; PyObject *ret = NULL; netsnmp_session *ss; netsnmp_pdu *pdu, *response; @@ -2587,8 +2609,12 @@ netsnmp_set(PyObject *self, PyObject *args) if (varlist) { PyObject *varlist_iter = PyObject_GetIter(varlist); + if (!varlist_iter) { + snmp_free_pdu(pdu); + goto done; + } - while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) { + while ((varbind = PyIter_Next(varlist_iter))) { if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 || py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0) { @@ -2673,6 +2699,8 @@ netsnmp_set(PyObject *self, PyObject *args) done: Py_XDECREF(varbind); SAFE_FREE(oid_arr); + if (PyErr_Occurred()) + return NULL; return (ret ? ret : Py_BuildValue("")); } diff --git a/netsnmp/tests/system/test_errors.py b/netsnmp/tests/system/test_errors.py index ea8376d..9cd0556 100644 --- a/netsnmp/tests/system/test_errors.py +++ b/netsnmp/tests/system/test_errors.py @@ -6,6 +6,23 @@ class ErrorPathTests(unittest.TestCase): + def test_session_methods_reject_bare_varbind(self): + session = netsnmp.Session(**READ_ARGS) + varbind = netsnmp.Varbind( + '.1.3.6.1.2.1.1.3', '0', b'1', 'INTEGER') + calls = ( + (TypeError, lambda: session.get(varbind)), + (TypeError, lambda: session.getnext(varbind)), + (TypeError, lambda: session.set(varbind)), + (AttributeError, lambda: session.walk(varbind)), + (AttributeError, lambda: session.getbulk(0, 1, varbind)), + ) + + for error_type, call in calls: + with self.subTest(call=call): + with self.assertRaises(error_type): + call() + def test_unknown_oid_returns_no_value(self): varbind = netsnmp.Varbind('.1.3.6.1.2.1.1.999', '0') values = netsnmp.snmpget(varbind, **READ_ARGS)