]> git.sur5r.net Git - openldap/blob - libraries/libldap/charray.c
Do not overwrite charray argument if charray_add realloc fails.
[openldap] / libraries / libldap / charray.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /* charray.c - routines for dealing with char * arrays */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/string.h>
12 #include <ac/socket.h>
13
14 #include "ldap-int.h"
15
16 int
17 ldap_charray_add(
18     char        ***a,
19     char        *s
20 )
21 {
22         int     n;
23
24         if ( *a == NULL ) {
25                 *a = (char **) LDAP_MALLOC( 2 * sizeof(char *) );
26                 n = 0;
27
28                 if( *a == NULL ) {
29                         return -1;
30                 }
31
32         } else {
33                 char **new;
34
35                 for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
36                         ;       /* NULL */
37                 }
38
39                 new = (char **) LDAP_REALLOC( (char *) *a,
40                     (n + 2) * sizeof(char *) );
41
42                 if( new == NULL ) {
43                         /* caller is required to call ldap_charray_free(*a) */
44                         return -1;
45                 }
46
47                 *a = new;
48         }
49
50         (*a)[n] = LDAP_STRDUP(s);
51
52         if( (*a)[n] == NULL ) {
53                 return 1;
54         }
55
56         (*a)[++n] = NULL;
57
58         return 0;
59 }
60
61 int
62 ldap_charray_merge(
63     char        ***a,
64     char        **s
65 )
66 {
67         int     i, n, nn;
68         char **aa;
69
70         for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
71                 ;       /* NULL */
72         }
73         for ( nn = 0; s[nn] != NULL; nn++ ) {
74                 ;       /* NULL */
75         }
76
77         aa = (char **) LDAP_REALLOC( (char *) *a, (n + nn + 1) * sizeof(char *) );
78
79         if( aa == NULL )
80                 return -1;
81
82         *a = aa;
83
84         for ( i = 0; i < nn; i++ ) {
85                 (*a)[n + i] = LDAP_STRDUP(s[i]);
86
87                 if( (*a)[n + i] == NULL ) {
88                         for( --i ; i >= 0 ; i-- ) {
89                                 LDAP_FREE( (*a)[n + i] );
90                                 (*a)[n + i] = NULL;
91                         }
92                         return -1;
93                 }
94         }
95
96         (*a)[n + nn] = NULL;
97         return 0;
98 }
99
100 void
101 ldap_charray_free( char **a )
102 {
103         char    **p;
104
105         if ( a == NULL ) {
106                 return;
107         }
108
109         for ( p = a; *p != NULL; p++ ) {
110                 if ( *p != NULL ) {
111                         LDAP_FREE( *p );
112                 }
113         }
114
115         LDAP_FREE( (char *) a );
116 }
117
118 int
119 ldap_charray_inlist(
120     char        **a,
121     char        *s
122 )
123 {
124         int     i;
125
126         for ( i = 0; a[i] != NULL; i++ ) {
127                 if ( strcasecmp( s, a[i] ) == 0 ) {
128                         return( 1 );
129                 }
130         }
131
132         return( 0 );
133 }
134
135 char **
136 ldap_charray_dup( char **a )
137 {
138         int     i;
139         char    **new;
140
141         for ( i = 0; a[i] != NULL; i++ )
142                 ;       /* NULL */
143
144         new = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
145
146         if( new == NULL ) {
147                 return NULL;
148         }
149
150         for ( i = 0; a[i] != NULL; i++ ) {
151                 new[i] = LDAP_STRDUP( a[i] );
152
153                 if( new[i] == NULL ) {
154                         for( --i ; i >= 0 ; i-- ) {
155                                 LDAP_FREE( new[i] );
156                         }
157                         LDAP_FREE( new );
158                         return NULL;
159                 }
160         }
161         new[i] = NULL;
162
163         return( new );
164 }
165
166 char **
167 ldap_str2charray( char *str, char *brkstr )
168 {
169         char    **res;
170         char    *s;
171         char    *lasts;
172         int     i;
173
174         /* protect the input string from strtok */
175         str = LDAP_STRDUP( str );
176         if( str == NULL ) {
177                 return NULL;
178         }
179
180         i = 1;
181         for ( s = str; *s; s++ ) {
182                 if ( strchr( brkstr, *s ) != NULL ) {
183                         i++;
184                 }
185         }
186
187         res = (char **) LDAP_MALLOC( (i + 1) * sizeof(char *) );
188
189         if( res == NULL ) {
190                 LDAP_FREE( str );
191                 return NULL;
192         }
193
194         i = 0;
195
196         for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
197                 s != NULL;
198                 s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
199         {
200                 res[i] = LDAP_STRDUP( s );
201
202                 if(res[i] == NULL) {
203                         for( --i ; i >= 0 ; i-- ) {
204                                 LDAP_FREE( res[i] );
205                         }
206                         LDAP_FREE( res );
207                         LDAP_FREE( str );
208                         return NULL;
209                 }
210
211                 i++;
212         }
213
214         res[i] = NULL;
215
216         LDAP_FREE( str );
217         return( res );
218 }