[pan2] * a few fixes to iconv * https://bugzilla.gnome.org/show_bug.cgi?id=666199



commit bfbb51199f42b47845031024908cb08d56314d39
Author: Heinrich MÃller <henmull src gnome org>
Date:   Sun Dec 18 16:06:55 2011 +0100

    * a few fixes to iconv
    * https://bugzilla.gnome.org/show_bug.cgi?id=666199

 pan/gui/actions.cc             |    1 +
 pan/gui/gui.cc                 |   21 +++++++------
 pan/gui/header-pane.cc         |    4 ++
 pan/tasks/task-article.cc      |   23 +++++++++++----
 pan/usenet-utils/gnksa-test.cc |   11 +++++--
 pan/usenet-utils/gnksa.cc      |   62 ++++++++++++++++++++++++++++++---------
 pan/usenet-utils/mime-utils.cc |    8 +++--
 pan/usenet-utils/mime-utils.h  |    3 +-
 8 files changed, 95 insertions(+), 38 deletions(-)
---
diff --git a/pan/gui/actions.cc b/pan/gui/actions.cc
index 6b6814a..b7e3f63 100644
--- a/pan/gui/actions.cc
+++ b/pan/gui/actions.cc
@@ -434,6 +434,7 @@ namespace
       N_("Clear _Header Pane"), NULL,
       NULL,
       G_CALLBACK(do_clear_header_pane) },
+
     { "clear-body-pane", NULL,
       N_("Clear _Body Pane"), NULL,
       NULL,
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 91bd55d..1585dc9 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -916,9 +916,9 @@ void GUI :: do_clear_header_pane ()
 {
   gtk_window_set_title (get_window(_root), _("Pan"));
   _header_pane->set_group (Quark());
-  // close iconv handler
-  iconv_close(conv);
+
 }
+
 void GUI :: do_clear_body_pane ()
 {
   _body_pane->clear ();
@@ -1629,11 +1629,7 @@ void GUI :: do_read_selected_group ()
   // set the charset encoding based upon that group's / global default
   if (!group.empty())
   {
-    std::string local (_group_prefs.get_string (group, "character-encoding", ""));
-    if (local.empty())
-    {
-      local = _prefs.get_string("default-charset", "UTF-8");
-    }
+    std::string local (_group_prefs.get_string (group, "character-encoding", "UTF-8"));
     set_charset (local);
 
     // update iconv handler
@@ -1641,11 +1637,16 @@ void GUI :: do_read_selected_group ()
     char buf[256];
     g_snprintf(buf, sizeof(buf), "%s//IGNORE", _prefs.get_string("default-charset", "UTF-8").c_str());
     const char * to  = g_mime_charset_iconv_name(buf);
-    conv = iconv_open (to, from);
-    if (conv == (iconv_t)-1)
+    if (strncmp (from, buf, strlen(from)) != 0)
     {
-      Log::add_err(_("Error loading iconv library. Some Charsets in GUI will not be able to be encoded."));
+      conv = iconv_open (to, from);
+      if (conv == (iconv_t)-1)
+      {
+        Log::add_err(_("Error loading iconv library. Some Charsets in GUI will not be able to be encoded."));
+      } else
+        iconv_inited = true;
     }
+
   }
 
 
diff --git a/pan/gui/header-pane.cc b/pan/gui/header-pane.cc
index 95781bf..97af79b 100644
--- a/pan/gui/header-pane.cc
+++ b/pan/gui/header-pane.cc
@@ -1626,6 +1626,10 @@ HeaderPane :: ~HeaderPane ()
 
   for (guint i=0; i<ICON_QTY; ++i)
     g_object_unref (G_OBJECT(_icons[i].pixbuf));
+
+  // close iconv handler
+  if (iconv_inited) iconv_close(conv);
+  iconv_inited = false;
 }
 
 GtkWidget*
diff --git a/pan/tasks/task-article.cc b/pan/tasks/task-article.cc
index 3c77f7b..80e1278 100644
--- a/pan/tasks/task-article.cc
+++ b/pan/tasks/task-article.cc
@@ -24,11 +24,14 @@
 #include <config.h>
 #include <algorithm>
 #include <cassert>
-extern "C" {
-#include <glib/gi18n.h>
+extern "C"
+{
+  #include <glib/gi18n.h>
+  #include <iconv.h>
 }
 #include <pan/general/debug.h>
 #include <pan/general/file-util.h>
+#include <pan/general/utf8-utils.h>
 #include <pan/general/log.h>
 #include <pan/general/macros.h>
 #include <pan/usenet-utils/mime-utils.h>
@@ -49,11 +52,19 @@ namespace
     std::string stripped;
     mime::remove_multipart_from_subject (article.subject.c_str(), stripped);
 
+    const char* str = stripped.c_str();
+    iconv_t c = iconv_open("UTF-8","UTF-8");
+    char * res = __g_mime_iconv_strdup(c, str);
+    iconv_close(c);
+
     char buf[1024];
     if (save)
-      snprintf (buf, sizeof(buf), _("Saving %s"), stripped.c_str());
+      snprintf (buf, sizeof(buf), _("Saving %s"), res);
     else
-      snprintf (buf, sizeof(buf), _("Reading %s"), stripped.c_str());
+      snprintf (buf, sizeof(buf), _("Reading %s"), res);
+
+    g_free(res);
+
     return std::string (buf);
   }
 }
