[gmime-devel] Re-2: Malformed name in from/to header results in hang



Hi Jeff,
 
thanks a lot for your fast reply and bugfix.
 
I have applied your patch and it seems to be correct now.
And your changes are better than mine, because you use the native Windows function GetACP() instead of g_get_charset() which doesn't seem to work correct on Windows Server 2008. That was one of the problems I'm fighting with on Friday.
On my developer maschine with Windows XP my workaround works like expected but if I run it on a Windows Server 2008 maschine the g_get_charset() function does not return the correct charset I think - I could not verify this in deep, but after using GetACP() it works.
 
Another weird thing is that if I call g_mime_parser_construct_message() twice for the same eml file (in different functions and everytime surrounded with g_mime_init() and g_mime_shutdown()) the second time the library hangs at the same iconv call.
But now the errno is E2BIG which is incorrect because all the buffers seem to be ok.
 
This happen only if the gmime tries to convert from UTF-8 to UTF-8 - so I decided to change the order of the calls in g_mime_utils_decode_8bit() function - by adding the locale charset to the charsets array first.
 

 
 if (!(included & USER_CHARSETS_INCLUDE_LOCALE))
  charsets[i++] = locale;
 
 if (!(included & USER_CHARSETS_INCLUDE_LATIN1))
  charsets[i++] = "iso-8859-1";
 
 if (!(included & USER_CHARSETS_INCLUDE_UTF8))
  charsets[i++] = "UTF-8";
 
The strange thing is, that this is not reproducable with any eml file - I've found only one which results in the hang. I have attached the file - so maybe you are able to find a better workaround for that.
 
Maybe this is a problem with my code - it not clear to me which memory I have to free or not.
 
Here is what I'm calling:
 
// ParseEML
//
//------------------------------------------------------------------------------
void CEMLExporter::ParseEML(boost::filesystem::path& inEMLFile, std::map<std::wstring, std::wstring>& inoutHeaderFieldValues)
{
 FILE *fp = NULL;
 
 GMimeParser   *parser = NULL;
 GMimeStream   *gfs = NULL;
 GMimeMessage  *message = NULL;
 GMimeObject   *part = NULL;
 
 fopen_s(&fp, inEMLFile.string().c_str(), "r");
 
 g_mime_init(0);
 
 gfs = g_mime_stream_file_new(fp);
 if(gfs)
 {
  parser = g_mime_parser_new_with_stream(gfs);
  if(parser)
  {
   message = g_mime_parser_construct_message(parser);
 
   std::map<std::wstring, std::wstring>::const_iterator fieldIter;
   for(fieldIter = mConfig->mEMLHeaderFields.begin(); fieldIter != mConfig->mEMLHeaderFields.end(); ++fieldIter)
   {
    if(fieldIter->first == L"Subject")
    {
     inoutHeaderFieldValues[fieldIter->second] = str_to_wstr(g_mime_message_get_subject(message), CP_UTF8);
    }
    else if(fieldIter->first == L"Date")
    {
     std::string rfc822DateString = g_mime_message_get_date_as_string(message);
 
     inoutHeaderFieldValues[fieldIter->second] = GetDateTimeStringFromRFC822(rfc822DateString);
     //inoutHeaderFieldValues[fieldIter->second] = GetDataTime(message);
    }
    else if(fieldIter->first == L"From")
    {
     inoutHeaderFieldValues[fieldIter->second] = str_to_wstr(g_mime_message_get_sender(message), CP_UTF8);
    }
    else if(fieldIter->first == L"To")
    {
     std::vector<std::string> recipients;
     GetRecipients(message, GMIME_RECIPIENT_TYPE_TO, recipients);
     GetRecipients(message, GMIME_RECIPIENT_TYPE_CC, recipients);
     GetRecipients(message, GMIME_RECIPIENT_TYPE_BCC, recipients);
 
     inoutHeaderFieldValues[fieldIter->second] = str_to_wstr(boost::algorithm::join(recipients, ","), CP_UTF8);
    }
   }
  }
 }
 
 g_mime_shutdown();
 
 fclose(fp);
 
}
 
 
Best regards
 
Bastian
 
 
 
 
Original Message     
   processed by David.fx 
Subject: 
Re: [gmime-devel] Malformed name in from/to header results in hang (16-Jul-2011 19:50)
From:    
To:      
 
Here's an updated patch (previous patch broke one of my unit tests).

Please let me know if this solves your bug or not.

Jeff

On 07/13/2011 06:26 AM, Bastian Pfennigschmidt wrote:
Ok, I've found a workaround for this behavior.
 
1. It seems that the iconv returns errno ERANGE in case of that german umlaut character, if source encoding is set to UTF-8. So I added this ERANGE error code to the last if block "if (errno == EINVAL || errno == EILSEQ || errno == ERANGE)". In that case we do not run into an infinite loop.
 
But this is not the correct solution because the result string contains a question mark instead the correct german umlaut, so I take a look at the source charset which are passed to the iconv function and found that the only source charset tried by gmime was UTF-8. The gmime library tries to get the local_charset by calling setlocale in gmime-charset.c (g_mime_charset_map_init) - but this doesn't seem to work on my Windows environment. The value returned for LC_CTYPE is "German_Germany.1252" which results in locale = "1252" and this is not a valid iconv charset.
 
As a bugfix for Windows I add the following lines of code to determine the current charset via glib.
 
#ifdef G_OS_WIN32
 g_get_charset(&locale_charset);
#else
 locale = setlocale (LC_ALL, NULL);
 .
 .
 .
#endif
 
Now I get CP1252 which is a correct charset for iconv and now my german umlaut will be encoded into UTF-8 correctly.
 
 
Best regards
 
B. Pfennigschmidt
 
 
_______________________________________________ gmime-devel-list mailing list gmime-devel-list gnome org http://mail.gnome.org/mailman/listinfo/gmime-devel-list



To: fejj gnome org
Cc: gmime-devel-list gnome org
--- Begin Message ---







--- End Message ---


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]