CMakeLists.txt cmake/modules COPYING src/CMakeLists.txt src/uricode.h src/uriencode.cpp src/uriencode.h src/utils.cpp tests/conversiontest.cpp tests/conversiontest.h
Christian Mollekopf
mollekopf at kolabsys.com
Tue Jul 17 12:05:46 CEST 2012
CMakeLists.txt | 1
COPYING | 1
cmake/modules/FindLibkolabxmlDependencies.cmake | 9 +
src/CMakeLists.txt | 4
src/uricode.h | 124 ------------------------
src/uriencode.cpp | 46 ++++++++
src/uriencode.h | 29 +++++
src/utils.cpp | 6 -
tests/conversiontest.cpp | 23 +++-
tests/conversiontest.h | 1
10 files changed, 107 insertions(+), 137 deletions(-)
New commits:
commit dacb5c4bb756794788e75288e0d765f437d5d264
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Tue Jul 17 12:05:19 2012 +0200
Replaced non-free uri encoding code with libcurl.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 495d1f2..76add63 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -173,6 +173,7 @@ include_directories(
${Boost_INCLUDE_DIRS}
${XSDCXX_INCLUDE_DIRS}
${XERCES_C_INCLUDE_DIRS}
+ ${CURL_INCLUDE_DIRS}
)
diff --git a/COPYING b/COPYING
index 8f75ae9..724d8fe 100644
--- a/COPYING
+++ b/COPYING
@@ -2,5 +2,4 @@ schemas/*: Apache v2 (see http://www.calconnect.org/artifacts/ical-art.shtml)
compiled/xsdbin.cxx: not copyrighted - public domain
compiled/grammar-input-stream.*: not copyrighted - public domain
src/base64.*: Copyright (C) 2004-2008 René Nyffenegger
-src/uricode.h: Copyright (C) Jin Qing
everything else: LGPLv3 or later
\ No newline at end of file
diff --git a/cmake/modules/FindLibkolabxmlDependencies.cmake b/cmake/modules/FindLibkolabxmlDependencies.cmake
index 84c2de6..66eefd6 100644
--- a/cmake/modules/FindLibkolabxmlDependencies.cmake
+++ b/cmake/modules/FindLibkolabxmlDependencies.cmake
@@ -30,6 +30,13 @@ endif()
find_package_handle_standard_args(Xerces DEFAULT_MSG
XERCES_C XERCES_C_INCLUDE_DIRS)
+find_library(CURL NAMES curl)
+if (CURL)
+ find_path(CURL_INCLUDE_DIRS NAMES curl/curl.h)
+endif()
+find_package_handle_standard_args(Curl DEFAULT_MSG
+ CURL CURL_INCLUDE_DIRS)
+
find_program(SWIG swig /usr/bin/)
if(SWIG)
set(SWIG_FOUND ON)
@@ -44,4 +51,4 @@ endif()
#abort if any of the requireds are missing
find_package_handle_standard_args(LibkolabxmlDependencies DEFAULT_MSG
- UUID_LIBRARY_FOUND XSDCXX XERCES_C)
+ UUID_LIBRARY_FOUND XSDCXX XERCES_C CURL)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index dfb2721..94a3de0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,13 +15,13 @@ add_library(kolabxml SHARED
containers/kolabcontact.cpp
containers/kolabconfiguration.cpp
containers/kolabfreebusy.cpp
- utils.cpp base64.cpp
+ utils.cpp base64.cpp uriencode.cpp
../compiled/XMLParserWrapper.cpp
../compiled/grammar-input-stream.cxx
${SCHEMA_SOURCEFILES}
)
add_dependencies(kolabxml generate_bindings)
-target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES} ${UUID})
+target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES} ${UUID} ${CURL})
# For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.42)
diff --git a/src/uricode.h b/src/uricode.h
deleted file mode 100644
index 86c5f8d..0000000
--- a/src/uricode.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// Uri encode and decode.
-// RFC1630, RFC1738, RFC2396
-//
-// Copyright 2006 Jin Qing
-
-#include <string>
-#include <assert.h>
-
-const char HEX2DEC[256] =
-{
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1,
-
- /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-
- /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-
- /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
- /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
-};
-
-std::string UriDecode(const std::string & sSrc)
-{
- // Note from RFC1630: "Sequences which start with a percent sign
- // but are not followed by two hexadecimal characters (0-9, A-F) are reserved
- // for future extension"
-
- const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
- const std::string::size_type SRC_LEN = sSrc.length();
- const unsigned char * const SRC_END = pSrc + SRC_LEN;
- const unsigned char * const SRC_LAST_DEC = SRC_END - 2; // last decodable '%'
-
- char * const pStart = new char[SRC_LEN];
- char * pEnd = pStart;
-
- while (pSrc < SRC_LAST_DEC)
- {
- if (*pSrc == '%')
- {
- char dec1, dec2;
- if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)])
- && -1 != (dec2 = HEX2DEC[*(pSrc + 2)]))
- {
- *pEnd++ = static_cast<char>((dec1 << 4) + dec2);
- pSrc += 3;
- continue;
- }
- }
-
- *pEnd++ = *pSrc++;
- }
-
- // the last 2- chars
- while (pSrc < SRC_END)
- *pEnd++ = *pSrc++;
-
- std::string sResult(pStart, pEnd);
- delete [] pStart;
- return sResult;
-}
-
-// Only alphanum is safe.
-const char SAFE[256] =
-{
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,
-
- /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
- /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
- /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
- /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0,
-
- /* 8 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* 9 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* A */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* B */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
-
- /* C */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* D */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* E */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
- /* F */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
-};
-
-std::string UriEncode(const std::string & sSrc)
-{
- const char DEC2HEX[16 + 1] = "0123456789ABCDEF";
- const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
- const std::string::size_type SRC_LEN = sSrc.length();
- unsigned char * const pStart = new unsigned char[SRC_LEN * 3];
- unsigned char * pEnd = pStart;
- const unsigned char * const SRC_END = pSrc + SRC_LEN;
-
- for (; pSrc < SRC_END; ++pSrc)
- {
- if (SAFE[*pSrc])
- *pEnd++ = *pSrc;
- else
- {
- // escape this char
- *pEnd++ = '%';
- *pEnd++ = DEC2HEX[*pSrc >> 4];
- *pEnd++ = DEC2HEX[*pSrc & 0x0F];
- }
- }
-
- std::string sResult((char *)pStart, (char *)pEnd);
- delete [] pStart;
- return sResult;
-}
-
diff --git a/src/uriencode.cpp b/src/uriencode.cpp
new file mode 100644
index 0000000..363f98e
--- /dev/null
+++ b/src/uriencode.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <curl/curl.h>
+#include <string>
+
+std::string uriEncode(const std::string &s)
+{
+ CURL *easyhandle = curl_easy_init();
+ const char *result = curl_easy_escape(easyhandle, s.c_str(), s.length());
+ curl_easy_cleanup(easyhandle);
+ if (!result) {
+ return std::string();
+ }
+ const std::string r(result);
+ curl_free(result);
+ return r;
+}
+
+std::string uriDecode(const std::string &s)
+{
+ CURL *easyhandle = curl_easy_init();
+ int length = 0;
+ const char *result = curl_easy_unescape(easyhandle, s.c_str(), s.length(), &length);
+ curl_easy_cleanup(easyhandle);
+ if (!length) {
+ return std::string();
+ }
+ const std::string r(result, length);
+ curl_free(result);
+ return r;
+}
diff --git a/src/uriencode.h b/src/uriencode.h
new file mode 100644
index 0000000..c704351
--- /dev/null
+++ b/src/uriencode.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef URIENCODE_H
+#define URIENCODE_H
+
+#include <string>
+
+/**
+ * Url encoding according to RFC 3986 (used for mailto encoding)
+ */
+std::string uriEncode(const std::string &s);
+std::string uriDecode(const std::string &s);
+
+#endif
\ No newline at end of file
diff --git a/src/utils.cpp b/src/utils.cpp
index 5e0bcb0..db0e254 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -33,7 +33,7 @@
#include <boost/thread.hpp>
#include <time.h>
#include "base64.h"
-#include "uricode.h"
+#include "uriencode.h"
#include "libkolabxml-version.h"
namespace Kolab {
@@ -251,12 +251,12 @@ std::string toMailto(const std::string &email, const std::string &name)
mailto.append("<");
mailto.append(email);
mailto.append(">");
- return std::string("mailto:")+UriEncode(mailto);
+ return std::string("mailto:")+uriEncode(mailto);
}
std::string fromMailto(const std::string &mailtoUri, std::string &name)
{
- const std::string &decoded = UriDecode(mailtoUri);
+ const std::string &decoded = uriDecode(mailtoUri);
if (decoded.substr(0, 7).compare("mailto:")) {
WARNING("no mailto address");
std::cout << decoded << std::endl;
diff --git a/tests/conversiontest.cpp b/tests/conversiontest.cpp
index 7144fb4..8ead31d 100644
--- a/tests/conversiontest.cpp
+++ b/tests/conversiontest.cpp
@@ -174,10 +174,10 @@ void ConversionTest::mailtoUriEncodingTest_data()
{
QTest::addColumn<QString>("email");
QTest::addColumn<QString>("name");
- QTest::addColumn<QString>("result");
QTest::addColumn<QString>("resultEncoded");
-
- QTest::newRow("1") << "email_1 at email.com" << "John Doe" << "mailto:John Doe<email_1 at email.com>" << "mailto:John%20Doe%3Cemail%5F1%40email%2Ecom%3E";
+ QTest::newRow("1") << "email_1 at email.com" << "John Doe" << "mailto:John%20Doe%3Cemail_1%40email.com%3E";
+ QTest::newRow("Reserved characters") << "!*'();:@&=+$,/?#[]@email.com" << "John Doe" << "mailto:John%20Doe%3C%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D%40email.com%3E";
+ QTest::newRow("Unreserved characters") << "Aa0-_.~@email.com" << "John Doe" << "mailto:John%20Doe%3CAa0-_.~%40email.com%3E";
Kolab::Utils::clearErrors();
}
@@ -186,18 +186,29 @@ void ConversionTest::mailtoUriEncodingTest()
{
QFETCH(QString, email);
QFETCH(QString, name);
- QFETCH(QString, result);
QFETCH(QString, resultEncoded);
const std::string &mailto = Kolab::XCARD::toMailto(email.toStdString(), name.toStdString());
- std::cout << mailto << std::endl;
+// std::cout << mailto << std::endl;
QCOMPARE(QString::fromStdString(mailto), resultEncoded);
std::string n;
- const std::string &e = Kolab::XCARD::fromMailto(mailto, n);
+ const std::string &e = Kolab::XCARD::fromMailto(resultEncoded.toStdString(), n);
QCOMPARE(QString::fromStdString(n), name);
QCOMPARE(QString::fromStdString(e), email);
}
+void ConversionTest::mailtoUriDecodingTest()
+{
+ QString name("John Doe");
+ QString email("email_1 at email.com");
+ //While we shouldn't encode '_' and '.' according to RFC 3986, we should still understand it for backwards compatiblity
+ const std::string resultEncoded = "mailto:John%20Doe%3Cemail%5F1%40email%2Ecom%3E";
+ std::string n;
+ const std::string &e = Kolab::XCARD::fromMailto(resultEncoded, n);
+ QCOMPARE(QString::fromStdString(n), name);
+ QCOMPARE(QString::fromStdString(e), email);
+}
+
void ConversionTest::urnTest()
{
QCOMPARE(Kolab::Shared::toURN("1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"));
diff --git a/tests/conversiontest.h b/tests/conversiontest.h
index 7ccd110..1ae4094 100644
--- a/tests/conversiontest.h
+++ b/tests/conversiontest.h
@@ -32,6 +32,7 @@ class ConversionTest : public QObject
void mailtoUriEncodingTest_data();
void mailtoUriEncodingTest();
+ void mailtoUriDecodingTest();
void urnTest();
More information about the commits
mailing list