From 274e13015374cfb27a2047f90c479d6bd8d8e0c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Mon, 12 Oct 2015 19:05:17 +0200
Subject: [PATCH] decode_value(): Fixed memory leak on unfinished programs
 --with-debug.

The decoder state wasn't freed on exit if the decoder tables contained
unfinished programs when compiled --with-debug.
---
 src/encode.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/src/encode.c b/src/encode.c
index 6d99fa9dc9..08af4a5bf7 100644
--- a/src/encode.c
+++ b/src/encode.c
@@ -4119,14 +4119,6 @@ static void free_decode_data (struct decode_data *data, int delay,
 
 #ifdef PIKE_DEBUG
   if (!free_after_error) {
-    NEW_MAPPING_LOOP (data->decoded->data) {
-      if (TYPEOF(k->val) == T_PROGRAM &&
-	  !(k->val.u.program->flags & PROGRAM_FINISHED)) {
-	decode_error (data, NULL,
-		      "Got unfinished program <%O> after decode: %O\n",
-		      &k->ind, &k->val);
-      }
-    }
     if(data->unfinished_programs)
       Pike_fatal("We have unfinished programs left in decode()!\n");
     if(data->unfinished_objects)
@@ -4136,9 +4128,7 @@ static void free_decode_data (struct decode_data *data, int delay,
   }
 #endif
 
-  free_string (data->data_str);
   if (data->codec) free_object (data->codec);
-  free_mapping(data->decoded);
 
   while(data->unfinished_programs)
   {
@@ -4169,6 +4159,30 @@ static void free_decode_data (struct decode_data *data, int delay,
   free_object (data->thread_obj);
 #endif
 
+#ifdef PIKE_DEBUG
+  if (!free_after_error) {
+    NEW_MAPPING_LOOP (data->decoded->data) {
+      if (TYPEOF(k->val) == T_PROGRAM &&
+	  !(k->val.u.program->flags & PROGRAM_FINISHED)) {
+	ONERROR err;
+	/* Move some references to the stack so that they
+	 * will be freed when decode_error() throws, but
+	 * still be available to decode_error().
+	 */
+	push_string(data->data_str);
+	push_mapping(data->decoded);
+	SET_ONERROR(err, data, free);
+
+	decode_error (data, NULL,
+		      "Got unfinished program <%O> after decode: %O\n",
+		      &k->ind, &k->val);
+	UNSET_ONERROR(err);
+      }
+    }
+  }
+#endif
+  free_string(data->data_str);
+  free_mapping(data->decoded);
   free( (char *) data);
 }
 
-- 
GitLab