@@ -132,7 +143,7 @@ TaskArticle :: ~TaskArticle ()
   // ensure our on_worker_done() doesn't get called after we're dead
   if (_decoder)
       _decoder->cancel_silently();
-  
+
   _cache.release (_article.get_part_mids());
 }
 
@@ -291,7 +302,7 @@ TaskArticle :: on_nntp_done  (NNTP             * nntp,
       }
       break;
   }
-  
+
   update_work (nntp);
   check_in (nntp, health);
 }
diff --git a/pan/usenet-utils/gnksa-test.cc b/pan/usenet-utils/gnksa-test.cc
index 9fe4997..e35cc87 100644
--- a/pan/usenet-utils/gnksa-test.cc
+++ b/pan/usenet-utils/gnksa-test.cc
@@ -8,7 +8,7 @@
 
 using namespace pan;
 
-typedef struct 
+typedef struct
 {
 	int expected_retval;
 	const char * address;
@@ -35,7 +35,7 @@ test_generate_references (void)
 	msg_id = "<pan 2001 12 08 22 06 46 245566 1891 gmx de>";
 	out = GNKSA::generate_references (refs, msg_id);
 	expected = "<9uh0rq$8g9ua$1 ID-41667 news dfncis de> <9596705 7QZiUf9aFP aschiller easynet de> <Xns916D78745865Dvg newsf1 volker-gringmuth de> <3C111F64 D2AABC41 babsi de> <pan 2001 12 07 21 44 36 620796 4981 gmx de> <pan 2001 12 08 21 19 07 420400 7547 babsi de> <pan 2001 12 08 21 30 14 714578 7547 babsi de> <pan 2001 12 08 22 06 46 245566 1891 gmx de>";
-        check (expected == out)
+  check (expected == out)
 
 	refs = "<qm2vdvs9kmd9nualp7gpcuqp02ommq191p 4ax com> <3EE5A096 98029307 hotmail com> <bc4sb4$fbmlp$1 ID-191099 news dfncis de> <3EE6DE5C A8D18620 hotmail com> <bc6qeb$g02ia$9 ID-191099 news dfncis de> <3EE70552 FFBAD8F1 hotmail com> <bc80jt$gjfab$9 ID-191099 news dfncis de> <3EE7B742 CB99E2A9 hotmail com> <bc8esv$god63$2 ID-191099 news dfncis de> <3EE83795 BAB1A91B hotmail com> <bc9o49$glr0p$1 ID-191099 news dfncis de> <3EE8F9DD 18250DED hotmail com> <1231781 L8vHGuMyzo cleeson com> <3EEB7C07 4752E42A hotmail com> <1296817 URW5Hf7Ksp pedro-loves-maide cleeson com> <3EEEF80E 861F9856 hotmail com> <28546748 CjhBzqWdrr pedro-loves-maide cleeson com> <3EF04A70 BCC38BF9 hotmail com> <3009961 k4EQsI0dRT pedro-loves-maide cleeson com> <3EF2E85E 904F3FBA hotmail com> <352040964 KGvfqQSRi4 pedro-loves-maide cleeson com> <3EFC7072 C6E6D00E hotmail com> <1622701 ZSR7dHnD1g pedro loves maide> <3F13C513 6CDFABEB hotmail com> <3F13DBF6 8000505 gmx net>";
 	msg_id = "<3f13ffeb$0$301$ba620e4c reader1 news skynet be>";
@@ -53,6 +53,11 @@ test_generate_references (void)
   out = GNKSA::remove_broken_message_ids_from_references (refs);
   check (expected == out)
 
+  refs = "as.com> <asdf <qm2vdvs9kmd9nualp7gpcuqp02ommq191p_!dfdsfsd 4ax com> <3EE5A096 98029307 hotmail com> <as";
+  expected = "<qm2vdvs9kmd9nualp7gpcuqp02ommq191p_!dfdsfsd 4ax com> <3EE5A096 98029307 hotmail com>";
+  out = GNKSA::remove_broken_message_ids_from_references (refs);
+  check (expected == out)
+
   return 0;
 }
 
