Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kdegraphics-mobipocket for 
openSUSE:Factory checked in at 2025-12-15 11:48:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kdegraphics-mobipocket (Old)
 and      /work/SRC/openSUSE:Factory/.kdegraphics-mobipocket.new.1939 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kdegraphics-mobipocket"

Mon Dec 15 11:48:08 2025 rev:24 rq:1322365 version:25.12.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/kdegraphics-mobipocket/kdegraphics-mobipocket.changes
    2025-11-08 16:28:12.908344846 +0100
+++ 
/work/SRC/openSUSE:Factory/.kdegraphics-mobipocket.new.1939/kdegraphics-mobipocket.changes
  2025-12-15 11:48:54.019531148 +0100
@@ -1,0 +2,38 @@
+Sat Dec  6 11:40:32 UTC 2025 - Christophe Marin <[email protected]>
+
+- Update to 25.12.0
+  * New feature release
+  * For more details please see:
+  * https://kde.org/announcements/gear/25.12.0/
+- Changes since 25.11.80:
+  * Use QTextStream instead of qDebug()
+
+-------------------------------------------------------------------
+Sat Nov 15 19:56:34 UTC 2025 - Christophe Marin <[email protected]>
+
+- Update to 25.11.80
+  * New feature release
+- Changes since 25.08.3:
+  * Remove obsolete private helper method, use more QByteArrayView
+  * Remove Qt5 compatibility code
+  * Remove bogus fallback to random image for thumbnail
+  * Add tool to dump metadata and text
+  * Allow building qmobipocket as a static library
+  * Remove Qt5 support
+  * Test HuffDic robustness against invalid dictionary contents
+  * Avoid overflow of dict offsets in bounds checks
+  * Add heuristic to protect HuffDic decompressor against 'ZIP bombs'
+  * Abort HuffDic decompression on first error
+  * Avoid HuffDic decompressor dictionary out-of-bounds accesses
+  * Verify hasDRM() returns the correct value
+  * Fix invalid QStringDecoder instantiation for cp1252
+  * Add support for categorized logging
+  * Add missing bounds check for HuffDic records
+  * Verify a truncated valid file does not cause invalid reads
+  * Fix invalid QTextCodec access for invalid files
+  * Fix possible out-of-bounds read when determining extra flags
+  * Fix possible out-of-bounds read for EXTH parsing
+  * Move PDB class definition to private header, clean it up
+  * Add missing bounds checks for getImage(), clean up, extend tests
+
+-------------------------------------------------------------------

Old:
----
  kdegraphics-mobipocket-25.08.3.tar.xz
  kdegraphics-mobipocket-25.08.3.tar.xz.sig

New:
----
  kdegraphics-mobipocket-25.12.0.tar.xz
  kdegraphics-mobipocket-25.12.0.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kdegraphics-mobipocket.spec ++++++
--- /var/tmp/diff_new_pack.8r3Rqc/_old  2025-12-15 11:48:55.715601729 +0100
+++ /var/tmp/diff_new_pack.8r3Rqc/_new  2025-12-15 11:48:55.731602395 +0100
@@ -16,12 +16,12 @@
 #
 
 
-%define kf6_version 6.14.0
-%define qt6_version 6.8.0
+%define kf6_version 6.19.0
+%define qt6_version 6.9.0
 
 %bcond_without released
 Name:           kdegraphics-mobipocket
-Version:        25.08.3
+Version:        25.12.0
 Release:        0
 Summary:        E-book plugin and library
 License:        GPL-2.0-or-later


++++++ kdegraphics-mobipocket-25.08.3.tar.xz -> 
kdegraphics-mobipocket-25.12.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/.gitlab-ci.yml 
new/kdegraphics-mobipocket-25.12.0/.gitlab-ci.yml
--- old/kdegraphics-mobipocket-25.08.3/.gitlab-ci.yml   2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/.gitlab-ci.yml   2025-11-16 
23:57:58.000000000 +0100
@@ -5,7 +5,6 @@
   - project: sysadmin/ci-utilities
     file:
       - /gitlab-templates/android-qt6.yml
