Bug Summary

File:src/util.c
Warning:line 382, column 16
Potential leak of memory pointed to by 'r'

Annotated Source Code

1/*
2 * Copyright (c) 2007, Novell Inc.
3 *
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
6 */
7
8#define _GNU_SOURCE
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <string.h>
14#include <sys/time.h>
15
16#include "util.h"
17
18void
19solv_oom(size_t num, size_t len)
20{
21 if (num)
22 fprintf(stderrstderr, "Out of memory allocating %zu*%zu bytes!\n", num, len);
23 else
24 fprintf(stderrstderr, "Out of memory allocating %zu bytes!\n", len);
25 abort();
26 exit(1);
27}
28
29void *
30solv_malloc(size_t len)
31{
32 void *r = malloc(len ? len : 1);
18
Assuming 'len' is 0
19
'?' condition is false
20
Memory is allocated
33 if (!r)
21
Assuming 'r' is non-null
22
Taking false branch
34 solv_oom(0, len);
35 return r;
36}
37
38void *
39solv_malloc2(size_t num, size_t len)
40{
41 if (len && (num * len) / len != num)
42 solv_oom(num, len);
43 return solv_malloc(num * len);
44}
45
46void *
47solv_realloc(void *old, size_t len)
48{
49 if (old == 0)
50 old = malloc(len ? len : 1);
51 else
52 old = realloc(old, len ? len : 1);
53 if (!old)
54 solv_oom(0, len);
55 return old;
56}
57
58void *
59solv_realloc2(void *old, size_t num, size_t len)
60{
61 if (len && (num * len) / len != num)
62 solv_oom(num, len);
63 return solv_realloc(old, num * len);
64}
65
66void *
67solv_calloc(size_t num, size_t len)
68{
69 void *r;
70 if (num == 0 || len == 0)
71 r = malloc(1);
72 else
73 r = calloc(num, len);
74 if (!r)
75 solv_oom(num, len);
76 return r;
77}
78
79/* this was solv_realloc2(old, len, size), but we now overshoot
80 * for huge len sizes */
81void *
82solv_extend_realloc(void *old, size_t len, size_t size, size_t block)
83{
84 size_t xblock = (block + 1) << 5;
85 len = (len + block) & ~block;
86 if (len >= xblock && xblock)
87 {
88 xblock <<= 1;
89 while (len >= xblock && xblock)
90 xblock <<= 1;
91 if (xblock)
92 {
93 size_t nlen;
94 xblock = (xblock >> 5) - 1;
95 nlen = (len + xblock) & ~xblock;
96 if (nlen > len)
97 len = nlen;
98 }
99 }
100 return solv_realloc2(old, len, size);
101}
102
103void *
104solv_free(void *mem)
105{
106 if (mem)
107 free(mem);
108 return 0;
109}
110
111char *
112solv_strdup(const char *s)
113{
114 char *r;
115 if (!s)
116 return 0;
117 r = strdup(s);
118 if (!r)
119 solv_oom(0, strlen(s));
120 return r;
121}
122
123unsigned int
124solv_timems(unsigned int subtract)
125{
126 struct timeval tv;
127 unsigned int r;
128
129 if (gettimeofday(&tv, 0))
130 return 0;
131 r = (((unsigned int)tv.tv_sec >> 16) * 1000) << 16;
132 r += ((unsigned int)tv.tv_sec & 0xffff) * 1000;
133 r += (unsigned int)tv.tv_usec / 1000;
134 return r - subtract;
135}
136
137/* bsd's qsort_r has different arguments, so we define our
138 own version in case we need to do some clever mapping
139
140 see also: http://sources.redhat.com/ml/libc-alpha/2008-12/msg00003.html
141 */
142#if (defined(__GLIBC__2) || defined(__NEWLIB__)) && (defined(HAVE_QSORT_R1) || defined(HAVE___QSORT_R))
143
144void
145solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
146{
147# if defined(HAVE_QSORT_R1)
148 qsort_r(base, nmemb, size, compar, compard);
149# else
150 /* backported for SLE10-SP2 */
151 __qsort_r(base, nmemb, size, compar, compard);
152# endif
153
154}
155
156#elif defined(HAVE_QSORT_R1) /* not glibc, but has qsort_r() */
157
158struct solv_sort_data {
159 int (*compar)(const void *, const void *, void *);
160 void *compard;
161};
162
163static int
164solv_sort_helper(void *compard, const void *a, const void *b)
165{
166 struct solv_sort_data *d = compard;
167 return (*d->compar)(a, b, d->compard);
168}
169
170void
171solv_sort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *compard)
172{
173 struct solv_sort_data d;
174 d.compar = compar;
175 d.compard = compard;
176 qsort_r(base, nmemb, size, &d, solv_sort_helper);
177}
178
179#else /* not glibc and no qsort_r() */
180/* use own version of qsort if none available */
181#include "qsort_r.c"
182#endif
183
184char *
185solv_dupjoin(const char *str1, const char *str2, const char *str3)
186{
187 int l1, l2, l3;
188 char *s, *str;
189 l1 = str1 ? strlen(str1) : 0;
190 l2 = str2 ? strlen(str2) : 0;
191 l3 = str3 ? strlen(str3) : 0;
192 s = str = solv_malloc(l1 + l2 + l3 + 1);
193 if (l1)
194 {
195 strcpy(s, str1);
196 s += l1;
197 }
198 if (l2)
199 {
200 strcpy(s, str2);
201 s += l2;
202 }
203 if (l3)
204 {
205 strcpy(s, str3);
206 s += l3;
207 }
208 *s = 0;
209 return str;
210}
211
212char *
213solv_dupappend(const char *str1, const char *str2, const char *str3)
214{
215 char *str = solv_dupjoin(str1, str2, str3);
216 solv_free((void *)str1);
217 return str;
218}
219
220int
221solv_hex2bin(const char **strp, unsigned char *buf, int bufl)
222{
223 const char *str = *strp;
224 int i;
225
226 for (i = 0; i < bufl; i++)
227 {
228 int c = *str;
229 int d;
230 if (c >= '0' && c <= '9')
231 d = c - '0';
232 else if (c >= 'a' && c <= 'f')
233 d = c - ('a' - 10);
234 else if (c >= 'A' && c <= 'F')
235 d = c - ('A' - 10);
236 else
237 break;
238 c = str[1];
239 d <<= 4;
240 if (c >= '0' && c <= '9')
241 d |= c - '0';
242 else if (c >= 'a' && c <= 'f')
243 d |= c - ('a' - 10);
244 else if (c >= 'A' && c <= 'F')
245 d |= c - ('A' - 10);
246 else
247 break;
248 buf[i] = d;
249 str += 2;
250 }
251 *strp = str;
252 return i;
253}
254
255char *
256solv_bin2hex(const unsigned char *buf, int l, char *str)
257{
258 int i;
259 for (i = 0; i < l; i++, buf++)
260 {
261 int c = *buf >> 4;
262 *str++ = c < 10 ? c + '0' : c + ('a' - 10);
263 c = *buf & 15;
264 *str++ = c < 10 ? c + '0' : c + ('a' - 10);
265 }
266 *str = 0;
267 return str;
268}
269
270size_t
271solv_validutf8(const char *buf)
272{
273 const unsigned char *p;
274 int x;
275
276 for (p = (const unsigned char *)buf; (x = *p) != 0; p++)
277 {
278 if (x < 0x80)
279 continue;
280 if (x < 0xc0)
281 break;
282 if (x < 0xe0)
283 {
284 /* one byte to follow */
285 if ((p[1] & 0xc0) != 0x80)
286 break;
287 if ((x & 0x1e) == 0)
288 break; /* not minimal */
289 p += 1;
290 continue;
291 }
292 if (x < 0xf0)
293 {
294 /* two bytes to follow */
295 if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80)
296 break;
297 if ((x & 0x0f) == 0 && (p[1] & 0x20) == 0)
298 break; /* not minimal */
299 if (x == 0xed && (p[1] & 0x20) != 0)
300 break; /* d800-dfff surrogate */
301 if (x == 0xef && p[1] == 0xbf && (p[2] == 0xbe || p[2] == 0xbf))
302 break; /* fffe or ffff */
303 p += 2;
304 continue;
305 }
306 if (x < 0xf8)
307 {
308 /* three bytes to follow */
309 if ((p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80)
310 break;
311 if ((x & 0x07) == 0 && (p[1] & 0x30) == 0)
312 break; /* not minimal */
313 if ((x & 0x07) > 4 || ((x & 0x07) == 4 && (p[1] & 0x30) != 0))
314 break; /* above 0x10ffff */
315 p += 3;
316 continue;
317 }
318 break; /* maybe valid utf8, but above 0x10ffff */
319 }
320 return (const char *)p - buf;
321}
322
323char *
324solv_latin1toutf8(const char *buf)
325{
326 int l = 1;
327 const char *p;
328 char *r, *rp;
329
330 for (p = buf; *p; p++)
331 if ((*(const unsigned char *)p & 128) != 0)
332 l++;
333 r = rp = solv_malloc(p - buf + l);
334 for (p = buf; *p; p++)
335 {
336 if ((*(const unsigned char *)p & 128) != 0)
337 {
338 *rp++ = *(const unsigned char *)p & 64 ? 0xc3 : 0xc2;
339 *rp++ = *p & 0xbf;
340 }
341 else
342 *rp++ = *p;
343 }
344 *rp = 0;
345 return r;
346}
347
348char *
349solv_replacebadutf8(const char *buf, int replchar)
350{
351 size_t l, nl;
352 const char *p;
353 char *r = 0, *rp = 0;
354 int repllen, replin;
355
356 if (replchar < 0 || replchar > 0x10ffff)
1
Assuming 'replchar' is >= 0
2
Assuming 'replchar' is <= 1114111
3
Taking false branch
357 replchar = 0xfffd;
358 if (!replchar)
4
Assuming 'replchar' is not equal to 0
5
Taking false branch
359 repllen = replin = 0;
360 else if (replchar < 0x80)
6
Assuming 'replchar' is >= 128
7
Taking false branch
361 {
362 repllen = 1;
363 replin = (replchar & 0x40) | 0x80;
364 }
365 else if (replchar < 0x800)
8
Assuming 'replchar' is >= 2048
9
Taking false branch
366 {
367 repllen = 2;
368 replin = 0x40;
369 }
370 else if (replchar < 0x10000)
10
Assuming 'replchar' is >= 65536
11
Taking false branch
371 {
372 repllen = 3;
373 replin = 0x60;
374 }
375 else
376 {
377 repllen = 4;
378 replin = 0x70;
379 }
380 for (;;)
12
Loop condition is true. Entering loop body
24
Loop condition is true. Entering loop body
43
Loop condition is true. Entering loop body
381 {
382 for (p = buf, nl = 0; *p; )
13
Loop condition is true. Entering loop body
25
Loop condition is true. Entering loop body
35
Loop condition is true. Entering loop body
44
Potential leak of memory pointed to by 'r'
383 {
384 l = solv_validutf8(p);
385 if (rp && l)
26
Assuming 'l' is not equal to 0
27
Taking true branch
36
Assuming 'l' is not equal to 0
37
Taking true branch
386 {
387 memcpy(rp, p, l);
388 rp += l;
389 }
390 nl += l;
391 p += l;
392 if (!*p)
14
Taking true branch
28
Taking false branch
38
Assuming the condition is true
39
Taking true branch
393 break;
15
Execution continues on line 415
40
Execution continues on line 415
394 /* found a bad char, replace with replchar */
395 if (rp && replchar)
29
Taking true branch
396 {
397 switch (repllen)
30
Control jumps to 'case 4:' at line 399
398 {
399 case 4:
400 *rp++ = (replchar >> 18 & 0x3f) | 0x80;
401 case 3:
402 *rp++ = (replchar >> 12 & 0x3f) | 0x80;
403 case 2:
404 *rp++ = (replchar >> 6 & 0x3f) | 0x80;
405 default:
406 *rp++ = (replchar & 0x3f) | 0x80;
407 }
408 rp[-repllen] ^= replin;
409 }
410 nl += repllen;
411 p++;
412 while ((*(const unsigned char *)p & 0xc0) == 0x80)
31
Loop condition is true. Entering loop body
32
Loop condition is true. Entering loop body
33
Loop condition is true. Entering loop body
34
Loop condition is false. Execution continues on line 382
413 p++;
414 }
415 if (rp)
16
Taking false branch
41
Assuming 'rp' is null
42
Taking false branch
416 break;
417 r = rp = solv_malloc(nl + 1);
17
Calling 'solv_malloc'
23
Returned allocated memory
418 }
419 *rp = 0;
420 return r;
421}
422