From 7c9cf28012f65ce6a67651030b817d7d45eda62b Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 25 Oct 2011 15:11:32 +0000 Subject: Fixed bug in base64 decoding. If an attempt is made to read data after the end of the stream has been reached, and the input didn't end with '=' chars then it would return the final buffer an extra time before ending. Now it ends when it should, no matter how many extra times you try to read. --- src/base64.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/base64.cpp') diff --git a/src/base64.cpp b/src/base64.cpp index 18a18e5..04ca009 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -118,6 +118,8 @@ Bu::size Bu::Base64::read( void *pBuf, Bu::size nBytes ) { if( rNext.isEos() ) { + if( iRPos == 0 ) + iRPos = iChars; bEosIn = true; if( j != 0 ) { -- cgit v1.2.3 From 052da60c2c5c4ce80ec0986ea07482348e7aa30a Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 25 Oct 2011 16:04:43 +0000 Subject: Base64 does line wrapping correctly on write, and also doesn't try to flush the write buffer when reading is done. It's...strange, but yeah, it was doing that. Deflate also defaults to zlib compression now, which means you can compress & decompress without using any extra params. Turns out zlib auto-detect won't decompress raw streams, so this is the safest overall option, and the easiest to work with. zlib headers are small, and includes a crc at the end so you can be sure your data is accurate, raw does not. --- default.bld | 4 ++-- src/base64.cpp | 45 +++++++++++++++++++++++++++++++++++++-------- src/base64.h | 4 +++- src/deflate.cpp | 3 --- src/deflate.h | 2 +- 5 files changed, 43 insertions(+), 15 deletions(-) (limited to 'src/base64.cpp') diff --git a/default.bld b/default.bld index 18a2d72..130c1a2 100644 --- a/default.bld +++ b/default.bld @@ -162,12 +162,12 @@ target files("src/tests/*.cpp").replace("src/","").replace(".cpp","") // Some tests need extra libs and whatnot, that goes here. -target ["tests/bzip2", "tests/streamstack", "tests/enc"] +target ["tests/bzip2", "tests/streamstack"] { LDFLAGS += "-lbz2"; } -target ["tests/deflate"] +target ["tests/deflate", "tests/enc"] { LDFLAGS += "-lz"; } diff --git a/src/base64.cpp b/src/base64.cpp index 04ca009..4d659f0 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -13,7 +13,7 @@ const char Bu::Base64::tblEnc[65] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; -Bu::Base64::Base64( Bu::Stream &rNext ) : +Bu::Base64::Base64( Bu::Stream &rNext, int iChunkSize ) : Bu::Filter( rNext ), iBPos( 0 ), iBuf( 0 ), @@ -22,7 +22,9 @@ Bu::Base64::Base64( Bu::Stream &rNext ) : bEosIn( false ), iTotalIn( 0 ), iTotalOut( 0 ), - eMode( Nothing ) + eMode( Nothing ), + iChunkSize( iChunkSize ), + iCurChunk( 0 ) { start(); @@ -62,11 +64,12 @@ Bu::Base64::~Base64() void Bu::Base64::start() { + iCurChunk = 0; } Bu::size Bu::Base64::stop() { -// if( eMode |= Encode ) + if( eMode == Encode ) { char outBuf[4]; int iBUsed = 4-(3-iBPos); @@ -80,17 +83,30 @@ Bu::size Bu::Base64::stop() { outBuf[k] = '='; } - iTotalOut += rNext.write( outBuf, 4 ); + iCurChunk += 4; + if( iChunkSize && iCurChunk >= iChunkSize ) + { + iCurChunk = iCurChunk-iChunkSize; + iTotalOut += rNext.write( outBuf, 4-iCurChunk ); + iTotalOut += rNext.write("\r\n", 2 ); + iTotalOut += rNext.write( outBuf+(4-iCurChunk), iCurChunk ); + } + else + iTotalOut += rNext.write( outBuf, 4 ); return iTotalOut; } -// else -// { + else + { return iTotalIn; -// } + } } Bu::size Bu::Base64::read( void *pBuf, Bu::size nBytes ) { + if( eMode == Encode ) + throw Bu::Base64Exception("Cannot read from an output stream."); + eMode = Decode; + if( bEosIn == true && iRPos == iChars ) return 0; Bu::size sIn = 0; @@ -157,6 +173,10 @@ Bu::size Bu::Base64::read( void *pBuf, Bu::size nBytes ) Bu::size Bu::Base64::write( const void *pBuf, Bu::size nBytes ) { + if( eMode == Decode ) + throw Bu::Base64Exception("Cannot write to an input stream."); + eMode = Encode; + Bu::size sOut = 0; char outBuf[4]; for( Bu::size j = 0; j < nBytes; j++ ) @@ -168,7 +188,16 @@ Bu::size Bu::Base64::write( const void *pBuf, Bu::size nBytes ) { outBuf[3-k] = tblEnc[(iBuf>>(6*k))&0x3f]; } - sOut += rNext.write( outBuf, 4 ); + iCurChunk += 4; + if( iChunkSize && iCurChunk >= iChunkSize ) + { + iCurChunk = iCurChunk-iChunkSize; + sOut += rNext.write( outBuf, 4-iCurChunk ); + sOut += rNext.write("\r\n", 2 ); + sOut += rNext.write( outBuf+(4-iCurChunk), iCurChunk ); + } + else + sOut += rNext.write( outBuf, 4 ); iBPos = iBuf = 0; } } diff --git a/src/base64.h b/src/base64.h index 53d7860..c081ac1 100644 --- a/src/base64.h +++ b/src/base64.h @@ -22,7 +22,7 @@ namespace Bu class Base64 : public Bu::Filter { public: - Base64( Bu::Stream &rNext ); + Base64( Bu::Stream &rNext, int iChunkSize=0 ); virtual ~Base64(); virtual void start(); @@ -51,6 +51,8 @@ namespace Bu Decode = 0x02, }; Mode eMode; + int iChunkSize; + int iCurChunk; }; }; diff --git a/src/deflate.cpp b/src/deflate.cpp index 10a9c5f..2d925a7 100644 --- a/src/deflate.cpp +++ b/src/deflate.cpp @@ -149,9 +149,6 @@ Bu::size Bu::Deflate::read( void *pData, Bu::size nBytes ) for(;;) { int ret = inflate( pState, Z_NO_FLUSH ); - printf("inflate returned %d; avail in=%d, out=%d\n", ret, - pState->avail_in, pState->avail_out ); - nReadTotal += nRead-pState->avail_out; if( ret == Z_STREAM_END ) diff --git a/src/deflate.h b/src/deflate.h index 34e8657..f835cfc 100644 --- a/src/deflate.h +++ b/src/deflate.h @@ -37,7 +37,7 @@ namespace Bu AutoGzip = 0x04|0x03 }; - Deflate( Bu::Stream &rNext, int nCompression=-1, Format eFmt=AutoRaw ); + Deflate( Bu::Stream &rNext, int nCompression=-1, Format eFmt=AutoZlib ); virtual ~Deflate(); virtual void start(); -- cgit v1.2.3