~ubuntu-branches/ubuntu/maverick/openldap/maverick-proposed

« back to all changes in this revision

Viewing changes to libraries/liblber/decode.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2009-09-07 13:41:10 UTC
  • mto: This revision was merged to the branch mainline in revision 19.
  • Revision ID: james.westby@ubuntu.com-20090907134110-jsdrvn0atu1fex4m
Tags: upstream-2.4.18
ImportĀ upstreamĀ versionĀ 2.4.18

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* decode.c - ber input decoding routines */
2
 
/* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.105.2.6 2009/01/22 00:00:53 kurt Exp $ */
 
2
/* $OpenLDAP: pkg/ldap/libraries/liblber/decode.c,v 1.105.2.8 2009/08/13 00:56:58 quanah Exp $ */
3
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
4
 *
5
5
 * Copyright 1998-2009 The OpenLDAP Foundation.
33
33
#include <stdio.h>
34
34
 
35
35
#include <ac/stdlib.h>
36
 
 
37
36
#include <ac/stdarg.h>
38
37
#include <ac/string.h>
39
38
#include <ac/socket.h>
40
39
 
41
40
#include "lber-int.h"
42
41
 
43
 
static ber_len_t ber_getnint LDAP_P((
44
 
        BerElement *ber,
45
 
        ber_int_t *num,
46
 
        ber_len_t len ));
47
42
 
48
43
/* out->bv_len should be the buffer size on input */
49
44
int
91
86
        return 0;
92
87
}
93
88
 
94
 
/* return the tag - LBER_DEFAULT returned means trouble */
95
 
ber_tag_t
96
 
ber_get_tag( BerElement *ber )
 
89
/* Return tag, with *bv = rest of element (starting at length octets) */
 
90
static ber_tag_t
 