@@ -199,7 +204,7 @@ static ReferencesCheck references [] =
 	},
 	/* make sure that twisted domains like [10.0.0.4] don't get stripped.
 	   see comments on pan/base/gnksa.c gnksa_check_message_id() for details. */
-	{       
+	{
 		998,
 
 		"<B8CE15E0 2DBE%frederic platzer wanadoo fr> "
diff --git a/pan/usenet-utils/gnksa.cc b/pan/usenet-utils/gnksa.cc
index b4f065c..193bc47 100644
--- a/pan/usenet-utils/gnksa.cc
+++ b/pan/usenet-utils/gnksa.cc
@@ -79,6 +79,10 @@ gnksa_init (void)
 	int i;
 	unsigned char ch;
 
+  /* '!' (char)33 is allowed for message-ids
+  http://tools.ietf.org/html/rfc5322#section-3.2.3
+  http://tools.ietf.org/html/rfc5536#section-3.1.3
+  */
 	for (ch=0; ch<UCHAR_MAX; ++ch) {
 		_unquoted_chars[ch] = isgraph(ch) && ch!='!' && ch!='(' && ch!=')' && ch!='<'
 		                                  && ch!='>' && ch!='@' && ch!=',' && ch!=';'
@@ -104,6 +108,16 @@ gnksa_init (void)
 #else
 
 static char _unquoted_chars[UCHAR_MAX] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,
+0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
+
+/*
+static char _unquoted_chars[UCHAR_MAX] = {
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
 0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@@ -112,6 +126,24 @@ static char _unquoted_chars[UCHAR_MAX] = {
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
 
+char   : 0
+char ! : 0
+char " : 0
+char # : 1
+char $ : 1
+char % : 1
+char & : 1
+char ' : 1
+char ( : 0
+char ) : 0
+char * : 1
+char + : 1
+char , : 0
+char - : 1
+char . : 0
+
+*/
+
 #endif
 
 static char _quoted_chars[UCHAR_MAX] = {
@@ -165,7 +197,7 @@ read_space (const char * start, const char ** end)
 		return true;
 	}
 	return false;
-	
+
 }
 
 static bool
@@ -314,7 +346,7 @@ gnksa_check_domain_literal (const StringView& domain)
 	bool need_closing_brace;
 	const char * pch;
 
-	// parse domain literal into ip number 
+	// parse domain literal into ip number
 
 	pch = domain.str;
 	need_closing_brace = *pch == '[';
@@ -366,11 +398,11 @@ GNKSA :: check_domain (const StringView& domain)
    while (mydomain.pop_token (token, '.'))
       ++label_qty;
 
-   // make sure we have more than one label in the domain 
+   // make sure we have more than one label in the domain
    if (label_qty < 2)
       return GNKSA::SINGLE_DOMAIN;
 
-   // check for illegal labels 
+   // check for illegal labels
    mydomain = domain;
    for (int i=0; i<label_qty-1; ++i) {
       mydomain.pop_token (token, '.');
@@ -380,14 +412,14 @@ GNKSA :: check_domain (const StringView& domain)
          return GNKSA::ILLEGAL_LABEL_HYPHEN;
    }
 
-   // last label -- toplevel domain 
+   // last label -- toplevel domain
    mydomain.pop_token (token, '.');
    switch (token.len)
    {
       case 1:
          if (isdigit((unsigned char)*token.str))
             return gnksa_check_domain_literal (domain);
-         // single-letter TLDs dont exist 
+         // single-letter TLDs dont exist
          return GNKSA::ILLEGAL_DOMAIN;
 
       case 2:
@@ -418,7 +450,7 @@ namespace
   int
   check_localpart (const StringView& localpart)
   {
-    // make sure it's not empty... 
+    // make sure it's not empty...
     if (localpart.empty())
       return GNKSA::LOCALPART_MISSING;
 
@@ -623,12 +655,12 @@ GNKSA :: do_check_from (const StringView   & from,
 {
    int addrtype = 0;
 
-   // split from 
+   // split from
    addr.clear ();
    name.clear ();
    int retval = split_from (from, addr, name, addrtype, strict);
 
-   // check address 
+   // check address
    if (retval==OK && !addr.empty())
       retval = check_address (addr);
 
@@ -681,7 +713,7 @@ namespace
     *
     * The purpose of this function is to remove severely broken,
     * usually suntactically-invalid Message-IDs, such as those
-    * missing '<', '@', or '>'. 
+    * missing '<', '@', or '>'.
     *
     * However we want to retain Message-IDs that might be sloppy,
     * such as ones that have possibly-invalid domains.
@@ -713,7 +745,7 @@ namespace
       if (pch == NULL)
          return GNKSA::ATSIGN_MISSING;
 
-      // check the domain name 
+      // check the domain name
       StringView domain (tmp.substr (pch+1, NULL));
       --domain.len; // remove trailing '>'
       if (domain.empty())
@@ -754,7 +786,7 @@ GNKSA :: remove_broken_message_ids_from_references (const StringView& references
     else if (*end == '>')
       ++end;
     v = v.substr (end, 0);
-                                                                                     
+
     // check the message-id for validity
     if (check_message_id (StringView(begin, end-begin)) == GNKSA::OK) {
       s.insert (s.end(), begin, end);
@@ -810,7 +842,7 @@ GNKSA :: generate_message_id (const StringView& domain)
 {
    std::string s;
 
-   // add unique local part to message-id 
+   // add unique local part to message-id
    s += "pan.";
    const time_t now (time(NULL));
    struct tm local_now = *gmtime (&now);
@@ -832,7 +864,7 @@ GNKSA :: generate_message_id_from_email_address (const StringView& addr)
 {
    StringView domain;
 
-   // find the domain in the email address 
+   // find the domain in the email address
    if (!addr.empty()) {
       const char * pch = addr.strchr ('@');
       if (pch != NULL)
@@ -879,7 +911,7 @@ GNKSA :: generate_references (const StringView   & references,
 ***/
 
 GNKSA::SigType
-GNKSA::is_signature_delimiter (const StringView& line) 
+GNKSA::is_signature_delimiter (const StringView& line)
 {
    switch (line.len) {
       case 2: if (!strncmp (line.str,"--"   ,2)) return SIG_NONSTANDARD;
diff --git a/pan/usenet-utils/mime-utils.cc b/pan/usenet-utils/mime-utils.cc
index 5152fc2..b4ac29b 100644
--- a/pan/usenet-utils/mime-utils.cc
+++ b/pan/usenet-utils/mime-utils.cc
@@ -69,18 +69,20 @@ using namespace pan;
 namespace pan
 {
 
-  iconv_t conv;
+  iconv_t conv(0);
+  bool iconv_inited(false);
 
   char *
   __g_mime_iconv_strndup (iconv_t cd, const char *str, size_t n)
   {
+
     size_t inleft, outleft, converted = 0;
     char *out, *outbuf;
     const char *inbuf;
     size_t outlen;
     int errnosav;
 
-    if (cd == (iconv_t) -1)
+    if (cd == (iconv_t) -1 || !iconv_inited)
       return g_strndup (str, n);
 
     outlen = n * 2 + 16;
@@ -96,7 +98,7 @@ namespace pan
 
       converted = iconv (cd, (char **) &inbuf, &inleft, &outbuf, &outleft);
 
-      if (converted != (size_t) -1 || errno == EINVAL) {
+      if (converted != (size_t) -1 && errno == 0) {
         /*
          * EINVAL  An  incomplete  multibyte sequence has been encoun­
          *         tered in the input.
diff --git a/pan/usenet-utils/mime-utils.h b/pan/usenet-utils/mime-utils.h
index bcd17a9..a89da0a 100644
--- a/pan/usenet-utils/mime-utils.h
+++ b/pan/usenet-utils/mime-utils.h
@@ -37,7 +37,7 @@ namespace pan
   /**
    * Utilities to build and parse GMimeMesasges.
    *
-   * Most of nastiness this is to handle Usenet's use of chainging together
+   * Most of this nastiness is to handle Usenet's use of chainging together
    * multiple articles as parts of a whole.  This code tries to build
    * a multipart GMimeMessage from multiple posts when necessary, and to
    * also handle Usenet's loose standards for uu/yenc by checking each line
@@ -72,6 +72,7 @@ namespace pan
   void pan_g_mime_message_add_recipients_from_string (GMimeMessage *message, GMimeRecipientType type, const char *string);
 
   extern iconv_t conv;
+  extern bool iconv_inited;
 
   char * __g_mime_iconv_strndup (iconv_t cd, const char *str, size_t n);
 



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