From: Ben Pfaff Date: Sat, 22 Apr 2023 21:51:49 +0000 (-0700) Subject: VECTOR: Check that multiple vectors don't create the same variable name. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27b725e6d02cbea19b1435ffbaaa9ef5e87f0435;p=pspp VECTOR: Check that multiple vectors don't create the same variable name. This is possible but I hadn't realized it before. Thanks to Youngseok Choi for reporting this bug. Reported at https://lists.gnu.org/archive/html/bug-gnu-pspp/2023-04/msg00004.html. --- diff --git a/src/language/commands/vector.c b/src/language/commands/vector.c index ba61dcae56..b9407cbb6a 100644 --- a/src/language/commands/vector.c +++ b/src/language/commands/vector.c @@ -32,6 +32,7 @@ #include "libpspp/misc.h" #include "libpspp/pool.h" #include "libpspp/str.h" +#include "libpspp/string-set.h" #include "gl/intprops.h" #include "gl/xalloc.h" @@ -116,7 +117,6 @@ cmd_vector (struct lexer *lexer, struct dataset *ds) struct fmt_spec format = fmt_for_output (FMT_F, 8, 2); bool seen_format = false; size_t n_vars = 0; - int name_ofs = lex_ofs (lexer) - 2; int lparen_ofs = lex_ofs (lexer) - 1; while (!lex_match (lexer, T_RPAREN)) { @@ -171,6 +171,7 @@ cmd_vector (struct lexer *lexer, struct dataset *ds) /* Check that none of the variables exist and that their names are not excessively long. */ + struct string_set new_names = STRING_SET_INITIALIZER (new_names); for (size_t i = 0; i < n_vectors; i++) for (size_t j = 0; j < n_vars; j++) { @@ -178,21 +179,32 @@ cmd_vector (struct lexer *lexer, struct dataset *ds) char *error = dict_id_is_valid__ (dict, name); if (error) { - lex_ofs_error (lexer, name_ofs, end_ofs, "%s", error); + lex_ofs_error (lexer, vectors_start, end_ofs, "%s", error); free (error); free (name); goto error; } if (dict_lookup_var (dict, name)) { - lex_ofs_error (lexer, name_ofs, end_ofs, + lex_ofs_error (lexer, vectors_start, end_ofs, _("%s is an existing variable name."), name); free (name); + string_set_destroy (&new_names); + goto error; + } + if (!string_set_insert_nocopy (&new_names, name)) + { + /* name was already freed. */ + lex_ofs_error ( + lexer, vectors_start, end_ofs, + _("Two different vectors add variable %s%zu."), + vectors[i], j + 1); + string_set_destroy (&new_names); goto error; } - free (name); } + string_set_destroy (&new_names); /* Finally create the variables and vectors. */ struct variable **vars = pool_nmalloc (pool, n_vars, sizeof *vars); diff --git a/tests/language/commands/vector.at b/tests/language/commands/vector.at index 5eeb5bbc06..426ab5a0f2 100644 --- a/tests/language/commands/vector.at +++ b/tests/language/commands/vector.at @@ -118,6 +118,7 @@ VECTOR v(**). VECTOR v(F8.2). VECTOR xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(5). VECTOR v **. +VECTOR v v1 (123). ]) AT_DATA([insert.sps], [dnl INSERT FILE='vector.sps' ERROR=IGNORE. @@ -174,5 +175,9 @@ AT_CHECK([pspp --testing-mode -O format=csv insert.sps], [1], [dnl "vector.sps:15.10-15.11: error: VECTOR: Syntax error expecting `=' or `@{:@'. 15 | VECTOR v **. | ^~" + +"vector.sps:16.8-16.17: error: VECTOR: Two different vectors add variable v11. + 16 | VECTOR v v1 (123). + | ^~~~~~~~~~" ]) AT_CLEANUP \ No newline at end of file