X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fsfm-read.c;h=bd8800bb9f9e09b698a5b756b93753a8e592753a;hb=28d7aaf2db476de5d62eb90787fef50fec444287;hp=12df275e7f557cc7824709cf0b4a278db8c3fb5f;hpb=6cec94f8545d5895b5bdfa73798b386b453ffa18;p=pspp diff --git a/src/sfm-read.c b/src/sfm-read.c index 12df275e7f..bd8800bb9f 100644 --- a/src/sfm-read.c +++ b/src/sfm-read.c @@ -33,7 +33,7 @@ #include "file-handle.h" #include "filename.h" #include "format.h" -#include "getline.h" +#include "getl.h" #include "hash.h" #include "magic.h" #include "misc.h" @@ -41,6 +41,9 @@ #include "str.h" #include "var.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + #include "debug-print.h" /* System file reader. */ @@ -93,7 +96,7 @@ bswap (unsigned char *a, unsigned char *b) *b = t; } -/* bswap_int32(): Reverse the byte order of 32-bit integer *X. */ +/* Reverse the byte order of 32-bit integer *X. */ static inline void bswap_int32 (int32 *x_) { @@ -342,7 +345,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict, { const int n_vars = data.count / 3 ; int i; - if ( data.count % 3 ) + if ( data.count % 3 || n_vars > dict_get_var_cnt(*dict) ) { msg (MW, _("%s: Invalid subrecord length. " "Record: 7; Subrecord: 11"), @@ -350,7 +353,7 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict, skip = 1; } - for ( i = 0 ; i < n_vars ; ++i ) + for ( i = 0 ; i < min(n_vars, dict_get_var_cnt(*dict)) ; ++i ) { struct { @@ -421,6 +424,16 @@ sfm_open_reader (struct file_handle *fh, struct dictionary **dict, break; } + /* Identify any duplicates. */ + if ( compare_var_names(short_name, long_name, 0) && + NULL != dict_lookup_var (*dict, long_name)) + { + lose ((ME, _("%s: Duplicate long variable name `%s' " + "within system file."), + handle_get_filename (r->fh), long_name)); + break; + } + /* Set long name. Renaming a variable may clear the short name, but we want to retain it, so @@ -864,11 +877,17 @@ read_variables (struct sfm_reader *r, } name[j] = 0; + if ( ! var_is_valid_name(name, false) ) + lose ((ME, _("%s: Invalid variable name `%s' within system file."), + handle_get_filename (r->fh), name)); + /* Create variable. */ + vv = (*var_by_idx)[i] = dict_create_var (dict, name, sv.type); if (vv == NULL) lose ((ME, _("%s: Duplicate variable name `%s' within system file."), handle_get_filename (r->fh), name)); + var_set_short_name (vv, vv->name); /* Case reading data. */ @@ -907,63 +926,45 @@ read_variables (struct sfm_reader *r, if (sv.n_missing_values != 0) { flt64 mv[3]; + int mv_cnt = abs (sv.n_missing_values); if (vv->width > MAX_SHORT_STRING) lose ((ME, _("%s: Long string variable %s may not have missing " "values."), handle_get_filename (r->fh), vv->name)); - assertive_buf_read (r, mv, sizeof *mv * abs (sv.n_missing_values), 0); + assertive_buf_read (r, mv, sizeof *mv * mv_cnt, 0); if (r->reverse_endian && vv->type == NUMERIC) - for (j = 0; j < abs (sv.n_missing_values); j++) + for (j = 0; j < mv_cnt; j++) bswap_flt64 (&mv[j]); if (sv.n_missing_values > 0) { - vv->miss_type = sv.n_missing_values; - if (vv->type == NUMERIC) - for (j = 0; j < sv.n_missing_values; j++) - vv->missing[j].f = mv[j]; - else - for (j = 0; j < sv.n_missing_values; j++) - memcpy (vv->missing[j].s, &mv[j], vv->width); + for (j = 0; j < sv.n_missing_values; j++) + if (vv->type == NUMERIC) + mv_add_num (&vv->miss, mv[j]); + else + mv_add_str (&vv->miss, (unsigned char *) &mv[j]); } else { - int x = 0; - if (vv->type == ALPHA) lose ((ME, _("%s: String variable %s may not have missing " "values specified as a range."), handle_get_filename (r->fh), vv->name)); if (mv[0] == r->lowest) - { - vv->miss_type = MISSING_LOW; - vv->missing[x++].f = mv[1]; - } + mv_add_num_range (&vv->miss, LOWEST, mv[1]); else if (mv[1] == r->highest) - { - vv->miss_type = MISSING_HIGH; - vv->missing[x++].f = mv[0]; - } + mv_add_num_range (&vv->miss, mv[0], HIGHEST); else - { - vv->miss_type = MISSING_RANGE; - vv->missing[x++].f = mv[0]; - vv->missing[x++].f = mv[1]; - } + mv_add_num_range (&vv->miss, mv[0], mv[1]); if (sv.n_missing_values == -3) - { - vv->miss_type += 3; - vv->missing[x++].f = mv[2]; - } + mv_add_num (&vv->miss, mv[2]); } } - else - vv->miss_type = MISSING_NONE; if (!parse_format_spec (r, sv.print, &vv->print, vv) || !parse_format_spec (r, sv.write, &vv->write, vv)) @@ -1057,8 +1058,15 @@ read_value_labels (struct sfm_reader *r, if (r->reverse_endian) bswap_int32 (&n_labels); + if ( n_labels >= ((int32) ~0) / sizeof *labels) + { + corrupt_msg(MW, _("%s: Invalid number of labels: %d. Ignoring labels."), + handle_get_filename (r->fh), n_labels); + n_labels = 0; + } + /* Allocate memory. */ - labels = xmalloc (n_labels * sizeof *labels); + labels = xcalloc (n_labels , sizeof *labels); for (i = 0; i < n_labels; i++) labels[i].label = NULL;