fixed range check in parse_record_placement (32Bit/64Bit issue) #58968
authorFriedrich Beckmann <friedrich.beckmann@gmx.de>
Mon, 17 Aug 2020 09:52:47 +0000 (11:52 +0200)
committerFriedrich Beckmann <friedrich.beckmann@gmx.de>
Mon, 17 Aug 2020 11:55:34 +0000 (13:55 +0200)
The regression failed for test "lexer crash due to overflow" (403)
on i386 architecture. The reason is that long is 64Bit on amd64 while
it is 32Bit on i386. The code used long as type that can hold larger
values than int which does not work on 32Bit systems.

The change keeps the value as double as long as the range checks are done.

see: https://savannah.gnu.org/bugs/?58968

src/language/data-io/placement-parser.c

index 671933382a534054816dc89c66e6892ed31a2475..66aefbff9d7d590f6a1b0df7df772f711d8af116 100644 (file)
@@ -399,16 +399,18 @@ parse_record_placement (struct lexer *lexer, int *record, int *column)
 {
   while (lex_match (lexer, T_SLASH))
     {
-      if (lex_is_integer (lexer))
+      if (lex_is_number (lexer))
         {
-          long n = lex_integer (lexer);
-          if (n <= *record || n > INT_MAX)
+         double orignum = lex_number (lexer);
+         long n = (lex_is_integer (lexer)?lex_integer (lexer):*record);
+         bool out_of_range = orignum > INT_MAX || orignum < INT_MIN;
+          if (n <= *record || out_of_range)
             {
-              msg (SE, _("The record number specified, %ld, is at or "
+              msg (SE, _("The record number specified, %.0f, is at or "
                          "before the previous record, %d.  Data "
                          "fields must be listed in order of "
                          "increasing record number."),
-                   n, *record);
+                   orignum, *record);
               return false;
             }
           *record = n;