mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 19:24:08 +00:00
Handle dictzip errors without program termination (Fix issue #207)
This commit is contained in:
parent
c45bf96701
commit
2d76ced4d3
|
@ -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( "<div class=\"dictd_article\">DICTZIP error: " )
|
||||
+ dict_error_str( dz ) + "</div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
//sprintf( buf, "Offset: %u, Size: %u\n", articleOffset, articleSize );
|
||||
|
||||
string articleText = string( "<div class=\"dictd_article\">" ) +
|
||||
Html::preformat( articleBody ) + "</div>";
|
||||
|
||||
free( articleBody );
|
||||
articleText = string( "<div class=\"dictd_article\">" ) +
|
||||
Html::preformat( articleBody ) + "</div>";
|
||||
free( articleBody );
|
||||
}
|
||||
|
||||
// Ok. Now, does it go to main articles, or to alternate ones? We list
|
||||
// main ones first, and alternates after.
|
||||
|
|
79
dictzip.c
79
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
27
dsl.cc
27
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -341,7 +341,11 @@ void StardictDictionary::loadArticle( uint32_t address,
|
|||
}
|
||||
|
||||
if ( !articleBody )
|
||||
throw exCantReadFile( getDictionaryFilenames()[ 2 ] );
|
||||
{
|
||||
// throw exCantReadFile( getDictionaryFilenames()[ 2 ] );
|
||||
articleText = string( "<div class=\"sdict_m\">DICTZIP error: " ) + dict_error_str( dz ) + "</div>";
|
||||
return;
|
||||
}
|
||||
|
||||
articleText.clear();
|
||||
|
||||
|
|
6
xdxf.cc
6
xdxf.cc
|
@ -545,7 +545,11 @@ void XdxfDictionary::loadArticle( uint32_t address,
|
|||
}
|
||||
|
||||
if ( !articleBody )
|
||||
throw exCantReadFile( getDictionaryFilenames()[ 0 ] );
|
||||
{
|
||||
// throw exCantReadFile( getDictionaryFilenames()[ 0 ] );
|
||||
articleText = string( "<div class=\"xdxf\">DICTZIP error: " ) + dict_error_str( dz ) + "</div>";
|
||||
return;
|
||||
}
|
||||
|
||||
articleText = Xdxf2Html::convert( string( articleBody ), Xdxf2Html::XDXF, idxHeader.hasAbrv ? &abrv : NULL, this );
|
||||
|
||||
|
|
Loading…
Reference in a new issue