[pan2] * a few fixes to iconv * https://bugzilla.gnome.org/show_bug.cgi?id=666199
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2] * a few fixes to iconv * https://bugzilla.gnome.org/show_bug.cgi?id=666199
- Date: Sun, 18 Dec 2011 15:12:31 +0000 (UTC)
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]