summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2009-10-01 01:26:19 -0400
committerEliot Horowitz <eliot@10gen.com>2009-10-01 01:26:19 -0400
commit1bb3d4a00461d0aea02cf76eb7073d1776c7bc04 (patch)
treea299e501b4bfe018f1067a4a5d99e7dfd0812b5a
parentcc2377b335c3e169723f24dd2ec9305048acd08c (diff)
downloadmongo-1bb3d4a00461d0aea02cf76eb7073d1776c7bc04.tar.gz
fix base64 issue
-rw-r--r--dbtests/basictests.cpp36
-rw-r--r--util/base64.cpp33
-rw-r--r--util/base64.h2
3 files changed, 55 insertions, 16 deletions
diff --git a/dbtests/basictests.cpp b/dbtests/basictests.cpp
index 5bf22b83f0b..2a9ecfbf9e0 100644
--- a/dbtests/basictests.cpp
+++ b/dbtests/basictests.cpp
@@ -55,6 +55,29 @@ namespace BasicTests {
ASSERT_EQUALS( s , base64::decode( base64::encode( s ) ) );
}
+ void roundTrip( const char * data , int len ){
+ string s = base64::encode( data , len );
+ string out = base64::decode( s );
+ ASSERT_EQUALS( out.size() , len );
+ bool broke = false;
+ for ( int i=0; i<len; i++ ){
+ if ( data[i] != out[i] )
+ broke = true;
+ }
+ if ( ! broke )
+ return;
+
+ cout << s << endl;
+ for ( int i=0; i<len; i++ )
+ cout << hex << ( data[i] & 0xFF ) << dec << " ";
+ cout << endl;
+ for ( int i=0; i<len; i++ )
+ cout << hex << ( out[i] & 0xFF ) << dec << " ";
+ cout << endl;
+
+ ASSERT(0);
+ }
+
void run(){
ASSERT_EQUALS( "ZWxp" , base64::encode( "eli" , 3 ) );
@@ -71,6 +94,19 @@ namespace BasicTests {
roundTrip( "eliot" );
roundTrip( "eliots" );
roundTrip( "eliotsz" );
+
+ char z[] = { 0x1 , 0x2 , 0x3 , 0x4 };
+ roundTrip( z , 4 );
+
+ char y[] = {
+ 0x01, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8B, 0x30,
+ 0xD3, 0x8F, 0x41, 0x14, 0x93, 0x51, 0x55, 0x97, 0x61, 0x96,
+ 0x9B, 0x71, 0xD7, 0x9F, 0x82, 0x18, 0xA3, 0x92, 0x59, 0xA7,
+ 0xA2, 0x9A, 0xAB, 0xB2, 0xDB, 0xAF, 0xC3, 0x1C, 0xB3, 0xD3,
+ 0x5D, 0xB7, 0xE3, 0x9E, 0xBB, 0xF3, 0xDF, 0xBF
+ };
+ roundTrip( y , 4 );
+ roundTrip( y , 40 );
}
};
diff --git a/util/base64.cpp b/util/base64.cpp
index 15b9cbbc3d3..ab2594888a8 100644
--- a/util/base64.cpp
+++ b/util/base64.cpp
@@ -49,8 +49,13 @@ namespace mongo {
assert( encode[i] == toupper( encode[i+26] ) );
}
-
+ char e( int x ){
+ return encode[x&0x3f];
+ }
+
+ private:
const char * encode;
+ public:
char * decode;
} alphabet;
@@ -61,28 +66,28 @@ namespace mongo {
const char * start = data + i;
// byte 0
- ss << alphabet.encode[start[0]>>2];
+ ss << alphabet.e(start[0]>>2);
// byte 1
- char temp = ( start[0] & 0x3 ) << 4;
+ char temp = ( start[0] << 4 );
if ( left == 1 ){
- ss << alphabet.encode[temp];
+ ss << alphabet.e(temp);
break;
}
- temp |= start[1] >> 4;
- ss << alphabet.encode[temp];
+ temp |= ( ( start[1] >> 4 ) & 0xF );
+ ss << alphabet.e(temp);
// byte 2
temp = ( start[1] & 0xF ) << 2;
if ( left == 2 ){
- ss << alphabet.encode[temp];
+ ss << alphabet.e(temp);
break;
}
- temp |= start[2] >> 6;
- ss << alphabet.encode[temp];
+ temp |= ( ( start[2] >> 6 ) & 0x3 );
+ ss << alphabet.e(temp);
// byte 3
- ss << alphabet.encode[start[2] & 0x3f];
+ ss << alphabet.e(start[2] & 0x3f);
}
int mod = size % 3;
@@ -114,12 +119,10 @@ namespace mongo {
char buf[4];
buf[3] = 0;
for ( int i=0; i<size; i+=4){
- memset( buf , 0 , 4 );
const char * start = data + i;
- buf[0] = ( alphabet.decode[start[0]] << 2 ) | ( alphabet.decode[start[1]] >> 4 );
- buf[1] = ( alphabet.decode[start[1]] << 4 ) | ( alphabet.decode[start[2]] >> 2 );
- buf[2] = ( alphabet.decode[start[2]] << 6 ) | ( alphabet.decode[start[3]] );
-
+ buf[0] = ( ( alphabet.decode[start[0]] << 2 ) & 0xFC ) | ( ( alphabet.decode[start[1]] >> 4 ) & 0x3 );
+ buf[1] = ( ( alphabet.decode[start[1]] << 4 ) & 0xF0 ) | ( ( alphabet.decode[start[2]] >> 2 ) & 0xF );
+ buf[2] = ( ( alphabet.decode[start[2]] << 6 ) & 0xC0 ) | ( ( alphabet.decode[start[3]] & 0x3F ) );
ss << buf;
}
}
diff --git a/util/base64.h b/util/base64.h
index 305e45af1c8..c9dde9c23dc 100644
--- a/util/base64.h
+++ b/util/base64.h
@@ -21,7 +21,7 @@
namespace mongo {
namespace base64 {
- void encode( stringstream& ss , void * data , int size );
+ void encode( stringstream& ss , const char * data , int size );
string encode( const char * data , int size );
string encode( const string& s );