Blame SOURCES/wget-1.14-CVE-2016-4971.patch

226bdc
diff --git a/src/ftp.c b/src/ftp.c
226bdc
index 2be2c76..345718f 100644
226bdc
--- a/src/ftp.c
226bdc
+++ b/src/ftp.c
226bdc
@@ -234,14 +234,15 @@ print_length (wgint size, wgint start, bool authoritative)
226bdc
   logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
226bdc
 }
226bdc
 
226bdc
-static uerr_t ftp_get_listing (struct url *, ccon *, struct fileinfo **);
226bdc
+static uerr_t ftp_get_listing (struct url *, struct url *, ccon *, struct fileinfo **);
226bdc
 
226bdc
 /* Retrieves a file with denoted parameters through opening an FTP
226bdc
    connection to the server.  It always closes the data connection,
226bdc
    and closes the control connection in case of error.  If warc_tmp
226bdc
    is non-NULL, the downloaded data will be written there as well.  */
226bdc
 static uerr_t
226bdc
-getftp (struct url *u, wgint passed_expected_bytes, wgint *qtyread,
226bdc
+getftp (struct url *u, struct url *original_url,
226bdc
+        wgint passed_expected_bytes, wgint *qtyread,
226bdc
         wgint restval, ccon *con, int count, FILE *warc_tmp)
226bdc
 {
226bdc
   int csock, dtsock, local_sock, res;
226bdc
@@ -944,7 +945,7 @@ Error in server response, closing control connection.\n"));
226bdc
 	  bool exists = false;
226bdc
 	  uerr_t res;
226bdc
 	  struct fileinfo *f;
226bdc
-	  res = ftp_get_listing (u, con, &f);
226bdc
+	  res = ftp_get_listing (u, original_url, con, &f);
226bdc
 	  /* Set the DO_RETR command flag again, because it gets unset when
226bdc
 	     calling ftp_get_listing() and would otherwise cause an assertion
226bdc
 	     failure earlier on when this function gets repeatedly called
226bdc
@@ -1392,7 +1393,8 @@ Error in server response, closing control connection.\n"));
226bdc
    This loop either gets commands from con, or (if ON_YOUR_OWN is
226bdc
    set), makes them up to retrieve the file given by the URL.  */
226bdc
 static uerr_t
226bdc
-ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file)
226bdc
+ftp_loop_internal (struct url *u, struct url *original_url, struct fileinfo *f,
226bdc
+        ccon *con, char **local_file)
226bdc
 {
226bdc
   int count, orig_lp;
226bdc
   wgint restval, len = 0, qtyread = 0;
226bdc
@@ -1415,7 +1417,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
226bdc
   else
226bdc
     {
226bdc
       /* URL-derived file.  Consider "-O file" name. */
226bdc
-      con->target = url_file_name (u, NULL);
226bdc
+      con->target = url_file_name (opt.trustservernames || !original_url ? u : original_url, NULL);
226bdc
       if (!opt.output_document)
226bdc
         locf = con->target;
226bdc
       else
226bdc
@@ -1524,7 +1526,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
226bdc
 
226bdc
       /* If we are working on a WARC record, getftp should also write
226bdc
          to the warc_tmp file. */
226bdc
-      err = getftp (u, len, &qtyread, restval, con, count, warc_tmp);
226bdc
+      err = getftp (u, original_url, len, &qtyread, restval, con, count, warc_tmp);
226bdc
 
226bdc
       if (con->csock == -1)
226bdc
         con->st &= ~DONE_CWD;
226bdc
@@ -1677,7 +1679,8 @@ Removing file due to --delete-after in ftp_loop_internal():\n"));
226bdc
 /* Return the directory listing in a reusable format.  The directory
226bdc
    is specifed in u->dir.  */
226bdc
 static uerr_t
226bdc
-ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
226bdc
+ftp_get_listing (struct url *u, struct url *original_url, ccon *con,
226bdc
+                 struct fileinfo **f)
226bdc
 {
226bdc
   uerr_t err;
226bdc
   char *uf;                     /* url file name */
226bdc
@@ -1698,7 +1701,7 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
226bdc
 
226bdc
   con->target = xstrdup (lf);
226bdc
   xfree (lf);
226bdc
-  err = ftp_loop_internal (u, NULL, con, NULL);
226bdc
+  err = ftp_loop_internal (u, original_url, NULL, con, NULL);
226bdc
   lf = xstrdup (con->target);
226bdc
   xfree (con->target);
226bdc
   con->target = old_target;
226bdc
@@ -1721,8 +1724,9 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
226bdc
   return err;
226bdc
 }
226bdc
 
226bdc
-static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *);
226bdc
-static uerr_t ftp_retrieve_glob (struct url *, ccon *, int);
226bdc
+static uerr_t ftp_retrieve_dirs (struct url *, struct url *,
226bdc
+                                 struct fileinfo *, ccon *);
226bdc
+static uerr_t ftp_retrieve_glob (struct url *, struct url *, ccon *, int);
226bdc
 static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **);
226bdc
 static void freefileinfo (struct fileinfo *f);
226bdc
 
226bdc
@@ -1734,7 +1738,8 @@ static void freefileinfo (struct fileinfo *f);
226bdc
    If opt.recursive is set, after all files have been retrieved,
226bdc
    ftp_retrieve_dirs will be called to retrieve the directories.  */
226bdc
 static uerr_t
226bdc
-ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con)
226bdc
+ftp_retrieve_list (struct url *u, struct url *original_url,
226bdc
+                   struct fileinfo *f, ccon *con)
226bdc
 {
226bdc
   static int depth = 0;
226bdc
   uerr_t err;
226bdc
@@ -1893,7 +1898,9 @@ Already have correct symlink %s -> %s\n\n"),
226bdc
           else                /* opt.retr_symlinks */
226bdc
             {
226bdc
               if (dlthis)
226bdc
-                err = ftp_loop_internal (u, f, con, NULL);
226bdc
+                {
226bdc
+                  err = ftp_loop_internal (u, original_url, f, con, NULL);
226bdc
+                }
226bdc
             } /* opt.retr_symlinks */
226bdc
           break;
226bdc
         case FT_DIRECTORY:
226bdc
@@ -1904,7 +1911,9 @@ Already have correct symlink %s -> %s\n\n"),
226bdc
         case FT_PLAINFILE:
226bdc
           /* Call the retrieve loop.  */
226bdc
           if (dlthis)
226bdc
-            err = ftp_loop_internal (u, f, con, NULL);
226bdc
+            {
226bdc
+              err = ftp_loop_internal (u, original_url, f, con, NULL);
226bdc
+            }
226bdc
           break;
226bdc
         case FT_UNKNOWN:
226bdc
           logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
226bdc
@@ -1969,7 +1978,7 @@ Already have correct symlink %s -> %s\n\n"),
226bdc
   /* We do not want to call ftp_retrieve_dirs here */
226bdc
   if (opt.recursive &&
226bdc
       !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
226bdc
-    err = ftp_retrieve_dirs (u, orig, con);
226bdc
+    err = ftp_retrieve_dirs (u, original_url, orig, con);
226bdc
   else if (opt.recursive)
226bdc
     DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
226bdc
              depth, opt.reclevel));
