Script 'mail_helper' called by obssrc
Hello community,

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

Package is "kmime"

Mon Dec 15 11:49:00 2025 rev:124 rq:1322420 version:25.12.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/kmime/kmime.changes      2025-11-08 
16:29:12.454837576 +0100
+++ /work/SRC/openSUSE:Factory/.kmime.new.1939/kmime.changes    2025-12-15 
11:50:11.334748579 +0100
@@ -1,0 +2,16 @@
+Sat Dec  6 11:40:48 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/
+- No code change since 25.11.80
+
+-------------------------------------------------------------------
+Sat Nov 15 19:56:51 UTC 2025 - Christophe Marin <[email protected]>
+
+- Update to 25.11.80
+  * New feature release
+- Too many changes to list here.
+
+-------------------------------------------------------------------

Old:
----
  kmime-25.08.3.tar.xz
  kmime-25.08.3.tar.xz.sig

New:
----
  kmime-25.12.0.tar.xz
  kmime-25.12.0.tar.xz.sig

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

Other differences:
------------------
++++++ kmime.spec ++++++
--- /var/tmp/diff_new_pack.4KRj51/_old  2025-12-15 11:50:12.398792859 +0100
+++ /var/tmp/diff_new_pack.4KRj51/_new  2025-12-15 11:50:12.406793192 +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:           kmime
-Version:        25.08.3
+Version:        25.12.0
 Release:        0
 Summary:        KDE PIM libraries MIME support
 License:        LGPL-2.1-or-later


++++++ kmime-25.08.3.tar.xz -> kmime-25.12.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/.gitattributes 
new/kmime-25.12.0/.gitattributes
--- old/kmime-25.08.3/.gitattributes    1970-01-01 01:00:00.000000000 +0100
+++ new/kmime-25.12.0/.gitattributes    2025-12-01 07:01:16.000000000 +0100
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: CC0-1.0
+# SPDX-FileCopyrightText: none
+
+*.yenc binary
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/.gitlab-ci.yml 
new/kmime-25.12.0/.gitlab-ci.yml
--- old/kmime-25.08.3/.gitlab-ci.yml    2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/.gitlab-ci.yml    2025-12-01 07:01:16.000000000 +0100
@@ -15,3 +15,4 @@
       - /gitlab-templates/alpine-qt6.yml
       - /gitlab-templates/xml-lint.yml
       - /gitlab-templates/yaml-lint.yml
+      - /gitlab-templates/oss-fuzz.yml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/CMakeLists.txt 
new/kmime-25.12.0/CMakeLists.txt
--- old/kmime-25.08.3/CMakeLists.txt    2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/CMakeLists.txt    2025-12-01 07:01:16.000000000 +0100
@@ -1,15 +1,16 @@
 cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
-set(PIM_VERSION "6.5.3")
+set(PIM_VERSION "6.6.0")
 
 project(KMime VERSION ${PIM_VERSION})
 
 # ECM setup
-set(KF_MIN_VERSION "6.14.0")
+set(KF_MIN_VERSION "6.18.0")
 
 find_package(ECM ${KF_MIN_VERSION} CONFIG REQUIRED)
 set(CMAKE_MODULE_PATH ${KMime_SOURCE_DIR}/cmake ${ECM_MODULE_PATH})
 
 set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_SCAN_FOR_MODULES OFF)
 set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
 
 include(KDEInstallDirs)
@@ -42,10 +43,12 @@
 option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt 
Assistant, Qt Creator & KDevelop)" OFF)
 add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. 
Qt Assistant, Qt Creator & KDevelop)")
 
+option(BUILD_FUZZERS "Build KMime fuzzers" OFF)
+
 ########### Find packages ###########
 find_package(KF6Codecs ${KF_MIN_VERSION} CONFIG REQUIRED)
 add_definitions(-DQT_NO_CONTEXTLESS_CONNECT)
-ecm_set_disabled_deprecation_versions(QT 6.10.0  KF 6.16.0)
+ecm_set_disabled_deprecation_versions(QT 6.10.0  KF 6.20.0)
 
 option(USE_UNITY_CMAKE_SUPPORT "Use UNITY cmake support (speedup compile 
time)" OFF)
 
@@ -62,6 +65,10 @@
     add_subdirectory(tests)
 endif()
 
+if(BUILD_FUZZERS)
+    add_subdirectory(autotests/ossfuzz)
+endif()
+
 ########### CMake Config Files ###########
 set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KPim6Mime")
 if(BUILD_QCH)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/contenttest.cpp 
new/kmime-25.12.0/autotests/contenttest.cpp
--- old/kmime-25.08.3/autotests/contenttest.cpp 2025-11-01 08:28:58.000000000 
+0100
+++ new/kmime-25.12.0/autotests/contenttest.cpp 2025-12-01 07:01:16.000000000 
+0100
@@ -16,6 +16,7 @@
 #include <type_traits>
 
 using namespace KMime;
+using namespace Qt::Literals;
 
 QTEST_MAIN(ContentTest)
 
@@ -267,14 +268,46 @@
 {
     auto c = new Content();
     c->setBody("\0");
-    QVERIFY(c->decodedContent() == QByteArray());
+    QVERIFY(c->decodedBody() == QByteArray());
     c->setBody(QByteArray());
-    QVERIFY(c->decodedContent() == QByteArray());
+    QVERIFY(c->decodedBody() == QByteArray());
     c->setBody(" ");
-    QVERIFY(c->decodedContent() == QByteArray(" "));
+    QVERIFY(c->decodedBody() == QByteArray(" "));
     delete c;
 }
 
