Avoid negative overflow when the text output driver tries to print
authorJohn Darrington <john@darrington.wattle.id.au>
Sat, 20 Jun 2020 05:17:06 +0000 (07:17 +0200)
committerJohn Darrington <john@darrington.wattle.id.au>
Sat, 20 Jun 2020 05:18:19 +0000 (07:18 +0200)
random binary data.

libpspp/u8-line.c (u8_line_find_pos): Deal properly with the case
where the target is not found in the search string.

libpspp/u8-line.c (u8_line_reserve): Add some assertions to prevent
negative overflow into lower function calls.

Reported by: Andrea Fioraldi

Fixes bug: #58591

src/libpspp/u8-line.c

index 34e650952a2c201da5e7b3080e25b60989aecda4..3b4f9c60c4d2e55ea7503bf89bc3d80fc0801c33 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2011, 2012 Free Software Foundation, Inc.
+   Copyright (C) 2011, 2012, 2020 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -96,8 +96,8 @@ struct u8_pos
     size_t ofs1;
   };
 
-static void
-u8_line_find_pos (struct u8_line *line, int target_x, struct u8_pos *c)
+static bool
+u8_line_find_pos (const struct u8_line *line, int target_x, struct u8_pos *c)
 {
   const uint8_t *s = CHAR_CAST (const uint8_t *, ds_cstr (&line->s));
   size_t length = ds_length (&line->s);
@@ -106,21 +106,25 @@ u8_line_find_pos (struct u8_line *line, int target_x, struct u8_pos *c)
   int x;
 
   x = 0;
-  for (ofs = 0; ; ofs += mblen)
+  c->x0 = 0;
+  c->ofs0 = 0;
+  for (ofs = 0; ofs <= length; ofs += mblen)
     {
       int w;
-
+      c->x0 = x;
+      c->ofs0 = ofs;
       mblen = u8_mb_to_display (&w, s + ofs, length - ofs);
       if (x + w > target_x)
         {
-          c->x0 = x;
           c->x1 = x + w;
-          c->ofs0 = ofs;
           c->ofs1 = ofs + mblen;
-          return;
+          return true;
         }
       x += w;
     }
+  c->x1 = x;
+  c->ofs1 = ofs;
+  return false;
 }
 
 /* Prepares LINE to write N bytes of characters that comprise X1-X0 column
@@ -129,6 +133,7 @@ u8_line_find_pos (struct u8_line *line, int target_x, struct u8_pos *c)
 char *
 u8_line_reserve (struct u8_line *line, int x0, int x1, int n)
 {
+  assert (x1 >= x0);
   if (x0 >= line->width)
     {
       /* The common case: adding new characters at the end of a line. */
@@ -179,9 +184,11 @@ u8_line_reserve (struct u8_line *line, int x0, int x1, int n)
               p1.x0++;
             }
           while (p1.x0 < x1);
+          assert (p1.ofs1 >= p0.ofs0);
           return ds_splice_uninit (&line->s, p0.ofs0, p1.ofs1 - p0.ofs0, n);
         }
 
+      assert (p1.ofs0 >= p0.ofs0);
       return ds_splice_uninit (&line->s, p0.ofs0, p1.ofs0 - p0.ofs0, n);
     }
 }