[webkit-dev] Fix for WebCore's base64Decode...

David Kilzer ddkilzer at webkit.org
Fri Dec 12 04:42:48 PST 2008


Hi Paul,

Please file a bug on <https://bugs.webkit.org/> and attach a patch for review.  It sounds like it *may* be possible to use the local copy of the Acid 3 test as a test case for the fix (for ports using libcurl or libsoup).

Thanks!

Dave




________________________________
From: Paul Pedriana <ppedriana at gmail.com>
To: WebKit-Dev <webkit-dev at lists.webkit.org>
Sent: Friday, December 12, 2008 12:03:04 AM
Subject: [webkit-dev] Fix for WebCore's base64Decode...

I see this in curl and soup code:

       // Use the GLib Base64 if available, since WebCore's decoder isn't
       // general-purpose and fails on Acid3 test 97 (whitespace).

In WebCore's base64Decode, I see this:

   for (unsigned idx = 0; idx < len; idx++) {
       unsigned char ch = data[idx];
       if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) || (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
           out[idx] = base64DecMap[ch];
       else
           return false;                                       <--- it shouldn't be doing this
   }

RFC 2045 states:
   All line breaks or other characters not found in Table 1 must
   be ignored by decoding software.

Thus can't WebCore's base64Decode be fixed simply like so, which works as expected in my tests:

bool base64Decode(const char* data, unsigned len, Vector<char>& out)
{
   out.clear();
   if (len == 0)
       return true;

   while (len && data[len-1] == '=')
       --len;

   out.grow(len);
   unsigned outSize = 0;
   for (unsigned idx = 0; idx < len; idx++) {
       unsigned char ch = data[idx];
       if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) || (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=') {
           out[outSize] = base64DecMap[ch];
           outSize++;
       }
   }

   out.resize(static_cast<size_t>(outSize));

   // 4-byte to 3-byte conversion
   unsigned outLen = outSize - ((outSize + 3) / 4);
   if (!outLen || ((outLen + 2) / 3) * 4 < outSize)
       return false;

   unsigned sidx = 0;
   unsigned didx = 0;
   if (outLen > 1) {
       while (didx < outLen - 2) {
           out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
           out[didx + 1] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
           out[didx + 2] = (((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077));
           sidx += 4;
           didx += 3;
       }
   }

   if (didx < outLen)
       out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));

   if (++didx < outLen)
       out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));

   if (outLen < out.size())
       out.shrink(outLen);

   return true;
}

Is this all there is to the bug or is there more that I'm not aware of?

Thanks.

Paul








_______________________________________________
webkit-dev mailing list
webkit-dev at lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20081212/16dd555e/attachment.html>


More information about the webkit-dev mailing list