Hello community, here is the log from the commit of package libvmime_zarafa7 for openSUSE:Factory checked in at 2015-10-02 09:23:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libvmime_zarafa7 (Old) and /work/SRC/openSUSE:Factory/.libvmime_zarafa7.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libvmime_zarafa7" Changes: -------- --- /work/SRC/openSUSE:Factory/libvmime_zarafa7/libvmime_zarafa7.changes 2015-05-19 23:39:13.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libvmime_zarafa7.new/libvmime_zarafa7.changes 2015-10-02 09:23:43.000000000 +0200 @@ -1,0 +2,11 @@ +Mon Sep 28 13:42:17 UTC 2015 - jeng...@inai.de + +- Add 09-vmime-phf-stop-on-whitespace.diff, + 10-vmime-backport-mailboxList-parser-29954e5.diff, + 11-vmime-disable-rfc2231.diff, + 12-vmime-ignore-multiple-colons-in-headers.diff, + 13-vmime-ignore-newlines.diff, 14-vmime-remove-setlocale.diff, + 15-vmime-wrongly-padded-B64-words.diff, 16-vmime-x-uuencode.diff, + 17-vmime-avoid-unneeded-conversion.diff, vmime-all4debian.diff + +------------------------------------------------------------------- @@ -44,6 +54,0 @@ -- Add libvmime-nodatetime.diff, libvmime-sotag.diff, - vmime-0.8.1-charset-catch.diff, - vmime-0.9.2-header-value-on-next-line.diff, - vmime-mixed-qp-in-parameter.diff, - vmime-0.9.2-qp-in-buffers.diff, - vmime-noansiflag.patch New: ---- 09-vmime-phf-stop-on-whitespace.diff 10-vmime-backport-mailboxList-parser-29954e5.diff 11-vmime-disable-rfc2231.diff 12-vmime-ignore-multiple-colons-in-headers.diff 13-vmime-ignore-newlines.diff 14-vmime-remove-setlocale.diff 15-vmime-wrongly-padded-B64-words.diff 16-vmime-x-uuencode.diff 17-vmime-avoid-unneeded-conversion.diff build.collax debian.changelog debian.compat debian.control debian.copyright debian.docs debian.libvmime-zarafa7-0.install debian.libvmime-zarafa7-dev.install debian.rules debian.series libvmime-0.9.1+svn603sotag.tar.bz2 libvmime-zarafa7.dsc manual-sotag.xdiff readme.txt vmime-all4debian.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libvmime_zarafa7.spec ++++++ --- /var/tmp/diff_new_pack.ofRvHa/_old 2015-10-02 09:23:44.000000000 +0200 +++ /var/tmp/diff_new_pack.ofRvHa/_new 2015-10-02 09:23:44.000000000 +0200 @@ -1,7 +1,7 @@ # -# spec file for package libvmime +# spec file for package libvmime_zarafa7 # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -26,21 +26,34 @@ Url: http://vmime.sf.net/ #Svn-Clone: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk -Source: libvmime-%version.tar.bz2 +Source: libvmime-%{version}sotag.tar.bz2 Source2: spice_source.sh +Source3: libvmime-%{version}.tar.bz2 +Source4: readme.txt +Source5: build.collax +Source6: debian.docs +Source7: libvmime-sotag.diff +Source8: manual-sotag.xdiff +Source9: vmime-all4debian.diff Patch1: libvmime-nodatetime.diff -Patch2: libvmime-sotag.diff Patch3: vmime-0.8.1-charset-catch.diff Patch4: vmime-0.9.2-header-value-on-next-line.diff Patch5: vmime-mixed-qp-in-parameter.diff Patch6: vmime-0.9.2-qp-in-buffers.diff Patch7: vmime-noansiflag.patch +Patch9: 09-vmime-phf-stop-on-whitespace.diff +Patch10: 10-vmime-backport-mailboxList-parser-29954e5.diff +Patch11: 11-vmime-disable-rfc2231.diff +Patch12: 12-vmime-ignore-multiple-colons-in-headers.diff +Patch13: 13-vmime-ignore-newlines.diff +Patch14: 14-vmime-remove-setlocale.diff +Patch15: 15-vmime-wrongly-padded-B64-words.diff +Patch16: 16-vmime-x-uuencode.diff +Patch17: 17-vmime-avoid-unneeded-conversion.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: autoconf BuildRequires: automake BuildRequires: gcc-c++ -BuildRequires: libgcrypt-devel -BuildRequires: libgsasl-devel BuildRequires: libtool BuildRequires: pkgconfig BuildRequires: postfix @@ -48,11 +61,9 @@ # Somehow it's not drawn in BuildRequires: python %endif -BuildRequires: scons BuildRequires: xz %if 0%{?suse_version} >= 1100 BuildRequires: gettext-tools -BuildRequires: libgnutls-devel BuildRequires: libselinux-devel %else %if 0%{?suse_version} > 0 @@ -103,24 +114,23 @@ %prep %setup -qn vmime -%patch -P 1 -P 2 -P 3 -P 4 -P 5 -P 6 -P 7 -p1 +%patch -P 1 -P 3 -P 4 -P 5 -P 6 -P 7 -p1 +%patch -P 9 -P 10 -P 11 -P 12 -P 13 -P 14 -P 15 -P 16 -P 17 -p1 %build export CFLAGS="%optflags -DVMIME_ALWAYS_GENERATE_7BIT_PARAMETER=1"; export CXXFLAGS="$CFLAGS"; # sendmail's awesome location. export PATH="$PATH:/usr/sbin"; -pkg-config --list-all | grep gsasl -scons autotools; -%configure --disable-static +%configure --disable-static --disable-sasl --disable-tls make %{?_smp_mflags}; %install b="%buildroot"; make install DESTDIR="$b" docdir="%_docdir/%name"; find "$b" -type f -name "*.la" -delete; -mv "$b/%_libdir/pkgconfig"/{vmime_zarafa7.pc,vmime.pc} -ln -s libvmime_zarafa7.so "$b/%_libdir/libvmime.so" +ln -sfv libvmime_zarafa7.so "$b/%_libdir/libvmime.so" +mv -v "$b/%_libdir/pkgconfig"/{vmime_zarafa7.pc,vmime.pc} %check make check; @@ -131,7 +141,6 @@ %files -n %lname %defattr(-,root,root) -%doc COPYING %_libdir/%{name}*.so.* %files devel ++++++ 09-vmime-phf-stop-on-whitespace.diff ++++++ For certain broken input mail which forgets to use the semicolon in e.g. Content-Type: text/plain charset=utf-8 --- src/parameterizedHeaderField.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) Index: vmime/src/parameterizedHeaderField.cpp =================================================================== --- vmime.orig/src/parameterizedHeaderField.cpp +++ vmime/src/parameterizedHeaderField.cpp @@ -97,7 +97,7 @@ void parameterizedHeaderField::parse(con // Advance up to ';', if any string::size_type valueLength = 0; - while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text + while (p < pend && *p != ';' && (!parserHelpers::isSpace(*p))) // FIXME: support ";" inside quoted or RFC-2047-encoded text { ++p; ++valueLength; @@ -118,6 +118,10 @@ void parameterizedHeaderField::parse(con { std::map <string, paramInfo> params; + if (*p != ';') + while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text + ++p; + while (*p == ';') { // Skip ';' ++++++ 10-vmime-backport-mailboxList-parser-29954e5.diff ++++++ --- src/mailboxList.cpp | 30 +++++++++++++++++++++++++++++- vmime/address.hpp | 1 - 2 files changed, 29 insertions(+), 2 deletions(-) Index: vmime/src/mailboxList.cpp =================================================================== --- vmime.orig/src/mailboxList.cpp +++ vmime/src/mailboxList.cpp @@ -22,6 +22,7 @@ // #include "vmime/mailboxList.hpp" +#include "vmime/mailboxGroup.hpp" #include "vmime/exception.hpp" @@ -199,7 +200,34 @@ const std::vector <ref <const component> void mailboxList::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { - m_list.parse(buffer, position, end, newPosition); + string::size_type pos = position; + + while (pos < end) + { + ref <address> parsedAddress = address::parseNext(buffer, pos, end, &pos); + + if (parsedAddress != NULL) + { + if (parsedAddress->isGroup()) + { + ref <mailboxGroup> group = parsedAddress.staticCast <mailboxGroup>(); + + for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) + { + m_list.appendAddress(group->getMailboxAt(i)); + } + } + else + { + m_list.appendAddress(parsedAddress); + } + } + } + + setParsedBounds(position, end); + + if (newPosition) + *newPosition = end; } Index: vmime/vmime/address.hpp =================================================================== --- vmime.orig/vmime/address.hpp +++ vmime/vmime/address.hpp @@ -65,7 +65,6 @@ public: virtual ref <component> clone() const = 0; -protected: /** Parse an address from an input buffer. * ++++++ 11-vmime-disable-rfc2231.diff ++++++ --- src/parameter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) Index: vmime/src/parameter.cpp =================================================================== --- vmime.orig/src/parameter.cpp +++ vmime/src/parameter.cpp @@ -400,7 +400,9 @@ void parameter::generate(utility::output // Also generate an extended parameter if the value contains 8-bit characters // or is too long for a single line - if (extended || cutValue) + + // Disable RFC-2231 header generation. Some email clients have bad reactions to it. + if ((extended || cutValue) && false) { #if VMIME_ALWAYS_GENERATE_7BIT_PARAMETER ++++++ 12-vmime-ignore-multiple-colons-in-headers.diff ++++++ --- src/headerField.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) Index: vmime/src/headerField.cpp =================================================================== --- vmime.orig/src/headerField.cpp +++ vmime/src/headerField.cpp @@ -132,7 +132,9 @@ ref <headerField> headerField::parseNext buffer.begin() + nameEnd); // Skip ':' character - ++pos; + // Patch: don't just skip one colon, but any and all, if available. NS 2 December 2013 + while ((pos < end) && (buffer[pos] == ':')) + ++pos; // Skip spaces between ':' and the field contents while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) ++++++ 13-vmime-ignore-newlines.diff ++++++ --- src/word.cpp | 3 +++ 1 file changed, 3 insertions(+) Index: vmime/src/word.cpp =================================================================== --- vmime.orig/src/word.cpp +++ vmime/src/word.cpp @@ -73,11 +73,14 @@ ref <word> word::parseNext(const string& // - before the first word // - between two encoded words // - after the last word + // Always ignore newlines string whiteSpaces; while (pos < end && parserHelpers::isSpace(buffer[pos])) { whiteSpaces += buffer[pos]; + if(buffer[pos] != '\r' && buffer[pos] != '\n') // do not include newlines + whiteSpaces += buffer[pos]; ++pos; } ++++++ 14-vmime-remove-setlocale.diff ++++++ This interferes with the overlying program (especially threaded ones). --- src/platforms/posix/posixHandler.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) Index: vmime/src/platforms/posix/posixHandler.cpp =================================================================== --- vmime.orig/src/platforms/posix/posixHandler.cpp +++ vmime/src/platforms/posix/posixHandler.cpp @@ -153,11 +153,7 @@ const vmime::charset posixHandler::getLo { const PLockHelper lock; - const char* prevLocale = ::setlocale(LC_ALL, ""); - vmime::charset ch(::nl_langinfo(CODESET)); - ::setlocale(LC_ALL, prevLocale); - - return (ch); + return vmime::charset(::nl_langinfo(CODESET)); } ++++++ 15-vmime-wrongly-padded-B64-words.diff ++++++ --- src/word.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++--------------- vmime/word.hpp | 23 ++++++++++++++++++++- 2 files changed, 67 insertions(+), 16 deletions(-) Index: vmime/src/word.cpp =================================================================== --- vmime.orig/src/word.cpp +++ vmime/src/word.cpp @@ -64,8 +64,7 @@ word::word(const string& buffer, const c ref <word> word::parseNext(const string& buffer, const string::size_type position, - const string::size_type end, string::size_type* newPosition, - bool prevIsEncoded, bool* isEncoded, bool isFirst) + const string::size_type end, string::size_type* newPosition, parserState* state) { string::size_type pos = position; @@ -121,7 +120,7 @@ ref <word> word::parseNext(const string& if (!unencoded.empty()) { - if (prevIsEncoded) + if (state->prevIsEncoded && !state->isFirst) unencoded = whiteSpaces + unencoded; ref <word> w = vmime::create <word>(unencoded, charset(charsets::US_ASCII)); @@ -130,8 +129,8 @@ ref <word> word::parseNext(const string& if (newPosition) *newPosition = pos; - if (isEncoded) - *isEncoded = false; + state->prevIsEncoded = false; + state->isFirst = false; return (w); } @@ -182,13 +181,13 @@ ref <word> word::parseNext(const string& pos += 2; // ?= ref <word> w = vmime::create <word>(); - w->parse(buffer, wordStart, pos, NULL); + w->parseWithState(buffer, wordStart, pos, NULL, state); if (newPosition) *newPosition = pos; - if (isEncoded) - *isEncoded = true; + state->prevIsEncoded = true; + state->isFirst = false; return (w); } @@ -196,7 +195,7 @@ ref <word> word::parseNext(const string& ++pos; } - if (startPos != end && !isFirst && prevIsEncoded) + if (startPos != end && !state->isFirst && state->prevIsEncoded) unencoded += whiteSpaces; if (startPos != end) @@ -211,8 +210,8 @@ ref <word> word::parseNext(const string& if (newPosition) *newPosition = end; - if (isEncoded) - *isEncoded = false; + state->prevIsEncoded = false; + state->isFirst = false; return (w); } @@ -229,9 +228,9 @@ const std::vector <ref <word> > word::pa string::size_type pos = position; - bool prevIsEncoded = false; + parserState state; - while ((w = word::parseNext(buffer, pos, end, &pos, prevIsEncoded, &prevIsEncoded, (w == NULL))) != NULL) + while ((w = word::parseNext(buffer, pos, end, &pos, &state)) != NULL) res.push_back(w); if (newPosition) @@ -244,6 +243,14 @@ const std::vector <ref <word> > word::pa void word::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { + parseWithState(buffer, position, end, newPosition, NULL); +} + + +void word::parseWithState + (const string& buffer, const size_t position, + const size_t end, size_t* newPosition, parserState* state) +{ if (position + 6 < end && // 6 = "=?(.+)?(.*)?=" buffer[position] == '=' && buffer[position + 1] == '?') { @@ -290,12 +297,20 @@ void word::parse(const string& buffer, c if (theEncoder) { // Decode text + string encodedBuffer(dataPos, dataEnd); string decodedBuffer; - utility::inputStreamStringAdapter ein(string(dataPos, dataEnd)); + + if (state && !state->undecodedBytes.empty()) + { + encodedBuffer = state->undecodedBytes + encodedBuffer; + state->undecodedBytes.clear(); + } + + utility::inputStreamStringAdapter ein(encodedBuffer); utility::outputStreamStringAdapter eout(decodedBuffer); - theEncoder->decode(ein, eout); + const size_t decodedLen = theEncoder->decode(ein, eout); delete (theEncoder); m_buffer = decodedBuffer; @@ -306,6 +321,21 @@ void word::parse(const string& buffer, c if (newPosition) *newPosition = (p - buffer.begin()); + // For Base64 encoding, ensure all bytes have been decoded. + // If there are remaining bytes, keep them for the next run. + // + // This allows decoding some insanities like: + // =?utf-8?B?5Lit5?= =?utf-8?B?paH?= + if (*encPos == 'B' || *encPos == 'b') + { + const size_t actualEncodedLen = encodedBuffer.length(); + const size_t theoricalEncodedLen = + ((decodedLen + ((decodedLen % 3) ? (3 - (decodedLen % 3)) : 0) ) / 3) * 4; + + if (state && actualEncodedLen != theoricalEncodedLen) + state->undecodedBytes.assign(dataPos + theoricalEncodedLen, dataEnd); + } + return; } } Index: vmime/vmime/word.hpp =================================================================== --- vmime.orig/vmime/word.hpp +++ vmime/vmime/word.hpp @@ -125,6 +125,20 @@ public: bool prevWordIsEncoded; bool lastCharIsSpace; }; + + class parserState + { + public: + + parserState() + : prevIsEncoded(false), isFirst(true) + { + } + + bool prevIsEncoded; + bool isFirst; + std::string undecodedBytes; + }; #endif @@ -134,13 +148,20 @@ public: void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; + void parseWithState + (const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + parserState* state); + void generate(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos, const int flags, generatorState* state) const; const std::vector <ref <const component> > getChildComponents() const; private: - static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, bool prevIsEncoded, bool* isEncoded, bool isFirst); + static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, parserState* state); static const std::vector <ref <word> > parseMultiple(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition); ++++++ 16-vmime-x-uuencode.diff ++++++ --- src/constants.cpp | 1 + src/utility/encoder/encoderFactory.cpp | 1 + 2 files changed, 2 insertions(+) Index: vmime/src/constants.cpp =================================================================== --- vmime.orig/src/constants.cpp +++ vmime/src/constants.cpp @@ -80,6 +80,7 @@ namespace encodingTypes const string::value_type* const QUOTED_PRINTABLE = "quoted-printable"; const string::value_type* const BINARY = "binary"; const string::value_type* const UUENCODE = "uuencode"; + const string::value_type* const X_UUENCODE = "x-uuencode"; } Index: vmime/src/utility/encoder/encoderFactory.cpp =================================================================== --- vmime.orig/src/utility/encoder/encoderFactory.cpp +++ vmime/src/utility/encoder/encoderFactory.cpp @@ -43,6 +43,7 @@ encoderFactory::encoderFactory() registerName <b64Encoder>("base64"); registerName <qpEncoder>("quoted-printable"); registerName <uuEncoder>("uuencode"); + registerName <uuEncoder>("x-uuencode"); registerName <sevenBitEncoder>("7bit"); registerName <eightBitEncoder>("8bit"); registerName <binaryEncoder>("binary"); ++++++ 17-vmime-avoid-unneeded-conversion.diff ++++++ --- a/src/word.cpp 2015-01-15 11:16:52.274064206 +0100 +++ b/src/word.cpp 2015-01-15 11:58:12.570143004 +0100 @@ -723,6 +723,10 @@ const string word::getConvertedText(const charset& dest) const { + if (dest == m_charset) { + return m_buffer; // no conversion needed + } + string out; try { ++++++ build.collax ++++++ #!/bin/bash source=libvmime version=0.9.1+svn603sotag build=ak1 srcdir=vmime parallel_build=1 configopts=' --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --disable-static --disable-sasl --disable-tls ' #--------------- packaging information --------------- package=libvmime-zarafa7 section=libs description="vmime" docpackage=0 develpackage=1 exportslibs=1 #licensefiles="LICENSE.txt" #----------------- dependency tracking ---------------- builddepends=' libc6 libc6-dev libgcc1 libstdc++-v3 libstdc++-v3-dev openssl openssl-dev zlib1g zlib1g-dev ' ## please-complete! build_patch () { local cur="$PWD" pushd "$srcdir/" patch -p1 -i "$cur/vmime-all4debian.diff" popd } build_install () { echo WTF1 std_build_install echo WTF2 ln -sfv libvmime_zarafa7.so "$instdir/usr/lib/libvmime.so" mv -v "$instdir/usr/lib/pkgconfig"/vmime{_zarafa7,}.pc echo WTF3 } . buildfunctions.sh ++++++ debian.changelog ++++++ libvmime-zarafa7 (0.9.1+svn603-1) unstable; urgency=medium * blah -- Z <developm...@zarafa.com> Tue, 08 Jul 2014 23:10:39 +0200 ++++++ debian.compat ++++++ 8 ++++++ debian.control ++++++ Source: libvmime-zarafa7 Priority: optional Maintainer: zZz <developm...@zarafa.com> Build-Depends: debhelper (>= 4.0.0), autotools-dev, g++ (>= 4), pkg-config, postfix, autoconf, automake, libtool, hostname Standards-Version: 3.6.1 Section: libs Package: libvmime-zarafa7-dev Section: libdev Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libvmime-zarafa7-0 (= ${Source-Version}) Conflicts: libvmime-dev, libvmime-zarafa-dev Replaces: libvmime-zarafa-dev Description: a C++ mail library (development files) VMime is a powerful C++ class library for parsing, generating, or editing Internet RFC-[2]822 and MIME messages. VMime is designed to provide a fast and an easy way to manipulate Internet mail messages. . The recent releases of VMime also include support for using messaging protocols (POP3, IMAP, SMTP and maildir) with a lot of features supported: listing folders, downloading and adding messages to folders, extracting parts from message, getting and setting message flags, and a lot more. Package: libvmime-zarafa7-0 Section: libs Architecture: any Depends: ${shlibs:Depends} Description: a C++ mail library (runtime library) VMime is a powerful C++ class library for parsing, generating, or editing Internet RFC-[2]822 and MIME messages. VMime is designed to provide a fast and an easy way to manipulate Internet mail messages. . The recent releases of VMime also include support for using messaging protocols (POP3, IMAP, SMTP and maildir) with a lot of features supported: listing folders, downloading and adding messages to folders, extracting parts from message, getting and setting message flags, and a lot more. ++++++ debian.copyright ++++++ This package was debianized by Michael Kromer <m...@zarafa.com> on Thu, 07 Aug 2014 17:30:00 +0200. It was downloaded from http://www.vmime.org/ Upstream author: Vincent Richard <vinc...@vincent-richard.net> This software is copyright (c) 2004 by Vincent Richard. You are free to distribute this software under the terms of the GNU General Public License. On Debian systems, the complete text of the GNU General Public License can be found in the file '/usr/share/common-licenses/GPL'. ++++++ debian.docs ++++++ README ++++++ debian.libvmime-zarafa7-0.install ++++++ usr/lib/libvmime_zarafa7.so.0* ++++++ debian.libvmime-zarafa7-dev.install ++++++ usr/include/vmime/ usr/lib/libvmime_zarafa7.so usr/lib/libvmime.so usr/lib/pkgconfig/*.pc ++++++ debian.rules ++++++ #!/usr/bin/make -f export DH_VERBOSE=1 %: dh $@ --parallel override_dh_auto_configure: dh_auto_configure -- CFLAGS="-Wall -g -DVMIME_ALWAYS_GENERATE_7BIT_PARAMETER=1 -O2" --disable-static --disable-sasl --disable-tls override_dh_auto_install: dh_auto_install ln -sfv libvmime_zarafa7.so debian/tmp/usr/lib/libvmime.so mv -v debian/tmp/usr/lib/pkgconfig/vmime_zarafa7.pc \ debian/tmp/usr/lib/pkgconfig/vmime.pc ++++++ debian.series ++++++ # debian is too strict to just take a concatenation of patches vmime-all4debian.diff ++++++ libvmime-nodatetime.diff ++++++ --- /var/tmp/diff_new_pack.ofRvHa/_old 2015-10-02 09:23:44.000000000 +0200 +++ /var/tmp/diff_new_pack.ofRvHa/_new 2015-10-02 09:23:44.000000000 +0200 @@ -1,17 +1,18 @@ +Causes pointless rebuilds due to changing checksums due to time-dependent output. --- src/base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -Index: libvmime-0.9.1/src/base.cpp +Index: vmime/src/base.cpp =================================================================== ---- libvmime-0.9.1.orig/src/base.cpp -+++ libvmime-0.9.1/src/base.cpp +--- vmime.orig/src/base.cpp ++++ vmime/src/base.cpp @@ -74,7 +74,7 @@ const string libname() { return (VMIME_P * * @return library version */ -const string libversion() { return (VMIME_VERSION " (" __DATE__ " " __TIME__ ")"); } -+const string libversion() { return (VMIME_VERSION " (_""_DATE_""_ causes unnecessary rebuilds - avoid)"); } ++const string libversion() { return (VMIME_VERSION " ()"); } /** Return the library API version (eg: "6:1:6"). * ++++++ libvmime-zarafa7.dsc ++++++ Format: 1.0 Source: libvmime-zarafa7 Binary: libvmime-zarafa7-dev, libvmime-zarafa7-0 Architecture: any Version: 0.9.1+svn603-1 Maintainer: Zarafa <developm...@zarafa.com> Standards-Version: 3.6.1 Build-Depends: debhelper (>= 8), autotools-dev, g++ (>= 4), pkg-config, postfix, autoconf, automake, libtool, hostname Files: DEBTRANSFORM-TAR: libvmime-0.9.1+svn603sotag.tar.bz2 ++++++ manual-sotag.xdiff ++++++ From: Jan Engelhardt <jeng...@inai.de> ZCP is once again depending on an outdated vmime version, so mark it appropriately that it does not conflict with the normal libvmime. --- SConstruct | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Index: vmime/SConstruct =================================================================== --- vmime.orig/SConstruct +++ vmime/SConstruct @@ -63,8 +63,8 @@ packageAPI = '%d:%d:%d' % (packageAPICur #else: # packageVersionedGenericName = packageGenericName # packageVersionedName = packageName -packageVersionedGenericName = packageGenericName -packageVersionedName = packageName +packageVersionedGenericName = "vmime_zarafa7" +packageVersionedName = "libvmime_zarafa7" ################## ++++++ readme.txt ++++++ unpack vmime source (svn or libvmime-0.9.1+svn603.tar.bz2) apply manual-sotag.xdiff run `scons autotools` repack as libvmime-0.9.1+svn603sotag.tar.bz2 All because RHEL6 has no scons and because I don't like porting it. ++++++ vmime-0.8.1-charset-catch.diff ++++++ --- /var/tmp/diff_new_pack.ofRvHa/_old 2015-10-02 09:23:44.000000000 +0200 +++ /var/tmp/diff_new_pack.ofRvHa/_new 2015-10-02 09:23:44.000000000 +0200 @@ -1,7 +1,12 @@ -diff -Nurb libvmime-0.8.1.orig/src/word.cpp libvmime-0.8.1.patched/src/word.cpp ---- libvmime-0.8.1.orig/src/word.cpp 2006-10-02 15:44:00.000000000 +0200 -+++ libvmime-0.8.1.patched/src/word.cpp 2007-12-12 20:26:55.267497149 +0100 -@@ -616,7 +616,13 @@ +--- + src/word.cpp | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: vmime/src/word.cpp +=================================================================== +--- vmime.orig/src/word.cpp ++++ vmime/src/word.cpp +@@ -692,7 +692,13 @@ const string word::getConvertedText(cons { string out; ++++++ vmime-0.9.2-header-value-on-next-line.diff ++++++ --- /var/tmp/diff_new_pack.ofRvHa/_old 2015-10-02 09:23:44.000000000 +0200 +++ /var/tmp/diff_new_pack.ofRvHa/_new 2015-10-02 09:23:44.000000000 +0200 @@ -1,7 +1,12 @@ -diff -Nurb libvmime-0.9.2.orig/src/headerField.cpp libvmime-0.9.2.patched/src/headerField.cpp ---- libvmime-0.9.2.orig/src/headerField.cpp 2010-05-20 05:33:45.000000000 -0700 -+++ libvmime-0.9.2.patched/src/headerField.cpp 2011-08-29 12:10:08.438497914 -0700 -@@ -157,14 +157,12 @@ +--- + src/headerField.cpp | 17 ++--------------- + 1 file changed, 2 insertions(+), 15 deletions(-) + +Index: vmime/src/headerField.cpp +=================================================================== +--- vmime.orig/src/headerField.cpp ++++ vmime/src/headerField.cpp +@@ -157,14 +157,12 @@ ref <headerField> headerField::parseNext { contentsEnd = pos; pos += 2; @@ -17,7 +22,7 @@ while (pos < end) { -@@ -186,24 +184,13 @@ +@@ -186,24 +184,13 @@ ref <headerField> headerField::parseNext ++pos; } ++++++ vmime-0.9.2-qp-in-buffers.diff ++++++ --- /var/tmp/diff_new_pack.ofRvHa/_old 2015-10-02 09:23:44.000000000 +0200 +++ /var/tmp/diff_new_pack.ofRvHa/_new 2015-10-02 09:23:44.000000000 +0200 @@ -1,6 +1,12 @@ ---- svn/src/wordEncoder.cpp (revision 603) -+++ svn/src/wordEncoder.cpp (working copy) -@@ -239,6 +239,13 @@ +--- + src/wordEncoder.cpp | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: vmime/src/wordEncoder.cpp +=================================================================== +--- vmime.orig/src/wordEncoder.cpp ++++ vmime/src/wordEncoder.cpp +@@ -239,6 +239,13 @@ bool wordEncoder::isEncodingNeeded(const if (buffer.find_first_of("\n\r") != string::npos) return true; ++++++ vmime-all4debian.diff ++++++ --- src/base.cpp | 2 src/constants.cpp | 1 src/headerField.cpp | 21 ++------- src/mailboxList.cpp | 30 +++++++++++++ src/parameter.cpp | 16 ++++++- src/parameterizedHeaderField.cpp | 6 ++ src/platforms/posix/posixHandler.cpp | 6 -- src/utility/encoder/encoderFactory.cpp | 1 src/word.cpp | 73 ++++++++++++++++++++++++++------- src/wordEncoder.cpp | 7 +++ vmime/address.hpp | 1 vmime/word.hpp | 23 +++++++++- 13 files changed, 152 insertions(+), 53 deletions(-) Index: vmime/src/base.cpp =================================================================== --- vmime.orig/src/base.cpp +++ vmime/src/base.cpp @@ -74,7 +74,7 @@ const string libname() { return (VMIME_P * * @return library version */ -const string libversion() { return (VMIME_VERSION " (" __DATE__ " " __TIME__ ")"); } +const string libversion() { return (VMIME_VERSION " ()"); } /** Return the library API version (eg: "6:1:6"). * Index: vmime/src/constants.cpp =================================================================== --- vmime.orig/src/constants.cpp +++ vmime/src/constants.cpp @@ -80,6 +80,7 @@ namespace encodingTypes const string::value_type* const QUOTED_PRINTABLE = "quoted-printable"; const string::value_type* const BINARY = "binary"; const string::value_type* const UUENCODE = "uuencode"; + const string::value_type* const X_UUENCODE = "x-uuencode"; } Index: vmime/src/headerField.cpp =================================================================== --- vmime.orig/src/headerField.cpp +++ vmime/src/headerField.cpp @@ -132,7 +132,9 @@ ref <headerField> headerField::parseNext buffer.begin() + nameEnd); // Skip ':' character - ++pos; + // Patch: don't just skip one colon, but any and all, if available. NS 2 December 2013 + while ((pos < end) && (buffer[pos] == ':')) + ++pos; // Skip spaces between ':' and the field contents while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) @@ -157,14 +159,12 @@ ref <headerField> headerField::parseNext { contentsEnd = pos; pos += 2; - break; } else if (c == '\n') { contentsEnd = pos; ++pos; - break; - } + } else { while (pos < end) { @@ -186,24 +186,13 @@ ref <headerField> headerField::parseNext ++pos; } + } // Handle the case of folded lines if (buffer[pos] == ' ' || buffer[pos] == '\t') { // This is a folding white-space: we keep it as is and // we continue with contents parsing... - - // If the line contains only space characters, we assume it is - // the end of the headers. This is not strictly standard-compliant - // but, hey, we can't fail when parsing some malformed mails... - while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) - ++pos; - - if ((pos < end && buffer[pos] == '\n') || - (pos + 1 < end && buffer[pos] == '\r' && buffer[pos + 1] == '\n')) - { - break; - } } else { Index: vmime/src/mailboxList.cpp =================================================================== --- vmime.orig/src/mailboxList.cpp +++ vmime/src/mailboxList.cpp @@ -22,6 +22,7 @@ // #include "vmime/mailboxList.hpp" +#include "vmime/mailboxGroup.hpp" #include "vmime/exception.hpp" @@ -199,7 +200,34 @@ const std::vector <ref <const component> void mailboxList::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { - m_list.parse(buffer, position, end, newPosition); + string::size_type pos = position; + + while (pos < end) + { + ref <address> parsedAddress = address::parseNext(buffer, pos, end, &pos); + + if (parsedAddress != NULL) + { + if (parsedAddress->isGroup()) + { + ref <mailboxGroup> group = parsedAddress.staticCast <mailboxGroup>(); + + for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) + { + m_list.appendAddress(group->getMailboxAt(i)); + } + } + else + { + m_list.appendAddress(parsedAddress); + } + } + } + + setParsedBounds(position, end); + + if (newPosition) + *newPosition = end; } Index: vmime/src/parameter.cpp =================================================================== --- vmime.orig/src/parameter.cpp +++ vmime/src/parameter.cpp @@ -240,7 +240,17 @@ void parameter::parse(const std::vector value << t.getWholeBuffer(); if (!foundCharsetChunk) - ch = t.getWordAt(0)->getCharset(); + // this is still wrong. each word can have its + // own charset, and can be mixed (eg. iso-8859-1 + // and iso-2022-jp), but very unlikely. + // real fix is to have parameters store a + // vmime::text instead of a vmime::word in + // m_value. but that changes the interface + for (size_t i = 0; i < t.getWordCount(); i++) + if (t.getWordAt(i)->getCharset() != ch && ch == charsets::US_ASCII) { + ch = t.getWordAt(i)->getCharset(); + break; + } } } } @@ -390,7 +400,9 @@ void parameter::generate(utility::output // Also generate an extended parameter if the value contains 8-bit characters // or is too long for a single line - if (extended || cutValue) + + // Disable RFC-2231 header generation. Some email clients have bad reactions to it. + if ((extended || cutValue) && false) { #if VMIME_ALWAYS_GENERATE_7BIT_PARAMETER Index: vmime/src/parameterizedHeaderField.cpp =================================================================== --- vmime.orig/src/parameterizedHeaderField.cpp +++ vmime/src/parameterizedHeaderField.cpp @@ -97,7 +97,7 @@ void parameterizedHeaderField::parse(con // Advance up to ';', if any string::size_type valueLength = 0; - while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text + while (p < pend && *p != ';' && (!parserHelpers::isSpace(*p))) // FIXME: support ";" inside quoted or RFC-2047-encoded text { ++p; ++valueLength; @@ -118,6 +118,10 @@ void parameterizedHeaderField::parse(con { std::map <string, paramInfo> params; + if (*p != ';') + while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text + ++p; + while (*p == ';') { // Skip ';' Index: vmime/src/platforms/posix/posixHandler.cpp =================================================================== --- vmime.orig/src/platforms/posix/posixHandler.cpp +++ vmime/src/platforms/posix/posixHandler.cpp @@ -153,11 +153,7 @@ const vmime::charset posixHandler::getLo { const PLockHelper lock; - const char* prevLocale = ::setlocale(LC_ALL, ""); - vmime::charset ch(::nl_langinfo(CODESET)); - ::setlocale(LC_ALL, prevLocale); - - return (ch); + return vmime::charset(::nl_langinfo(CODESET)); } Index: vmime/src/utility/encoder/encoderFactory.cpp =================================================================== --- vmime.orig/src/utility/encoder/encoderFactory.cpp +++ vmime/src/utility/encoder/encoderFactory.cpp @@ -43,6 +43,7 @@ encoderFactory::encoderFactory() registerName <b64Encoder>("base64"); registerName <qpEncoder>("quoted-printable"); registerName <uuEncoder>("uuencode"); + registerName <uuEncoder>("x-uuencode"); registerName <sevenBitEncoder>("7bit"); registerName <eightBitEncoder>("8bit"); registerName <binaryEncoder>("binary"); Index: vmime/src/word.cpp =================================================================== --- vmime.orig/src/word.cpp +++ vmime/src/word.cpp @@ -64,8 +64,7 @@ word::word(const string& buffer, const c ref <word> word::parseNext(const string& buffer, const string::size_type position, - const string::size_type end, string::size_type* newPosition, - bool prevIsEncoded, bool* isEncoded, bool isFirst) + const string::size_type end, string::size_type* newPosition, parserState* state) { string::size_type pos = position; @@ -73,11 +72,14 @@ ref <word> word::parseNext(const string& // - before the first word // - between two encoded words // - after the last word + // Always ignore newlines string whiteSpaces; while (pos < end && parserHelpers::isSpace(buffer[pos])) { whiteSpaces += buffer[pos]; + if(buffer[pos] != '\r' && buffer[pos] != '\n') // do not include newlines + whiteSpaces += buffer[pos]; ++pos; } @@ -118,7 +120,7 @@ ref <word> word::parseNext(const string& if (!unencoded.empty()) { - if (prevIsEncoded) + if (state->prevIsEncoded && !state->isFirst) unencoded = whiteSpaces + unencoded; ref <word> w = vmime::create <word>(unencoded, charset(charsets::US_ASCII)); @@ -127,8 +129,8 @@ ref <word> word::parseNext(const string& if (newPosition) *newPosition = pos; - if (isEncoded) - *isEncoded = false; + state->prevIsEncoded = false; + state->isFirst = false; return (w); } @@ -179,13 +181,13 @@ ref <word> word::parseNext(const string& pos += 2; // ?= ref <word> w = vmime::create <word>(); - w->parse(buffer, wordStart, pos, NULL); + w->parseWithState(buffer, wordStart, pos, NULL, state); if (newPosition) *newPosition = pos; - if (isEncoded) - *isEncoded = true; + state->prevIsEncoded = true; + state->isFirst = false; return (w); } @@ -193,7 +195,7 @@ ref <word> word::parseNext(const string& ++pos; } - if (startPos != end && !isFirst && prevIsEncoded) + if (startPos != end && !state->isFirst && state->prevIsEncoded) unencoded += whiteSpaces; if (startPos != end) @@ -208,8 +210,8 @@ ref <word> word::parseNext(const string& if (newPosition) *newPosition = end; - if (isEncoded) - *isEncoded = false; + state->prevIsEncoded = false; + state->isFirst = false; return (w); } @@ -226,9 +228,9 @@ const std::vector <ref <word> > word::pa string::size_type pos = position; - bool prevIsEncoded = false; + parserState state; - while ((w = word::parseNext(buffer, pos, end, &pos, prevIsEncoded, &prevIsEncoded, (w == NULL))) != NULL) + while ((w = word::parseNext(buffer, pos, end, &pos, &state)) != NULL) res.push_back(w); if (newPosition) @@ -241,6 +243,14 @@ const std::vector <ref <word> > word::pa void word::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { + parseWithState(buffer, position, end, newPosition, NULL); +} + + +void word::parseWithState + (const string& buffer, const size_t position, + const size_t end, size_t* newPosition, parserState* state) +{ if (position + 6 < end && // 6 = "=?(.+)?(.*)?=" buffer[position] == '=' && buffer[position + 1] == '?') { @@ -287,12 +297,20 @@ void word::parse(const string& buffer, c if (theEncoder) { // Decode text + string encodedBuffer(dataPos, dataEnd); string decodedBuffer; - utility::inputStreamStringAdapter ein(string(dataPos, dataEnd)); + + if (state && !state->undecodedBytes.empty()) + { + encodedBuffer = state->undecodedBytes + encodedBuffer; + state->undecodedBytes.clear(); + } + + utility::inputStreamStringAdapter ein(encodedBuffer); utility::outputStreamStringAdapter eout(decodedBuffer); - theEncoder->decode(ein, eout); + const size_t decodedLen = theEncoder->decode(ein, eout); delete (theEncoder); m_buffer = decodedBuffer; @@ -303,6 +321,21 @@ void word::parse(const string& buffer, c if (newPosition) *newPosition = (p - buffer.begin()); + // For Base64 encoding, ensure all bytes have been decoded. + // If there are remaining bytes, keep them for the next run. + // + // This allows decoding some insanities like: + // =?utf-8?B?5Lit5?= =?utf-8?B?paH?= + if (*encPos == 'B' || *encPos == 'b') + { + const size_t actualEncodedLen = encodedBuffer.length(); + const size_t theoricalEncodedLen = + ((decodedLen + ((decodedLen % 3) ? (3 - (decodedLen % 3)) : 0) ) / 3) * 4; + + if (state && actualEncodedLen != theoricalEncodedLen) + state->undecodedBytes.assign(dataPos + theoricalEncodedLen, dataEnd); + } + return; } } @@ -690,9 +723,19 @@ bool word::operator!=(const word& w) con const string word::getConvertedText(const charset& dest) const { + if (dest == m_charset) { + return m_buffer; // no conversion needed + } + string out; + try { charset::convert(m_buffer, out, m_charset, dest); + } + catch (vmime::exception &e) { + // copy 'word' as text + out = m_buffer; + } return (out); } Index: vmime/src/wordEncoder.cpp =================================================================== --- vmime.orig/src/wordEncoder.cpp +++ vmime/src/wordEncoder.cpp @@ -239,6 +239,13 @@ bool wordEncoder::isEncodingNeeded(const if (buffer.find_first_of("\n\r") != string::npos) return true; + // If the string contains a QP string, we need to encode this. + // Not a 100% check, but we'd only get more encoded strings. + std::string::size_type pos = buffer.find("=?"); + std::string::size_type end = buffer.find("?="); + if (pos != string::npos && end != string::npos && end > pos) + return true; + return false; } Index: vmime/vmime/address.hpp =================================================================== --- vmime.orig/vmime/address.hpp +++ vmime/vmime/address.hpp @@ -65,7 +65,6 @@ public: virtual ref <component> clone() const = 0; -protected: /** Parse an address from an input buffer. * Index: vmime/vmime/word.hpp =================================================================== --- vmime.orig/vmime/word.hpp +++ vmime/vmime/word.hpp @@ -125,6 +125,20 @@ public: bool prevWordIsEncoded; bool lastCharIsSpace; }; + + class parserState + { + public: + + parserState() + : prevIsEncoded(false), isFirst(true) + { + } + + bool prevIsEncoded; + bool isFirst; + std::string undecodedBytes; + }; #endif @@ -134,13 +148,20 @@ public: void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL); void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const; + void parseWithState + (const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + parserState* state); + void generate(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos, const int flags, generatorState* state) const; const std::vector <ref <const component> > getChildComponents() const; private: - static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, bool prevIsEncoded, bool* isEncoded, bool isFirst); + static ref <word> parseNext(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition, parserState* state); static const std::vector <ref <word> > parseMultiple(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition); ++++++ vmime-mixed-qp-in-parameter.diff ++++++ --- /var/tmp/diff_new_pack.ofRvHa/_old 2015-10-02 09:23:44.000000000 +0200 +++ /var/tmp/diff_new_pack.ofRvHa/_new 2015-10-02 09:23:44.000000000 +0200 @@ -1,28 +1,27 @@ -Index: svn/src/parameter.cpp +--- + src/parameter.cpp | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +Index: vmime/src/parameter.cpp =================================================================== ---- svn/src/parameter.cpp (revision 597) -+++ svn/src/parameter.cpp (working copy) -@@ -239,8 +239,21 @@ - { +--- vmime.orig/src/parameter.cpp ++++ vmime/src/parameter.cpp +@@ -240,7 +240,17 @@ void parameter::parse(const std::vector value << t.getWholeBuffer(); -- if (!foundCharsetChunk) + if (!foundCharsetChunk) - ch = t.getWordAt(0)->getCharset(); -+ if (!foundCharsetChunk) { -+ // this is still wrong. each word can have it's ++ // this is still wrong. each word can have its + // own charset, and can be mixed (eg. iso-8859-1 + // and iso-2022-jp), but very unlikely. + // real fix is to have parameters store a -+ // vmime::text in stead of a vmime::word in ++ // vmime::text instead of a vmime::word in + // m_value. but that changes the interface -+ for (size_t i = 0; i < t.getWordCount(); i++) { ++ for (size_t i = 0; i < t.getWordCount(); i++) + if (t.getWordAt(i)->getCharset() != ch && ch == charsets::US_ASCII) { + ch = t.getWordAt(i)->getCharset(); + break; + } -+ } -+ -+ } } } } ++++++ vmime-noansiflag.patch ++++++ --- /var/tmp/diff_new_pack.ofRvHa/_old 2015-10-02 09:23:45.000000000 +0200 +++ /var/tmp/diff_new_pack.ofRvHa/_new 2015-10-02 09:23:45.000000000 +0200 @@ -24,7 +24,7 @@ #-fomit-frame-pointer -fmove-all-movables -fstrict-aliasing #env.Append(LIBS = ['additional-lib-here']) -@@ -1299,7 +1295,9 @@ VMIME_ADDITIONAL_PC_LIBS="" +@@ -1300,7 +1296,9 @@ VMIME_ADDITIONAL_PC_LIBS="" # Check compilers, processors, etc # @@ -35,7 +35,7 @@ AC_PROG_CXX AC_PROG_CPP AC_C_CONST -@@ -1839,8 +1837,8 @@ AC_SUBST(PKGCONFIG_LIBS) +@@ -1840,8 +1838,8 @@ AC_SUBST(PKGCONFIG_LIBS) EXTRA_CFLAGS="$EXTRA_CFLAGS -D_REENTRANT=1 -D_THREAD_SAFE=1 $LIBGNUTLS_CFLAGS" EXTRA_LIBS="$GSASL_LIBS $LIBGNUTLS_LIBS" @@ -46,7 +46,7 @@ # -- Debug if test x$VMIME_DEBUG = x1 ; then -@@ -1868,7 +1866,7 @@ EXTRA_CFLAGS="$EXTRA_CFLAGS $lt_prog_com +@@ -1869,7 +1867,7 @@ EXTRA_CFLAGS="$EXTRA_CFLAGS $lt_prog_com """)