diff options
author | Eliot Horowitz <eliot@10gen.com> | 2009-10-01 01:26:19 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2009-10-01 01:26:19 -0400 |
commit | 1bb3d4a00461d0aea02cf76eb7073d1776c7bc04 (patch) | |
tree | a299e501b4bfe018f1067a4a5d99e7dfd0812b5a | |
parent | cc2377b335c3e169723f24dd2ec9305048acd08c (diff) | |
download | mongo-1bb3d4a00461d0aea02cf76eb7073d1776c7bc04.tar.gz |
fix base64 issue
-rw-r--r-- | dbtests/basictests.cpp | 36 | ||||
-rw-r--r-- | util/base64.cpp | 33 | ||||
-rw-r--r-- | util/base64.h | 2 |
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 ); |