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

« back to all changes in this revision

Viewing changes to libraries/liblber/io.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
/* io.c - ber general i/o routines */
2
 
/* $OpenLDAP: pkg/ldap/libraries/liblber/io.c,v 1.111.2.10 2009/03/17 16:21:28 quanah Exp $ */
 
2
/* $OpenLDAP: pkg/ldap/libraries/liblber/io.c,v 1.111.2.11 2009/08/02 21:06:34 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.
55
55
        ber_len_t       actuallen, nleft;
56
56
 
57
57
        assert( ber != NULL );
58
 
 
59
58
        assert( LBER_VALID( ber ) );
60
59
 
61
60
        nleft = ber_pvt_ber_remaining( ber );
66
65
        return( (ber_slen_t) actuallen );
67
66
}
68
67
 
 
68
/*
 
69
 * Read from the ber buffer.  The caller must maintain ber->ber_tag.
 
70
 * Do not use to read whole tags.  See ber_get_tag() and ber_skip_data().
 
71
 */
69
72
ber_slen_t
70
73
ber_read(
71
74
        BerElement *ber,
76
79
 
77
80
        assert( ber != NULL );
78
81
        assert( buf != NULL );
79
 
 
80
82
        assert( LBER_VALID( ber ) );
81
83
 
82
84
        nleft = ber_pvt_ber_remaining( ber );
89
91
        return( (ber_slen_t) actuallen );
90
92
}
91
93
 
 
94
/*
 
95
 * Write to the ber buffer.
 
96
 * Note that ber_start_seqorset/ber_put_seqorset() bypass ber_write().
 
97
 */
92
98
ber_slen_t
93
99
ber_write(
94
100
        BerElement *ber,
95
101
        LDAP_CONST char *buf,
96
102
        ber_len_t len,
97
 
        int nosos )
 
103
        int zero )      /* nonzero is unsupported from OpenLDAP 2.4.18 */