226bdc
@@ -1982,7 +1991,8 @@ Already have correct symlink %s -> %s\n\n"),
226bdc
    ftp_retrieve_glob on each directory entry.  The function knows
226bdc
    about excluded directories.  */
226bdc
 static uerr_t
226bdc
-ftp_retrieve_dirs (struct url *u, struct fileinfo *f, ccon *con)
226bdc
+ftp_retrieve_dirs (struct url *u, struct url *original_url,
226bdc
+                   struct fileinfo *f, ccon *con)
226bdc
 {
226bdc
   char *container = NULL;
226bdc
   int container_size = 0;
226bdc
@@ -2032,7 +2042,7 @@ Not descending to %s as it is excluded/not-included.\n"),
226bdc
       odir = xstrdup (u->dir);  /* because url_set_dir will free
226bdc
                                    u->dir. */
226bdc
       url_set_dir (u, newdir);
226bdc
-      ftp_retrieve_glob (u, con, GLOB_GETALL);
226bdc
+      ftp_retrieve_glob (u, original_url, con, GLOB_GETALL);
226bdc
       url_set_dir (u, odir);
226bdc
       xfree (odir);
226bdc
 
226bdc
@@ -2091,14 +2101,15 @@ is_invalid_entry (struct fileinfo *f)
226bdc
    GLOB_GLOBALL, use globbing; if it's GLOB_GETALL, download the whole
226bdc
    directory.  */
226bdc
 static uerr_t
226bdc
-ftp_retrieve_glob (struct url *u, ccon *con, int action)
226bdc
+ftp_retrieve_glob (struct url *u, struct url *original_url,
226bdc
+                   ccon *con, int action)
226bdc
 {
226bdc
   struct fileinfo *f, *start;
226bdc
   uerr_t res;
226bdc
 
226bdc
   con->cmd |= LEAVE_PENDING;
226bdc
 
226bdc
-  res = ftp_get_listing (u, con, &start;;
226bdc
+  res = ftp_get_listing (u, original_url, con, &start;;
226bdc
   if (res != RETROK)
226bdc
     return res;
226bdc
   /* First: weed out that do not conform the global rules given in
226bdc
@@ -2194,7 +2205,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
226bdc
   if (start)
226bdc
     {
226bdc
       /* Just get everything.  */
226bdc
-      res = ftp_retrieve_list (u, start, con);
226bdc
+      res = ftp_retrieve_list (u, original_url, start, con);
226bdc
     }
226bdc
   else
226bdc
     {
226bdc
@@ -2210,7 +2221,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
226bdc
         {
226bdc
           /* Let's try retrieving it anyway.  */
226bdc
           con->st |= ON_YOUR_OWN;
226bdc
-          res = ftp_loop_internal (u, NULL, con, NULL);
226bdc
+          res = ftp_loop_internal (u, original_url, NULL, con, NULL);
226bdc
           return res;
226bdc
         }
226bdc
 
226bdc
@@ -2230,8 +2241,8 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
226bdc
    of URL.  Inherently, its capabilities are limited on what can be
226bdc
    encoded into a URL.  */
226bdc
 uerr_t
226bdc
-ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
226bdc
-          bool recursive, bool glob)
226bdc
+ftp_loop (struct url *u, struct url *original_url, char **local_file, int *dt,
226bdc
+          struct url *proxy, bool recursive, bool glob)
226bdc
 {
226bdc
   ccon con;                     /* FTP connection */
226bdc
   uerr_t res;
226bdc
@@ -2252,16 +2263,17 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
226bdc
   if (!*u->file && !recursive)
226bdc
     {
226bdc
       struct fileinfo *f;
226bdc
-      res = ftp_get_listing (u, &con, &f);
226bdc
+      res = ftp_get_listing (u, original_url, &con, &f);
226bdc
 
226bdc
       if (res == RETROK)
226bdc
         {
226bdc
           if (opt.htmlify && !opt.spider)
226bdc
             {
226bdc
+              struct url *url_file = opt.trustservernames ? u : original_url;
226bdc
               char *filename = (opt.output_document
226bdc
                                 ? xstrdup (opt.output_document)
226bdc
                                 : (con.target ? xstrdup (con.target)
226bdc
-                                   : url_file_name (u, NULL)));
226bdc
+                                   : url_file_name (url_file, NULL)));
226bdc
               res = ftp_index (filename, u, f);
226bdc
               if (res == FTPOK && opt.verbose)
226bdc
                 {
226bdc
@@ -2306,11 +2318,13 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
226bdc
           /* ftp_retrieve_glob is a catch-all function that gets called
226bdc
              if we need globbing, time-stamping, recursion or preserve
226bdc
              permissions.  Its third argument is just what we really need.  */
226bdc
-          res = ftp_retrieve_glob (u, &con,
226bdc
+          res = ftp_retrieve_glob (u, original_url, &con,
226bdc
                                    ispattern ? GLOB_GLOBALL : GLOB_GETONE);
226bdc
         }
226bdc
       else
226bdc
-        res = ftp_loop_internal (u, NULL, &con, local_file);
226bdc
+        {
226bdc
+          res = ftp_loop_internal (u, original_url, NULL, &con, local_file);
226bdc
+        }
226bdc
     }
226bdc
   if (res == FTPOK)
226bdc
     res = RETROK;
226bdc
diff --git a/src/ftp.h b/src/ftp.h
226bdc
index be00d88..2abc9c0 100644
226bdc
--- a/src/ftp.h
226bdc
+++ b/src/ftp.h
226bdc
@@ -129,7 +129,8 @@ enum wget_ftp_fstatus
226bdc
 };
226bdc
 
226bdc
 struct fileinfo *ftp_parse_ls (const char *, const enum stype);
226bdc
-uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool);
226bdc
+uerr_t ftp_loop (struct url *, struct url *, char **, int *, struct url *,
226bdc
+                 bool, bool);
226bdc
 
226bdc
 uerr_t ftp_index (const char *, struct url *, struct fileinfo *);
226bdc
 
226bdc
diff --git a/src/retr.c b/src/retr.c
226bdc
index 66624dc..21fad56 100644
226bdc
--- a/src/retr.c
226bdc
+++ b/src/retr.c
226bdc
@@ -794,7 +794,8 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
226bdc
       if (redirection_count)
226bdc
         oldrec = glob = false;
226bdc
 
226bdc
-      result = ftp_loop (u, &local_file, dt, proxy_url, recursive, glob);
226bdc
+      result = ftp_loop (u, orig_parsed, &local_file, dt, proxy_url,
226bdc
+                         recursive, glob);
226bdc
       recursive = oldrec;
226bdc
 
226bdc
       /* There is a possibility of having HTTP being redirected to