Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.1
libvmime_zarafa7
vmime-all4debian.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File vmime-all4debian.diff of Package libvmime_zarafa7
--- 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);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor