forked from pool/kdump
Accepting request 234827 from home:ptesarik:branches:Kernel:kdump
Fix service failures after online/offline CPU under systemd. URL-decode the target URL. OBS-URL: https://build.opensuse.org/request/show/234827 OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/kdump?expand=0&rev=90
This commit is contained in:
parent
53406c38d1
commit
0f56f11067
718
kdump-urldecode.patch
Normal file
718
kdump-urldecode.patch
Normal file
@ -0,0 +1,718 @@
|
||||
From: Petr Tesarik <ptesarik@suse.cz>
|
||||
Subject: Perform percent decoding on target URL
|
||||
References: bnc#869590
|
||||
Patch-mainline: scheduled for v0.8.13
|
||||
|
||||
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
|
||||
|
||||
diff --git a/kdumptool/CMakeLists.txt b/kdumptool/CMakeLists.txt
|
||||
index 81ce47e..9a5bc1a 100644
|
||||
--- a/kdumptool/CMakeLists.txt
|
||||
+++ b/kdumptool/CMakeLists.txt
|
||||
@@ -142,3 +142,8 @@ add_executable(testprocess
|
||||
testprocess.cc
|
||||
)
|
||||
target_link_libraries(testprocess common ${EXTRA_LIBS})
|
||||
+
|
||||
+add_executable(testurldecode
|
||||
+ testurldecode.cc
|
||||
+)
|
||||
+target_link_libraries(testurldecode common ${EXTRA_LIBS})
|
||||
diff --git a/kdumptool/stringutil.cc b/kdumptool/stringutil.cc
|
||||
index 807a30a..70d2dc5 100644
|
||||
--- a/kdumptool/stringutil.cc
|
||||
+++ b/kdumptool/stringutil.cc
|
||||
@@ -270,6 +270,19 @@ void Stringutil::digest_base64(const void *buf, size_t len,
|
||||
|
||||
#endif // HAVE_LIBSSL
|
||||
|
||||
+// -----------------------------------------------------------------------------
|
||||
+int Stringutil::hex2int(char c)
|
||||
+ throw (KError)
|
||||
+{
|
||||
+ if (c >= '0' && c <= '9')
|
||||
+ return c - '0';
|
||||
+ if (c >= 'a' && c <= 'f')
|
||||
+ return c - 'a' + 10;
|
||||
+ if (c >= 'A' && c <= 'F')
|
||||
+ return c - 'A' + 10;
|
||||
+ throw KError(string("Stringutil::hex2int: '") + c + "' is not a hex digit");
|
||||
+}
|
||||
+
|
||||
//}}}
|
||||
//{{{ KString ------------------------------------------------------------------
|
||||
|
||||
@@ -333,6 +346,27 @@ bool KString::endsWith(const string &part) const
|
||||
return strcmp(c_str() + size() - part.size(), part.c_str()) == 0;
|
||||
}
|
||||
|
||||
+// -----------------------------------------------------------------------------
|
||||
+KString &KString::decodeURL(bool formenc)
|
||||
+ throw()
|
||||
+{
|
||||
+ iterator src, dst;
|
||||
+ for (src = dst = begin(); src != end(); ++src) {
|
||||
+ char c1, c2;
|
||||
+ if (*src == '%' && end() - src >= 2 &&
|
||||
+ isxdigit(c1 = src[1]) && isxdigit(c2 = src[2])) {
|
||||
+ *dst++ = (Stringutil::hex2int(c1) << 4) |
|
||||
+ Stringutil::hex2int(c2);
|
||||
+ src += 2;
|
||||
+ } else if (formenc && *src == '+')
|
||||
+ *dst++ = ' ';
|
||||
+ else
|
||||
+ *dst++ = *src;
|
||||
+ }
|
||||
+ resize(dst - begin());
|
||||
+ return *this;
|
||||
+}
|
||||
+
|
||||
//}}}
|
||||
|
||||
// vim: set sw=4 ts=4 fdm=marker et: :collapseFolds=1:
|
||||
diff --git a/kdumptool/stringutil.h b/kdumptool/stringutil.h
|
||||
index 321ab59..4dad735 100644
|
||||
--- a/kdumptool/stringutil.h
|
||||
+++ b/kdumptool/stringutil.h
|
||||
@@ -200,6 +200,9 @@ class Stringutil {
|
||||
throw (KError);
|
||||
|
||||
#endif // HAVE_LIBSSL
|
||||
+
|
||||
+ static int hex2int(char c)
|
||||
+ throw (KError);
|
||||
};
|
||||
|
||||
//}}}
|
||||
@@ -289,6 +292,14 @@ class KString : public std::string {
|
||||
bool endsWith(const std::string &part) const
|
||||
throw ();
|
||||
|
||||
+ /**
|
||||
+ * Perform URL decoding on the string.
|
||||
+ *
|
||||
+ * @param[in] formenc if @c true, translate '+' into spaces
|
||||
+ * @return reference to this object (after decoding)
|
||||
+ */
|
||||
+ KString &decodeURL(bool formenc = false)
|
||||
+ throw();
|
||||
};
|
||||
|
||||
//}}}
|
||||
diff --git a/kdumptool/testurldecode.cc b/kdumptool/testurldecode.cc
|
||||
new file mode 100644
|
||||
index 0000000..36e639f
|
||||
--- /dev/null
|
||||
+++ b/kdumptool/testurldecode.cc
|
||||
@@ -0,0 +1,60 @@
|
||||
+/*
|
||||
+ * (c) 2014, Petr Tesarik <ptesarik@suse.de>, SUSE LINUX Products GmbH
|
||||
+ *
|
||||
+ * 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 2
|
||||
+ * 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.
|
||||
+ */
|
||||
+#include <iostream>
|
||||
+#include <cstdlib>
|
||||
+
|
||||
+#include "global.h"
|
||||
+#include "stringutil.h"
|
||||
+#include "debug.h"
|
||||
+
|
||||
+using std::cout;
|
||||
+using std::cerr;
|
||||
+using std::endl;
|
||||
+
|
||||
+// -----------------------------------------------------------------------------
|
||||
+int main(int argc, char *argv[])
|
||||
+{
|
||||
+ Debug::debug()->setStderrLevel(Debug::DL_TRACE);
|
||||
+ bool formenc = false;
|
||||
+
|
||||
+ try {
|
||||
+ int i = 1;
|
||||
+ if (i < argc && KString(argv[i]) == "-f") {
|
||||
+ formenc = true;
|
||||
+ ++i;
|
||||
+ }
|
||||
+
|
||||
+ bool addspace = false;
|
||||
+ while (i < argc) {
|
||||
+ KString arg(argv[i]);
|
||||
+ if (addspace)
|
||||
+ cout << ' ';
|
||||
+ cout << arg.decodeURL(formenc);
|
||||
+ addspace = true;
|
||||
+ ++i;
|
||||
+ }
|
||||
+ cout << endl;
|
||||
+
|
||||
+ } catch(const std::exception &ex) {
|
||||
+ cerr << "Fatal exception: " << ex.what() << endl;
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ return EXIT_SUCCESS;
|
||||
+}
|
||||
diff --git a/kdumptool/urlparser.cc b/kdumptool/urlparser.cc
|
||||
index 095415e..fda09ea 100644
|
||||
--- a/kdumptool/urlparser.cc
|
||||
+++ b/kdumptool/urlparser.cc
|
||||
@@ -86,166 +86,147 @@ string URLParser::protocol2string(URLParser::Protocol protocol)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
+string URLParser::extractScheme(string::iterator &it,
|
||||
+ const string::const_iterator &end)
|
||||
+{
|
||||
+ string::iterator const start = it;
|
||||
+
|
||||
+ if (it == m_url.end() || !isalpha(*it))
|
||||
+ return string();
|
||||
+
|
||||
+ do {
|
||||
+ ++it;
|
||||
+ if (it == m_url.end()) {
|
||||
+ it = start;
|
||||
+ return string();
|
||||
+ }
|
||||
+ } while (*it != ':' && *it != '/' && *it != '?' && *it != '#');
|
||||
+
|
||||
+ if (*it != ':') {
|
||||
+ it = start;
|
||||
+ return string();
|
||||
+ }
|
||||
+
|
||||
+ return string(start, it++);
|
||||
+}
|
||||
+
|
||||
+// -----------------------------------------------------------------------------
|
||||
+string URLParser::extractAuthority(string::iterator &it,
|
||||
+ const string::const_iterator &end)
|
||||
+{
|
||||
+ if (end - it < 2 || it[0] != '/' || it[1] != '/')
|
||||
+ return string();
|
||||
+
|
||||
+ it += 2;
|
||||
+ string::iterator const start = it;
|
||||
+ while (*it != '/' && *it != '?' && *it != '#')
|
||||
+ ++it;
|
||||
+
|
||||
+ return string(start, it);
|
||||
+}
|
||||
+
|
||||
+// -----------------------------------------------------------------------------
|
||||
URLParser::URLParser(const std::string &url)
|
||||
throw (KError)
|
||||
: m_url(url), m_port(-1)
|
||||
{
|
||||
Debug::debug()->trace("URLParser::URLParser(%s)", url.c_str());
|
||||
|
||||
- if (url.size() == 0)
|
||||
- throw KError("URL must be longer than 0 characters.");
|
||||
-
|
||||
- // local files that don't have URL syntax
|
||||
- // we support that for backward-compatibility
|
||||
- if (url[0] == '/') {
|
||||
- m_protocol = PROT_FILE;
|
||||
- m_path = url;
|
||||
- return;
|
||||
- }
|
||||
+ string::iterator it = m_url.begin();
|
||||
|
||||
//
|
||||
- // get the protocol
|
||||
+ // extract the three main URL componenets
|
||||
//
|
||||
+ string scheme = extractScheme(it, m_url.end());
|
||||
+ string authority = extractAuthority(it, m_url.end());
|
||||
+ m_path.assign(it, m_url.end());
|
||||
+ // TODO: query and fragment are not handled
|
||||
|
||||
- string::size_type first_colon = url.find(':');
|
||||
- if (first_colon == string::npos)
|
||||
- throw KError("The URL does not contain any protocol.");
|
||||
- string proto_part = url.substr(0, first_colon);
|
||||
- Debug::debug()->trace("Setting protocol to %s", proto_part.c_str());
|
||||
- m_protocol = string2protocol(proto_part);
|
||||
-
|
||||
- if (url.size() < (first_colon + 3) ||
|
||||
- url[first_colon+1] != '/' ||
|
||||
- url[first_colon+2] != '/')
|
||||
- throw KError("protocol: must be followed by '//'.");
|
||||
+ if (m_path.empty() || m_path[0] != '/')
|
||||
+ throw KError("URLParser: Only absolute paths are supported.");
|
||||
|
||||
//
|
||||
- // call the parse methods matching for the protocol
|
||||
+ // parse the authority part
|
||||
//
|
||||
|
||||
- if (m_protocol == PROT_FILE) {
|
||||
- m_path = url.substr(first_colon+3);
|
||||
- } else if (m_protocol == PROT_NFS) {
|
||||
- parseNFSUrl(url.substr(first_colon+3));
|
||||
- } else if (m_protocol == PROT_SFTP || m_protocol == PROT_SSH ||
|
||||
- m_protocol == PROT_FTP || m_protocol == PROT_CIFS) {
|
||||
- parseFTPUrl(url.substr(first_colon+3));
|
||||
- } else
|
||||
- throw KError("Invalid protocol: " +
|
||||
- Stringutil::number2string(m_protocol) + ".");
|
||||
+ // Look for (optional) port
|
||||
+ it = authority.end();
|
||||
+ while (it != authority.begin() && isdigit(it[-1]))
|
||||
+ --it;
|
||||
+ if (it != authority.begin() && it[-1] == ':') {
|
||||
+ string port(it, authority.end());
|
||||
+ authority.resize(it - authority.begin() - 1);
|
||||
|
||||
- Debug::debug()->dbg("URL parsed as: protocol=%s, host=%s, port=%d, "
|
||||
- "username=%s, password=%s, path=%s",
|
||||
- getProtocolAsString().c_str(),
|
||||
- getHostname().c_str(), getPort(), getUsername().c_str(),
|
||||
- getPassword().c_str(), getPath().c_str());
|
||||
+ if (port.size() > 0)
|
||||
+ m_port = Stringutil::string2number(port);
|
||||
+ }
|
||||
|
||||
-}
|
||||
+ // look for userinfo
|
||||
+ string::size_type last_at = authority.rfind('@');
|
||||
+ if (last_at != string::npos) {
|
||||
+ m_hostname = authority.substr(last_at+1);
|
||||
+ authority.resize(last_at);
|
||||
+
|
||||
+ // now separate user and password
|
||||
+ string::size_type first_colon = authority.find(':');
|
||||
+ if (first_colon != string::npos) {
|
||||
+ m_username = authority.substr(0, first_colon);
|
||||
+ m_password = authority.substr(first_colon+1);
|
||||
+ } else
|
||||
+ m_username = authority;
|
||||
+ } else
|
||||
+ m_hostname = authority;
|
||||
|
||||
-// -----------------------------------------------------------------------------
|
||||
-void URLParser::parseUserPassHostPort(const string &userpasshostport)
|
||||
- throw (KError)
|
||||
-{
|
||||
- // now scan for an '@' to separate userhost from hostport
|
||||
- string::size_type last_at = userpasshostport.rfind('@');
|
||||
- string userhost;
|
||||
- string hostport;
|
||||
- if (last_at == string::npos) {
|
||||
- hostport = userpasshostport;
|
||||
-
|
||||
- switch (m_protocol) {
|
||||
- case PROT_FTP:
|
||||
- m_username = FTP_DEFAULT_USER;
|
||||
- break;
|
||||
-
|
||||
- case PROT_SFTP:
|
||||
- case PROT_SSH:
|
||||
- m_username = SFTP_DEFAULT_USER;
|
||||
- break;
|
||||
-
|
||||
- default:
|
||||
- // do nothing but make the compiler happy
|
||||
- break;
|
||||
- }
|
||||
+ //
|
||||
+ // undo percent encoding
|
||||
+ //
|
||||
+ m_hostname.decodeURL();
|
||||
+ m_password.decodeURL();
|
||||
+ m_username.decodeURL();
|
||||
+ m_path.decodeURL();
|
||||
|
||||
+ //
|
||||
+ // guess the scheme, if omitted
|
||||
+ //
|
||||
+ if (scheme.empty()) {
|
||||
+ if (m_hostname.empty() || m_hostname == "localhost") {
|
||||
+ m_protocol = PROT_FILE;
|
||||
+ Debug::debug()->trace("URL looks like a local file");
|
||||
+ } else {
|
||||
+ m_protocol = PROT_NFS;
|
||||
+ Debug::debug()->trace("URL looks like a remote file");
|
||||
+ }
|
||||
} else {
|
||||
- string userpass = userpasshostport.substr(0, last_at);
|
||||
- hostport = userpasshostport.substr(last_at+1);
|
||||
-
|
||||
- // now separate user and passwort
|
||||
- string::size_type firstcolon = userpass.find(':');
|
||||
- if (firstcolon != string::npos) {
|
||||
- m_username = userpass.substr(0, firstcolon);
|
||||
- m_password = userpass.substr(firstcolon+1);
|
||||
- } else
|
||||
- m_username = userpass;
|
||||
+ Debug::debug()->trace("Scheme explicitly set to %s", scheme.c_str());
|
||||
+ m_protocol = string2protocol(scheme);
|
||||
}
|
||||
|
||||
- // look for a literal IPv6 addresses
|
||||
- string::size_type last_colon = hostport.rfind(':');
|
||||
- if (hostport[0] == '[') {
|
||||
- string::size_type bracket = hostport.find(']');
|
||||
- if (bracket != string::npos && bracket > last_colon)
|
||||
- last_colon = string::npos;
|
||||
- }
|
||||
-
|
||||
- // and separate host and port
|
||||
- if (last_colon != string::npos) {
|
||||
- m_hostname = hostport.substr(0, last_colon);
|
||||
- string portstr = hostport.substr(last_colon+1);
|
||||
- if (portstr.size() > 0)
|
||||
- m_port = Stringutil::string2number(portstr);
|
||||
- } else
|
||||
- m_hostname = hostport;
|
||||
-}
|
||||
-
|
||||
-// -----------------------------------------------------------------------------
|
||||
-void URLParser::parseNFSUrl(const string &partUrl)
|
||||
- throw (KError)
|
||||
-{
|
||||
- Debug::debug()->trace("URLParser::parseNFSUrl(%s)", partUrl.c_str());
|
||||
-
|
||||
- // look for the first '/'
|
||||
- string::size_type first_slash = partUrl.find('/');
|
||||
- if (first_slash == string::npos)
|
||||
- throw KError("NFS URL must contain at least one '/'.");
|
||||
+ //
|
||||
+ // protocol-specific defaults
|
||||
+ //
|
||||
|
||||
- m_hostname = partUrl.substr(0, first_slash);
|
||||
+ if (m_protocol == PROT_FILE && m_hostname == "localhost")
|
||||
+ m_hostname.clear();
|
||||
|
||||
- string::size_type last_colon = m_hostname.rfind(':');
|
||||
- if (m_hostname[0] == '[') {
|
||||
- string::size_type bracket = m_hostname.find(']');
|
||||
- if (bracket != string::npos && bracket > last_colon)
|
||||
- last_colon = string::npos;
|
||||
+ if (m_username.empty()) {
|
||||
+ if (m_protocol == PROT_FTP)
|
||||
+ m_username = FTP_DEFAULT_USER;
|
||||
+ else if (m_protocol == PROT_SFTP || m_protocol == PROT_SSH)
|
||||
+ m_username = SFTP_DEFAULT_USER;
|
||||
}
|
||||
- if (last_colon != string::npos) {
|
||||
- string hostport = m_hostname;
|
||||
- m_hostname = hostport.substr(0, last_colon);
|
||||
- string portstring = hostport.substr(last_colon+1);
|
||||
- if (portstring.size() > 0)
|
||||
- m_port = Stringutil::string2number(hostport.substr(last_colon+1));
|
||||
- }
|
||||
-
|
||||
- m_path = partUrl.substr(first_slash);
|
||||
-}
|
||||
-
|
||||
-// -----------------------------------------------------------------------------
|
||||
-void URLParser::parseFTPUrl(const string &partUrl)
|
||||
- throw (KError)
|
||||
-{
|
||||
- Debug::debug()->trace("URLParser::parseFTPUrl(%s)", partUrl.c_str());
|
||||
|
||||
- // look for the first '/' to separate the host name part from the
|
||||
- // path name
|
||||
- string::size_type first_slash = partUrl.find('/');
|
||||
- if (first_slash == string::npos)
|
||||
- throw KError(getProtocolAsString() +
|
||||
- " URL must contain at least one '/'.");
|
||||
+ //
|
||||
+ // sanity checks
|
||||
+ //
|
||||
+ if (m_protocol == PROT_FILE && !m_hostname.empty())
|
||||
+ throw KError("File protocol cannot specify a remote host");
|
||||
|
||||
- parseUserPassHostPort(partUrl.substr(0, first_slash));
|
||||
+ Debug::debug()->dbg("URL parsed as: protocol=%s, host=%s, port=%d, "
|
||||
+ "username=%s, password=%s, path=%s",
|
||||
+ getProtocolAsString().c_str(),
|
||||
+ getHostname().c_str(), getPort(), getUsername().c_str(),
|
||||
+ getPassword().c_str(), getPath().c_str());
|
||||
|
||||
- // and the rest is the path
|
||||
- m_path = partUrl.substr(first_slash);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
diff --git a/kdumptool/urlparser.h b/kdumptool/urlparser.h
|
||||
index aac01e7..94aab27 100644
|
||||
--- a/kdumptool/urlparser.h
|
||||
+++ b/kdumptool/urlparser.h
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "global.h"
|
||||
#include "optionparser.h"
|
||||
#include "subcommand.h"
|
||||
+#include "stringutil.h"
|
||||
|
||||
//{{{ URLParser ----------------------------------------------------------------
|
||||
|
||||
@@ -158,29 +159,32 @@ class URLParser {
|
||||
static std::string protocol2string(Protocol protocol)
|
||||
throw (KError);
|
||||
|
||||
- protected:
|
||||
-
|
||||
- void parseCifsUrl(const std::string &partUrl)
|
||||
- throw (KError);
|
||||
-
|
||||
- void parseNFSUrl(const std::string &partUrl)
|
||||
- throw (KError);
|
||||
-
|
||||
- void parseUserPassHostPort(const std::string &userpasshostport)
|
||||
- throw (KError);
|
||||
-
|
||||
- void parseFTPUrl(const std::string &partUrl)
|
||||
- throw (KError);
|
||||
-
|
||||
private:
|
||||
- std::string m_url;
|
||||
+ std::string m_url;
|
||||
Protocol m_protocol;
|
||||
- std::string m_hostname;
|
||||
- std::string m_password;
|
||||
- std::string m_username;
|
||||
+ KString m_hostname;
|
||||
+ KString m_password;
|
||||
+ KString m_username;
|
||||
int m_port;
|
||||
- std::string m_path;
|
||||
- std::string m_share;
|
||||
+ KString m_path;
|
||||
+
|
||||
+ /**
|
||||
+ * Extract scheme from a string
|
||||
+ *
|
||||
+ * @param[in,out] it starting position (updated if scheme is found)
|
||||
+ * @param[in] end end of input string
|
||||
+ */
|
||||
+ std::string extractScheme(std::string::iterator &it,
|
||||
+ const std::string::const_iterator &end);
|
||||
+
|
||||
+ /**
|
||||
+ * Extract authority from a string
|
||||
+ *
|
||||
+ * @param[in,out] it starting position (updated if authority is found)
|
||||
+ * @param[in] end end of input string
|
||||
+ */
|
||||
+ std::string extractAuthority(std::string::iterator &it,
|
||||
+ const std::string::const_iterator &end);
|
||||
};
|
||||
|
||||
//}}}
|
||||
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
|
||||
index 41c222b..0b35466 100644
|
||||
--- a/tests/CMakeLists.txt
|
||||
+++ b/tests/CMakeLists.txt
|
||||
@@ -60,3 +60,7 @@ ADD_TEST(delete_dumps
|
||||
ADD_TEST(process
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/process.sh
|
||||
${CMAKE_BINARY_DIR}/kdumptool/testprocess)
|
||||
+
|
||||
+ADD_TEST(urldecode
|
||||
+ ${CMAKE_CURRENT_SOURCE_DIR}/testurldecode.sh
|
||||
+ ${CMAKE_BINARY_DIR}/kdumptool/testurldecode)
|
||||
diff --git a/tests/testurldecode.sh b/tests/testurldecode.sh
|
||||
new file mode 100755
|
||||
index 0000000..a8076b4
|
||||
--- /dev/null
|
||||
+++ b/tests/testurldecode.sh
|
||||
@@ -0,0 +1,163 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# (c) 2014, Petr Tesarik <ptesarik@suse.de>, SUSE LINUX Products GmbH
|
||||
+#
|
||||
+# 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 2
|
||||
+# 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.
|
||||
+#
|
||||
+
|
||||
+# Check that results match expectation
|
||||
+# {{{
|
||||
+function check()
|
||||
+{
|
||||
+ local arg="$1"
|
||||
+ local expect="$2"
|
||||
+ local result="$3"
|
||||
+ if [ "$result" != "$expect" ] ; then
|
||||
+ echo "failed string: $arg"
|
||||
+ echo "Expected:"
|
||||
+ echo "$expect"
|
||||
+ echo "Result:"
|
||||
+ echo "$result"
|
||||
+ errornumber=$(( errornumber + 1 ))
|
||||
+ fi
|
||||
+}
|
||||
+# }}}
|
||||
+
|
||||
+#
|
||||
+# Program {{{
|
||||
+#
|
||||
+
|
||||
+# number of tested characters for random tests
|
||||
+NTEST=100
|
||||
+
|
||||
+URLDECODE=$1
|
||||
+HEXDUMP="od -Ax -tx1"
|
||||
+
|
||||
+if [ -z "$URLDECODE" ] ; then
|
||||
+ echo "Usage: $0 urldecode"
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+errornumber=0
|
||||
+
|
||||
+# TEST #1: Random uppercase %-sequences
|
||||
+
|
||||
+ARG=
|
||||
+EXPECT=
|
||||
+i=0
|
||||
+while [ $i -lt $NTEST ]
|
||||
+do
|
||||
+ ch=$(( $RANDOM % 256 ))
|
||||
+ hex=$( printf "%02X" $ch )
|
||||
+ ARG="$ARG%$hex"
|
||||
+ EXPECT="$EXPECT\\x$hex"
|
||||
+ i=$(( i + 1 ))
|
||||
+done
|
||||
+EXPECT=$( echo -e "$EXPECT" | $HEXDUMP )
|
||||
+RESULT=$( "$URLDECODE" "$ARG" | $HEXDUMP )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+# TEST #2: Random lowercase %-sequences
|
||||
+
|
||||
+ARG=
|
||||
+EXPECT=
|
||||
+i=0
|
||||
+while [ $i -lt $NTEST ]
|
||||
+do
|
||||
+ ch=$(( $RANDOM % 256 ))
|
||||
+ hex=$( printf "%02x" $ch )
|
||||
+ ARG="$ARG%$hex"
|
||||
+ EXPECT="$EXPECT\\x$hex"
|
||||
+ i=$(( i + 1 ))
|
||||
+done
|
||||
+EXPECT=$( echo -e "$EXPECT" | $HEXDUMP )
|
||||
+RESULT=$( "$URLDECODE" "$ARG" | $HEXDUMP )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+# TEST #3: Decoding '+'
|
||||
+
|
||||
+ARG=" + +begin hello+world end+"
|
||||
+EXPECT="+ +begin hello+world end+"
|
||||
+RESULT=$( "$URLDECODE" $ARG )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+# now using form decoding
|
||||
+EXPECT=" begin hello world end "
|
||||
+RESULT=$( "$URLDECODE" -f $ARG )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+# TEST #4: Transitions quoted <-> unquoted
|
||||
+
|
||||
+ARG=
|
||||
+EXPECT=
|
||||
+i=0
|
||||
+while [ $i -lt $NTEST ]
|
||||
+do
|
||||
+ ch=$(( $RANDOM % 256 ))
|
||||
+ hex=$( printf "%02x" $ch )
|
||||
+ case $(( $ch % 3 )) in
|
||||
+ 0)
|
||||
+ ARG="$ARG $hex%$hex"
|
||||
+ EXPECT="$EXPECT $hex\\x$hex"
|
||||
+ ;;
|
||||
+
|
||||
+ 1)
|
||||
+ ARG="$ARG %$hex$hex"
|
||||
+ EXPECT="$EXPECT \\x$hex$hex"
|
||||
+ ;;
|
||||
+
|
||||
+ 2)
|
||||
+ ARG="$ARG $hex%$hex$hex"
|
||||
+ EXPECT="$EXPECT $hex\\x$hex$hex"
|
||||
+ ;;
|
||||
+
|
||||
+ 3)
|
||||
+ ARG="$ARG +%$hex+$hex"
|
||||
+ EXPECT="$EXPECT \\x$hex $hex"
|
||||
+ ;;
|
||||
+ esac
|
||||
+ i=$(( i + 1 ))
|
||||
+done
|
||||
+EXPECT=$( echo -e "$EXPECT" | $HEXDUMP )
|
||||
+RESULT=$( "$URLDECODE" "$ARG" | $HEXDUMP )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+# TEST #5: Test invalid sequence
|
||||
+
|
||||
+ARG=" %invalid %0invalid %ainvalid %x0invalid %+invalid %0+invalid"
|
||||
+EXPECT="%invalid %0invalid %ainvalid %x0invalid % invalid %0 invalid"
|
||||
+RESULT=$( "$URLDECODE" -f $ARG )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+# TEST #6: More than two hex digits
|
||||
+
|
||||
+ARG="%4567 %456789abcdef0123"
|
||||
+EXPECT="E67 E6789abcdef0123"
|
||||
+RESULT=$( "$URLDECODE" $ARG )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+# TEST #7: NUL character
|
||||
+
|
||||
+ARG="NUL character here: '%00'"
|
||||
+EXPECT=$( echo -e "NUL character here: '\000'" | $HEXDUMP )
|
||||
+RESULT=$( "$URLDECODE" $ARG | $HEXDUMP )
|
||||
+check "$ARG" "$EXPECT" "$RESULT"
|
||||
+
|
||||
+exit $errornumber
|
||||
+
|
||||
+# }}}
|
||||
+
|
||||
+# vim: set sw=4 ts=4 fdm=marker et: :collapseFolds=1:
|
||||
diff --git a/tests/testurlparser.sh b/tests/testurlparser.sh
|
||||
index 9cb9f1b..1d05353 100755
|
||||
--- a/tests/testurlparser.sh
|
||||
+++ b/tests/testurlparser.sh
|
||||
@@ -32,6 +32,7 @@ URLS=( "/var/log/dump"
|
||||
"cifs://bwalle:dontsay@neptunium:/var/log/dump"
|
||||
"smb://bwalle@192.168.0.70:/var/log"
|
||||
"cifs://bwalle:dontsay@neptunium:/var/log/dump"
|
||||
+ "ftp://pt%65sarik:don%27t%20say@fu%6eny+host/var/log/dum%70"
|
||||
)
|
||||
|
||||
# protocol:host:port:user:pass:path
|
||||
@@ -45,6 +46,7 @@ VALUES=( "file::-1:::/var/log/dump"
|
||||
"cifs:neptunium:-1:bwalle:dontsay:/var/log/dump"
|
||||
"cifs:192.168.0.70:-1:bwalle::/var/log"
|
||||
"cifs:neptunium:-1:bwalle:dontsay:/var/log/dump"
|
||||
+ "ftp:funny+host:-1:ptesarik:don't say:/var/log/dump"
|
||||
)
|
||||
# }}}
|
||||
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue May 20 11:15:40 UTC 2014 - ptesarik@suse.cz
|
||||
|
||||
- kdump-urldecode.patch: Perform percent decoding on target URL
|
||||
(bnc#869590).
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon May 19 14:18:27 UTC 2014 - ptesarik@suse.cz
|
||||
|
||||
|
@ -60,6 +60,7 @@ Source: %{name}-%{version}.tar.bz2
|
||||
Source2: %{name}-%{version}-rpmlintrc
|
||||
Source3: kdump.service
|
||||
Patch1: %{name}-fix-udev-rules.patch
|
||||
Patch2: %{name}-urldecode.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
# rename "kdump-helpers" (10.3) -> "kdump" (11.0/SP2)
|
||||
Provides: kdump-helpers = %{version}
|
||||
@ -98,6 +99,8 @@ Authors:
|
||||
%prep
|
||||
%setup
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
chmod +x tests/testurldecode.sh
|
||||
|
||||
%build
|
||||
export CFLAGS="%optflags"
|
||||
|
Loading…
x
Reference in New Issue
Block a user