91
ber_tag_and_rest( const BerElement *ber, struct berval *bv )
97
92
{
98
 
        unsigned char   xbyte;
99
93
        ber_tag_t       tag;
100
 
        unsigned int    i;
 
94
        ptrdiff_t       rest;
 
95
        unsigned char   *ptr;
101
96
 
102
97
        assert( ber != NULL );
103
98
        assert( LBER_VALID( ber ) );
104
99
 
105
 
        if ( ber_pvt_ber_remaining( ber ) < 1 ) {
106
 
                return LBER_DEFAULT;
107
 
        }
108
 
 
109
 
        if ( ber->ber_ptr == ber->ber_buf ) {
110
 
                tag = *(unsigned char *)ber->ber_ptr;
111
 
        } else {
112
 
                tag = ber->ber_tag;
113
 
        }
114
 
        ber->ber_ptr++;
115
 
 
 
100
        ptr = (unsigned char *) ber->ber_ptr;
 
101
        rest = (unsigned char *) ber->ber_end - ptr;
 
102
        if ( rest <= 0 ) {
 
103
                goto fail;
 
104
        }
 
105
 
 
106
        tag = ber->ber_tag;
 
107
        if ( (char *) ptr == ber->ber_buf ) {
 
108
                tag = *ptr;
 
109
        }
 
110
        ptr++;
 
111
        rest--;
116
112
        if ( (tag & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK ) {
117
 
                return tag;
 
113
                goto done;
118
114
        }
119
115
 
120
 
        for ( i = 1; i < sizeof(ber_tag_t); i++ ) {
121
 
                if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 ) {
122
 
                        return LBER_DEFAULT;
 
116
        do {
 
117
                if ( rest <= 0 ) {
 
118
                        break;
123
119
                }
124
 
 
125
120
                tag <<= 8;
126
 
                tag |= 0x00ffUL & (ber_tag_t) xbyte;
 
121
                tag |= *ptr++ & 0xffU;
 
122
                rest--;
127
123
 
128
 
                if ( ! (xbyte & LBER_MORE_TAG_MASK) ) {
129
 
                        break;
 
124
                if ( ! (tag & LBER_MORE_TAG_MASK) ) {
 
125
                        goto done;
130
126
                }
131
 
        }
132
 
 
133
 
        /* tag too big! */
134
 
        if ( i == sizeof(ber_tag_t) ) {
135
 
                return LBER_DEFAULT;
136
 
        }
137
 
 
138
 
        return tag;
139
 
}
140
 
 
141
 
ber_tag_t
142
 
ber_skip_tag( BerElement *ber, ber_len_t *len )
 
127
        } while ( tag <= (ber_tag_t)-1 / 256 );
 
128
 
 
129
 fail:
 
130
        /* Error or unsupported tag size */
 
131
        tag = LBER_DEFAULT;
 
132
 
 
133
 done:
 
134
        bv->bv_len = rest;
 
135
        bv->bv_val = (char *) ptr;
 
136
        return tag;
 
137
}
 
138
 
 
139
/* Return the tag - LBER_DEFAULT returned means trouble */
 
140
ber_tag_t
 
141
ber_get_tag( BerElement *ber )
 
142
{
 
143
        struct berval bv;
 
144
        ber_tag_t tag = ber_tag_and_rest( ber, &bv );
 
145
 
 
146
        ber->ber_ptr = bv.bv_val;
 
147
        return tag;
 
148
}
 
149
 
 
150
/* Return next element's tag and point *bv at its contents in-place */
 
151
ber_tag_t
 
152
ber_peek_element( const BerElement *ber, struct berval *bv )
143
153
{
144
154
        ber_tag_t       tag;
145
 
        unsigned char   lc;
146
 
        ber_len_t       i, noctets;
147
 
        unsigned char netlen[sizeof(ber_len_t)];
 
155
        ber_len_t       len, rest;
 
156
        unsigned        i;
 
157
        unsigned char *ptr;
148
158
 
149
 
        assert( ber != NULL );
150
 
        assert( len != NULL );
151
 
        assert( LBER_VALID( ber ) );
 
159
        assert( bv != NULL );
152
160
 
153
161
        /*
154
162
         * Any ber element looks like this: tag length contents.
155
 
         * Assuming everything's ok, we return the tag byte (we
156
 
         * can assume a single byte), and return the length in len.
 
163
         * Assuming everything's ok, we return the tag, and point
 
164
         * bv at the contents.
157
165
         *
158
166
         * Assumptions:
159
167
         *      1) definite lengths
160
168
         *      2) primitive encodings used whenever possible
161
169
         */
162
170
 
163
 
        *len = 0;
 
171
        len = 0;
164
172
 
165
173
        /*
166
174
         * First, we read the tag.
167
175
         */
 
176
        tag = ber_tag_and_rest( ber, bv );
168
177
 
169
 
        if ( (tag = ber_get_tag( ber )) == LBER_DEFAULT ) {
170
 
                return LBER_DEFAULT;
 
178
        rest = bv->bv_len;
 
179
        ptr = (unsigned char *) bv->bv_val;
 
180
        if ( tag == LBER_DEFAULT || rest == 0 ) {
 
181
                goto fail;
171
182
        }
172
183
 
173
184
        /*
174
 
         * Next, read the length.  The first byte contains the length of
175
 
         * the length.  If bit 8 is set, the length is the long form,
176
 
         * otherwise it's the short form.  We don't allow a length that's
177
 
         * greater than what we can hold in a ber_len_t.
 
185
         * Next, read the length.  The first octet determines the length
 
186
         * of the length.       If bit 8 is 0, the length is the short form,
 
187
         * otherwise if the octet != 0x80 it's the long form, otherwise
 
188
         * the ber element has the unsupported indefinite-length format.
 
189
         * Lengths that do not fit in a ber_len_t are not accepted.
178
190
         */
179
191
 
180
 
        if ( ber_read( ber, (char *) &lc, 1 ) != 1 ) {
181
 
                return LBER_DEFAULT;
182
 
        }
183
 
 
184
 
        if ( lc & 0x80U ) {
185
 
                noctets = (lc & 0x7fU);
186
 
 
187
 
                if ( noctets > sizeof(ber_len_t) ) {
188
 
                        return LBER_DEFAULT;
189
 
                }
190
 
 
191
 
                if( (unsigned) ber_read( ber, (char *) netlen, noctets ) != noctets ) {
192
 
                        return LBER_DEFAULT;
193
 
                }
194
 
 
195
 
                for( i = 0; i < noctets; i++ ) {
196
 
                        *len <<= 8;
197
 
                        *len |= netlen[i];
198
 
                }
199
 
 
200
 
        } else {
201
 
                *len = lc;
 
192
        len = *ptr++;
 
193
        rest--;
 
194
 
 
195
        if ( len & 0x80U ) {
 
196
                len &= 0x7fU;
 
197
                if ( len - 1U > sizeof(ber_len_t) - 1U || rest < len ) {
 
198
                        /* Indefinite-length/too long length/not enough data */
 
199
                        goto fail;
 
200
                }
 
201
 
 
202
                rest -= len;
 
203
                i = len;
 
204
                for( len = *ptr++ & 0xffU; --i; len |= *ptr++ & 0xffU ) {
 
205
                        len <<= 8;
 
206
                }
202
207
        }
203
208
 
204
209
        /* BER element should have enough data left */
205
 
        if( *len > (ber_len_t) ber_pvt_ber_remaining( ber ) ) {
206
 
                return LBER_DEFAULT;
207
 
        }
208
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
 
210
        if( len > rest ) {
 
211
        fail:
 
212
                tag = LBER_DEFAULT;
 
213
        }
 
214
 
 
215
        bv->bv_len = len;
 
216
        bv->bv_val = (char *) ptr;
 
217
        return tag;
 
218
}
 
219
 
 
220
/* Move past next element, point *bv at it in-place, and return its tag.
 
221
 * The caller may \0-terminate *bv, as next octet is saved in ber->ber_tag.
 
222
 * Similar to ber_get_stringbv(ber, bv, LBER_BV_NOTERM) except on error.
 
223
 */
 
224
ber_tag_t
 
225
ber_skip_element( BerElement *ber, struct berval *bv )
 
226
{
 
227
        ber_tag_t tag = ber_peek_element( ber, bv );
 
228
 
 
229
        if ( tag != LBER_DEFAULT ) {
 
230
                ber->ber_ptr = bv->bv_val + bv->bv_len;
 
231
                ber->ber_tag = *(unsigned char *) ber->ber_ptr;
 
232
        }
209
233
 
210
234
        return tag;
211
235
}
215
239
        BerElement *ber,
216
240
        ber_len_t *len )
217
241
{
218
 
        /*
219
 
         * This implementation assumes ber_skip_tag() only
220
 
         * modifies ber_ptr field of the BerElement.
221
 
         */
222
 
 
223
 
        char *save;
224
 
        ber_tag_t       tag, old;
225
 
 
226
 
        old = ber->ber_tag;
227
 
        save = ber->ber_ptr;
228
 
        tag = ber_skip_tag( ber, len );
229
 
        ber->ber_ptr = save;
230
 
        ber->ber_tag = old;
231
 
 
232
 
        return tag;
233
 
}
234
 
 
235
 
static ber_len_t
236
 
ber_getnint(
 
242
        struct berval bv;
 
243
        ber_tag_t tag = ber_peek_element( ber, &bv );
 
244
 
 
245
        *len = bv.bv_len;
 
246
        return tag;
 
247
}
 
248
 
 
249
ber_tag_t
 
250
ber_skip_tag( BerElement *ber, ber_len_t *lenp )
 
251
{
 
252
        struct berval bv;
 
253
        ber_tag_t tag = ber_peek_element( ber, &bv );
 
254
 
 
255
        ber->ber_ptr = bv.bv_val;
 
256
        ber->ber_tag = *(unsigned char *) ber->ber_ptr;
 
257
 
 
258
        *lenp = bv.bv_len;
 
259
        return tag;
 
260
}
 
261
 
 
262
ber_tag_t
 
263
ber_get_int(
237
264
        BerElement *ber,
238
 
        ber_int_t *num,
239
 
        ber_len_t len )
 
265
        ber_int_t *num )
240
266
{
241
 
        unsigned char buf[sizeof(ber_int_t)];
 
267
        ber_tag_t       tag;
 
268
        ber_len_t       len;
 
269
        struct berval bv;
242
270
 
243
 
        assert( ber != NULL );
244
271
        assert( num != NULL );
245
 
        assert( LBER_VALID( ber ) );
246
 
 
247
 
        /*
248
 
         * The tag and length have already been stripped off.  We should
249
 
         * be sitting right before len bytes of 2's complement integer,
250
 
         * ready to be read straight into an int.  We may have to sign
251
 
         * extend after we read it in.
252
 
         */
253
 
 
254
 
        if ( len > sizeof(ber_int_t) ) {
255
 
                return -1;
256
 
        }
257
 
 
258
 
        /* read into the low-order bytes of our buffer */
259
 
        if ( (ber_len_t) ber_read( ber, (char *) buf, len ) != len ) {
260
 
                return -1;
261
 
        }
262
 
 
 
272
 
 
273
        tag = ber_skip_element( ber, &bv );
 
274
        len = bv.bv_len;
 
275
        if ( tag == LBER_DEFAULT || len > sizeof(ber_int_t) ) {
 
276
                return LBER_DEFAULT;
 
277
        }
 
278
 
 
279
        /* parse two's complement integer */
263
280
        if( len ) {
264
 
                /* sign extend if necessary */
 
281
                unsigned char *buf = (unsigned char *) bv.bv_val;
265
282
                ber_len_t i;
266
 
                ber_int_t netnum = 0x80 & buf[0] ? -1 : 0;
 
283
                ber_int_t netnum = buf[0] & 0xff;
 
284
 
 
285
                /* sign extend */
 
286
                netnum = (netnum ^ 0x80) - 0x80;
267
287
 
268
288
                /* shift in the bytes */
269
 
                for( i=0 ; i<len; i++ ) {
 
289
                for( i = 1; i < len; i++ ) {
270
290
                        netnum = (netnum << 8 ) | buf[i];
271
291
                }
272
292
 
275
295
        } else {
276
296
                *num = 0;
277
297
        }
278
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
279
 
 
280
 
        return len;
281
 
}
282
 
 
283
 
ber_tag_t
284
 
ber_get_int(
285
 
        BerElement *ber,
286
 
        ber_int_t *num )
287
 
{
288
 
        ber_tag_t       tag;
289
 
        ber_len_t       len;
290
 
 
291
 
        assert( ber != NULL );
292
 
        assert( LBER_VALID( ber ) );
293
 
 
294
 
        if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
295
 
                return LBER_DEFAULT;
296
 
        }
297
 
 
298
 
        if ( ber_getnint( ber, num, len ) != len ) {
299
 
                return LBER_DEFAULT;
300
 
        }
301
 
        
 
298
 
302
299
        return tag;
303
300
}
304
301
 
316
313
        char *buf,
317
314
        ber_len_t *len )
318
315
{
319
 
        ber_len_t       datalen;
 
316
        struct berval bv;
320
317
        ber_tag_t       tag;
321
318
 
322
 
        assert( ber != NULL );
323
 
        assert( LBER_VALID( ber ) );
324
 
 
325
 
        if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
 
319
        if ( (tag = ber_skip_element( ber, &bv )) == LBER_DEFAULT ) {
326
320
                return LBER_DEFAULT;
327
321
        }
328
322
 
329
323
        /* must fit within allocated space with termination */
330
 
        if ( datalen >= *len ) {
331
 
                return LBER_DEFAULT;
332
 
        }
333
 
 
334
 
        if ( (ber_len_t) ber_read( ber, buf, datalen ) != datalen ) {
335
 
                return LBER_DEFAULT;
336
 
        }
337
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
338
 
 
339
 
        buf[datalen] = '\0';
340
 
 
341
 
        *len = datalen;
 
324
        if ( bv.bv_len >= *len ) {
 
325
                return LBER_DEFAULT;
 
326
        }
 
327
 
 
328
        memcpy( buf, bv.bv_val, bv.bv_len );
 
329
        buf[bv.bv_len] = '\0';
 
330
 
 
331
        *len = bv.bv_len;
342
332
        return tag;
343
333
}
344
334
 
354
344
 * stack use to the absolute minimum.
355
345
 */
356
346
typedef struct bgbvr {
357
 
        enum bgbvc choice;
358
 
        BerElement *ber;
359
 
        int alloc;
360
 
        ber_len_t siz;
361
 
        ber_len_t off;
362
 
        union {
363
 
                char ***c;
364
 
                BerVarray *ba;
365
 
                struct berval ***bv;
366
 
        } res;
 
347
        const enum bgbvc choice;
 
348
        const int alloc;        /* choice == BvOff ? 0 : LBER_ALLOC */
 
349
        ber_len_t siz;          /* input array element size, output count */
 
350
        ber_len_t off;          /* BvOff offset to the struct berval */
 
351
        void *result;
367
352
} bgbvr;
368
353
 
