]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorHoward Chu <hyc@openldap.org>
Sat, 1 Dec 2007 20:35:36 +0000 (20:35 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 1 Dec 2007 20:35:36 +0000 (20:35 +0000)
libraries/liblutil/utils.c

index a96fa060cf42a0d357ffbf6fa6c97668c9845362..f14e6c877de679b20fdf96d2b4c1dd3f6212e26c 100644 (file)
@@ -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 );