+void ContentTest::testDecodedText()
+{
+    {
+        Content c{};
+        c.setEncodedBody("plain text");
+        QCOMPARE(c.decodedText(), u"plain text"_s);
+    }
+    {
+        Content c{};
+        auto cte = std::make_unique<Headers::ContentTransferEncoding>();
+        cte->setEncoding(Headers::CEbase64);
+        c.setHeader(cte.release());
+        c.setEncodedBody("YmFzZTY0LWVuY29kZWQgdGV4dA==");
+        QCOMPARE(c.decodedText(), u"base64-encoded text"_s);
+        QCOMPARE(c.decodedBody(), "base64-encoded text\n");
+    }
+    {
+        Content c{};
+        auto cte = std::make_unique<Headers::ContentTransferEncoding>();
+        cte->setEncoding(Headers::CEbase64);
+        c.setHeader(cte.release());
+        auto ct = std::make_unique<Headers::ContentType>();
+        ct->setMimeType("text/pgp");
+        c.setHeader(ct.release());
+        
c.setEncodedBody("YmFzZTY0LWVuY29kZWQgYmluYXJ5IGJsb2Igb2YgZW5jcnlwdGVkIHRleHQ=");
+        // content of type text/pgp might be a binary blob of encrypted text; 
it must not be decoded as text
+        QCOMPARE(c.decodedText(), QString{});
+        QCOMPARE(c.decodedBody(), "base64-encoded binary blob of encrypted 
text");
+    }
+
+}
+
 void ContentTest::testMultipleHeaderExtraction()
 {
     QByteArray data =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/contenttest.h 
new/kmime-25.12.0/autotests/contenttest.h
--- old/kmime-25.08.3/autotests/contenttest.h   2025-11-01 08:28:58.000000000 
+0100
+++ new/kmime-25.12.0/autotests/contenttest.h   2025-12-01 07:01:16.000000000 
+0100
@@ -18,6 +18,7 @@
     void testSetContent();
     void testEncodedContent();
     void testDecodedContent();
+    void testDecodedText();
     void testMultipartMixed();
     void testMultipleHeaderExtraction();
     /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kmime-25.08.3/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-4804196479336448
 
new/kmime-25.12.0/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-4804196479336448
--- 
old/kmime-25.08.3/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-4804196479336448
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/kmime-25.12.0/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-4804196479336448
       2025-12-01 07:01:16.000000000 +0100
@@ -0,0 +1 @@
+=ybegin line=name=size=2147483647
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kmime-25.08.3/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-5617955779182592
 
new/kmime-25.12.0/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-5617955779182592
--- 
old/kmime-25.08.3/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-5617955779182592
       1970-01-01 01:00:00.000000000 +0100
+++ 
new/kmime-25.12.0/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-5617955779182592
       2025-12-01 07:01:16.000000000 +0100
@@ -0,0 +1,5 @@
+
+begin 216
+
+M
+end.eml
\ No newline at end of file
Binary files 
old/kmime-25.08.3/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-6349101081100288
 and 
new/kmime-25.12.0/autotests/data/clusterfuzz-testcase-minimized-kmime_fuzzer-6349101081100288
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kmime-25.08.3/autotests/data/yenc-single-part-corrupt-size.yenc 
new/kmime-25.12.0/autotests/data/yenc-single-part-corrupt-size.yenc
--- old/kmime-25.08.3/autotests/data/yenc-single-part-corrupt-size.yenc 
1970-01-01 01:00:00.000000000 +0100
+++ new/kmime-25.12.0/autotests/data/yenc-single-part-corrupt-size.yenc 
2025-12-01 07:01:16.000000000 +0100
@@ -0,0 +1,17 @@
+From: [email protected]
+Newsgroups: yenc
+Date: 27 Oct 2001 15:07:44 +0200
+Subject: yEnc-Prefix: "testfile.txt" 584 yEnc bytes - yEnc test (1)
+Message-ID: <[email protected]>
+Path: liebchen.winews.net!not-for-mail
+Lines: 16
+X-Newsreader: MyNews
+
+-- 
+=ybegin line=128 size=2147483647 name=testfile.txt 
+�o��JWJ~�������JR[S74k}mssdJ\__XXZ74)('&%$#"! =M
=J=I=@����������������������������������������������
+��������������������������������������������������������������������������������~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSR
+QPONMLKJIHGFEDCBA@?>=}<;:9876543210/=n-,+*74k}mssdJZXX\__74*+,-=n/0123456789:;<=}>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl
+mnopqrstuvwxyz{|}~�������������������������������������������������������������������������������������������������������������
+�������������������=@=I=J=M 
!"#$%&'()74o��J��J~�������74
+=yend size=584 crc32=ded29f4f 
Binary files old/kmime-25.08.3/autotests/data/yenc-single-part.txt and 
new/kmime-25.12.0/autotests/data/yenc-single-part.txt differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/data/yenc-single-part.yenc 
new/kmime-25.12.0/autotests/data/yenc-single-part.yenc
--- old/kmime-25.08.3/autotests/data/yenc-single-part.yenc      1970-01-01 
01:00:00.000000000 +0100
+++ new/kmime-25.12.0/autotests/data/yenc-single-part.yenc      2025-12-01 
07:01:16.000000000 +0100
@@ -0,0 +1,17 @@
+From: [email protected]
+Newsgroups: yenc
+Date: 27 Oct 2001 15:07:44 +0200
+Subject: yEnc-Prefix: "testfile.txt" 584 yEnc bytes - yEnc test (1)
+Message-ID: <[email protected]>
+Path: liebchen.winews.net!not-for-mail
+Lines: 16
+X-Newsreader: MyNews
+
+-- 
+=ybegin line=128 size=584 name=testfile.txt 
+�o��JWJ~�������JR[S74k}mssdJ\__XXZ74)('&%$#"! =M
=J=I=@����������������������������������������������
+��������������������������������������������������������������������������������~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSR
+QPONMLKJIHGFEDCBA@?>=}<;:9876543210/=n-,+*74k}mssdJZXX\__74*+,-=n/0123456789:;<=}>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl
+mnopqrstuvwxyz{|}~�������������������������������������������������������������������������������������������������������������
+�������������������=@=I=J=M 
!"#$%&'()74o��J��J~�������74
+=yend size=584 crc32=ded29f4f 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/messagetest.cpp 
new/kmime-25.12.0/autotests/messagetest.cpp
--- old/kmime-25.08.3/autotests/messagetest.cpp 2025-11-01 08:28:58.000000000 
+0100
+++ new/kmime-25.12.0/autotests/messagetest.cpp 2025-12-01 07:01:16.000000000 
+0100
@@ -44,10 +44,8 @@
     QCOMPARE(msg2->mainBodyPart("text/plain"), text);
     QCOMPARE(msg2->mainBodyPart("text/html"), (Content *)nullptr);
 
