]> sjero.net Git - wget/commitdiff
[svn] Fix fragments crash. Support fragments for FTP URLs.
authorhniksic <devnull@localhost>
Sat, 2 Jul 2005 02:51:38 +0000 (19:51 -0700)
committerhniksic <devnull@localhost>
Sat, 2 Jul 2005 02:51:38 +0000 (19:51 -0700)
src/ChangeLog
src/url.c

index 7e6765db651bfad5359f1b21eeeb51cc84ede991..d533f2d7df26ee4ecbe3a33bfd96d286d89f49e5 100644 (file)
@@ -1,3 +1,8 @@
+2005-07-02  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * url.c (url_parse): Would crash when parsing fragments.  Support
+       fragments for FTP URLs too.
+
 2005-07-02  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * version.c: Don't use "cvs" in version name, since we're not
index 726965263a62bd5f0349c9a7dfd31288d971f3f3..9e3b346811ccb88d136ea647f8466bcb153cab35 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -43,6 +43,13 @@ so, delete this exception statement from your version.  */
 #include "url.h"
 #include "host.h"  /* for is_valid_ipv6_address */
 
+enum {
+  scm_disabled = 1,            /* for https when OpenSSL fails to init. */
+  scm_has_params = 2,          /* whether scheme has ;params */
+  scm_has_query = 4,           /* whether scheme has ?query */
+  scm_has_fragment = 8         /* whether scheme has #fragment */
+};
+
 struct scheme_data
 {
   /* Short name of the scheme, such as "http" or "ftp". */
@@ -51,23 +58,18 @@ struct scheme_data
   const char *leading_string;
   /* Default port of the scheme when none is specified. */
   int default_port;
-  /* Used for disabling https when OpenSSL fails to init. */
-  bool disabled;
-  /* Allowed separators, handled by url_parse.  For example, ftp
-     doesn't support the "?query", and http/https don't support
-     ";params".  All schemes must support at least "/:".  */
-  const char *separators;
+  /* Various flags. */
   int flags;
 };
 
 /* Supported schemes: */
 static struct scheme_data supported_schemes[] =
 {
-  { "http",    "http://",  DEFAULT_HTTP_PORT,  false, "/:?#" },
+  { "http",    "http://",  DEFAULT_HTTP_PORT,  scm_has_query|scm_has_fragment },
 #ifdef HAVE_SSL
-  { "https",   "https://", DEFAULT_HTTPS_PORT, false, "/:?#" },
+  { "https",   "https://", DEFAULT_HTTPS_PORT, scm_has_query|scm_has_fragment },
 #endif
-  { "ftp",     "ftp://",   DEFAULT_FTP_PORT,   false, "/:;#" },
+  { "ftp",     "ftp://",   DEFAULT_FTP_PORT,   scm_has_params|scm_has_fragment },
 
   /* SCHEME_INVALID */
   { NULL,      NULL,       -1,                 0 }
@@ -413,7 +415,7 @@ url_scheme (const char *url)
     if (0 == strncasecmp (url, supported_schemes[i].leading_string,
                          strlen (supported_schemes[i].leading_string)))
       {
-       if (!(supported_schemes[i].disabled))
+       if (!(supported_schemes[i].flags & scm_disabled))
          return (enum url_scheme) i;
        else
          return SCHEME_INVALID;
@@ -453,7 +455,7 @@ scheme_default_port (enum url_scheme scheme)
 void
 scheme_disable (enum url_scheme scheme)
 {
-  supported_schemes[scheme].disabled = true;
+  supported_schemes[scheme].flags |= scm_disabled;
 }
 
 /* Skip the username and password, if present in the URL.  The
@@ -621,6 +623,23 @@ lowercase_str (char *str)
   return changed;
 }
 
+static const char *
+init_seps (enum url_scheme scheme)
+{
+  static char seps[8] = ":/";
+  char *p = seps + 2;
+  int flags = supported_schemes[scheme].flags;
+
+  if (flags & scm_has_params)
+    *p++ = ';';
+  if (flags & scm_has_query)
+    *p++ = '?';
+  if (flags & scm_has_fragment)
+    *p++ = '#';
+  *p++ = '\0';
+  return seps;
+}
+
 static const char *parse_errors[] = {
 #define PE_NO_ERROR                    0
   N_("No error"),
@@ -700,7 +719,7 @@ url_parse (const char *url, int *error)
   /* Initialize separators for optional parts of URL, depending on the
      scheme.  For example, FTP has params, and HTTP and HTTPS have
      query string and fragment. */
-  seps = supported_schemes[scheme].separators;
+  seps = init_seps (scheme);
 
   host_b = p;
 
@@ -805,9 +824,12 @@ url_parse (const char *url, int *error)
 } while (0)
 
   GET_URL_PART ('/', path);
-  GET_URL_PART (';', params);
-  GET_URL_PART ('?', query);
-  GET_URL_PART ('#', fragment);
+  if (supported_schemes[scheme].flags & scm_has_params)
+    GET_URL_PART (';', params);
+  if (supported_schemes[scheme].flags & scm_has_query)
+    GET_URL_PART ('?', query);
+  if (supported_schemes[scheme].flags & scm_has_fragment)
+    GET_URL_PART ('#', fragment);
 
 #undef GET_URL_PART
   assert (*p == 0);