Fix invalid read when fetching sys files with very long string variables.
[pspp-builds.git] / src / procedure.c
index 0d75e0ebc3b9086876d3f63071585e3aa05592bd..67f22c5c0dfca5a0e0442feb0a8888973bd222a1 100644 (file)
@@ -20,9 +20,6 @@
 #include <config.h>
 
 #include <procedure.h>
-#include <data/case-source.h>
-#include <data/case-sink.h>
-#include <data/storage-stream.h>
 
 #include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
 
 #include "expressions/public.h"
+#include <data/case-source.h>
+#include <data/case-sink.h>
 #include <data/case.h>
 #include <data/casefile.h>
 #include <data/dictionary.h>
 #include <data/file-handle-def.h>
 #include <data/settings.h>
+#include <data/storage-stream.h>
 #include <data/value-labels.h>
 #include <data/variable.h>
 #include <language/control/control-stack.h>
 #include <libpspp/alloc.h>
 #include <libpspp/message.h>
-#include <libpspp/message.h>
 #include <libpspp/misc.h>
 #include <libpspp/str.h>
 #include <output/manager.h>
@@ -85,6 +84,10 @@ static struct dict_compactor *compactor;
 /* Time at which vfm was last invoked. */
 static time_t last_vfm_invocation;
 
+/* Whether we're inside a procedure.
+   For debugging purposes only. */
+static bool in_procedure;
+
 /* Lag queue. */
 int n_lag;                     /* Number of cases to lag. */
 static int lag_count;          /* Number of cases in lag_queue so far. */
@@ -178,12 +181,9 @@ procedure (bool (*proc_func) (struct ccase *, void *), void *aux)
 static bool
 internal_procedure (bool (*proc_func) (struct ccase *, void *), void *aux) 
 {
-  static int recursive_call;
   struct write_case_data wc_data;
   bool ok;
 
-  assert (++recursive_call == 1);
-
   wc_data.proc_func = proc_func;
   wc_data.aux = aux;
   create_trns_case (&wc_data.trns_case, default_dict);
@@ -200,8 +200,6 @@ internal_procedure (bool (*proc_func) (struct ccase *, void *), void *aux)
   case_destroy (&wc_data.sink_case);
   case_destroy (&wc_data.trns_case);
 
-  assert (--recursive_call == 0);
-
   return ok;
 }
 
@@ -228,7 +226,7 @@ create_trns_case (struct ccase *trns_case, struct dictionary *dict)
       union value *value = case_data_rw (trns_case, v->fv);
 
       if (v->type == NUMERIC)
-        value->f = v->reinit ? 0.0 : SYSMIS;
+        value->f = v->leave ? 0.0 : SYSMIS;
       else
         memset (value->s, ' ', v->width);
     }
@@ -239,6 +237,9 @@ create_trns_case (struct ccase *trns_case, struct dictionary *dict)
 static void
 open_active_file (void)
 {
+  assert (!in_procedure);
+  in_procedure = true;
+
   /* Make temp_dict refer to the dictionary right before data
      reaches the sink */
   if (!temporary)
@@ -426,7 +427,7 @@ clear_case (struct ccase *c)
   for (i = 0; i < var_cnt; i++) 
     {
       struct variable *v = dict_get_var (default_dict, i);
-      if (v->reinit
+      if (!v->leave
         {
           if (v->type == NUMERIC)
             case_data_rw (c, v->fv)->f = SYSMIS;
@@ -483,6 +484,10 @@ close_active_file (void)
   process_if_expr = NULL;
   dict_set_case_limit (default_dict, 0);
   dict_clear_vectors (default_dict);
+
+  assert (in_procedure);
+  in_procedure = false;
+
   return cancel_transformations ();
 }
 \f
@@ -511,6 +516,9 @@ void
 add_transformation (trns_proc_func *proc, trns_free_func *free, void *private)
 {
   struct transformation *trns;
+
+  assert (!in_procedure);
+
   if (n_trns >= m_trns)
     t_trns = x2nrealloc (t_trns, &m_trns, sizeof *t_trns);
   trns = &t_trns[n_trns++];