Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libvmime for openSUSE:Factory checked in at 2022-06-19 21:11:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libvmime (Old) and /work/SRC/openSUSE:Factory/.libvmime.new.1548 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libvmime" Sun Jun 19 21:11:08 2022 rev:27 rq:983638 version:0.9.2.175 Changes: -------- --- /work/SRC/openSUSE:Factory/libvmime/libvmime.changes 2022-01-15 20:05:17.341763185 +0100 +++ /work/SRC/openSUSE:Factory/.libvmime.new.1548/libvmime.changes 2022-06-19 21:11:17.138163754 +0200 @@ -1,0 +2,7 @@ +Sat Jun 11 14:40:34 UTC 2022 - Jan Engelhardt <[email protected]> + +- Update to snapshot 0.9.2.175 (fc69321d) + * Added utility function to convert byteArray to HEX string. + * Added support for digest algorithm SHA256 (in certificates). + +------------------------------------------------------------------- Old: ---- debian.libvmime-suse4.install vmime-0.9.2.165.tar.xz New: ---- debian.libvmime-suse5.install vmime-0.9.2.175.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libvmime.spec ++++++ --- /var/tmp/diff_new_pack.JXMW7z/_old 2022-06-19 21:11:17.698164587 +0200 +++ /var/tmp/diff_new_pack.JXMW7z/_new 2022-06-19 21:11:17.718164616 +0200 @@ -17,8 +17,8 @@ Name: libvmime -%define lname libvmime-suse4 -Version: 0.9.2.165 +%define lname libvmime-suse5 +Version: 0.9.2.175 Release: 0 Summary: Library for working with RFC 5322, MIME messages and IMAP/POP/SMTP License: GPL-3.0-or-later @@ -98,6 +98,8 @@ popd %endif +# for some reason I don't care researching in detail, CentOS8 dies with +# a PIC-related relocation error during cmake-configure. Hence forcing -fPIC. %cmake \ -DCMAKE_INSTALL_PREFIX:PATH="%_prefix" \ -DINCLUDE_INSTALL_DIR:PATH="%_includedir" \ @@ -113,9 +115,9 @@ -DVMIME_BUILD_STATIC_LIBRARY:BOOL=OFF \ -DCMAKE_BUILD_TYPE:STRING="RelWithDebInfo" \ -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="$cf" \ - -DCMAKE_CXX_FLAGS:STRING=" " \ + -DCMAKE_CXX_FLAGS:STRING="%{?centos_version:-fPIC} " \ -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING="$cf" \ - -DCMAKE_C_FLAGS:STRING=" " \ + -DCMAKE_C_FLAGS:STRING="%{?centos_version:-fPIC} " \ -DVMIME_BUILD_DOCUMENTATION:BOOL=OFF %cmake_build @@ -135,7 +137,7 @@ %files -n %lname %license COPYING -%_libdir/libvmime-suse.so.4* +%_libdir/libvmime-suse.so.5* %files devel %_includedir/vmime ++++++ _service ++++++ --- /var/tmp/diff_new_pack.JXMW7z/_old 2022-06-19 21:11:17.750164664 +0200 +++ /var/tmp/diff_new_pack.JXMW7z/_new 2022-06-19 21:11:17.754164671 +0200 @@ -2,7 +2,7 @@ <service name="tar_scm" mode="disabled"> <param name="scm">git</param> <param name="url">https://github.com/kisli/vmime</param> - <param name="revision">edcb4b4b1f1feb5d823d2eaba6aa6dda462d0b00</param> + <param name="revision">fc69321d5304c73be685c890f3b30528aadcfeaf</param> <param name="parent-tag">v0.9.2</param> <param name="versionformat">0.9.2.@TAG_OFFSET@</param> </service> ++++++ debian.changelog ++++++ --- /var/tmp/diff_new_pack.JXMW7z/_old 2022-06-19 21:11:17.770164694 +0200 +++ /var/tmp/diff_new_pack.JXMW7z/_new 2022-06-19 21:11:17.774164700 +0200 @@ -1,4 +1,4 @@ -libvmime (0.9.2.165-0) unstable; urgency=low +libvmime (0.9.2.175-0) unstable; urgency=low * Initial package. ++++++ debian.control ++++++ --- /var/tmp/diff_new_pack.JXMW7z/_old 2022-06-19 21:11:17.794164729 +0200 +++ /var/tmp/diff_new_pack.JXMW7z/_new 2022-06-19 21:11:17.794164729 +0200 @@ -5,7 +5,7 @@ Standards-Version: 4.5.0 Build-Depends: debhelper-compat (= 12) -Package: libvmime-suse4 +Package: libvmime-suse5 Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends} Description: Library for working with MIME messages and IMAP/POP/SMTP @@ -13,7 +13,8 @@ Package: libvmime-dev Architecture: any -Depends: ${misc:Depends}, libvmime-suse4 (= ${binary:Version}) +Depends: ${misc:Depends}, libvmime-suse5 (= ${binary:Version}), + libgsasl-dev | libgsasl7-dev, libgnutls28-dev Description: Development files for vmime, an e-mail message library . ++++++ debian.libvmime-dev.install ++++++ --- /var/tmp/diff_new_pack.JXMW7z/_old 2022-06-19 21:11:17.814164760 +0200 +++ /var/tmp/diff_new_pack.JXMW7z/_new 2022-06-19 21:11:17.818164765 +0200 @@ -1,2 +1,4 @@ usr/include/* +usr/lib/*/*.so +usr/lib/*/pkgconfig/ ++++++ debian.libvmime-suse4.install -> debian.libvmime-suse5.install ++++++ ++++++ libvmime-soname.diff ++++++ --- /var/tmp/diff_new_pack.JXMW7z/_old 2022-06-19 21:11:17.858164825 +0200 +++ /var/tmp/diff_new_pack.JXMW7z/_new 2022-06-19 21:11:17.858164825 +0200 @@ -19,7 +19,7 @@ # . Interfaces added (upward-compatible changes): AGE++ # . Interfaces removed: AGE=0 -SET(VMIME_API_VERSION_CURRENT 1) -+SET(VMIME_API_VERSION_CURRENT 4) ++SET(VMIME_API_VERSION_CURRENT 5) SET(VMIME_API_VERSION_REVISION 0) SET(VMIME_API_VERSION_AGE 0) ++++++ libvmime.dsc ++++++ --- /var/tmp/diff_new_pack.JXMW7z/_old 2022-06-19 21:11:17.878164854 +0200 +++ /var/tmp/diff_new_pack.JXMW7z/_new 2022-06-19 21:11:17.882164861 +0200 @@ -1,7 +1,7 @@ Format: 1.0 Source: libvmime Architecture: any -Version: 0.9.2.165 +Version: 0.9.2.175 DEBTRANSFORM-RELEASE: 1 Maintainer: openSUSE <[email protected]> Homepage: https://opensuse.org/ ++++++ vmime-0.9.2.165.tar.xz -> vmime-0.9.2.175.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/address.cpp new/vmime-0.9.2.175/src/vmime/address.cpp --- old/vmime-0.9.2.165/src/vmime/address.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/address.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -71,6 +71,7 @@ const size_t position, const size_t end, size_t* newPosition, + const bool allowGroup, bool *isLastAddressOfGroup ) { @@ -203,13 +204,16 @@ } } - if (newPosition) { + size_t newPos; - if (pos == end) { - *newPosition = end; - } else { - *newPosition = pos + 1; // ',' or ';' - } + if (pos == end) { + newPos = end; + } else { + newPos = pos + 1; // ',' or ';' + } + + if (newPosition) { + *newPosition = newPos; } // Parse extracted address (mailbox or group) @@ -218,13 +222,33 @@ shared_ptr <address> parsedAddress; if (isGroup) { - parsedAddress = make_shared <mailboxGroup>(); + + if (allowGroup) { + + parsedAddress = make_shared <mailboxGroup>(); + + } else { // group not allowed in group, ignore group and continue parsing + + return parseNext( + ctx, + buffer, + newPos, + end, + newPosition, + /* allowGroup */ false, + isLastAddressOfGroup + ); + } + } else { + parsedAddress = make_shared <mailbox>(); } - parsedAddress->parse(ctx, buffer, start, pos, NULL); - parsedAddress->setParsedBounds(start, pos); + if (parsedAddress) { + parsedAddress->parse(ctx, buffer, start, pos, NULL); + parsedAddress->setParsedBounds(start, pos); + } return parsedAddress; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/address.hpp new/vmime-0.9.2.175/src/vmime/address.hpp --- old/vmime-0.9.2.165/src/vmime/address.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/address.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -78,6 +78,7 @@ const size_t position, const size_t end, size_t* newPosition, + const bool allowGroup, bool *isLastAddressOfGroup ); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/addressList.cpp new/vmime-0.9.2.175/src/vmime/addressList.cpp --- old/vmime-0.9.2.165/src/vmime/addressList.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/addressList.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -63,7 +63,7 @@ while (pos < end) { - shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL); + shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, /* allowGroup */ true, NULL); if (parsedAddress) { m_list.push_back(parsedAddress); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/dateTime.cpp new/vmime-0.9.2.175/src/vmime/dateTime.cpp --- old/vmime-0.9.2.165/src/vmime/dateTime.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/dateTime.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -66,6 +66,14 @@ ; hours+min. (HHMM) */ +static const char* dayNames[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +static const char* monthNames[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; void datetime::parseImpl( const parsingContext& /* ctx */, @@ -590,14 +598,6 @@ size_t* newLinePos ) const { - static const char* dayNames[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - static const char* monthNames[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - const int z = ((m_zone < 0) ? -m_zone : m_zone); const int zh = z / 60; const int zm = z % 60; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/mailboxField.cpp new/vmime-0.9.2.175/src/vmime/mailboxField.cpp --- old/vmime-0.9.2.165/src/vmime/mailboxField.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/mailboxField.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -56,7 +56,7 @@ // may have more than one address specified (even if this field // should contain only one). We are never too much careful... shared_ptr <address> parsedAddress = address::parseNext( - ctx, buffer, position, end, newPosition, NULL + ctx, buffer, position, end, newPosition, /* allowGroup */ true, NULL ); if (parsedAddress) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/mailboxGroup.cpp new/vmime-0.9.2.175/src/vmime/mailboxGroup.cpp --- old/vmime-0.9.2.165/src/vmime/mailboxGroup.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/mailboxGroup.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -87,19 +87,13 @@ while (pos < end && !isLastAddressOfGroup) { shared_ptr <address> parsedAddress = - address::parseNext(ctx, buffer, pos, end, &pos, &isLastAddressOfGroup); + address::parseNext(ctx, buffer, pos, end, &pos, /* allowGroup */ false, &isLastAddressOfGroup); if (parsedAddress) { if (parsedAddress->isGroup()) { - shared_ptr <mailboxGroup> group = dynamicCast <mailboxGroup>(parsedAddress); - - // Sub-groups are not allowed in mailbox groups: so, we add all - // the contents of the sub-group into this group... - for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) { - m_list.push_back(vmime::clone(group->getMailboxAt(i))); - } + // Should not happen } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/mailboxList.cpp new/vmime-0.9.2.175/src/vmime/mailboxList.cpp --- old/vmime-0.9.2.165/src/vmime/mailboxList.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/mailboxList.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -204,7 +204,7 @@ while (pos < end) { - shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL); + shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, /* allowGroup */ true, NULL); if (parsedAddress) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/folder.cpp new/vmime-0.9.2.175/src/vmime/net/folder.cpp --- old/vmime-0.9.2.165/src/vmime/net/folder.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/folder.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -56,7 +56,10 @@ void folder::removeMessageChangedListener(events::messageChangedListener* l) { - std::remove(m_messageChangedListeners.begin(), m_messageChangedListeners.end(), l); + m_messageChangedListeners.erase( + std::remove(m_messageChangedListeners.begin(), m_messageChangedListeners.end(), l), + m_messageChangedListeners.end() + ); } @@ -78,7 +81,10 @@ void folder::removeMessageCountListener(events::messageCountListener* l) { - std::remove(m_messageCountListeners.begin(), m_messageCountListeners.end(), l); + m_messageCountListeners.erase( + std::remove(m_messageCountListeners.begin(), m_messageCountListeners.end(), l), + m_messageCountListeners.end() + ); } @@ -100,7 +106,10 @@ void folder::removeFolderListener(events::folderListener* l) { - std::remove(m_folderListeners.begin(), m_folderListeners.end(), l); + m_folderListeners.erase( + std::remove(m_folderListeners.begin(), m_folderListeners.end(), l), + m_folderListeners.end() + ); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPCommand.cpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPCommand.cpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPCommand.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPCommand.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -354,6 +354,25 @@ return createCommand(cmd.str()); } +shared_ptr <IMAPCommand> IMAPCommand::UIDSEARCH( + const std::vector <string>& keys, + const vmime::charset* charset +) { + + std::ostringstream cmd; + cmd.imbue(std::locale::classic()); + cmd << "UID SEARCH"; + + if (charset) { + cmd << " CHARSET " << charset->getName(); + } + + for (size_t i = 0, n = keys.size() ; i < n ; ++i) { + cmd << " " << keys[i]; + } + + return createCommand(cmd.str()); +} // static shared_ptr <IMAPCommand> IMAPCommand::STARTTLS() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPCommand.hpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPCommand.hpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPCommand.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPCommand.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -66,6 +66,7 @@ static shared_ptr <IMAPCommand> APPEND(const string& mailboxName, const std::vector <string>& flags, vmime::datetime* date, const size_t size); static shared_ptr <IMAPCommand> COPY(const messageSet& msgs, const string& mailboxName); static shared_ptr <IMAPCommand> SEARCH(const std::vector <string>& keys, const vmime::charset* charset); + static shared_ptr <IMAPCommand> UIDSEARCH(const std::vector <string>& keys, const vmime::charset* charset); static shared_ptr <IMAPCommand> STARTTLS(); static shared_ptr <IMAPCommand> CAPABILITY(); static shared_ptr <IMAPCommand> NOOP(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPFolder.cpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPFolder.cpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPFolder.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPFolder.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -1502,6 +1502,102 @@ } +std::vector <size_t> IMAPFolder::getMessageNumbersMatchingSearchAttributes( + const IMAPSearchAttributes& sa, + const vmime::charset* charset +) { + + auto searchKeys = sa.generate(); + + IMAPCommand::SEARCH(searchKeys, charset)->send(m_connection); + + // Get the response + scoped_ptr <IMAPParser::response> resp(m_connection->readResponse()); + + if (resp->isBad() || + resp->response_done->response_tagged->resp_cond_state->status != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("SEARCH", resp->getErrorLog(), "bad response"); + } + + auto& respDataList = resp->continue_req_or_response_data; + + std::vector <size_t> seqNumbers; + + for (auto it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if (!(*it)->response_data) { + throw exceptions::command_error("SEARCH", resp->getErrorLog(), "invalid response"); + } + + auto *mailboxData = (*it)->response_data->mailbox_data.get(); + + // We are only interested in responses of type "SEARCH" + if (!mailboxData || + mailboxData->type != IMAPParser::mailbox_data::SEARCH) { + + continue; + } + + for (auto &nzn : mailboxData->search_nz_number_list) { + seqNumbers.push_back(nzn->value); + } + } + + processStatusUpdate(resp.get()); + + return seqNumbers; +} + + +std::vector <message::uid> IMAPFolder::getMessageUIDsMatchingSearchAttributes( + const IMAPSearchAttributes& sa, + const vmime::charset* charset +) { + + auto searchKeys = sa.generate(); + + IMAPCommand::UIDSEARCH(searchKeys, charset)->send(m_connection); + + // Get the response + scoped_ptr <IMAPParser::response> resp(m_connection->readResponse()); + + if (resp->isBad() || + resp->response_done->response_tagged->resp_cond_state->status != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("UIDSEARCH", resp->getErrorLog(), "bad response"); + } + + auto& respDataList = resp->continue_req_or_response_data; + + std::vector <message::uid> uidNumbers; + + for (auto it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if (!(*it)->response_data) { + throw exceptions::command_error("UIDSEARCH", resp->getErrorLog(), "invalid response"); + } + + auto *mailboxData = (*it)->response_data->mailbox_data.get(); + + // We are only interested in responses of type "SEARCH" + if (!mailboxData || + mailboxData->type != IMAPParser::mailbox_data::SEARCH) { + + continue; + } + + for (auto &nzn : mailboxData->search_nz_number_list) { + uidNumbers.push_back(nzn->value); + } + } + + processStatusUpdate(resp.get()); + + return uidNumbers; +} + + void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp) { std::vector <shared_ptr <events::event> > events; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPFolder.hpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPFolder.hpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPFolder.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPFolder.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -39,6 +39,7 @@ #include "vmime/net/folder.hpp" #include "vmime/net/imap/IMAPParser.hpp" +#include "vmime/net/imap/IMAPSearchAttributes.hpp" namespace vmime { @@ -95,7 +96,37 @@ std::vector <size_t> getMessageNumbersStartingOnUID(const message::uid& uid); - size_t getMessageCount(); + /** Return the sequence numbers of messages matching the searchAttributes. + * + * @param sa the searchAttributes containing search tokens to match messages to + * @param charset optional charset name, the string tokens are assumed to be encoded + * in the provided encoding OR need to be in US-ASCII if no charset is provided + * @throw exceptions::net_exception if an error occurs + * + * Quirks: some servers will not accept any encoding other than US-ASCII, + * other servers will accept UTF-8 but will fail utf-8 + */ + std::vector <size_t> getMessageNumbersMatchingSearchAttributes( + const IMAPSearchAttributes& sa, + const vmime::charset* charset = nullptr + ); + + /** Return the UIDs of messages matching the searchAttributes. + * + * @param sa the searchAttributes containing search tokens to match messages to + * @param charset optional charset name, the string tokens are assumed to be encoded + * in the provided encoding OR need to be in US-ASCII if no charset is provided + * @throw exceptions::net_exception if an error occurs + * + * Quirks: some servers will not accept any encoding other than US-ASCII, + * other servers will accept UTF-8 but will fail utf-8 + */ + std::vector <message::uid> getMessageUIDsMatchingSearchAttributes( + const IMAPSearchAttributes& sa, + const vmime::charset* charset = nullptr + ); + + size_t getMessageCount(); shared_ptr <folder> getFolder(const folder::path::component& name); std::vector <shared_ptr <folder> > getFolders(const bool recursive = false); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPSearchAttributes.cpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPSearchAttributes.cpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPSearchAttributes.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPSearchAttributes.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -0,0 +1,574 @@ +#include "vmime/net/imap/IMAPSearchAttributes.hpp" + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/imap/IMAPUtils.hpp" + + +namespace vmime { +namespace net { +namespace imap { + +namespace helpers { + + +class keylessToken : public IMAPSearchToken { + +public: + + keylessToken(const char* token) + : IMAPSearchToken(token) { + } + + void generate(std::ostringstream& out) const { + + out << m_token; + } +}; + + +template <class TYPE> +class typedSearchToken : public IMAPSearchToken { + +public: + + typedSearchToken(const char* token, const TYPE& keyword) + : IMAPSearchToken(token) + , m_keyword(keyword) { + + } + + typedSearchToken(const char* token, const TYPE&& keyword) + : IMAPSearchToken(token) + , m_keyword(std::move(keyword)) { + + } + +protected: + + TYPE m_keyword; +}; + + +// Represents a string search token with the search string quoted +class stringToken : public typedSearchToken <string> { + +public: + + stringToken(const char* token, const string& keyword) + : typedSearchToken(token, keyword) { + + } + + void generate(std::ostringstream& out) const override { + + out << m_token << " \"" << m_keyword << "\""; + }; +}; + + +class headerToken : public typedSearchToken <const char*> { + +public: + + headerToken(const char* token, const char* header) + : typedSearchToken(token, header) { + + } + + headerToken(const char* token, const char* header, const string& headerKeyword) + : typedSearchToken(token, header) + , m_headerKeyword(headerKeyword) { + + } + + void generate(std::ostringstream& out) const override { + + out << m_token << " " << m_keyword << " \"" << m_headerKeyword << "\""; + }; + +protected: + + string m_headerKeyword; +}; + + +class dateToken : public typedSearchToken <vmime::datetime> { + +public: + + dateToken(const char* token, const vmime::datetime& date) + : typedSearchToken(token, date) { + + } + + // RFC claims that we need to disregard time information + void generate(std::ostringstream& out) const override { + + out << m_token << " " << IMAPUtils::searchDate(m_keyword); + }; +}; + + +class numberToken : public typedSearchToken< int > { + +public: + + numberToken(const char* token, uint32_t keyword) + : typedSearchToken(token, keyword) { + + } + + void generate(std::ostringstream& out) const override { + + out << m_token << " " << m_keyword; + }; +}; + + +class flagToken : public typedSearchToken <vmime::net::message::Flags> { + +public: + + flagToken(const char* token, vmime::net::message::Flags keyword) + : typedSearchToken(token, keyword) { + + } + + void generate(std::ostringstream& out) const override { + + out << m_token << " "; + + switch (m_keyword) { + case vmime::net::message::Flags::FLAG_SEEN: out << "Seen"; break; + case vmime::net::message::Flags::FLAG_REPLIED: out << "Answered"; break; + case vmime::net::message::Flags::FLAG_MARKED: out << "Flagged"; break; + case vmime::net::message::Flags::FLAG_DRAFT: out << "Draft"; break; + case vmime::net::message::Flags::FLAG_DELETED: out << "Deleted"; break; + default: throw exceptions::operation_not_supported(); + } + }; +}; + + +class tokenMessageSetEnumerator : public messageSetEnumerator { + +public: + + tokenMessageSetEnumerator() + : m_first(true) { + + m_oss.imbue(std::locale::classic()); + } + + void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) { + + if (!m_first) { + m_oss << ","; + } + + if (range.getFirst() == range.getLast()) { + m_oss << range.getFirst(); + } else if (range.getLast() == size_t(-1)) { + m_oss << range.getFirst() << ":*"; + } else { + m_oss << range.getFirst() << ":" << range.getLast(); + } + + m_first = false; + } + + void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range) { + + if (!m_first) { + m_oss << ","; + } + + if (range.getFirst() == range.getLast()) { + m_oss << range.getFirst(); + } else if (range.getLast() == size_t(-1)) { + m_oss << range.getFirst() << ":*"; + } else { + m_oss << range.getFirst() << ":" << range.getLast(); + } + + m_first = false; + } + + const std::string str() const { + + return m_oss.str(); + } + +private: + + std::ostringstream m_oss; + bool m_first; +}; + + +class messageSetToken : public typedSearchToken <vmime::net::messageSet> { + +public: + + messageSetToken(const char *token, const vmime::net::messageSet& keyword) + : typedSearchToken(token, keyword) { + + } + + messageSetToken(const char *token, const vmime::net::messageSet&& keyword) + : typedSearchToken(token, std::move(keyword)) { + + } + + void generate(std::ostringstream& out) const override { + + if (*m_token) { + out << m_token << " ("; + } + else { + out << "("; + } + tokenMessageSetEnumerator enu; + m_keyword.enumerate(enu); + out << enu.str(); + out << ")"; + } +}; + + +// Contains a list of tokens which the server will interpret as AND +class tokenVectorToken : public typedSearchToken <std::vector <vmime::shared_ptr <const IMAPSearchToken>>> { + +public: + + tokenVectorToken(const char* token, const std::vector <vmime::shared_ptr <const IMAPSearchToken>>& tokensAndKeywords) + : typedSearchToken(token, tokensAndKeywords) { + + if (0 == m_keyword.size()) { + throw exceptions::invalid_argument(); + } + } + + tokenVectorToken(const char* token, const std::vector <vmime::shared_ptr <const IMAPSearchToken>>&& tokensAndKeywords) + : typedSearchToken(token, tokensAndKeywords) { + + if (0 == m_keyword.size()) { + throw exceptions::invalid_argument(); + } + } + + void generate(std::ostringstream& out) const override { + + out << m_token; + + if (*m_token) { + out << " ("; + } else { + out << "("; + } + + m_keyword[0]->generate(out); + + for (size_t i = 1; i < m_keyword.size(); i++) { + out << " "; + m_keyword[i]->generate(out); + } + + out << ")"; + }; +}; + + +// A pair of tokens, used with OR +class tokenPairToken : public typedSearchToken <std::pair <vmime::shared_ptr <const IMAPSearchToken>, vmime::shared_ptr <const IMAPSearchToken>>> { + +public: + + tokenPairToken(const char* token, const std::pair <vmime::shared_ptr <const IMAPSearchToken>, vmime::shared_ptr <const IMAPSearchToken>>& pair) + : typedSearchToken(token, pair) { + + } + + void generate(std::ostringstream& out) const override { + + out << m_token << " "; + m_keyword.first->generate(out); + out << " "; + m_keyword.second->generate(out); + }; +}; + + +} // helpers + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::AND(const std::vector <IMAPSearchTokenPtr> &&keywords) { + + return vmime::make_shared <helpers::tokenVectorToken>("", std::move(keywords)); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::ANSWERED() { + + return vmime::make_shared <helpers::keylessToken>("ANSWERED"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::BCC(const string& keyword) { + + return vmime::make_shared <helpers::stringToken>("BCC", keyword); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::BEFORE(const datetime& keyword) { + + return vmime::make_shared <helpers::dateToken>("BEFORE", keyword); +} + +IMAPSearchTokenPtr IMAPSearchTokenFactory::BODY(const string& keyword) { + + return vmime::make_shared <helpers::stringToken>("BODY", keyword); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::CC(const string& keyword) { + + return vmime::make_shared <helpers::stringToken>("CC", keyword); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::DELETED() { + + return vmime::make_shared <helpers::keylessToken>("DELETED"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::DRAFT() { + + return vmime::make_shared <helpers::keylessToken>("DRAFT"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::FLAGGED() { + + return vmime::make_shared <helpers::keylessToken>("FLAGGED"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::FROM(const string& keyword) { + + return vmime::make_shared <helpers::stringToken>("FROM", keyword); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::HEADER(const char* fieldName) { + + return vmime::make_shared <helpers::headerToken>("HEADER", fieldName); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::HEADER(const char* fieldName, const string& fieldContents) { + + return vmime::make_shared <helpers::headerToken>("HEADER", fieldName, fieldContents); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::KEYWORD(vmime::net::message::Flags flag) { + + return vmime::make_shared <helpers::flagToken>("KEYWORD", flag); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::LARGER(uint32_t size) { + + return vmime::make_shared <helpers::numberToken>("LARGER", size); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::MESSAGESET(const vmime::net::messageSet& set) { + + return vmime::make_shared <helpers::messageSetToken>("", set); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::MESSAGESET(const vmime::net::messageSet&& set) { + + return vmime::make_shared <helpers::messageSetToken>("", std::move(set)); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::NEW() { + + return vmime::make_shared <helpers::keylessToken>("NEW"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::NOT(const IMAPSearchTokenPtr& token) { + + return vmime::make_shared <helpers::tokenVectorToken>("NOT", std::vector <vmime::shared_ptr <const IMAPSearchToken>>({token})); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::OLD() { + + return vmime::make_shared <helpers::keylessToken>("OLD"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::ON(const datetime& date) { + + return vmime::make_shared <helpers::dateToken>("ON", date); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::OR(const IMAPSearchTokenPtr& tokenA, const IMAPSearchTokenPtr& tokenB) { + + return vmime::make_shared <helpers::tokenPairToken>("OR", std::make_pair(tokenA, tokenB)); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::RECENT() { + + return vmime::make_shared <helpers::keylessToken>("RECENT"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::SEEN() { + + return vmime::make_shared <helpers::keylessToken>("SEEN"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::SENTBEFORE(const datetime& date) { + + return vmime::make_shared <helpers::dateToken>("SENTBEFORE", date); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::SENTON(const datetime& date) { + + return vmime::make_shared <helpers::dateToken>("SENTON", date); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::SENTSINCE(const datetime& date) { + + return vmime::make_shared <helpers::dateToken>("SENTSINCE", date); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::SINCE(const datetime& date) { + + return vmime::make_shared <helpers::dateToken>("SINCE", date); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::SMALLER(uint32_t size) { + + return vmime::make_shared <helpers::numberToken>("SMALLER", size); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::SUBJECT(const string& keyword) { + + return vmime::make_shared <helpers::stringToken>("SUBJECT", keyword); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::TEXT(const string& keyword) { + + return vmime::make_shared <helpers::stringToken>("TEXT", keyword); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::TO(const string& keyword) { + + return vmime::make_shared <helpers::stringToken>("TO", keyword); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UID(const vmime::net::messageSet& set) { + + return vmime::make_shared <helpers::messageSetToken>("UID", set); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UID(const vmime::net::messageSet&& set) { + + return vmime::make_shared <helpers::messageSetToken>("UID", std::move(set)); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UNANSWERED() { + + return vmime::make_shared <helpers::keylessToken>("UNANSWERED"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UNDELETED() { + + return vmime::make_shared <helpers::keylessToken>("UNDELETED"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UNDRAFT() { + + return vmime::make_shared <helpers::keylessToken>("UNDRAFT"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UNFLAGGED() { + + return vmime::make_shared <helpers::keylessToken>("UNFLAGGED"); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UNKEYWORD(vmime::net::message::Flags flag) { + + return vmime::make_shared <helpers::flagToken>("UNKEYWORD", flag); +} + + +IMAPSearchTokenPtr IMAPSearchTokenFactory::UNSEEN() { + + return vmime::make_shared <helpers::keylessToken>("UNSEEN"); +} + + +IMAPSearchAttributes::IMAPSearchAttributes(std::vector <vmime::shared_ptr <const IMAPSearchToken>>&& tokens) + : m_andTokens(std::move(tokens)) { +} + + +void IMAPSearchAttributes::add(const vmime::shared_ptr <const IMAPSearchToken>& token) { + + m_andTokens.push_back(token); +} + + +std::vector <string> IMAPSearchAttributes::generate() const { + + std::vector< string > keys; + + for (auto& token : m_andTokens) { + + std::ostringstream key; + key.imbue(std::locale::classic()); + + token->generate(key); + + keys.push_back(key.str()); + } + + return keys; +} + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPSearchAttributes.hpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPSearchAttributes.hpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPSearchAttributes.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPSearchAttributes.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -0,0 +1,150 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPSEARCHATTRIBUTES_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPSEARCHATTRIBUTES_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include <vector> + +#include "vmime/types.hpp" +#include "vmime/utility/stringUtils.hpp" +#include "vmime/dateTime.hpp" +#include "vmime/net/message.hpp" +#include "vmime/net/messageSet.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPSearchToken : public object { + +public: + + IMAPSearchToken(const char* token) + : m_token(token) { + + if (nullptr == m_token) { + throw exceptions::invalid_argument(); + } + } + + virtual void generate(std::ostringstream& out) const = 0; + +protected: + + const char* m_token; +}; + + +typedef vmime::shared_ptr <const IMAPSearchToken> IMAPSearchTokenPtr; + + +class IMAPSearchTokenFactory : public object { + +public: + + static IMAPSearchTokenPtr AND(const std::vector <IMAPSearchTokenPtr>&); + static IMAPSearchTokenPtr AND(const std::vector <IMAPSearchTokenPtr>&&); + static IMAPSearchTokenPtr ANSWERED(); + static IMAPSearchTokenPtr BCC(const string&); + static IMAPSearchTokenPtr BEFORE(const datetime&); + static IMAPSearchTokenPtr BODY(const string&); + static IMAPSearchTokenPtr CC(const string&); + static IMAPSearchTokenPtr DELETED(); + static IMAPSearchTokenPtr DRAFT(); + static IMAPSearchTokenPtr FLAGGED(); + static IMAPSearchTokenPtr FROM(const string&); + static IMAPSearchTokenPtr HEADER(const char* fieldName); + static IMAPSearchTokenPtr HEADER(const char* filedName, const string& fieldContents); + static IMAPSearchTokenPtr KEYWORD(vmime::net::message::Flags); + static IMAPSearchTokenPtr LARGER(uint32_t); + static IMAPSearchTokenPtr MESSAGESET(const vmime::net::messageSet&); + static IMAPSearchTokenPtr MESSAGESET(const vmime::net::messageSet&&); + static IMAPSearchTokenPtr NEW(); + static IMAPSearchTokenPtr NOT(const IMAPSearchTokenPtr&); + static IMAPSearchTokenPtr OLD(); + static IMAPSearchTokenPtr ON(const datetime&); + static IMAPSearchTokenPtr OR(const IMAPSearchTokenPtr&, const IMAPSearchTokenPtr&); + static IMAPSearchTokenPtr RECENT(); + static IMAPSearchTokenPtr SEEN(); + static IMAPSearchTokenPtr SENTBEFORE(const datetime&); + static IMAPSearchTokenPtr SENTON(const datetime&); + static IMAPSearchTokenPtr SENTSINCE(const datetime&); + static IMAPSearchTokenPtr SINCE(const datetime&); + static IMAPSearchTokenPtr SMALLER(uint32_t); + static IMAPSearchTokenPtr SUBJECT(const string&); + static IMAPSearchTokenPtr TEXT(const string&); + static IMAPSearchTokenPtr TO(const string&); + static IMAPSearchTokenPtr UID(const vmime::net::messageSet&); + static IMAPSearchTokenPtr UID(const vmime::net::messageSet&&); + static IMAPSearchTokenPtr UNANSWERED(); + static IMAPSearchTokenPtr UNDELETED(); + static IMAPSearchTokenPtr UNDRAFT(); + static IMAPSearchTokenPtr UNFLAGGED(); + static IMAPSearchTokenPtr UNKEYWORD(vmime::net::message::Flags); + static IMAPSearchTokenPtr UNSEEN(); +}; + + +/** Holds a set of attributes to match messages against when searching folder contents. + */ +class VMIME_EXPORT IMAPSearchAttributes : public object { + +public: + + IMAPSearchAttributes() = default; + IMAPSearchAttributes(std::vector <vmime::shared_ptr <const IMAPSearchToken>>&&); + + /** Adds a new search token that will be used to match messages against. Multiple tokens are + * treated as an AND operation. + * + * @param token the search token to add + */ + void add(const vmime::shared_ptr <const IMAPSearchToken>& token); + + std::vector <string> generate() const; + +protected: + + std::vector <vmime::shared_ptr <const IMAPSearchToken>> m_andTokens; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#endif // VMIME_NET_IMAP_IMAPSEARCHATTRIBUTES_HPP_INCLUDED diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPUtils.cpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPUtils.cpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPUtils.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPUtils.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -43,6 +43,12 @@ namespace imap { +static const char* IMAP_MONTH_NAMES[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + + // static const string IMAPUtils::quoteString(const string& text) { @@ -546,6 +552,22 @@ // static +const string IMAPUtils::searchDate(const vmime::datetime& date) { + + std::ostringstream res; + res.imbue(std::locale::classic()); + + res << date.getDay(); + res << '-'; + res << IMAP_MONTH_NAMES[std::min(std::max(date.getMonth() - 1, 0), 11)]; + res << '-'; + res << date.getYear(); + + return res.str(); +} + + +// static const string IMAPUtils::dateTime(const vmime::datetime& date) { std::ostringstream res; @@ -567,12 +589,7 @@ res << '-'; - static const char* monthNames[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - - res << monthNames[std::min(std::max(date.getMonth() - 1, 0), 11)]; + res << IMAP_MONTH_NAMES[std::min(std::max(date.getMonth() - 1, 0), 11)]; res << '-'; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/imap/IMAPUtils.hpp new/vmime-0.9.2.175/src/vmime/net/imap/IMAPUtils.hpp --- old/vmime-0.9.2.165/src/vmime/net/imap/IMAPUtils.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/imap/IMAPUtils.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -85,6 +85,13 @@ static const std::vector <string> messageFlagList(const int flags); + /** Format a date to IMAP SEARCH date format (eg. 25-Nov-2021). + * + * @param date date to format + * @return IMAP SEARCH-formatted date + */ + static const string searchDate(const vmime::datetime& date); + /** Format a date/time to IMAP date/time format. * * @param date date/time to format diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/net/maildir/maildirFolder.cpp new/vmime-0.9.2.175/src/vmime/net/maildir/maildirFolder.cpp --- old/vmime-0.9.2.165/src/vmime/net/maildir/maildirFolder.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/net/maildir/maildirFolder.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -1356,6 +1356,7 @@ } + } // maildir } // net } // vmime diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/security/cert/X509Certificate.hpp new/vmime-0.9.2.175/src/vmime/security/cert/X509Certificate.hpp --- old/vmime-0.9.2.165/src/vmime/security/cert/X509Certificate.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/security/cert/X509Certificate.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -61,8 +61,9 @@ /** Supported digest algorithms (used for fingerprint). */ enum DigestAlgorithm { - DIGEST_MD5, /**< MD5 digest */ - DIGEST_SHA1 /**< SHA1 digest */ + DIGEST_MD5, + DIGEST_SHA1, + DIGEST_SHA256 }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp new/vmime-0.9.2.175/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp --- old/vmime-0.9.2.165/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -311,10 +311,15 @@ galgo = GNUTLS_DIG_MD5; break; + case DIGEST_SHA256: + + galgo = GNUTLS_DIG_SHA256; + break; + default: case DIGEST_SHA1: - galgo = GNUTLS_DIG_SHA; + galgo = GNUTLS_DIG_SHA1; break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp new/vmime-0.9.2.175/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp --- old/vmime-0.9.2.165/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -556,6 +556,11 @@ digest = EVP_md5(); break; + case DIGEST_SHA256: + + digest = EVP_sha256(); + break; + default: case DIGEST_SHA1: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/text.cpp new/vmime-0.9.2.175/src/vmime/text.cpp --- old/vmime-0.9.2.165/src/vmime/text.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/text.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -269,7 +269,6 @@ void text::createFromString(const string& in, const charset& ch) { - size_t asciiCount = 0; size_t asciiPercent = 0; removeAllWords(); @@ -282,7 +281,7 @@ const bool alwaysEncode = ch.getRecommendedEncoding(recommendedEnc); if (!alwaysEncode) { - asciiCount = utility::stringUtils::countASCIIchars(in.begin(), in.end()); + const auto asciiCount = utility::stringUtils::countASCIIchars(in.begin(), in.end()); asciiPercent = (in.length() == 0 ? 100 : (100 * asciiCount) / in.length()); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/src/vmime/utility/stringUtils.hpp new/vmime-0.9.2.175/src/vmime/utility/stringUtils.hpp --- old/vmime-0.9.2.165/src/vmime/utility/stringUtils.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/src/vmime/utility/stringUtils.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -29,6 +29,7 @@ #include "vmime/base.hpp" #include <sstream> +#include <iostream> namespace vmime { @@ -52,6 +53,20 @@ return string(reinterpret_cast <const char*>(data), count); } + /** Makes a HEX string from byteArray. + * + * @param data byteArray containing data + * @return a string object containing a hex copy of the specified data + */ + static const string makeHexStringFromBytes(const byteArray& data) { + std::stringstream ss; + for (const byte_t& b : data) + { + ss << std::hex << int(b); + } + return ss.str(); + } + /** Casts a string to bytes. * * @param str string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/tests/net/smtp/SMTPTransportTestUtils.hpp new/vmime-0.9.2.175/tests/net/smtp/SMTPTransportTestUtils.hpp --- old/vmime-0.9.2.165/tests/net/smtp/SMTPTransportTestUtils.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/tests/net/smtp/SMTPTransportTestUtils.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -241,6 +241,7 @@ m_state = STATE_NOT_CONNECTED; m_bdatChunkCount = 0; + m_bdatChunkSize = m_bdatChunkReceived = 0; m_ehloSent = m_mailSent = m_rcptSent = m_quitSent = false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/tests/parser/mailboxGroupTest.cpp new/vmime-0.9.2.175/tests/parser/mailboxGroupTest.cpp --- old/vmime-0.9.2.165/tests/parser/mailboxGroupTest.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/tests/parser/mailboxGroupTest.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -32,6 +32,8 @@ VMIME_TEST(testParseExtraChars) VMIME_TEST(testEmptyGroup) VMIME_TEST(testEncodedEmptyGroup) + VMIME_TEST(testGroupInGroup) + VMIME_TEST(testBrokenGroup) VMIME_TEST_LIST_END @@ -104,4 +106,30 @@ VASSERT_EQ("count", 0, mgrp.getMailboxCount()); } + void testGroupInGroup() { + + vmime::mailboxGroup mgrp; + mgrp.parse("group1:[email protected],group2:[email protected];,[email protected];"); + + VASSERT_EQ("name", "group1", mgrp.getName().getWholeBuffer()); + VASSERT_EQ("count", 2, mgrp.getMailboxCount()); + VASSERT_EQ("mbox1", "[email protected]", mgrp.getMailboxAt(0)->getEmail()); + VASSERT_EQ("mbox2", "[email protected]", mgrp.getMailboxAt(1)->getEmail()); + } + + void testBrokenGroup() { + + std::string bad(":,"); + + for (int i = 0 ; i < 10 ; ++i) { + bad = bad + bad; + } + + vmime::mailboxGroup mgrp; + mgrp.parse(bad); + + VASSERT_EQ("name", "", mgrp.getName().getWholeBuffer()); + VASSERT_EQ("count", 0, mgrp.getMailboxCount()); + } + VMIME_TEST_SUITE_END diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/tests/parser/mailboxListTest.cpp new/vmime-0.9.2.175/tests/parser/mailboxListTest.cpp --- old/vmime-0.9.2.165/tests/parser/mailboxListTest.cpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/tests/parser/mailboxListTest.cpp 2022-03-26 22:30:00.000000000 +0100 @@ -28,6 +28,7 @@ VMIME_TEST_LIST_BEGIN VMIME_TEST(testParseGroup) + VMIME_TEST(testBrokenGroup) VMIME_TEST_LIST_END @@ -44,4 +45,18 @@ VASSERT_EQ("email", "[email protected]", mboxList.getMailboxAt(2)->getEmail().generate()); } + void testBrokenGroup() { + + std::string bad(":,"); + + for (int i = 0 ; i < 10 ; ++i) { + bad = bad + bad; + } + + vmime::mailboxList mboxList; + mboxList.parse(bad); + + VASSERT_EQ("count", 0, mboxList.getMailboxCount()); + } + VMIME_TEST_SUITE_END diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vmime-0.9.2.165/tests/testUtils.hpp new/vmime-0.9.2.175/tests/testUtils.hpp --- old/vmime-0.9.2.165/tests/testUtils.hpp 2021-05-16 18:43:14.000000000 +0200 +++ new/vmime-0.9.2.175/tests/testUtils.hpp 2022-03-26 22:30:00.000000000 +0100 @@ -93,7 +93,7 @@ // Work-around for comparing 'std::string' against 'char*' inline void assertEquals( const char* expected, - const std::string actual, + const std::string &actual, SourceLine sourceLine, const std::string &message ) {