-      - /gitlab-templates/linux.yml
       - /gitlab-templates/linux-qt6.yml
       - /gitlab-templates/linux-qt6-next.yml
       - /gitlab-templates/freebsd-qt6.yml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/.kde-ci.yml 
new/kdegraphics-mobipocket-25.12.0/.kde-ci.yml
--- old/kdegraphics-mobipocket-25.08.3/.kde-ci.yml      2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/.kde-ci.yml      2025-11-16 
23:57:58.000000000 +0100
@@ -6,9 +6,5 @@
    'require':
     'frameworks/extra-cmake-modules': '@latest-kf6'
 
- - 'on': ['Linux/Qt5', 'FreeBSD/Qt5', 'Windows/Qt5', 'Android/Qt5']
-   'require':
-    'frameworks/extra-cmake-modules': '@stable'
-
 Options:
  require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/CMakeLists.txt 
new/kdegraphics-mobipocket-25.12.0/CMakeLists.txt
--- old/kdegraphics-mobipocket-25.08.3/CMakeLists.txt   2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/CMakeLists.txt   2025-11-16 
23:57:58.000000000 +0100
@@ -2,7 +2,7 @@
 
 project(mobipocket VERSION 3.0.0)
 
-find_package(ECM 5.92.0 REQUIRED NO_MODULE)
+find_package(ECM 6.0 REQUIRED NO_MODULE)
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} )
 
 include(KDEInstallDirs)
@@ -20,14 +20,10 @@
 include(KDEGitCommitHooks)
 include(KDEClangFormat)
 
-set(REQUIRED_QT_VERSION 5.12.0)
-find_package(Qt${QT_MAJOR_VERSION} ${REQUIRED_QT_VERSION} CONFIG REQUIRED Core 
Gui)
+set(REQUIRED_QT_VERSION 6.5.0)
+find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Core Gui)
 
-if (QT_MAJOR_VERSION STREQUAL "6")
-    set(CMAKECONFIG_NAME "QMobipocket6")
-else()
-    set(CMAKECONFIG_NAME "QMobipocket")
-endif()
+set(CMAKECONFIG_NAME "QMobipocket6")
 
 ecm_setup_version(PROJECT
     VARIABLE_PREFIX QMOBIPOCKET
@@ -41,6 +37,7 @@
 )
 
 add_subdirectory(lib)
+add_subdirectory(tools)
 if (BUILD_TESTING)
   add_subdirectory(autotests)
 endif()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kdegraphics-mobipocket-25.08.3/QMobipocketConfig.cmake.in 
new/kdegraphics-mobipocket-25.12.0/QMobipocketConfig.cmake.in
--- old/kdegraphics-mobipocket-25.08.3/QMobipocketConfig.cmake.in       
2025-07-27 16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/QMobipocketConfig.cmake.in       
2025-11-16 23:57:58.000000000 +0100
@@ -3,7 +3,7 @@
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
 
 include(CMakeFindDependencyMacro)
-find_dependency(Qt@QT_MAJOR_VERSION@Core "@REQUIRED_QT_VERSION@")
-find_dependency(Qt@QT_MAJOR_VERSION@Gui "@REQUIRED_QT_VERSION@")
+find_dependency(Qt6Core "@REQUIRED_QT_VERSION@")
+find_dependency(Qt6Gui "@REQUIRED_QT_VERSION@")
 
 include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kdegraphics-mobipocket-25.08.3/autotests/CMakeLists.txt 
