ITS#7174 lutil_str2bin: can't modify input strings

This commit is contained in:
Howard Chu 2012-02-19 18:10:16 -08:00
parent 0df3b9222a
commit 92ed65d298

View File

@ -714,8 +714,6 @@ scale( int new, lutil_int_decnum *prev, unsigned char *tmp )
* Output buffer must be provided, bv_len must indicate buffer size * Output buffer must be provided, bv_len must indicate buffer size
* Hex input can be "0x1234" or "'1234'H" * Hex input can be "0x1234" or "'1234'H"
* *
* Temporarily modifies the input string.
*
* Note: High bit of binary form is always the sign bit. If the number * Note: High bit of binary form is always the sign bit. If the number
* is supposed to be positive but has the high bit set, a zero byte * is supposed to be positive but has the high bit set, a zero byte
* is prepended. It is assumed that this has already been handled on * is prepended. It is assumed that this has already been handled on
@ -724,7 +722,7 @@ scale( int new, lutil_int_decnum *prev, unsigned char *tmp )
int int
lutil_str2bin( struct berval *in, struct berval *out, void *ctx ) lutil_str2bin( struct berval *in, struct berval *out, void *ctx )
{ {
char *pin, *pout, ctmp; char *pin, *pout;
char *end; char *end;
int i, chunk, len, rc = 0, hex = 0; int i, chunk, len, rc = 0, hex = 0;
if ( !out || !out->bv_val || out->bv_len < in->bv_len ) if ( !out || !out->bv_val || out->bv_len < in->bv_len )
@ -749,6 +747,8 @@ lutil_str2bin( struct berval *in, struct berval *out, void *ctx )
if ( hex ) { if ( hex ) {
#define HEXMAX (2 * sizeof(long)) #define HEXMAX (2 * sizeof(long))
unsigned long l; unsigned long l;
char tbuf[HEXMAX+1];
/* Convert a longword at a time, but handle leading /* Convert a longword at a time, but handle leading
* odd bytes first * odd bytes first
*/ */
@ -758,11 +758,10 @@ lutil_str2bin( struct berval *in, struct berval *out, void *ctx )
while ( len ) { while ( len ) {
int ochunk; int ochunk;
ctmp = pin[chunk]; memcpy( tbuf, pin, chunk );
pin[chunk] = '\0'; tbuf[chunk] = '\0';
errno = 0; errno = 0;
l = strtoul( pin, &end, 16 ); l = strtoul( tbuf, &end, 16 );
pin[chunk] = ctmp;
if ( errno ) if ( errno )
return -1; return -1;
ochunk = (chunk + 1)/2; ochunk = (chunk + 1)/2;
@ -778,10 +777,12 @@ lutil_str2bin( struct berval *in, struct berval *out, void *ctx )
out->bv_len = pout - out->bv_val; out->bv_len = pout - out->bv_val;
} else { } else {
/* Decimal */ /* Decimal */
#define DECMAX 8 /* 8 digits at a time */
char tmpbuf[64], *tmp; char tmpbuf[64], *tmp;
lutil_int_decnum num; lutil_int_decnum num;
int neg = 0; int neg = 0;
long l; long l;
char tbuf[DECMAX+1];
len = in->bv_len; len = in->bv_len;
pin = in->bv_val; pin = in->bv_val;
@ -795,8 +796,6 @@ lutil_str2bin( struct berval *in, struct berval *out, void *ctx )
pin++; pin++;
} }
#define DECMAX 8 /* 8 digits at a time */
/* tmp must be at least as large as outbuf */ /* tmp must be at least as large as outbuf */
if ( out->bv_len > sizeof(tmpbuf)) { if ( out->bv_len > sizeof(tmpbuf)) {
tmp = ber_memalloc_x( out->bv_len, ctx ); tmp = ber_memalloc_x( out->bv_len, ctx );
@ -808,11 +807,10 @@ lutil_str2bin( struct berval *in, struct berval *out, void *ctx )
chunk = DECMAX; chunk = DECMAX;
while ( len ) { while ( len ) {
ctmp = pin[chunk]; memcpy( tbuf, pin, chunk );
pin[chunk] = '\0'; tbuf[chunk] = '\0';
errno = 0; errno = 0;
l = strtol( pin, &end, 10 ); l = strtol( tbuf, &end, 10 );
pin[chunk] = ctmp;
if ( errno ) { if ( errno ) {
rc = -1; rc = -1;
goto decfail; goto decfail;