get_str_line: Use heap instead of stack

The stack allocated buffer does introduce an arbitrary limit,
to the length of the line.

Previously, if the line was too long, it might be catched by a
stack smash canary or resulted into a crash.

This is not guaranteed though, and thus could result into undefined
behavior.

To mitigate this, an dynamic allocated buffer is replacing the stack
allocated buffer, with the initial capacity of the copied line.
This commit is contained in:
Fabian Viöl
2021-04-29 10:36:34 +02:00
parent fbe18d9ca4
commit 766f4c3f62

View File

@@ -2719,16 +2719,19 @@ static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat)
while (!(p->buf[i] == '\n' || p->buf[i] == '\0')) { while (!(p->buf[i] == '\n' || p->buf[i] == '\0')) {
i++; i++;
} }
char buf[2046]; size_t line_length = i - p->offset;
char *dst; garray_T ga;
dst = xstpncpy(buf, (char *)p->buf + p->offset, i - p->offset); ga_init(&ga, (int)sizeof(char_u), (int)line_length);
if ((uint32_t)(dst - buf) != i - p->offset) { ga_concat_len(&ga, (char *)p->buf + p->offset, line_length);
if (ga.ga_len != (int)line_length) {
smsg(_(":source error parsing command %s"), p->buf); smsg(_(":source error parsing command %s"), p->buf);
return NULL; return NULL;
} }
buf[i - p->offset] = '\0'; ga_append(&ga, '\0');
p->offset = i + 1; p->offset = i + 1;
return (char_u *)xstrdup(buf); char_u *line = (char_u *)xstrdup(ga.ga_data);
ga_clear(&ga);
return line;
} }
static int source_using_linegetter(void *cookie, static int source_using_linegetter(void *cookie,