diff options
-rw-r--r-- | src/ChangeLog | 1 | ||||
-rw-r--r-- | src/socket.c | 32 |
2 files changed, 28 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 6e67e53..b49c76b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -106,6 +106,7 @@ Version 4.1.0 (??/??/20??): * Emanuele Giaquinta <e.giaquinta@glauco.it> * Yi-Hsuan Hsin <mhsin@mhsin.org> * Chris Jones <cjns1989@gmail.com> + * Max Kalashnikov <mmt@maxkalashnikov.com> * Steve Kemp <steve@steve.org.uk> * Ryan Niebur <ryan@debian.org> * Jan Christoph Nordholz <hesso@pool.math.tu-berlin.de> diff --git a/src/socket.c b/src/socket.c index 619aebb..940034d 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1622,6 +1622,30 @@ int ilen; } #endif +/* 'end' is exclusive, i.e. you should *not* write in *end */ +static char * +strncpy_escape_quote(dst, src, end) +char *dst; +const char *src, *end; +{ + while (*src && dst < end) + { + if (*src == '"') + { + if (dst + 2 < end) /* \\ \" \0 */ + *dst++ = '\\'; + else + return NULL; + } + *dst++ = *src++; + } + if (dst >= end) + return NULL; + + *dst = '\0'; + return dst; +} + static void DoCommandMsg(mp) struct msg *mp; @@ -1645,16 +1669,14 @@ struct msg *mp; for (fc = fullcmd; n > 0; n--) { int len = strlen(p); - /* Make sure there's enough room */ - if (fc + len + 3 > fullcmd + sizeof(fullcmd) - 1) + *fc++ = '"'; + if (!(fc = strncpy_escape_quote(fc, p, fullcmd + sizeof(fullcmd) - 2))) /* '"' ' ' */ { + Msg(0, "Remote command too long."); queryflag = -1; return; } - *fc++ = '"'; - strncpy(fc, p, fullcmd + sizeof(fullcmd) - fc - 1); p += len + 1; - fc += len; *fc++ = '"'; *fc++ = ' '; } |