diff --git a/Modules/constants.c b/Modules/constants.c index 07d60653..953c9658 100644 --- a/Modules/constants.c +++ b/Modules/constants.c @@ -50,139 +50,197 @@ LDAPerr(int errnum) PyObject * LDAPraise_for_message(LDAP *l, LDAPMessage *m) { + int myerrno, errnum, opt_errnum, res, msgid = -1, msgtype = 0; + PyObject *errobj = NULL; + PyObject *info = NULL; + PyObject *str = NULL; + PyObject *pyerrno = NULL; + PyObject *pyresult = NULL; + PyObject *pyctrls = NULL; + char *matched = NULL; + char *error = NULL; + char **refs = NULL; + LDAPControl **serverctrls = NULL; + if (l == NULL) { PyErr_SetFromErrno(LDAPexception_class); ldap_msgfree(m); return NULL; } - else { - int myerrno, errnum, opt_errnum, msgid = -1, msgtype = 0; - PyObject *errobj; - PyObject *info; - PyObject *str; - PyObject *pyerrno; - PyObject *pyresult; - PyObject *pyctrls = NULL; - char *matched = NULL, *error = NULL, **refs = NULL; - LDAPControl **serverctrls = NULL; - - /* at first save errno for later use before it gets overwritten by another call */ - myerrno = errno; - - if (m != NULL) { - msgid = ldap_msgid(m); - msgtype = ldap_msgtype(m); - ldap_parse_result(l, m, &errnum, &matched, &error, &refs, - &serverctrls, 1); - } - if (msgtype <= 0) { - opt_errnum = ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum); - if (opt_errnum != LDAP_OPT_SUCCESS) - errnum = opt_errnum; + /* at first save errno for later use before it gets overwritten by another call */ + myerrno = errno; + if (m != NULL) { + msgid = ldap_msgid(m); + msgtype = ldap_msgtype(m); + ldap_parse_result(l, m, &errnum, &matched, &error, &refs, + &serverctrls, 1); + } + + if (msgtype <= 0) { + opt_errnum = ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum); + if (opt_errnum != LDAP_OPT_SUCCESS) { + errnum = opt_errnum; if (errnum == LDAP_NO_MEMORY) { - return PyErr_NoMemory(); + PyErr_NoMemory(); + goto cleanup; } - - ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched); - ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error); } - if (errnum >= LDAP_ERROR_MIN && errnum <= LDAP_ERROR_MAX && - errobjects[errnum + LDAP_ERROR_OFFSET] != NULL) { - errobj = errobjects[errnum + LDAP_ERROR_OFFSET]; + ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched); + ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error); + } + + if (errnum >= LDAP_ERROR_MIN && errnum <= LDAP_ERROR_MAX) { + // Borrowed reference + errobj = errobjects[errnum + LDAP_ERROR_OFFSET]; + } + if (errobj == NULL) { + // Borrowed reference + errobj = LDAPexception_class; + } + + info = PyDict_New(); + if (info == NULL) { + goto cleanup; + } + + if (msgtype > 0) { + pyresult = PyInt_FromLong(msgtype); + if (!pyresult) { + goto cleanup; } - else { - errobj = LDAPexception_class; + res = PyDict_SetItemString(info, "msgtype", pyresult); + if (res) { + goto cleanup; } + Py_CLEAR(pyresult); + } - info = PyDict_New(); - if (info == NULL) { - ldap_memfree(matched); - ldap_memfree(error); - ldap_memvfree((void **)refs); - ldap_controls_free(serverctrls); - return NULL; + if (msgid >= 0) { + pyresult = PyInt_FromLong(msgid); + if (!pyresult) { + goto cleanup; } - - if (msgtype > 0) { - pyresult = PyInt_FromLong(msgtype); - if (pyresult) - PyDict_SetItemString(info, "msgtype", pyresult); - Py_XDECREF(pyresult); + res = PyDict_SetItemString(info, "msgid", pyresult); + if (res) { + goto cleanup; } + Py_CLEAR(pyresult); + } - if (msgid >= 0) { - pyresult = PyInt_FromLong(msgid); - if (pyresult) - PyDict_SetItemString(info, "msgid", pyresult); - Py_XDECREF(pyresult); - } + pyresult = PyInt_FromLong(errnum); + if (!pyresult) { + goto cleanup; + } + res = PyDict_SetItemString(info, "result", pyresult); + if (res) { + goto cleanup; + } + Py_CLEAR(pyresult); + + str = PyUnicode_FromString(ldap_err2string(errnum)); + if (!str) { + goto cleanup; + } + res = PyDict_SetItemString(info, "desc", str); + if (res) { + goto cleanup; + } + Py_CLEAR(str); - pyresult = PyInt_FromLong(errnum); - if (pyresult) - PyDict_SetItemString(info, "result", pyresult); - Py_XDECREF(pyresult); - - str = PyUnicode_FromString(ldap_err2string(errnum)); - if (str) - PyDict_SetItemString(info, "desc", str); - Py_XDECREF(str); - - if (myerrno != 0) { - pyerrno = PyInt_FromLong(myerrno); - if (pyerrno) - PyDict_SetItemString(info, "errno", pyerrno); - Py_XDECREF(pyerrno); + if (myerrno != 0) { + pyerrno = PyInt_FromLong(myerrno); + if (!pyerrno) { + goto cleanup; } + res = PyDict_SetItemString(info, "errno", pyerrno); + if (res) { + goto cleanup; + } + Py_CLEAR(pyerrno); + } - if (!(pyctrls = LDAPControls_to_List(serverctrls))) { - int err = LDAP_NO_MEMORY; + if (!(pyctrls = LDAPControls_to_List(serverctrls))) { + int err = LDAP_NO_MEMORY; + ldap_set_option(l, LDAP_OPT_ERROR_NUMBER, &err); - ldap_set_option(l, LDAP_OPT_ERROR_NUMBER, &err); - ldap_memfree(matched); - ldap_memfree(error); - ldap_memvfree((void **)refs); - ldap_controls_free(serverctrls); - return PyErr_NoMemory(); - } - ldap_controls_free(serverctrls); - PyDict_SetItemString(info, "ctrls", pyctrls); - Py_XDECREF(pyctrls); - - if (matched != NULL) { - if (*matched != '\0') { - str = PyUnicode_FromString(matched); - if (str) - PyDict_SetItemString(info, "matched", str); - Py_XDECREF(str); + PyErr_NoMemory(); + goto cleanup; + } + ldap_controls_free(serverctrls); + serverctrls = NULL; + res = PyDict_SetItemString(info, "ctrls", pyctrls); + if (res) { + goto cleanup; + } + Py_CLEAR(pyctrls); + + if (matched != NULL) { + if (*matched != '\0') { + str = PyUnicode_FromString(matched); + if (!str) { + goto cleanup; + } + res = PyDict_SetItemString(info, "matched", str); + if (res) { + goto cleanup; } - ldap_memfree(matched); + Py_CLEAR(str); } + ldap_memfree(matched); + matched = NULL; + } - if (errnum == LDAP_REFERRAL && refs != NULL && refs[0] != NULL) { - /* Keep old behaviour, overshadow error message */ - char err[1024]; + if (errnum == LDAP_REFERRAL && refs != NULL && refs[0] != NULL) { + /* Keep old behaviour, overshadow error message */ + char err[1024]; - snprintf(err, sizeof(err), "Referral:\n%s", refs[0]); - str = PyUnicode_FromString(err); - PyDict_SetItemString(info, "info", str); - Py_XDECREF(str); + snprintf(err, sizeof(err), "Referral:\n%s", refs[0]); + str = PyUnicode_FromString(err); + if (!str) { + goto cleanup; + } + res = PyDict_SetItemString(info, "info", str); + if (res) { + goto cleanup; + } + Py_CLEAR(str); + } + else if (error != NULL && *error != '\0') { + str = PyUnicode_FromString(error); + if (!str) { + goto cleanup; } - else if (error != NULL && *error != '\0') { - str = PyUnicode_FromString(error); - if (str) - PyDict_SetItemString(info, "info", str); - Py_XDECREF(str); + res = PyDict_SetItemString(info, "info", str); + if (res) { + goto cleanup; } + Py_CLEAR(str); + } - PyErr_SetObject(errobj, info); - Py_DECREF(info); - ldap_memvfree((void **)refs); + PyErr_SetObject(errobj, info); + +cleanup: + if (matched) { + ldap_memfree(matched); + } + if (error) { ldap_memfree(error); - return NULL; } + if (refs) { + ldap_memvfree((void **)refs); + } + if (serverctrls) { + ldap_controls_free(serverctrls); + } + Py_XDECREF(pyresult); + Py_XDECREF(pyerrno); + Py_XDECREF(str); + Py_XDECREF(info); + Py_XDECREF(pyctrls); + return NULL; } PyObject *