sim: hw: replace fgets with getline
authorMike Frysinger <vapier@gentoo.org>
Sat, 16 Jan 2021 03:24:38 +0000 (22:24 -0500)
committerMike Frysinger <vapier@gentoo.org>
Sat, 30 Jan 2021 06:07:58 +0000 (01:07 -0500)
This avoids fixed sized buffers on the stack.

sim/common/ChangeLog
sim/common/sim-hw.c

index f6346e93352ef21d9e9871229602843aa3b31a4c..cafb4b2043282aca3611b21e9a09b81250d82f0b 100644 (file)
@@ -1,3 +1,7 @@
+2021-01-30  Mike Frysinger  <vapier@gentoo.org>
+
+       * sim-hw.c (merge_device_file): Replace fgets with getline.
+
 2021-01-30  Mike Frysinger  <vapier@gentoo.org>
 
        * gennltvals.sh (gen_arches): Sort calls by first arg.
index 81b4f64f7c22e794d61d68e9d5ff9c13b9dac8bf..11d3abdbbfb07c7b0acae4fe458c7637e8a7592e 100644 (file)
@@ -138,8 +138,9 @@ merge_device_file (struct sim_state *sd,
 {
   FILE *description;
   struct hw *current = STATE_HW (sd)->tree;
-  int line_nr;
-  char device_path[1000];
+  char *device_path = NULL;
+  size_t buf_size = 0;
+  ssize_t device_path_len;
 
   /* try opening the file */
   description = fopen (file_name, "r");
@@ -149,19 +150,14 @@ merge_device_file (struct sim_state *sd,
       return SIM_RC_FAIL;
     }
 
-  line_nr = 0;
-  while (fgets (device_path, sizeof (device_path), description))
+  while ((device_path_len = getline (&device_path, &buf_size, description)) > 0)
     {
       char *device;
-      /* check that a complete line was read */
-      if (strchr (device_path, '\n') == NULL)
-       {
-         fclose (description);
-         sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr);
-         return SIM_RC_FAIL;
-       }
-      *strchr (device_path, '\n') = '\0';
-      line_nr++;
+      char *next_line = NULL;
+
+      if (device_path[device_path_len - 1] == '\n')
+       device_path[--device_path_len] = '\0';
+
       /* skip comments ("#" or ";") and blank lines lines */
       for (device = device_path;
           *device != '\0' && isspace (*device);
@@ -170,33 +166,44 @@ merge_device_file (struct sim_state *sd,
          || device[0] == ';'
          || device[0] == '\0')
        continue;
+
       /* merge any appended lines */
-      while (device_path[strlen (device_path) - 1] == '\\')
+      while (device_path[device_path_len - 1] == '\\')
        {
-         int curlen = strlen (device_path) - 1;
+         size_t next_buf_size = 0;
+         ssize_t next_line_len;
+
          /* zap the `\' at the end of the line */
-         device_path[curlen] = '\0';
+         device_path[--device_path_len] = '\0';
+
+         /* get the next line */
+         next_line_len = getline (&next_line, &next_buf_size, description);
+         if (next_line_len <= 0)
+           break;
+
+         if (next_line[next_line_len - 1] == '\n')
+           next_line[--next_line_len] = '\0';
+
          /* append the next line */
-         if (!fgets (device_path + curlen,
-                     sizeof (device_path) - curlen,
-                     description))
-           {
-             fclose (description);
-             sim_io_eprintf (sd, "%s:%d: unexpected eof", file_name, line_nr);
-             return SIM_RC_FAIL;
-           }
-         if (strchr (device_path, '\n') == NULL)
+         if (buf_size - device_path_len <= next_line_len)
            {
-             fclose (description);
-             sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr);
-             return SIM_RC_FAIL;
+             ptrdiff_t offset = device - device_path;
+
+             buf_size += next_buf_size;
+             device_path = xrealloc (device_path, buf_size);
+             device = device_path + offset;
            }
-         *strchr (device_path, '\n') = '\0';
-         line_nr++;
+         memcpy (device_path + device_path_len, next_line,
+                 next_line_len + 1);
+         device_path_len += next_line_len;
        }
+      free (next_line);
+
       /* parse this line */
       current = hw_tree_parse (current, "%s", device);
     }
+
+  free (device_path);
   fclose (description);
   return SIM_RC_OK;
 }