- Added flag if encoded or not to set functions
authorMarius Tomaschewski <mt@suse.de>
Wed, 18 Jan 2006 18:11:49 +0000 (18:11 +0000)
committerMarius Tomaschewski <mt@suse.de>
Wed, 18 Jan 2006 18:11:49 +0000 (18:11 +0000)
- Added isValidHost and isValidPort functions,
  implementing more exact checks
- Improved documentation if a function wants
  encoded or a decoded strings.
- Moved internal UrlData into implementation
- Implemented/Fixed many checks

zypp/url/UrlBase.cc
zypp/url/UrlBase.h

index 9ca71dd..a24d8c0 100644 (file)
 #include <zypp/base/String.h>
 
 #include <stdexcept>
-// FIXME:
-#if defined(WITH_URL_PARSE_DEBUG)
-#include <iostream>
-#endif
+#include <climits>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+
+// ---------------------------------------------------------------
+/*
+** authority = //[user [:password] @ ] host [:port]
+**
+** host      = hostname | IPv4 | "[" IPv6-IP "]" | "[v...]"
+*/
+#define RX_SPLIT_AUTHORITY \
+        "^(([^:@]*)([:]([^@]*))?@)?(\\[[^]]+\\]|[^:]+)?([:](.*))?"
+
+#define RX_VALID_SCHEME    "^[a-zA-Z][a-zA-Z0-9\\.+-]*$"
+
+#define RX_VALID_PORT      "^[0-9]{1,5}$"
+
+#define RX_VALID_HOSTNAME  "^[[:alnum:]]+([\\.-][[:alnum:]]+)*$"
+
+#define RX_VALID_HOSTIPV4  \
+        "^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$"
+
+#define RX_VALID_HOSTIPV6  \
+        "^\\[[:a-fA-F0-9]+(:[0-9]{1,3}(\\.[0-9]{1,3}){3})?\\]$"
+
 
 //////////////////////////////////////////////////////////////////////
 namespace zypp
@@ -28,6 +52,9 @@ namespace zypp
 
 
     // ---------------------------------------------------------------
+    /*
+    ** URL toString() view option constants:
+    */
     const ViewOptions ViewOptions::WITH_SCHEME       = 0x0001;
     const ViewOptions ViewOptions::WITH_USERNAME     = 0x0002;
     const ViewOptions ViewOptions::WITH_PASSWORD     = 0x0004;
@@ -57,24 +84,53 @@ namespace zypp
 
 
     // ---------------------------------------------------------------
+    /*
+    ** Behaviour configuration variables.
+    */
+    typedef std::map< std::string, std::string > UrlConfig;
+
+
+    // ---------------------------------------------------------------
     /**
-     * authority = //[user [:password] @ ] host [:port]
-     *
-     * host      = hostname | IPv4 | "[" IPv6-IP "]" | "[v...]"
+     * \brief Internal data used by UrlBase.
      */
-    #define RX_SPLIT_AUTHORITY \
-    "^(([^:@]*)" "([:]([^@]*))?" "@)?" "(\\[[^]]+\\]|[^:]+)?" "([:](.*))?"
+    class UrlBaseData
+    {
+    public:
+      UrlBaseData()
+      {}
+
+      UrlBaseData(const UrlConfig &conf)
+        : config(conf)
+      {}
+
+      UrlConfig       config;
+      ViewOptions     vopts;
+
+      std::string     scheme;
+      std::string     user;
+      std::string     pass;
+      std::string     host;
+      std::string     port;
+      std::string     pathname;
+      std::string     pathparams;
+      std::string     querystr;
+      std::string     fragment;
+    };
 
 
     // ---------------------------------------------------------------
