diff --git a/src/xspice/icm/analog/file_source/cfunc.mod b/src/xspice/icm/analog/file_source/cfunc.mod index 595f940cb..0b5dfe723 100644 --- a/src/xspice/icm/analog/file_source/cfunc.mod +++ b/src/xspice/icm/analog/file_source/cfunc.mod @@ -503,7 +503,11 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc. tprev = t; /* before storing, check if vector size is large enough. - If not, add another 1000*size doubles */ + If not, add another 1000*size doubles. Each record appended below + is a full stepsize (= size + 1: one timepoint plus `size` channel + values), so reserve stepsize -- reserving only `size` left room for + one fewer value than is written and overran the buffer by one + double at the allocation boundary. */ if (count > (int) loc->indata->vecallocated - stepsize) { loc->indata->vecallocated += (size_t) (size * 1000); void * const p = realloc(loc->indata->datavec, diff --git a/src/xspice/icm/analog/xfer/cfunc.mod b/src/xspice/icm/analog/xfer/cfunc.mod index eaa67d5e3..6bb43d2e6 100644 --- a/src/xspice/icm/analog/xfer/cfunc.mod +++ b/src/xspice/icm/analog/xfer/cfunc.mod @@ -120,9 +120,13 @@ static double *read_file(const char *fn, int span, int offset, j = 0; } - /* Check allocation. */ + /* Check allocation. The store loop below can append up to one value + per column on this line, and sscanf read up to 9 (count <= 9) -- a + line with more than one data record stores more than the 3 of a + single freq/real/imag triple. Reserve for the whole line (9) so a + multi-record line cannot write past the buffer. */ - if (i + 3 > size) { + if (i + 9 > size) { size += ALLOC; file_data = realloc(file_data, size * sizeof(double)); if (!file_data)