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>
* gennltvals.sh (gen_arches): Sort calls by first arg.

View 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))
if (buf_size - device_path_len <= next_line_len)
{
fclose (description);
sim_io_eprintf (sd, "%s:%d: unexpected eof", 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;
}
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++;
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;
}