ELinks 0.13.GIT shows garbage at
<http://www.dwheeler.com/oss_fs_why.html> when bzip2
decompression is enabled.  I added some logging:

========================================================================
diff --git a/src/encoding/bzip2.c b/src/encoding/bzip2.c
index 8e7139a..c473aee 100644
--- a/src/encoding/bzip2.c
+++ b/src/encoding/bzip2.c
@@ -94,9 +94,19 @@ bzip2_read(struct stream_encoded *stream, unsigned char 
*buf, int len)
        data->fbz_stream.next_out = buf;
 
        do {
+               char *last_out = data->fbz_stream.next_out;
+
                if (data->fbz_stream.avail_in == 0) {
                        int l = safe_read(data->fdread, data->buf,
                                          ELINKS_BZ_BUFFER_LENGTH);
+                       int save_errno = errno;
+                       fprintf(stderr, "[[bzip2 read from fd: errno=%d, 
in=%d]]\n<<",
+                               (int) save_errno,
+                               (int) l);
+                       if (l > 0)
+                               fwrite(data->buf, l, 1, stderr);
+                       fprintf(stderr, ">>\n");
+                       errno = save_errno;
 
                        if (l == -1) {
                                if (errno == EAGAIN)
@@ -112,7 +122,19 @@ bzip2_read(struct stream_encoded *stream, unsigned char 
*buf, int len)
                        data->fbz_stream.avail_in = l;
                }
 
+               fprintf(stderr, "[[bzip2 to decompress: avail_in=%d, 
avail_out=%d]]\n<<",
+                       (int) data->fbz_stream.avail_in,
+                       (int) data->fbz_stream.avail_out);
+               fwrite(data->fbz_stream.next_in, data->fbz_stream.avail_in, 1, 
stderr);
+               fprintf(stderr, ">>\n");
                err = BZ2_bzDecompress(&data->fbz_stream);
+               fprintf(stderr, "[[bzip2 from decompress: err=%d, avail_in=%d, 
avail_out=%d, out=%d]]\n<<",
+                       (int) err,
+                       (int) data->fbz_stream.avail_in,
+                       (int) data->fbz_stream.avail_out,
+                       (int) (data->fbz_stream.next_out - last_out));
+               fwrite(last_out, data->fbz_stream.next_out - last_out, 1, 
stderr);
+               fprintf(stderr, ">>\n");
                if (err == BZ_STREAM_END) {
                        data->last_read = 1;
                        break;
@@ -122,6 +144,10 @@ bzip2_read(struct stream_encoded *stream, unsigned char 
*buf, int len)
        } while (data->fbz_stream.avail_out > 0);
 
        assert(len - data->fbz_stream.avail_out == data->fbz_stream.next_out - 
(char *) buf);
+       fprintf(stderr, "[[bzip2 returning: out=%d]]\n<<",
+               (int) (len - data->fbz_stream.avail_out));
+       fwrite(buf, len - data->fbz_stream.avail_out, 1, stderr);
+       fprintf(stderr, ">>\n");
        return len - data->fbz_stream.avail_out;
 }
 
diff --git a/src/network/socket.c b/src/network/socket.c
index 304ba8f..9ea3e07 100644
--- a/src/network/socket.c
+++ b/src/network/socket.c
@@ -69,7 +69,7 @@ struct connect_info {
 
 
 /* To enable logging of tranfers, for debugging purposes. */
-#if 0
+#if 1
 
 #define DEBUG_TRANSFER_LOGFILE "/tmp/log"
 
========================================================================

The logs show that the safe_read() in bzip2_read() does not get
all of the body bytes that ELinks receives from the server.
After bzip2_read() receives EAGAIN from safe_read() and returns
0, something skips 1460 bytes.  I think this happens because
decompress_data() in src/protocol/http/http.c sees that did_read
== 0 and breaks the loop regardless of len, even though the
caller assumes that decompress_data() always uses all of the
input bytes.

The following patch fixes this for me.  Do you think it could
cause any problems?

========================================================================
diff --git a/src/protocol/http/http.c b/src/protocol/http/http.c
index 260754f..ab22093 100644
--- a/src/protocol/http/http.c
+++ b/src/protocol/http/http.c
@@ -1101,8 +1101,8 @@ decompress_data(struct connection *conn, unsigned char 
*data, int len,
                did_read = read_encoded(conn->stream, output + *new_len, 
BIG_READ);
 
                if (did_read > 0) *new_len += did_read;
-               else {
-                       if (did_read < 0) state = FINISHING;
+               else if (did_read < 0) {
+                       state = FINISHING;
                        break;
                }
        } while (len || (did_read == BIG_READ));
========================================================================

Attachment: pgpTYImgoJUZE.pgp
Description: PGP signature

_______________________________________________
elinks-dev mailing list
[email protected]
http://linuxfromscratch.org/mailman/listinfo/elinks-dev

Reply via email to