-    // Careful with removing content here.  If we remove one of the two 
contents
-    // (by adding it to another message), the multipart will automatically be
-    // converted to a single-part, deleting the other content!
-    msg2->clearContents(false);
+    msg2->takeContent(text);
+    msg2->takeContent(html);
 
     // multipart/alternative
     msg->contentType()->setMimeType("multipart/alternative");
@@ -712,6 +710,10 @@
     QTest::newRow("digits-overflow") << u"read-digits-overflow.mbox"_s;
     QTest::newRow("uninitialized-memory") << 
u"uninitialized-memory-use.mbox"_s;
     QTest::newRow("infinite-memory") << 
u"clusterfuzz-testcase-minimized-kmime_fuzzer-5255984894509056"_s;
+    QTest::newRow("assert") << 
u"clusterfuzz-testcase-minimized-kmime_fuzzer-5617955779182592"_s;
+    QTest::newRow("yenc-large-alloc") << 
u"clusterfuzz-testcase-minimized-kmime_fuzzer-4804196479336448"_s;
+    QTest::newRow("yenc-corrupt-size") << u"yenc-single-part.yenc"_s;
+    QTest::newRow("uuencode-no-filename") << 
u"clusterfuzz-testcase-minimized-kmime_fuzzer-6349101081100288"_s;
 }
 
 void MessageTest::testGarbage()
@@ -722,4 +724,16 @@
     QVERIFY(msg);
 }
 
