ferencd@0: // ferencd@0: // VMime library (http://www.vmime.org) ferencd@0: // Copyright (C) 2002-2013 Vincent Richard ferencd@0: // ferencd@0: // This program is free software; you can redistribute it and/or ferencd@0: // modify it under the terms of the GNU General Public License as ferencd@0: // published by the Free Software Foundation; either version 3 of ferencd@0: // the License, or (at your option) any later version. ferencd@0: // ferencd@0: // This program is distributed in the hope that it will be useful, ferencd@0: // but WITHOUT ANY WARRANTY; without even the implied warranty of ferencd@0: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ferencd@0: // General Public License for more details. ferencd@0: // ferencd@0: // You should have received a copy of the GNU General Public License along ferencd@0: // with this program; if not, write to the Free Software Foundation, Inc., ferencd@0: // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ferencd@0: // ferencd@0: // Linking this library statically or dynamically with other modules is making ferencd@0: // a combined work based on this library. Thus, the terms and conditions of ferencd@0: // the GNU General Public License cover the whole combination. ferencd@0: // ferencd@0: ferencd@0: #include "tests/testUtils.hpp" ferencd@0: ferencd@0: #include "vmime/utility/url.hpp" ferencd@0: #include "vmime/utility/urlUtils.hpp" ferencd@0: ferencd@0: ferencd@0: VMIME_TEST_SUITE_BEGIN(urlTest) ferencd@0: ferencd@0: VMIME_TEST_LIST_BEGIN ferencd@0: VMIME_TEST(testParse1) ferencd@0: VMIME_TEST(testParse2) ferencd@0: VMIME_TEST(testParse3) ferencd@0: VMIME_TEST(testParse4) ferencd@0: VMIME_TEST(testParse5) ferencd@0: VMIME_TEST(testGenerate) ferencd@0: VMIME_TEST(testUtilsEncode) ferencd@0: VMIME_TEST(testUtilsDecode) ferencd@0: VMIME_TEST(testUtilsDecodeSpecialCases) ferencd@0: VMIME_TEST(testUtilsEncodeReservedChars) ferencd@0: VMIME_TEST(testUtilsEncodeUnsafeChars) ferencd@0: VMIME_TEST_LIST_END ferencd@0: ferencd@0: ferencd@0: static bool parseHelper(vmime::utility::url& u, const vmime::string& str) ferencd@0: { ferencd@0: try ferencd@0: { ferencd@0: u = vmime::utility::url(str); ferencd@0: } ferencd@0: catch (vmime::exceptions::malformed_url) ferencd@0: { ferencd@0: return false; ferencd@0: } ferencd@0: ferencd@0: return true; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testParse1() ferencd@0: { ferencd@0: // Test some valid constructions ferencd@0: vmime::utility::url u1("", ""); ferencd@0: ferencd@0: VASSERT_EQ("1.1", true, parseHelper(u1, "protocol://user:password@host:12345/path/")); ferencd@0: VASSERT_EQ("1.2", "protocol", u1.getProtocol()); ferencd@0: VASSERT_EQ("1.3", "user", u1.getUsername()); ferencd@0: VASSERT_EQ("1.4", "password", u1.getPassword()); ferencd@0: VASSERT_EQ("1.5", "host", u1.getHost()); ferencd@0: VASSERT_EQ("1.6", 12345, u1.getPort()); ferencd@0: VASSERT_EQ("1.7", "/path/", u1.getPath()); ferencd@0: ferencd@0: vmime::utility::url u2("", ""); ferencd@0: ferencd@0: VASSERT_EQ("2.1", true, parseHelper(u2, "protocol://user@host:12345/path/")); ferencd@0: VASSERT_EQ("2.2", "protocol", u2.getProtocol()); ferencd@0: VASSERT_EQ("2.3", "user", u2.getUsername()); ferencd@0: VASSERT_EQ("2.4", "", u2.getPassword()); ferencd@0: VASSERT_EQ("2.5", "host", u2.getHost()); ferencd@0: VASSERT_EQ("2.6", 12345, u2.getPort()); ferencd@0: VASSERT_EQ("2.7", "/path/", u2.getPath()); ferencd@0: ferencd@0: vmime::utility::url u3("", ""); ferencd@0: ferencd@0: VASSERT_EQ("3.1", true, parseHelper(u3, "protocol://host:12345/path/")); ferencd@0: VASSERT_EQ("3.2", "protocol", u3.getProtocol()); ferencd@0: VASSERT_EQ("3.3", "", u3.getUsername()); ferencd@0: VASSERT_EQ("3.4", "", u3.getPassword()); ferencd@0: VASSERT_EQ("3.5", "host", u3.getHost()); ferencd@0: VASSERT_EQ("3.6", 12345, u3.getPort()); ferencd@0: VASSERT_EQ("3.7", "/path/", u3.getPath()); ferencd@0: ferencd@0: vmime::utility::url u4("", ""); ferencd@0: ferencd@0: VASSERT_EQ("4.1", true, parseHelper(u4, "protocol://host/path/")); ferencd@0: VASSERT_EQ("4.2", "protocol", u4.getProtocol()); ferencd@0: VASSERT_EQ("4.3", "", u4.getUsername()); ferencd@0: VASSERT_EQ("4.4", "", u4.getPassword()); ferencd@0: VASSERT_EQ("4.5", "host", u4.getHost()); ferencd@0: VASSERT_EQ("4.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort()); ferencd@0: VASSERT_EQ("4.7", "/path/", u4.getPath()); ferencd@0: ferencd@0: vmime::utility::url u5("", ""); ferencd@0: ferencd@0: VASSERT_EQ("5.1", true, parseHelper(u5, "protocol://host/")); ferencd@0: VASSERT_EQ("5.2", "protocol", u5.getProtocol()); ferencd@0: VASSERT_EQ("5.3", "", u5.getUsername()); ferencd@0: VASSERT_EQ("5.4", "", u5.getPassword()); ferencd@0: VASSERT_EQ("5.5", "host", u5.getHost()); ferencd@0: VASSERT_EQ("5.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort()); ferencd@0: VASSERT_EQ("5.7", "", u5.getPath()); ferencd@0: ferencd@0: vmime::utility::url u6("", ""); ferencd@0: ferencd@0: VASSERT_EQ("6.1", true, parseHelper(u4, "protocol://host/path/file")); ferencd@0: VASSERT_EQ("6.2", "protocol", u4.getProtocol()); ferencd@0: VASSERT_EQ("6.3", "", u4.getUsername()); ferencd@0: VASSERT_EQ("6.4", "", u4.getPassword()); ferencd@0: VASSERT_EQ("6.5", "host", u4.getHost()); ferencd@0: VASSERT_EQ("6.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort()); ferencd@0: VASSERT_EQ("6.7", "/path/file", u4.getPath()); ferencd@0: } ferencd@0: ferencd@0: void testParse2() ferencd@0: { ferencd@0: // Now, test some ill-formed URLs ferencd@0: ferencd@0: // -- missing protocol ferencd@0: vmime::utility::url u1("", ""); ferencd@0: VASSERT_EQ("1", false, parseHelper(u1, "://host")); ferencd@0: ferencd@0: // -- port can contain only digits ferencd@0: vmime::utility::url u2("", ""); ferencd@0: VASSERT_EQ("2", false, parseHelper(u2, "proto://host:abc123")); ferencd@0: ferencd@0: // -- no host specified ferencd@0: vmime::utility::url u3("", ""); ferencd@0: VASSERT_EQ("3", false, parseHelper(u3, "proto:///path")); ferencd@0: ferencd@0: // -- no protocol separator (://) ferencd@0: vmime::utility::url u4("", ""); ferencd@0: VASSERT_EQ("4", false, parseHelper(u4, "protohost/path")); ferencd@0: } ferencd@0: ferencd@0: void testParse3() ferencd@0: { ferencd@0: // Test decoding ferencd@0: vmime::utility::url u1("", ""); ferencd@0: ferencd@0: VASSERT_EQ("1.1", true, parseHelper(u1, "pro%12to://user%34:pass%56word@ho%78st:12345/pa%abth/")); ferencd@0: VASSERT_EQ("1.2", "pro%12to", u1.getProtocol()); // protocol should not be decoded ferencd@0: VASSERT_EQ("1.3", "user\x34", u1.getUsername()); ferencd@0: VASSERT_EQ("1.4", "pass\x56word", u1.getPassword()); ferencd@0: VASSERT_EQ("1.5", "ho\x78st", u1.getHost()); ferencd@0: VASSERT_EQ("1.6", 12345, u1.getPort()); ferencd@0: VASSERT_EQ("1.7", "/pa\xabth/", u1.getPath()); ferencd@0: } ferencd@0: ferencd@0: void testParse4() ferencd@0: { ferencd@0: // Test parameters ferencd@0: vmime::utility::url u1("", ""); ferencd@0: ferencd@0: VASSERT_EQ("1.1", true, parseHelper(u1, "proto://host/path?p1=v1&p2=v2")); ferencd@0: VASSERT_EQ("1.2", "v1", u1.getParams()["p1"]); ferencd@0: VASSERT_EQ("1.3", "v2", u1.getParams()["p2"]); ferencd@0: VASSERT_EQ("1.4", "/path", u1.getPath()); ferencd@0: ferencd@0: vmime::utility::url u2("", ""); ferencd@0: ferencd@0: VASSERT_EQ("2.1", true, parseHelper(u2, "proto://host/path?p1=v1&p2")); ferencd@0: VASSERT_EQ("2.2", "v1", u2.getParams()["p1"]); ferencd@0: VASSERT_EQ("2.3", "p2", u2.getParams()["p2"]); ferencd@0: VASSERT_EQ("2.4", "/path", u2.getPath()); ferencd@0: ferencd@0: vmime::utility::url u3("", ""); ferencd@0: ferencd@0: VASSERT_EQ("3.1", true, parseHelper(u3, "proto://host/?p1=v1&p2=v2")); ferencd@0: VASSERT_EQ("3.2", "v1", u3.getParams()["p1"]); ferencd@0: VASSERT_EQ("3.3", "v2", u3.getParams()["p2"]); ferencd@0: VASSERT_EQ("3.4", "", u3.getPath()); ferencd@0: ferencd@0: vmime::utility::url u4("", ""); ferencd@0: ferencd@0: VASSERT_EQ("4.1", true, parseHelper(u4, "proto://host/path?p1=%3D&%3D=v2")); ferencd@0: VASSERT_EQ("4.2", "=", u4.getParams()["p1"]); ferencd@0: VASSERT_EQ("4.3", "v2", u4.getParams()["="]); ferencd@0: VASSERT_EQ("4.4", "/path", u4.getPath()); ferencd@0: } ferencd@0: ferencd@0: // '@' symbol in the username part ferencd@0: void testParse5() ferencd@0: { ferencd@0: vmime::utility::url u1("", ""); ferencd@0: ferencd@0: VASSERT_EQ("1", true, parseHelper(u1, "imap://account@myserver.com:password@myserver.com")); ferencd@0: VASSERT_EQ("2", "account@myserver.com", u1.getUsername()); ferencd@0: VASSERT_EQ("3", "password", u1.getPassword()); ferencd@0: VASSERT_EQ("4", "myserver.com", u1.getHost()); ferencd@0: } ferencd@0: ferencd@0: void testGenerate() ferencd@0: { ferencd@0: vmime::utility::url u1("proto", "host", 12345, "path", "user", "password"); ferencd@0: VASSERT_EQ("1", "proto://user:password@host:12345/path", ferencd@0: static_cast (u1)); ferencd@0: ferencd@0: vmime::utility::url u2("proto", "host"); ferencd@0: VASSERT_EQ("2", "proto://host", static_cast (u2)); ferencd@0: ferencd@0: vmime::utility::url u3("proto", "host"); ferencd@0: u3.getParams()["p1"] = "v1"; ferencd@0: VASSERT_EQ("3.1", "proto://host/?p1=v1", ferencd@0: static_cast (u3)); ferencd@0: u3.getParams()["p2"] = "v2"; ferencd@0: VASSERT_EQ("3.2", "proto://host/?p1=v1&p2=v2", ferencd@0: static_cast (u3)); ferencd@0: ferencd@0: // Test special characters ferencd@0: u3.getParams().clear(); ferencd@0: u3.getParams()["&"] = "="; ferencd@0: VASSERT_EQ("3.3", "proto://host/?%26=%3D", ferencd@0: static_cast (u3)); ferencd@0: } ferencd@0: ferencd@0: void testUtilsEncode() ferencd@0: { ferencd@0: VASSERT_EQ("1", "%01", vmime::utility::urlUtils::encode("\x01")); ferencd@0: VASSERT_EQ("2", "%20", vmime::utility::urlUtils::encode(" ")); ferencd@0: VASSERT_EQ("3", "%FF", vmime::utility::urlUtils::encode("\xff")); ferencd@0: VASSERT_EQ("4", "a", vmime::utility::urlUtils::encode("a")); ferencd@0: } ferencd@0: ferencd@0: void testUtilsDecode() ferencd@0: { ferencd@0: for (int i = 0 ; i < 255 ; ++i) ferencd@0: { ferencd@0: std::ostringstream ossTest; ferencd@0: ossTest << "%" << "0123456789ABCDEF"[i / 16] ferencd@0: << "0123456789ABCDEF"[i % 16]; ferencd@0: ferencd@0: std::ostringstream ossNum; ferencd@0: ossNum << i; ferencd@0: ferencd@0: vmime::string res; ferencd@0: res += static_cast (i); ferencd@0: ferencd@0: VASSERT_EQ(ossNum.str(), res, ferencd@0: vmime::utility::urlUtils::decode(ossTest.str())); ferencd@0: } ferencd@0: ferencd@0: } ferencd@0: ferencd@0: void testUtilsDecodeSpecialCases() ferencd@0: { ferencd@0: // Bug #1656547: segfault with '%' at the end of the string ferencd@0: VASSERT_EQ("1.1", "sadfsda%", vmime::utility::urlUtils::decode("sadfsda%")); ferencd@0: VASSERT_EQ("1.2", "sadfsda\x05", vmime::utility::urlUtils::decode("sadfsda%5")); ferencd@0: VASSERT_EQ("1.3", "sadfsda\x42", vmime::utility::urlUtils::decode("sadfsda%42")); ferencd@0: } ferencd@0: ferencd@0: void testUtilsEncodeReservedChars() ferencd@0: { ferencd@0: VASSERT_EQ("1", "%24", vmime::utility::urlUtils::encode("$")); ferencd@0: VASSERT_EQ("2", "%26", vmime::utility::urlUtils::encode("&")); ferencd@0: VASSERT_EQ("3", "%2B", vmime::utility::urlUtils::encode("+")); ferencd@0: VASSERT_EQ("4", "%2C", vmime::utility::urlUtils::encode(",")); ferencd@0: VASSERT_EQ("5", "%2F", vmime::utility::urlUtils::encode("/")); ferencd@0: VASSERT_EQ("6", "%3A", vmime::utility::urlUtils::encode(":")); ferencd@0: VASSERT_EQ("7", "%3B", vmime::utility::urlUtils::encode(";")); ferencd@0: VASSERT_EQ("8", "%3D", vmime::utility::urlUtils::encode("=")); ferencd@0: VASSERT_EQ("9", "%3F", vmime::utility::urlUtils::encode("?")); ferencd@0: VASSERT_EQ("10", "%40", vmime::utility::urlUtils::encode("@")); ferencd@0: } ferencd@0: ferencd@0: void testUtilsEncodeUnsafeChars() ferencd@0: { ferencd@0: VASSERT_EQ("1", "%20", vmime::utility::urlUtils::encode(" ")); ferencd@0: VASSERT_EQ("2", "%22", vmime::utility::urlUtils::encode("\"")); ferencd@0: VASSERT_EQ("3", "%3C", vmime::utility::urlUtils::encode("<")); ferencd@0: VASSERT_EQ("4", "%3E", vmime::utility::urlUtils::encode(">")); ferencd@0: VASSERT_EQ("5", "%23", vmime::utility::urlUtils::encode("#")); ferencd@0: VASSERT_EQ("6", "%25", vmime::utility::urlUtils::encode("%")); ferencd@0: VASSERT_EQ("7", "%7B", vmime::utility::urlUtils::encode("{")); ferencd@0: VASSERT_EQ("8", "%7D", vmime::utility::urlUtils::encode("}")); ferencd@0: VASSERT_EQ("9", "%7C", vmime::utility::urlUtils::encode("|")); ferencd@0: VASSERT_EQ("10", "%5C", vmime::utility::urlUtils::encode("\\")); ferencd@0: VASSERT_EQ("11", "%5E", vmime::utility::urlUtils::encode("^")); ferencd@0: VASSERT_EQ("12", "%7E", vmime::utility::urlUtils::encode("~")); ferencd@0: VASSERT_EQ("13", "%5B", vmime::utility::urlUtils::encode("[")); ferencd@0: VASSERT_EQ("14", "%5D", vmime::utility::urlUtils::encode("]")); ferencd@0: VASSERT_EQ("15", "%60", vmime::utility::urlUtils::encode("`")); ferencd@0: } ferencd@0: ferencd@0: VMIME_TEST_SUITE_END ferencd@0: