Revision: 7472
          http://mahogany.svn.sourceforge.net/mahogany/?rev=7472&view=rev
Author:   vadz
Date:     2008-05-04 18:15:04 -0700 (Sun, 04 May 2008)

Log Message:
-----------
fix uudecoding and virtual MIME parts which were totally broken in Unicode 
build; also fix virtual MIME parts body size determination which was broken 
even in ANSI build

Modified Paths:
--------------
    trunk/M/include/MimePartVirtual.h
    trunk/M/src/classes/MessageView.cpp
    trunk/M/src/mail/MessageCC.cpp
    trunk/M/src/mail/MimePartVirtual.cpp
    trunk/M/src/modules/viewflt/UUDecode.cpp

Modified: trunk/M/include/MimePartVirtual.h
===================================================================
--- trunk/M/include/MimePartVirtual.h   2008-05-04 20:40:22 UTC (rev 7471)
+++ trunk/M/include/MimePartVirtual.h   2008-05-05 01:15:04 UTC (rev 7472)
@@ -31,7 +31,7 @@
    /**
       Construct a MIME part from the entire part text (body + header).
     */
-   MimePartVirtual(const String& msgText);
+   MimePartVirtual(const wxMemoryBuffer& msgText);
 
    /**
       Construct a nested MIME part.
@@ -62,7 +62,7 @@
 
 
    // the entire text of the message, only non empty for the top level part
-   String m_msgText;
+   wxMemoryBuffer m_msgText;
 
    // pointer to the start of headers of this part
    const char *m_pStart;

Modified: trunk/M/src/classes/MessageView.cpp
===================================================================
--- trunk/M/src/classes/MessageView.cpp 2008-05-04 20:40:22 UTC (rev 7471)
+++ trunk/M/src/classes/MessageView.cpp 2008-05-05 01:15:04 UTC (rev 7472)
@@ -2583,7 +2583,9 @@
          pgpInfo = new PGPInfoGoodMsg(this);
 
          {
-            MimePartVirtual *mpv = new MimePartVirtual(decryptedData);
+            wxMemoryBuffer buf;
+            buf.AppendData(decryptedData.To8BitData(), decryptedData.length());
+            MimePartVirtual *mpv = new MimePartVirtual(buf);
             AddVirtualMimePart(mpv);
             ProcessPart(mpv);
          }

Modified: trunk/M/src/mail/MessageCC.cpp
===================================================================
--- trunk/M/src/mail/MessageCC.cpp      2008-05-04 20:40:22 UTC (rev 7471)
+++ trunk/M/src/mail/MessageCC.cpp      2008-05-05 01:15:04 UTC (rev 7472)
@@ -869,34 +869,14 @@
                     BODY **ppBody,
                     size_t *pHdrLen)
 {
-   const char *bodycptr = NULL;
-   unsigned long headerLen = 0;
-
-   // find end of header "\r\n\r\n"
-   bool eol = true;
-   for ( unsigned long pos = 0; msgText[pos]; pos++ )
-   {
-      // empty line or end of text?
-      if ( msgText[pos] == '\r' && msgText[++pos] == '\n' )
-      {
-         if ( eol )
-         {
-            headerLen = pos - 1;
-            bodycptr = msgText + pos + 1; // skip eol
-            break;
-         }
-
-         eol = true;
-      }
-      else
-      {
-         eol = false;
-      }
-   }
-
-   if ( !headerLen )
+   // find end of header indicated by a blank line
+   const char *bodycptr = strstr(msgText, "\r\n\r\n");
+   if ( !bodycptr )
       return false;
 
+   const unsigned long headerLen = bodycptr - msgText + 2; // include EOL
+   bodycptr += 4; // skip 2 EOLs
+
    STRING str;
    INIT(&str, mail_string, const_cast<char *>(bodycptr), strlen(bodycptr));
    rfc822_parse_msg(ppEnv, ppBody,

Modified: trunk/M/src/mail/MimePartVirtual.cpp
===================================================================
--- trunk/M/src/mail/MimePartVirtual.cpp        2008-05-04 20:40:22 UTC (rev 
7471)
+++ trunk/M/src/mail/MimePartVirtual.cpp        2008-05-05 01:15:04 UTC (rev 
7472)
@@ -44,17 +44,17 @@
 // ----------------------------------------------------------------------------
 
 // ctor for top level part
-MimePartVirtual::MimePartVirtual(const String& msgText)
+MimePartVirtual::MimePartVirtual(const wxMemoryBuffer& msgText)
                : m_msgText(msgText)
 {
-   m_pStart = m_msgText;
+   m_pStart = static_cast<char *>(m_msgText.GetData());
 
    m_env = NULL;
 
    m_lenHeader =
    m_lenBody = 0;
 
-   if ( !CclientParseMessage(msgText, &m_env, &m_body, &m_lenHeader) )
+   if ( !CclientParseMessage(m_pStart, &m_env, &m_body, &m_lenHeader) )
    {
       // no idea what is user supposed to make out of this message...
       wxLogError(_("Failed to create a virtual MIME part."));
@@ -62,8 +62,14 @@
       return;
    }
 
-   m_lenBody = m_msgText.length() - m_lenHeader - lenEOL;
+   m_lenBody = m_msgText.GetDataLen() - m_lenHeader - lenEOL;
 
+   // c-client can't determine it itself correctly (the "string" we pass to it
+   // can have embedded NULs and we don't pass the real length), so fix it here
+   m_body->size.bytes =
+   m_body->contents.text.size = m_lenBody;
+
+
    CreateSubParts();
 }
 

Modified: trunk/M/src/modules/viewflt/UUDecode.cpp
===================================================================
--- trunk/M/src/modules/viewflt/UUDecode.cpp    2008-05-04 20:40:22 UTC (rev 
7471)
+++ trunk/M/src/modules/viewflt/UUDecode.cpp    2008-05-05 01:15:04 UTC (rev 
7472)
@@ -59,10 +59,10 @@
 
 // all UUencoded data start with a line whose prefix is "begin" and preceded by
 // a blank line
-#define UU_BEGIN_PREFIX _T("begin ")
+#define UU_BEGIN_PREFIX "begin "
 
 // UUencoded data ends at a line consisting solely of "end"
-#define UU_END_PREFIX _T("\r\nend\r\n")
+#define UU_END_PREFIX "\r\nend\r\n"
 
 // ============================================================================
 // UUDecodeFilter implementation
@@ -89,99 +89,95 @@
 // UUDecodeFilter work function
 // ----------------------------------------------------------------------------
 
+namespace
+{
+
 // check if c is valid in uuencoded text
-static inline bool IsUUValid(wxChar c)
+inline bool IsUUValid(char c)
 {
-   return c >= _T(' ') && c <= _T('`');
+   return c >= ' ' && c <= '`';
 }
 
+static const int MAX_UU_LINE_LEN = 45;
+
 // "decode" a single character
-#define DEC(c)    (((c) - ' ') & 077)
+#define UUdec(c)    (((c) - ' ') & 077)
 
-int UUdecodeLine(const wxChar* input, wxChar* output, const wxChar** endOfLine)
+int UUdecodeLine(const char *input, char *output, const char **endOfLine)
 {
-   // "input[0] - space" contains the count of characters in this line, check
-   // that it is valid
-   if ( input[0] <= _T(' ') || input[0] > _T('`') )
-   {
-      // invalid uu char
+   if ( !IsUUValid(*input) )
       return -1;
-   }
 
-   wxChar * cv_ptr = output;
-   register const wxChar * p = input;
+   const int cv_len = UUdec(*input++);
+   if ( cv_len > MAX_UU_LINE_LEN )
+      return -1;
 
-   const int cv_len = DEC(*p++);
-
    // Actually decode the uue data; ensure characters are in range.
-   for (int i=0; i<cv_len; i+=3, p+=4)
+   for ( int i = 0; i < cv_len; i += 3, input += 4 )
    {
-      if ( !IsUUValid(p[0]) ||
-           !IsUUValid(p[1]) ||
-           !IsUUValid(p[2]) ||
-           !IsUUValid(p[3]) )
+      if ( !IsUUValid(input[0]) || !IsUUValid(input[1]) ||
+           !IsUUValid(input[2]) || !IsUUValid(input[3]) )
       {
          return -1;
       }
 
-      *cv_ptr++ = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
-      *cv_ptr++ = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
-      *cv_ptr++ = DEC(p[2]) << 6 | DEC(p[3]);
+      *output++ = UUdec(input[0]) << 2 | UUdec(input[1]) >> 4;
+      *output++ = UUdec(input[1]) << 4 | UUdec(input[2]) >> 2;
+      *output++ = UUdec(input[2]) << 6 | UUdec(input[3]);
    }
-   if (*p != _T('\r') && *p != _T('\n') && *p != _T('\0'))
+
+   if ( *input != '\r' && *input != '\n' && *input != '\0' )
       return -1;
-   //else  *p=0;
 
-   *endOfLine = p;
+   *endOfLine = input;
    return cv_len;
 }
 
-bool UUdecodeFile(const wxChar* input, String& output, const wxChar** 
endOfEncodedStream)
+bool
+UUdecodeFile(const char *input,
+             wxMemoryBuffer& output,
+             const char **endOfEncodedStream)
 {
-   static const int allocationSize = 10000;
+   static const size_t allocationSize = 10000;
 
-   String decodedFile;
    size_t totalAllocatedBytes = 0;
 
    size_t totalDecodedBytes = 0;
    int decodedBytesInLine;
-   const wxChar* startOfLine = input;
-   const wxChar* endOfLine = 0; // init not needed
-   wxChar* buffer = new wxChar[45];
+   const char *startOfLine = input;
+   const char *endOfLine = 0; // init not needed
+   char buffer[MAX_UU_LINE_LEN];
    while ( (decodedBytesInLine =
                UUdecodeLine(startOfLine, buffer, &endOfLine)) > 0 )
    {
       // We've just decoded a line
       totalDecodedBytes += decodedBytesInLine;
-      String decodedLine(buffer, decodedBytesInLine);
-      if (decodedFile.length() + (size_t)decodedBytesInLine >= 
totalAllocatedBytes)
+      if ( output.GetDataLen() + decodedBytesInLine >= totalAllocatedBytes )
       {
          totalAllocatedBytes += allocationSize;
-         decodedFile.Alloc(totalAllocatedBytes);
+         output.GetWriteBuf(totalAllocatedBytes);
       }
-      decodedFile += decodedLine;
 
-      ASSERT_MSG( decodedFile.Length() == totalDecodedBytes,
-            _T("Number of decoded bytes does not match!") );
-      ASSERT_MSG( endOfLine[0] == _T('\r'), _T("Line has no '\\r' at the 
end!") );
-      ASSERT_MSG( endOfLine[1] == _T('\n'), _T("Line has no '\\n' at the 
end!") );
+      output.AppendData(buffer, decodedBytesInLine);
 
+      ASSERT_MSG( endOfLine[0] == '\r', "Line has no '\\r' at the end!" );
+      ASSERT_MSG( endOfLine[1] == '\n', "Line has no '\\n' at the end!" );
+
       startOfLine = endOfLine + lenEOL;
    }
 
-   delete[] buffer;
-   if (decodedBytesInLine < 0)
+   if ( decodedBytesInLine < 0 )
    {
       wxLogWarning(_("Invalid character in uuencoded text."));
       return false;
    }
 
-   decodedFile.Shrink();
-   output = decodedFile;
    *endOfEncodedStream = endOfLine;
+
    return true;
 }
 
+} // anonymous namespace
 
 
 void
@@ -192,8 +188,8 @@
    // do we have something looking like UUencoded data?
    static const size_t lenBegin = wxStrlen(UU_BEGIN_PREFIX);
 
-   const wxChar *start = text.c_str();
-   const wxChar *nextToOutput = start;
+   const char *start = text.c_str();
+   const char *nextToOutput = start;
    while ( *start )
    {
       bool hasBegin = wxStrncmp(start, UU_BEGIN_PREFIX, lenBegin) == 0;
@@ -216,10 +212,10 @@
                // 2 or 4 and more characters after the start
             default:
                // only blank line allowed before
-               if ( start[-1] != _T('\n') || start[-2] != _T('\r') )
+               if ( start[-1] != '\n' || start[-2] != '\r' )
                   hasBegin = false;
                if ( start - text.c_str() > 2 &&
-                        (start[-3] != _T('\n') || start[-4] != _T('\r')) )
+                        (start[-3] != '\n' || start[-4] != '\r') )
                   hasBegin = false;
          }
       }
@@ -227,7 +223,7 @@
       if ( !hasBegin )
       {
          // try the next line (but only if not already at the end)
-         start = wxStrchr(start, _T('\n'));
+         start = wxStrchr(start, '\n');
          if ( start )
          {
             start++;  // skip '\n' itself
@@ -244,7 +240,7 @@
          }
       }
 
-      const wxChar* startBeginLine = start;
+      const char *startBeginLine = start;
       start += lenBegin;
 
       // Let's check that the next 4 chars after the 'begin ' are
@@ -252,34 +248,71 @@
       //
       // NB: 4 digit mode masks are in theory possible but shouldn't be used
       //     with uuencoded files
-      if ( !(    start[0] >= _T('0') && start[0] <= _T('7')
-              && start[1] >= _T('0') && start[1] <= _T('7')
-              && start[2] >= _T('0') && start[2] <= _T('7')
-              && start[3] == _T(' ') ) )
+      if ( !(    start[0] >= '0' && start[0] <= '7'
+              && start[1] >= '0' && start[1] <= '7'
+              && start[2] >= '0' && start[2] <= '7'
+              && start[3] == ' ' ) )
       {
          wxLogWarning(_("The BEGIN line is not correctly formed."));
          continue;
       }
 
-      const wxChar* startName = start+4;     // skip mode and space
-      const wxChar* endName = startName;
+      const char *startName = start+4;     // skip mode and space
+      const char *endName = startName;
       // Rest of the line is the name
-      while (*endName != _T('\r'))
+      while ( *endName != '\r' )
       {
-         ++endName;
-         ASSERT_MSG( endName < text.c_str()+text.length(),
-                         _T("'begin' line does not end?") );
+         if ( !*endName++ )
+         {
+            wxLogWarning(_("The BEGIN line is unterminated."));
+            String prolog(nextToOutput);
+            if ( !prolog.empty() )
+            {
+               m_next->Process(prolog, viewer, style);
+            }
+            return;   // no more text
+         }
       }
 
-      ASSERT_MSG( endName[1] == _T('\n'),
-                     _T("'begin' line does not end with \"\\r\\n\"?") );
+      ASSERT_MSG( endName[1] == '\n',
+                     "'begin' line does not end with \"\\r\\n\"?" );
 
-      String fileName = String(startName, endName);
-      const wxChar* start_data = endName + lenEOL;
+      const String fileName(startName, endName);
+      const char *start_data = endName + lenEOL;
 
-      String decodedFile;
-      const wxChar* endOfEncodedStream = 0;
-      bool ok = UUdecodeFile(start_data, decodedFile, &endOfEncodedStream);
+
+      // buffer with the entire virtual part contents
+      wxMemoryBuffer virtData;
+
+      // start with the header for the uudecoded virtual part
+      String header("Mime-Version: 1.0\r\n"
+                    //"Content-Transfer-Encoding: uuencode\r\n"
+                    "Content-Disposition: attachment; filename=\"" +
+                    fileName + "\"\r\n");
+
+      // get a mimeType from the extention
+      String mimeType;
+      String ext;
+      wxSplitPath(fileName, NULL, NULL, &ext);
+      if ( !ext.empty() )
+      {
+         wxFileType *
+            ft = mApplication->GetMimeManager().GetFileTypeFromExtension(ext);
+         if ( ft )
+            ft->GetMimeType(&mimeType);
+         delete ft;
+      }
+
+      if ( mimeType.empty() )
+         mimeType = "APPLICATION/OCTET-STREAM";
+      header += "Content-Type: " + mimeType;
+      header += "; name=\"" + fileName + "\"\r\n";
+      header += "\r\n"; // blank line separating the header from body
+
+      virtData.AppendData(header.ToAscii(), header.length());
+
+      const char *endOfEncodedStream = 0;
+      bool ok = UUdecodeFile(start_data, virtData, &endOfEncodedStream);
       if ( ok )
       {
          static const size_t lenEnd = wxStrlen(UU_END_PREFIX);
@@ -303,29 +336,8 @@
             m_next->Process(prolog, viewer, style);
          }
 
-         // now create the header for the uuencoded part
-         String header(_T("Mime-Version: 1.0\r\n")
-                       _T("Content-Disposition: uuencoded\r\n"));
-
-         // get a mimeType from the extention
-         String mimeType;
-         String ext;
-         wxSplitPath(fileName, NULL, NULL, &ext);
-         if ( !ext.empty() )
-         {
-            wxFileType *
-               ft = 
mApplication->GetMimeManager().GetFileTypeFromExtension(ext);
-            if ( ft )
-               ft->GetMimeType(&mimeType);
-            delete ft;
-         }
-
-         if ( mimeType.empty() )
-            mimeType = _T("APPLICATION/OCTET-STREAM");
-         header += _T("Content-Type: ") + mimeType + _T("\r\n");
-
-         MimePartVirtual *
-            mimepart = new MimePartVirtual(header + _T("\r\n") + decodedFile);
+         // create and process the virtual part containing uudecoded contents
+         MimePartVirtual * const mimepart = new MimePartVirtual(virtData);
          m_msgView->AddVirtualMimePart(mimepart);
          m_msgView->ShowPart(mimepart);
 


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to