[Ace-users] [ace-bugs] Bug in ACE_Base64

J.T. Conklin jtc at acorntoolworks.com
Fri Dec 14 23:33:07 CST 2007


Krishnakumar B <kitty at dre.vanderbilt.edu> writes:
>> The ACE_Base64 implementation is "right", just not what you want.
>> When it encodes the data, the output is split into 72 column "chunks"
>> (RFC 2045 allows up to 76 columns) each terminated by a newline.
>
> Yes, it's true that the ACE encoder doesn't allow you to customize the use
> of chunks.
>
> Alick, can you please apply the following patch to see if it helps?  I have
> not compiled or tested it, but I think it might fix it.

Hi Kitty,

I sent Alick the enclosed patch earlier today.  I have compiled it,
and it passes the Codecs_Test unit tests.  It adds a Java-inspired
is_chunked parameter to encode().

In a private response to my earlier message, Alick clarified his
original complaint that some input "strings" were encoded with a
trailing newline, while others were not.  From code inspection, 
I found that the newline wasn't being added if the input string
length was a multiple of 3.

It appears you chose to omit the final newline, while I chose to
always emit it (in chunked mode).  An argument could be made for
either choice, but I think emitting it makes more sense (I think
the similar python and Java (in chunked mode) APIs emit a 
newline too).

Your patch changes length() and decode().  It's not obvious to me 
what that fixes.  Perhaps whatever that addresses can be addressed
separately?

Please share your thoughts,

    --jtc

Index: Codecs.cpp
===================================================================
--- Codecs.cpp	(revision 80261)
+++ Codecs.cpp	(working copy)
@@ -37,7 +37,8 @@
 ACE_Byte*
 ACE_Base64::encode (const ACE_Byte* input,
                     const size_t input_len,
-                    size_t* output_len)
+                    size_t* output_len,
+		    bool is_chunked)
 {
   if (!ACE_Base64::init_)
     ACE_Base64::init();
@@ -70,7 +71,8 @@
           result[pos++] = alphabet[bits & 0x3f];
           cols += 4;
           if (cols == max_columns) {
-            result[pos++] = '\n';
+	    if (is_chunked) 
+              result[pos++] = '\n';
             cols = 0;
           }
           bits = 0;
@@ -87,19 +89,24 @@
       bits <<= (16 - (8 * char_count));
       result[pos++] = alphabet[bits >> 18];
       result[pos++] = alphabet[(bits >> 12) & 0x3f];
+      cols += 2;
       if (char_count == 1)
         {
           result[pos++] = pad;
           result[pos++] = pad;
+	  cols += 2;
         }
       else
         {
           result[pos++] = alphabet[(bits >> 6) & 0x3f];
           result[pos++] = pad;
+	  cols += 2;
         }
-      if (cols > 0)
-        result[pos++] = '\n';
     }
+
+  if (cols > 0 && is_chunked)
+    result[pos++] = '\n';
+
   result[pos] = 0;
   *output_len = pos;
   return result;
Index: Codecs.h
===================================================================
--- Codecs.h	(revision 80261)
+++ Codecs.h	(working copy)
@@ -55,13 +55,15 @@
    * @param input Binary data in byte stream.
    * @param input_len Length of the byte stream.
    * @param output_len Length of the encoded Base64 byte stream.
+   * @param is_chunked If true, terminate 72 character blocks with newline
    * @return Encoded Base64 data in byte stream or NULL if input data cannot
    *         be encoded.
    */
 
   static ACE_Byte* encode (const ACE_Byte* input,
                            const size_t input_len,
-                           size_t* output_len);
+                           size_t* output_len,
+			   bool is_chunked = true);
   /**
    * Decodes a stream of Base64 to bytes data
    *

-- 
J.T. Conklin



More information about the Ace-users mailing list