From: Mike Frysinger Date: Sat, 16 Jan 2021 03:24:38 +0000 (-0500) Subject: sim: hw: replace fgets with getline X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f4dd74915b2139dbc64eecc38a0acda40408c3b2;p=binutils-gdb.git sim: hw: replace fgets with getline This avoids fixed sized buffers on the stack. --- diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index f6346e93352..cafb4b20432 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,7 @@ +2021-01-30 Mike Frysinger + + * sim-hw.c (merge_device_file): Replace fgets with getline. + 2021-01-30 Mike Frysinger * gennltvals.sh (gen_arches): Sort calls by first arg. diff --git a/sim/common/sim-hw.c b/sim/common/sim-hw.c index 81b4f64f7c2..11d3abdbbfb 100644 --- a/sim/common/sim-hw.c +++ b/sim/common/sim-hw.c @@ -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; }