]> sjero.net Git - wget/commitdiff
[svn] base64_encode could read past the end of STR.
authorhniksic <devnull@localhost>
Mon, 19 Jun 2006 20:35:53 +0000 (13:35 -0700)
committerhniksic <devnull@localhost>
Mon, 19 Jun 2006 20:35:53 +0000 (13:35 -0700)
src/ChangeLog
src/utils.c

index ab09fb6270b73bd3587f057a29b668869cc1e362..d7cfd22027b10fe3c39b1da4aea35a589fba4c20 100644 (file)
@@ -1,3 +1,8 @@
+2006-06-19  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * utils.c (base64_encode): Would read past end of STR.
+       Reported by rick@eckle.org.
+
 2006-06-13  Mauro Tortonesi  <mauro@ferrara.linux.it>
 
        * options.h (struct options): Introduced member restrict_files_case to
index 723103415fa80f38117b6931ec2355e6b2a6476a..0a2fc9f977549ad3e5127321f7af371e25ec3679 100644 (file)
@@ -1912,26 +1912,35 @@ base64_encode (const char *str, int length, char *b64store)
     'w','x','y','z','0','1','2','3',
     '4','5','6','7','8','9','+','/'
   };
-  int i;
   const unsigned char *s = (const unsigned char *) str;
+  const unsigned char *end = (const unsigned char *) str + length - 2;
   char *p = b64store;
 
   /* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
-  for (i = 0; i < length; i += 3)
+  for (; s < end; s += 3)
     {
       *p++ = tbl[s[0] >> 2];
       *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
       *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
       *p++ = tbl[s[2] & 0x3f];
-      s += 3;
     }
 
   /* Pad the result if necessary...  */
-  if (i == length + 1)
-    *(p - 1) = '=';
-  else if (i == length + 2)
-    *(p - 1) = *(p - 2) = '=';
-
+  switch (length % 3)
+    {
+    case 1:
+      *p++ = tbl[s[0] >> 2];
+      *p++ = tbl[(s[0] & 3) << 4];
+      *p++ = '=';
+      *p++ = '=';
+      break;
+    case 2:
+      *p++ = tbl[s[0] >> 2];
+      *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
+      *p++ = tbl[((s[1] & 0xf) << 2)];
+      *p++ = '=';
+      break;
+    }
   /* ...and zero-terminate it.  */
   *p = '\0';