aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Viöl <f.vioel@googlemail.com>2021-04-29 10:36:34 +0200
committerFabian Viöl <f.vioel@googlemail.com>2021-04-29 11:48:51 +0200
commit766f4c3f62f530cf6c29272bae63a097681ab7fb (patch)
tree5d16f9c8ebacc6c11e22c9da3ab55cf4720f487e
parentfbe18d9ca41a419414cb112d0a426aa8803c6236 (diff)
downloadrneovim-766f4c3f62f530cf6c29272bae63a097681ab7fb.tar.gz
rneovim-766f4c3f62f530cf6c29272bae63a097681ab7fb.tar.bz2
rneovim-766f4c3f62f530cf6c29272bae63a097681ab7fb.zip
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.
-rw-r--r--src/nvim/ex_cmds2.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 950a1a436f..56d22349fc 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -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')) {
i++;
}
- char buf[2046];
- char *dst;
- dst = xstpncpy(buf, (char *)p->buf + p->offset, i - p->offset);
- if ((uint32_t)(dst - buf) != i - p->offset) {
+ size_t line_length = i - p->offset;
+ garray_T ga;
+ ga_init(&ga, (int)sizeof(char_u), (int)line_length);
+ 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);
return NULL;
}
- buf[i - p->offset] = '\0';
+ ga_append(&ga, '\0');
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,