Fix up potential overflows in size calculations by replacing
[pspp] / src / count.c
index 1697c0fbd3a32db806a66b2f304ff19f9281ac58..876c0793234442c609082609147cf565c2783860 100644 (file)
@@ -29,6 +29,9 @@
 #include "str.h"
 #include "var.h"
 
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
 /* Implementation details:
 
    The S?SS manuals do not specify the order that COUNT subcommands are
@@ -88,7 +91,7 @@ struct counting
 
     /* variables to count */
     struct variable **v;
-    int n;
+    size_t n;
 
     /* values to count */
     int missing;               /* (numeric only)
@@ -108,7 +111,7 @@ struct cnt_var_info
     struct cnt_var_info *next;
 
     struct variable *d;                /* Destination variable. */
-    char n[SHORT_NAME_LEN + 1];        /* Name of dest var. */
+    char n[LONG_NAME_LEN + 1]; /* Name of dest var. */
 
     struct counting *c;                /* The counting specifications. */
   };
@@ -145,7 +148,7 @@ cmd_count (void)
       cnt->d = NULL;
       cnt->c = NULL;
 
-      /* Get destination struct variable, or at least its name. */
+      /* Get destination variable, or at least its name. */
       if (!lex_force_id ())
        goto fail;
       cnt->d = dict_lookup_var (default_dict, tokid);
@@ -158,7 +161,7 @@ cmd_count (void)
            }
        }
       else
-       strcpy (cnt->n, tokid);
+       str_copy_trunc (cnt->n, sizeof cnt->n, tokid);
 
       lex_get ();
       if (!lex_force_match ('='))
@@ -227,20 +230,20 @@ fail:
 
 /* Parses a set of numeric criterion values. */
 static int
-parse_numeric_criteria (struct counting * c)
+parse_numeric_criteria (struct counting *c)
 {
-  int n = 0;
-  int m = 0;
+  size_t n = 0;
+  size_t m = 0;
 
   c->crit.n = 0;
   c->missing = 0;
   for (;;)
     {
       struct cnt_num *cur;
-      if (n >= m - 1)
+      if (n + 1 >= m)
        {
          m += 16;
-         c->crit.n = xrealloc (c->crit.n, m * sizeof (struct cnt_num));
+         c->crit.n = xnrealloc (c->crit.n, m, sizeof *c->crit.n);
        }
 
       cur = &c->crit.n[n++];
@@ -321,14 +324,14 @@ parse_numeric_criteria (struct counting * c)
 /* Parses a set of string criteria values.  The skeleton is the same
    as parse_numeric_criteria(). */
 static int
-parse_string_criteria (struct counting * c)
+parse_string_criteria (struct counting *c)
 {
   int len = 0;
 
-  int n = 0;
-  int m = 0;
+  size_t n = 0;
+  size_t m = 0;
 
-  int i;
+  size_t i;
 
   for (i = 0; i < c->n; i++)
     if (c->v[i]->width > len)
@@ -338,10 +341,10 @@ parse_string_criteria (struct counting * c)
   for (;;)
     {
       struct cnt_str *cur;
-      if (n >= m - 1)
+      if (n + 1 >= m)
        {
          m += 16;
-         c->crit.n = xrealloc (c->crit.n, m * sizeof (struct cnt_str));
+         c->crit.s = xnrealloc (c->crit.s, m, sizeof *c->crit.s);
        }
 
       if (!lex_force_string ())
@@ -349,7 +352,7 @@ parse_string_criteria (struct counting * c)
       cur = &c->crit.s[n++];
       cur->type = CNT_SINGLE;
       cur->s = malloc (len + 1);
-      st_pad_copy (cur->s, ds_c_str (&tokstr), len + 1);
+      str_copy_rpad (cur->s, len + 1, ds_c_str (&tokstr));
       lex_get ();
 
       lex_match (',');
@@ -365,10 +368,10 @@ parse_string_criteria (struct counting * c)
 
 /* Counts the number of values in case C matching counting CNT. */
 static inline int
-count_numeric (struct counting * cnt, struct ccase * c)
+count_numeric (struct counting *cnt, struct ccase *c)
 {
   int counter = 0;
-  int i;
+  size_t i;
 
   for (i = 0; i < cnt->n; i++)
     {
@@ -382,7 +385,7 @@ count_numeric (struct counting * cnt, struct ccase * c)
            counter++;
          continue;
        }
-      if (cnt->missing >= 2 && is_num_user_missing (cmp, cnt->v[i]))
+      if (cnt->missing >= 2 && mv_is_num_user_missing (&cnt->v[i]->miss, cmp))
        {
          counter++;
          continue;
@@ -430,10 +433,10 @@ count_numeric (struct counting * cnt, struct ccase * c)
 
 /* Counts the number of values in case C matching counting CNT. */
 static inline int
-count_string (struct counting * cnt, struct ccase * c)
+count_string (struct counting *cnt, struct ccase *c)
 {
   int counter = 0;
-  int i;
+  size_t i;
 
   for (i = 0; i < cnt->n; i++)
     {
@@ -463,7 +466,7 @@ count_string (struct counting * cnt, struct ccase * c)
 
 /* Performs the COUNT transformation T on case C. */
 static int
-count_trns_proc (struct trns_header * trns, struct ccase * c,
+count_trns_proc (struct trns_header *trns, struct ccase *c,
                  int case_num UNUSED)
 {
   struct cnt_var_info *info;
@@ -485,7 +488,7 @@ count_trns_proc (struct trns_header * trns, struct ccase * c,
 
 /* Destroys all dynamic data structures associated with T. */
 static void
-count_trns_free (struct trns_header * t)
+count_trns_free (struct trns_header *t)
 {
   struct cnt_var_info *iter, *next;