369
354
static ber_tag_t
370
 
ber_get_stringbvl( bgbvr *b, ber_len_t *rlen )
 
355
ber_get_stringbvl( BerElement *ber, bgbvr *b )
371
356
{
372
357
        int i = 0, n;
373
358
        ber_tag_t tag;
374
 
        ber_len_t len;
 
359
        ber_len_t tot_size = 0, siz = b->siz;
375
360
        char *last, *orig;
376
361
        struct berval bv, *bvp = NULL;
377
 
 
378
 
        /* For rewinding, just like ber_peek_tag() */
379
 
        orig = b->ber->ber_ptr;
380
 
        tag = b->ber->ber_tag;
381
 
 
382
 
        if ( ber_first_element( b->ber, &len, &last ) != LBER_DEFAULT ) {
383
 
                for ( ; b->ber->ber_ptr < last; i++ ) {
384
 
                        if (ber_skip_tag( b->ber, &len ) == LBER_DEFAULT) break;
385
 
                        b->ber->ber_ptr += len;
386
 
                        b->ber->ber_tag = *(unsigned char *)b->ber->ber_ptr;
387
 
                }
 
362
        union stringbvl_u {
 
363
                char **ca;                              /* ChArray */
 
364
                BerVarray ba;                   /* BvArray */
 
365
                struct berval **bv;             /* BvVec */
 
366
                char *bo;                               /* BvOff */
 
367
        } res;
 
368
 
 
369
        tag = ber_skip_tag( ber, &bv.bv_len );
 
370
 
 
371
        if ( tag != LBER_DEFAULT ) {
 
372
                tag = 0;
 
373
                orig = ber->ber_ptr;
 
374
                last = orig + bv.bv_len;
 
375
 
 
376
                for ( ; ber->ber_ptr < last; i++, tot_size += siz ) {
 
377
                        if ( ber_skip_element( ber, &bv ) == LBER_DEFAULT )
 
378
                                break;
 
379
                }
 
380
                if ( ber->ber_ptr != last ) {
 
381
                        i = 0;
 
382
                        tag = LBER_DEFAULT;
 
383
                }
 
384
 
 
385
                ber->ber_ptr = orig;
 
386
                ber->ber_tag = *(unsigned char *) orig;
388
387
        }
389
388
 
390
 
        if ( rlen ) *rlen = i;
391
 
 
 
389
        b->siz = i;
392
390
        if ( i == 0 ) {
393
 
                *b->res.c = NULL;
394
 
                return 0;
395
 
        }
396
 
 
397
 
        n = i;
398
 
 
399
 
        /* Allocate the result vector */
 
391
                return tag;
 
392
        }
 
393
 
 
394
        /* Allocate and NULL-terminate the result vector */
 
395
        b->result = ber_memalloc_x( tot_size + siz, ber->ber_memctx );
 
396
        if ( b->result == NULL ) {
 
397
                return LBER_DEFAULT;
 
398
        }
400
399
        switch (b->choice) {
401
400
        case ChArray:
402
 
                *b->res.c = ber_memalloc_x( (n+1)*sizeof( char * ),
403
 
                        b->ber->ber_memctx);
404
 
                if ( *b->res.c == NULL ) return LBER_DEFAULT;
405
 
                (*b->res.c)[n] = NULL;
 
401
                res.ca = b->result;
 
402
                res.ca[i] = NULL;
406
403
                break;
407
404
        case BvArray:
408
 
                *b->res.ba = ber_memalloc_x( (n+1)*sizeof( struct berval ),
409
 
                        b->ber->ber_memctx);
410
 
                if ( *b->res.ba == NULL ) return LBER_DEFAULT;
411
 
                (*b->res.ba)[n].bv_val = NULL;
 
405
                res.ba = b->result;
 
406
                res.ba[i].bv_val = NULL;
412
407
                break;
413
408
        case BvVec:
414
 
                *b->res.bv = ber_memalloc_x( (n+1)*sizeof( struct berval *),
415
 
                        b->ber->ber_memctx);
416
 
                if ( *b->res.bv == NULL ) return LBER_DEFAULT;
417
 
                (*b->res.bv)[n] = NULL;
 
409
                res.bv = b->result;
 
410
                res.bv[i] = NULL;
418
411
                break;
419
412
        case BvOff:
420
 
                *b->res.ba = ber_memalloc_x( (n+1) * b->siz, b->ber->ber_memctx );
421
 
                if ( *b->res.ba == NULL ) return LBER_DEFAULT;
422
 
                ((struct berval *)((char *)(*b->res.ba) + n*b->siz +
423
 
                        b->off))->bv_val = NULL;
 
413
                res.bo = (char *) b->result + b->off;
 
414
                ((struct berval *) (res.bo + tot_size))->bv_val = NULL;
 
415
                tot_size = 0;
424
416
                break;
425
417
        }
426
 
        b->ber->ber_ptr = orig;
427
 
        b->ber->ber_tag = tag;
428
 
        ber_skip_tag( b->ber, &len );
429
 
        
430
 
        for (n=0; n<i; n++)
431
 
        {
432
 
                tag = ber_next_element( b->ber, &len, last );
433
 
                if ( ber_get_stringbv( b->ber, &bv, b->alloc ) == LBER_DEFAULT ) {
 
418
 
 
419
        n = 0;
 
420
        do {
 
421
                tag = ber_get_stringbv( ber, &bv, b->alloc );
 
422
                if ( tag == LBER_DEFAULT ) {
434
423
                        goto nomem;
435
424
                }
436
425
 
437
426
                /* store my result */
438
427
                switch (b->choice) {
439
428
                case ChArray:
440
 
                        (*b->res.c)[n] = bv.bv_val;
 
429
                        res.ca[n] = bv.bv_val;
441
430
                        break;
442
431
                case BvArray:
443
 
                        (*b->res.ba)[n] = bv;
 
432
                        res.ba[n] = bv;
444
433
                        break;
445
434
                case BvVec:
446
 
                        bvp = ber_memalloc_x( sizeof( struct berval ), b->ber->ber_memctx);
 
435
                        bvp = ber_memalloc_x( sizeof( struct berval ),
 
436
                                ber->ber_memctx );
447
437
                        if ( !bvp ) {
448
 
                                LBER_FREE(bv.bv_val);
 
438
                                ber_memfree_x( bv.bv_val, ber->ber_memctx );
449
439
                                goto nomem;
450
440
                        }
451
 
                        (*b->res.bv)[n] = bvp;
 
441
                        res.bv[n] = bvp;
452
442
                        *bvp = bv;
453
443
                        break;
454
444
                case BvOff:
455
 
                        *(BerVarray)((char *)(*b->res.ba)+n*b->siz+b->off) = bv;
 
445
                        *(struct berval *)(res.bo + tot_size) = bv;
 
446
                        tot_size += siz;
456
447
                        break;
457
448
                }
458
 
        }
 
449
        } while (++n < i);
459
450
        return tag;
460
451
 
461
452
nomem:
462
 
        if (b->alloc || b->choice == BvVec) {
463
 
                for (--n; n>=0; n--) {
 
453
        if (b->choice != BvOff) {       /* BvOff does not have b->alloc set */
 
454
                while (--n >= 0) {
464
455
                        switch(b->choice) {
465
456
                        case ChArray:
466
 
                                LBER_FREE((*b->res.c)[n]);
 
457
                                ber_memfree_x(res.ca[n], ber->ber_memctx);
467
458
                                break;
468
459
                        case BvArray:
469
 
                                LBER_FREE((*b->res.ba)[n].bv_val);
 
460
                                ber_memfree_x(res.ba[n].bv_val, ber->ber_memctx);
470
461
                                break;
471
462
                        case BvVec:
472
 
                                LBER_FREE((*b->res.bv)[n]->bv_val);
473
 
                                LBER_FREE((*b->res.bv)[n]);
 
463
                                ber_memfree_x(res.bv[n]->bv_val, ber->ber_memctx);
 
464
                                ber_memfree_x(res.bv[n], ber->ber_memctx);
474
465
                                break;
475
466
                        default:
476
467
                                break;
477
468
                        }
478
469
                }
479
470
        }
480
 
        LBER_FREE(*b->res.c);
481
 
        *b->res.c = NULL;
 
471
        ber_memfree_x(b->result, ber->ber_memctx);
 
472
        b->result = NULL;
482
473
        return LBER_DEFAULT;
483
474
}
484
475
 
486
477
ber_get_stringbv( BerElement *ber, struct berval *bv, int option )
487
478
{
488
479
        ber_tag_t       tag;
489
 
 
490
 
        assert( ber != NULL );
491
 
        assert( bv != NULL );
492
 
 
493
 
        assert( LBER_VALID( ber ) );
494
 
 
495
 
        if ( (tag = ber_skip_tag( ber, &bv->bv_len )) == LBER_DEFAULT ) {
 
480
        char            *data;
 
481
 
 
482
        tag = ber_skip_element( ber, bv );
 
483
        if ( tag == LBER_DEFAULT ) {
496
484
                bv->bv_val = NULL;
497
 
                return LBER_DEFAULT;
498
 
        }
499
 
 
500
 
        if ( (ber_len_t) ber_pvt_ber_remaining( ber ) < bv->bv_len ) {
501
 
                return LBER_DEFAULT;
502
 
        }
503
 
 
 
485
                return tag;
 
486
        }
 
487
 
 
488
        data = bv->bv_val;
504
489
        if ( option & LBER_BV_ALLOC ) {
505
490
                bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
506
491
                        ber->ber_memctx );
508
493
                        return LBER_DEFAULT;
509
494
                }
510
495
 
511
 
                if ( bv->bv_len > 0 && (ber_len_t) ber_read( ber, bv->bv_val,
512
 
                        bv->bv_len ) != bv->bv_len )
513
 
                {
514
 
                        LBER_FREE( bv->bv_val );
515
 
                        bv->bv_val = NULL;
516
 
                        return LBER_DEFAULT;
 
496
                if ( bv->bv_len != 0 ) {
 
497
                        memcpy( bv->bv_val, data, bv->bv_len );
517
498
                }
518
 
        } else {
519
 
                bv->bv_val = ber->ber_ptr;
520
 
                ber->ber_ptr += bv->bv_len;
 
499
                data = bv->bv_val;
521
500
        }
522
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
523
501
        if ( !( option & LBER_BV_NOTERM ))
524
 
                bv->bv_val[bv->bv_len] = '\0';
 
502
                data[bv->bv_len] = '\0';
525
503
 
526
504
        return tag;
527
505
}
530
508
ber_get_stringbv_null( BerElement *ber, struct berval *bv, int option )
531
509
{
532
510
        ber_tag_t       tag;
533
 
 
534
 
        assert( ber != NULL );
535
 
        assert( bv != NULL );
536
 
 
537
 
        assert( LBER_VALID( ber ) );
538
 
 
539
 
        if ( (tag = ber_skip_tag( ber, &bv->bv_len )) == LBER_DEFAULT ) {
540
 
                bv->bv_val = NULL;
541
 
                return LBER_DEFAULT;
542
 
        }
543
 
 
544
 
        if ( (ber_len_t) ber_pvt_ber_remaining( ber ) < bv->bv_len ) {
545
 
                return LBER_DEFAULT;
546
 
        }
547
 
 
548
 
        if ( bv->bv_len == 0 ) {
549
 
                bv->bv_val = NULL;
550
 
                ber->ber_tag = *(unsigned char *)ber->ber_ptr;
 
511
        char            *data;
 
512
 
 
513
        tag = ber_skip_element( ber, bv );
 
514
        if ( tag == LBER_DEFAULT || bv->bv_len == 0 ) {
 
515
                bv->bv_val = NULL;
551
516
                return tag;
552
517
        }
553
518
 
 
519
        data = bv->bv_val;
554
520
        if ( option & LBER_BV_ALLOC ) {
555
521
                bv->bv_val = (char *) ber_memalloc_x( bv->bv_len + 1,
556
522
                        ber->ber_memctx );
558
524
                        return LBER_DEFAULT;
559
525
                }
560
526
 
561
 
                if ( bv->bv_len > 0 && (ber_len_t) ber_read( ber, bv->bv_val,
562
 
                        bv->bv_len ) != bv->bv_len )
563
 
                {
564
 
                        LBER_FREE( bv->bv_val );
565
 
                        bv->bv_val = NULL;
566
 
                        return LBER_DEFAULT;
567
 
                }
568
 
        } else {
569
 
                bv->bv_val = ber->ber_ptr;
570
 
                ber->ber_ptr += bv->bv_len;
 
527
                memcpy( bv->bv_val, data, bv->bv_len );
 
528
                data = bv->bv_val;
571
529
        }
572
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
573
530
        if ( !( option & LBER_BV_NOTERM ))
574
 
                bv->bv_val[bv->bv_len] = '\0';
 
531
                data[bv->bv_len] = '\0';
575
532
 
576
533
        return tag;
577
534
}
620
577
 
621
578
        tag = ber_get_stringbv( ber, *bv, LBER_BV_ALLOC );
622
579
        if ( tag == LBER_DEFAULT ) {
623
 
                LBER_FREE( *bv );
 
580
                ber_memfree_x( *bv, ber->ber_memctx );
624
581
                *bv = NULL;
625
582
        }
626
583
        return tag;
632
589
        char **buf,
633
590
        ber_len_t *blen )
634
591
{
635
 
        ber_len_t       datalen;
636
592
        ber_tag_t       tag;
 
593
        struct berval   data;
637
594
        unsigned char   unusedbits;
638
595
 
639
 
        assert( ber != NULL );
640
596
        assert( buf != NULL );
641
597
        assert( blen != NULL );
642
598
 
643
 
        assert( LBER_VALID( ber ) );
644
 
 
645
 
        if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
646
 
                *buf = NULL;
647
 
                return LBER_DEFAULT;
648
 
        }
649
 
        --datalen;
650
 
 
651
 
        *buf = (char *) ber_memalloc_x( datalen, ber->ber_memctx );
 
599
        if ( (tag = ber_skip_element( ber, &data )) == LBER_DEFAULT ) {
 
600
                goto fail;
 
601
        }
 
602
 
 
603
        if ( --data.bv_len > (ber_len_t)-1 / 8 ) {
 
604
                goto fail;
 
605
        }
 
606
        unusedbits = *(unsigned char *) data.bv_val++;
 
607
        if ( unusedbits > 7 ) {
 
608
                goto fail;
 
609
        }
 
610
 
 
611
        *buf = (char *) ber_memalloc_x( data.bv_len, ber->ber_memctx );
652
612
        if ( *buf == NULL ) {
653
613
                return LBER_DEFAULT;
654
614
        }
655
 
 
656
 
        if ( ber_read( ber, (char *)&unusedbits, 1 ) != 1 ) {
657
 
                LBER_FREE( buf );
658
 
                *buf = NULL;
659
 
                return LBER_DEFAULT;
660
 
        }
661
 
 
662
 
        if ( (ber_len_t) ber_read( ber, *buf, datalen ) != datalen ) {
663
 
                LBER_FREE( buf );
664
 
                *buf = NULL;
665
 
                return LBER_DEFAULT;
666
 
        }
667
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
668
 
 
669
 
        *blen = datalen * 8 - unusedbits;
 
615
        memcpy( *buf, data.bv_val, data.bv_len );
 
616
 
 
617
        *blen = data.bv_len * 8 - unusedbits;
670
618
        return tag;
 
619
 
 
620
 fail:
 
621
        *buf = NULL;
 
622
        return LBER_DEFAULT;
671
623
}
672
624
 