new/kdegraphics-mobipocket-25.12.0/autotests/CMakeLists.txt
--- old/kdegraphics-mobipocket-25.08.3/autotests/CMakeLists.txt 2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/autotests/CMakeLists.txt 2025-11-16 
23:57:58.000000000 +0100
@@ -1,8 +1,8 @@
-find_package(Qt${QT_MAJOR_VERSION} ${REQUIRED_QT_VERSION} CONFIG REQUIRED Test)
+find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Test)
 
 add_executable(bitreadertest_bin bitreadertest.cpp)
 target_link_libraries(bitreadertest_bin
-    Qt${QT_MAJOR_VERSION}::Test
+    Qt6::Test
 )
 ecm_mark_as_test(bitreadertest_bin)
 
@@ -15,7 +15,7 @@
     ../lib/decompressor.cpp
 )
 target_link_libraries(decompressortest_bin
-    Qt${QT_MAJOR_VERSION}::Test
+    Qt6::Test
 )
 ecm_mark_as_test(decompressortest_bin)
 
@@ -28,6 +28,6 @@
 ecm_add_test(mobipockettest.cpp
     TEST_NAME "mobipockettest"
     LINK_LIBRARIES
-        Qt${QT_MAJOR_VERSION}::Test
+        Qt6::Test
         qmobipocket
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kdegraphics-mobipocket-25.08.3/autotests/decompressortest.cpp 
new/kdegraphics-mobipocket-25.12.0/autotests/decompressortest.cpp
--- old/kdegraphics-mobipocket-25.08.3/autotests/decompressortest.cpp   
2025-07-27 16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/autotests/decompressortest.cpp   
2025-11-16 23:57:58.000000000 +0100
@@ -23,6 +23,7 @@
     void testRLE_data();
     void testHuffInit();
     void testHuffDecompress();
+    void testFuzzHuff();
     void benchmarkHuffDecompress();
 };
 
@@ -203,6 +204,50 @@
     }
 }
 
+void DecompressorTest::testFuzzHuff()
+{
+    auto verify = [](const auto &decompressor) {
+        QByteArray d(256, '\0');
+        for (int i = 0; i < d.size(); i++) {
+            d[i] = i;
+        }
+        // The output does not matter and is likely
+        // just garbage, but it should not crash
+        auto r = decompressor->decompress(d);
+    };
+
+    auto dict = createHuffIdentityDict();
+
+    for (auto i = dict.at(0).size() - 1; i >= 0; i--) {
+        unsigned char originalValue = dict.at(0).at(i);
+
+        {
+            dict[0][i] = originalValue ^ 0xff;
+            auto decompressor = Decompressor::create('H', dict);
+            verify(decompressor);
+        }
+
+        if ((originalValue == 0) || (originalValue == 0xff)) {
+            dict[0][i] = originalValue;
+            continue;
+        }
+
+        {
+            dict[0][i] = 0;
+            auto decompressor = Decompressor::create('H', dict);
+            verify(decompressor);
+        }
+
+        {
+            dict[0][i] = static_cast<unsigned char>(0xff);
+            auto decompressor = Decompressor::create('H', dict);
+            verify(decompressor);
+        }
+
+        dict[0][i] = originalValue;
+    }
+}
+
 QTEST_GUILESS_MAIN(DecompressorTest)
 
 #include "decompressortest.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/lib/CMakeLists.txt 
new/kdegraphics-mobipocket-25.12.0/lib/CMakeLists.txt
--- old/kdegraphics-mobipocket-25.08.3/lib/CMakeLists.txt       2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/lib/CMakeLists.txt       2025-11-16 
23:57:58.000000000 +0100
@@ -1,8 +1,4 @@
-if (QT_MAJOR_VERSION STREQUAL "6")
-    set(qmobipocket_INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR}/QMobipocket6)
-else()
-    set(qmobipocket_INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR}/QMobipocket)
-endif()
+set(qmobipocket_INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR}/QMobipocket6)
 
 ecm_qt_declare_logging_category(debug_SRCS
     HEADER qmobipocket_debug.h
@@ -12,17 +8,13 @@
     EXPORT QMOBIPOCKET
 )
 
