Skip to content

Commit cebabb1

Browse files
authored
Merge pull request #5159 from chu11/issue5158_memleak_libioencode
libioencode: fix memleaks on error paths
2 parents 756a030 + a949f58 commit cebabb1

File tree

2 files changed

+39
-34
lines changed

2 files changed

+39
-34
lines changed

src/common/libioencode/ioencode.c

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
#include <jansson.h>
2121

22-
#include "src/common/libutil/macros.h"
2322
#include "src/common/libccan/ccan/base64/base64.h"
23+
#include "src/common/libutil/errno_safe.h"
2424

2525
#include "ioencode.h"
2626

@@ -37,13 +37,14 @@ static json_t *data_encode_base64 (const char *stream,
3737

3838
if ((dest = malloc (destlen))
3939
&& (n = base64_encode (dest, destlen, data, len)) >= 0) {
40-
o = json_pack ("{s:s s:s s:s s:s#}",
41-
"stream", stream,
42-
"rank", rank,
43-
"encoding", "base64",
44-
"data", dest, n);
40+
if (!(o = json_pack ("{s:s s:s s:s s:s#}",
41+
"stream", stream,
42+
"rank", rank,
43+
"encoding", "base64",
44+
"data", dest, n)))
45+
errno = ENOMEM;
4546
}
46-
free (dest);
47+
ERRNO_SAFE_WRAP (free, dest);
4748
return o;
4849
}
4950

@@ -54,7 +55,6 @@ json_t *ioencode (const char *stream,
5455
bool eof)
5556
{
5657
json_t *o = NULL;
57-
json_t *rv = NULL;
5858

5959
/* data can be NULL and len == 0 if eof true */
6060
if (!stream
@@ -77,22 +77,25 @@ json_t *ioencode (const char *stream,
7777
* encoding the data in base64:
7878
*/
7979
if (!(o = data_encode_base64 (stream, rank, data, len)))
80-
goto error;
80+
return NULL;
8181
}
8282
}
8383
else {
8484
if (!(o = json_pack ("{s:s s:s}",
8585
"stream", stream,
86-
"rank", rank)))
87-
goto error;
86+
"rank", rank))) {
87+
errno = ENOMEM;
88+
return NULL;
89+
}
8890
}
8991
if (eof) {
90-
if (json_object_set_new (o, "eof", json_true ()) < 0)
91-
goto error;
92+
if (json_object_set_new (o, "eof", json_true ()) < 0) {
93+
json_decref (o);
94+
errno = ENOMEM;
95+
return NULL;
96+
}
9297
}
93-
rv = o;
94-
error:
95-
return rv;
98+
return o;
9699
}
97100

98101
static int decode_data_base64 (char *src,
@@ -105,8 +108,10 @@ static int decode_data_base64 (char *src,
105108
if (datap) {
106109
if (!(*datap = malloc (size)))
107110
return -1;
108-
if ((rc = base64_decode (*datap, size, src, srclen)) < 0)
111+
if ((rc = base64_decode (*datap, size, src, srclen)) < 0) {
112+
ERRNO_SAFE_WRAP (free, (*datap));
109113
return -1;
114+
}
110115
if (lenp)
111116
*lenp = rc;
112117
}
@@ -127,12 +132,12 @@ int iodecode (json_t *o,
127132
const char *rank;
128133
const char *encoding = NULL;
129134
size_t bin_len = 0;
135+
char *bufp = NULL;
130136
char *data = NULL;
131137
size_t len = 0;
132138
int eof = 0;
133139
bool has_data = false;
134140
bool has_eof = false;
135-
int rv = -1;
136141

137142
if (!o) {
138143
errno = EINVAL;
@@ -142,49 +147,47 @@ int iodecode (json_t *o,
142147
if (json_unpack (o, "{s:s s:s s?s}",
143148
"stream", &stream,
144149
"rank", &rank,
145-
"encoding", &encoding) < 0)
146-
goto cleanup;
147-
if (json_unpack (o, "{s:s%}", "data", &data, &len) == 0) {
148-
has_data = true;
150+
"encoding", &encoding) < 0) {
151+
errno = EPROTO;
152+
return -1;
149153
}
154+
if (json_unpack (o, "{s:s%}", "data", &data, &len) == 0)
155+
has_data = true;
150156
if (json_unpack (o, "{s:b}", "eof", &eof) == 0)
151157
has_eof = true;
152158

153159
if (!has_data && !has_eof) {
154160
errno = EPROTO;
155-
goto cleanup;
161+
return -1;
156162
}
157163

158164
if (streamp)
159165
(*streamp) = stream;
160166
if (rankp)
161167
(*rankp) = rank;
162168
if (datap || lenp) {
163-
if (datap)
164-
*datap = NULL;
165169
if (data) {
166170
if (encoding && strcmp (encoding, "base64") == 0) {
167-
if (decode_data_base64 (data, len, datap, &bin_len) < 0)
168-
goto cleanup;
171+
if (decode_data_base64 (data, len, &bufp, &bin_len) < 0)
172+
return -1;
169173
}
170174
else {
171175
bin_len = len;
172176
if (datap) {
173-
if (!(*datap = malloc (bin_len)))
174-
goto cleanup;
175-
memcpy (*datap, data, bin_len);
177+
if (!(bufp = malloc (bin_len)))
178+
return -1;
179+
memcpy (bufp, data, bin_len);
176180
}
177181
}
178182
}
179183
}
184+
if (datap)
185+
(*datap) = bufp;
180186
if (lenp)
181187
(*lenp) = bin_len;
182188
if (eofp)
183189
(*eofp) = eof;
184-
185-
rv = 0;
186-
cleanup:
187-
return rv;
190+
return 0;
188191
}
189192

190193
/*

src/common/libioencode/ioencode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
/* encode io data and/or EOF into RFC24 data event object
1818
* - to set only EOF, set data to NULL and data_len to 0
1919
* - it is an error to provide no data and EOF = false
20+
* - returns RFC24 object on success, NULL on error with errno set
2021
* - returned object should be json_decref()'d after use
2122
*/
2223
json_t *ioencode (const char *stream,
@@ -30,6 +31,7 @@ json_t *ioencode (const char *stream,
3031
* - if no data available, data set to NULL and len to 0
3132
* - data must be freed after return
3233
* - data can be NULL and len non-NULL to retrieve data length
34+
* - returns 0 on success, -1 on error with errno set
3335
*/
3436
int iodecode (json_t *o,
3537
const char **stream,

0 commit comments

Comments
 (0)