Fix OOB write (#340538)
authorAlexander Larsson <alexl@redhat.com>
Thu, 4 May 2006 15:53:36 +0000 (15:53 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Thu, 4 May 2006 15:53:36 +0000 (15:53 +0000)
2006-05-04  Alexander Larsson  <alexl@redhat.com>

* glib/gbase64.c: (g_base64_decode_step):
Fix OOB write (#340538)

ChangeLog
ChangeLog.pre-2-12
glib/gbase64.c

index 2e8d7a8..af1edf5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-04  Alexander Larsson  <alexl@redhat.com>
+
+       * glib/gbase64.c: (g_base64_decode_step):
+       Fix OOB write (#340538)
+
 2006-05-03  Matthias Clasen  <mclasen@redhat.com>
 
        * tests/base64-test.c: Add some more tests.
index 2e8d7a8..af1edf5 100644 (file)
@@ -1,3 +1,8 @@
+2006-05-04  Alexander Larsson  <alexl@redhat.com>
+
+       * glib/gbase64.c: (g_base64_decode_step):
+       Fix OOB write (#340538)
+
 2006-05-03  Matthias Clasen  <mclasen@redhat.com>
 
        * tests/base64-test.c: Add some more tests.
index 14f20d3..08c1c24 100644 (file)
@@ -280,7 +280,8 @@ g_base64_decode_step (const gchar  *in,
   const guchar *inptr;
   guchar *outptr;
   const guchar *inend;
-  guchar c;
+  guchar c, rank;
+  guchar last[2];
   unsigned int v;
   int i;
   
@@ -291,18 +292,24 @@ g_base64_decode_step (const gchar  *in,
   v=*save;
   i=*state;
   inptr = (const guchar *)in;
+  last[0] = last[1] = 0;
   while (inptr < inend)
     {
-      c = mime_base64_rank [*inptr++];
-      if (c != 0xff)
+      c = *inptr++;
+      rank = mime_base64_rank [c];
+      if (rank != 0xff)
        {
-         v = (v<<6) | c;
+         last[1] = last[0];
+         last[0] = c;
+         v = (v<<6) | rank;
          i++;
          if (i==4)
            {
              *outptr++ = v>>16;
-             *outptr++ = v>>8;
-             *outptr++ = v;
+             if (last[1] != '=')
+               *outptr++ = v>>8;
+             if (last[0] != '=')
+               *outptr++ = v;
              i=0;
            }
        }
@@ -311,21 +318,6 @@ g_base64_decode_step (const gchar  *in,
   *save = v;
   *state = i;
   
-  /* quick scan back for '=' on the end somewhere */
-  /* fortunately we can drop 1 output char for each trailing = (upto 2) */
-  i=2;
-  while (inptr > (const guchar *)in && i)
-    {
-      inptr--;
-      if (mime_base64_rank [*inptr] != 0xff)
-       {
-         if (*inptr == '=')
-           outptr--;
-         i--;
-       }
-    }
-
-  /* if i!= 0 then there is a truncation error! */
   return outptr - out;
 }