Author: cazfi
Date: Tue Sep 22 21:17:11 2015
New Revision: 29954

URL: http://svn.gna.org/viewcvs/freeciv?rev=29954&view=rev
Log:
Increase xz decompression memory usage limit to 65Mb

Reported by Christian Knoke <chrisk>

See bug #23891

Modified:
    branches/S2_6/utility/ioz.c

Modified: branches/S2_6/utility/ioz.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/utility/ioz.c?rev=29954&r1=29953&r2=29954&view=diff
==============================================================================
--- branches/S2_6/utility/ioz.c (original)
+++ branches/S2_6/utility/ioz.c Tue Sep 22 21:17:11 2015
@@ -74,12 +74,15 @@
 #define XZ_DECODER_TEST_SIZE (4*1024)      /* 4kb */
 
 /* In my tests 7Mb proved to be not enough and with 10Mb decompression
-   succeeded. */
-#define XZ_DECODER_MEMLIMIT (15*1024*1024) /* 15Mb */
+   succeeded in typical case. */
+#define XZ_DECODER_MEMLIMIT (65*1024*1024)        /* 65Mb */
+#define XZ_DECODER_MEMLIMIT_STEP (25*1024*1024)   /* Increase 25Mb at a time */
+#define XZ_DECODER_MEMLIMIT_FINAL (100*1024*1024) /* 100Mb */
 
 struct xz_struct {
   lzma_stream stream;
   int out_index;
+  uint64_t memlimit;
 
   /* liblzma bug workaround. This is what stream.avail_out should be,
      calculated correctly. Used only when reading file. */
@@ -104,6 +107,7 @@
 };
 
 static bool xz_outbuffer_to_file(fz_FILE *fp, lzma_action action);
+static void xz_action(fz_FILE *fp, lzma_action action);
 
 #endif /* FREECIV_HAVE_LIBLZMA */
 
@@ -278,9 +282,10 @@
 
 #ifdef FREECIV_HAVE_LIBLZMA
     /* Try to open as xz file */
+    fp->u.xz.memlimit = XZ_DECODER_MEMLIMIT;
     memset(&fp->u.xz.stream, 0, sizeof(lzma_stream));
     fp->u.xz.error = lzma_stream_decoder(&fp->u.xz.stream,
-                                         XZ_DECODER_MEMLIMIT,
+                                         fp->u.xz.memlimit,
                                          LZMA_CONCATENATED);
     if (fp->u.xz.error != LZMA_OK) {
       free(fp);
@@ -310,7 +315,7 @@
           fp->u.xz.hack_byte_used = FALSE;
           action = LZMA_FINISH;
         }
-        fp->u.xz.error = lzma_code(&fp->u.xz.stream, action);
+        xz_action(fp, action);
         if (fp->u.xz.error == LZMA_OK || fp->u.xz.error == LZMA_STREAM_END) {
           fp->method = FZ_XZ;
           fp->u.xz.out_index = 0;
@@ -604,7 +609,7 @@
           } else {
             fp->u.xz.stream.next_out = fp->u.xz.out_buf;
             fp->u.xz.stream.avail_out = PLAIN_FILE_BUF_SIZE;
-            fp->u.xz.error = lzma_code(&fp->u.xz.stream, LZMA_FINISH);
+            xz_action(fp, LZMA_FINISH);
             fp->u.xz.out_index = 0;
             fp->u.xz.out_avail =
               fp->u.xz.stream.total_out - fp->u.xz.total_read;
@@ -625,7 +630,7 @@
           } else {
             action = LZMA_FINISH;
           }
-          fp->u.xz.error = lzma_code(&fp->u.xz.stream, action);
+          xz_action(fp, action);
           fp->u.xz.out_avail =
             fp->u.xz.stream.total_out - fp->u.xz.total_read;
           fp->u.xz.out_index = 0;
@@ -729,6 +734,28 @@
 
   return TRUE;
 }
+
+/***************************************************************
+  Helper function to do given decompression action.
+***************************************************************/
+static void xz_action(fz_FILE *fp, lzma_action action)
+{
+  fp->u.xz.error = lzma_code(&fp->u.xz.stream, action);
+  if (fp->u.xz.error != LZMA_MEMLIMIT_ERROR) {
+    return;
+  }
+
+  while (fp->u.xz.error == LZMA_MEMLIMIT_ERROR
+         && fp->u.xz.memlimit < XZ_DECODER_MEMLIMIT_FINAL) {
+    fp->u.xz.memlimit += XZ_DECODER_MEMLIMIT_STEP;
+    if (fp->u.xz.memlimit > XZ_DECODER_MEMLIMIT_FINAL) {
+      fp->u.xz.memlimit = XZ_DECODER_MEMLIMIT_FINAL;
+    }
+    fp->u.xz.error = lzma_memlimit_set(&fp->u.xz.stream, fp->u.xz.memlimit);
+  }
+
+  fp->u.xz.error = lzma_code(&fp->u.xz.stream, action);
+}
 #endif /* FREECIV_HAVE_LIBLZMA */
 
 /***************************************************************


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to