-add_library(qmobipocket SHARED)
+add_library(qmobipocket)
 set_target_properties(qmobipocket PROPERTIES
     VERSION ${QMOBIPOCKET_VERSION}
     SOVERSION ${QMOBIPOCKET_SOVERSION}
-)
-if (QT_MAJOR_VERSION STREQUAL "6")
-    set_target_properties(qmobipocket PROPERTIES
-        LIBRARY_OUTPUT_NAME QMobipocket6
-        EXPORT_NAME QMobipocket6
+    LIBRARY_OUTPUT_NAME QMobipocket6
+    EXPORT_NAME QMobipocket6
     )
-endif()
 
 target_sources( qmobipocket PRIVATE
     decompressor.cpp
@@ -31,28 +23,16 @@
     ${debug_SRCS}
 )
 
-if (QT_MAJOR_VERSION STREQUAL "5")
-    set(_generate_export_header_version_args)
-else()
-    # For Qt6/KF6 world transitively include the version header
-    if(ECM_VERSION VERSION_LESS "5.106")
-        set(include_version_header_code "#include <qmobipocket_version.h>\n")
-        set(_generate_export_header_version_args CUSTOM_CONTENT_FROM_VARIABLE 
include_version_header_code)
-    else()
-        set(_generate_export_header_version_args USE_VERSION_HEADER)
-    endif()
-endif()
-
 ecm_generate_export_header(qmobipocket
      VERSION ${QMOBIPOCKET_VERSION}
      DEPRECATED_BASE_VERSION 0
-    ${_generate_export_header_version_args}
+     USE_VERSION_HEADER}
 )
 
 target_link_libraries (qmobipocket
     PUBLIC
-    Qt${QT_MAJOR_VERSION}::Core
-    Qt${QT_MAJOR_VERSION}::Gui
+    Qt6::Core
+    Qt6::Gui
 )
 
 target_include_directories(qmobipocket
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/lib/bitreader_p.h 
new/kdegraphics-mobipocket-25.12.0/lib/bitreader_p.h
--- old/kdegraphics-mobipocket-25.08.3/lib/bitreader_p.h        2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/lib/bitreader_p.h        2025-11-16 
23:57:58.000000000 +0100
@@ -10,11 +10,7 @@
 class BitReader
 {
 public:
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
     BitReader(QByteArrayView d)
-#else
-    BitReader(const QByteArray &d)
-#endif
         : len(d.size() * 8)
         , data(d)
     {
@@ -62,10 +58,6 @@
     int pos = 0;
     int len = 0;
     int rEndPos = 0; //< position past the LSB of r
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
     QByteArrayView data;
-#else
-    QByteArray data;
-#endif
 };
 } // namespace Mobipocket
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/lib/decompressor.cpp 
new/kdegraphics-mobipocket-25.12.0/lib/decompressor.cpp
--- old/kdegraphics-mobipocket-25.08.3/lib/decompressor.cpp     2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/lib/decompressor.cpp     2025-11-16 
23:57:58.000000000 +0100
@@ -198,11 +198,7 @@
         if (dict_no >= dict_count) {
             return false;
         }
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
         QByteArrayView dict = dicts.at(dict_no);
-#else
-        const QByteArray &dict = dicts.at(dict_no);
-#endif
         auto dict_size = dict.size();
 
         quint32 off1 = 16 + (r & entry_mask) * 2;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/lib/mobipocket.cpp 
new/kdegraphics-mobipocket-25.12.0/lib/mobipocket.cpp
--- old/kdegraphics-mobipocket-25.08.3/lib/mobipocket.cpp       2025-07-27 
16:58:54.000000000 +0200
+++ new/kdegraphics-mobipocket-25.12.0/lib/mobipocket.cpp       2025-11-16 
23:57:58.000000000 +0100
@@ -10,11 +10,7 @@
 #include <QIODevice>
 #include <QImageReader>
 #include <QRegularExpression>
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
 #include <QStringConverter>
-#else
-#include <QTextCodec>
-#endif
 #include <QtEndian>
 
 namespace Mobipocket
@@ -35,23 +31,19 @@
     // number of first record holding image. Usually it is directly after end 
of text, but not always
     quint16 firstImageRecord = 0;
     QMap<Document::MetaKey, QString> metadata;
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
     QStringDecoder toUtf16;
-#else
-    QTextCodec *codec = nullptr;
-#endif
     bool drm = false;
     quint32 extraflags = 0;
 
-    // index of thumbnail in image list. May be specified in EXTH.
-    // If not then just use first image and hope for the best
-    int thumbnailIndex = 0;
+    // index of Thumbnail image in image list. May be specified in EXTH.
+    int thumbnailIndex = -1;
+    // index of Cover image in image list. May be specified in EXTH.
+    int coverIndex = -1;
 
     void init();
     void findFirstImage();
-    void parseEXTH(const QByteArray &data);
+    void parseEXTH(QByteArrayView data);
     void parseHtmlHead(const QString &data);
-    QString readStringRecord(const QByteArray &data);
 };
 
 void DocumentPrivate::parseHtmlHead(const QString &data)
