diff --git a/dictdfiles.cc b/dictdfiles.cc index 4423524f..e47ff70d 100644 --- a/dictdfiles.cc +++ b/dictdfiles.cc @@ -264,18 +264,24 @@ sptr< Dictionary::DataRequest > DictdDictionary::getArticle( wstring const & wor uint32_t articleOffset = decodeBase64( string( tab1 + 1, tab2 - tab1 - 1 ) ); uint32_t articleSize = decodeBase64( tab2 + 1 ); + string articleText; char * articleBody = dict_data_read_( dz, articleOffset, articleSize, 0, 0 ); if ( !articleBody ) - throw exCantReadFile( getDictionaryFilenames()[ 1 ] ); - + { +// throw exCantReadFile( getDictionaryFilenames()[ 1 ] ); + articleText = string( "
DICTZIP error: " ) + + dict_error_str( dz ) + "
"; + } + else + { //sprintf( buf, "Offset: %u, Size: %u\n", articleOffset, articleSize ); - string articleText = string( "
" ) + - Html::preformat( articleBody ) + "
"; - - free( articleBody ); + articleText = string( "
" ) + + Html::preformat( articleBody ) + "
"; + free( articleBody ); + } // Ok. Now, does it go to main articles, or to alternate ones? We list // main ones first, and alternates after. diff --git a/dictzip.c b/dictzip.c index 1c3eeff7..3b808a71 100644 --- a/dictzip.c +++ b/dictzip.c @@ -173,7 +173,7 @@ static void err_fatal( const char *routine, const char *format, ... ) fflush( stderr ); fflush( stdout ); - exit ( 1 ); +// exit ( 1 ); } /* \doc |err_fatal_errno| flushes "stdout", prints a fatal error report on @@ -212,7 +212,7 @@ static void err_fatal_errno( const char *routine, const char *format, ... ) fflush( stderr ); fflush( stdout ); - exit( 1 ); +// exit( 1 ); } /* \doc |err_internal| flushes "stdout", prints the fatal error message, @@ -246,7 +246,7 @@ static void err_internal( const char *routine, const char *format, ... ) fprintf( stderr, "Aborting...\n" ); fflush( stderr ); fflush( stdout ); - abort(); +// abort(); } #ifndef __func__ @@ -273,8 +273,11 @@ static int dict_read_header( const char *filename, unsigned long offset; if (!(str = gd_fopen( filename, "rb" ))) + { err_fatal_errno( __func__, "Cannot open data file \"%s\" for read\n", filename ); + return 1; + } header->filename = NULL;//str_find( filename ); header->headerLength = GZ_XLEN - 1; @@ -326,9 +329,13 @@ static int dict_read_header( const char *filename, header->version |= getc( str ) << 8; if (header->version != 1) + { err_internal( __func__, "dzip header version %d not supported\n", header->version ); + fclose( str ); + return 1; + } header->chunkLength = getc( str ) << 0; header->chunkLength |= getc( str ) << 8; @@ -360,6 +367,8 @@ static int dict_read_header( const char *filename, err_fatal ( __func__, "too long FNAME field in dzip file \"%s\"\n", filename); + fclose( str ); + return 1; } } @@ -379,6 +388,8 @@ static int dict_read_header( const char *filename, err_fatal ( __func__, "too long COMMENT field in dzip file \"%s\"\n", filename); + fclose( str ); + return 1; } } @@ -396,9 +407,13 @@ static int dict_read_header( const char *filename, } if (ftell( str ) != header->headerLength + 1) + { err_internal( __func__, "File position (%lu) != header length + 1 (%d)\n", ftell( str ), header->headerLength + 1 ); + fclose( str ); + return 1; + } fseek( str, -8, SEEK_END ); header->crc = getc( str ) << 0; @@ -543,6 +558,11 @@ char *dict_data_read_ ( end = start + size; buffer = xmalloc( size + 1 ); + if( !buffer ) + { + strcpy( h->errorString, "Cannot allocate memory" ); + return 0; + } if ( !size ) { @@ -557,11 +577,16 @@ char *dict_data_read_ ( assert( h != NULL); switch (h->type) { case DICT_GZIP: +/* err_fatal( __func__, "Cannot seek on pure gzip format files.\n" "Use plain text (for performance)" " or dzip format (for space savings).\n" ); break; +*/ + strcpy( h->errorString, "Cannot seek on pure gzip format files" ); + xfree( buffer ); + return 0; case DICT_TEXT: { #ifdef __WIN32 @@ -575,6 +600,7 @@ char *dict_data_read_ ( fread( buffer, size, 1, h->fd ) != 1 ) #endif { + strcpy( h->errorString, "Cannot read file" ); xfree( buffer ); return 0; } @@ -592,9 +618,16 @@ char *dict_data_read_ ( h->zStream.next_out = NULL; h->zStream.avail_out = 0; if (inflateInit2( &h->zStream, -15 ) != Z_OK) +/* err_internal( __func__, "Cannot initialize inflation engine: %s\n", h->zStream.msg ); +*/ + { + sprintf( h->errorString, "Cannot initialize inflation engine: %s", h->zStream.msg ); + xfree( buffer ); + return 0; + } ++h->initialized; } firstChunk = start / h->chunkLength; @@ -643,9 +676,15 @@ char *dict_data_read_ ( inBuffer = h->cache[target].inBuffer; if (h->chunks[i] >= OUT_BUFFER_SIZE ) { +/* err_internal( __func__, "h->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n", i, h->chunks[i], OUT_BUFFER_SIZE ); +*/ + sprintf( h->errorString, "h->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n", + i, h->chunks[i], OUT_BUFFER_SIZE ); + xfree( buffer ); + return 0; } #ifdef __WIN32 @@ -670,11 +709,24 @@ char *dict_data_read_ ( h->zStream.next_out = (Bytef *)inBuffer; h->zStream.avail_out = h->chunkLength; if (inflate( &h->zStream, Z_PARTIAL_FLUSH ) != Z_OK) - err_fatal( __func__, "inflate: %s\n", h->zStream.msg ); + { +// err_fatal( __func__, "inflate: %s\n", h->zStream.msg ); + sprintf( h->errorString, "inflate: %s\n", h->zStream.msg ); + xfree( buffer ); + return 0; + } if (h->zStream.avail_in) +/* err_internal( __func__, "inflate did not flush (%d pending, %d avail)\n", h->zStream.avail_in, h->zStream.avail_out ); +*/ + { + sprintf( h->errorString, "inflate did not flush (%d pending, %d avail)\n", + h->zStream.avail_in, h->zStream.avail_out ); + xfree( buffer ); + return 0; + } count = h->chunkLength - h->zStream.avail_out; dict_data_filter( inBuffer, &count, h->chunkLength, postFilter ); @@ -689,9 +741,17 @@ char *dict_data_read_ ( pt += lastOffset - firstOffset; } else { if (count != h->chunkLength ) +/* err_internal( __func__, "Length = %d instead of %d\n", count, h->chunkLength ); +*/ + { + sprintf( h->errorString, "Length = %d instead of %d\n", + count, h->chunkLength ); + xfree( buffer ); + return 0; + } memcpy( pt, inBuffer + firstOffset, h->chunkLength - firstOffset ); pt += h->chunkLength - firstOffset; @@ -708,9 +768,16 @@ char *dict_data_read_ ( *pt = '\0'; break; case DICT_UNKNOWN: - err_fatal( __func__, "Cannot read unknown file type\n" ); - break; +// err_fatal( __func__, "Cannot read unknown file type\n" ); + strcpy( h->errorString, "Cannot read unknown file type" ); + xfree( buffer ); + return 0; } return buffer; } + +char *dict_error_str( dictData *data ) +{ + return data->errorString; +} diff --git a/dictzip.h b/dictzip.h index ab045df3..2d3cf4b0 100644 --- a/dictzip.h +++ b/dictzip.h @@ -80,6 +80,7 @@ typedef struct dictData { unsigned long compressedLength; int stamp; dictCache cache[DICT_CACHE_SIZE]; + char errorString[512]; } dictData; @@ -96,6 +97,8 @@ extern char *dict_data_read_ ( const char *preFilter, const char *postFilter ); +extern char *dict_error_str( dictData *data ); + extern int mmap_mode; #ifdef __cplusplus diff --git a/dsl.cc b/dsl.cc index d1d7c0e0..b8353c7c 100644 --- a/dsl.cc +++ b/dsl.cc @@ -503,20 +503,25 @@ void DslDictionary::loadArticle( uint32_t address, } if ( !articleBody ) - throw exCantReadFile( getDictionaryFilenames()[ 0 ] ); - - try { - articleData = - DslIconv::toWstring( - DslIconv::getEncodingNameFor( DslEncoding( idxHeader.dslEncoding ) ), - articleBody, articleSize ); - free( articleBody ); +// throw exCantReadFile( getDictionaryFilenames()[ 0 ] ); + articleData = GD_NATIVE_TO_WS( L"\n\r\t" ) + gd::toWString( QString( "DICTZIP error: " ) + dict_error_str( dz ) ); } - catch( ... ) + else { - free( articleBody ); - throw; + try + { + articleData = + DslIconv::toWstring( + DslIconv::getEncodingNameFor( DslEncoding( idxHeader.dslEncoding ) ), + articleBody, articleSize ); + free( articleBody ); + } + catch( ... ) + { + free( articleBody ); + throw; + } } } diff --git a/stardict.cc b/stardict.cc index 02fbe469..5c6d4855 100644 --- a/stardict.cc +++ b/stardict.cc @@ -341,7 +341,11 @@ void StardictDictionary::loadArticle( uint32_t address, } if ( !articleBody ) - throw exCantReadFile( getDictionaryFilenames()[ 2 ] ); + { +// throw exCantReadFile( getDictionaryFilenames()[ 2 ] ); + articleText = string( "
DICTZIP error: " ) + dict_error_str( dz ) + "
"; + return; + } articleText.clear(); diff --git a/xdxf.cc b/xdxf.cc index 4cd1b23e..37818cdc 100644 --- a/xdxf.cc +++ b/xdxf.cc @@ -545,7 +545,11 @@ void XdxfDictionary::loadArticle( uint32_t address, } if ( !articleBody ) - throw exCantReadFile( getDictionaryFilenames()[ 0 ] ); + { +// throw exCantReadFile( getDictionaryFilenames()[ 0 ] ); + articleText = string( "
DICTZIP error: " ) + dict_error_str( dz ) + "
"; + return; + } articleText = Xdxf2Html::convert( string( articleBody ), Xdxf2Html::XDXF, idxHeader.hasAbrv ? &abrv : NULL, this );