Re: [Proposal/Patch 0/3] Using GIO for POP3



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



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