From: Ben Pfaff Date: Fri, 21 May 2010 04:54:56 +0000 (-0700) Subject: sys-file-reader: Tolerate variable labels longer than 255 bytes. X-Git-Tag: v0.7.5~12 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp-builds.git;a=commitdiff_plain;h=78b2280e4d75fc07ce0f17c3607c0707f7ccb819 sys-file-reader: Tolerate variable labels longer than 255 bytes. Michel Boaventura provided a system file with a 256-byte variable label that PSPP rejected. This commit allows it to be read. --- diff --git a/doc/dev/system-file-format.texi b/doc/dev/system-file-format.texi index 1309cb79..757867ca 100644 --- a/doc/dev/system-file-format.texi +++ b/doc/dev/system-file-format.texi @@ -267,8 +267,10 @@ stops (@samp{.}). The variable name is padded on the right with spaces. @item int32 label_len; This field is present only if @code{has_var_label} is set to 1. It is -set to the length, in characters, of the variable label, which must be a -number between 0 and 120. +set to the length, in characters, of the variable label. The +documented maximum length varies from 120 to 255 based on SPSS +version, but some files have been seen with longer labels. PSPP +accepts longer labels and truncates them to 255 bytes on input. @item char label[]; This field is present only if @code{has_var_label} is set to 1. It has @@ -426,7 +428,9 @@ in length. Its type and width cannot be determined until the following value label variables record (see below) is read. @item char label_len; -The label's length, in bytes. +The label's length, in bytes. The documented maximum length varies +from 60 to 120 based on SPSS version. PSPP supports value labels up +to 255 bytes long. @item char label[]; @code{label_len} bytes of the actual label, followed by up to 7 bytes diff --git a/src/data/sys-file-reader.c b/src/data/sys-file-reader.c index d2b105c0..48a5188f 100644 --- a/src/data/sys-file-reader.c +++ b/src/data/sys-file-reader.c @@ -614,16 +614,20 @@ read_variable_record (struct sfm_reader *r, struct dictionary *dict, sys_error (r, _("Variable label indicator field is not 0 or 1.")); if (has_variable_label == 1) { - size_t len; + size_t len, read_len; char label[255 + 1]; len = read_int (r); - if (len >= sizeof label) - sys_error (r, _("Variable %s has label of invalid length %zu."), - name, len); - read_string (r, label, len + 1); + + /* Read up to 255 bytes of label. */ + read_len = MIN (sizeof label - 1, len); + read_string (r, label, read_len + 1); var_set_label (var, label); + /* Skip unread label bytes. */ + skip_bytes (r, len - read_len); + + /* Skip label padding up to multiple of 4 bytes. */ skip_bytes (r, ROUND_UP (len, 4) - len); } diff --git a/tests/dissect-sysfile.c b/tests/dissect-sysfile.c index 25e2f7f4..3d26a0fb 100644 --- a/tests/dissect-sysfile.c +++ b/tests/dissect-sysfile.c @@ -357,16 +357,20 @@ read_variable_record (struct sfm_reader *r) if (has_variable_label == 1) { long long int offset = ftello (r->file); - size_t len; + size_t len, read_len; char label[255 + 1]; len = read_int (r); - if (len >= sizeof label) - sys_error (r, _("Variable %s has label of invalid length %zu."), - name, len); - read_string (r, label, len + 1); + + /* Read up to 255 bytes of label. */ + read_len = MIN (sizeof label - 1, len); + read_string (r, label, read_len + 1); printf("\t%08llx Variable label: \"%s\"\n", offset, label); + /* Skip unread label bytes. */ + skip_bytes (r, len - read_len); + + /* Skip label padding up to multiple of 4 bytes. */ skip_bytes (r, ROUND_UP (len, 4) - len); }