673
625
ber_tag_t
674
626
ber_get_null( BerElement *ber )
675
627
{
676
628
        ber_len_t       len;
677
 
        ber_tag_t       tag;
678
 
 
679
 
        assert( ber != NULL );
680
 
        assert( LBER_VALID( ber ) );
681
 
 
682
 
        if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
683
 
                return LBER_DEFAULT;
684
 
        }
685
 
 
686
 
        if ( len != 0 ) {
687
 
                return LBER_DEFAULT;
688
 
        }
689
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
690
 
 
691
 
        return( tag );
 
629
        ber_tag_t       tag = ber_skip_tag( ber, &len );
 
630
 
 
631
        return( len == 0 ? tag : LBER_DEFAULT );
692
632
}
693
633
 
694
634
ber_tag_t
696
636
        BerElement *ber,
697
637
        ber_int_t *boolval )
698
638
{
699
 
        ber_int_t       longbool;
700
 
        ber_tag_t       rc;
701
 
 
702
 
        assert( ber != NULL );
703
 
        assert( boolval != NULL );
704
 
 
705
 
        assert( LBER_VALID( ber ) );
706
 
 
707
 
        rc = ber_get_int( ber, &longbool );
708
 
        *boolval = longbool;
709
 
 
710
 
        return rc;
 
639
        return ber_get_int( ber, boolval );
711
640
}
712
641
 
