/[gentoo-projects]/pax-utils/xfuncs.c
Gentoo

Contents of /pax-utils/xfuncs.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (show annotations) (download) (as text)
Thu Mar 20 07:52:07 2014 UTC (8 months, 1 week ago) by vapier
Branch: MAIN
CVS Tags: HEAD
Changes since 1.11: +6 -2 lines
File MIME type: text/x-csrc
fix possible memory read errors when walking arrays

the current code will always fetch the arr->eles[n] in array_for_each before doing the n < arr->num check.  gcc might optimize it such that the read occurs rather than delaying it until after the loop limit check, but it also might not.  at any rate, ASAN catches it and complains mightly.  this new method ends up wasting 1 pointer worth of memory, but we wont worry about 4 or 8 bytes per array as this code is not that critical.

1 /*
2 * Copyright 2003-2012 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/xfuncs.c,v 1.11 2012/11/04 07:26:24 vapier Exp $
5 *
6 * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org>
8 */
9
10 #include "paxinc.h"
11
12 char *xstrdup(const char *s)
13 {
14 char *ret = strdup(s);
15 if (!ret) err("Could not strdup(): %s", strerror(errno));
16 return ret;
17 }
18
19 void *xmalloc(size_t size)
20 {
21 void *ret = malloc(size);
22 if (!ret) err("Could not malloc() %zu bytes", size);
23 return ret;
24 }
25
26 void *xzalloc(size_t size)
27 {
28 return memset(xmalloc(size), 0, size);
29 }
30
31 void *xrealloc(void *ptr, size_t size)
32 {
33 void *ret = realloc(ptr, size);
34 if (!ret) err("Could not realloc() %zu bytes", size);
35 return ret;
36 }
37
38 void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n)
39 {
40 bool init;
41 size_t new_len;
42
43 init = *curr_len ? false : true;
44 new_len = (init ? 0 : strlen(*dst)) + strlen(src);
45 if (*curr_len <= new_len) {
46 *curr_len = new_len + (*curr_len / 2) + 1;
47 *dst = realloc(*dst, *curr_len);
48 if (!*dst)
49 err("could not realloc() %zu bytes", *curr_len);
50 if (init)
51 *dst[0] = '\0';
52 }
53
54 if (n)
55 strncat(*dst, src, n);
56 else
57 strcat(*dst, src);
58 }
59
60 void xchrcat(char **dst, const char append, size_t *curr_len)
61 {
62 static char my_app[2];
63 my_app[0] = append;
64 my_app[1] = '\0';
65 xstrcat(dst, my_app, curr_len);
66 }
67
68 void *xmemdup(const void *src, size_t n)
69 {
70 void *ret = xmalloc(n);
71 memcpy(ret, src, n);
72 return ret;
73 }
74
75 void xarraypush(array_t *arr, const void *ele, size_t ele_len)
76 {
77 size_t n = arr->num++;
78 /* We allocate one excess element so that array_for_each can
79 * always safely fetch the next element. It's minor memory
80 * wastage to avoid having to do a len check all the time.
81 */
82 arr->eles = xrealloc_array(arr->eles, arr->num + 1, sizeof(ele));
83 arr->eles[n] = xmemdup(ele, ele_len);
84 }
85
86 void xarrayfree(array_t *arr)
87 {
88 array_t blank = array_init_decl;
89 size_t n;
90
91 for (n = 0; n < arr->num; ++n)
92 free(arr->eles[n]);
93 free(arr->eles);
94
95 *arr = blank;
96 }
97
98 char *array_flatten_str(array_t *array)
99 {
100 size_t n, len = 0;
101 char *str, *ret = NULL;
102
103 array_for_each(array, n, str) {
104 if (ret)
105 xchrcat(&ret, ',', &len);
106 xstrcat(&ret, str, &len);
107 }
108
109 return ret;
110 }

  ViewVC Help
Powered by ViewVC 1.1.20