- djm@cvs.openbsd.org 2003/07/19 00:45:53
[sftp-int.c]
fix sftp filename parsing for arguments with escaped quotes. bz #517;
ok markus
diff --git a/ChangeLog b/ChangeLog
index f645e68..c2bb7bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,10 @@
- deraadt@cvs.openbsd.org 2003/07/18 01:54:25
[scp.c]
userid is unsigned, but well, force it anyways; andrushock@korovino.net
+ - djm@cvs.openbsd.org 2003/07/19 00:45:53
+ [sftp-int.c]
+ fix sftp filename parsing for arguments with escaped quotes. bz #517;
+ ok markus
20030714
- (dtucker) [acconfig.h configure.ac port-aix.c] Older AIXes don't declare
@@ -711,4 +715,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
-$Id: ChangeLog,v 1.2861 2003/07/19 10:07:45 dtucker Exp $
+$Id: ChangeLog,v 1.2862 2003/07/19 10:09:21 dtucker Exp $
diff --git a/sftp-int.c b/sftp-int.c
index f2d3f94..73653b7 100644
--- a/sftp-int.c
+++ b/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 "buffer.h"
#include "xmalloc.h"
@@ -332,7 +332,7 @@
{
const char *cp = *cpp, *end;
char quot;
- int i;
+ int i, j;
cp += strspn(cp, WHITESPACE);
if (!*cp) {
@@ -341,37 +341,54 @@
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);
+
+ memcpy(*path, cp, end - cp);
+ (*path)[end - cp] = '\0';
}
-
- i = end - cp;
-
- *path = xmalloc(i + 1);
- memcpy(*path, cp, i);
- (*path)[i] = '\0';
- return(0);
+ return (0);
fail:
- *path = NULL;
+ xfree(*path);
+ *path = NULL;
return (-1);
}