+    /*
+    ** Anonymous/internal utility namespace:
+    */
     namespace // anonymous
     {
 
                        // -------------------------------------------------------------
       inline void
       checkUrlData(const std::string &data,
-             const std::string &name,
-             const std::string &regx)
+                   const std::string &name,
+                   const std::string &regx)
       {
         if( regx.empty() || regx == "^$")
         {
@@ -106,7 +162,7 @@ namespace zypp
 
     // ---------------------------------------------------------------
     UrlBase::UrlBase()
-      : m_data( new UrlData())
+      : m_data( new UrlBaseData())
     {
       configure();
     }
@@ -114,7 +170,7 @@ namespace zypp
 
     // ---------------------------------------------------------------
     UrlBase::UrlBase(const UrlBase &url)
-      : m_data( new UrlData( *(url.m_data)))
+      : m_data( new UrlBaseData( *(url.m_data)))
     {
     }
 
@@ -125,7 +181,7 @@ namespace zypp
                      const std::string &pathdata,
                      const std::string &querystr,
                      const std::string &fragment)
-      : m_data( new UrlData())
+      : m_data( new UrlBaseData())
     {
       configure();
       init(scheme, authority, pathdata, querystr, fragment);
@@ -144,7 +200,7 @@ namespace zypp
       setAuthority(authority);
       setPathData(pathdata);
       setQueryString(querystr);
-      setFragment(fragment);
+      setFragment(fragment, zypp::url::E_ENCODED);
     }
 
 
@@ -159,23 +215,24 @@ namespace zypp
       config("psep_querystr",   "&");
       config("vsep_querystr",   "=");
 
-      config("safe_username",   "");
-      config("safe_password",   "");
+      config("safe_username",   "~!$&'()*+=,;");
+      config("safe_password",   "~!$&'()*+=,:;");
       config("safe_hostname",   "[:]");
-      config("safe_pathname",   "/");
-      config("safe_pathparams", "");
-      config("safe_querystr",   "");
-      config("safe_fragment",   "");
+      config("safe_pathname",   "~!$&'()*+=,:@/");
+      config("safe_pathparams", "~!$&'()*+=,:;@/");
+      config("safe_querystr",   "~!$&'()*+=,:;@/?");
+      config("safe_fragment",   "~!$&'()*+=,:;@/?");
+
+      config("with_authority",  "y");
 
-      config("rx_scheme",       "^[a-zA-Z][a-zA-Z0-9\\._-]*$");
-      config("rx_username",     ".*");
-      config("rx_password",     ".*");
-      config("rx_hostname",     ".*");           // FIXME
-      config("rx_port",         "^[0-9]{1,5}$");
-      config("rx_pathname",     ".*");
-      config("rx_pathparams",   ".*");
-      config("rx_querystr",     ".*");
-      config("rx_fragment",     ".*");
+      config("rx_username",     "^([a-zA-Z0-9!$&'\\(\\)*+=,;~\\._-]|%[a-fA-F0-9]{2})+$");
+      config("rx_password",     "^([a-zA-Z0-9!$&'\\(\\)*+=,:;~\\._-]|%[a-fA-F0-9]{2})+$");
+
+      config("rx_pathname",     "^([a-zA-Z0-9!$&'\\(\\)*+=,:@/~\\._-]|%[a-fA-F0-9]{2})+$");
+      config("rx_pathparams",   "^([a-zA-Z0-9!$&'\\(\\)*+=,:;@/~\\._-]|%[a-fA-F0-9]{2})+$");
+
+      config("rx_querystr",     "^([a-zA-Z0-9!$&'\\(\\)*+=,:;@/?~\\._-]|%[a-fA-F0-9]{2})+$");
+      config("rx_fragment",     "^([a-zA-Z0-9!$&'\\(\\)*+=,:;@/?~\\._-]|%[a-fA-F0-9]{2})+$");
     }
 
 
@@ -221,7 +278,7 @@ namespace zypp
     {
       zypp::url::UrlConfig   config(m_data->config);
       zypp::url::ViewOptions vopts(m_data->vopts);
-      *m_data = UrlData();
+      *m_data = UrlBaseData();
       m_data->config = config;
       m_data->vopts  = vopts;
     }
