]> sjero.net Git - wget/blobdiff - src/url.c
Use Gnulib's alloc functions throughout the source.
[wget] / src / url.c
index 650c634736ed41c034f1b3bd16bd6365fad7dbc9..997b1058c111a726fb21923bf562ee28fc3c548a 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -1,5 +1,6 @@
 /* URL handling.
-   Copyright (C) 1996-2006 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+   2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Wget.
 
@@ -16,17 +17,20 @@ GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
-In addition, as a special exception, the Free Software Foundation
-gives permission to link the code of its release of Wget with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables.  You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL".  If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so.  If you do not wish to do
-so, delete this exception statement from your version.  */
+Additional permission under GNU GPL version 3 section 7
 
-#include <config.h>
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work.  */
+
+#define USE_GNULIB_ALLOC
+
+#include "wget.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -37,7 +41,6 @@ so, delete this exception statement from your version.  */
 #include <errno.h>
 #include <assert.h>
 
-#include "wget.h"
 #include "utils.h"
 #include "url.h"
 #include "host.h"  /* for is_valid_ipv6_address */
@@ -182,7 +185,7 @@ url_unescape (char *s)
         {
           char c;
           /* Do nothing if '%' is not followed by two hex digits. */
-          if (!h[1] || !h[2] || !(ISXDIGIT (h[1]) && ISXDIGIT (h[2])))
+          if (!h[1] || !h[2] || !(c_isxdigit (h[1]) && c_isxdigit (h[2])))
             goto copychar;
           c = X2DIGITS_TO_NUM (h[1], h[2]);
           /* Don't unescape %00 because there is no way to insert it
@@ -271,7 +274,7 @@ char_needs_escaping (const char *p)
 {
   if (*p == '%')
     {
-      if (ISXDIGIT (*(p + 1)) && ISXDIGIT (*(p + 2)))
+      if (c_isxdigit (*(p + 1)) && c_isxdigit (*(p + 2)))
         return false;
       else
         /* Garbled %.. sequence: encode `%'. */
@@ -427,7 +430,7 @@ url_scheme (const char *url)
   return SCHEME_INVALID;
 }
 
-#define SCHEME_CHAR(ch) (ISALNUM (ch) || (ch) == '-' || (ch) == '+')
+#define SCHEME_CHAR(ch) (c_isalnum (ch) || (ch) == '-' || (ch) == '+')
 
 /* Return 1 if the URL begins with any "scheme", 0 otherwise.  As
    currently implemented, it returns true if URL begins with
@@ -589,10 +592,10 @@ lowercase_str (char *str)
 {
   bool changed = false;
   for (; *str; str++)
-    if (ISUPPER (*str))
+    if (c_isupper (*str))
       {
         changed = true;
-        *str = TOLOWER (*str);
+        *str = c_tolower (*str);
       }
   return changed;
 }
@@ -768,7 +771,7 @@ url_parse (const char *url, int *error)
       if (port_b != port_e)
         for (port = 0, pp = port_b; pp < port_e; pp++)
           {
-            if (!ISDIGIT (*pp))
+            if (!c_isdigit (*pp))
               {
                 /* http://host:12randomgarbage/blah */
                 /*               ^                  */
@@ -855,7 +858,7 @@ url_parse (const char *url, int *error)
       /* If we suspect that a transformation has rendered what
          url_string might return different from URL_ENCODED, rebuild
          u->url using url_string.  */
-      u->url = url_string (u, false);
+      u->url = url_string (u, URL_AUTH_SHOW);
 
       if (url_encoded != url)
         xfree ((char *) url_encoded);
@@ -1071,7 +1074,7 @@ sync_path (struct url *u)
 
   /* Regenerate u->url as well.  */
   xfree (u->url);
-  u->url = url_string (u, false);
+  u->url = url_string (u, URL_AUTH_SHOW);
 }
 
 /* Mutators.  Code in ftp.c insists on changing u->dir and u->file.
@@ -1369,12 +1372,12 @@ append_uri_pathel (const char *b, const char *e, bool escaped,
       || opt.restrict_files_case == restrict_uppercase)
     {
       char *q;
-      for (q = TAIL (dest); *q; ++q)
+      for (q = TAIL (dest); q < TAIL (dest) + outlen; ++q)
         {
           if (opt.restrict_files_case == restrict_lowercase)
-            *q = TOLOWER (*q);
+            *q = c_tolower (*q);
           else
-            *q = TOUPPER (*q);
+            *q = c_toupper (*q);
         }
     }
           
@@ -1814,7 +1817,7 @@ uri_merge (const char *base, const char *link)
    the URL will be quoted.  */
 
 char *
