From 958e78555714e9f1847513f9cc576fa2cd7a6769 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 31 Jan 2016 12:28:54 -0800 Subject: [PATCH] spreadsheet: Avoid sharing a dictionary between spreadsheet and client. Spreadsheet implementations keep a copy of the dictionary that they build to simplify reading cases. Until now, they shared that dictionary, in a modifiable way, with their client. This meant, however, that if the client modified the dictionary, it could screw up reading further cases from the spreadsheet. This commit fixes the problem by forcing clients to make their own copy of the dictionary if they want to modify it. Bug #44158. --- src/data/gnumeric-reader.c | 9 +++++---- src/data/ods-reader.c | 8 ++++---- src/data/spreadsheet-reader.h | 7 ++++--- src/language/data-io/get-data.c | 29 +++++++++------------------ src/ui/gui/psppire-import-assistant.c | 2 +- 5 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/data/gnumeric-reader.c b/src/data/gnumeric-reader.c index 0783e10f7c..7033448d8b 100644 --- a/src/data/gnumeric-reader.c +++ b/src/data/gnumeric-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. + Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013, 2016 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -185,10 +185,13 @@ gnumeric_unref (struct spreadsheet *s) { xmlFree (r->sheets[i].name); } - + + free (r->sheets); state_data_destroy (&r->msd); + dict_destroy (r->dict); + free (s->file_name); free (r); @@ -872,8 +875,6 @@ gnumeric_make_reader (struct spreadsheet *spreadsheet, } free (var_spec); - dict_destroy (spreadsheet->dict); - spreadsheet->dict = NULL; gnm_file_casereader_destroy (NULL, r); diff --git a/src/data/ods-reader.c b/src/data/ods-reader.c index c5ada6e091..2f058b044d 100644 --- a/src/data/ods-reader.c +++ b/src/data/ods-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. + Copyright (C) 2011, 2012, 2013, 2016 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -170,7 +170,9 @@ ods_unref (struct spreadsheet *s) { xmlFree (r->sheets[i].name); } - + + dict_destroy (r->dict); + zip_reader_destroy (r->zreader); free (r->sheets); free (s->file_name); @@ -919,8 +921,6 @@ ods_make_reader (struct spreadsheet *spreadsheet, free (var_spec); - dict_destroy (r->spreadsheet.dict); - r->spreadsheet.dict = NULL; ods_file_casereader_destroy (NULL, r); return NULL; diff --git a/src/data/spreadsheet-reader.h b/src/data/spreadsheet-reader.h index c03cf71642..0f0819b249 100644 --- a/src/data/spreadsheet-reader.h +++ b/src/data/spreadsheet-reader.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2010 Free Software Foundation, Inc. + Copyright (C) 2007, 2010, 2016 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -66,8 +66,9 @@ struct spreadsheet /* The total number of sheets in the "workbook" */ int n_sheets; - /* The dictionary */ - struct dictionary *dict; + /* The dictionary for client's reference. + Client must clone if it needs a permanent or modifiable copy. */ + const struct dictionary *dict; int ref_cnt; }; diff --git a/src/language/data-io/get-data.c b/src/language/data-io/get-data.c index 2bf419659d..995be8e7ce 100644 --- a/src/language/data-io/get-data.c +++ b/src/language/data-io/get-data.c @@ -110,41 +110,30 @@ cmd_get_data (struct lexer *lexer, struct dataset *ds) lex_match_id (lexer, "ODS")) { char *filename = NULL; - struct casereader *reader = NULL; - struct dictionary *dict = NULL; - if (!parse_spreadsheet (lexer, &filename, &opts)) goto error; + struct spreadsheet *spreadsheet = NULL; if ( gnm_read_support && 0 == strncasecmp (tok, "GNM", 3)) - { - struct spreadsheet *spreadsheet = gnumeric_probe (filename, true); - if (spreadsheet == NULL) - goto error; - reader = gnumeric_make_reader (spreadsheet, &opts); - dict = spreadsheet->dict; - gnumeric_unref (spreadsheet); - } + spreadsheet = gnumeric_probe (filename, true); else if ( odf_read_support && 0 == strncasecmp (tok, "ODS", 3)) - { - struct spreadsheet *spreadsheet = ods_probe (filename, true); - if (spreadsheet == NULL) - goto error; - reader = ods_make_reader (spreadsheet, &opts); - dict = spreadsheet->dict; - ods_unref (spreadsheet); - } + spreadsheet = ods_probe (filename, true); free (filename); + if (spreadsheet == NULL) + goto error; + struct casereader *reader = spreadsheet_make_reader (spreadsheet, &opts); if (reader) { - dataset_set_dict (ds, dict); + dataset_set_dict (ds, dict_clone (spreadsheet->dict)); dataset_set_source (ds, reader); free (tok); destroy_spreadsheet_read_info (&opts); + spreadsheet_unref (spreadsheet); return CMD_SUCCESS; } + spreadsheet_unref (spreadsheet); } else msg (SE, _("Unsupported TYPE %s."), tok); diff --git a/src/ui/gui/psppire-import-assistant.c b/src/ui/gui/psppire-import-assistant.c index a7d29f2a8c..1b6cf570af 100644 --- a/src/ui/gui/psppire-import-assistant.c +++ b/src/ui/gui/psppire-import-assistant.c @@ -2047,7 +2047,7 @@ prepare_formats_page (PsppireImportAssistant *ia) case SPREADSHEET_GNUMERIC: { reader = spreadsheet_make_reader (ia->spreadsheet, &sro); - ia->dict = ia->spreadsheet->dict; + ia->dict = dict_clone (ia->spreadsheet->dict); } break; default: -- 2.30.2