Hi Peter: Am 04.04.17 22:32 schrieb(en) Peter Bloomfield:
Oh, that is strange - actually, it should show the real counts here (i.e. "..exceeds the maximum allowed length 998").Yes, it was actually "reply length 1153 exceeds the maximum allowed length 998"
Ouch. So someone is just violating the standard...
Anyway, a fix would be easy...RFC 5322 also says that "Receiving implementations would do well to handle an arbitrarily large number of characters in a line for robustness sake." To be "liberal in what [we] accept from others", I feel that we should not treat an overlong line as a failure.
I see - I should read the standards *completely*... :-/ Attached is a simple patch, on top of the original package, which removes the line length limit for POP3. It also removes the respective tests from the unit test application.
I ran an older Balsa to download and delete that message from the server, and it rendered just fine--I can send you a copy, but of course the long line(s) might get cropped along the way!
As you are right that we should be liberal in accepting somewhat broken data, I don't think it's necessary... Probably some broken spam, not worth the time to investigate it! Thanks a lot for testing! Cheers, Albrecht.
diff --git a/libnetclient/net-client-pop.c b/libnetclient/net-client-pop.c index c908135..7145276 100644 --- a/libnetclient/net-client-pop.c +++ b/libnetclient/net-client-pop.c @@ -30,8 +30,9 @@ struct _NetClientPopPrivate { /* Note: the maximum line length of a message body downloaded from the POP3 server may be up to 998 chars, excluding the terminating - * CRLF, see RFC 5322, Sect. 2.1.1 */ -#define MAX_POP_LINE_LEN 998U + * CRLF, see RFC 5322, Sect. 2.1.1. However, it also states that "Receiving implementations would do well to handle an arbitrarily + * large number of characters in a line for robustness sake", so we actually accept lines from POP3 of unlimited length. */ +#define MAX_POP_LINE_LEN 0U #define POP_DATA_BUF_SIZE 4096U diff --git a/libnetclient/net-client.c b/libnetclient/net-client.c index 70dc3ac..c7b73f7 100644 --- a/libnetclient/net-client.c +++ b/libnetclient/net-client.c @@ -51,7 +51,7 @@ net_client_new(const gchar *host_and_port, guint16 default_port, gsize max_line_ { NetClient *client; - g_return_val_if_fail((host_and_port != NULL) && (max_line_len > 0U), NULL); + g_return_val_if_fail(host_and_port != NULL, NULL); client = NET_CLIENT(g_object_new(NET_CLIENT_TYPE, NULL)); @@ -73,7 +73,7 @@ net_client_configure(NetClient *client, const gchar *host_and_port, guint16 defa NetClientPrivate *priv; gboolean result; - g_return_val_if_fail(NET_IS_CLIENT(client) && (host_and_port != NULL) && (max_line_len > 0U), FALSE); + g_return_val_if_fail(NET_IS_CLIENT(client) && (host_and_port != NULL), FALSE); priv = client->priv; if (priv->plain_conn != NULL) { @@ -162,7 +162,7 @@ net_client_read_line(NetClient *client, gchar **recv_line, GError **error) line_buf = g_data_input_stream_read_line(client->priv->istream, &length, NULL, &read_err); if (line_buf != NULL) { /* check that the protocol-specific maximum line length is not exceeded */ - if (length > client->priv->max_line_len) { + if ((client->priv->max_line_len > 0U) && (length > client->priv->max_line_len)) { g_set_error(error, NET_CLIENT_ERROR_QUARK, (gint) NET_CLIENT_ERROR_LINE_TOO_LONG, _("reply length %lu exceeds the maximum allowed length %lu"), length, client->priv->max_line_len); g_free(line_buf); @@ -226,7 +226,7 @@ net_client_vwrite_line(NetClient *client, const gchar *format, va_list args, GEr g_return_val_if_fail(NET_IS_CLIENT(client) && (format != NULL), FALSE); buf_len = g_vsnprintf(buffer, client->priv->max_line_len - 2U, format, args); - if ((buf_len < 0) || ((gsize) buf_len > (client->priv->max_line_len - 2U))) { + if ((buf_len < 0) || ((client->priv->max_line_len > 0U) && ((gsize) buf_len > (client->priv->max_line_len - 2U)))) { g_set_error(error, NET_CLIENT_ERROR_QUARK, (gint) NET_CLIENT_ERROR_LINE_TOO_LONG, _("line too long")); result = FALSE; } else { diff --git a/libnetclient/net-client.h b/libnetclient/net-client.h index 286b90b..be89df1 100644 --- a/libnetclient/net-client.h +++ b/libnetclient/net-client.h @@ -80,7 +80,7 @@ GType net_client_get_type(void) * * @param host_and_port remote host and port or service, separated by a colon, which shall be connected * @param default_port default remote port if host_and_port does not contain a port - * @param max_line_len maximum line length supported by the underlying protocol + * @param max_line_len maximum line length supported by the underlying protocol, 0 for no limit * @return the net network client object * * Create a new network client object with the passed parameters. Call <tt>g_object_unref()</tt> on it to shut down the connection @@ -94,7 +94,7 @@ NetClient *net_client_new(const gchar *host_and_port, guint16 default_port, gsiz * @param client network client * @param host_and_port remote host and port or service, separated by a colon, which shall be connected * @param default_port default remote port if host_and_port does not contain a port - * @param max_line_len maximum line length supported by the underlying protocol + * @param max_line_len maximum line length supported by the underlying protocol, 0 for no limit * @param error filled with error information on error * @return TRUE is the connection was successful, FALSE on error * diff --git a/libnetclient/test/tests.c b/libnetclient/test/tests.c index 06ac9e5..053d48c 100644 --- a/libnetclient/test/tests.c +++ b/libnetclient/test/tests.c @@ -59,7 +59,6 @@ test_basic(void) gchar *read_res; sput_fail_unless(net_client_new(NULL, 65000, 42) == NULL, "missing host"); - sput_fail_unless(net_client_new("localhost", 65000, 0) == NULL, "zero max line length"); sput_fail_unless((basic = net_client_new("localhost", 65000, 42)) != NULL, "localhost; port 65000"); sput_fail_unless(net_client_get_host(NULL) == NULL, "get host w/o client"); @@ -70,7 +69,6 @@ test_basic(void) sput_fail_unless((basic = net_client_new("www.google.com", 80, 1)) != NULL, "www.google.com:80; port 0"); sput_fail_unless(net_client_configure(NULL, "localhost", 65000, 42, NULL) == FALSE, "configure w/o client"); sput_fail_unless(net_client_configure(basic, NULL, 65000, 42, NULL) == FALSE, "configure w/o host"); - sput_fail_unless(net_client_configure(basic, "localhost", 65000, 0, NULL) == FALSE, "configure w/ zero max line length"); sput_fail_unless(net_client_configure(basic, "localhost", 65000, 42, NULL) == TRUE, "configure localhost:65000 ok"); sput_fail_unless(net_client_set_timeout(NULL, 3) == FALSE, "set timeout w/o client");
Attachment:
pgpz2KB0_FsUd.pgp
Description: PGP signature