]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fox off-by-1 errors in new FTP login parse
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 17 Aug 2009 12:40:10 +0000 (00:40 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 17 Aug 2009 12:40:10 +0000 (00:40 +1200)
src/ftp.cc

index d18098fc975b89801b6333edda1e3312f1a58e79..ac52cce2d440653290df1b311d0865c143fa8edc 100644 (file)
@@ -534,9 +534,10 @@ FtpStateData::~FtpStateData()
 void
 FtpStateData::loginParser(const char *login, int escaped)
 {
-    const char *u = NULL;
-    const char *p = NULL;
-    int len;
+    const char *u = NULL; // end of the username sub-string
+    int len;              // length of the current sub-string to handle.
+
+    int total_len = strlen(login);
 
     debugs(9, 4, HERE << ": login='" << login << "', escaped=" << escaped);
     debugs(9, 9, HERE << ": IN : login='" << login << "', escaped=" << escaped << ", user=" << user << ", password=" << password);
@@ -546,35 +547,38 @@ FtpStateData::loginParser(const char *login, int escaped)
         /* if there was a username part */
         if (u > login) {
             len = u - login;
+            ++u; // jump off the delimiter.
             if (len > MAX_URL)
-                len = MAX_URL;
-            xstrncpy(user, login, len);
-            user[len] = '\0';
+                len = MAX_URL-1;
+            xstrncpy(user, login, len +1);
+            debugs(9, 9, HERE << ": found user='" << user << "'(" << len <<"), escaped=" << escaped);
             if (escaped)
                 rfc1738_unescape(user);
+            debugs(9, 9, HERE << ": found user='" << user << "'(" << len <<") unescaped.");
         }
 
         /* if there was a password part */
-        p = strchr(u, '@');
-        if ( p > u ) {
-            len = p - u;
-            xstrncpy(password, u + 1, len);
-            password[len] = '\0';
+        len = login + total_len - u;
+        if ( len > 0) {
+            if (len > MAX_URL)
+                len = MAX_URL -1;
+            xstrncpy(password, u, len +1);
+            debugs(9, 9, HERE << ": found password='" << password << "'(" << len <<"), escaped=" << escaped);
             if (escaped) {
                 rfc1738_unescape(password);
                 password_url = 1;
             }
+            debugs(9, 9, HERE << ": found password='" << password << "'(" << len <<") unescaped.");
         }
     } else if (login[0]) {
         /* no password, just username */
-        u = strchr(login, '@');
-        len = u - login;
-        if (len > MAX_URL)
-            len = MAX_URL;
-        xstrncpy(user, login, len);
-        user[len] = '\0';
+        if (total_len > MAX_URL)
+            total_len = MAX_URL -1;
+        xstrncpy(user, login, total_len +1);
+        debugs(9, 9, HERE << ": found user='" << user << "'(" << total_len <<"), escaped=" << escaped);
         if (escaped)
             rfc1738_unescape(user);
+        debugs(9, 9, HERE << ": found user='" << user << "'(" << total_len <<") unescaped.");
     }
 
     debugs(9, 9, HERE << ": OUT: login='" << login << "', escaped=" << escaped << ", user=" << user << ", password=" << password);