@@ -82,7 +74,8 @@
         metadata[Document::Description] = descriptionMatch.captured(1);
 }
 
-namespace {
+namespace
+{
     const QVector<QByteArray> getHuffRecords(const PDB &pdb)
     {
         const QByteArray header = pdb.getRecord(0);
@@ -130,7 +123,6 @@
     maxRecordSize = qFromBigEndian<quint16>(mhead.constData() + 10);
     if (mhead.size() > 31)
         encoding = qFromBigEndian<quint32>(mhead.constData() + 28);
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
     if (encoding == 65001) {
         toUtf16 = QStringDecoder(QStringDecoder::Utf8);
     } else {
@@ -140,12 +132,6 @@
             toUtf16 = QStringDecoder(QStringConverter::Latin1);
         }
     }
-#else
-    if (encoding == 65001)
-        codec = QTextCodec::codecForName("UTF-8");
-    else
-        codec = QTextCodec::codecForName("CP1252");
-#endif
     if (mhead.size() >= 92)
         parseEXTH(mhead);
 
@@ -158,11 +144,7 @@
 
     // try getting metadata from HTML if nothing or only title was recovered 
from MOBI and EXTH records
     if (metadata.size() < 2 && !drm)
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
         parseHtmlHead(toUtf16(dec->decompress(pdb.getRecord(1))));
-#else
-        parseHtmlHead(codec->toUnicode(dec->decompress(pdb.getRecord(1))));
-#endif
     valid = true;
 }
 
@@ -182,27 +164,14 @@
     }
 }
 
