+++ /dev/null
-diff --git a/AUTHORS b/AUTHORS
-index f65085d..b08ec55 100644
---- a/AUTHORS
-+++ b/AUTHORS
-@@ -215,6 +215,9 @@ Hugo Haas <hugo@larve.net>
- Minor random hacking
- debian/watch file
-
-+<incoherent@mail.ru>
-+ bzip2 decoding fix and rewrite
-+
- Ingo Blechschmidt <iblech@web.de>
- German translation updates
-
-diff --git a/src/encoding/bzip2.c b/src/encoding/bzip2.c
-index 0291a39..c33b88e 100644
---- a/src/encoding/bzip2.c
-+++ b/src/encoding/bzip2.c
-@@ -12,6 +12,7 @@ #endif
- #ifdef HAVE_BZLIB_H
- #include <bzlib.h> /* Everything needs this after stdio.h */
- #endif
-+#include <errno.h>
-
- #include "elinks.h"
-
-@@ -20,29 +21,32 @@ #include "encoding/encoding.h"
- #include "util/memory.h"
-
-
-+#define ELINKS_BZ_BUFFER_LENGTH BZ_MAX_UNUSED
-+
- struct bz2_enc_data {
-- FILE *file;
-- BZFILE *bzfile;
-- int last_read; /* If err after last bzRead() was BZ_STREAM_END.. */
-+ int fdread;
-+ bz_stream fbz_stream;
-+ int last_read; /* If err after last bzDecompress was BZ_STREAM_END.. */
-+ unsigned char buf[ELINKS_BZ_BUFFER_LENGTH];
- };
-
--/* TODO: When it'll be official, use bzdopen() from Yoshioka Tsuneo. --pasky */
--
- static int
- bzip2_open(struct stream_encoded *stream, int fd)
- {
- struct bz2_enc_data *data = mem_alloc(sizeof(*data));
- int err;
-
-+ stream->data = 0;
- if (!data) {
- return -1;
- }
-- data->last_read = 0;
--
-- data->file = fdopen(fd, "rb");
-+ memset(data, 0, sizeof(struct bz2_enc_data) - ELINKS_BZ_BUFFER_LENGTH);
-
-- data->bzfile = BZ2_bzReadOpen(&err, data->file, 0, 0, NULL, 0);
-- if (!data->bzfile) {
-+ data->last_read = 0;
-+ data->fdread = fd;
-+
-+ err = BZ2_bzDecompressInit(&data->fbz_stream, 0, 0);
-+ if (err != BZ_OK) {
- mem_free(data);
- return -1;
- }
-@@ -58,17 +62,44 @@ bzip2_read(struct stream_encoded *stream
- struct bz2_enc_data *data = (struct bz2_enc_data *) stream->data;
- int err = 0;
-
-- if (data->last_read)
-- return 0;
-+ if (!data) return -1;
-
-- len = BZ2_bzRead(&err, data->bzfile, buf, len);
-+ assert(len > 0);
-
-- if (err == BZ_STREAM_END)
-- data->last_read = 1;
-- else if (err)
-- return -1;
-+ if (data->last_read) return 0;
-+
-+ data->fbz_stream.avail_out = len;
-+ data->fbz_stream.next_out = buf;
-+
-+ do {
-+ if (data->fbz_stream.avail_in == 0) {
-+ int l = safe_read(data->fdread, data->buf,
-+ ELINKS_BZ_BUFFER_LENGTH);
-
-- return len;
-+ if (l == -1) {
-+ if (errno == EAGAIN)
-+ break;
-+ else
-+ return -1; /* I/O error */
-+ } else if (l == 0) {
-+ /* EOF. It is error: we wait for more bytes */
-+ return -1;
-+ }
-+
-+ data->fbz_stream.next_in = data->buf;
-+ data->fbz_stream.avail_in = l;
-+ }
-+
-+ err = BZ2_bzDecompress(&data->fbz_stream);
-+ if (err == BZ_STREAM_END) {
-+ data->last_read = 1;
-+ break;
-+ } else if (err != BZ_OK) {
-+ return -1;
-+ }
-+ } while (data->fbz_stream.avail_out > 0);
-+
-+ return len - data->fbz_stream.avail_out;
- }
-
- static unsigned char *
-@@ -148,11 +179,13 @@ static void
- bzip2_close(struct stream_encoded *stream)
- {
- struct bz2_enc_data *data = (struct bz2_enc_data *) stream->data;
-- int err;
-
-- BZ2_bzReadClose(&err, data->bzfile);
-- fclose(data->file);
-- mem_free(data);
-+ if (data) {
-+ BZ2_bzDecompressEnd(&data->fbz_stream);
-+ close(data->fdread);
-+ mem_free(data);
-+ stream->data = 0;
-+ }
- }
-
- static unsigned char *bzip2_extensions[] = { ".bz2", ".tbz", NULL };
-diff --git a/src/protocol/http/http.c b/src/protocol/http/http.c
-index 87d468d..6f7469f 100644
---- a/src/protocol/http/http.c
-+++ b/src/protocol/http/http.c
-@@ -720,20 +720,13 @@ http_send_header(struct socket *socket)
- #if defined(CONFIG_GZIP) || defined(CONFIG_BZIP2)
- add_to_string(&header, "Accept-Encoding: ");
-
--#ifdef BUG_517
- #ifdef CONFIG_BZIP2
- add_to_string(&header, "bzip2");
- #endif
--#endif
--
- #ifdef CONFIG_GZIP
--
--#ifdef BUG_517
- #ifdef CONFIG_BZIP2
- add_to_string(&header, ", ");
- #endif
--#endif
--
- add_to_string(&header, "gzip");
- #endif
- add_crlf_to_string(&header);
-@@ -1810,13 +1803,11 @@ #ifdef CONFIG_GZIP
- && (!strcasecmp(d, "gzip") || !strcasecmp(d, "x-gzip")))
- conn->content_encoding = ENCODING_GZIP;
- #endif
--#ifdef BUG_517
- #ifdef CONFIG_BZIP2
- if (file_encoding != ENCODING_BZIP2
- && (!strcasecmp(d, "bzip2") || !strcasecmp(d, "x-bzip2")))
- conn->content_encoding = ENCODING_BZIP2;
- #endif
--#endif
- mem_free(d);
- }
-
+++ /dev/null
-diff --git a/src/protocol/http/http.c b/src/protocol/http/http.c
-index 1264f6f..6de3078 100644
---- a/src/protocol/http/http.c
-+++ b/src/protocol/http/http.c
-@@ -983,29 +983,23 @@ decompress_data(struct connection *conn,
- int *new_len)
- {
- struct http_connection_info *http = conn->info;
-- /* to_read is number of bytes to be read from the decoder. It is 65536
-- * (then we are just emptying the decoder buffer as we finished the walk
-- * through the incoming stream already) or PIPE_BUF / 2 (when we are
-- * still walking through the stream - then we write PIPE_BUF / 2 to the
-- * pipe and read it back to the decoder ASAP; the point is that we can't
-- * write more than PIPE_BUF to the pipe at once, but we also have to
-- * never let read_encoded() (gzread(), in fact) to empty the pipe - that
-- * causes further malfunction of zlib :[ ... so we will make sure that
-- * we will always have at least PIPE_BUF / 2 + 1 in the pipe (returning
-- * early otherwise)). */
-- int to_read = PIPE_BUF / 2, did_read = 0;
-+ enum { NORMAL, FINISHING } state = NORMAL;
-+ int did_read = 0;
- int *length_of_block;
- unsigned char *output = NULL;
-
-- length_of_block = (http->length == LEN_CHUNKED ? &http->chunk_remaining
-- : &http->length);
--
- #define BIG_READ 65536
-- if (!*length_of_block) {
-- /* Going to finish this decoding bussiness. */
-- /* Some nicely big value - empty encoded output queue by reading
-- * big chunks from it. */
-- to_read = BIG_READ;
-+
-+ if (http->length == LEN_CHUNKED) {
-+ if (http->chunk_remaining == CHUNK_ZERO_SIZE)
-+ state = FINISHING;
-+ length_of_block = &http->chunk_remaining;
-+ } else {
-+ length_of_block = &http->length;
-+ if (!*length_of_block) {
-+ /* Going to finish this decoding bussiness. */
-+ state = FINISHING;
-+ }
- }
-
- if (conn->content_encoding == ENCODING_NONE) {
-@@ -1024,14 +1018,13 @@ #define BIG_READ 65536
- }
-
- do {
-- int init = 0;
-+ unsigned char *tmp;
-
-- if (to_read == PIPE_BUF / 2) {
-+ if (state == NORMAL) {
- /* ... we aren't finishing yet. */
-- int written = safe_write(conn->stream_pipes[1], data,
-- len > to_read ? to_read : len);
-+ int written = safe_write(conn->stream_pipes[1], data, len);
-
-- if (written > 0) {
-+ if (written >= 0) {
- data += written;
- len -= written;
-
-@@ -1042,7 +1035,7 @@ #define BIG_READ 65536
- * non-keep-alive and chunked */
- if (!http->length) {
- /* That's all, folks - let's finish this. */
-- to_read = BIG_READ;
-+ state = FINISHING;
- } else if (!len) {
- /* We've done for this round (but not done
- * completely). Thus we will get out with
-@@ -1061,28 +1054,26 @@ #define BIG_READ 65536
- conn->stream = open_encoded(conn->stream_pipes[0],
- conn->content_encoding);
- if (!conn->stream) return NULL;
-- /* On "startup" pipe is treated with care, but if everything
-- * was already written to the pipe, caution isn't necessary */
-- else if (to_read != BIG_READ) init = 1;
-- } else init = 0;
-+ }
-
-- output = (unsigned char *) mem_realloc(output, *new_len + to_read);
-- if (!output) break;
-+ tmp = mem_realloc(output, *new_len + BIG_READ);
-+ if (!tmp) break;
-+ output = tmp;
-+
-+ did_read = read_encoded(conn->stream, output + *new_len, BIG_READ);
-
-- did_read = read_encoded(conn->stream, output + *new_len,
-- init ? PIPE_BUF / 32 : to_read); /* on init don't read too much */
- if (did_read > 0) *new_len += did_read;
-- else if (did_read == -1) {
-- mem_free_set(&output, NULL);
-- *new_len = 0;
-- break; /* Loop prevention (bug 517), is this correct ? --Zas */
-+ else {
-+ if (did_read < 0) state = FINISHING;
-+ break;
- }
-- } while (len || did_read == BIG_READ);
-+ } while (len || (did_read == BIG_READ));
-
-- shutdown_connection_stream(conn);
-+ if (state == FINISHING) shutdown_connection_stream(conn);
- return output;
- }
-
-+
- static int
- is_line_in_buffer(struct read_buffer *rb)
- {
-@@ -1206,11 +1197,8 @@ read_chunked_http_data(struct connection
- } else {
- unsigned char *data;
- int data_len;
-- int len;
- int zero = (http->chunk_remaining == CHUNK_ZERO_SIZE);
--
-- if (zero) http->chunk_remaining = 0;
-- len = http->chunk_remaining;
-+ int len = zero ? 0 : http->chunk_remaining;
-
- /* Maybe everything necessary didn't come yet.. */
- int_upper_bound(&len, rb->length);
-@@ -1850,8 +1838,7 @@ #endif
- conn->cached->encoding_info = stracpy(get_encoding_name(conn->content_encoding));
- }
-
-- if (http->length == -1
-- || (PRE_HTTP_1_1(http->recv_version) && http->close))
-+ if (http->length == -1 || http->close)
- socket->state = SOCKET_END_ONCLOSE;
-
- read_http_data(socket, rb);
+++ /dev/null
-bug 638: Save, set and restore the DISPLAY environment variable.
-
-Thanks to this trick the appropriate handler is executed,
-even in a mixed (X11, framebuffer) environment.
-
----
-commit 65a3518a912d6cc6aa38cee4a4142299d7a25cc7
-tree 47b6a1c4af22420fef498ac26dd0955e79428024
-parent 81f8ee1fa2b94ef40460eb4a42710e1ed9e22c98
-author Witold Filipczyk <witekfl@poczta.onet.pl> Sun, 16 Mar 2008 16:29:32 +0100
-committer Witold Filipczyk <nobody@nowhere> Sun, 16 Mar 2008 16:29:32 +0100
-
- configure.in | 1 +
- src/mime/backend/mailcap.c | 58 +++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 58 insertions(+), 1 deletions(-)
-
-diff --git a/configure.in b/configure.in
-index 0a867ae..5cfeaa9 100644
---- a/configure.in
-+++ b/configure.in
-@@ -307,6 +307,7 @@ AC_CHECK_FUNCS(gettimeofday clock_gettime)
- AC_CHECK_FUNCS([cygwin_conv_to_full_win32_path])
-
- AC_CHECK_FUNCS(setenv putenv, HAVE_SETENV_OR_PUTENV=yes)
-+AC_CHECK_FUNCS(unsetenv)
- AC_CHECK_FUNCS(getuid, HAVE_GETUID=yes)
- AC_CHECK_FUNCS(geteuid, HAVE_GETEUID=yes)
-
-diff --git a/src/mime/backend/mailcap.c b/src/mime/backend/mailcap.c
-index 76ea78b..70e270d 100644
---- a/src/mime/backend/mailcap.c
-+++ b/src/mime/backend/mailcap.c
-@@ -646,8 +646,57 @@ get_mailcap_entry(unsigned char *type)
- return entry;
- }
-
-+#if defined(HAVE_SETENV) || defined(HAVE_PUTENV)
-+/* restore == 0 set DISPLAY
-+ * restore == 1 restore DISPLAY
-+ */
-+static void
-+set_display(int xwin, int restore)
-+{
-+ static unsigned char *display = NULL;
-+
-+ if (!restore) {
-+ display = getenv("DISPLAY");
-+ if (display) display = stracpy(display);
-+ if (xwin) {
-+#ifdef HAVE_SETENV
-+ setenv("DISPLAY", ":0", 1);
-+#else
-+ putenv("DISPLAY=:0");
-+#endif
-+ } else {
-+#ifdef HAVE_UNSETENV
-+ unsetenv("DISPLAY");
-+#else
-+ putenv("DISPLAY");
-+#endif
-+ }
-+ } else { /* restore DISPLAY */
-+ if (display) {
-+#ifdef HAVE_SETENV
-+ setenv("DISPLAY", display, 1);
-+#else
-+ {
-+ static unsigned char DISPLAY[1024] = { 'D','I','S','P','L','A','Y','=' };
-+
-+ strncpy(DISPLAY + 8, display, 1023 - 8);
-+ putenv(DISPLAY);
-+ }
-+#endif
-+ mem_free(display);
-+ } else {
-+#ifdef HAVE_UNSETENV
-+ unsetenv("DISPLAY");
-+#else
-+ putenv("DISPLAY");
-+#endif
-+ }
-+ }
-+}
-+#endif
-+
- static struct mime_handler *
--get_mime_handler_mailcap(unsigned char *type, int options)
-+get_mime_handler_mailcap(unsigned char *type, int xwin)
- {
- struct mailcap_entry *entry;
- struct mime_handler *handler;
-@@ -658,7 +707,14 @@ get_mime_handler_mailcap(unsigned char *type, int options)
- || (!mailcap_map && !init_mailcap_map()))
- return NULL;
-
-+#if defined(HAVE_SETENV) || defined(HAVE_PUTENV)
-+ set_display(xwin, 0);
-+#endif
- entry = get_mailcap_entry(type);
-+
-+#if defined(HAVE_SETENV) || defined(HAVE_PUTENV)
-+ set_display(xwin, 1);
-+#endif
- if (!entry) return NULL;
-
- program = format_command(entry->command, type, entry->copiousoutput);