about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-15T20·26+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-02-15T20·26+0100
commitbfdacb712c9a95b5c61857b2b3a7dd3cfd0faf3b (patch)
tree044e616d9510d167046688e9a33f4dc5a3cfbbab
parent03109e958089846846827a47f4dcfce843752d3b (diff)
decompressXZ: Ensure that lzma_end() is called
Otherwise we might leak memory.
-rw-r--r--src/libutil/compression.cc33
1 files changed, 21 insertions, 12 deletions
diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc
index fb4160669a29..eaaaf246b18d 100644
--- a/src/libutil/compression.cc
+++ b/src/libutil/compression.cc
@@ -6,34 +6,43 @@
 
 namespace nix {
 
+/* RAII wrapper around lzma_stream. */
+struct LzmaStream
+{
+    lzma_stream strm;
+    LzmaStream() : strm(LZMA_STREAM_INIT) { };
+    ~LzmaStream() { lzma_end(&strm); };
+    lzma_stream & operator()() { return strm; }
+};
+
 std::string decompressXZ(const std::string & in)
 {
-    lzma_stream strm = LZMA_STREAM_INIT;
+    LzmaStream strm;
 
     lzma_ret ret = lzma_stream_decoder(
-        &strm, UINT64_MAX, LZMA_CONCATENATED);
+        &strm(), UINT64_MAX, LZMA_CONCATENATED);
     if (ret != LZMA_OK)
         throw Error("unable to initialise lzma decoder");
 
     lzma_action action = LZMA_RUN;
     uint8_t outbuf[BUFSIZ];
     string res;
-    strm.next_in = (uint8_t *) in.c_str();
-    strm.avail_in = in.size();
-    strm.next_out = outbuf;
-    strm.avail_out = sizeof(outbuf);
+    strm().next_in = (uint8_t *) in.c_str();
+    strm().avail_in = in.size();
+    strm().next_out = outbuf;
+    strm().avail_out = sizeof(outbuf);
 
     while (true) {
 
-        if (strm.avail_in == 0)
+        if (strm().avail_in == 0)
             action = LZMA_FINISH;
 
-        lzma_ret ret = lzma_code(&strm, action);
+        lzma_ret ret = lzma_code(&strm(), action);
 
-        if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
-            res.append((char *) outbuf, sizeof(outbuf) - strm.avail_out);
-            strm.next_out = outbuf;
-            strm.avail_out = sizeof(outbuf);
+        if (strm().avail_out == 0 || ret == LZMA_STREAM_END) {
+            res.append((char *) outbuf, sizeof(outbuf) - strm().avail_out);
+            strm().next_out = outbuf;
+            strm().avail_out = sizeof(outbuf);
         }
 
         if (ret == LZMA_STREAM_END)