-QString DocumentPrivate::readStringRecord(const QByteArray &data)
-{
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
-    return toUtf16(data);
-#else
-    return codec->toUnicode(data);
-#endif
-}
-
-void DocumentPrivate::parseEXTH(const QByteArray &data)
+void DocumentPrivate::parseEXTH(QByteArrayView data)
 {
     // try to get name
     if (data.size() >= 92) {
         qint32 nameoffset = qFromBigEndian<quint32>(data.constData() + 84);
         qint32 namelen = qFromBigEndian<quint32>(data.constData() + 88);
         if ((nameoffset + namelen) <= data.size()) {
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
             metadata[Document::Title] = toUtf16(data.mid(nameoffset, namelen));
-#else
-            metadata[Document::Title] = codec->toUnicode(data.mid(nameoffset, 
namelen));
-#endif
         }
     }
 
@@ -224,16 +193,19 @@
             break;
         switch (type) {
         case 100:
-            metadata[Document::Author] = readStringRecord(data.mid(offset + 8, 
len - 8));
+            metadata[Document::Author] = toUtf16(data.mid(offset + 8, len - 
8));
             break;
         case 103:
-            metadata[Document::Description] = readStringRecord(data.mid(offset 
+ 8, len - 8));
+            metadata[Document::Description] = toUtf16(data.mid(offset + 8, len 
- 8));
             break;
         case 105:
-            metadata[Document::Subject] = readStringRecord(data.mid(offset + 
8, len - 8));
+            metadata[Document::Subject] = toUtf16(data.mid(offset + 8, len - 
8));
             break;
         case 109:
-            metadata[Document::Copyright] = readStringRecord(data.mid(offset + 
8, len - 8));
+            metadata[Document::Copyright] = toUtf16(data.mid(offset + 8, len - 
8));
+            break;
+        case 201:
+            coverIndex = qFromBigEndian<quint32>(data.constData() + offset + 
8);
             break;
         case 202:
             thumbnailIndex = qFromBigEndian<quint32>(data.constData() + offset 
+ 8);
@@ -259,12 +231,9 @@
     delete d;
 }
 
-namespace {
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
+namespace
+{
 constexpr qsizetype preTrailingDataLength(QByteArrayView data, quint32 flags)
-#else
-qsizetype preTrailingDataLength(QByteArray data, quint32 flags)
-#endif
 {
     if (flags == 0) {
         return data.size();
@@ -294,7 +263,6 @@
     }
     return data.size();
 }
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
 static_assert(preTrailingDataLength({"0\x00", 2}, 0x0) == 2);
 static_assert(preTrailingDataLength({"0\x00", 2}, 0x1) == 1);
 static_assert(preTrailingDataLength({"0\x01", 2}, 0x1) == 0);
@@ -309,7 +277,6 @@
 static_assert(preTrailingDataLength({"abc\x01\x7f\x82", 6}, 0x3) == 2);
 static_assert(preTrailingDataLength({"abc\x81\x80\x02", 6}, 0x6) == 3);
 static_assert(preTrailingDataLength({"abc\x00\x81\x81", 6}, 0x7) == 3);
-#endif
 } // namespace
 
 QString Document::text(int size) const
@@ -327,11 +294,7 @@
         if (size != -1 && whole.size() > size)
             break;
     }
-#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
     return d->toUtf16(whole);
-#else
-    return d->codec ? d->codec->toUnicode(whole) : QString();
-#endif
 }
 
 int Document::imageCount() const
