sim: hw: replace fgets with getline

This avoids fixed sized buffers on the stack.
This commit is contained in:
Mike Frysinger 2021-01-15 22:24:38 -05:00
parent 481fac96bd
commit f4dd74915b
2 changed files with 41 additions and 30 deletions

View 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> 2021-01-30 Mike Frysinger <vapier@gentoo.org>
* gennltvals.sh (gen_arches): Sort calls by first arg. * gennltvals.sh (gen_arches): Sort calls by first arg.

View File

@ -138,8 +138,9 @@ merge_device_file (struct sim_state *sd,
{ {
FILE *description; FILE *description;
struct hw *current = STATE_HW (sd)->tree; struct hw *current = STATE_HW (sd)->tree;
int line_nr; char *device_path = NULL;
char device_path[1000]; size_t buf_size = 0;
ssize_t device_path_len;
/* try opening the file */ /* try opening the file */
description = fopen (file_name, "r"); description = fopen (file_name, "r");
@ -149,19 +150,14 @@ merge_device_file (struct sim_state *sd,
return SIM_RC_FAIL; return SIM_RC_FAIL;
} }
line_nr = 0; while ((device_path_len = getline (&device_path, &buf_size, description)) > 0)
while (fgets (device_path, sizeof (device_path), description))
{ {
char *device; char *device;
/* check that a complete line was read */ char *next_line = NULL;
if (strchr (device_path, '\n') == NULL)
{ if (device_path[device_path_len - 1] == '\n')
fclose (description); device_path[--device_path_len] = '\0';
sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr);
return SIM_RC_FAIL;
}
*strchr (device_path, '\n') = '\0';
line_nr++;
/* skip comments ("#" or ";") and blank lines lines */ /* skip comments ("#" or ";") and blank lines lines */
for (device = device_path; for (device = device_path;
*device != '\0' && isspace (*device); *device != '\0' && isspace (*device);
@ -170,33 +166,44 @@ merge_device_file (struct sim_state *sd,
|| device[0] == ';' || device[0] == ';'
|| device[0] == '\0') || device[0] == '\0')
continue; continue;
/* merge any appended lines */ /* 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 */ /* 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 */ /* append the next line */
if (!fgets (device_path + curlen, if (buf_size - device_path_len <= next_line_len)
sizeof (device_path) - curlen,
description))
{ {
fclose (description); ptrdiff_t offset = device - device_path;
sim_io_eprintf (sd, "%s:%d: unexpected eof", file_name, line_nr);
return SIM_RC_FAIL; buf_size += next_buf_size;
device_path = xrealloc (device_path, buf_size);
device = device_path + offset;
} }
if (strchr (device_path, '\n') == NULL) memcpy (device_path + device_path_len, next_line,
{ next_line_len + 1);
fclose (description); device_path_len += next_line_len;
sim_io_eprintf (sd, "%s:%d: line to long", file_name, line_nr);
return SIM_RC_FAIL;
}
*strchr (device_path, '\n') = '\0';
line_nr++;
} }
free (next_line);
/* parse this line */ /* parse this line */
current = hw_tree_parse (current, "%s", device); current = hw_tree_parse (current, "%s", device);
} }
free (device_path);
fclose (description); fclose (description);
return SIM_RC_OK; return SIM_RC_OK;
} }