psppire-window: Fix use-after-free error in read_spv_file().
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 27 Dec 2020 06:16:39 +0000 (22:16 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 27 Dec 2020 06:16:39 +0000 (22:16 -0800)
spv_item_get_table() returns a borrowed reference, but read_spv_file()
treated it as if it owned it.  This fixes the problem.

This fixes crashes opening .spv files in PSPPIRE with File|Open.

Also, change spv_item_get_table() to return a const pointer, to make it
clearer that the reference is a borrowed one.

src/output/spv/spv.c
src/output/spv/spv.h
src/ui/gui/psppire-window.c

index cbdf10fcdf0a694a64e4efeeae6dfeaf67b1f31c..29c26c275b5bfdaa40389ddbecf0d727e58f3dd6 100644 (file)
@@ -849,7 +849,7 @@ pivot_table_open_legacy (struct spv_item *item)
   return error;
 }
 
-struct pivot_table *
+const struct pivot_table *
 spv_item_get_table (const struct spv_item *item_)
 {
   struct spv_item *item = CONST_CAST (struct spv_item *, item_);
@@ -1196,7 +1196,10 @@ spv_item_set_table_look (struct spv_item *item,
      (We can't just set item->table_look because light tables ignore it and
      legacy tables sometimes override it.) */
   if (spv_item_is_table (item))
-    pivot_table_set_look (spv_item_get_table (item), look);
+    {
+      spv_item_load (item);
+      pivot_table_set_look (item->table, look);
+    }
 
   for (size_t i = 0; i < item->n_children; i++)
     spv_item_set_table_look (item->children[i], look);
index 21d19a6615b9d6b8dbd93eb470a4b1a228dac540..6857d9b3b67f7e0d01dd699a2c6de6893b0c1798 100644 (file)
@@ -157,7 +157,7 @@ size_t spv_item_get_n_children (const struct spv_item *);
 struct spv_item *spv_item_get_child (const struct spv_item *, size_t idx);
 
 bool spv_item_is_table (const struct spv_item *);
-struct pivot_table *spv_item_get_table (const struct spv_item *);
+const struct pivot_table *spv_item_get_table (const struct spv_item *);
 
 bool spv_item_is_text (const struct spv_item *);
 const struct pivot_value *spv_item_get_text (const struct spv_item *);
index 15f8503de26589aba8b82de8bcccdce830b8a01e..99da30fa3eac4772b15983a705c603a474dbb697 100644 (file)
@@ -796,7 +796,7 @@ read_spv_file (const char *filename)
       if (items[i]->type == SPV_ITEM_TEXT)
         spv_text_submit (items[i]);
       else if (items[i]->type == SPV_ITEM_TABLE)
-        pivot_table_submit (spv_item_get_table (items[i]));
+        pivot_table_submit (pivot_table_ref (spv_item_get_table (items[i])));
       prev_heading = heading;
     }
   dump_heading_transition (prev_heading, spv_get_root (spv));