1 diff --git a/AUTHORS b/AUTHORS
2 index f65085d..b08ec55 100644
5 @@ -215,6 +215,9 @@ Hugo Haas <hugo@larve.net>
10 + bzip2 decoding fix and rewrite
12 Ingo Blechschmidt <iblech@web.de>
13 German translation updates
15 diff --git a/src/encoding/bzip2.c b/src/encoding/bzip2.c
16 index 0291a39..c33b88e 100644
17 --- a/src/encoding/bzip2.c
18 +++ b/src/encoding/bzip2.c
19 @@ -12,6 +12,7 @@ #endif
21 #include <bzlib.h> /* Everything needs this after stdio.h */
27 @@ -20,29 +21,32 @@ #include "encoding/encoding.h"
28 #include "util/memory.h"
31 +#define ELINKS_BZ_BUFFER_LENGTH BZ_MAX_UNUSED
36 - int last_read; /* If err after last bzRead() was BZ_STREAM_END.. */
38 + bz_stream fbz_stream;
39 + int last_read; /* If err after last bzDecompress was BZ_STREAM_END.. */
40 + unsigned char buf[ELINKS_BZ_BUFFER_LENGTH];
43 -/* TODO: When it'll be official, use bzdopen() from Yoshioka Tsuneo. --pasky */
46 bzip2_open(struct stream_encoded *stream, int fd)
48 struct bz2_enc_data *data = mem_alloc(sizeof(*data));
55 - data->last_read = 0;
57 - data->file = fdopen(fd, "rb");
58 + memset(data, 0, sizeof(struct bz2_enc_data) - ELINKS_BZ_BUFFER_LENGTH);
60 - data->bzfile = BZ2_bzReadOpen(&err, data->file, 0, 0, NULL, 0);
61 - if (!data->bzfile) {
62 + data->last_read = 0;
65 + err = BZ2_bzDecompressInit(&data->fbz_stream, 0, 0);
70 @@ -58,17 +62,44 @@ bzip2_read(struct stream_encoded *stream
71 struct bz2_enc_data *data = (struct bz2_enc_data *) stream->data;
74 - if (data->last_read)
76 + if (!data) return -1;
78 - len = BZ2_bzRead(&err, data->bzfile, buf, len);
81 - if (err == BZ_STREAM_END)
82 - data->last_read = 1;
85 + if (data->last_read) return 0;
87 + data->fbz_stream.avail_out = len;
88 + data->fbz_stream.next_out = buf;
91 + if (data->fbz_stream.avail_in == 0) {
92 + int l = safe_read(data->fdread, data->buf,
93 + ELINKS_BZ_BUFFER_LENGTH);
97 + if (errno == EAGAIN)
100 + return -1; /* I/O error */
101 + } else if (l == 0) {
102 + /* EOF. It is error: we wait for more bytes */
106 + data->fbz_stream.next_in = data->buf;
107 + data->fbz_stream.avail_in = l;
110 + err = BZ2_bzDecompress(&data->fbz_stream);
111 + if (err == BZ_STREAM_END) {
112 + data->last_read = 1;
114 + } else if (err != BZ_OK) {
117 + } while (data->fbz_stream.avail_out > 0);
119 + return len - data->fbz_stream.avail_out;
122 static unsigned char *
123 @@ -148,11 +179,13 @@ static void
124 bzip2_close(struct stream_encoded *stream)
126 struct bz2_enc_data *data = (struct bz2_enc_data *) stream->data;
129 - BZ2_bzReadClose(&err, data->bzfile);
130 - fclose(data->file);
133 + BZ2_bzDecompressEnd(&data->fbz_stream);
134 + close(data->fdread);
140 static unsigned char *bzip2_extensions[] = { ".bz2", ".tbz", NULL };
141 diff --git a/src/protocol/http/http.c b/src/protocol/http/http.c
142 index 87d468d..6f7469f 100644
143 --- a/src/protocol/http/http.c
144 +++ b/src/protocol/http/http.c
145 @@ -720,20 +720,13 @@ http_send_header(struct socket *socket)
146 #if defined(CONFIG_GZIP) || defined(CONFIG_BZIP2)
147 add_to_string(&header, "Accept-Encoding: ");
151 add_to_string(&header, "bzip2");
159 add_to_string(&header, ", ");
163 add_to_string(&header, "gzip");
165 add_crlf_to_string(&header);
166 @@ -1810,13 +1803,11 @@ #ifdef CONFIG_GZIP
167 && (!strcasecmp(d, "gzip") || !strcasecmp(d, "x-gzip")))
168 conn->content_encoding = ENCODING_GZIP;
172 if (file_encoding != ENCODING_BZIP2
173 && (!strcasecmp(d, "bzip2") || !strcasecmp(d, "x-bzip2")))
174 conn->content_encoding = ENCODING_BZIP2;