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