From d4db51f2780b32d19689096b997e496816370e9c Mon Sep 17 00:00:00 2001 From: shenleban tongying Date: Sun, 10 Nov 2024 21:04:59 -0500 Subject: [PATCH] opt: mdx -> avoid duplicated Adler-32 checksum in zlib decompression --- .clang-tidy | 1 + src/dict/mdictparser.cc | 8 +++----- src/dict/utils/decompress.cc | 19 +++++++++---------- src/dict/utils/decompress.hh | 11 +++++------ 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 42075503..689c8aa3 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -26,6 +26,7 @@ Checks: > -google-default-arguments, -google-readability-casting, -hicpp-deprecated-headers, + -hicpp-no-array-decay, -misc-const-correctness, -misc-include-cleaner, -misc-non-private-member-variables-in-classes, diff --git a/src/dict/mdictparser.cc b/src/dict/mdictparser.cc index b2072852..6ddbd676 100644 --- a/src/dict/mdictparser.cc +++ b/src/dict/mdictparser.cc @@ -264,14 +264,12 @@ bool MdictParser::parseCompressedBlock( qint64 compressedBlockSize, case 0x02000000: // zlib compression - decompressedBlock = zlibDecompress( buf, size ); - - if ( !checkAdler32( decompressedBlock.constData(), decompressedBlock.size(), checksum ) ) { - gdWarning( "MDict: parseCompressedBlock: zlib: checksum does not match" ); + decompressedBlock = zlibDecompress( buf, size, checksum ); + if ( decompressedBlock.isEmpty() ) { + gdWarning( "MDict: parseCompressedBlock: zlib: failed to decompress or checksum does not match" ); return false; } break; - default: gdWarning( "MDict: parseCompressedBlock: unknown type" ); return false; diff --git a/src/dict/utils/decompress.cc b/src/dict/utils/decompress.cc index 25e6efc3..e9f7967d 100644 --- a/src/dict/utils/decompress.cc +++ b/src/dict/utils/decompress.cc @@ -3,20 +3,21 @@ #include #include -#define CHUNK_SIZE 2048 +using std::string; -QByteArray zlibDecompress( const char * bufptr, unsigned length ) +static constexpr qsizetype CHUNK_SIZE = 2048; + +QByteArray zlibDecompress( const char * bufptr, unsigned length, uLong adler32_checksum ) { - z_stream zs; - char buf[ CHUNK_SIZE ]; + z_stream zs{}; QByteArray str; - int res; - memset( &zs, 0, sizeof( zs ) ); + int res = Z_OK; zs.next_in = (Bytef *)bufptr; zs.avail_in = length; res = inflateInit( &zs ); if ( res == Z_OK ) { + char buf[ CHUNK_SIZE ]; while ( res != Z_STREAM_END ) { zs.next_out = (Bytef *)buf; zs.avail_out = CHUNK_SIZE; @@ -27,9 +28,7 @@ QByteArray zlibDecompress( const char * bufptr, unsigned length ) } } } - - inflateEnd( &zs ); - if ( res != Z_STREAM_END ) { + if ( inflateEnd( &zs ) != Z_OK || res != Z_STREAM_END || ( adler32_checksum != 0 && zs.adler != adler32_checksum ) ) { str.clear(); } return str; @@ -37,7 +36,7 @@ QByteArray zlibDecompress( const char * bufptr, unsigned length ) string decompressZlib( const char * bufptr, unsigned length ) { - QByteArray b = zlibDecompress( bufptr, length ); + QByteArray b = zlibDecompress( bufptr, length, 0 ); return string( b.constData(), b.size() ); } diff --git a/src/dict/utils/decompress.hh b/src/dict/utils/decompress.hh index 3d24e8d0..2f217788 100644 --- a/src/dict/utils/decompress.hh +++ b/src/dict/utils/decompress.hh @@ -3,12 +3,11 @@ #include #include -using std::string; +/// @param adler32_checksum 0 to skip checksum +QByteArray zlibDecompress( const char * bufptr, unsigned length, unsigned long adler32_checksum ); -QByteArray zlibDecompress( const char * bufptr, unsigned length ); +std::string decompressZlib( const char * bufptr, unsigned length ); -string decompressZlib( const char * bufptr, unsigned length ); +std::string decompressBzip2( const char * bufptr, unsigned length ); -string decompressBzip2( const char * bufptr, unsigned length ); - -string decompressLzma2( const char * bufptr, unsigned length, bool raw_decoder = false ); +std::string decompressLzma2( const char * bufptr, unsigned length, bool raw_decoder = false );