diff --git a/libraries/liblutil/utils.c b/libraries/liblutil/utils.c index a96fa060cf42a0d357ffbf6fa6c97668c9845362..f14e6c877de679b20fdf96d2b4c1dd3f6212e26c 100644 --- a/libraries/liblutil/utils.c +++ b/libraries/liblutil/utils.c @@ -663,6 +663,8 @@ scale( int new, lutil_int_decnum *prev, unsigned char *tmp ) * Output buffer must be provided, bv_len must indicate buffer size * 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 * 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 @@ -736,15 +738,16 @@ lutil_str2bin( struct berval *in, struct berval *out ) num.beg = num.bufsiz-1; num.len = 0; if ( pin[0] == '-' ) { - neg = 1; + neg = 0xff; len--; pin++; } #define DECMAX 8 /* 8 digits at a time */ - if ( len > sizeof(tmpbuf)) { - tmp = ber_memalloc( len ); + /* tmp must be at least as large as outbuf */ + if ( out->bv_len > sizeof(tmpbuf)) { + tmp = ber_memalloc( out->bv_len ); } else { tmp = tmpbuf; } @@ -778,29 +781,14 @@ lutil_str2bin( struct berval *in, struct berval *out ) for ( i=0; i<num.len; i++ ) ptr[i] ^= 0xff; - /* Add 1, with carry */ - i--; - j = 1; - for ( ; i>=0; i-- ) { - j += ptr[i]; - ptr[i] = j & 0xff; - j >>= 8; - if (!j) - break; - } - /* If we overflowed and there's still room, - * set an explicit sign byte - */ - if ( !( ptr[0] & 0x80 ) && num.beg ) { - num.beg--; - num.len++; - num.buf[num.beg] = 0x80; - } - } else if (( num.buf[num.beg] & 0x80 ) && num.beg ) { - /* positive int with high bit set, prepend 0 */ + /* add 1, with carry - overflow handled below */ + while ( i-- && ! (ptr[i] = (ptr[i] + 1) & 0xff )) ; + } + /* Prepend sign byte if wrong sign bit */ + if (( num.buf[num.beg] ^ neg ) & 0x80 ) { num.beg--; num.len++; - num.buf[num.beg] = 0; + num.buf[num.beg] = neg; } if ( num.beg ) AC_MEMCPY( num.buf, num.buf+num.beg, num.len );