Skip to content

Commit 7067217

Browse files
committed
Add error handling to Python API calls in LDAPraise_for_message
1 parent 3c0f7ef commit 7067217

File tree

1 file changed

+160
-105
lines changed

1 file changed

+160
-105
lines changed

Modules/constants.c

Lines changed: 160 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -51,138 +51,193 @@ LDAPerr(int errnum)
5151
PyObject *
5252
LDAPraise_for_message(LDAP *l, LDAPMessage *m)
5353
{
54+
int myerrno, errnum, opt_errnum, res, msgid = -1, msgtype = 0;
55+
PyObject *errobj = NULL;
56+
PyObject *info;
57+
PyObject *str = NULL;
58+
PyObject *pyerrno = NULL;
59+
PyObject *pyresult = NULL;
60+
PyObject *pyctrls = NULL;
61+
char *matched = NULL,
62+
*error = NULL,
63+
**refs = NULL;
64+
LDAPControl **serverctrls = NULL;
65+
5466
if (l == NULL) {
5567
PyErr_SetFromErrno(LDAPexception_class);
5668
ldap_msgfree(m);
5769
return NULL;
5870
}
59-
else {
60-
int myerrno, errnum, opt_errnum, msgid = -1, msgtype = 0;
61-
PyObject *errobj;
62-
PyObject *info;
63-
PyObject *str;
64-
PyObject *pyerrno;
65-
PyObject *pyresult;
66-
PyObject *pyctrls = NULL;
67-
char *matched = NULL,
68-
*error = NULL,
69-
**refs = NULL;
70-
LDAPControl **serverctrls = NULL;
71-
72-
/* at first save errno for later use before it gets overwritten by another call */
73-
myerrno = errno;
74-
75-
if (m != NULL) {
76-
msgid = ldap_msgid(m);
77-
msgtype = ldap_msgtype(m);
78-
ldap_parse_result(l, m, &errnum, &matched, &error, &refs,
79-
&serverctrls, 1);
80-
}
8171

82-
if (msgtype <= 0) {
83-
opt_errnum = ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum);
84-
if (opt_errnum != LDAP_OPT_SUCCESS)
85-
errnum = opt_errnum;
72+
/* at first save errno for later use before it gets overwritten by another call */
73+
myerrno = errno;
8674

87-
if (errnum == LDAP_NO_MEMORY) {
88-
return PyErr_NoMemory();
89-
}
75+
if (m != NULL) {
76+
msgid = ldap_msgid(m);
77+
msgtype = ldap_msgtype(m);
78+
ldap_parse_result(l, m, &errnum, &matched, &error, &refs,
79+
&serverctrls, 1);
80+
}
9081

91-
ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched);
92-
ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error);
93-
}
82+
if (msgtype <= 0) {
83+
opt_errnum = ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum);
84+
if (opt_errnum != LDAP_OPT_SUCCESS)
85+
errnum = opt_errnum;
9486

95-
if (errnum >= LDAP_ERROR_MIN && errnum <= LDAP_ERROR_MAX)
96-
errobj = errobjects[errnum + LDAP_ERROR_OFFSET];
97-
else
98-
errobj = LDAPexception_class;
99-
100-
info = PyDict_New();
101-
if (info == NULL) {
102-
ldap_memfree(matched);
103-
ldap_memfree(error);
104-
ldap_memvfree((void **)refs);
105-
ldap_controls_free(serverctrls);
106-
return NULL;
87+
if (errnum == LDAP_NO_MEMORY) {
88+
PyErr_NoMemory();
89+
goto cleanup;
10790
}
10891

109-
if (msgtype > 0) {
110-
pyresult = PyInt_FromLong(msgtype);
111-
if (pyresult)
112-
PyDict_SetItemString(info, "msgtype", pyresult);
113-
Py_XDECREF(pyresult);
114-
}
92+
ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched);
93+
ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error);
94+
}
95+
96+
if (errnum >= LDAP_ERROR_MIN && errnum <= LDAP_ERROR_MAX)
97+
errobj = errobjects[errnum + LDAP_ERROR_OFFSET];
98+
else
99+
errobj = LDAPexception_class;
100+
101+
info = PyDict_New();
102+
if (info == NULL) {
103+
goto cleanup;
104+
}
115105

