aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuido Günther <agx@sigxcpu.org>2014-03-01 10:17:13 +0100
committerGuido Günther <agx@sigxcpu.org>2014-03-01 10:23:31 +0100
commita76ea3fbda245337ddd85c7f92cb8fdf0917835b (patch)
treef85169e89f5a2bd0ad351eee3495a81df8a9006b /src
parent8447b03c0a53c44b4051eb223a76c2d5fd24ea67 (diff)
Unbreak gzip decompression on larger query results
g_converter_convert doesn't guarantee to convert all data when we set G_CONVERTER_INPUT_AT_END so make sure we continue to process the data. Fixes errors like ** (process:4072): WARNING **: Unhandled condition 1 Traceback (most recent call last): File "examples/trip-query.py", line 47, in trips_cb raise Exception("Failed to find any trips") Exception: Failed to find any trips Error: timed out Thanks: Matthias Schmitz for the report
Diffstat (limited to 'src')
-rw-r--r--src/providers/de-db.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/src/providers/de-db.c b/src/providers/de-db.c
index d58aba2..6857eb4 100644
--- a/src/providers/de-db.c
+++ b/src/providers/de-db.c
@@ -538,7 +538,7 @@ decompress (const gchar *in, gsize inlen,
gsize read, written;
GConverter *decomp = NULL;
GConverterResult conv;
- gsize outbuflen = inlen * 2;
+ gsize outbuflen, buflen, outpos = 0, inpos = 0;
gchar *outbuf = NULL;
g_return_val_if_fail (inlen > 0, ret);
@@ -546,43 +546,49 @@ decompress (const gchar *in, gsize inlen,
g_return_val_if_fail (err, ret);
decomp = (GConverter *)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
- while (TRUE) {
- g_free (outbuf);
- outbuf = g_try_malloc (outbuflen);
- if (outbuf == NULL)
- break;
+
+ outbuflen = buflen = inlen * 2;
+ outbuf = g_try_malloc (outbuflen);
+ if (outbuf == NULL)
+ goto out;
+
+ do {
conv = g_converter_convert (decomp,
- in, inlen,
- outbuf, outbuflen,
+ (in + inpos), inlen,
+ (outbuf + outpos), buflen,
G_CONVERTER_INPUT_AT_END,
&read, &written,
err);
- if (conv == G_CONVERTER_ERROR) {
- if ((*err)->code == G_IO_ERROR_NO_SPACE) {
- outbuflen *= 2;
- g_clear_error (err);
- continue;
- } else {
- break;
- }
- } else if (conv == G_CONVERTER_FINISHED) {
- if (read != inlen) {
- g_warning ("Expected %" G_GSIZE_FORMAT
- ", got %" G_GSIZE_FORMAT, inlen, read);
- break;
- }
+
+ switch (conv) {
+ case G_CONVERTER_ERROR:
+ goto out;
+ case G_CONVERTER_FINISHED:
+ outpos += written;
ret = 0;
+ goto out;
+ case G_CONVERTER_CONVERTED:
+ outpos += written;
+ inpos += read;
+ inlen -= read;
+ if (outbuflen - written < buflen) {
+ outbuflen += buflen;
+ outbuf = g_try_realloc (outbuf, outbuflen);
+ if (outbuf == NULL)
+ goto out;
+ }
break;
- } else {
+ case G_CONVERTER_FLUSHED:
+ default:
g_warning ("Unhandled condition %d", conv);
- ret = -1;
- break;
+ goto out;
}
- }
+ } while (TRUE);
+out:
if (ret == 0) {
*out = outbuf;
- *outlen = written;
+ *outlen = outpos;
} else
g_free (outbuf);