@@ -236,26 +293,6 @@ namespace zypp
 
 
     // ---------------------------------------------------------------
-    std::string
-    UrlBase::cleanupPathName(const std::string &path)
-    {
-      size_t pos = 0;
-
-      while( pos < path.length() && path.at(pos) == '/')
-        pos++;
-
-      if( pos > 1)
-      {
-        // make sure, there is not more than
-        // _one_ leading "/" in the path name.
-        return path.substr(pos - 1);
-      }
-
-      return std::string(path);
-    }
-
-
-    // ---------------------------------------------------------------
     zypp::url::UrlSchemes
     UrlBase::getKnownSchemes() const
     {
@@ -285,7 +322,7 @@ namespace zypp
     UrlBase::isValidScheme(const std::string &scheme) const
     {
       if(scheme.empty() ||
-         str::regex_match(scheme, str::regex(config("rx_scheme"))))
+         str::regex_match(scheme, str::regex(RX_VALID_SCHEME)))
       {
         std::string    lscheme( str::toLower(scheme));
         UrlSchemes     schemes( getKnownSchemes());
@@ -324,8 +361,8 @@ namespace zypp
     std::string
     UrlBase::toString(const zypp::url::ViewOptions &opts) const
     {
-      std::string url;
-      UrlData     tmp;
+      std::string   url;
+      UrlBaseData   tmp;
 
       if( opts.has(ViewOptions::WITH_SCHEME))
       {
@@ -675,21 +712,10 @@ namespace zypp
       str::smatch out;
       bool        ret = str::regex_match(authority, out, rex);
 
-      // FIXME:
-      #if defined(WITH_URL_PARSE_DEBUG)
-      std::cerr << "Regex parsed URL authority("
-                << out.size() << "):" << std::endl;
-      std::cerr << "==> " << authority << std::endl;
-      for(size_t n=0; n < out.size(); n++)
-      {
-        std::cerr << "[" << n << "] " << out[n].str() << std::endl;
-      }
-      #endif
-
       if( ret && out.size() == 8)
       {
-        setUsername(out[2].str());
-        setPassword(out[4].str());
+        setUsername(out[2].str(), zypp::url::E_ENCODED);
+        setPassword(out[4].str(), zypp::url::E_ENCODED);
         setHost(out[5].str());
         setPort(out[7].str());
       }
@@ -701,21 +727,26 @@ namespace zypp
       }
     }
 
-
     // ---------------------------------------------------------------
     void
     UrlBase::setPathData(const std::string &pathdata)
     {
-      size_t pos;
-      pos = pathdata.find(config("sep_pathparams"));
+      size_t      pos = std::string::npos;
+      std::string sep(config("sep_pathparams"));
+
+      if( !sep.empty())
+        pos = pathdata.find(sep);
+
       if( pos != std::string::npos)
       {
-        setPathName(pathdata.substr(0, pos));
+        setPathName(pathdata.substr(0, pos),
+                    zypp::url::E_ENCODED);
         setPathParams(pathdata.substr(pos + 1));
       }
       else
       {
-        setPathName(pathdata);
+        setPathName(pathdata,
+                    zypp::url::E_ENCODED);
         setPathParams("");
       }
     }
@@ -733,7 +764,6 @@ namespace zypp
       {
         checkUrlData(querystr, "query string", config("rx_querystr"));
 
-        // FIXME: split & recode?
         m_data->querystr = querystr;
       }
     }
@@ -741,7 +771,8 @@ namespace zypp
 
     // ---------------------------------------------------------------
     void
-    UrlBase::setFragment(const std::string &fragment)
+    UrlBase::setFragment(const std::string &fragment,
+                         EEncoding         eflag)
     {
       if( fragment.empty())
       {
@@ -749,20 +780,26 @@ namespace zypp
       }
       else
       {
-        std::string data( zypp::url::decode(fragment));
-
-        checkUrlData(data, "fragment", config("rx_fragment"));
+        if(eflag == zypp::url::E_ENCODED)
+        {
+          checkUrlData(fragment, "fragment", config("rx_fragment"));
 
-        m_data->fragment = zypp::url::encode(
-          data, config("safe_fragment")
-        );
+          m_data->fragment = fragment;
+        }
+        else
+        {
+          m_data->fragment = zypp::url::encode(
+            fragment, config("safe_password")
+          );
+        }
       }
     }
 
 
     // ---------------------------------------------------------------
     void
-    UrlBase::setUsername(const std::string &user)
+    UrlBase::setUsername(const std::string &user,
+                         EEncoding         eflag)
     {
       if( user.empty())
       {
@@ -770,20 +807,33 @@ namespace zypp
       }
       else
       {
-        std::string data( zypp::url::decode(user));
+        if( config("with_authority") != "y")
+        {
+          throw std::invalid_argument(
+            std::string("Url scheme does not allow a username")
+          );
+        }
 
-        checkUrlData(data, "username", config("rx_username"));
+        if(eflag == zypp::url::E_ENCODED)
+        {
+          checkUrlData(user, "username", config("rx_username"));
 
-        m_data->user = zypp::url::encode(
-          data, config("safe_username")
-        );
+          m_data->user = user;
+        }
+        else
+        {
+          m_data->user = zypp::url::encode(
+            user, config("safe_username")
+          );
+        }
       }
     }
 
 
     // ---------------------------------------------------------------
     void
-    UrlBase::setPassword(const std::string &pass)
+    UrlBase::setPassword(const std::string &pass,
+                         EEncoding         eflag)
     {
       if( pass.empty())
       {
@@ -791,13 +841,25 @@ namespace zypp
       }
       else
       {
-        std::string data( zypp::url::decode(pass));
+        if( config("with_authority") != "y")
+        {
+          throw std::invalid_argument(
+            std::string("Url scheme does not allow a password")
+          );
+        }
 
-        checkUrlData(data, "password", config("rx_password"));
+        if(eflag == zypp::url::E_ENCODED)
+        {
+          checkUrlData(pass, "password", config("rx_password"));
 
-        m_data->pass = zypp::url::encode(
-          data, config("safe_password")
-        );
+          m_data->pass = pass;
+        }
+        else
+        {
+          m_data->pass = zypp::url::encode(
+            pass, config("safe_password")
+          );
+        }
       }
     }
 
@@ -812,13 +874,35 @@ namespace zypp
       }
       else
       {
-        std::string data( zypp::url::decode(host));
+        if( config("with_authority") != "y")
+        {
+          throw std::invalid_argument(
+            std::string("Url scheme does not allow a host")
+          );
+        }
 
-        checkUrlData(data, "hostname", config("rx_hostname"));
+        if( isValidHost(host))
+        {
+          std::string temp;
+          if( host.at(0) == '[')
+          {
+            temp = str::toUpper(zypp::url::decode(host));
+          }
+          else
+          {
+            temp = str::toLower(zypp::url::decode(host));
+          }
 
-        m_data->host = zypp::url::encode(
-          data, config("safe_hostname")
-        );
+          m_data->host = zypp::url::encode(
+            temp, config("safe_hostname")
+          );
+        }
+        else
+        {
+          throw std::invalid_argument(
+            std::string("Invalid host argument '" + host + "'")
+          );
+        }
       }
     }
 