@@ -371,14 +334,12 @@
 
 QImage Document::thumbnail() const
 {
-    QImage img = getImage(d->thumbnailIndex);
-
-    // does not work, try first image
-    if (img.isNull() && d->thumbnailIndex) {
-        d->thumbnailIndex = 0;
-        img = getImage(0);
+    if (QImage img = getImage(d->thumbnailIndex); !img.isNull()) {
+        return img;
     }
-    return img;
+
+    // Fall back to cover image, or return an empty image
+    return getImage(d->coverIndex);
 }
 
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/tools/CMakeLists.txt 
new/kdegraphics-mobipocket-25.12.0/tools/CMakeLists.txt
--- old/kdegraphics-mobipocket-25.08.3/tools/CMakeLists.txt     1970-01-01 
01:00:00.000000000 +0100
+++ new/kdegraphics-mobipocket-25.12.0/tools/CMakeLists.txt     2025-11-16 
23:57:58.000000000 +0100
@@ -0,0 +1,36 @@
+add_executable(mobidump mobidump.cpp)
+target_link_libraries(mobidump
+    Qt6::Core
+    qmobipocket
+)
+
+# Though the dump utility is not a regular test case, running it increases
+# code coverage significantly
+# We check if the output matches using a regular expression
+
+add_test(NAME dump_fail COMMAND mobidump "${CMAKE_CURRENT_SOURCE_DIR}")
+set_tests_properties(dump_fail PROPERTIES
+    # Directories are not valid arguments
+    WILL_FAIL TRUE
+)
+
+add_test(NAME dump_too_many_args COMMAND mobidump 
"${CMAKE_CURRENT_SOURCE_DIR}" "xxx")
+set_tests_properties(dump_too_many_args PROPERTIES
+    WILL_FAIL TRUE
+)
+
+add_test(NAME dump_file_not_found COMMAND mobidump 
"${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist")
+set_tests_properties(dump_file_not_found PROPERTIES
+    # Directories are not valid arguments
+    WILL_FAIL TRUE
+)
+
+add_test(NAME dump_meta COMMAND mobidump 
"${CMAKE_CURRENT_SOURCE_DIR}/../autotests/testdata/test.mobi")
+set_tests_properties(dump_meta PROPERTIES
+    PASS_REGULAR_EXPRESSION "The Big Brown Bear"
+)
+
+add_test(NAME dump_text COMMAND mobidump "-f" 
"${CMAKE_CURRENT_SOURCE_DIR}/../autotests/testdata/test.mobi")
+set_tests_properties(dump_text PROPERTIES
+    PASS_REGULAR_EXPRESSION "This is a sample"
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kdegraphics-mobipocket-25.08.3/tools/mobidump.cpp 
new/kdegraphics-mobipocket-25.12.0/tools/mobidump.cpp
--- old/kdegraphics-mobipocket-25.08.3/tools/mobidump.cpp       1970-01-01 
01:00:00.000000000 +0100
+++ new/kdegraphics-mobipocket-25.12.0/tools/mobidump.cpp       2025-11-16 
23:57:58.000000000 +0100
@@ -0,0 +1,56 @@
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <QFileInfo>
+#include <QTextStream>
+
+#include "mobipocket.h"
+
+int main(int argc, char **argv)
+{
+    QCoreApplication app(argc, argv);
+
+    QCommandLineParser parser;
+    parser.addOption({{QStringLiteral("f"), QStringLiteral("fulltext")}, 
QStringLiteral("Show full text")});
+    parser.addPositionalArgument(QStringLiteral("filename"), 
QStringLiteral("File to process"));
+    parser.process(app);
+
+    if (parser.positionalArguments().size() != 1) {
+        QTextStream(stderr) << "Exactly one argument is accepted" << Qt::endl;
+        parser.showHelp(1);
+    }
+    bool showFulltext = parser.isSet(QStringLiteral("fulltext"));
+
+    auto fi = QFileInfo(parser.positionalArguments().at(0));
+    QString url = fi.absoluteFilePath();
+
+    if (!fi.exists()) {
+        QTextStream(stderr) << "File " << url << " not found" << Qt::endl;
+        return 1;
+    }
+
+    if (!fi.isFile() || !fi.isReadable()) {
+        QTextStream(stderr) << "File " << url << " is not a readable file" << 
Qt::endl;
+        return 1;
+    }
+
+    QFile file(url);
+    file.open(QFile::ReadOnly);
+    Mobipocket::Document doc(&file);
+
+    if (!doc.isValid()) {
+        QTextStream(stderr) << "File " << url << " is not a valid MobiPocket 
file" << Qt::endl;
+        return 1;
+    }
+
+    QTextStream out(stdout);
+    out << "===\nFile metadata:" << Qt::endl;
+    for (const auto &meta : doc.metadata().asKeyValueRange()) {
+        out << meta.first << " \"" << meta.second << "\"" << Qt::endl;
+    }
+    out << "DRM protected:" << (doc.hasDRM() ? " yes" : " no") << Qt::endl;
+    if (showFulltext && !doc.hasDRM()) {
+        out << "===\nRaw text:" << Qt::endl;
+        out << "\"" << doc.text() << "\"" << Qt::endl;
+    }
+    out << "===" << Qt::endl << Qt::endl;
+}

Reply via email to