713
642
ber_tag_t
716
645
        ber_len_t *len,
717
646
        char **last )
718
647
{
719
 
        assert( ber != NULL );
720
 
        assert( len != NULL );
721
648
        assert( last != NULL );
722
649
 
723
650
        /* skip the sequence header, use the len to mark where to stop */
725
652
                *last = NULL;
726
653
                return LBER_DEFAULT;
727
654
        }
728
 
        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
729
655
 
730
656
        *last = ber->ber_ptr + *len;
731
657
 
732
 
        if ( *last == ber->ber_ptr ) {
 
658
        if ( *len == 0 ) {
733
659
                return LBER_DEFAULT;
734
660
        }
735
661
 
743
669
        LDAP_CONST char *last )
744
670
{
745
671
        assert( ber != NULL );
746
 
        assert( len != NULL );
747
672
        assert( last != NULL );
748
 
 
749
673
        assert( LBER_VALID( ber ) );
750
674
 
751
675
        if ( ber->ber_ptr >= last ) {
763
687
{
764
688
        va_list         ap;
765
689
        LDAP_CONST char         *fmt_reset;
766
 
        char            *s, **ss;
767
 
        struct berval   **bvp, *bval;
 
690
        char            *s, **ss, ***sss;
 
691
        struct berval   data, *bval, **bvp, ***bvpp;
768
692
        ber_int_t       *i;
769
693
        ber_len_t       *l;
770
694
        ber_tag_t       *t;
775
699
 
776
700
        assert( ber != NULL );
777
701
        assert( fmt != NULL );
778
 
 
779
702
        assert( LBER_VALID( ber ) );
780
703
 
781
704
        fmt_reset = fmt;
823
746
                        break;
824
747
 
825
748
                case 'e':       /* enumerated */
826
 
                case 'i':       /* int */
 
749
                case 'i':       /* integer */
827
750
                        i = va_arg( ap, ber_int_t * );
828
751
                        rc = ber_get_int( ber, i );
829
752
                        break;
844
767
                                 * len ptr on finish. parsed in-place.
845
768
                                 */
846
769
                {
847
 
                        bgbvr cookie = { BvOff };
848
 
                        cookie.ber = ber;
849
 
                        cookie.res.ba = va_arg( ap, struct berval ** );
850
 
                        cookie.alloc = 0;
 
770
                        bgbvr cookie = { BvOff, 0 };
 
771
                        bvp = va_arg( ap, struct berval ** );
851
772
                        l = va_arg( ap, ber_len_t * );
852
773
                        cookie.siz = *l;
853
774
                        cookie.off = va_arg( ap, ber_len_t );
854
 
                        rc = ber_get_stringbvl( &cookie, l );
 
775
                        rc = ber_get_stringbvl( ber, &cookie );
 
776
                        *bvp = cookie.result;
 
777
                        *l = cookie.siz;
855
778
                        break;
856
779
                }
857
780
 
887
810
 
888
811
                case 'v':       /* sequence of strings */
889
812
                {
890
 
                        bgbvr cookie = { ChArray };
891
 
                        cookie.ber = ber;
892
 
                        cookie.res.c = va_arg( ap, char *** );
893
 
                        cookie.alloc = LBER_BV_ALLOC;
894
 
                        rc = ber_get_stringbvl( &cookie, NULL );
 
813
                        bgbvr cookie = {
 
814
                                ChArray, LBER_BV_ALLOC, sizeof( char * )
 
815
                        };
 
816
                        rc = ber_get_stringbvl( ber, &cookie );
 
817
                        *(va_arg( ap, char *** )) = cookie.result;
895
818
                        break;
896
819
                }
897
820
 
898
821
                case 'V':       /* sequence of strings + lengths */
899
822
                {
900
 
                        bgbvr cookie = { BvVec };
901
 
                        cookie.ber = ber;
902
 
                        cookie.res.bv = va_arg( ap, struct berval *** );
903
 
                        cookie.alloc = LBER_BV_ALLOC;
904
 
                        rc = ber_get_stringbvl( &cookie, NULL );
 
823
                        bgbvr cookie = {
 
824
                                BvVec, LBER_BV_ALLOC, sizeof( struct berval * )
 
825
                        };
 
826
                        rc = ber_get_stringbvl( ber, &cookie );
 
827
                        *(va_arg( ap, struct berval *** )) = cookie.result;
905
828
                        break;
906
829
                }
907
830
 
908
831
                case 'W':       /* bvarray */
909
832
                {
910
 
                        bgbvr cookie = { BvArray };
911
 
                        cookie.ber = ber;
912
 
                        cookie.res.ba = va_arg( ap, struct berval ** );
913
 
                        cookie.alloc = LBER_BV_ALLOC;
914
 
                        rc = ber_get_stringbvl( &cookie, NULL );
 
833
                        bgbvr cookie = {
 
834
                                BvArray, LBER_BV_ALLOC, sizeof( struct berval )
 
835
                        };
 
836
                        rc = ber_get_stringbvl( ber, &cookie );
 
837
                        *(va_arg( ap, struct berval ** )) = cookie.result;
915
838
                        break;
916
839
                }
917
840
 
918
841
                case 'x':       /* skip the next element - whatever it is */
919
 
                        if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
920
 
                                break;
921
 
                        ber->ber_ptr += len;
922
 
                        ber->ber_tag = *(unsigned char *)ber->ber_ptr;
 
842
                        rc = ber_skip_element( ber, &data );
923
843
                        break;
924
844
 
925
845
                case '{':       /* begin sequence */
926
846
                case '[':       /* begin set */
927
 
                        if ( *(fmt + 1) != 'v' && *(fmt + 1) != 'V'
928
 
                                && *(fmt + 1) != 'W' && *(fmt + 1) != 'M' )
 
847
                        switch ( fmt[1] ) {
 
848
                        case 'v': case 'V': case 'W': case 'M':
 
849
                                break;
 
850
                        default:
929
851
                                rc = ber_skip_tag( ber, &len );
 
852
                                break;
 
853
                        }
930
854
                        break;
931
855
 
932
856
                case '}':       /* end sequence */
944
868
        }
945
869
 
946
870
        va_end( ap );
 
871
 
947
872
        if ( rc == LBER_DEFAULT ) {
948
873
                /*
949
874
                 * Error.  Reclaim malloced memory that was given to the caller.
966
891
                case 'a':       /* octet string - allocate storage as needed */
967
892
                case 'A':
968
893
                        ss = va_arg( ap, char ** );
969
 
                        if ( *ss ) {
970
 
                                LBER_FREE( *ss );
971
 
                                *ss = NULL;
972
 
                        }
 
894
                        ber_memfree_x( *ss, ber->ber_memctx );
 
895
                        *ss = NULL;
973
896
                        break;
974
897
 
975
898
                case 'b':       /* boolean */
976
899
                case 'e':       /* enumerated */
977
 
                case 'i':       /* int */
978
 
                        (void) va_arg( ap, int * );
 
900
                case 'i':       /* integer */
 
901
                        (void) va_arg( ap, ber_int_t * );
979
902
                        break;
980
903
 
981
904
                case 'l':       /* length of next item */
982
 
                        (void) va_arg( ap, ber_len_t * );
 
905
                        *(va_arg( ap, ber_len_t * )) = 0;
 
906
                        break;
 
907
 
 
908
                case 'm':       /* berval in-place */
 
909
                        bval = va_arg( ap, struct berval * );
 
910
                        BER_BVZERO( bval );
 
911
                        break;
 
912
 
 
913
                case 'M':       /* BVoff array in-place */
 
914
                        bvp = va_arg( ap, struct berval ** );
 
915
                        ber_memfree_x( *bvp, ber->ber_memctx );
 
916
                        *bvp = NULL;
 
917
                        *(va_arg( ap, ber_len_t * )) = 0;
 
918
                        (void) va_arg( ap, ber_len_t );
983
919
                        break;
984
920
 
985
921
                case 'o':       /* octet string in a supplied berval */
986
922
                        bval = va_arg( ap, struct berval * );
987
 
                        if ( bval->bv_val != NULL ) {
988
 
                                LBER_FREE( bval->bv_val );
989
 
                                bval->bv_val = NULL;
990
 
                        }
991
 
                        bval->bv_len = 0;
 
923
                        ber_memfree_x( bval->bv_val, ber->ber_memctx );
 
924
                        BER_BVZERO( bval );
992
925
                        break;
993
926
 
994
927
                case 'O':       /* octet string - allocate & include length */
995
928
                        bvp = va_arg( ap, struct berval ** );
996
 
                        if ( *bvp ) {
997
 
                                ber_bvfree( *bvp );
998
 
                                *bvp = NULL;
999
 
                        }
 
929
                        ber_bvfree_x( *bvp, ber->ber_memctx );
 
930
                        *bvp = NULL;
1000
931
                        break;
1001
932
 
1002
933
                case 's':       /* octet string - in a buffer */
1003
934
                        (void) va_arg( ap, char * );
1004
 
                        (void) va_arg( ap, ber_len_t * );
 
935
                        *(va_arg( ap, ber_len_t * )) = 0;
1005
936
                        break;
1006
937
 
1007
938
                case 't':       /* tag of next item */
1011
942
 
1012
943
                case 'B':       /* bit string - allocate storage as needed */
1013
944
                        ss = va_arg( ap, char ** );
1014
 
                        if ( *ss ) {
1015
 
                                LBER_FREE( *ss );
1016
 
                                *ss = NULL;
1017
 
                        }
 
945
                        ber_memfree_x( *ss, ber->ber_memctx );
 
946
                        *ss = NULL;
1018
947
                        *(va_arg( ap, ber_len_t * )) = 0; /* for length, in bits */
1019
948
                        break;
1020
949
 
1021
 
                case 'm':       /* berval in-place */
1022
 
                case 'M':       /* BVoff array in-place */
1023
 
                case 'n':       /* null */
1024
950
                case 'v':       /* sequence of strings */
 
951
                        sss = va_arg( ap, char *** );
 
952
                        ber_memvfree_x( (void **) *sss, ber->ber_memctx );
 
953
                        *sss = NULL;
 
954
                        break;
 
955
 
1025
956
                case 'V':       /* sequence of strings + lengths */
 
957
                        bvpp = va_arg( ap, struct berval *** );
 
958
                        ber_bvecfree_x( *bvpp, ber->ber_memctx );
 
959
                        *bvpp = NULL;
 
960
                        break;
 
961
 
1026
962
                case 'W':       /* BerVarray */
 
963
                        bvp = va_arg( ap, struct berval ** );
 
964
                        ber_bvarray_free_x( *bvp, ber->ber_memctx );
 
965
                        *bvp = NULL;
 
966
                        break;
 
967
 
 
968
                case 'n':       /* null */
1027
969
                case 'x':       /* skip the next element - whatever it is */
1028
970
                case '{':       /* begin sequence */
1029
971
                case '[':       /* begin set */