+void MessageTest::testYenc()
+{
+    KMime::Message::Ptr msg = readAndParseMail(u"yenc-single-part.yenc"_s);
+    QVERIFY(msg);
+
+    QFile refFile(QLatin1StringView(TEST_DATA_DIR) + 
"/yenc-single-part.txt"_L1);
+    QVERIFY(refFile.open(QFile::ReadOnly));
+    QCOMPARE(msg->subject()->asUnicodeString(), "yEnc-Prefix: \"testfile.txt\" 
584 yEnc bytes - yEnc test (1)"_L1);
+    QCOMPARE(msg->contents().size(), 2);
+    QCOMPARE(msg->contents()[1]->decodedBody(), refFile.readAll());
+}
+
 #include "moc_messagetest.cpp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/messagetest.h 
new/kmime-25.12.0/autotests/messagetest.h
--- old/kmime-25.08.3/autotests/messagetest.h   2025-11-01 08:28:58.000000000 
+0100
+++ new/kmime-25.12.0/autotests/messagetest.h   2025-12-01 07:01:16.000000000 
+0100
@@ -43,6 +43,8 @@
 
     void testGarbage_data();
     void testGarbage();
+
+    void testYenc();
 private:
     KMime::Message::Ptr readAndParseMail(const QString &mailFile) const;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/ossfuzz/CMakeLists.txt 
new/kmime-25.12.0/autotests/ossfuzz/CMakeLists.txt
--- old/kmime-25.08.3/autotests/ossfuzz/CMakeLists.txt  1970-01-01 
01:00:00.000000000 +0100
+++ new/kmime-25.12.0/autotests/ossfuzz/CMakeLists.txt  2025-12-01 
07:01:16.000000000 +0100
@@ -0,0 +1,20 @@
+# SPDX-FileCopyrightText: 2025 Azhar Momin <[email protected]>
+# SPDX-License-Identifier: BSD-2-Clause
+
+if(DEFINED ENV{LIB_FUZZING_ENGINE})
+    set(fuzzing_engine $ENV{LIB_FUZZING_ENGINE})
+else()
+    if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+        set(fuzzing_engine -fsanitize=fuzzer)
+    else()
+        message(FATAL_ERROR "Fuzzing engine not supported")
+    endif()
+endif()
+
+
+add_executable(kmime_fuzzer kmime_fuzzer.cc)
+target_link_libraries(kmime_fuzzer PRIVATE KPim6Mime ${fuzzing_engine})
+
+set_target_properties(kmime_fuzzer PROPERTIES
+    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/fuzzers
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/ossfuzz/README.md 
new/kmime-25.12.0/autotests/ossfuzz/README.md
--- old/kmime-25.08.3/autotests/ossfuzz/README.md       1970-01-01 
01:00:00.000000000 +0100
+++ new/kmime-25.12.0/autotests/ossfuzz/README.md       2025-12-01 
07:01:16.000000000 +0100
@@ -0,0 +1,35 @@
+<!-- SPDX-FileCopyrightText: 2025 Azhar Momin <[email protected]> -->
+<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
+
+# KMime OSS-Fuzz Integration
+
+## Fuzzing Locally
+Make sure you're using Clang (by setting `CC` and `CXX`), since fuzzing 
requires it. Then build KMime with `BUILD_FUZZERS=ON` to generate the 
`kmime_fuzzer` binary:
+```sh
+cmake -B build -DBUILD_FUZZERS=ON
+cmake --build build
+./build/bin/fuzzers/kmime_fuzzer
+```
+
+## Testing OSS-Fuzz Integration
+Testing OSS-Fuzz integration requires: Python & Docker
+
+First clone the OSS-Fuzz repository:
+```sh
+git clone https://github.com/google/oss-fuzz.git
+```
+
+After navigating to the cloned repository, run the following command to build 
the fuzzers:
+```sh
+python3 infra/helper.py build_image kmime
+python3 infra/helper.py build_fuzzers --sanitizer address kmime
+```
+
+This may take a while since it builds the whole QtBase dependency alongside 
with KMime and KCodecs. Once the build is completed, you can run the fuzzers 
using the following command:
+```sh
+python3 infra/helper.py run_fuzzer kmime kmime_fuzzer
+```
+
+The code for preparing the build lives in the `prepare_build.sh` script and 
the code for building the fuzzers lives in the `build_fuzzers.sh` script (which 
is also responsible for building the dependencies, creating the seed corpus and 
copying the dict file).
+
+For more information on OSS-Fuzz, visit the [official 
website](https://google.github.io/oss-fuzz/).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/ossfuzz/build_fuzzers.sh 
new/kmime-25.12.0/autotests/ossfuzz/build_fuzzers.sh
--- old/kmime-25.08.3/autotests/ossfuzz/build_fuzzers.sh        2025-11-01 
08:28:58.000000000 +0100
+++ new/kmime-25.12.0/autotests/ossfuzz/build_fuzzers.sh        2025-12-01 
07:01:16.000000000 +0100
@@ -3,46 +3,41 @@
 # SPDX-FileCopyrightText: 2025 Azhar Momin <[email protected]>
 # SPDX-License-Identifier: LGPL-2.0-or-later
 
+export PATH="$WORK/bin:$PATH"
+
 cd $SRC/extra-cmake-modules
 cmake . -G Ninja \
-  -DBUILD_TESTING=OFF
+    -DBUILD_TESTING=OFF \
+    -DCMAKE_INSTALL_PREFIX=$WORK
 ninja install -j$(nproc)
 
 cd $SRC/qtbase
-./configure -platform linux-clang-libc++ -prefix /usr -static -opensource 
-confirm-license -debug \
+./configure -platform linux-clang-libc++ -prefix $WORK -static -opensource 
-confirm-license -debug \
     -qt-pcre -qt-zlib \
     -no-glib -no-icu -no-feature-gui -no-feature-sql -no-feature-network 
-no-feature-xml \
-    -no-feature-dbus -no-feature-printsupport
-ninja install -j$(nproc)
-
-cd $SRC/qttools
-cmake . -G Ninja \
-  -DBUILD_SHARED_LIBS=OFF \
-  -DCMAKE_INSTALL_PREFIX=/usr
+    -no-feature-dbus -no-feature-printsupport -no-feature-widgets
 ninja install -j$(nproc)
 
 cd $SRC/kcodecs
 rm -rf poqm
 cmake . -G Ninja \
--DBUILD_SHARED_LIBS=OFF \
--DBUILD_TESTING=OFF
+    -DBUILD_SHARED_LIBS=OFF \
+    -DBUILD_TESTING=OFF \
+    -DCMAKE_INSTALL_PREFIX=$WORK
 ninja install -j$(nproc)
 
 cd $SRC/kmime
 rm -rf poqm
 cmake . -G Ninja \
--DBUILD_SHARED_LIBS=OFF \
--DBUILD_TESTING=OFF
+    -DBUILD_SHARED_LIBS=OFF \
+    -DBUILD_TESTING=OFF \
+    -DBUILD_FUZZERS=ON \
+    -DCMAKE_INSTALL_PREFIX=$WORK
 ninja install -j$(nproc)
 
-$CXX $CXXFLAGS -std=c++20 -fPIC autotests/ossfuzz/kmime_fuzzer.cc -o 
$OUT/kmime_fuzzer \
-    -I /usr/include/QtCore/ \
-    -I /usr/local/include/KPim6/KMime -I /usr/local/include/KPim6/KMime/kmime \
-    -lKPim6Mime -lKF6Codecs \
-    -lQt6Core -lQt6BundledPcre2 -lQt6BundledZLIB \
-    -lm -ldl -lpthread \
-    $LIB_FUZZING_ENGINE
-
+# Copy the fuzzer
+cp bin/fuzzers/kmime_fuzzer $OUT/kmime_fuzzer
+# Create a seed corpus
 find . -name "*.mbox" | zip -q $OUT/kmime_fuzzer_seed_corpus.zip -@
-
+# Copy the dictionary
 cp autotests/ossfuzz/kmime_fuzzer.dict $OUT/kmime_fuzzer.dict
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/ossfuzz/kmime_fuzzer.cc 
new/kmime-25.12.0/autotests/ossfuzz/kmime_fuzzer.cc
--- old/kmime-25.08.3/autotests/ossfuzz/kmime_fuzzer.cc 2025-11-01 
08:28:58.000000000 +0100
+++ new/kmime-25.12.0/autotests/ossfuzz/kmime_fuzzer.cc 2025-12-01 
07:01:16.000000000 +0100
@@ -6,6 +6,7 @@
 #include "message.h"
 
 #include <QCoreApplication>
+#include <QtEnvironmentVariables>
 
 void traverseContent(KMime::Content *content) {
   for (KMime::Content *c : content->contents()) {
@@ -22,6 +23,8 @@
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  qputenv("QT_ENABLE_REGEXP_JIT", "1");
+
   int argc = 0;
   QCoreApplication a(argc, nullptr);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/autotests/ossfuzz/prepare_build.sh 
new/kmime-25.12.0/autotests/ossfuzz/prepare_build.sh
--- old/kmime-25.08.3/autotests/ossfuzz/prepare_build.sh        2025-11-01 
08:28:58.000000000 +0100
+++ new/kmime-25.12.0/autotests/ossfuzz/prepare_build.sh        2025-12-01 
07:01:16.000000000 +0100
@@ -7,6 +7,5 @@
     apt-get install -y cmake ninja-build gperf
 
 git clone --depth 1 --branch=dev git://code.qt.io/qt/qtbase.git
-git clone --depth 1 --branch=dev git://code.qt.io/qt/qttools.git
 git clone --depth 1 -b master 
https://invent.kde.org/frameworks/extra-cmake-modules.git
 git clone --depth 1 -b master https://invent.kde.org/frameworks/kcodecs.git
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/poqm/ca/libkmime6_qt.po 
new/kmime-25.12.0/poqm/ca/libkmime6_qt.po
--- old/kmime-25.08.3/poqm/ca/libkmime6_qt.po   2025-11-01 08:28:58.000000000 
+0100
+++ new/kmime-25.12.0/poqm/ca/libkmime6_qt.po   2025-12-01 07:01:16.000000000 
+0100
@@ -82,17 +82,3 @@
 "Ha fallat la generació d'una Notificació de processament del missatge (MDN) "
 "per al missatge enviat el ${date} a ${to} amb l'assumpte «${subject}». El "
 "motiu s'especifica a la capçalera «Failure:» de sota."
-
-#~ msgctxt "invalid time specified"
-#~ msgid "unknown"
-#~ msgstr "desconegut"
-
-#~ msgid "Today %1"
-#~ msgstr "Avui %1"
-
-#~ msgid "Yesterday %1"
-#~ msgstr "Ahir %1"
-
-#~ msgctxt "1. weekday, 2. time"
-#~ msgid "%1 %2"
-#~ msgstr "%1 %2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/poqm/pt_BR/libkmime6_qt.po 
new/kmime-25.12.0/poqm/pt_BR/libkmime6_qt.po
--- old/kmime-25.08.3/poqm/pt_BR/libkmime6_qt.po        2025-11-01 
08:28:58.000000000 +0100
+++ new/kmime-25.12.0/poqm/pt_BR/libkmime6_qt.po        2025-12-01 
07:01:16.000000000 +0100
@@ -3,21 +3,21 @@
 # This file is distributed under the same license as the PACKAGE package.
 #
 # André Marcelo Alvarenga <[email protected]>, 2014.
-# SPDX-FileCopyrightText: 2025 Marcus Gama <[email protected]>
+# SPDX-FileCopyrightText: 2025 Geraldo Simiao <[email protected]>
 msgid ""
 msgstr ""
 "Project-Id-Version: libkmime5\n"
 "Report-Msgid-Bugs-To: https://bugs.kde.org\n";
 "POT-Creation-Date: 2023-11-20 01:59+0000\n"
-"PO-Revision-Date: 2025-07-23 10:53-0300\n"
-"Last-Translator: Marcus Gama <[email protected]>\n"
+"PO-Revision-Date: 2025-08-20 22:32-0300\n"
+"Last-Translator: Geraldo Simiao <[email protected]>\n"
 "Language-Team: Brazilian Portuguese <[email protected]>\n"
 "Language: pt_BR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Lokalize 25.04.3\n"
+"X-Generator: Lokalize 25.08.0\n"
 "X-Qt-Contexts: true\n"
 
 #: mdn.cpp:53
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/content.cpp 
new/kmime-25.12.0/src/content.cpp
--- old/kmime-25.08.3/src/content.cpp   2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/content.cpp   2025-12-01 07:01:16.000000000 +0100
@@ -227,12 +227,10 @@
     d->body.clear();
 }
 
-void Content::clearContents(bool del)
+void Content::clearContents()
 {
     Q_D(Content);
-    if (del) {
-        qDeleteAll(d->multipartContents);
-    }
+    qDeleteAll(d->multipartContents);
     d->multipartContents.clear();
     d->clearBodyMessage();
 }
@@ -321,7 +319,7 @@
     return e;
 }
 
-QByteArray Content::decodedContent() const
+QByteArray Content::decodedBody() const
 {
     QByteArray ret;
     const Headers::ContentTransferEncoding *ec = contentTransferEncoding();
@@ -372,6 +370,11 @@
     return ret;
 }
 
+QByteArray Content::decodedContent() const
+{
+    return decodedBody();
+}
+
 QString Content::decodedText(DecodedTextTrimOption trimOption) const
 {
     if (!d_ptr->decodeText(this)) {   //this is not a text content !!
@@ -554,7 +557,7 @@
     } else {
         // This is non-textual content.  Re-encode it.
         if (e == Headers::CEbase64) {
-            KCodecs::base64Encode(decodedContent(), d_ptr->body, true);
+            KCodecs::base64Encode(decodedBody(), d_ptr->body, true);
             enc->setEncoding(e);
             d_ptr->m_decoded = false;
         } else {
@@ -672,8 +675,9 @@
 {
     const Headers::ContentTransferEncoding *enc = q->contentTransferEncoding();
 
-    if (const auto ct = q->contentType(); ct && !ct->isText()) {
-        return false; //non textual data cannot be decoded here => use 
decodedContent() instead
+    if (const auto ct = q->contentType(); ct && (!ct->isText() || 
ct->isSubtype("pgp"))) {
+        // content of type text/pgp might be a binary blob of encrypted text; 
it must not be decoded as text
+        return false; //non textual data cannot be decoded here => use 
decodedBody() instead
     }
     if (m_decoded) {
         return true; //nothing to do
@@ -717,7 +721,7 @@
     }
 }
 
-ContentIndex KMime::Content::indexForContent(Content *content) const
+ContentIndex KMime::Content::indexForContent(const Content *content) const
 {
     const auto i = d_ptr->contents().indexOf(content);
     if (i >= 0) {
@@ -861,7 +865,8 @@
         // This seems to be only a part of the message, so we treat it as 
"message/partial".
         ct->setMimeType("message/partial");
         //ct->setId( uniqueString() ); not needed yet
-        ct->setPartialParams(uup.partialCount(), uup.partialNumber());
+        ct->setPartialCount(uup.partialCount());
+        ct->setPartialNumber(uup.partialNumber());
         q->contentTransferEncoding()->setEncoding(Headers::CE7Bit);
     } else {
         // This is a complete message, so treat it as "multipart/mixed".
@@ -886,7 +891,7 @@
         // Now add each of the binary parts as sub-Contents.
         for (int i = 0; i < uup.binaryParts().count(); ++i) {
             auto c = new Content(q);
-            c->contentType()->setMimeType(uup.mimeTypes().at(i));
+            c->contentType()->setMimeType(uup.mimeTypes().at(i) == 
"message/rfc822" ? "text/plain" : uup.mimeTypes().at(i));
             
c->contentType()->setName(QLatin1StringView(uup.filenames().at(i)));
             c->contentTransferEncoding()->setEncoding(Headers::CEuuenc);
             c->contentDisposition()->setDisposition(Headers::CDattachment);
@@ -916,7 +921,8 @@
         // Assume there is exactly one decoded part.  Treat this as 
"message/partial".
         ct->setMimeType("message/partial");
         //ct->setId( uniqueString() ); not needed yet
-        ct->setPartialParams(yenc.partialCount(), yenc.partialNumber());
+        ct->setPartialCount(yenc.partialCount());
+        ct->setPartialNumber(yenc.partialNumber());
         q->contentTransferEncoding()->setEncoding(Headers::CEbinary);
         q->changeEncoding(Headers::CEbase64);   // Convert to base64.
     } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/content.h 
new/kmime-25.12.0/src/content.h
--- old/kmime-25.08.3/src/content.h     2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/content.h     2025-12-01 07:01:16.000000000 +0100
@@ -90,7 +90,7 @@
                     message. Because of this, it will not have any children, 
it has no sub-contents
                     and is therefore a leaf content.
                     Only leaf contents have a body that is not empty, i.e. 
functions that operate
-                    on the body, such as body(), size() and decodedContent(), 
will work only on
+                    on the body, such as body(), size() and decodedBody(), 
will work only on
                     leaf contents.
   - A non-leaf Content: This is a content that itself doesn't have any body, 
but that does have
                         sub-contents.
@@ -213,17 +213,12 @@
   void clear();
 
   /**
-    Removes all sub-Contents from this content.  Deletes them if @p del is 
true.
-    This is different from calling removeContent() on each sub-Content, because
-    removeContent() will convert this to a single-part Content if only one
-    sub-Content is left.  Calling clearContents() does NOT make this Content
-    single-part.
+    Removes all sub-Contents from this content. sub-Contents will be deleted.
+    Calling clearContents() does NOT make this Content single-part.
 
-    @param del Whether to delete the sub-Contents.
-    @see removeContent()
     @since 4.4
   */
-  void clearContents(bool del = true);
+  void clearContents();
 
   /**
     Returns the Content header raw data.
@@ -269,18 +264,15 @@
     Note that the returned header may be empty.
     @param create Whether to create the header if it does not exist.
     @since 4.4.
-
-    KDE5: BIC: FIXME: Why is the default argument false here? That is
-    inconsistent with the methods in KMime::Message!
   */
-  template <typename T> T *header(bool create = false);
+  template <typename T> T *header(bool create = true);
   /**
     Returns the first header of type @tparam T.
 
     Can be @c nullptr if such a header doesn't exist.
     @since 24.08
   */
-  template <typename T> [[nodiscard]] T *header() const;
+  template <typename T> [[nodiscard]] const std::remove_cv_t<T> *header() 
const;
 
   /**
     Returns all @p type headers in the Content.
@@ -542,10 +534,10 @@
    *
    * Note that this will be empty for multipart contents or for encapsulated
    * messages, after parse() has been called.
+   * @since 25.12 (previously decodedContent())
    */
-  // TODO: KDE5: BIC: Rename this to decodedBody(), since only the body is
-  // returned. In contrast, setContent() sets the head and the body! Also, try
-  // to make this const.
+  [[nodiscard]] QByteArray decodedBody() const;
+  [[deprecated("Use decodedBody() instead")]]
   [[nodiscard]] QByteArray decodedContent() const;
 
   /** Options for Content::decodedText().
@@ -558,7 +550,7 @@
   };
 
   /**
-    Returns the decoded text. Additional to decodedContent(), this also
+    Returns the decoded text. Additional to decodedBody(), this also
     applies charset decoding. If this is not a text Content, decodedText()
     returns an empty QString.
 
@@ -570,7 +562,7 @@
   [[nodiscard]] QString decodedText(DecodedTextTrimOption trimOption = NoTrim) 
const;
 
   /**
-    Returns the decoded text. Additional to decodedContent(), this also
+    Returns the decoded text. Additional to decodedBody(), this also
     applies charset decoding. If this is not a text Content, decodedText()
     returns an empty QString.
 
@@ -662,6 +654,7 @@
   */
   void prependContent(Content *content);
 
+  [[deprecated("Use takeContent/appendContent instead")]]
   void replaceContent(Content *oldContent, Content *newContent);
   /**
     Removes the given sub-Content and, if that actually was a sub-content
@@ -699,7 +692,7 @@
     if the Content is not found within the hierarchy.
     @param content the Content object to search.
   */
-  [[nodiscard]] ContentIndex indexForContent(Content *content) const;
+  [[nodiscard]] ContentIndex indexForContent(const Content *content) const;
 
   /**
     Returns true if this is the top-level node in the MIME tree. The top-level
@@ -804,7 +797,7 @@
     return static_cast<T *>(h);
 }
 
-template <typename T> T *Content::header() const
+template <typename T> const std::remove_cv_t<T> *Content::header() const
 {
     Headers::Base *h = headerByType(T::staticType());
     if (h) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/headerparsing.cpp 
new/kmime-25.12.0/src/headerparsing.cpp
--- old/kmime-25.08.3/src/headerparsing.cpp     2025-11-01 08:28:58.000000000 
+0100
+++ new/kmime-25.12.0/src/headerparsing.cpp     2025-12-01 07:01:16.000000000 
+0100
@@ -1089,9 +1089,7 @@
         return false;
     }
 
-    // KDE5 TODO: Don't expose displayName as public, but rather add setter 
for it that
-    //            automatically calls removeBidiControlChars
-    result.displayName = removeBidiControlChars(maybeDisplayName);
+    result.setDisplayName(maybeDisplayName);
 
     // get obs-mbox-list (may contain empty entries):
     scursor++;
@@ -1152,7 +1150,7 @@
     const char *oldscursor = scursor;
     if (parseMailbox(scursor, send, maybeMailbox, isCRLF)) {
         // yes, it is:
-        result.displayName.clear();
+        result.setDisplayName({});
         result.mailboxList.append(maybeMailbox);
         return true;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/headers.cpp 
new/kmime-25.12.0/src/headers.cpp
--- old/kmime-25.08.3/src/headers.cpp   2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/headers.cpp   2025-12-01 07:01:16.000000000 +0100
@@ -371,11 +371,8 @@
 
     // extract the mailboxes and complain if there are groups:
     for (const auto &it : std::as_const(maybeAddressList)) {
-        if (!(it).displayName.isEmpty()) {
-            KMIME_WARN << "mailbox groups in header disallowing them! Name: \""
-                       << (it).displayName << "\""
-                       << Qt::endl
-                          ;
+        if (!(it).displayName().isEmpty()) {
+            KMIME_WARN << "mailbox groups in header disallowing them! Name:" 
<< (it).displayName();
         }
         d->mailboxList += (it).mailboxList;
     }
@@ -967,10 +964,10 @@
     return rv;
 }
 
-void Ident::fromIdent(const Ident* ident)
+void Ident::fromIdent(const Ident &ident)
 {
-    d_func()->encCS = ident->d_func()->encCS;
-    d_func()->msgIdList = ident->d_func()->msgIdList;
+    d_func()->encCS = ident.d_func()->encCS;
+    d_func()->msgIdList = ident.d_func()->msgIdList;
 }
 
 void Ident::appendIdentifier(const QByteArray &id)
@@ -1730,6 +1727,11 @@
     }
 }
 
+void ContentType::setPartialNumber(int number)
+{
+    setParameter(QByteArrayLiteral("number"), QString::number(number));
+}
+
 int ContentType::partialCount() const {
     QByteArray p = parameter("total").toLatin1();
     if (!p.isEmpty()) {
@@ -1739,8 +1741,8 @@
     }
 }
 
-void ContentType::setPartialParams(int total, int number) {
-    setParameter(QByteArrayLiteral("number"), QString::number(number));
+void ContentType::setPartialCount(int total)
+{
     setParameter(QByteArrayLiteral("total"), QString::number(total));
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/headers.h 
new/kmime-25.12.0/src/headers.h
--- old/kmime-25.08.3/src/headers.h     2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/headers.h     2025-12-01 07:01:16.000000000 +0100
@@ -502,9 +502,13 @@
     [[nodiscard]] bool isEmpty() const override;
 
     /**
-      Initialize this identifier Copy the data from
+      Initialize this identifier by copying the data from @p ident.
      */
-    void fromIdent(const Ident* ident);
+    void fromIdent(const Ident &ident);
+    [[deprecated("Use fromIdent(const Ident&) instead")]]
+    void fromIdent(const Ident *ident) {
+        fromIdent(*ident);
+    }
 
     /**
       Returns the list of identifiers contained in this header.
@@ -1113,19 +1117,36 @@
       @see isPartial(), partialCount()
     */
     [[nodiscard]] int partialNumber() const;
+    /**
+      Sets the position of this part in a multi-part set.
+      @see partialCount()
+      @since 25.12
+    */
+    void setPartialNumber(int number);
 
     /**
       Returns the total number of parts in a multi-part set.
       @see isPartial(), partialNumber()
     */
     [[nodiscard]] int partialCount() const;
+    /**
+      Sets the total number of parts in a multi-part set.
+      @see partialCount()
+      @since 25.12
+    */
+    void setPartialCount(int total);
 
     /**
       Sets parameters of a partial MIME entity.
       @param total The total number of entities in the multi-part set.
       @param number The number of this entity in a multi-part set.
+      @deprecated since 25.12, use setPartialCount/setPartialNumber instead.
     */
-    void setPartialParams(int total, int number);
+    [[deprecated("Use setPartialCount/setPartialNumber instead")]]
+    void setPartialParams(int total, int number) {
+        setPartialNumber(number);
+        setPartialCount(total);
+    }
 
 protected:
     bool parse(const char *&scursor, const char *const send, bool isCRLF = 
false) override;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/parsers.cpp 
new/kmime-25.12.0/src/parsers.cpp
--- old/kmime-25.08.3/src/parsers.cpp   2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/parsers.cpp   2025-12-01 07:01:16.000000000 +0100
@@ -267,36 +267,29 @@
 {
 }
 
-bool YENCEncoded::yencMeta(QByteArray &src, const QByteArray &name, int *value)
+bool YENCEncoded::yencMeta(QByteArrayView src, QByteArrayView name, int *value)
 {
-    bool found = false;
-    QByteArray sought = name + '=';
-
-    auto iPos = src.indexOf(sought);
-    if (iPos > -1) {
-        auto pos1 = src.indexOf(' ', iPos);
-        auto pos2 = src.indexOf('\r', iPos);
-        auto pos3 = src.indexOf('\t', iPos);
-        auto pos4 = src.indexOf('\n', iPos);
-        if (pos2 >= 0 && (pos1 < 0 || pos1 > pos2)) {
-            pos1 = pos2;
-        }
-        if (pos3 >= 0 && (pos1 < 0 || pos1 > pos3)) {
-            pos1 = pos3;
+    for (qsizetype idx = 0; idx < src.size() - name.size() - 2;) {
+        idx = src.indexOf(name, idx);
+        if (idx < 0 || idx >= src.size() - name.size() - 2) {
+            return false;
         }
-        if (pos4 >= 0 && (pos1 < 0 || pos1 > pos4)) {
-            pos1 = pos4;
+        idx += name.size();
+        if (src[idx] != '=') {
+            continue;
         }
-        iPos = src.lastIndexOf('=', pos1) + 1;
-        if (iPos < pos1) {
-            char c = src.at(iPos);
-            if (c >= '0' && c <= '9') {
-                found = true;
-                *value = src.mid(iPos, pos1 - iPos).toInt();
-            }
+        ++idx;
+        auto endIdx = idx;
+        for (; endIdx < src.size() && std::isdigit(src[endIdx]); ++endIdx) {}
+        if (endIdx <= idx) {
+            continue;
         }
+
+        *value = src.mid(idx, endIdx - idx).toInt();
+        return true;
     }
-    return found;
+
+    return false;
 }
 
 bool YENCEncoded::parse()
@@ -307,7 +300,7 @@
         qsizetype beginPos = currentPos;
         qsizetype yencStart = currentPos;
         bool containsPart = false;
-        QByteArray fileName;
+        QByteArrayView fileName;
 
         if ((beginPos = m_src.indexOf("=ybegin ", currentPos)) > -1 &&
                 (beginPos == 0 || m_src.at(beginPos - 1) == '\n')) {
@@ -330,7 +323,7 @@
             // Try to identify yenc meta data
 
             // Filenames can contain any embedded chars until end of line
-            QByteArray meta = m_src.mid(beginPos, yencStart - beginPos);
+            auto meta = QByteArrayView(m_src).mid(beginPos, yencStart - 
beginPos);
             qsizetype namePos = meta.indexOf("name=");
             if (namePos == -1) {
                 success = false;
@@ -370,6 +363,10 @@
                     break;
                 }
                 if (!yencMeta(meta, "total", &m_totalNr)) {
+                    if (m_partNr == std::numeric_limits<int>::max()) {
+                        success = false;
+                        break;
+                    }
                     m_totalNr = m_partNr + 1;
                 }
                 if (yencSize == partEnd - partBegin + 1) {
@@ -387,7 +384,8 @@
             int lineLength = 0;
             bool containsEnd = false;
             QByteArray binary;
-            binary.resize(yencSize);
+            // don't allocate more memory than the data we actually have can 
at most expand to
+            binary.reserve(std::max<qsizetype>(0, 
std::min<qsizetype>(m_src.size() * 2, yencSize)));
             while (pos < len) {
                 int ch = m_src.at(pos);
                 if (ch < 0) {
@@ -418,7 +416,8 @@
                             if (totalSize >= yencSize) {
                                 break;
                             }
-                            binary[totalSize++] = ch;
+                            binary.push_back(ch);
+                            ++totalSize;
                             lineLength++;
                         } else {
                             break;
@@ -431,7 +430,8 @@
                         if (totalSize >= yencSize) {
                             break;
                         }
-                        binary[totalSize++] = ch;
+                        binary.push_back(ch);
+                        ++totalSize;
                         lineLength++;
                         pos++;
                     }
@@ -454,7 +454,7 @@
                 success = false;
                 break;
             }
-            meta = m_src.mid(pos, eolPos - pos);
+            meta = QByteArrayView(m_src).mid(pos, eolPos - pos);
             if (!yencMeta(meta, "size", &totalSize)) {
                 success = false;
                 break;
@@ -464,7 +464,7 @@
                 break;
             }
 
-            m_filenames.append(fileName);
+            m_filenames.append(fileName.toByteArray());
             QMimeDatabase db;
             m_mimeTypes.append(db.mimeTypeForFile(QString::fromUtf8(fileName), 
QMimeDatabase::MatchExtension).name().toUtf8());
             m_bins.append(binary);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/parsers_p.h 
new/kmime-25.12.0/src/parsers_p.h
--- old/kmime-25.08.3/src/parsers_p.h   2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/parsers_p.h   2025-12-01 07:01:16.000000000 +0100
@@ -94,7 +94,7 @@
     [[nodiscard]] bool parse();
 
   private:
-    static bool yencMeta(QByteArray &src, const QByteArray &name, int *value);
+    static bool yencMeta(QByteArrayView src, QByteArrayView name, int *value);
 };
 
 } // namespace Parser
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/types.cpp 
new/kmime-25.12.0/src/types.cpp
--- old/kmime-25.08.3/src/types.cpp     2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/types.cpp     2025-12-01 07:01:16.000000000 +0100
@@ -230,6 +230,16 @@
     return rv.join(QLatin1StringView(", "));
 }
 
+QString Address::displayName() const
+{
+    return m_displayName;
+}
+
+void Address::setDisplayName(const QString &displayName)
+{
+    m_displayName = removeBidiControlChars(displayName);
+}
+
 } // namespace Types
 
 } // namespace KMime
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/types.h 
new/kmime-25.12.0/src/types.h
--- old/kmime-25.08.3/src/types.h       2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/types.h       2025-12-01 07:01:16.000000000 +0100
@@ -17,9 +17,15 @@
 namespace KMime
 {
 
+/** Basic data types defined in RFC 2822. */
 namespace Types
 {
 
+/**
+ * Represents an addr-spec according to RFC 2822 §3.4.1.
+ * That's what you might commonly call an email address (but addressing
+ * emails is slightly more complex than that).
+*/
 struct KMIME_EXPORT AddrSpec {
     [[nodiscard]] QString asString() const;
     /*! This is the same as asString(), except it decodes IDNs for display */
@@ -153,9 +159,27 @@
 
 typedef QList<Mailbox> MailboxList;
 
-struct KMIME_EXPORT Address {
-    QString displayName;
+/**
+  Represents an address as defined in RFC 2822 §3.4.
+  That is, a mailbox or a named group, ie. a named list
+  of mailboxes.
+*/
+class KMIME_EXPORT Address {
+public:
+    /** The display name, in case this is a named group.
+     *  @since 25.12 (previously a public member with the same name)
+     */
+    [[nodiscard]] QString displayName() const;
+    /** Set the group name.
+     *  This strips bidi control characters.
+     *  @since 25.12
+     */
+    void setDisplayName(const QString &displayName);
+
+    /** Either a single mailbox or the mailboxes in the named group. */
     MailboxList mailboxList;
+private:
+    QString m_displayName;
 };
 typedef QList<Address> AddressList;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmime-25.08.3/src/util.cpp 
new/kmime-25.12.0/src/util.cpp
--- old/kmime-25.08.3/src/util.cpp      2025-11-01 08:28:58.000000000 +0100
+++ new/kmime-25.12.0/src/util.cpp      2025-12-01 07:01:16.000000000 +0100
@@ -175,6 +175,9 @@
 
 bool isCryptoPart(const Content *content)
 {
+    if (!content) {
+        return false;
+    }
     const auto ct = content->contentType();
     if (!ct || !ct->isMediatype("application")) {
         return false;

Reply via email to