98
104
{
 
105
        char **p;
 
106
 
99
107
        assert( ber != NULL );
100
108
        assert( buf != NULL );
101
 
 
102
109
        assert( LBER_VALID( ber ) );
103
110
 
104
 
        if ( nosos || ber->ber_sos == NULL ) {
105
 
                if ( ber->ber_ptr + len > ber->ber_end ) {
106
 
                        if ( ber_realloc( ber, len ) != 0 ) return( -1 );
107
 
                }
108
 
                AC_MEMCPY( ber->ber_ptr, buf, (size_t)len );
109
 
                ber->ber_ptr += len;
110
 
                return( (ber_slen_t) len );
111
 
 
112
 
        } else {
113
 
                if ( ber->ber_sos->sos_ptr + len > ber->ber_end ) {
114
 
                        if ( ber_realloc( ber, len ) != 0 ) return( -1 );
115
 
                }
116
 
                AC_MEMCPY( ber->ber_sos->sos_ptr, buf, (size_t)len );
117
 
                ber->ber_sos->sos_ptr += len;
118
 
                ber->ber_sos->sos_clen += len;
119
 
                return( (ber_slen_t) len );
120
 
        }
 
111
        if ( zero != 0 ) {
 
112
                ber_log_printf( LDAP_DEBUG_ANY, ber->ber_debug, "%s",
 
113
                        "ber_write: nonzero 4th argument not supported\n" );
 
114
                return( -1 );
 
115
        }
 
116
 
 
117
        p = ber->ber_sos_ptr == NULL ? &ber->ber_ptr : &ber->ber_sos_ptr;
 
118
        if ( len > (ber_len_t) (ber->ber_end - *p) ) {
 
119
                if ( ber_realloc( ber, len ) != 0 ) return( -1 );
 
120
        }
 
121
        AC_MEMCPY( *p, buf, len );
 
122
        *p += len;
 
123
 
 
124
        return( (ber_slen_t) len );
121
125
}
122
126
 
 
127
/* Resize the ber buffer */
123
128
int
124
129
ber_realloc( BerElement *ber, ber_len_t len )
125
130
{
126
 
        ber_len_t       total;
127
 
        Seqorset        *s;
128
 
        long            off;
129
 
        char            *oldbuf;
 
131
        ber_len_t       total, offset, sos_offset;
 
132
        char            *buf;
130
133
 
131
134
        assert( ber != NULL );
132
 
        assert( len > 0 );
133
135
        assert( LBER_VALID( ber ) );
134
136
 
 
137
        /* leave room for ber_flatten() to \0-terminate ber_buf */
 
138
        if ( ++len == 0 ) {
 
139
                return( -1 );
 
140
        }
 
141
 
135
142
        total = ber_pvt_ber_total( ber );
136
143
 
137
144
#define LBER_EXBUFSIZ   4060 /* a few words less than 2^N for binary buddy */
140
147
        /* don't realloc by small amounts */
141
148
        total += len < LBER_EXBUFSIZ ? LBER_EXBUFSIZ : len;
142
149
# else
143
 
        {       /* not sure what value this adds */
 
150
        {       /* not sure what value this adds.  reduce fragmentation? */
144
151
                ber_len_t have = (total + (LBER_EXBUFSIZE - 1)) / LBER_EXBUFSIZ;
145
152
                ber_len_t need = (len + (LBER_EXBUFSIZ - 1)) / LBER_EXBUFSIZ;
146
153
                total = ( have + need ) * LBER_EXBUFSIZ;
150
157
        total += len;   /* realloc just what's needed */
151
158
#endif
152
159
 
153
 
        oldbuf = ber->ber_buf;
154
 
 
155
 
        ber->ber_buf = (char *) ber_memrealloc_x( oldbuf, total, ber->ber_memctx );
156
 
        
157
 
        if ( ber->ber_buf == NULL ) {
158
 
                ber->ber_buf = oldbuf;
159
 
                return( -1 );
160
 
        }
161
 
 
162
 
        ber->ber_end = ber->ber_buf + total;
163
 
 
164
 
        /*
165
 
         * If the stinking thing was moved, we need to go through and
166
 
         * reset all the sos and ber pointers.  Offsets would've been
167
 
         * a better idea... oh well.
168
 
         */
169
 
 
170
 
        if ( ber->ber_buf != oldbuf ) {
171
 
                ber->ber_ptr = ber->ber_buf + (ber->ber_ptr - oldbuf);
172
 
 
173
 
                for ( s = ber->ber_sos; s != NULL; s = s->sos_next ) {
174
 
                        off = s->sos_first - oldbuf;
175
 
                        s->sos_first = ber->ber_buf + off;
176
 
 
177
 
                        off = s->sos_ptr - oldbuf;
178
 
                        s->sos_ptr = ber->ber_buf + off;
179
 
                }
180
 
        }
 
160
        if ( total < len || total > (ber_len_t)-1 / 2 /* max ber_slen_t */ ) {
 
161
                return( -1 );
 
162
        }
 
163
 
 
164
        buf = ber->ber_buf;
 
165
        offset = ber->ber_ptr - buf;
 
166
        sos_offset = ber->ber_sos_ptr ? ber->ber_sos_ptr - buf : 0;
 
167
        /* if ber_sos_ptr != NULL, it is > ber_buf so that sos_offset > 0 */
 
168
 
 
169
        buf = (char *) ber_memrealloc_x( buf, total, ber->ber_memctx );
 
170
        if ( buf == NULL ) {
 
171
                return( -1 );
 
172
        }
 
173
 
 
174
        ber->ber_buf = buf;
 
175
        ber->ber_end = buf + total;
 
176
        ber->ber_ptr = buf + offset;
 
177
        if ( sos_offset )
 
178
                ber->ber_sos_ptr = buf + sos_offset;
181
179
 
182
180
        return( 0 );
183
181
}
185
183
void
186
184
ber_free_buf( BerElement *ber )
187
185
{
188
 
        Seqorset *s, *next;
189
 
 
190
186
        assert( LBER_VALID( ber ) );
191
187
 
192
188
        if ( ber->ber_buf) ber_memfree_x( ber->ber_buf, ber->ber_memctx );
193
189
 
194
 
        for( s = ber->ber_sos ; s != NULL ; s = next ) {
195
 
                next = s->sos_next;
196
 
                ber_memfree_x( s, ber->ber_memctx );
197
 
        }
198
 
 
199
190
        ber->ber_buf = NULL;
200
 
        ber->ber_sos = NULL;
 
191
        ber->ber_sos_ptr = NULL;
201
192
        ber->ber_valid = LBER_UNINITIALIZED;
202
193
}
203
194
 
230
221
 
231
222
        assert( sb != NULL );
232
223
        assert( ber != NULL );
233
 
 
234
224
        assert( SOCKBUF_VALID( sb ) );
235
225
        assert( LBER_VALID( ber ) );
236
226
 
415
405
                                return -1;
416
406
                        }
417
407
                        AC_MEMCPY( bv->bv_val, ber->ber_buf, len );
418
 
                } else {
 
408
                        bv->bv_val[len] = '\0';
 
409
                } else if ( ber->ber_buf != NULL ) {
419
410
                        bv->bv_val = ber->ber_buf;
 
411
                        bv->bv_val[len] = '\0';
 
412
                } else {
 
413
                        bv->bv_val = "";
420
414
                }
421
 
                bv->bv_val[len] = '\0';
422
415
                bv->bv_len = len;
423
416
        }
424
417
        return 0;
484
477
        assert( sb != NULL );
485
478
        assert( len != NULL );
486
479
        assert( ber != NULL );
487
 
 
488
480
        assert( SOCKBUF_VALID( sb ) );
489
481
        assert( LBER_VALID( ber ) );
490
482
 
725
717
ber_rewind ( BerElement * ber )
726
718
{
727
719
        ber->ber_rwptr = NULL;
728
 
        ber->ber_sos = NULL;
 
720
        ber->ber_sos_ptr = NULL;
729
721
        ber->ber_end = ber->ber_ptr;
730
722
        ber->ber_ptr = ber->ber_buf;
 
723
#if 0   /* TODO: Should we add this? */
 
724
        ber->ber_tag = LBER_DEFAULT;
 
725
        ber->ber_usertag = 0;
 
726
#endif
731
727
}
732
728
 
733
729
int