Update of /cvsroot/mahogany/M/src/modules/viewflt
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9332/src/modules/viewflt

Modified Files:
        UUDecode.cpp 
Log Message:
1. "fixed" big memory leak
2. fixed new[]/delete mismatch
3. detect "begin" only when preceded by a blank line
4. file mode is in octal, so check for octal digits only
5. added missing _T()s
6. reformatted slightly

Index: UUDecode.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/modules/viewflt/UUDecode.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -b -u -2 -r1.5 -r1.6
--- UUDecode.cpp        15 May 2004 10:53:34 -0000      1.5
+++ UUDecode.cpp        16 May 2004 11:51:42 -0000      1.6
@@ -31,6 +31,4 @@
 #include <wx/bitmap.h>
 
-
-
 #include "MimePart.h"
 #include <wx/mimetype.h>
@@ -74,13 +72,17 @@
 
    /// get the raw (un-decoded) contents of this part
-   virtual const void *GetRawContent(unsigned long *len = NULL) const {
+   virtual const void *GetRawContent(unsigned long *len = NULL) const
+   {
       // We actually return the only thing we have: the decoded file.
       return GetContent(len);
    }
-   virtual const void *GetContent(unsigned long *len) const {
-     if (len) *len = m_content.Length();
+   virtual const void *GetContent(unsigned long *len) const
+   {
+     if (len)
+        *len = m_content.Length();
      return m_content.c_str();
    }
-   virtual String GetTextContent() const {
+   virtual String GetTextContent() const
+   {
       // Same as for MimePartCC
       unsigned long len;
@@ -115,5 +117,6 @@
 };
 
-
+// strlen("\r\n")
+static const size_t lenEOL = 2;
 
 
@@ -127,4 +130,5 @@
 public:
    UUDecodeFilter(MessageView *msgView, ViewFilter *next, bool enable);
+   virtual ~UUDecodeFilter();
 
 protected:
@@ -132,4 +136,13 @@
                           MessageViewer *viewer,
                           MTextStyle& style);
+
+   // all MimePartRaw we create: we add them to this array to free them later
+   //
+   // unfortunately this is totally bogus as we're normally destroyed only when
+   // the program terminates so even if it doesn't appear as the memory leak in
+   // the end, it still is one: the MimePartRaws should have been destroyed
+   // much earlier... unfortunately it's not clear when, probably they should
+   // be attached to the Message and destroyed with it but this is so ugly...
+   wxArrayPtrVoid m_mimeParts;
 };
 
@@ -138,9 +151,10 @@
 // ----------------------------------------------------------------------------
 
-// all UUencoded data start with a line whose prefix is this
-#define UU_BEGIN_PREFIX _T("begin ")
+// all UUencoded data start with a line whose prefix is "begin" and preceded by
+// a blank line
+#define UU_BEGIN_PREFIX _T("\r\nbegin ")
 
-// end of the UU encoded data is with a line equal to this
-#define UU_END_PREFIX _T("end")
+// UUencoded data ends at a line consisting solely of "end"
+#define UU_END_PREFIX _T("\r\nend")
 
 // ============================================================================
@@ -158,7 +172,19 @@
 // ----------------------------------------------------------------------------
 
-UUDecodeFilter::UUDecodeFilter(MessageView *msgView, ViewFilter *next, bool enable)
+UUDecodeFilter::UUDecodeFilter(MessageView *msgView,
+                               ViewFilter *next,
+                               bool enable)
          : ViewFilter(msgView, next, enable)
-{}
+{
+}
+
+UUDecodeFilter::~UUDecodeFilter()
+{
+   const size_t count = m_mimeParts.GetCount();
+   for ( size_t n = 0; n < count; n++ )
+   {
+      delete static_cast<MimePartRaw *>(m_mimeParts[n]);
+   }
+}
 
 // ----------------------------------------------------------------------------
@@ -166,27 +192,44 @@
 // ----------------------------------------------------------------------------
 
+// check if c is valid in uuencoded text
+static inline IsUUValid(wxChar c)
+{
+   return c >= _T(' ') && c <= _T('`');
+}
 
+// "decode" a single character
 #define DEC(c) (((c) - ' ') & 077)
 
-int UUdecodeLine(const wxChar* input, wxChar* output, const wxChar** endOfLine) {
-  if  (input[0] > ' ' && input[0] <= '`') {
-    char * cv_ptr = output;
-    register const wxChar * p=input;
-
-    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) {
-      if ( (p[0]<' ' || p[0]>'`') ||
-            (p[1]<' ' || p[1]>'`') ||
-            (p[2]<' ' || p[2]>'`') ||
-            (p[3]<' ' || p[3]>'`') ) {
+int UUdecodeLine(const wxChar* input, wxChar* output, const wxChar** 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
+      return -1;
+   }
+
+   wxChar * cv_ptr = output;
+   register const wxChar * p = input;
+
+   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)
+   {
+      if ( !IsUUValid(p[0]) ||
+           !IsUUValid(p[1]) ||
+           !IsUUValid(p[2]) ||
+           !IsUUValid(p[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]);
     }
-    if (*p != '\r' && *p != '\n' && *p != '\0')
+   if (*p != _T('\r') && *p != _T('\n') && *p != _T('\0'))
       return -1;
     //else  *p=0;
@@ -194,10 +237,8 @@
     *endOfLine = p;
     return cv_len;
-  } else 
-    return -1;
 }
 
-bool UUdecodeFile(const wxChar* input, String& output, const wxChar** 
endOfEncodedStream) {
-
+bool UUdecodeFile(const wxChar* input, String& output, const wxChar** 
endOfEncodedStream)
+{
   static const int allocationSize = 10000;
 
@@ -210,24 +251,29 @@
   const wxChar* endOfLine = 0; // init not needed
   wxChar* buffer = new wxChar[45];
-  //memset(buffer, '\0', 45);
-  while ((decodedBytesInLine = UUdecodeLine(startOfLine, buffer, &endOfLine)) > 0) {
+   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 (decodedFile.length() + (size_t)decodedBytesInLine >= totalAllocatedBytes)
+      {
       totalAllocatedBytes += allocationSize;
       decodedFile.Alloc(totalAllocatedBytes);
     }
-    decodedFile << decodedLine;
+      decodedFile += decodedLine;
+
     ASSERT_MSG( decodedFile.Length() == totalDecodedBytes, 
       _T("Number of decoded bytes does not match!") );
-    ASSERT_MSG( endOfLine[0] == '\r', _T("Line has no '\\r' at the end!") );
-    ASSERT_MSG( endOfLine[1] == '\n', _T("Line has no '\\n' at the end!") );
-    startOfLine = endOfLine + 2;
+      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!") );
+
+      startOfLine = endOfLine + lenEOL;
   }
-  delete buffer;
-  if (decodedBytesInLine < 0) {
+
+   delete[] buffer;
+   if (decodedBytesInLine < 0)
     return false;
-  }
+
   decodedFile.Shrink();
   output = decodedFile;
@@ -244,5 +290,5 @@
 {
    // do we have something looking like UUencoded data?
-   //
+   static const size_t lenBegin = wxStrlen(UU_BEGIN_PREFIX);
    
    const wxChar *start = text.c_str();
@@ -250,9 +296,8 @@
    while ( *start )
    {
-
-      if ( wxStrncmp(start, UU_BEGIN_PREFIX, wxStrlen(UU_BEGIN_PREFIX)) != 0 )
+      if ( wxStrncmp(start, UU_BEGIN_PREFIX, lenBegin) != 0 )
       {
          // try the next line (but only if not already at the end)
-         start = wxStrchr(start, '\n');
+         start = wxStrchr(start, _T('\n'));
          if ( start )
          {
@@ -271,49 +316,50 @@
       }
 
-      ASSERT_MSG( wxStrncmp(start, UU_BEGIN_PREFIX, wxStrlen(UU_BEGIN_PREFIX)) == 0,
-         _T("Stopped without a seemingly begin line ?") );
-
       const wxChar* startBeginLine = start;
-      start = start + wxStrlen(UU_BEGIN_PREFIX);
+      start += lenBegin;
+
       // Let's check that the next 4 chars after the 'begin ' are
-      // digit, digit, digit, space
-      if ( !(    start[0] >= '0' && start[0] <= '9'
-              && start[1] >= '0' && start[1] <= '9'
-              && start[2] >= '0' && start[2] <= '9'
-              && start[3] == ' ' ) ) 
+      // 3 octal digits and space
+      //
+      // 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 defined(__WXDEBUG__)
          wxLogWarning(_("The BEGIN line is not correctly formed."));
-#endif
+         start -= lenBegin;
          continue;
       }
 
-      const wxChar* startName = start+4;
+      const wxChar* startName = start+4;     // skip mode and space
       const wxChar* endName = startName;
       // Rest of the line is the name
-      while (*endName != '\r')
+      while (*endName != _T('\r'))
       {
          ++endName;
-         ASSERT_MSG( endName < text.c_str()+text.Length(), _T("'begin' line does not 
end?") );
+         ASSERT_MSG( endName < text.c_str()+text.length(),
+                         _T("'begin' line does not end?") );
       }
-      ASSERT_MSG( endName[1] == '\n', _T("'begin' line does not end with 
\"\\r\\n\"?") );
+
+      ASSERT_MSG( endName[1] == _T('\n'),
+                     _T("'begin' line does not end with \"\\r\\n\"?") );
+
       String fileName = String(startName, endName);
-      const wxChar* start_data = endName + 2;
+      const wxChar* start_data = endName + lenEOL;
 
       String decodedFile;
       const wxChar* endOfEncodedStream = 0;
-      bool ok = UUdecodeFile(start_data, decodedFile, &endOfEncodedStream);
-      if ( ok )
+      if ( UUdecodeFile(start_data, decodedFile, &endOfEncodedStream) )
       {
-         if ( endOfEncodedStream[0] == '\r' &&
-            endOfEncodedStream[1] == '\n' &&
-            endOfEncodedStream[2] == 'e' &&
-            endOfEncodedStream[3] == 'n' &&
-            endOfEncodedStream[4] == 'd' )
+         static const size_t lenEnd = wxStrlen(UU_END_PREFIX);
+         if ( wxStrncmp(endOfEncodedStream, UU_END_PREFIX, lenEnd) == 0 )
          {
-            endOfEncodedStream += 5;
+            endOfEncodedStream += lenEnd;
          }
+
          // output the part before the BEGIN line, if any
-         String prolog(nextToOutput, startBeginLine-2);
+         String prolog(nextToOutput, startBeginLine - lenEOL);
          if ( !prolog.empty() )
          {
@@ -330,17 +376,18 @@
          delete fileType;
 
-         MimePartRaw* decodedMime = 
+         MimePartRaw *mimepart =
             new MimePartRaw(fileName, mimeType, decodedFile, _T("uuencoded"));
-         m_msgView->ShowPart(decodedMime);
+         m_mimeParts.Add(mimepart);
+         m_msgView->ShowPart(mimepart);
 
-         nextToOutput = start = endOfEncodedStream;
+         nextToOutput =
+         start = endOfEncodedStream;
       }
       else
       {
-#if defined(__WXDEBUG__)
          wxLogWarning(_("This message seems to contain uuencoded data, but in fact it 
does not."));
-#endif
       }
    }
+
    String prolog(nextToOutput);
    if ( !prolog.empty() )



-------------------------------------------------------
This SF.Net email is sponsored by: SourceForge.net Broadband
Sign-up now for SourceForge Broadband and get the fastest
6.0/768 connection for only $19.95/mo for the first 3 months!
http://ads.osdn.com/?ad_id=2562&alloc_id=6184&op=click
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to