diff options
73 files changed, 1061 insertions, 832 deletions
@@ -28,6 +28,10 @@ doc/html/* /COPYING.txt /build/ +# CTest-generated files +/CTestTestfile.cmake +/Testing/ + # Mac ._DS_Store diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..650c27f0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +# Travis-CI build file for VMime +# See http://travis-ci.org for details + +language: cpp + +compiler: + - gcc + - clang + +# Settings +env: + - CTEST_OUTPUT_ON_FAILURE=1 OPTIONS="-DVMIME_SENDMAIL_PATH=/path/to/sendmail -DCMAKE_BUILD_TYPE=Debug -DVMIME_BUILD_TESTS=ON" + +# Make sure some required tools/libraries are installed +install: + - sudo apt-get update >/dev/null + - sudo apt-get -q install cmake libcppunit-dev valgrind + - sudo apt-get -q install libgsasl7-dev libgnutls-dev libssl-dev + +# Run the build script +script: + - mkdir _build + - cd _build + - cmake .. -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS + - cmake --build . --target install + - ctest diff --git a/CMakeLists.txt b/CMakeLists.txt index c37407e0..e8a57791 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ INCLUDE(CheckLibraryExists) # CMake configuration SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY build/bin) SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY build/lib) +SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build/lib) SET(CMAKE_VERBOSE_MAKEFILE ON) @@ -83,13 +84,6 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ) -# Automatically set lib suffix -IF(UNIX AND NOT APPLE AND NOT CMAKE_CROSSCOMPILING AND NOT EXISTS "/etc/debian_version") - IF(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT LIB_SUFFIX) - SET(LIB_SUFFIX 64) - ENDIF() -ENDIF() - # Shared library OPTION( VMIME_BUILD_SHARED_LIBRARY @@ -109,8 +103,8 @@ IF(VMIME_BUILD_SHARED_LIBRARY) SET_TARGET_PROPERTIES( ${VMIME_LIBRARY_NAME} PROPERTIES - VERSION "${VMIME_VERSION}" - SOVERSION "${VMIME_API_VERSION}" + VERSION "${VMIME_API_VERSION}" + SOVERSION "${VMIME_API_VERSION_CURRENT}" ) ENDIF() @@ -158,20 +152,55 @@ ENDIF() SET(CMAKE_INSTALL_LIBDIR lib CACHE PATH "Output directory for libraries") +# Automatically set lib suffix +IF(UNIX AND NOT APPLE AND NOT CMAKE_CROSSCOMPILING AND NOT EXISTS "/etc/debian_version") + IF(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT LIB_SUFFIX) + # ...only if LIB_SUFFIX is not defined... + IF(NOT DEFINED LIB_SUFFIX) + # ...and if CMAKE_INSTALL_LIBDIR does not already contain the suffix + IF(NOT "${CMAKE_INSTALL_LIBDIR}" MATCHES ".*64.*") + SET(LIB_SUFFIX 64) + ENDIF() + ENDIF() + ENDIF() +ENDIF() + +# Determine library installation dir, in this order: +# 1) use VMIME_INSTALL_LIBDIR if set +# 2) use LIB_INSTALL_DIR if defined +# 3) use CMAKE_INSTALL_LIBDIR if set +# if it is a relative path, prepend CMAKE_INSTALL_PREFIX to it +# 4) use CMAKE_INSTALL_PREFIX/lib +IF(NOT DEFINED VMIME_INSTALL_LIBDIR) + IF(DEFINED LIB_INSTALL_DIR) + SET(VMIME_INSTALL_LIBDIR ${LIB_INSTALL_DIR}) + # respect CMAKE_INSTALL_LIBDIR if set + ELSEIF(DEFINED CMAKE_INSTALL_LIBDIR) + SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}) + IF(IS_ABSOLUTE ${VMIME_INSTALL_LIBDIR}) + SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}) + ELSE() + SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}) + ENDIF() + ELSE() + SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) + ENDIF() +ENDIF() + # Installation of libraries IF(VMIME_BUILD_SHARED_LIBRARY) INSTALL( TARGETS ${VMIME_LIBRARY_NAME} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT sharedlibs - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT sharedlibs + LIBRARY DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT sharedlibs + ARCHIVE DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT sharedlibs ) ENDIF() IF(VMIME_BUILD_STATIC_LIBRARY) INSTALL( TARGETS ${VMIME_LIBRARY_NAME}-static - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT staticlibs - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT staticlibs + LIBRARY DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT staticlibs + ARCHIVE DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT staticlibs ) ENDIF() @@ -196,21 +225,57 @@ OPTION( IF(VMIME_BUILD_TESTS) + ENABLE_TESTING() + + INCLUDE(cmake/FindCppUnit.cmake) + INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIR}) + FILE( GLOB_RECURSE VMIME_TESTS_SRC_FILES - tests/*Test.cpp tests/testRunner.cpp tests/testUtils.cpp + ${CMAKE_SOURCE_DIR}/tests/*Test.cpp ) + # Build one file for each test + FOREACH(VMIME_TEST_SRC_FILE ${VMIME_TESTS_SRC_FILES}) + + # "/path/to/vmime/tests/module/testFile.cpp" --> "module_testFile" + GET_FILENAME_COMPONENT(VMIME_TEST_SRC_PATH "${VMIME_TEST_SRC_FILE}" PATH) + STRING(REPLACE "${CMAKE_SOURCE_DIR}" "" VMIME_TEST_SRC_PATH "${VMIME_TEST_SRC_PATH}") + GET_FILENAME_COMPONENT(VMIME_TEST_NAME "${VMIME_TEST_SRC_FILE}" NAME_WE) + SET(VMIME_TEST_NAME "${VMIME_TEST_SRC_PATH}/${VMIME_TEST_NAME}") + STRING(REPLACE "/" "_" VMIME_TEST_NAME "${VMIME_TEST_NAME}") + STRING(REPLACE "_tests_" "" VMIME_TEST_NAME "${VMIME_TEST_NAME}") + + ADD_EXECUTABLE( + ${VMIME_TEST_NAME} + ${VMIME_TEST_SRC_FILE} ${CMAKE_SOURCE_DIR}/tests/testRunner.cpp ${CMAKE_SOURCE_DIR}/tests/testUtils.cpp + ) + + TARGET_LINK_LIBRARIES( + ${VMIME_TEST_NAME} + ${VMIME_LIBRARY_NAME} + ${CPPUNIT_LIBRARY} + ) + + ADD_DEPENDENCIES( + ${VMIME_TEST_NAME} + ${VMIME_LIBRARY_NAME} + ) + + ADD_TEST( + ${VMIME_TEST_NAME} + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${VMIME_TEST_NAME} + ) + + ENDFOREACH() + + # Build one file for all tests ADD_EXECUTABLE( "run-tests" - ${VMIME_TESTS_SRC_FILES} + ${VMIME_TESTS_SRC_FILES} ${CMAKE_SOURCE_DIR}/tests/testRunner.cpp ${CMAKE_SOURCE_DIR}/tests/testUtils.cpp ) - INCLUDE(cmake/FindCppUnit.cmake) - - INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIR}) - TARGET_LINK_LIBRARIES( "run-tests" ${VMIME_LIBRARY_NAME} @@ -290,18 +355,12 @@ ADD_CUSTOM_TARGET( SET(prefix ${CMAKE_INSTALL_PREFIX}) SET(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin) SET(includedir ${CMAKE_INSTALL_PREFIX}/include/vmime) +SET(libdir ${VMIME_INSTALL_LIBDIR}) SET(VMIME_PKGCONFIG_LIBS "") SET(VMIME_PKGCONFIG_CFLAGS "") SET(VMIME_PKGCONFIG_REQUIRES "") -IF(${UNIX}) - SET(libdir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) -ENDIF(${UNIX}) -IF(${WIN32}) - SET(libdir ${CMAKE_INSTALL_PREFIX}/bin) -ENDIF(${WIN32}) - ############################################################################## # Build type @@ -625,6 +684,8 @@ IF(WIN32) ${TARGET_LINK_LIBRARIES} "ws2_32" ) + ELSE() + SET(VMIME_PKGCONFIG_LIBS "${VMIME_PKGCONFIG_LIBS} -lws2_32") ENDIF() ENDIF() @@ -763,11 +824,11 @@ ENDIF() # Set our configure file -CONFIGURE_FILE(cmake/config.hpp.cmake vmime/config.hpp) +CONFIGURE_FILE(cmake/config.hpp.cmake ${CMAKE_SOURCE_DIR}/vmime/config.hpp) # PkgConfig post-configuration CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/libvmime.pc.in ${CMAKE_BINARY_DIR}/libvmime.pc @ONLY) -INSTALL(FILES ${CMAKE_BINARY_DIR}/libvmime.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig COMPONENT headers) +INSTALL(FILES ${CMAKE_BINARY_DIR}/libvmime.pc DESTINATION "${VMIME_INSTALL_LIBDIR}/pkgconfig" COMPONENT headers) INCLUDE(CPack) @@ -346,7 +346,8 @@ libvmime_tests = [ ] libvmimetest_common = [ - 'tests/testUtils.hpp' + 'tests/testUtils.hpp', + 'tests/utility/encoder/encoderTestUtils.hpp' ] libvmimetest_sources = [ @@ -356,12 +357,14 @@ libvmimetest_sources = [ 'tests/parser/attachmentHelperTest.cpp', 'tests/parser/bodyPartTest.cpp', 'tests/parser/charsetTest.cpp', + 'tests/parser/charsetFilteredOutputStreamTest.cpp', 'tests/parser/datetimeTest.cpp', 'tests/parser/dispositionTest.cpp', 'tests/parser/emailAddressTest.cpp', 'tests/parser/headerTest.cpp', 'tests/parser/headerFieldTest.cpp', 'tests/parser/htmlTextPartTest.cpp', + 'tests/parser/mailboxGroupTest.cpp', 'tests/parser/mailboxTest.cpp', 'tests/parser/mediaTypeTest.cpp', 'tests/parser/messageIdTest.cpp', @@ -378,7 +381,8 @@ libvmimetest_sources = [ 'tests/utility/pathTest.cpp', 'tests/utility/urlTest.cpp', 'tests/utility/smartPtrTest.cpp', - 'tests/utility/encoderTest.cpp', + 'tests/utility/encoder/qpEncoderTest.cpp', + 'tests/utility/encoder/b64EncoderTest.cpp', 'tests/utility/outputStreamStringAdapterTest.cpp', 'tests/utility/outputStreamSocketAdapterTest.cpp', 'tests/utility/outputStreamByteArrayAdapterTest.cpp', diff --git a/doc/book/net.tex b/doc/book/net.tex index 6977c290..7653b48e 100644 --- a/doc/book/net.tex +++ b/doc/book/net.tex @@ -701,10 +701,13 @@ class timeoutHandler : public object \end{lstlisting} While the operation runs, the service calls {\vcode isTimeout()} at variable -intervals. If the function returns {\vcode true}, then -{\vcode handleTimeout()} is called. If it also returns {\vcode true}, the -operation is cancelled and an {\vcode operation\_timed\_out} exception is -thrown. The function {\vcode resetTimeout()} is called each time data has +intervals. If the {\vcode isTimeout()} function returns {\vcode true}, +then {\vcode handleTimeout()} is called. If the {\vcode handleTimeout()} +function returns {\vcode false}, the operation is cancelled and +an {\vcode operation\_timed\_out} exception is thrown. Else, if +{\vcode handleTimeout()} returns true, the operation continues and the +time-out count is reset. +The function {\vcode resetTimeout()} is called each time data has been received from the server to reset time-out delay. The following example shows how to implement a simple time-out handler: diff --git a/src/address.cpp b/src/address.cpp index ab207cf6..b57892d5 100644 --- a/src/address.cpp +++ b/src/address.cpp @@ -68,7 +68,7 @@ address-list = (address *("," address)) / obs-addr-list ref <address> address::parseNext (const parsingContext& ctx, const string& buffer, const string::size_type position, - const string::size_type end, string::size_type* newPosition) + const string::size_type end, string::size_type* newPosition, bool *isLastAddressOfGroup) { bool escaped = false; bool quoted = false; @@ -76,6 +76,10 @@ ref <address> address::parseNext bool inRouteAddr = false; bool isGroup = false; bool stop = false; + int commentLevel = 0; + + if (isLastAddressOfGroup) + *isLastAddressOfGroup = false; string::size_type pos = position; @@ -106,9 +110,22 @@ ref <address> address::parseNext case '>': inRouteAddr = false; break; + + case '(': + + ++commentLevel; + break; + + case ')': + + if (commentLevel > 0) + --commentLevel; + + break; + case '=': - if (!quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?') + if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?') { ++pos; quotedRFC2047 = true; @@ -118,7 +135,7 @@ ref <address> address::parseNext case '?': - if (quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=') + if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=') { ++pos; quotedRFC2047 = false; @@ -128,7 +145,7 @@ ref <address> address::parseNext default: { - if (!quoted && !quotedRFC2047 && !inRouteAddr) + if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr) { switch (buffer[pos]) { @@ -140,6 +157,9 @@ ref <address> address::parseNext ++pos; } + if (isLastAddressOfGroup) + *isLastAddressOfGroup = true; + stop = true; break; diff --git a/src/addressList.cpp b/src/addressList.cpp index 5e033f38..326a54e3 100644 --- a/src/addressList.cpp +++ b/src/addressList.cpp @@ -60,7 +60,7 @@ void addressList::parseImpl while (pos < end) { - ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos); + ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL); if (parsedAddress != NULL) m_list.push_back(parsedAddress); diff --git a/src/headerField.cpp b/src/headerField.cpp index 59b10e76..7d23ce84 100644 --- a/src/headerField.cpp +++ b/src/headerField.cpp @@ -142,7 +142,7 @@ ref <headerField> headerField::parseNext ++pos; const string::size_type contentsStart = pos; - string::size_type contentsEnd = 0; + string::size_type contentsEnd = end; // Extract the field value while (pos < end) diff --git a/src/mailboxField.cpp b/src/mailboxField.cpp index 1f11f49c..4eb9d734 100644 --- a/src/mailboxField.cpp +++ b/src/mailboxField.cpp @@ -52,7 +52,7 @@ void mailboxField::parse // Here, we cannot simply call "m_mailbox.parse()" because it // may have more than one address specified (even if this field // should contain only one). We are never too much careful... - ref <address> parsedAddress = address::parseNext(ctx, buffer, position, end, newPosition); + ref <address> parsedAddress = address::parseNext(ctx, buffer, position, end, newPosition, NULL); if (parsedAddress) { diff --git a/src/mailboxGroup.cpp b/src/mailboxGroup.cpp index 65611b33..9da16653 100644 --- a/src/mailboxGroup.cpp +++ b/src/mailboxGroup.cpp @@ -78,10 +78,11 @@ void mailboxGroup::parseImpl string::size_type pos = position + (p - pstart); + bool isLastAddressOfGroup = false; - while (pos < end) + while (pos < end && !isLastAddressOfGroup) { - ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos); + ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, &isLastAddressOfGroup); if (parsedAddress) { @@ -103,7 +104,7 @@ void mailboxGroup::parseImpl } } - text::decodeAndUnfold(ctx, name, &m_name); + text::decodeAndUnfold(ctx, utility::stringUtils::trim(name), &m_name); setParsedBounds(position, end); diff --git a/src/mediaType.cpp b/src/mediaType.cpp index 62d65c23..123c8cee 100644 --- a/src/mediaType.cpp +++ b/src/mediaType.cpp @@ -49,7 +49,7 @@ mediaType::mediaType(const string& type, const string& subType) void mediaType::parseImpl - (const parsingContext& ctx, const string& buffer, const string::size_type position, + (const parsingContext& /* ctx */, const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { const string::value_type* const pend = buffer.data() + end; diff --git a/src/net/smtp/SMTPCommandSet.cpp b/src/net/smtp/SMTPCommandSet.cpp index 0454e184..a967c3a6 100644 --- a/src/net/smtp/SMTPCommandSet.cpp +++ b/src/net/smtp/SMTPCommandSet.cpp @@ -124,7 +124,7 @@ const string SMTPCommandSet::getText() const } -const bool SMTPCommandSet::isFinished() const +bool SMTPCommandSet::isFinished() const { return (m_pipeline && m_started) || (m_commands.size() == 0 && m_started); } diff --git a/src/parameter.cpp b/src/parameter.cpp index 37a59890..b86d4815 100644 --- a/src/parameter.cpp +++ b/src/parameter.cpp @@ -234,7 +234,7 @@ void parameter::parse(const parsingContext& ctx, const std::vector <valueChunk>& // This syntax is non-standard (expressly prohibited // by RFC-2047), but is used by Mozilla: // - // Content-Type: image/png; + // Content-Type: image/png; // name="=?us-ascii?Q?Logo_VMime=2Epng?=" // Using 'vmime::text' to parse the data is safe even @@ -248,7 +248,20 @@ void parameter::parse(const parsingContext& ctx, const std::vector <valueChunk>& value << t.getWholeBuffer(); if (!foundCharsetChunk) - ch = t.getWordAt(0)->getCharset(); + { + // This is still wrong. Each word can have it's 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; + } + } + } } } } diff --git a/src/parameterizedHeaderField.cpp b/src/parameterizedHeaderField.cpp index 619fe7cf..c4e0b368 100644 --- a/src/parameterizedHeaderField.cpp +++ b/src/parameterizedHeaderField.cpp @@ -98,7 +98,7 @@ void parameterizedHeaderField::parseImpl // 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; @@ -119,6 +119,12 @@ void parameterizedHeaderField::parseImpl { std::map <string, paramInfo> params; + if (*p != ';') + { + while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text + ++p; + } + while (*p == ';') { // Skip ';' diff --git a/src/utility/streamUtils.cpp b/src/utility/streamUtils.cpp index 72916547..06ea17a1 100644 --- a/src/utility/streamUtils.cpp +++ b/src/utility/streamUtils.cpp @@ -68,7 +68,7 @@ stream::size_type bufferedStreamCopyRange(inputStream& is, outputStream& os, while (!is.eof() && total < length) { const stream::size_type remaining = std::min(length - total, blockSize); - const stream::size_type read = is.read(buffer, blockSize); + const stream::size_type read = is.read(buffer, remaining); if (read != 0) { diff --git a/src/word.cpp b/src/word.cpp index b558b842..8e254865 100644 --- a/src/word.cpp +++ b/src/word.cpp @@ -125,7 +125,7 @@ ref <word> word::parseNext if (!unencoded.empty()) { - if (prevIsEncoded) + if (prevIsEncoded && !isFirst) unencoded = whiteSpaces + unencoded; ref <word> w = vmime::create <word>(unencoded, defaultCharset); @@ -200,11 +200,13 @@ ref <word> word::parseNext ++pos; } - if (startPos != end && !isFirst && prevIsEncoded) - unencoded += whiteSpaces; - if (startPos != end) + { + if (prevIsEncoded && !isFirst) + unencoded = whiteSpaces + unencoded; + unencoded += buffer.substr(startPos, end - startPos); + } // Treat unencoded text at the end of the buffer if (!unencoded.empty()) diff --git a/src/wordEncoder.cpp b/src/wordEncoder.cpp index 82a74cff..332f9bf2 100644 --- a/src/wordEncoder.cpp +++ b/src/wordEncoder.cpp @@ -247,7 +247,7 @@ bool wordEncoder::isEncodingNeeded return true; // If any RFC-2047 sequence is found in the buffer, encode it - if (buffer.find("=?") != string::npos) + if (buffer.find("=?") != string::npos || buffer.find("?=") != string::npos) return true; return false; diff --git a/tests/charset/Makefile b/tests/charset/Makefile deleted file mode 100644 index e46fafa5..00000000 --- a/tests/charset/Makefile +++ /dev/null @@ -1,5 +0,0 @@ - - -main: main.cpp ../../libvmime-debug.a - g++ -g -o main main.cpp -I../.. ../../libvmime-debug.a -lgnutls -lgsasl - diff --git a/tests/charset/main.cpp b/tests/charset/main.cpp deleted file mode 100644 index d8523461..00000000 --- a/tests/charset/main.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 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. -// - -#include <iostream> -#include <ostream> - -#include "vmime/vmime.hpp" -#include "vmime/platforms/posix/posixHandler.hpp" - - -int main(int argc, char* argv[]) -{ - // VMime initialization - vmime::platform::setHandler<vmime::platforms::posix::posixHandler>(); - - - const vmime::string from(argv[1]); - const vmime::string to(argv[2]); - - vmime::utility::inputStreamAdapter in(std::cin); - vmime::utility::outputStreamAdapter out(std::cout); - - vmime::charset::convert(in, out, from, to); -} diff --git a/tests/charset/run-test.sh b/tests/charset/run-test.sh deleted file mode 100755 index 95846c06..00000000 --- a/tests/charset/run-test.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh - -TEST_DIR="./test-suites" -TEMP_DIR="/tmp" -PROGRAM="./main" - - -testFiles=`cd $TEST_DIR ; find . -maxdepth 1 -regex '\./[^\.]*\.in\..*' -type f` - -echo -echo Testing charset conversions -echo ===================================================================== - -for testFile in $testFiles ; do - - testName=`echo $testFile | sed 's/^\.\/\([^\.]*\).*/\1/'` - sourceCharset=`echo $testFile | sed 's/^\.\/[^\.]*\.[^\.]*\.\(.*\)/\1/'` - - testOutFiles=`cd $TEST_DIR ; find . -maxdepth 1 -regex "\./$testName\.out\..*" -type f` - - for testOutFile in $testOutFiles ; do - - destCharset=`echo $testOutFile | sed 's/^\.\/[^\.]*\.[^\.]*\.\(.*\)/\1/'` - - printf %20s "$testName " - printf %30s "$sourceCharset --> $destCharset : " - - $PROGRAM $sourceCharset $destCharset < $TEST_DIR/$testFile > $TEMP_DIR/vmime_result - - diff="diff $TEMP_DIR/vmime_result $TEST_DIR/$testOutFile" - res=`$diff` - - if [ "$res" = "" ] - then - echo "[OK]" - else - diffFile=$TEMP_DIR/vmime.charset.$testName.$sourceCharset.$destCharset.diff - echo "[NO: diff file is $diffFile]" - $diff > $diffFile - fi - - done - -done - -echo - diff --git a/tests/charset/test-suites/gnu.in.utf-8 b/tests/charset/test-suites/gnu.in.utf-8 deleted file mode 100644 index 782bb84e..00000000 --- a/tests/charset/test-suites/gnu.in.utf-8 +++ /dev/null @@ -1,48 +0,0 @@ -Korean Part. -GNU 프로젝트의 웹서버인 www.gnu.org에 오신 것을 환영합니다. GNU 프로젝트는 -GNU 시스템이라고 불리는 유닉스 형태의 완벽한 자유 소프트웨어 운영체제를 -개발하기 위해서 1984년부터 시작되었습니다. (GNU라는 단어는 ``GNU's Not -Unix''를 의미하는 재귀적 약어이며 ``그-뉴"라고 발음합니다.) GNU -시스템으로부터 연유한 다양한 종류의 운영체제들이 현재 ``리눅스''라는 -이름으로 사용되고 있지만, 시스템 커널로 리눅스를 탑재한 운영체제의 보다 -정확한 이름은 GNU/리눅스 시스템입니다. - -Japanese Part - -GNU プロジェクトのウェブサーバ、www.gnu.org へようこそ。1984 年のプロジェクト -開始以来、GNU プロジェクトでは、Unix に似た フリーソフトウェアの完全なオペレー -ティングシステム、GNU システムを開発して来ました(GNU とは「GNU's Not Unix(GNU -は Unix ではない)」の再帰頭字語であり、「グニュー」と発音されます)。現在、カーネ -ルとして Linux を用いた GNU システムのさまざまな変種が広く使われています。これ -らのシステムは「Linux」と呼ばれることが多いのですが、より正確には GNU/Linux -システム と呼ばれるものなのです。 - -Chinese Part. - -歡迎來到GNU 專案的伺服主機,www.gnu.org。 GNU 專案 開始於1984年,旨在發展一 -個 Unix-like 且為 自由軟體 的作業系統: GNU 系統。(GNU 是由``GNU's Not -Unix''所遞迴定義出的頭字語);它的發音為"guh-NEW"。各種使用 Linux 作為核心的 GNU -作業系統正被廣泛的使用著;雖然這些系統通常被稱作 ``Linux'',但是它們應該更精 -確地被稱為 GNU/Linux 系統。 - -English Part. - -Welcome to the GNU Project web server, www.gnu.org. The GNU Project was -launched in 1984 to develop a complete Unix-like operating system which is -free software: the GNU system. (GNU is a recursive acronym for ``GNU's Not -Unix''; it is pronounced "guh-NEW".) Variants of the GNU operating system, -which use the kernel Linux, are now widely used; though these systems are -often referred to as ``Linux'', they are more accurately called GNU/Linux -systems. - -French Part. -Bienvenue sur le serveur web du projet GNU, www.gnu.org. Le projet GNU a été -lancé en 1984 afin de développer un système d'exploitation complet, -semblable à Unix et qui soit un logiciel libre: le système GNU. (« GNU » -est l'acronyme récursif the « GNU's Not Unix »; on le prononce « gnou » -avec un G audible) Des variantes du système d'exploitation GNU, basées sur -le noyau « Linux », sont utilisées largement à présent; bien que ces -systèmes soient communément appelés par le terme « Linux », ils le -seraient plus exactement par « GNU/Linux ». - - diff --git a/tests/charset/test-suites/gnu.out.iso-8859-1 b/tests/charset/test-suites/gnu.out.iso-8859-1 deleted file mode 100644 index bc11399e..00000000 --- a/tests/charset/test-suites/gnu.out.iso-8859-1 +++ /dev/null @@ -1,48 +0,0 @@ -Korean Part. -GNU ??????????????? ???????????? www.gnu.org??? ?????? ?????? ???????????????. GNU ??????????????? -GNU ?????????????????? ????????? ????????? ????????? ????????? ?????? ??????????????? ??????????????? -???????????? ????????? 1984????????? ?????????????????????. (GNU?????? ????????? ``GNU's Not -Unix''??? ???????????? ????????? ???????????? ``???-???"?????? ???????????????.) GNU -????????????????????? ????????? ????????? ????????? ?????????????????? ?????? ``?????????''?????? -???????????? ???????????? ?????????, ????????? ????????? ???????????? ????????? ??????????????? ?????? -????????? ????????? GNU/????????? ??????????????????. - -Japanese Part - -GNU ??????????????????????????????????????????www.gnu.org ??????????????????1984 ???????????????????????? -???????????????GNU ???????????????????????????Unix ????????? ??????????????????????????????????????????????????? -???????????????????????????GNU ???????????????????????????????????????(GNU ?????????GNU's Not Unix(GNU -??? Unix ????????????)????????????????????????????????????????????????????????????????????????)????????????????????? -???????????? Linux ???????????? GNU ??????????????????????????????????????????????????????????????????????????? -????????????????????????Linux?????????????????????????????????????????????????????????????????? GNU/Linux -???????????? ???????????????????????????????????? - -Chinese Part. - -????????????GNU ????????????????????????www.gnu.org??? GNU ?????? ?????????1984????????????????????? -??? Unix-like ?????? ???????????? ?????????????????? GNU ????????????GNU ??????``GNU's Not -Unix''???????????????????????????????????????????????????"guh-NEW"??????????????? Linux ??????????????? GNU -???????????????????????????????????????????????????????????????????????? ``Linux''??????????????????????????? -??????????????? GNU/Linux ????????? - -English Part. - -Welcome to the GNU Project web server, www.gnu.org. The GNU Project was -launched in 1984 to develop a complete Unix-like operating system which is -free software: the GNU system. (GNU is a recursive acronym for ``GNU's Not -Unix''; it is pronounced "guh-NEW".) Variants of the GNU operating system, -which use the kernel Linux, are now widely used; though these systems are -often referred to as ``Linux'', they are more accurately called GNU/Linux -systems. - -French Part. -Bienvenue sur le serveur web du projet GNU, www.gnu.org. Le projet GNU a �t� -lanc� en 1984 afin de d�velopper un syst�me d'exploitation complet, -semblable � Unix et qui soit un logiciel libre: le syst�me GNU. (� GNU � -est l'acronyme r�cursif the � GNU's Not Unix �; on le prononce � gnou � -avec un G audible) Des variantes du syst�me d'exploitation GNU, bas�es sur -le noyau � Linux �, sont utilis�es largement � pr�sent; bien que ces -syst�mes soient commun�ment appel�s par le terme � Linux �, ils le -seraient plus exactement par � GNU/Linux �. - - diff --git a/tests/misc/importanceHelperTest.cpp b/tests/misc/importanceHelperTest.cpp index 1227cb40..f4696efb 100644 --- a/tests/misc/importanceHelperTest.cpp +++ b/tests/misc/importanceHelperTest.cpp @@ -26,11 +26,7 @@ #include "vmime/misc/importanceHelper.hpp" -#define VMIME_TEST_SUITE importanceHelperTest -#define VMIME_TEST_SUITE_MODULE "Misc" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(importanceHelperTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testResetImportance) diff --git a/tests/net/maildir/maildirStoreTest.cpp b/tests/net/maildir/maildirStoreTest.cpp index d908d471..10de80df 100644 --- a/tests/net/maildir/maildirStoreTest.cpp +++ b/tests/net/maildir/maildirStoreTest.cpp @@ -29,10 +29,6 @@ #include "vmime/net/maildir/maildirFormat.hpp" -#define VMIME_TEST_SUITE maildirStoreTest -#define VMIME_TEST_SUITE_MODULE "Net/Maildir" - - // Shortcuts and helpers typedef vmime::utility::file::path fspath; typedef vmime::utility::file::path::component fspathc; @@ -142,7 +138,7 @@ static const vmime::string TEST_MAILDIRFILES_COURIER[] = // files to create and -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(maildirStoreTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testDetectFormat_KMail) diff --git a/tests/net/pop3/POP3ResponseTest.cpp b/tests/net/pop3/POP3ResponseTest.cpp index 54c36274..1541ce8b 100644 --- a/tests/net/pop3/POP3ResponseTest.cpp +++ b/tests/net/pop3/POP3ResponseTest.cpp @@ -26,14 +26,10 @@ #include "vmime/net/pop3/POP3Response.hpp" -#define VMIME_TEST_SUITE POP3ResponseTest -#define VMIME_TEST_SUITE_MODULE "Net/POP3" - - using namespace vmime::net::pop3; -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testSingleLineResponseOK) diff --git a/tests/net/pop3/POP3UtilsTest.cpp b/tests/net/pop3/POP3UtilsTest.cpp index f1e4f597..ac92056a 100644 --- a/tests/net/pop3/POP3UtilsTest.cpp +++ b/tests/net/pop3/POP3UtilsTest.cpp @@ -27,14 +27,10 @@ #include "vmime/net/pop3/POP3Response.hpp" -#define VMIME_TEST_SUITE POP3UtilsTest -#define VMIME_TEST_SUITE_MODULE "Net/POP3" - - using namespace vmime::net::pop3; -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(POP3UtilsTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParseMultiListOrUidlResponse) diff --git a/tests/net/smtp/SMTPCommandSetTest.cpp b/tests/net/smtp/SMTPCommandSetTest.cpp index a315d678..0cf4b03b 100644 --- a/tests/net/smtp/SMTPCommandSetTest.cpp +++ b/tests/net/smtp/SMTPCommandSetTest.cpp @@ -30,11 +30,7 @@ using namespace vmime::net::smtp; -#define VMIME_TEST_SUITE SMTPCommandSetTest -#define VMIME_TEST_SUITE_MODULE "Net/SMTP" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testCreate) diff --git a/tests/net/smtp/SMTPCommandTest.cpp b/tests/net/smtp/SMTPCommandTest.cpp index 0ff52741..10052f3f 100644 --- a/tests/net/smtp/SMTPCommandTest.cpp +++ b/tests/net/smtp/SMTPCommandTest.cpp @@ -29,11 +29,7 @@ using namespace vmime::net::smtp; -#define VMIME_TEST_SUITE SMTPCommandTest -#define VMIME_TEST_SUITE_MODULE "Net/SMTP" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testCreateCommand) diff --git a/tests/net/smtp/SMTPResponseTest.cpp b/tests/net/smtp/SMTPResponseTest.cpp index 17c7774c..7d8a13c9 100644 --- a/tests/net/smtp/SMTPResponseTest.cpp +++ b/tests/net/smtp/SMTPResponseTest.cpp @@ -26,11 +26,7 @@ #include "vmime/net/smtp/SMTPResponse.hpp" -#define VMIME_TEST_SUITE SMTPResponseTest -#define VMIME_TEST_SUITE_MODULE "Net/SMTP" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testSingleLineResponse) diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp index 4f34f71f..4ffda792 100644 --- a/tests/net/smtp/SMTPTransportTest.cpp +++ b/tests/net/smtp/SMTPTransportTest.cpp @@ -24,15 +24,11 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE SMTPTransportTest -#define VMIME_TEST_SUITE_MODULE "Net/SMTP" - - class greetingErrorSMTPTestSocket; class MAILandRCPTSMTPTestSocket; -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testGreetingError) diff --git a/tests/parser/attachmentHelperTest.cpp b/tests/parser/attachmentHelperTest.cpp index c043db23..0ddf2448 100644 --- a/tests/parser/attachmentHelperTest.cpp +++ b/tests/parser/attachmentHelperTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE attachmentHelperTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testAddAttachment1) diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp index 1c5545a2..487b3160 100644 --- a/tests/parser/bodyPartTest.cpp +++ b/tests/parser/bodyPartTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE bodyPartTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(bodyPartTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) diff --git a/tests/parser/charsetFilteredOutputStreamTest.cpp b/tests/parser/charsetFilteredOutputStreamTest.cpp new file mode 100644 index 00000000..fdfed2c6 --- /dev/null +++ b/tests/parser/charsetFilteredOutputStreamTest.cpp @@ -0,0 +1,205 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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. +// + +#include "tests/testUtils.hpp" + +#include "vmime/charset.hpp" +#include "vmime/charsetConverter.hpp" + +#include "charsetTestSuites.hpp" + + +VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest) + + VMIME_TEST_LIST_BEGIN + VMIME_TEST(testInputBufferUnderflow) + VMIME_TEST(testInvalidInput1) + VMIME_TEST(testStreamCopy) + VMIME_TEST(testOneByteAtTime) + VMIME_TEST(testVariableInputChunk) + VMIME_TEST_LIST_END + + + void testInputBufferUnderflow() + { + vmime::ref <vmime::charsetConverter> cc = + vmime::charsetConverter::create("utf-8", "iso-8859-1"); + + vmime::string output; + vmime::utility::outputStreamStringAdapter os(output); + vmime::ref <vmime::utility::filteredOutputStream> cfos = cc->getFilteredOutputStream(os); + + // føo = 66 c3 b8 6f [UTF8] + // føo = 66 c3 b8 6f [latin1] + + cfos->write("\x66\xc3", 2); + + // Incomplete UTF-8 sequence was not converted + VASSERT_EQ("chunk 1", toHex("f"), toHex(output)); + + // Write second byte of UTF-8 sequence + cfos->write("\xb8\x6f", 2); + + VASSERT_EQ("chunk 2", toHex("f\xf8o"), toHex(output)); + } + + void testInvalidInput1() + { + vmime::string in("foo\xab\xcd\xef bar"); + vmime::string expectedOut("foo??? bar"); + + vmime::string actualOut; + vmime::utility::outputStreamStringAdapter osa(actualOut); + + vmime::ref <vmime::charsetConverter> conv = + vmime::charsetConverter::create + (vmime::charset("utf-8"), + vmime::charset("iso-8859-1")); + + vmime::ref <vmime::utility::charsetFilteredOutputStream> os = + conv->getFilteredOutputStream(osa); + + vmime::utility::inputStreamStringAdapter is(in); + + vmime::utility::stream::value_type buffer[16]; + + for (int i = 0 ; !is.eof() ; ++i) + os->write(buffer, is.read(buffer, 1)); + + os->flush(); + + VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut)); + } + + // Using 'bufferedStreamCopy' + void testStreamCopy() + { + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) + { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; + + std::ostringstream testName; + testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset; + + const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength); + vmime::string in(entry.fromBytes, entry.fromBytes + inLength); + + const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength); + vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength); + + vmime::string actualOut; + vmime::utility::outputStreamStringAdapter osa(actualOut); + + vmime::ref <vmime::charsetConverter> conv = + vmime::charsetConverter::create(entry.fromCharset, entry.toCharset); + + vmime::ref <vmime::utility::charsetFilteredOutputStream> os = + conv->getFilteredOutputStream(osa); + + vmime::utility::inputStreamStringAdapter is(in); + + vmime::utility::bufferedStreamCopy(is, *os); + + os->flush(); + + VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut)); + } + } + + // One byte at a time + void testOneByteAtTime() + { + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) + { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; + + std::ostringstream testName; + testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset; + + const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength); + vmime::string in(entry.fromBytes, entry.fromBytes + inLength); + + const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength); + vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength); + + vmime::string actualOut; + vmime::utility::outputStreamStringAdapter osa(actualOut); + + vmime::ref <vmime::charsetConverter> conv = + vmime::charsetConverter::create(entry.fromCharset, entry.toCharset); + + vmime::ref <vmime::utility::charsetFilteredOutputStream> os = + conv->getFilteredOutputStream(osa); + + vmime::utility::inputStreamStringAdapter is(in); + + vmime::utility::stream::value_type buffer[16]; + + for (int i = 0 ; !is.eof() ; ++i) + os->write(buffer, is.read(buffer, 1)); + + os->flush(); + + VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut)); + } + } + + // Variable chunks + void testVariableInputChunk() + { + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) + { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; + + std::ostringstream testName; + testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset; + + const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength); + vmime::string in(entry.fromBytes, entry.fromBytes + inLength); + + const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength); + vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength); + + vmime::string actualOut; + vmime::utility::outputStreamStringAdapter osa(actualOut); + + vmime::ref <vmime::charsetConverter> conv = + vmime::charsetConverter::create(entry.fromCharset, entry.toCharset); + + vmime::ref <vmime::utility::charsetFilteredOutputStream> os = + conv->getFilteredOutputStream(osa); + + vmime::utility::inputStreamStringAdapter is(in); + + vmime::utility::stream::value_type buffer[16]; + + for (int i = 0 ; !is.eof() ; ++i) + os->write(buffer, is.read(buffer, (i % 5) + 1)); + + os->flush(); + + VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut)); + } + } + +VMIME_TEST_SUITE_END diff --git a/tests/parser/charsetTest.cpp b/tests/parser/charsetTest.cpp index eaedb218..8725c530 100644 --- a/tests/parser/charsetTest.cpp +++ b/tests/parser/charsetTest.cpp @@ -23,230 +23,76 @@ #include "tests/testUtils.hpp" +#include "charsetTestSuites.hpp" -#define VMIME_TEST_SUITE charsetTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -// Excerpt from http://www.gnu.org/ -static const vmime::charset inputCharset("gb2312"); -static const char inputBytes[] = - "\xbb\xb6\xd3\xad\xc0\xb4\xb5\xbd\x20\x47\x4e\x55\x20\xb9\xa4\xb3" - "\xcc\xb5\xc4\xcd\xf8\xd2\xb3\xcb\xc5\xb7\xfe\xd6\xf7\xbb\xfa\x20" - "\x77\x77\x77\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xa1\xa3\x20\x47" - "\x4e\x55\x20\xb9\xa4\xb3\xcc\x20\xbf\xaa\xca\xbc\xec\xb6\xd2\xbb" - "\xbe\xc5\xb0\xcb\xcb\xc4\xc4\xea\xa3\xac\xd6\xbc\xd4\xda\xb7\xa2" - "\xd5\xb9\xd2\xbb\xb8\xf6\xc0\xe0\xcb\xc6\x20\x55\x6e\x69\x78\x20" - "\xa3\xac\xc7\xd2\xce\xaa\x20\xd7\xd4\xd3\xc9\xc8\xed\xbc\xfe\x20" - "\xb5\xc4\xcd\xea\xd5\xfb\xb2\xd9\xd7\xf7\xcf\xb5\xcd\xb3\xa3\xba" - "\x20\x47\x4e\x55\x20\xcf\xb5\xcd\xb3\xa1\xa3\xa3\xa8\x47\x4e\x55" - "\x20\xca\xc7\xd3\xc9\xa1\xb0\x47\x4e\x55\x27\x73\x20\x4e\x6f\x74" - "\x20\x55\x6e\x69\x78\xa1\xb1\xcb\xf9\xb5\xdd\xbb\xd8\xb6\xa8\xd2" - "\xe5\xb3\xf6\xb5\xc4\xca\xd7\xd7\xd6\xc4\xb8\xcb\xf5\xd0\xb4\xd3" - "\xef\xa3\xbb\xcb\xfc\xb5\xc4\xb7\xa2\xd2\xf4\xce\xaa\xa1\xb0\x67" - "\x75\x68\x2d\x4e\x45\x57\xa1\xb1\xa3\xa9\xa1\xa3\xb8\xf7\xd6\xd6" - "\xca\xb9\xd3\xc3\x20\x4c\x69\x6e\x75\x78\x20\xd7\xf7\xce\xaa\xc4" - "\xda\xba\xcb\xb5\xc4\x20\x47\x4e\x55\x20\xb2\xd9\xd7\xf7\xcf\xb5" - "\xcd\xb3\xd5\xfd\xb1\xbb\xb9\xe3\xb7\xba\xb5\xd8\xca\xb9\xd3\xc3" - "\xd6\xf8\xa3\xbb\xcb\xe4\xc8\xbb\xd5\xe2\xd0\xa9\xcf\xb5\xcd\xb3" - "\xcd\xa8\xb3\xa3\xb1\xbb\xb3\xc6\xd7\xf7\xce\xaa\xa1\xb0\x4c\x69" - "\x6e\x75\x78\xa1\xb1\xa3\xac\xb5\xab\xca\xc7\xcb\xfc\xc3\xc7\xd3" - "\xa6\xb8\xc3\xb8\xfc\xbe\xab\xc8\xb7\xb5\xd8\xb1\xbb\xb3\xc6\xce" - "\xaa\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xcf\xb5\xcd\xb3" - "\x20\xa1\xa3\x0a"; - -static const vmime::charset outputCharset("utf-8"); -static const char outputBytes[] = - "\xe6\xac\xa2\xe8\xbf\x8e\xe6\x9d\xa5\xe5\x88\xb0\x20\x47\x4e\x55" - "\x20\xe5\xb7\xa5\xe7\xa8\x8b\xe7\x9a\x84\xe7\xbd\x91\xe9\xa1\xb5" - "\xe4\xbc\xba\xe6\x9c\x8d\xe4\xb8\xbb\xe6\x9c\xba\x20\x77\x77\x77" - "\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xe3\x80\x82\x20\x47\x4e\x55" - "\x20\xe5\xb7\xa5\xe7\xa8\x8b\x20\xe5\xbc\x80\xe5\xa7\x8b\xe6\x96" - "\xbc\xe4\xb8\x80\xe4\xb9\x9d\xe5\x85\xab\xe5\x9b\x9b\xe5\xb9\xb4" - "\xef\xbc\x8c\xe6\x97\xa8\xe5\x9c\xa8\xe5\x8f\x91\xe5\xb1\x95\xe4" - "\xb8\x80\xe4\xb8\xaa\xe7\xb1\xbb\xe4\xbc\xbc\x20\x55\x6e\x69\x78" - "\x20\xef\xbc\x8c\xe4\xb8\x94\xe4\xb8\xba\x20\xe8\x87\xaa\xe7\x94" - "\xb1\xe8\xbd\xaf\xe4\xbb\xb6\x20\xe7\x9a\x84\xe5\xae\x8c\xe6\x95" - "\xb4\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xef\xbc\x9a" - "\x20\x47\x4e\x55\x20\xe7\xb3\xbb\xe7\xbb\x9f\xe3\x80\x82\xef\xbc" - "\x88\x47\x4e\x55\x20\xe6\x98\xaf\xe7\x94\xb1\xe2\x80\x9c\x47\x4e" - "\x55\x27\x73\x20\x4e\x6f\x74\x20\x55\x6e\x69\x78\xe2\x80\x9d\xe6" - "\x89\x80\xe9\x80\x92\xe5\x9b\x9e\xe5\xae\x9a\xe4\xb9\x89\xe5\x87" - "\xba\xe7\x9a\x84\xe9\xa6\x96\xe5\xad\x97\xe6\xaf\x8d\xe7\xbc\xa9" - "\xe5\x86\x99\xe8\xaf\xad\xef\xbc\x9b\xe5\xae\x83\xe7\x9a\x84\xe5" - "\x8f\x91\xe9\x9f\xb3\xe4\xb8\xba\xe2\x80\x9c\x67\x75\x68\x2d\x4e" - "\x45\x57\xe2\x80\x9d\xef\xbc\x89\xe3\x80\x82\xe5\x90\x84\xe7\xa7" - "\x8d\xe4\xbd\xbf\xe7\x94\xa8\x20\x4c\x69\x6e\x75\x78\x20\xe4\xbd" - "\x9c\xe4\xb8\xba\xe5\x86\x85\xe6\xa0\xb8\xe7\x9a\x84\x20\x47\x4e" - "\x55\x20\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xe6\xad" - "\xa3\xe8\xa2\xab\xe5\xb9\xbf\xe6\xb3\x9b\xe5\x9c\xb0\xe4\xbd\xbf" - "\xe7\x94\xa8\xe8\x91\x97\xef\xbc\x9b\xe8\x99\xbd\xe7\x84\xb6\xe8" - "\xbf\x99\xe4\xba\x9b\xe7\xb3\xbb\xe7\xbb\x9f\xe9\x80\x9a\xe5\xb8" - "\xb8\xe8\xa2\xab\xe7\xa7\xb0\xe4\xbd\x9c\xe4\xb8\xba\xe2\x80\x9c" - "\x4c\x69\x6e\x75\x78\xe2\x80\x9d\xef\xbc\x8c\xe4\xbd\x86\xe6\x98" - "\xaf\xe5\xae\x83\xe4\xbb\xac\xe5\xba\x94\xe8\xaf\xa5\xe6\x9b\xb4" - "\xe7\xb2\xbe\xe7\xa1\xae\xe5\x9c\xb0\xe8\xa2\xab\xe7\xa7\xb0\xe4" - "\xb8\xba\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xe7\xb3\xbb" - "\xe7\xbb\x9f\x20\xe3\x80\x82\x0a"; - - - -VMIME_TEST_SUITE_BEGIN + +VMIME_TEST_SUITE_BEGIN(charsetTest) VMIME_TEST_LIST_BEGIN // Test valid input VMIME_TEST(testConvertStringValid) VMIME_TEST(testConvertStreamValid) - VMIME_TEST(testFilterValid1) - VMIME_TEST(testFilterValid2) - VMIME_TEST(testFilterValid3) VMIME_TEST(testEncodingHebrew1255) - // Test invalid input - VMIME_TEST(testFilterInvalid1) - // IDNA VMIME_TEST(testEncodeIDNA) VMIME_TEST(testDecodeIDNA) - // TODO: more tests + VMIME_TEST(testUTF7Support) VMIME_TEST_LIST_END void testConvertStringValid() { - vmime::string in(inputBytes, sizeof(inputBytes) - 1); - vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1); - vmime::string actualOut; - - vmime::charset::convert - (in, actualOut, inputCharset, outputCharset); - - VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut)); - } - - void testConvertStreamValid() - { - vmime::string in(inputBytes, sizeof(inputBytes) - 1); - vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1); - - vmime::string actualOut; - vmime::utility::outputStreamStringAdapter os(actualOut); - - vmime::utility::inputStreamStringAdapter is(in); - - vmime::charset::convert - (is, os, inputCharset, outputCharset); - - os.flush(); - - VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut)); - } - - // Using 'bufferedStreamCopy' - void testFilterValid1() - { - vmime::string in(inputBytes, sizeof(inputBytes) - 1); - vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1); - - vmime::string actualOut; - vmime::utility::outputStreamStringAdapter osa(actualOut); - - vmime::ref <vmime::charsetConverter> conv = - vmime::charsetConverter::create(inputCharset, outputCharset); - - vmime::ref <vmime::utility::charsetFilteredOutputStream> os = - conv->getFilteredOutputStream(osa); - - vmime::utility::inputStreamStringAdapter is(in); - - vmime::utility::bufferedStreamCopy(is, *os); - - os->flush(); - - VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut)); - } - - // One byte at a time - void testFilterValid2() - { - vmime::string in(inputBytes, sizeof(inputBytes) - 1); - vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1); - - vmime::string actualOut; - vmime::utility::outputStreamStringAdapter osa(actualOut); - - vmime::ref <vmime::charsetConverter> conv = - vmime::charsetConverter::create(inputCharset, outputCharset); - - vmime::ref <vmime::utility::charsetFilteredOutputStream> os = - conv->getFilteredOutputStream(osa); - - vmime::utility::inputStreamStringAdapter is(in); - - vmime::utility::stream::value_type buffer[16]; - - for (int i = 0 ; !is.eof() ; ++i) - os->write(buffer, is.read(buffer, 1)); - - os->flush(); - - VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut)); - } - - // Variable chunks - void testFilterValid3() - { - vmime::string in(inputBytes, sizeof(inputBytes) - 1); - vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1); - - vmime::string actualOut; - vmime::utility::outputStreamStringAdapter osa(actualOut); - - vmime::ref <vmime::charsetConverter> conv = - vmime::charsetConverter::create(inputCharset, outputCharset); + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) + { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; - vmime::ref <vmime::utility::charsetFilteredOutputStream> os = - conv->getFilteredOutputStream(osa); + std::ostringstream testName; + testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset; - vmime::utility::inputStreamStringAdapter is(in); + const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength); + vmime::string in(entry.fromBytes, entry.fromBytes + inLength); - vmime::utility::stream::value_type buffer[16]; + const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength); + vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength); - for (int i = 0 ; !is.eof() ; ++i) - os->write(buffer, is.read(buffer, (i % 5) + 1)); + vmime::string actualOut; - os->flush(); + vmime::charset::convert + (in, actualOut, entry.fromCharset, entry.toCharset); - VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut)); + VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut)); + } } - void testFilterInvalid1() + void testConvertStreamValid() { - vmime::string in("foo\xab\xcd\xef bar"); - vmime::string expectedOut("foo??? bar"); + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) + { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; - vmime::string actualOut; - vmime::utility::outputStreamStringAdapter osa(actualOut); + std::ostringstream testName; + testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset; - vmime::ref <vmime::charsetConverter> conv = - vmime::charsetConverter::create - (vmime::charset("utf-8"), - vmime::charset("iso-8859-1")); + const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength); + vmime::string in(entry.fromBytes, entry.fromBytes + inLength); - vmime::ref <vmime::utility::charsetFilteredOutputStream> os = - conv->getFilteredOutputStream(osa); + const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength); + vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength); - vmime::utility::inputStreamStringAdapter is(in); + vmime::string actualOut; + vmime::utility::outputStreamStringAdapter os(actualOut); - vmime::utility::stream::value_type buffer[16]; + vmime::utility::inputStreamStringAdapter is(in); - for (int i = 0 ; !is.eof() ; ++i) - os->write(buffer, is.read(buffer, 1)); + vmime::charset::convert + (is, os, entry.fromCharset, entry.toCharset); - os->flush(); + os.flush(); - VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut)); + VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut)); + } } void testEncodingHebrew1255() @@ -259,44 +105,6 @@ VMIME_TEST_SUITE_BEGIN VASSERT_EQ("1", "=?windows-1255?B?6fn3+On5+Pfp6fk=?=", encoded); } - // Conversion to hexadecimal for easier debugging - static const vmime::string toHex(const vmime::string str) - { - static const char hexChars[] = "0123456789abcdef"; - - vmime::string res = "\n"; - - for (unsigned int i = 0 ; i < str.length() ; i += 16) - { - unsigned int r = std::min - (static_cast <size_t>(16), str.length() - i); - - vmime::string hex; - vmime::string chr; - - for (unsigned int j = 0 ; j < r ; ++j) - { - const unsigned char c = str[i + j]; - - hex += hexChars[c / 16]; - hex += hexChars[c % 16]; - hex += " "; - - if (c >= 32 && c <= 127) - chr += c; - else - chr += '.'; - } - - for (unsigned int j = r ; j < 16 ; ++j) - hex += " "; - - res += hex + " " + chr + "\n"; - } - - return res; - } - static const vmime::string convertHelper (const vmime::string& in, const vmime::charset& csrc, const vmime::charset& cdest) { @@ -330,5 +138,11 @@ VMIME_TEST_SUITE_BEGIN VASSERT_EQ("3.2", "إختبار", convertHelper("xn--kgbechtv", "idna", "utf-8")); } + void testUTF7Support() + { + // Ensure UTF-7 is supported, because it is used for IMAP + VASSERT_EQ("1", "VMime +ACY UTF-7 encoding", convertHelper("VMime & UTF-7 encoding", "utf-8", "utf-7")); + } + VMIME_TEST_SUITE_END diff --git a/tests/parser/charsetTestSuites.hpp b/tests/parser/charsetTestSuites.hpp new file mode 100644 index 00000000..b12b3e37 --- /dev/null +++ b/tests/parser/charsetTestSuites.hpp @@ -0,0 +1,103 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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. +// + + +struct charsetTestSuiteStruct +{ + const char* fromCharset; + const char* toCharset; + const char* fromBytes; + const unsigned int fromLength; + const char* toBytes; + const unsigned int toLength; +}; + + +static const charsetTestSuiteStruct charsetTestSuites[] = +{ + // Test data 1 (excerpt from http://www.gnu.org) + { + "gb2312", "utf-8", + + "\xbb\xb6\xd3\xad\xc0\xb4\xb5\xbd\x20\x47\x4e\x55\x20\xb9\xa4\xb3" + "\xcc\xb5\xc4\xcd\xf8\xd2\xb3\xcb\xc5\xb7\xfe\xd6\xf7\xbb\xfa\x20" + "\x77\x77\x77\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xa1\xa3\x20\x47" + "\x4e\x55\x20\xb9\xa4\xb3\xcc\x20\xbf\xaa\xca\xbc\xec\xb6\xd2\xbb" + "\xbe\xc5\xb0\xcb\xcb\xc4\xc4\xea\xa3\xac\xd6\xbc\xd4\xda\xb7\xa2" + "\xd5\xb9\xd2\xbb\xb8\xf6\xc0\xe0\xcb\xc6\x20\x55\x6e\x69\x78\x20" + "\xa3\xac\xc7\xd2\xce\xaa\x20\xd7\xd4\xd3\xc9\xc8\xed\xbc\xfe\x20" + "\xb5\xc4\xcd\xea\xd5\xfb\xb2\xd9\xd7\xf7\xcf\xb5\xcd\xb3\xa3\xba" + "\x20\x47\x4e\x55\x20\xcf\xb5\xcd\xb3\xa1\xa3\xa3\xa8\x47\x4e\x55" + "\x20\xca\xc7\xd3\xc9\xa1\xb0\x47\x4e\x55\x27\x73\x20\x4e\x6f\x74" + "\x20\x55\x6e\x69\x78\xa1\xb1\xcb\xf9\xb5\xdd\xbb\xd8\xb6\xa8\xd2" + "\xe5\xb3\xf6\xb5\xc4\xca\xd7\xd7\xd6\xc4\xb8\xcb\xf5\xd0\xb4\xd3" + "\xef\xa3\xbb\xcb\xfc\xb5\xc4\xb7\xa2\xd2\xf4\xce\xaa\xa1\xb0\x67" + "\x75\x68\x2d\x4e\x45\x57\xa1\xb1\xa3\xa9\xa1\xa3\xb8\xf7\xd6\xd6" + "\xca\xb9\xd3\xc3\x20\x4c\x69\x6e\x75\x78\x20\xd7\xf7\xce\xaa\xc4" + "\xda\xba\xcb\xb5\xc4\x20\x47\x4e\x55\x20\xb2\xd9\xd7\xf7\xcf\xb5" + "\xcd\xb3\xd5\xfd\xb1\xbb\xb9\xe3\xb7\xba\xb5\xd8\xca\xb9\xd3\xc3" + "\xd6\xf8\xa3\xbb\xcb\xe4\xc8\xbb\xd5\xe2\xd0\xa9\xcf\xb5\xcd\xb3" + "\xcd\xa8\xb3\xa3\xb1\xbb\xb3\xc6\xd7\xf7\xce\xaa\xa1\xb0\x4c\x69" + "\x6e\x75\x78\xa1\xb1\xa3\xac\xb5\xab\xca\xc7\xcb\xfc\xc3\xc7\xd3" + "\xa6\xb8\xc3\xb8\xfc\xbe\xab\xc8\xb7\xb5\xd8\xb1\xbb\xb3\xc6\xce" + "\xaa\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xcf\xb5\xcd\xb3" + "\x20\xa1\xa3\x0a", + 0, + + "\xe6\xac\xa2\xe8\xbf\x8e\xe6\x9d\xa5\xe5\x88\xb0\x20\x47\x4e\x55" + "\x20\xe5\xb7\xa5\xe7\xa8\x8b\xe7\x9a\x84\xe7\xbd\x91\xe9\xa1\xb5" + "\xe4\xbc\xba\xe6\x9c\x8d\xe4\xb8\xbb\xe6\x9c\xba\x20\x77\x77\x77" + "\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xe3\x80\x82\x20\x47\x4e\x55" + "\x20\xe5\xb7\xa5\xe7\xa8\x8b\x20\xe5\xbc\x80\xe5\xa7\x8b\xe6\x96" + "\xbc\xe4\xb8\x80\xe4\xb9\x9d\xe5\x85\xab\xe5\x9b\x9b\xe5\xb9\xb4" + "\xef\xbc\x8c\xe6\x97\xa8\xe5\x9c\xa8\xe5\x8f\x91\xe5\xb1\x95\xe4" + "\xb8\x80\xe4\xb8\xaa\xe7\xb1\xbb\xe4\xbc\xbc\x20\x55\x6e\x69\x78" + "\x20\xef\xbc\x8c\xe4\xb8\x94\xe4\xb8\xba\x20\xe8\x87\xaa\xe7\x94" + "\xb1\xe8\xbd\xaf\xe4\xbb\xb6\x20\xe7\x9a\x84\xe5\xae\x8c\xe6\x95" + "\xb4\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xef\xbc\x9a" + "\x20\x47\x4e\x55\x20\xe7\xb3\xbb\xe7\xbb\x9f\xe3\x80\x82\xef\xbc" + "\x88\x47\x4e\x55\x20\xe6\x98\xaf\xe7\x94\xb1\xe2\x80\x9c\x47\x4e" + "\x55\x27\x73\x20\x4e\x6f\x74\x20\x55\x6e\x69\x78\xe2\x80\x9d\xe6" + "\x89\x80\xe9\x80\x92\xe5\x9b\x9e\xe5\xae\x9a\xe4\xb9\x89\xe5\x87" + "\xba\xe7\x9a\x84\xe9\xa6\x96\xe5\xad\x97\xe6\xaf\x8d\xe7\xbc\xa9" + "\xe5\x86\x99\xe8\xaf\xad\xef\xbc\x9b\xe5\xae\x83\xe7\x9a\x84\xe5" + "\x8f\x91\xe9\x9f\xb3\xe4\xb8\xba\xe2\x80\x9c\x67\x75\x68\x2d\x4e" + "\x45\x57\xe2\x80\x9d\xef\xbc\x89\xe3\x80\x82\xe5\x90\x84\xe7\xa7" + "\x8d\xe4\xbd\xbf\xe7\x94\xa8\x20\x4c\x69\x6e\x75\x78\x20\xe4\xbd" + "\x9c\xe4\xb8\xba\xe5\x86\x85\xe6\xa0\xb8\xe7\x9a\x84\x20\x47\x4e" + "\x55\x20\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xe6\xad" + "\xa3\xe8\xa2\xab\xe5\xb9\xbf\xe6\xb3\x9b\xe5\x9c\xb0\xe4\xbd\xbf" + "\xe7\x94\xa8\xe8\x91\x97\xef\xbc\x9b\xe8\x99\xbd\xe7\x84\xb6\xe8" + "\xbf\x99\xe4\xba\x9b\xe7\xb3\xbb\xe7\xbb\x9f\xe9\x80\x9a\xe5\xb8" + "\xb8\xe8\xa2\xab\xe7\xa7\xb0\xe4\xbd\x9c\xe4\xb8\xba\xe2\x80\x9c" + "\x4c\x69\x6e\x75\x78\xe2\x80\x9d\xef\xbc\x8c\xe4\xbd\x86\xe6\x98" + "\xaf\xe5\xae\x83\xe4\xbb\xac\xe5\xba\x94\xe8\xaf\xa5\xe6\x9b\xb4" + "\xe7\xb2\xbe\xe7\xa1\xae\xe5\x9c\xb0\xe8\xa2\xab\xe7\xa7\xb0\xe4" + "\xb8\xba\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xe7\xb3\xbb" + "\xe7\xbb\x9f\x20\xe3\x80\x82\x0a", + 0 + } + +}; + +static const unsigned int charsetTestSuitesCount = sizeof(charsetTestSuites) / sizeof(charsetTestSuites[0]); diff --git a/tests/parser/datetimeTest.cpp b/tests/parser/datetimeTest.cpp index 07d77301..90bbebbb 100644 --- a/tests/parser/datetimeTest.cpp +++ b/tests/parser/datetimeTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE datetimeTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(datetimeTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) diff --git a/tests/parser/dispositionTest.cpp b/tests/parser/dispositionTest.cpp index 81818dae..7b767caa 100644 --- a/tests/parser/dispositionTest.cpp +++ b/tests/parser/dispositionTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE dispositionTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(dispositionTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) diff --git a/tests/parser/emailAddressTest.cpp b/tests/parser/emailAddressTest.cpp index 0185c220..378cc065 100644 --- a/tests/parser/emailAddressTest.cpp +++ b/tests/parser/emailAddressTest.cpp @@ -26,11 +26,7 @@ #include "vmime/platform.hpp" -#define VMIME_TEST_SUITE emailAddressTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(emailAddressTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParseASCII) diff --git a/tests/parser/headerFieldTest.cpp b/tests/parser/headerFieldTest.cpp index 2c8a954c..9d8f9dfa 100644 --- a/tests/parser/headerFieldTest.cpp +++ b/tests/parser/headerFieldTest.cpp @@ -24,14 +24,11 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE headerFieldTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(headerFieldTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testBadValueType) + VMIME_TEST(testValueOnNextLine) VMIME_TEST_LIST_END @@ -53,4 +50,20 @@ VMIME_TEST_SUITE_BEGIN custom->setValue(vmime::text("field value text"))); } + void testValueOnNextLine() + { + vmime::parsingContext ctx; + + const vmime::string buffer = "Field: \r\n\tfield data"; + + vmime::ref <vmime::headerField> hfield = + vmime::headerField::parseNext(ctx, buffer, 0, buffer.size()); + + vmime::ref <vmime::text> hvalue = + hfield->getValue().dynamicCast <vmime::text>(); + + VASSERT_EQ("Field name", "Field", hfield->getName()); + VASSERT_EQ("Field value", "field data", hvalue->getWholeBuffer()); + } + VMIME_TEST_SUITE_END diff --git a/tests/parser/headerTest.cpp b/tests/parser/headerTest.cpp index 47bd0ebe..91eb03df 100644 --- a/tests/parser/headerTest.cpp +++ b/tests/parser/headerTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE headerTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(headerTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testHas1) diff --git a/tests/parser/htmlTextPartTest.cpp b/tests/parser/htmlTextPartTest.cpp index 08754e72..732fcd8c 100644 --- a/tests/parser/htmlTextPartTest.cpp +++ b/tests/parser/htmlTextPartTest.cpp @@ -25,11 +25,7 @@ #include "vmime/htmlTextPart.hpp" -#define VMIME_TEST_SUITE htmlTextPartTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParseText) diff --git a/tests/parser/mailboxGroupTest.cpp b/tests/parser/mailboxGroupTest.cpp new file mode 100644 index 00000000..49d22658 --- /dev/null +++ b/tests/parser/mailboxGroupTest.cpp @@ -0,0 +1,97 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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. +// + +#include "tests/testUtils.hpp" + + +VMIME_TEST_SUITE_BEGIN(mailboxGroupTest) + + VMIME_TEST_LIST_BEGIN + VMIME_TEST(testParseExtraWhitespaces) + VMIME_TEST(testParseNoEndDelimiter) + VMIME_TEST(testParseExtraChars) + VMIME_TEST(testEmptyGroup) + VMIME_TEST_LIST_END + + + void testParseExtraWhitespaces() + { + vmime::mailboxGroup mgrp; + mgrp.parse(" \t group : aaa <[email protected]>, bbb <[email protected]>"); + + VASSERT_EQ("name", "group", mgrp.getName().getWholeBuffer()); + VASSERT_EQ("count", 2, mgrp.getMailboxCount()); + + VASSERT_EQ("mbox1.email", "[email protected]", mgrp.getMailboxAt(0)->getEmail()); + VASSERT_EQ("mbox1.name", "aaa", mgrp.getMailboxAt(0)->getName()); + + VASSERT_EQ("mbox2.email", "[email protected]", mgrp.getMailboxAt(1)->getEmail()); + VASSERT_EQ("mbox2.name", "bbb", mgrp.getMailboxAt(1)->getName()); + } + + void testParseNoEndDelimiter() + { + vmime::addressList addrs; + addrs.parse("group: aaa <[email protected]>, bbb <[email protected]>"); + + VASSERT_EQ("count", 1, addrs.getAddressCount()); + VASSERT_TRUE("is group", addrs.getAddressAt(0)->isGroup()); + + vmime::ref <vmime::mailboxGroup> mgrp = + addrs.getAddressAt(0).dynamicCast <vmime::mailboxGroup>(); + + VASSERT_EQ("name", "group", mgrp->getName().getWholeBuffer()); + VASSERT_EQ("count", 2, mgrp->getMailboxCount()); + + VASSERT_EQ("mbox1.email", "[email protected]", mgrp->getMailboxAt(0)->getEmail()); + VASSERT_EQ("mbox1.name", "aaa", mgrp->getMailboxAt(0)->getName()); + + VASSERT_EQ("mbox2.email", "[email protected]", mgrp->getMailboxAt(1)->getEmail()); + VASSERT_EQ("mbox2.name", "bbb", mgrp->getMailboxAt(1)->getName()); + } + + void testParseExtraChars() + { + vmime::mailboxGroup mgrp; + mgrp.parse("group: aaa <[email protected]>, bbb <[email protected]>; extra chars here..."); + + VASSERT_EQ("name", "group", mgrp.getName().getWholeBuffer()); + VASSERT_EQ("count", 2, mgrp.getMailboxCount()); + + VASSERT_EQ("mbox1.email", "[email protected]", mgrp.getMailboxAt(0)->getEmail()); + VASSERT_EQ("mbox1.name", "aaa", mgrp.getMailboxAt(0)->getName()); + + VASSERT_EQ("mbox2.email", "[email protected]", mgrp.getMailboxAt(1)->getEmail()); + VASSERT_EQ("mbox2.name", "bbb", mgrp.getMailboxAt(1)->getName()); + } + + void testEmptyGroup() + { + vmime::mailboxGroup mgrp; + mgrp.parse("Undisclosed recipients:;"); + + VASSERT_EQ("name", "Undisclosed recipients", mgrp.getName().getWholeBuffer()); + VASSERT_EQ("count", 0, mgrp.getMailboxCount()); + } + +VMIME_TEST_SUITE_END diff --git a/tests/parser/mailboxTest.cpp b/tests/parser/mailboxTest.cpp index 9e48a235..e6e4a608 100644 --- a/tests/parser/mailboxTest.cpp +++ b/tests/parser/mailboxTest.cpp @@ -24,15 +24,12 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE mailboxTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(mailboxTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) VMIME_TEST(testEmptyEmailAddress) + VMIME_TEST(testSeparatorInComment) VMIME_TEST_LIST_END @@ -128,5 +125,22 @@ VMIME_TEST_SUITE_BEGIN VASSERT_EQ("email", "", mbox->getEmail()); } + void testSeparatorInComment() + { + vmime::addressList addrList; + addrList.parse("aaa(comment,comment)@vmime.org, [email protected]"); + + VASSERT_EQ("count", 2, addrList.getAddressCount()); + + vmime::ref <vmime::mailbox> mbox1 = addrList.getAddressAt(0).dynamicCast <vmime::mailbox>(); + vmime::ref <vmime::mailbox> mbox2 = addrList.getAddressAt(1).dynamicCast <vmime::mailbox>(); + + VASSERT_EQ("name1", vmime::text(), mbox1->getName()); + VASSERT_EQ("email1", "[email protected]", mbox1->getEmail()); + + VASSERT_EQ("name2", vmime::text(), mbox2->getName()); + VASSERT_EQ("email2", "[email protected]", mbox2->getEmail()); + } + VMIME_TEST_SUITE_END diff --git a/tests/parser/mediaTypeTest.cpp b/tests/parser/mediaTypeTest.cpp index 462f6ae7..4002b714 100644 --- a/tests/parser/mediaTypeTest.cpp +++ b/tests/parser/mediaTypeTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE mediaTypeTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(mediaTypeTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testConstructors) diff --git a/tests/parser/messageIdSequenceTest.cpp b/tests/parser/messageIdSequenceTest.cpp index e7dd7e01..ed6d0be3 100644 --- a/tests/parser/messageIdSequenceTest.cpp +++ b/tests/parser/messageIdSequenceTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE messageIdSequenceTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(messageIdSequenceTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) diff --git a/tests/parser/messageIdTest.cpp b/tests/parser/messageIdTest.cpp index be8be3f1..9863ae51 100644 --- a/tests/parser/messageIdTest.cpp +++ b/tests/parser/messageIdTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE messageIdTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(messageIdTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) diff --git a/tests/parser/parameterTest.cpp b/tests/parser/parameterTest.cpp index 91c5f076..3ebd6e35 100644 --- a/tests/parser/parameterTest.cpp +++ b/tests/parser/parameterTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE parameterTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(parameterTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) @@ -39,6 +35,7 @@ VMIME_TEST_SUITE_BEGIN VMIME_TEST(testParseNonSignificantWS) VMIME_TEST(testEncodeTSpecials) VMIME_TEST(testEncodeTSpecialsInRFC2231) + VMIME_TEST(testWhitespaceBreaksTheValue) VMIME_TEST_LIST_END @@ -352,5 +349,16 @@ VMIME_TEST_SUITE_BEGIN vmime::create <vmime::parameter>("filename", "my_file_name_\xc3\xb6\xc3\xa4\xc3\xbc_(1).txt")->generate()); } + void testWhitespaceBreaksTheValue() + { + parameterizedHeaderField p; + p.parse("xxx yyy; param1=value1 \r\n"); + + VASSERT_EQ("count", 1, p.getParameterCount()); + VASSERT_EQ("value", "xxx", FIELD_VALUE(p)); + VASSERT_EQ("param1.name", "param1", PARAM_NAME(p, 0)); + VASSERT_EQ("param1.value", "value1", PARAM_VALUE(p, 0)); + } + VMIME_TEST_SUITE_END diff --git a/tests/parser/pathTest.cpp b/tests/parser/pathTest.cpp index caa6e0a0..f73dd0d4 100644 --- a/tests/parser/pathTest.cpp +++ b/tests/parser/pathTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE pathTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(pathTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse) diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp index 0261a72f..f4f30b1b 100644 --- a/tests/parser/textTest.cpp +++ b/tests/parser/textTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE textTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(textTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testConstructors) diff --git a/tests/parser/wordEncoderTest.cpp b/tests/parser/wordEncoderTest.cpp index 269a01bd..9bc4dcfd 100644 --- a/tests/parser/wordEncoderTest.cpp +++ b/tests/parser/wordEncoderTest.cpp @@ -26,11 +26,7 @@ #include "vmime/wordEncoder.hpp" -#define VMIME_TEST_SUITE wordEncoderTest -#define VMIME_TEST_SUITE_MODULE "Parser" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(wordEncoderTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testGetNextChunk) diff --git a/tests/security/digest/md5Test.cpp b/tests/security/digest/md5Test.cpp index 28220693..ec4e62b2 100644 --- a/tests/security/digest/md5Test.cpp +++ b/tests/security/digest/md5Test.cpp @@ -26,17 +26,13 @@ #include "vmime/security/digest/messageDigestFactory.hpp" -#define VMIME_TEST_SUITE md5Test -#define VMIME_TEST_SUITE_MODULE "Security/Digest" - - #define INIT_DIGEST(var, algo) \ vmime::ref <vmime::security::digest::messageDigest> var = \ vmime::security::digest::messageDigestFactory::getInstance()->create(algo) -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(md5Test) VMIME_TEST_LIST_BEGIN VMIME_TEST(testRFC1321_1) diff --git a/tests/security/digest/sha1Test.cpp b/tests/security/digest/sha1Test.cpp index 5ad98e62..2accf8c7 100644 --- a/tests/security/digest/sha1Test.cpp +++ b/tests/security/digest/sha1Test.cpp @@ -26,17 +26,13 @@ #include "vmime/security/digest/messageDigestFactory.hpp" -#define VMIME_TEST_SUITE sha1Test -#define VMIME_TEST_SUITE_MODULE "Security/Digest" - - #define INIT_DIGEST(var, algo) \ vmime::ref <vmime::security::digest::messageDigest> var = \ vmime::security::digest::messageDigestFactory::getInstance()->create(algo) -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(sha1Test) VMIME_TEST_LIST_BEGIN VMIME_TEST(testFIPS180_1) diff --git a/tests/testRunner.cpp b/tests/testRunner.cpp index b6c66850..fb40d3a2 100644 --- a/tests/testRunner.cpp +++ b/tests/testRunner.cpp @@ -192,6 +192,55 @@ void registerTestModule(const char* name_) } +const std::string getNormalizedPath(const std::string& path) +{ + std::string res = path; + + for (std::string::size_type i = 0, n = res.length() ; i < n ; ++i) + { + if (res[i] == '\\') + res[i] = '/'; + } + + return res; +} + + +const std::string getFileNameFromPath(const std::string& path) +{ + const std::string::size_type pos = path.find_last_of('/'); + + if (pos == std::string::npos) + return ""; + + return path.substr(pos + 1); +} + + +const char* getTestModuleNameFromSourceFile(const char *path_) +{ + static std::string moduleName; + + static const std::string testRunnerPath(getNormalizedPath(__FILE__)); + static const std::string testRunnerFileName(getFileNameFromPath(testRunnerPath)); + + const std::string path = getNormalizedPath(path_); + + // "/path/to/testRunner.cpp" --> "/path/to/" + const std::string basePath + (testRunnerPath.begin(), testRunnerPath.end() - testRunnerFileName.length()); + + // "/path/to/module/testFile.cpp" --> "module/testFile.cpp" + const std::string testFileName(getFileNameFromPath(path)); + const std::string testPath(path.begin() + basePath.length(), path.end()); + + // "module/testFile.cpp" --> "module" + moduleName = testPath.substr(0, testPath.length() - testFileName.length() - 1); + + return moduleName.c_str(); +} + + int main(int argc, char* argv[]) { // VMime initialization diff --git a/tests/testUtils.cpp b/tests/testUtils.cpp index 56117e07..d008ed94 100644 --- a/tests/testUtils.cpp +++ b/tests/testUtils.cpp @@ -270,3 +270,39 @@ std::ostream& operator<<(std::ostream& os, const vmime::exception& e) } +const vmime::string toHex(const vmime::string str) +{ + static const char hexChars[] = "0123456789abcdef"; + + vmime::string res = "\n"; + + for (unsigned int i = 0 ; i < str.length() ; i += 16) + { + unsigned int r = std::min + (static_cast <size_t>(16), str.length() - i); + + vmime::string hex; + vmime::string chr; + + for (unsigned int j = 0 ; j < r ; ++j) + { + const unsigned char c = str[i + j]; + + hex += hexChars[c / 16]; + hex += hexChars[c % 16]; + hex += " "; + + if (c >= 32 && c <= 127) + chr += c; + else + chr += '.'; + } + + for (unsigned int j = r ; j < 16 ; ++j) + hex += " "; + + res += hex + " " + chr + "\n"; + } + + return res; +} diff --git a/tests/testUtils.hpp b/tests/testUtils.hpp index 39d9e555..4fa6b457 100644 --- a/tests/testUtils.hpp +++ b/tests/testUtils.hpp @@ -33,8 +33,10 @@ // CppUnit +#pragma GCC diagnostic ignored "-Wold-style-cast" #include <cppunit/TestAssert.h> #include <cppunit/extensions/HelperMacros.h> +#pragma GCC diagnostic warning "-Wold-style-cast" #define VASSERT(msg, cond) \ CPPUNIT_ASSERT_MESSAGE(std::string(msg), cond) @@ -57,18 +59,24 @@ #define VASSERT_NO_THROW(msg, expression) \ CPPUNIT_ASSERT_NO_THROW(expression) -#define VMIME_TEST_SUITE_BEGIN \ - class VMIME_TEST_SUITE : public CppUnit::TestFixture { public: +#define VMIME_TEST_SUITE_BEGIN(testSuiteName) \ + class testSuiteName; \ + typedef testSuiteName VMIME_TEST_SUITE; \ + class testSuiteName : public CppUnit::TestFixture { public: #define VMIME_TEST_SUITE_END \ }; \ \ - static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry1); \ - static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry2)(VMIME_TEST_SUITE_MODULE); \ + /*static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry1);*/ \ + /*static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry2)(VMIME_TEST_SUITE_MODULE);*/ \ extern void registerTestModule(const char* name); \ + extern const char* getTestModuleNameFromSourceFile(const char *path); \ template <typename T> \ struct AutoRegisterModule { \ AutoRegisterModule() { \ - registerTestModule(VMIME_TEST_SUITE_MODULE); \ + static const char* moduleName = getTestModuleNameFromSourceFile(__FILE__); \ + static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry1); \ + static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry2)(moduleName); \ + registerTestModule(moduleName); \ } \ }; \ static AutoRegisterModule <VMIME_TEST_SUITE> autoRegisterModule; @@ -340,3 +348,6 @@ public: // Exception helper std::ostream& operator<<(std::ostream& os, const vmime::exception& e); + +// Conversion to hexadecimal for easier debugging +const vmime::string toHex(const vmime::string str); diff --git a/tests/utility/datetimeUtilsTest.cpp b/tests/utility/datetimeUtilsTest.cpp index 608a0521..1e21c5f9 100644 --- a/tests/utility/datetimeUtilsTest.cpp +++ b/tests/utility/datetimeUtilsTest.cpp @@ -27,11 +27,7 @@ #include "vmime/utility/datetimeUtils.hpp" -#define VMIME_TEST_SUITE datetimeUtilsTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testIsLeapYear) diff --git a/tests/utility/encoder/b64EncoderTest.cpp b/tests/utility/encoder/b64EncoderTest.cpp new file mode 100644 index 00000000..589afaba --- /dev/null +++ b/tests/utility/encoder/b64EncoderTest.cpp @@ -0,0 +1,145 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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. +// + +#include "tests/testUtils.hpp" + +#include "encoderTestUtils.hpp" + + +VMIME_TEST_SUITE_BEGIN(b64EncoderTest) + + VMIME_TEST_LIST_BEGIN + VMIME_TEST(testBase64) + VMIME_TEST_LIST_END + + + void testBase64() + { + static const vmime::string testSuites[] = + { + // Test 1 + "", + + "", + + // Test 2 + "A", + + "QQ==", + + // Test 3 + "AB", + + "QUI=", + + // Test 4 + "ABC", + + "QUJD", + + // Test 5 + "foo", + + "Zm9v", + + // Test 6 + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx" + "MjM0NTY3ODk=", + + // Test 7 + vmime::string( + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" + "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" + "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" + "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + 256), + + "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1" + "Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr" + "bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Ch" + "oqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX" + "2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" + }; + + + for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i) + { + const vmime::string decoded = testSuites[i * 2]; + const vmime::string encoded = testSuites[i * 2 + 1]; + + std::ostringstream oss; + oss << "[Base64] Test " << (i + 1) << ": "; + + // Encoding + VASSERT_EQ(oss.str() + "encoding", encoded, encode("base64", decoded)); + + // Decoding + VASSERT_EQ(oss.str() + "decoding", decoded, decode("base64", encoded)); + + // Multiple and successive encoding/decoding + VASSERT_EQ(oss.str() + "multiple1", decoded, + decode("base64", + encode("base64", decoded))); + + VASSERT_EQ(oss.str() + "multiple2", decoded, + decode("base64", + decode("base64", + encode("base64", + encode("base64", decoded))))); + + VASSERT_EQ(oss.str() + "multiple3", decoded, + decode("base64", + decode("base64", + decode("base64", + encode("base64", + encode("base64", + encode("base64", decoded))))))); + + VASSERT_EQ(oss.str() + "multiple4", decoded, + decode("base64", + decode("base64", + decode("base64", + decode("base64", + encode("base64", + encode("base64", + encode("base64", + encode("base64", decoded))))))))); + } + } + +VMIME_TEST_SUITE_END + diff --git a/tests/utility/encoder/encoderTestUtils.hpp b/tests/utility/encoder/encoderTestUtils.hpp new file mode 100644 index 00000000..dd2484ed --- /dev/null +++ b/tests/utility/encoder/encoderTestUtils.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 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. +// + + +// Encoding helper function +static const vmime::string encode(const vmime::string& name, const vmime::string& in, + int maxLineLength = 0, const vmime::propertySet props = vmime::propertySet()) +{ + vmime::ref <vmime::utility::encoder::encoder> enc = + vmime::utility::encoder::encoderFactory::getInstance()->create(name); + + enc->getProperties() = props; + + if (maxLineLength != 0) + enc->getProperties()["maxlinelength"] = maxLineLength; + + vmime::utility::inputStreamStringAdapter vin(in); + + std::ostringstream out; + vmime::utility::outputStreamAdapter vout(out); + + enc->encode(vin, vout); + + return (out.str()); +} + + +// Decoding helper function +static const vmime::string decode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0) +{ + vmime::ref <vmime::utility::encoder::encoder> enc = + vmime::utility::encoder::encoderFactory::getInstance()->create(name); + + if (maxLineLength != 0) + enc->getProperties()["maxlinelength"] = maxLineLength; + + vmime::utility::inputStreamStringAdapter vin(in); + + std::ostringstream out; + vmime::utility::outputStreamAdapter vout(out); + + enc->decode(vin, vout); + + return (out.str()); +} diff --git a/tests/utility/encoderTest.cpp b/tests/utility/encoder/qpEncoderTest.cpp index 24aba8ea..790c5fb3 100644 --- a/tests/utility/encoderTest.cpp +++ b/tests/utility/encoder/qpEncoderTest.cpp @@ -23,15 +23,12 @@ #include "tests/testUtils.hpp" +#include "encoderTestUtils.hpp" -#define VMIME_TEST_SUITE encoderTest -#define VMIME_TEST_SUITE_MODULE "Parser" - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(qpEncoderTest) VMIME_TEST_LIST_BEGIN - VMIME_TEST(testBase64) VMIME_TEST(testQuotedPrintable) VMIME_TEST(testQuotedPrintable_SoftLineBreaks) VMIME_TEST(testQuotedPrintable_CRLF) @@ -39,156 +36,6 @@ VMIME_TEST_SUITE_BEGIN VMIME_TEST_LIST_END - // Encoding helper function - static const vmime::string encode(const vmime::string& name, const vmime::string& in, - int maxLineLength = 0, const vmime::propertySet props = vmime::propertySet()) - { - vmime::ref <vmime::utility::encoder::encoder> enc = - vmime::utility::encoder::encoderFactory::getInstance()->create(name); - - enc->getProperties() = props; - - if (maxLineLength != 0) - enc->getProperties()["maxlinelength"] = maxLineLength; - - vmime::utility::inputStreamStringAdapter vin(in); - - std::ostringstream out; - vmime::utility::outputStreamAdapter vout(out); - - enc->encode(vin, vout); - - return (out.str()); - } - - // Decoding helper function - static const vmime::string decode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0) - { - vmime::ref <vmime::utility::encoder::encoder> enc = - vmime::utility::encoder::encoderFactory::getInstance()->create(name); - - if (maxLineLength != 0) - enc->getProperties()["maxlinelength"] = maxLineLength; - - vmime::utility::inputStreamStringAdapter vin(in); - - std::ostringstream out; - vmime::utility::outputStreamAdapter vout(out); - - enc->decode(vin, vout); - - return (out.str()); - } - - - void testBase64() - { - static const vmime::string testSuites[] = - { - // Test 1 - "", - - "", - - // Test 2 - "A", - - "QQ==", - - // Test 3 - "AB", - - "QUI=", - - // Test 4 - "ABC", - - "QUJD", - - // Test 5 - "foo", - - "Zm9v", - - // Test 6 - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - - "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx" - "MjM0NTY3ODk=", - - // Test 7 - vmime::string( - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" - "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" - "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" - "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" - "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" - "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" - "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" - "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", - 256), - - "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1" - "Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr" - "bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Ch" - "oqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX" - "2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" - }; - - - for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i) - { - const vmime::string decoded = testSuites[i * 2]; - const vmime::string encoded = testSuites[i * 2 + 1]; - - std::ostringstream oss; - oss << "[Base64] Test " << (i + 1) << ": "; - - // Encoding - VASSERT_EQ(oss.str() + "encoding", encoded, encode("base64", decoded)); - - // Decoding - VASSERT_EQ(oss.str() + "decoding", decoded, decode("base64", encoded)); - - // Multiple and successive encoding/decoding - VASSERT_EQ(oss.str() + "multiple1", decoded, - decode("base64", - encode("base64", decoded))); - - VASSERT_EQ(oss.str() + "multiple2", decoded, - decode("base64", - decode("base64", - encode("base64", - encode("base64", decoded))))); - - VASSERT_EQ(oss.str() + "multiple3", decoded, - decode("base64", - decode("base64", - decode("base64", - encode("base64", - encode("base64", - encode("base64", decoded))))))); - - VASSERT_EQ(oss.str() + "multiple4", decoded, - decode("base64", - decode("base64", - decode("base64", - decode("base64", - encode("base64", - encode("base64", - encode("base64", - encode("base64", decoded))))))))); - } - } - void testQuotedPrintable() { static const vmime::string testSuites[] = @@ -353,4 +200,3 @@ VMIME_TEST_SUITE_BEGIN // TODO: UUEncode VMIME_TEST_SUITE_END - diff --git a/tests/utility/filteredStreamTest.cpp b/tests/utility/filteredStreamTest.cpp index 8dc4d182..4a869c6e 100644 --- a/tests/utility/filteredStreamTest.cpp +++ b/tests/utility/filteredStreamTest.cpp @@ -26,11 +26,7 @@ #include "vmime/utility/filteredStream.hpp" -#define VMIME_TEST_SUITE filteredStreamTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(filteredStreamTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testDotFilteredInputStream) diff --git a/tests/utility/outputStreamByteArrayAdapterTest.cpp b/tests/utility/outputStreamByteArrayAdapterTest.cpp index e1f6810f..93e49fa1 100644 --- a/tests/utility/outputStreamByteArrayAdapterTest.cpp +++ b/tests/utility/outputStreamByteArrayAdapterTest.cpp @@ -26,11 +26,7 @@ #include "vmime/utility/outputStreamByteArrayAdapter.hpp" -#define VMIME_TEST_SUITE outputStreamByteArrayAdapterTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(outputStreamByteArrayAdapterTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testWrite) diff --git a/tests/utility/outputStreamSocketAdapterTest.cpp b/tests/utility/outputStreamSocketAdapterTest.cpp index ab8ec841..920c7f47 100644 --- a/tests/utility/outputStreamSocketAdapterTest.cpp +++ b/tests/utility/outputStreamSocketAdapterTest.cpp @@ -26,11 +26,7 @@ #include "vmime/utility/outputStreamSocketAdapter.hpp" -#define VMIME_TEST_SUITE outputStreamSocketAdapterTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(outputStreamSocketAdapterTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testWrite) diff --git a/tests/utility/outputStreamStringAdapterTest.cpp b/tests/utility/outputStreamStringAdapterTest.cpp index 9c2e516e..71ab9b38 100644 --- a/tests/utility/outputStreamStringAdapterTest.cpp +++ b/tests/utility/outputStreamStringAdapterTest.cpp @@ -26,11 +26,7 @@ #include "vmime/utility/outputStreamStringAdapter.hpp" -#define VMIME_TEST_SUITE outputStreamStringAdapterTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(outputStreamStringAdapterTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testWrite) diff --git a/tests/utility/pathTest.cpp b/tests/utility/pathTest.cpp index 6b923076..93215586 100644 --- a/tests/utility/pathTest.cpp +++ b/tests/utility/pathTest.cpp @@ -26,11 +26,7 @@ #include "vmime/utility/path.hpp" -#define VMIME_TEST_SUITE pathTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(pathTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testConstruct1) diff --git a/tests/utility/seekableInputStreamRegionAdapterTest.cpp b/tests/utility/seekableInputStreamRegionAdapterTest.cpp index 5cffbb68..3ed024e8 100644 --- a/tests/utility/seekableInputStreamRegionAdapterTest.cpp +++ b/tests/utility/seekableInputStreamRegionAdapterTest.cpp @@ -27,14 +27,10 @@ #include "vmime/utility/seekableInputStreamRegionAdapter.hpp" -#define VMIME_TEST_SUITE seekableInputStreamRegionAdapterTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - using namespace vmime::utility; -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testInitialPosition) diff --git a/tests/utility/smartPtrTest.cpp b/tests/utility/smartPtrTest.cpp index ceaf57e1..584adf3b 100644 --- a/tests/utility/smartPtrTest.cpp +++ b/tests/utility/smartPtrTest.cpp @@ -26,11 +26,7 @@ #include "vmime/utility/smartPtr.hpp" -#define VMIME_TEST_SUITE smartPtrTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(smartPtrTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testNull) diff --git a/tests/utility/stringProxyTest.cpp b/tests/utility/stringProxyTest.cpp index 0dd5ef73..0d888f6a 100644 --- a/tests/utility/stringProxyTest.cpp +++ b/tests/utility/stringProxyTest.cpp @@ -24,11 +24,7 @@ #include "tests/testUtils.hpp" -#define VMIME_TEST_SUITE stringProxyTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(stringProxyTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testConstruct) diff --git a/tests/utility/stringUtilsTest.cpp b/tests/utility/stringUtilsTest.cpp index d0ba187c..efd623db 100644 --- a/tests/utility/stringUtilsTest.cpp +++ b/tests/utility/stringUtilsTest.cpp @@ -26,11 +26,7 @@ #include "vmime/utility/stringUtils.hpp" -#define VMIME_TEST_SUITE stringUtilsTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testIsStringEqualNoCase1) diff --git a/tests/utility/urlTest.cpp b/tests/utility/urlTest.cpp index 524057da..6703ecd3 100644 --- a/tests/utility/urlTest.cpp +++ b/tests/utility/urlTest.cpp @@ -27,11 +27,7 @@ #include "vmime/utility/urlUtils.hpp" -#define VMIME_TEST_SUITE urlTest -#define VMIME_TEST_SUITE_MODULE "Utility" - - -VMIME_TEST_SUITE_BEGIN +VMIME_TEST_SUITE_BEGIN(urlTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testParse1) diff --git a/vmime/address.hpp b/vmime/address.hpp index 0faf876f..c6cd6dc6 100644 --- a/vmime/address.hpp +++ b/vmime/address.hpp @@ -70,12 +70,14 @@ public: * @param position position in the input buffer * @param end end position in the input buffer * @param newPosition will receive the new position in the input buffer + * @param isLastAddressOfGroup will be set to true if this is the last address + * of a group (end delimiter was found), or false otherwise (may be set to NULL) * @return a new address object, or null if no more address is available in the input buffer */ static ref <address> parseNext (const parsingContext& ctx, const string& buffer, const string::size_type position, const string::size_type end, - string::size_type* newPosition); + string::size_type* newPosition, bool *isLastAddressOfGroup); }; diff --git a/vmime/context.hpp b/vmime/context.hpp index 76cc0ee4..c369fb92 100644 --- a/vmime/context.hpp +++ b/vmime/context.hpp @@ -109,7 +109,7 @@ protected: context(const context& ctx); virtual context& operator=(const context& ctx); - virtual void copyFrom(const context& ctx); + void copyFrom(const context& ctx); bool m_internationalizedEmail; charsetConverterOptions m_charsetConvOptions; diff --git a/vmime/headerField.hpp b/vmime/headerField.hpp index 72d639c9..a6e80e32 100644 --- a/vmime/headerField.hpp +++ b/vmime/headerField.hpp @@ -124,6 +124,23 @@ public: void setValue(const string& value); + /** Parse a header field from a buffer. + * + * @param ctx parsing context + * @param buffer input buffer + * @param position current position in the input buffer + * @param end end position in the input buffer + * @param newPosition will receive the new position in the input buffer + * @return parsed header field, or NULL if no more header field can be parsed + * in the input buffer + */ + static ref <headerField> parseNext + (const parsingContext& ctx, + const string& buffer, + const string::size_type position, + const string::size_type end, + string::size_type* newPosition = NULL); + protected: void parseImpl @@ -140,14 +157,6 @@ protected: string::size_type* newLinePos = NULL) const; - static ref <headerField> parseNext - (const parsingContext& ctx, - const string& buffer, - const string::size_type position, - const string::size_type end, - string::size_type* newPosition = NULL); - - string m_name; ref <headerFieldValue> m_value; }; diff --git a/vmime/net/smtp/SMTPCommandSet.hpp b/vmime/net/smtp/SMTPCommandSet.hpp index 5b52ba0a..f97c4b2a 100644 --- a/vmime/net/smtp/SMTPCommandSet.hpp +++ b/vmime/net/smtp/SMTPCommandSet.hpp @@ -70,7 +70,7 @@ public: * @return true if all commands have been sent, * or false otherwise */ - const bool isFinished() const; + bool isFinished() const; /** Returns the last command which has been sent. * |