[package] opkg: fix a double free of pkg vectors when recursively removing packages...
[openwrt.git] / package / opkg / patches / 020-avoid_getline.patch
1 --- a/libopkg/parse_util.c
2 +++ b/libopkg/parse_util.c
3 @@ -22,6 +22,7 @@
4 #include "libbb/libbb.h"
5
6 #include "parse_util.h"
7 +#include "pkg_parse.h"
8
9 int
10 is_field(const char *type, const char *line)
11 @@ -86,3 +87,84 @@ parse_list(const char *raw, unsigned int
12 *count = line_count;
13 return depends;
14 }
15 +
16 +int
17 +parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
18 + char **buf0, size_t buf0len)
19 +{
20 + int ret, lineno;
21 + char *buf, *nl;
22 + size_t buflen;
23 +
24 + lineno = 1;
25 + ret = 0;
26 +
27 + buflen = buf0len;
28 + buf = *buf0;
29 + buf[0] = '\0';
30 +
31 + while (1) {
32 + if (fgets(buf, (int)buflen, fp) == NULL) {
33 + if (ferror(fp)) {
34 + opkg_perror(ERROR, "fgets");
35 + ret = -1;
36 + } else if (strlen(*buf0) == buf0len-1) {
37 + opkg_msg(ERROR, "Missing new line character"
38 + " at end of file!\n");
39 + parse_line(item, *buf0, mask);
40 + }
41 + break;
42 + }
43 +
44 + nl = strchr(buf, '\n');
45 + if (nl == NULL) {
46 + if (strlen(buf) < buflen-1) {
47 + /*
48 + * Line could be exactly buflen-1 long and
49 + * missing a newline, but we won't know until
50 + * fgets fails to read more data.
51 + */
52 + opkg_msg(ERROR, "Missing new line character"
53 + " at end of file!\n");
54 + parse_line(item, *buf0, mask);
55 + break;
56 + }
57 + if (buf0len >= EXCESSIVE_LINE_LEN) {
58 + opkg_msg(ERROR, "Excessively long line at "
59 + "%d. Corrupt file?\n",
60 + lineno);
61 + ret = -1;
62 + break;
63 + }
64 +
65 + /*
66 + * Realloc and point buf past the data already read,
67 + * at the NULL terminator inserted by fgets.
68 + * |<--------------- buf0len ----------------->|
69 + * | |<------- buflen ---->|
70 + * |---------------------|---------------------|
71 + * buf0 buf
72 + */
73 + buflen = buf0len +1;
74 + buf0len *= 2;
75 + *buf0 = xrealloc(*buf0, buf0len);
76 + buf = *buf0 + buflen -2;
77 +
78 + continue;
79 + }
80 +
81 + *nl = '\0';
82 +
83 + lineno++;
84 +
85 + if (parse_line(item, *buf0, mask))
86 + break;
87 +
88 + buf = *buf0;
89 + buflen = buf0len;
90 + buf[0] = '\0';
91 + }
92 +
93 + return ret;
94 +}
95 +
96 --- a/libopkg/parse_util.h
97 +++ b/libopkg/parse_util.h
98 @@ -22,4 +22,8 @@ int is_field(const char *type, const cha
99 char *parse_simple(const char *type, const char *line);
100 char **parse_list(const char *raw, unsigned int *count, const char sep, int skip_field);
101
102 +typedef int (*parse_line_t)(void *, const char *, uint);
103 +int parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
104 + char **buf0, size_t buf0len);
105 +
106 #endif
107 --- a/libopkg/pkg_hash.c
108 +++ b/libopkg/pkg_hash.c
109 @@ -23,6 +23,7 @@
110 #include "opkg_message.h"
111 #include "pkg_vec.h"
112 #include "pkg_hash.h"
113 +#include "parse_util.h"
114 #include "pkg_parse.h"
115 #include "opkg_utils.h"
116 #include "sprintf_alloc.h"
117 @@ -119,8 +120,14 @@ pkg_hash_add_from_file(const char *file_
118 pkg->src = src;
119 pkg->dest = dest;
120
121 - ret = pkg_parse_from_stream_nomalloc(pkg, fp, 0,
122 + ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, 0,
123 &buf, len);
124 +
125 + if (pkg->name == NULL) {
126 + /* probably just a blank line */
127 + ret = 1;
128 + }
129 +
130 if (ret) {
131 pkg_deinit (pkg);
132 free(pkg);
133 --- a/libopkg/pkg_parse.c
134 +++ b/libopkg/pkg_parse.c
135 @@ -104,9 +104,11 @@ get_arch_priority(const char *arch)
136 return 0;
137 }
138
139 -static int
140 -pkg_parse_line(pkg_t *pkg, const char *line, uint mask)
141 +int
142 +pkg_parse_line(void *ptr, const char *line, uint mask)
143 {
144 + pkg_t *pkg = (pkg_t *) ptr;
145 +
146 /* these flags are a bit hackish... */
147 static int reading_conffiles = 0, reading_description = 0;
148 int ret = 0;
149 @@ -266,91 +268,6 @@ dont_reset_flags:
150 }
151
152 int
153 -pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask,
154 - char **buf0, size_t buf0len)
155 -{
156 - int ret, lineno;
157 - char *buf, *nl;
158 - size_t buflen;
159 -
160 - lineno = 1;
161 - ret = 0;
162 -
163 - buflen = buf0len;
164 - buf = *buf0;
165 - buf[0] = '\0';
166 -
167 - while (1) {
168 - if (fgets(buf, (int)buflen, fp) == NULL) {
169 - if (ferror(fp)) {
170 - opkg_perror(ERROR, "fgets");
171 - ret = -1;
172 - } else if (strlen(*buf0) == buf0len-1) {
173 - opkg_msg(ERROR, "Missing new line character"
174 - " at end of file!\n");
175 - pkg_parse_line(pkg, *buf0, mask);
176 - }
177 - break;
178 - }
179 -
180 - nl = strchr(buf, '\n');
181 - if (nl == NULL) {
182 - if (strlen(buf) < buflen-1) {
183 - /*
184 - * Line could be exactly buflen-1 long and
185 - * missing a newline, but we won't know until
186 - * fgets fails to read more data.
187 - */
188 - opkg_msg(ERROR, "Missing new line character"
189 - " at end of file!\n");
190 - pkg_parse_line(pkg, *buf0, mask);
191 - break;
192 - }
193 - if (buf0len >= EXCESSIVE_LINE_LEN) {
194 - opkg_msg(ERROR, "Excessively long line at "
195 - "%d. Corrupt file?\n",
196 - lineno);
197 - ret = -1;
198 - break;
199 - }
200 -
201 - /*
202 - * Realloc and point buf past the data already read,
203 - * at the NULL terminator inserted by fgets.
204 - * |<--------------- buf0len ----------------->|
205 - * | |<------- buflen ---->|
206 - * |---------------------|---------------------|
207 - * buf0 buf
208 - */
209 - buflen = buf0len +1;
210 - buf0len *= 2;
211 - *buf0 = xrealloc(*buf0, buf0len);
212 - buf = *buf0 + buflen -2;
213 -
214 - continue;
215 - }
216 -
217 - *nl = '\0';
218 -
219 - lineno++;
220 -
221 - if (pkg_parse_line(pkg, *buf0, mask))
222 - break;
223 -
224 - buf = *buf0;
225 - buflen = buf0len;
226 - buf[0] = '\0';
227 - }
228 -
229 - if (pkg->name == NULL) {
230 - /* probably just a blank line */
231 - ret = 1;
232 - }
233 -
234 - return ret;
235 -}
236 -
237 -int
238 pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask)
239 {
240 int ret;
241 @@ -358,8 +275,13 @@ pkg_parse_from_stream(pkg_t *pkg, FILE *
242 const size_t len = 4096;
243
244 buf = xmalloc(len);
245 - ret = pkg_parse_from_stream_nomalloc(pkg, fp, mask, &buf, len);
246 + ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, mask, &buf, len);
247 free(buf);
248
249 + if (pkg->name == NULL) {
250 + /* probably just a blank line */
251 + ret = 1;
252 + }
253 +
254 return ret;
255 }
256 --- a/libopkg/pkg_parse.h
257 +++ b/libopkg/pkg_parse.h
258 @@ -18,10 +18,11 @@
259 #ifndef PKG_PARSE_H
260 #define PKG_PARSE_H
261
262 +#include "pkg.h"
263 +
264 int parse_version(pkg_t *pkg, const char *raw);
265 int pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask);
266 -int pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask,
267 - char **buf0, size_t buf0len);
268 +int pkg_parse_line(void *ptr, const char *line, uint mask);
269
270 #define EXCESSIVE_LINE_LEN (4096 << 8)
271
272 --- a/libopkg/release_parse.c
273 +++ b/libopkg/release_parse.c
274 @@ -23,8 +23,10 @@
275 #include "parse_util.h"
276
277 static int
278 -release_parse_line(release_t *release, const char *line)
279 +release_parse_line(void *ptr, const char *line, uint mask)
280 {
281 + release_t *release = (release_t *) ptr;
282 +
283 int ret = 0;
284 unsigned int count = 0;
285 char **list = 0;
286 @@ -111,25 +113,14 @@ dont_reset_flags:
287 int
288 release_parse_from_stream(release_t *release, FILE *fp)
289 {
290 - int ret = 0;
291 - char *buf = NULL;
292 - size_t buflen, nread;
293 -
294 - nread = getline(&buf, &buflen, fp);
295 - while ( nread != -1 ) {
296 - if (buf[nread-1] == '\n') buf[nread-1] = '\0';
297 - if (release_parse_line(release, buf))
298 - opkg_msg(DEBUG, "Failed to parse release line for %s:\n\t%s\n",
299 - release->name, buf);
300 - nread = getline(&buf, &buflen, fp);
301 - }
302 -
303 - if (!feof(fp)) {
304 - opkg_perror(ERROR, "Problems reading Release file for %sd\n", release->name);
305 - ret = -1;
306 - }
307 + int ret;
308 + char *buf;
309 + const size_t len = 4096;
310
311 + buf = xmalloc(len);
312 + ret = parse_from_stream_nomalloc(release_parse_line, release, fp, 0, &buf, len);
313 free(buf);
314 +
315 return ret;
316 }
317
This page took 0.07639 seconds and 5 git commands to generate.