@@ -833,18 +917,31 @@ namespace zypp
       }
       else
       {
-        std::string data( zypp::url::decode(port));
-
-        checkUrlData(data, "port", config("rx_port"));
+        if( config("with_authority") != "y")
+        {
+          throw std::invalid_argument(
+            std::string("Url scheme does not allow a port")
+          );
+        }
 
-        m_data->port = data;
+        if( isValidPort(port))
+        {
+          m_data->port = port;
+        }
+        else
+        {
+          throw std::invalid_argument(
+            std::string("Invalid host argument '" + port + "'")
+          );
+        }
       }
     }
 
 
     // ---------------------------------------------------------------
     void
-    UrlBase::setPathName(const std::string &path)
+    UrlBase::setPathName(const std::string &path,
+                         EEncoding         eflag)
     {
       if( path.empty())
       {
@@ -852,9 +949,15 @@ namespace zypp
       }
       else
       {
-        std::string data( cleanupPathName(zypp::url::decode(path)));
-
-        checkUrlData(data, "path", config("rx_pathname"));
+        std::string data;
+        if(eflag == zypp::url::E_ENCODED)
+        {
+          data = cleanupPathName(zypp::url::decode(path));
+        }
+        else
+        {
+          data = cleanupPathName(path);
+        }
 
         m_data->pathname = zypp::url::encode(
           data, config("safe_pathname")
@@ -875,7 +978,6 @@ namespace zypp
       {
         checkUrlData(params, "path parameters", config("rx_pathparams"));
 
-        // FIXME: split & recode?
         m_data->pathparams = params;
       }
     }
@@ -913,12 +1015,8 @@ namespace zypp
     void
     UrlBase::setPathParam(const std::string &param, const std::string &value)
     {
-          std::string raw_param( zypp::url::decode(param));
-          std::string raw_value( zypp::url::decode(value));
-
           zypp::url::ParamMap pmap( getPathParamsMap(zypp::url::E_DECODED));
-          pmap[raw_param] = raw_value;
-
+          pmap[param] = value;
           setPathParamsMap(pmap);
     }
 
@@ -954,16 +1052,70 @@ namespace zypp
     void
     UrlBase::setQueryParam(const std::string &param, const std::string &value)
     {
-          std::string raw_param( zypp::url::decode(param));
-          std::string raw_value( zypp::url::decode(value));
-
           zypp::url::ParamMap pmap( getQueryStringMap(zypp::url::E_DECODED));
-          pmap[raw_param] = raw_value;
-
+          pmap[param] = value;
           setQueryStringMap(pmap);
     }
 
 
+    // ---------------------------------------------------------------
+    std::string
+    UrlBase::cleanupPathName(const std::string &path)
+    {
+      size_t pos = 0;
+
+      while( pos < path.length() && path.at(pos) == '/')
+        pos++;
+
+      if( pos > 1)
+      {
+        // make sure, there is not more than
+        // _one_ leading "/" in the path name.
+        return path.substr(pos - 1);
+      }
+
+      return std::string(path);
+    }
+
+
+    // ---------------------------------------------------------------
+    bool
+    UrlBase::isValidHost(const std::string &host)
+    {
+      if( str::regex_match(host, str::regex(RX_VALID_HOSTIPV6)))
+      {
+        struct in6_addr ip;
+
+        if( inet_pton(AF_INET6, host.substr(1, host.size()-2).c_str(), &ip) > 0)
+          return true;
+        else
+          return false;
+      }
+      else
+      {
+        // matches also IPv4 dotted-decimal adresses...
+        std::string tmp( zypp::url::decode(host));
+        return str::regex_match(tmp, str::regex(RX_VALID_HOSTNAME));
+      }
+    }
+
+
+    // ---------------------------------------------------------------
+    bool
+    UrlBase::isValidPort(const std::string &port)
+    {
+        if( str::regex_match(port, str::regex(RX_VALID_PORT)))
+        {
+          long pnum = str::strtonum<long>(port);
+          if( pnum >= 1 && pnum <= USHRT_MAX)
+          {
+            return true;
+          }
+        }
+        return false;
+    }
+
+
     //////////////////////////////////////////////////////////////////
   } // namespace url
   ////////////////////////////////////////////////////////////////////
index 160d109..75bb19d 100644 (file)
@@ -27,20 +27,6 @@ namespace zypp
 
     // ---------------------------------------------------------------
     /**
-     * UrlBase behaviour configuration variables container.
-     */
-    typedef std::map< std::string, std::string > UrlConfig;
-
-
-    // ---------------------------------------------------------------
-    /**
-     * Vector of URL scheme names.
-     */
-    typedef std::vector<std::string>             UrlSchemes;
-
-
-    // ---------------------------------------------------------------
-    /**
      * Url::toString() view options.
      *
      * A instance of this class represents a bit-wise combination
@@ -191,12 +177,14 @@ namespace zypp
       static const ViewOption DEFAULTS;
       /** @} */
 
+
       /**
        * Create instance with default combination of view options.
        */
       ViewOption(): opt(DEFAULTS.opt)
       {}
 
+
       /**
        * Adds \p l and \p r to a new option combination.
        *
@@ -204,7 +192,9 @@ namespace zypp
        */
       friend inline ViewOption
       operator + (const ViewOption &l, const ViewOption &r)
-      { return ViewOption(l.opt |  r.opt); }
+      {
+        return ViewOption(l.opt |  r.opt);
+      }
 
       /**
        * Substract \p r from \p l to a new option combination.
@@ -213,7 +203,9 @@ namespace zypp
        */
       friend inline ViewOption
       operator - (const ViewOption &l, const ViewOption &r)
-      { return ViewOption(l.opt & ~r.opt); }
+      {
+        return ViewOption(l.opt & ~r.opt);
+      }
 
       /**
        * Assign specified option combination \p o to the current object.
@@ -223,7 +215,9 @@ namespace zypp
        */
       inline ViewOption &
       operator = (const ViewOption &o)
-      { opt = o.opt; return *this; }
+      {
+        opt = o.opt; return *this;
+      }
 
       /**
        * Check if specified option \p o is set in the current object.
@@ -233,7 +227,9 @@ namespace zypp
        */
       inline bool
       has(const ViewOption &o) const
-      { return o.opt & opt; }
+      {
+        return o.opt & opt;
+      }
 
     private:
       ViewOption(int o): opt(o) {}
@@ -245,36 +241,21 @@ namespace zypp
     /**
      * ViewOptions is just an alias for ViewOption.
      */
-    typedef ViewOption ViewOptions;
+    typedef ViewOption                           ViewOptions;
 
 
     // ---------------------------------------------------------------
     /**
-     * Internal data as used by UrlBase.
+     * Vector of URL scheme names.
      */
-    class UrlData
-    {
-    public:
-      UrlData()
-      {}
+    typedef std::vector<std::string>             UrlSchemes;
 
-      UrlData(const UrlConfig &conf)
-        : config(conf)
-      {}
 
-      UrlConfig       config;
-      ViewOptions     vopts;
-
-      std::string     scheme;
-      std::string     user;
-      std::string     pass;
-      std::string     host;
-      std::string     port;
-      std::string     pathname;
-      std::string     pathparams;
-      std::string     querystr;
-      std::string     fragment;
-    };
+    // ---------------------------------------------------------------
+    /**
+     * Forward declaration of internal UrlBase data.
+     */
+    class UrlBaseData;
 
 
     // ---------------------------------------------------------------
@@ -290,7 +271,9 @@ namespace zypp
     {
     public:
 
-      virtual ~UrlBase();
+      virtual
+      ~UrlBase();
+
       UrlBase();
 
       /**
@@ -391,13 +374,13 @@ namespace zypp
        * schemes (see getKnownSchemes()) if the list is not empty (as
        * in the UrlBase class).
        *
+       * \param  scheme The scheme name to verify.
        * \return True, if generic scheme name syntax is valid and
        *         the scheme name is known to the current object.
        */
       virtual bool
       isValidScheme(const std::string &scheme) const;
 
-
       /**
        * \brief Verifies the Url.
        *
@@ -677,20 +660,37 @@ namespace zypp
 
       /**
        * \brief Set the username in the URL authority.
-       * \param user The new username.
+       * \param user  The new username.
+       * \param eflag If the \p username is encoded or not.
        */
       virtual void
-      setUsername(const std::string &user);
+      setUsername(const std::string &user,
+                  EEncoding         eflag);
 
       /**
        * \brief Set the password in the URL authority.
-       * \param pass The new password.
+       * \param pass  The new password.
+       * \param eflag If the \p password is encoded or not.
        */
       virtual void
-      setPassword(const std::string &pass);
+      setPassword(const std::string &pass,
+                  EEncoding         eflag);
 
       /**
        * \brief Set the hostname or IP in the URL authority.
+       *
+       * The \p host parameter may contain a hostname, an IPv4 address
+       * in dotted-decimal form or an IPv6 address literal encapsulated
+       * within square brackets (RFC3513, Sect. 2.2).
+       *
+       * A hostname may contain national alphanumeric UTF8 characters
+       * (letters other than ASCII a-z0-9), that will be encoded.
+       * This function allows to specify both, a encoded or decoded
+       * hostname.
+       *
+       * Other IP literals in "[v ... ]" square bracket format are not
+       * supported by the implementation in UrlBase class.
+       *
        * \param host The new hostname or IP.
        */
       virtual void
@@ -708,8 +708,8 @@ namespace zypp
       /**
        * \brief Set the path data component in the URL.
        *
-       * The \p pathdata string may include path parameters
-       * separated using the ";" separator character.
+       * By default, the \p pathdata string may include path
+       * parameters separated by the ";" separator character.
        *
        * \param pathdata The encoded path data component string.
        */
@@ -718,36 +718,38 @@ namespace zypp
 
       /**
        * \brief Set the path name.
-       * \param path The new path name.
+       * \param path  The new path name.
+       * \param eflag If the \p path name is encoded or not.
        */
       virtual void
-      setPathName(const std::string &path);
+      setPathName(const std::string &path,
+                  EEncoding         eflag);
 
       /**
        * \brief Set the path parameters.
-       * \param params The new path parameter string.
+       * \param params The new encoded path parameter string.
        */
       virtual void
       setPathParams(const std::string &params);
 
       /**
        * \brief Set the path parameters.
-       * \param pvec The vector with path parameters.
+       * \param pvec The vector with encoded path parameters.
        */
       virtual void
       setPathParamsVec(const zypp::url::ParamVec &pvec);
 
       /**
        * \brief Set the path parameters.
-       * \param pmap The map with path parameters.
+       * \param pmap The map with decoded path parameters.
        */
       virtual void
       setPathParamsMap(const zypp::url::ParamMap &pmap);
 
       /**
        * \brief Set or add value for the specified path parameter.
-       * \param param The path parameter name.
-       * \param value The path parameter value.
+       * \param param The decoded path parameter name.
+       * \param value The decoded path parameter value.
        */
       virtual void
       setPathParam(const std::string &param, const std::string &value);
@@ -757,9 +759,6 @@ namespace zypp
       /**
        * \brief Set the query string in the URL.
        *
-       * The \p querystr string will be supposed to not to
-       * contain the "?" separator character.
-       *
        * \param querystr The new encoded query string.
        */
       virtual void
@@ -767,22 +766,22 @@ namespace zypp
 
       /**
        * \brief Set the query parameters.
-       * \param qvec The vector with query parameters.
+       * \param qvec The vector with encoded query parameters.
        */
       virtual void
       setQueryStringVec(const zypp::url::ParamVec &qvec);
 
       /**
        * \brief Set the query parameters.
-       * \param qmap The map with query parameters.
+       * \param qmap The map with decoded query parameters.
        */
       virtual void
       setQueryStringMap(const zypp::url::ParamMap &qmap);
 
       /**
        * \brief Set or add value for the specified query parameter.
-       * \param param The query parameter name.
-       * \param value The query parameter value.
+       * \param param The decoded query parameter name.
+       * \param value The decoded query parameter value.
        */
       virtual void
       setQueryParam(const std::string &param, const std::string &value);
@@ -791,10 +790,12 @@ namespace zypp
       // -----------------
       /**
        * \brief Set the fragment string in the URL.
-       * \param fragment The new encoded fragment string.
+       * \param fragment The new fragment string.
+       * \param eflag If the \p fragment is encoded or not.
        */
       virtual void
-      setFragment(const std::string &fragment);
+      setFragment(const std::string &fragment,
+                  EEncoding         eflag);
 
 
       // -----------------
@@ -809,7 +810,7 @@ namespace zypp
        *
        * The UrlBase class uses following config variables:
        *
-       * - Path parameter separators:
+       * - Common path parameter separators:
        *   - \a \c sep_pathparams   \c ";"
        *     Separator used to split path parameters from path name.
        *   - \a \c psep_pathparam   \c ","
@@ -819,7 +820,7 @@ namespace zypp
        *   .
        * .
        *
-       * - Query string separators:
+       * - Common query string separators:
        *   - \a \c psep_querystr    \c "&"
        *     Separator between query string parameters.
        *   - \a \c vsep_querystr    \c "="
@@ -829,27 +830,24 @@ namespace zypp
        *
        * - Characters in URL components, that are safe without
        *   URL percent-encoding (see zypp::url::encode()).
-       *   - \a safe_username    ""
-       *   - \a safe_password    ""
-       *   - \a safe_hostname    "[:]"
-       *   - \a safe_pathname    "/"
-       *   - \a safe_pathparams  ""
-       *   - \a safe_querystr    ""
-       *   - \a safe_fragment    ""
+       *   - \a safe_username
+       *   - \a safe_password
+       *   - \a safe_hostname
+       *   - \a safe_pathname
+       *   - \a safe_pathparams
+       *   - \a safe_querystr
+       *   - \a safe_fragment
        *   .
        * .
        *
-       * - Regular expressions used to verify URL components
-       *   and their sub-components:
-       *   - \a rx_scheme        "^[a-zA-Z][a-zA-Z0-9\\._-]*$"
-       *   - \a rx_username      ".*"
-       *   - \a rx_password      ".*"
-       *   - \a rx_hostname      ".*" FIXME!
-       *   - \a rx_port          "^[0-9]{1,5}$"
-       *   - \a rx_pathname      ".*"
-       *   - \a rx_pathparams    ".*"
-       *   - \a rx_querystr      ".*"
-       *   - \a rx_fragment      ".*"
+       * - Regular expressions used to verify encoded URL
+       *   components and their sub-components:
+       *   - \a rx_username
+       *   - \a rx_password
+       *   - \a rx_pathname
+       *   - \a rx_pathparams
+       *   - \a rx_querystr
+       *   - \a rx_fragment
        *   .
        * .
        */
@@ -920,15 +918,35 @@ namespace zypp
        * missinterpret multiple "/" occurences as an empty
        * URL authority.
        *
-       * \param path A path name.
+       * \param path   A path name to cleanup.
        * \return A path begining with at most one "/" character.
        */
       virtual std::string
       cleanupPathName(const std::string &path);
 
+      /**
+       * \brief Verifies specified host or IP.
+       *
+       * This function does not perform any hostname lookups and
+       * supports only IPv6 addresses in "[ ... ]" notation.
+       *
+       * \param  host  The host name or IP to verify.
+       * \return True, if host seems to be valid.
+       */
+      virtual bool
+      isValidHost(const std::string &host);
+
+      /**
+       * \brief Verifies specified port number.
+       *
+       * \param  port  The port number to verify.
+       * \return True, if port number is valid.
+       */
+      virtual bool
+      isValidPort(const std::string &port);
 
     private:
-      UrlData        *m_data;
+      UrlBaseData *m_data;
     };