From b4e3d932f4dfbdf3e51c81b78daabb40e23528b2 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Thu, 11 May 2017 10:40:51 +0200 Subject: [PATCH] DATA MATRIX: Avoid crash on invalid input --- src/language/data-io/matrix-data.c | 23 ++++++++++++++-- tests/language/data-io/matrix-data.at | 38 +++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/language/data-io/matrix-data.c b/src/language/data-io/matrix-data.c index 4370908aca..752a0be3d2 100644 --- a/src/language/data-io/matrix-data.c +++ b/src/language/data-io/matrix-data.c @@ -126,7 +126,7 @@ preprocess (struct casereader *casereader0, const struct dictionary *dict, void const struct caseproto *proto = casereader_get_proto (casereader0); struct casewriter *writer; writer = autopaging_writer_create (proto); - + struct ccase *prev_case = NULL; double **matrices = NULL; size_t n_splits = 0; @@ -170,6 +170,13 @@ preprocess (struct casereader *casereader0, const struct dictionary *dict, void if (0 == strncasecmp (val, "corr ", ROWTYPE_WIDTH) || 0 == strncasecmp (val, "cov ", ROWTYPE_WIDTH)) { + if (row >= mformat->n_continuous_vars) + { + msg (SE, + _("There are %d variable declared but the data has at least %d matrix rows."), + mformat->n_continuous_vars, row + 1); + goto error; + } int col; for (col = c_offset; col < mformat->n_continuous_vars; ++col) { @@ -198,7 +205,7 @@ preprocess (struct casereader *casereader0, const struct dictionary *dict, void temporary matrix */ const int idx = var_get_dict_index (mformat->varname); row = 0; - struct ccase *prev_case = NULL; + prev_split_hash = 1; n_splits = 0; for (; (c = casereader_read (casereader0)) != NULL; prev_case = c) @@ -288,6 +295,7 @@ preprocess (struct casereader *casereader0, const struct dictionary *dict, void casewriter_write (writer, outcase); } + if (prev_case) case_unref (prev_case); @@ -298,6 +306,17 @@ preprocess (struct casereader *casereader0, const struct dictionary *dict, void struct casereader *reader1 = casewriter_make_reader (writer); casereader_destroy (casereader0); return reader1; + + +error: + if (prev_case) + case_unref (prev_case); + + for (i = 0 ; i < n_splits; ++i) + free (matrices[i]); + free (matrices); + casereader_destroy (casereader0); + return NULL; } int diff --git a/tests/language/data-io/matrix-data.at b/tests/language/data-io/matrix-data.at index 2f39f5817f..058dc3f08e 100644 --- a/tests/language/data-io/matrix-data.at +++ b/tests/language/data-io/matrix-data.at @@ -362,3 +362,41 @@ var06,9.22,.01 ]) AT_CLEANUP + + +AT_SETUP([Matrix data - too many rows]) + +dnl Test for a crash which occurred when the matrix had more rows declared +dnl than variables to hold them. +AT_DATA([matrix-data.pspp], [dnl +matrix data + variables = rowtype_ + var01 var02 var03 var04 + / format = upper diagonal . +begin data + mean 21.4 5.0 72.9 17.4 + sd 6.5 1.6 22.8 5.7 + n 106 106 106 106 + corr 1.00 .32 .48 .28 + corr 1.00 .72 .54 .44 + corr 1.00 .50 .59 .64 + corr 1.00 .62 .49 -.30 + corr 1.00 .56 -.38 .52 + corr 1.00 -.73 .91 .80 + corr 1.00 -.65 -.60 + corr 1.00 .70 + corr 1.00 +end data . + +execute. +]) + + +AT_CHECK([pspp -O format=csv matrix-data.pspp], [1], [dnl +matrix-data.pspp:13: error: MATRIX DATA: There are 4 variable declared but the data has at least 5 matrix rows. + +matrix-data.pspp:20: error: EXECUTE: EXECUTE is allowed only after the active dataset has been defined. +]) + + +AT_CLEANUP -- 2.30.2