-url_string (const struct url *url, bool hide_password)
+url_string (const struct url *url, enum url_auth_mode auth_mode)
 {
   int size;
   char *result, *p;
@@ -1831,13 +1834,16 @@ url_string (const struct url *url, bool hide_password)
   /* Make sure the user name and password are quoted. */
   if (url->user)
     {
-      quoted_user = url_escape_allow_passthrough (url->user);
-      if (url->passwd)
+      if (auth_mode != URL_AUTH_HIDE)
         {
-          if (hide_password)
-            quoted_passwd = HIDDEN_PASSWORD;
-          else
-            quoted_passwd = url_escape_allow_passthrough (url->passwd);
+          quoted_user = url_escape_allow_passthrough (url->user);
+          if (url->passwd)
+            {
+              if (auth_mode == URL_AUTH_HIDE_PASSWD)
+                quoted_passwd = HIDDEN_PASSWORD;
+              else
+                quoted_passwd = url_escape_allow_passthrough (url->passwd);
+            }
         }
     }
 
@@ -1899,7 +1905,8 @@ url_string (const struct url *url, bool hide_password)
 
   if (quoted_user && quoted_user != url->user)
     xfree (quoted_user);
-  if (quoted_passwd && !hide_password && quoted_passwd != url->passwd)
+  if (quoted_passwd && auth_mode == URL_AUTH_SHOW
+      && quoted_passwd != url->passwd)
     xfree (quoted_passwd);
   if (quoted_host != url->host)
     xfree (quoted_host);
@@ -1935,10 +1942,7 @@ getchar_from_escaped_string (const char *str, char *c)
   
   if (p[0] == '%')
     {
-      if (p[1] == 0)
-        return 0; /* error: invalid string */
-
-      if (p[1] == '%')
+      if (!c_isxdigit(p[1]) || !c_isxdigit(p[2]))
         {
           *c = '%';
           return 1;
@@ -1949,8 +1953,13 @@ getchar_from_escaped_string (const char *str, char *c)
             return 0; /* error: invalid string */
 
           *c = X2DIGITS_TO_NUM (p[1], p[2]);
-
-          return 3;
+          if (URL_RESERVED_CHAR(*c))
+            {
+              *c = '%';
+              return 1;
+            }
+          else
+            return 3;
         }
     }
   else
@@ -1967,14 +1976,15 @@ are_urls_equal (const char *u1, const char *u2)
   const char *p, *q;
   int pp, qq;
   char ch1, ch2;
+  assert(u1 && u2);
 
   p = u1;
   q = u2;
 
-  while (*p 
+  while (*p && *q
          && (pp = getchar_from_escaped_string (p, &ch1))
          && (qq = getchar_from_escaped_string (q, &ch2))
-         && (TOLOWER(ch1) == TOLOWER(ch2)))
+         && (c_tolower(ch1) == c_tolower(ch2)))
     {
       p += pp;
       q += qq;
@@ -2085,6 +2095,7 @@ test_append_uri_pathel()
       
       append_string (test_array[i].original_url, &dest);
       append_uri_pathel (p, p + strlen(p), test_array[i].escaped, &dest);
+      append_char ('\0', &dest);
 
       mu_assert ("test_append_uri_pathel: wrong result", 
                  strcmp (dest.base, test_array[i].expected_result) == 0);
@@ -2106,6 +2117,8 @@ test_are_urls_equal()
     { "http://www.adomain.com/apath/", "http://www.adomain.com/anotherpath/", false },
     { "http://www.adomain.com/apath/", "http://www.anotherdomain.com/path/",  false },
     { "http://www.adomain.com/~path/", "http://www.adomain.com/%7epath/",     true },
+    { "http://www.adomain.com/longer-path/", "http://www.adomain.com/path/",  false },
+    { "http://www.adomain.com/path%2f", "http://www.adomain.com/path/",       false },
   };
   
   for (i = 0; i < sizeof(test_array)/sizeof(test_array[0]); ++i)