summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2003-07-19 00:45:54 +0000
committerDamien Miller <djm@cvs.openbsd.org>2003-07-19 00:45:54 +0000
commitbf80e4b34f3405e08ad8108f945ebe45f0e7eade (patch)
treed6b134f8029f6d4dff86faffd448a4cf0ea33cbf
parent7b79c7366ff21764d1b5f6a37f85fd6307cab99e (diff)
fix sftp filename parsing for arguments with escaped quotes. bz #517; ok markus
-rw-r--r--usr.bin/ssh/sftp-int.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/usr.bin/ssh/sftp-int.c b/usr.bin/ssh/sftp-int.c
index 50bfa678c99..0971579a4b0 100644
--- a/usr.bin/ssh/sftp-int.c
+++ b/usr.bin/ssh/sftp-int.c
@@ -25,7 +25,7 @@
/* XXX: recursive operations */
#include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.60 2003/05/15 03:43:59 mouring Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.61 2003/07/19 00:45:53 djm Exp $");
#include <glob.h>
@@ -334,7 +334,7 @@ get_pathname(const char **cpp, char **path)
{
const char *cp = *cpp, *end;
char quot;
- int i;
+ int i, j;
cp += strspn(cp, WHITESPACE);
if (!*cp) {
@@ -343,37 +343,54 @@ get_pathname(const char **cpp, char **path)
return (0);
}
+ *path = xmalloc(strlen(cp) + 1);
+
/* Check for quoted filenames */
if (*cp == '\"' || *cp == '\'') {
quot = *cp++;
- end = strchr(cp, quot);
- if (end == NULL) {
- error("Unterminated quote");
- goto fail;
+ /* Search for terminating quote, unescape some chars */
+ for (i = j = 0; i <= strlen(cp); i++) {
+ if (cp[i] == quot) { /* Found quote */
+ (*path)[j] = '\0';
+ break;
+ }
+ if (cp[i] == '\0') { /* End of string */
+ error("Unterminated quote");
+ goto fail;
+ }
+ if (cp[i] == '\\') { /* Escaped characters */
+ i++;
+ if (cp[i] != '\'' && cp[i] != '\"' &&
+ cp[i] != '\\') {
+ error("Bad escaped character '\%c'",
+ cp[i]);
+ goto fail;
+ }
+ }
+ (*path)[j++] = cp[i];
}
- if (cp == end) {
+
+ if (j == 0) {
error("Empty quotes");
goto fail;
}
- *cpp = end + 1 + strspn(end + 1, WHITESPACE);
+ *cpp = cp + i + strspn(cp + i, WHITESPACE);
} else {
/* Read to end of filename */
end = strpbrk(cp, WHITESPACE);
if (end == NULL)
end = strchr(cp, '\0');
*cpp = end + strspn(end, WHITESPACE);
- }
-
- i = end - cp;
- *path = xmalloc(i + 1);
- memcpy(*path, cp, i);
- (*path)[i] = '\0';
- return(0);
+ memcpy(*path, cp, end - cp);
+ (*path)[end - cp] = '\0';
+ }
+ return (0);
fail:
- *path = NULL;
+ xfree(*path);
+ *path = NULL;
return (-1);
}