From ac5fb6be210b63fd7216541679f513dc97491ede Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 31 Jul 2009 17:53:02 +0000 Subject: Wow, Bu::Base64 had a bug about premature end of stream / not base64 data, now it throws exceptions. It'll still try to process bad data for a while though. Also, it turns out that Bu::File never reported EOS, now it does, appropriately. I'm about to change Bu::Stream::isEOS to be Bu::Stream::isEos, this is your warning. --- src/base64.cpp | 10 ++++++++++ src/base64.h | 3 +++ src/file.cpp | 14 +++++++++++--- src/file.h | 1 + src/tests/base64.cpp | 37 ++++++++++++++++++++++++++++++++++--- 5 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/base64.cpp b/src/base64.cpp index c9a6b59..be5fe8d 100644 --- a/src/base64.cpp +++ b/src/base64.cpp @@ -1,5 +1,7 @@ #include "bu/base64.h" +namespace Bu { subExceptionDef( Base64Exception ) } + const char Bu::Base64::tblEnc[65] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; @@ -106,7 +108,15 @@ size_t Bu::Base64::read( void *pBuf, size_t nBytes ) for( int j = 0; j < 4; j++ ) { if( rNext.read( &buf[j], 1 ) == 0 ) + { + if( rNext.isEOS() ) + { + iChars = 0; + bEosIn = true; + throw Base64Exception("Premature end of stream detected while decoding Base64 data."); + } return sIn; + } if( buf[j] == ' ' || buf[j] == '\t' || buf[j] == '\n' || buf[j] == '\r' ) { diff --git a/src/base64.h b/src/base64.h index c7fb737..a00ed0e 100644 --- a/src/base64.h +++ b/src/base64.h @@ -2,9 +2,12 @@ #define BU_BASE64_H #include "bu/filter.h" +#include "bu/exceptionbase.h" namespace Bu { + subExceptionDecl( Base64Exception ); + /** * *@ingroup Streams diff --git a/src/file.cpp b/src/file.cpp index b22461a..0b9bff2 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -16,7 +16,8 @@ namespace Bu { subExceptionDef( FileException ) } Bu::File::File( const Bu::FString &sName, int iFlags ) : - fd( -1 ) + fd( -1 ), + bEos( true ) { fd = ::open( sName.getStr(), getPosixFlags( iFlags ), 0666 ); if( fd < 0 ) @@ -24,11 +25,13 @@ Bu::File::File( const Bu::FString &sName, int iFlags ) : throw Bu::FileException( errno, "%s: %s", strerror(errno), sName.getStr() ); } + bEos = false; } Bu::File::File( int fd ) : fd( fd ) { + bEos = false; } Bu::File::~File() @@ -46,6 +49,7 @@ void Bu::File::close() strerror(errno) ); } fd = -1; + bEos = true; } } @@ -55,7 +59,11 @@ size_t Bu::File::read( void *pBuf, size_t nBytes ) throw FileException("File not open."); ssize_t iRead = ::read( fd, pBuf, nBytes ); - if( iRead < 0 ) + if( iRead == 0 ) + bEos = true; + else if( iRead == -1 && errno == EAGAIN ) + return 0; + else if( iRead < 0 ) throw FileException( errno, "%s", strerror( errno ) ); return iRead; } @@ -105,7 +113,7 @@ void Bu::File::setPosEnd( long pos ) bool Bu::File::isEOS() { - return false; + return bEos; } bool Bu::File::canRead() diff --git a/src/file.h b/src/file.h index 61addae..6f28e7b 100644 --- a/src/file.h +++ b/src/file.h @@ -99,6 +99,7 @@ namespace Bu private: int fd; + bool bEos; }; } diff --git a/src/tests/base64.cpp b/src/tests/base64.cpp index 3122d5c..5e36448 100644 --- a/src/tests/base64.cpp +++ b/src/tests/base64.cpp @@ -1,4 +1,5 @@ #include "bu/file.h" +#include "bu/membuf.h" #include "bu/base64.h" int main( int argc, char *argv[] ) @@ -31,12 +32,42 @@ int main( int argc, char *argv[] ) Bu::File fOut( argv[1], Bu::File::WriteNew ); Bu::Base64 bIn( fIn ); - char buf[16]; + char buf[1024]; for(;;) { - int iRead = bIn.read( buf, 16 ); + int iRead = bIn.read( buf, 1024 ); + printf("Read %d bytes.\n", iRead ); fOut.write( buf, iRead ); - if( iRead < 16 ) + if( iRead == 0 ) + break; + } + } + else if( argv[0][0] == 'D' ) + { + argv++; + Bu::MemBuf mIn; + { + Bu::File fIn( argv[0], Bu::File::Read ); + char buf[1024]; + for(;;) + { + int iRead = fIn.read( buf, 1024 ); + mIn.write( buf, iRead ); + if( iRead < 1024 ) + break; + } + mIn.setPos( 0 ); + } + Bu::File fOut( argv[1], Bu::File::WriteNew ); + Bu::Base64 bIn( mIn ); + + char buf[1024]; + for(;;) + { + int iRead = bIn.read( buf, 1024 ); + printf("Read %d bytes.\n", iRead ); + fOut.write( buf, iRead ); + if( iRead == 0 ) break; } } -- cgit v1.2.3