116-
if (msgid >= 0) {
117-
pyresult = PyInt_FromLong(msgid);
118-
if (pyresult)
119-
PyDict_SetItemString(info, "msgid", pyresult);
120-
Py_XDECREF(pyresult);
106+
if (msgtype > 0) {
107+
pyresult = PyInt_FromLong(msgtype);
108+
if (!pyresult) {
109+
goto cleanup;
110+
}
111+
res = PyDict_SetItemString(info, "msgtype", pyresult);
112+
if (res) {
113+
goto cleanup;
121114
}
115+
Py_CLEAR(pyresult);
116+
}
122117

123-
pyresult = PyInt_FromLong(errnum);
124-
if (pyresult)
125-
PyDict_SetItemString(info, "result", pyresult);
126-
Py_XDECREF(pyresult);
127-
128-
str = PyUnicode_FromString(ldap_err2string(errnum));
129-
if (str)
130-
PyDict_SetItemString(info, "desc", str);
131-
Py_XDECREF(str);
132-
133-
if (myerrno != 0) {
134-
pyerrno = PyInt_FromLong(myerrno);
135-
if (pyerrno)
136-
PyDict_SetItemString(info, "errno", pyerrno);
137-
Py_XDECREF(pyerrno);
118+
if (msgid >= 0) {
119+
pyresult = PyInt_FromLong(msgid);
120+
if (!pyresult) {
121+
goto cleanup;
138122
}
123+
res = PyDict_SetItemString(info, "msgid", pyresult);
124+
if (res) {
125+
goto cleanup;
126+
}
127+
Py_CLEAR(pyresult);
128+
}
139129

140-
if (!(pyctrls = LDAPControls_to_List(serverctrls))) {
141-
int err = LDAP_NO_MEMORY;
130+
pyresult = PyInt_FromLong(errnum);
131+
if (!pyresult) {
132+
goto cleanup;
133+
}
134+
res = PyDict_SetItemString(info, "result", pyresult);
135+
if (res) {
136+
goto cleanup;
137+
}
138+
Py_CLEAR(pyresult);
142139

143-
ldap_set_option(l, LDAP_OPT_ERROR_NUMBER, &err);
144-
ldap_memfree(matched);
145-
ldap_memfree(error);
146-
ldap_memvfree((void **)refs);
147-
ldap_controls_free(serverctrls);
148-
return PyErr_NoMemory();
140+
str = PyUnicode_FromString(ldap_err2string(errnum));
141+
if (!str) {
142+
goto cleanup;
143+
}
144+
res = PyDict_SetItemString(info, "desc", str);
145+
if (res) {
146+
goto cleanup;
147+
}
148+
Py_CLEAR(str);
149+
150+
if (myerrno != 0) {
151+
pyerrno = PyInt_FromLong(myerrno);
152+
if (!pyerrno) {
153+
goto cleanup;
149154
}
150-
ldap_controls_free(serverctrls);
151-
PyDict_SetItemString(info, "ctrls", pyctrls);
152-
Py_XDECREF(pyctrls);
153-
154-
if (matched != NULL) {
155-
if (*matched != '\0') {
156-
str = PyUnicode_FromString(matched);
157-
if (str)
158-
PyDict_SetItemString(info, "matched", str);
159-
Py_XDECREF(str);
155+
res = PyDict_SetItemString(info, "errno", pyerrno);
156+
if (res) {
157+
goto cleanup;
158+
}
159+
Py_CLEAR(pyerrno);
160+
}
161+
162+
if (!(pyctrls = LDAPControls_to_List(serverctrls))) {
163+
int err = LDAP_NO_MEMORY;
164+
ldap_set_option(l, LDAP_OPT_ERROR_NUMBER, &err);
165+
166+
PyErr_NoMemory();
167+
goto cleanup;
168+
}
169+
ldap_controls_free(serverctrls);
170+
serverctrls = NULL;
171+
res = PyDict_SetItemString(info, "ctrls", pyctrls);
172+
if (res) {
173+
goto cleanup;
174+
}
175+
Py_CLEAR(pyctrls);
176+
177+
if (matched != NULL) {
178+
if (*matched != '\0') {
179+
str = PyUnicode_FromString(matched);
180+
if (!str) {
181+
goto cleanup;
182+
}
183+
res = PyDict_SetItemString(info, "matched", str);
184+
if (res) {
185+
goto cleanup;
160186
}
161-
ldap_memfree(matched);
187+
Py_CLEAR(str);
162188
}
189+
ldap_memfree(matched);
190+
matched = NULL;
191+
}
163192

164-
if (errnum == LDAP_REFERRAL && refs != NULL && refs[0] != NULL) {
165-
/* Keep old behaviour, overshadow error message */
166-
char err[1024];
193+
if (errnum == LDAP_REFERRAL && refs != NULL && refs[0] != NULL) {
194+
/* Keep old behaviour, overshadow error message */
195+
char err[1024];
167196

168-
snprintf(err, sizeof(err), "Referral:\n%s", refs[0]);
169-
str = PyUnicode_FromString(err);
170-
PyDict_SetItemString(info, "info", str);
171-
Py_XDECREF(str);
197+
snprintf(err, sizeof(err), "Referral:\n%s", refs[0]);
198+
str = PyUnicode_FromString(err);
199+
if (!str) {
200+
goto cleanup;
201+
}
202+
res = PyDict_SetItemString(info, "info", str);
203+
if (res) {
204+
goto cleanup;
205+
}
206+
Py_CLEAR(str);
207+
}
208+
else if (error != NULL && *error != '\0') {
209+
str = PyUnicode_FromString(error);
210+
if (!str) {
211+
goto cleanup;
172212
}
173-
else if (error != NULL && *error != '\0') {
174-
str = PyUnicode_FromString(error);
175-
if (str)
176-
PyDict_SetItemString(info, "info", str);
177-
Py_XDECREF(str);
213+
res = PyDict_SetItemString(info, "info", str);
214+
if (res) {
215+
goto cleanup;
178216
}
217+
Py_CLEAR(str);
218+
}
179219

180-
PyErr_SetObject(errobj, info);
181-
Py_DECREF(info);
182-
ldap_memvfree((void **)refs);
220+
PyErr_SetObject(errobj, info);
221+
222+
cleanup:
223+
if (matched) {
224+
ldap_memfree(matched);
225+
}
226+
if (error) {
183227
ldap_memfree(error);
184-
return NULL;
185228
}
229+
if (refs) {
230+
ldap_memvfree((void **)refs);
231+
}
232+
if (serverctrls) {
233+
ldap_controls_free(serverctrls);
234+
}
235+
Py_XDECREF(pyresult);
236+
Py_XDECREF(pyerrno);
237+
Py_XDECREF(str);
238+
Py_XDECREF(info);
239+
Py_XDECREF(errobj);
240+
return NULL;
186241
}
187242

188243
PyObject *

0 commit comments

Comments
 (0)