View | Details | Raw Unified | Return to bug 778 | Differences between
and this patch

Collapse All | Expand All

(-)usr.bin/ssh/sftp.c (-37 / +32 lines)
Lines 22-27 Link Here
22
#include <sys/socket.h>
22
#include <sys/socket.h>
23
#include <sys/param.h>
23
#include <sys/param.h>
24
24
25
#include <ctype.h>
25
#include <errno.h>
26
#include <errno.h>
26
#include <glob.h>
27
#include <glob.h>
27
#include <histedit.h>
28
#include <histedit.h>
Lines 411-418 parse_ls_flags(const char **cpp, int *lf Link Here
411
static int
412
static int
412
get_pathname(const char **cpp, char **path)
413
get_pathname(const char **cpp, char **path)
413
{
414
{
414
	const char *cp = *cpp, *end;
415
	const char *cp = *cpp;
415
	char quot;
416
	int quot = -1;
416
	u_int i, j;
417
	u_int i, j;
417
418
418
	cp += strspn(cp, WHITESPACE);
419
	cp += strspn(cp, WHITESPACE);
Lines 422-471 get_pathname(const char **cpp, char **pa Link Here
422
		return (0);
423
		return (0);
423
	}
424
	}
424
425
426
	/* There is no possibility of expansion, so this will fit */
425
	*path = xmalloc(strlen(cp) + 1);
427
	*path = xmalloc(strlen(cp) + 1);
426
428
427
	/* Check for quoted filenames */
429
	if (*cp == '\"' || *cp == '\'')
428
	if (*cp == '\"' || *cp == '\'') {
429
		quot = *cp++;
430
		quot = *cp++;
430
431
431
		/* Search for terminating quote, unescape some chars */
432
	/*
432
		for (i = j = 0; i <= strlen(cp); i++) {
433
	 * Search for terminating quote or unescaped whitespace,
433
			if (cp[i] == quot) {	/* Found quote */
434
	 * unescaping some special characters along the way.
434
				i++;
435
	 */
435
				(*path)[j] = '\0';
436
	for (i = j = 0; i <= strlen(cp); i++) {
436
				break;
437
		if ((quot == -1 && (isspace(cp[i]) || cp[i] == '\0')) ||
437
			}
438
		    cp[i] == quot) {
438
			if (cp[i] == '\0') {	/* End of string */
439
			i++;
439
				error("Unterminated quote");
440
			(*path)[j] = '\0';
440
				goto fail;
441
			break;
441
			}
442
			if (cp[i] == '\\') {	/* Escaped characters */
443
				i++;
444
				if (cp[i] != '\'' && cp[i] != '\"' &&
445
				    cp[i] != '\\') {
446
					error("Bad escaped character '\\%c'",
447
					    cp[i]);
448
					goto fail;
449
				}
450
			}
451
			(*path)[j++] = cp[i];
452
		}
442
		}
453
443
		if (quot != -1 && cp[i] == '\0') {
454
		if (j == 0) {
444
			error("Unterminated quote");
455
			error("Empty quotes");
456
			goto fail;
445
			goto fail;
457
		}
446
		}
458
		*cpp = cp + i + strspn(cp + i, WHITESPACE);
447
		if (cp[i] == '\\') {
459
	} else {
448
			i++;
460
		/* Read to end of filename */
449
			/* Pass unknown escape sequences through verbatim */
461
		end = strpbrk(cp, WHITESPACE);
450
			if (cp[i] != '\'' && cp[i] != '\"' &&
462
		if (end == NULL)
451
			    cp[i] != '\\' &&
463
			end = strchr(cp, '\0');
452
			    !(quot == -1 && isspace(cp[i])))
464
		*cpp = end + strspn(end, WHITESPACE);
453
				(*path)[j++] = '\\';
454
		}
455
		(*path)[j++] = cp[i];
456
	}
465
457
466
		memcpy(*path, cp, end - cp);
458
	if (j == 0) {
467
		(*path)[end - cp] = '\0';
459
		error("Empty pathname");
460
		goto fail;
468
	}
461
	}
462
463
	*cpp = cp + i + strspn(cp + i, WHITESPACE);
469
	return (0);
464
	return (0);
470
465
471
 fail:
466
 fail:
(-)regress/usr.bin/ssh/sftp-cmds.sh (-8 / +36 lines)
Lines 14-19 GLOBFILES=`(cd /bin;echo l*)` Link Here
14
# Path with embedded quote
14
# Path with embedded quote
15
QUOTECOPY=${COPY}".\"blah\""
15
QUOTECOPY=${COPY}".\"blah\""
16
QUOTECOPY_ARG=${COPY}'.\"blah\"'
16
QUOTECOPY_ARG=${COPY}'.\"blah\"'
17
# File with spaces
18
SPACECOPY="${COPY} this has spaces.txt"
19
SPACECOPY_ARG="${COPY}\ this\ has\ spaces.txt"
20
# File with glob metacharacters
21
GLOBMETACOPY="${COPY} [metachar].txt"
22
GLOBMETACOPY_ARG="\"${COPY} \\[metachar].txt\""
17
23
18
rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 ${BATCH}.*
24
rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 ${BATCH}.*
19
mkdir ${COPY}.dd
25
mkdir ${COPY}.dd
Lines 69-78 rm -f ${QUOTECOPY} Link Here
69
cp $DATA ${QUOTECOPY}
75
cp $DATA ${QUOTECOPY}
70
verbose "$tid: get filename with quotes"
76
verbose "$tid: get filename with quotes"
71
echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
77
echo "get \"$QUOTECOPY_ARG\" ${COPY}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
72
	|| fail "put failed"
78
	|| fail "get failed"
73
cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes"
79
cmp ${COPY} ${QUOTECOPY} || fail "corrupted copy after get with quotes"
74
rm -f ${QUOTECOPY} ${COPY}
80
rm -f ${QUOTECOPY} ${COPY}
75
81
82
rm -f "$SPACECOPY" ${COPY}
83
cp $DATA "$SPACECOPY"
84
verbose "$tid: get filename with spaces"
85
echo "get ${SPACECOPY_ARG} ${COPY}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
86
        || fail "get failed"
87
cmp ${COPY} "$SPACECOPY" || fail "corrupted copy after get with spaces"
88
89
rm -f "$GLOBMETACOPY" ${COPY}
90
cp $DATA "$GLOBMETACOPY"
91
verbose "$tid: get filename with glob metacharacters"
92
echo "get ${GLOBMETACOPY_ARG} ${COPY}" | \
93
	${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "get failed"
94
cmp ${COPY} "$GLOBMETACOPY" || \
95
	fail "corrupted copy after put with glob metacharacters"
96
76
rm -f ${COPY}.dd/*
97
rm -f ${COPY}.dd/*
77
verbose "$tid: get to directory"
98
verbose "$tid: get to directory"
78
echo "get $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
99
echo "get $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
Lines 103-118 done Link Here
103
124
104
rm -f ${COPY}
125
rm -f ${COPY}
105
verbose "$tid: put"
126
verbose "$tid: put"
106
echo "put $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
127
echo "put $DATA $COPY" | \
107
	|| fail "put failed"
128
	${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
108
cmp $DATA ${COPY} || fail "corrupted copy after put"
129
cmp $DATA ${COPY} || fail "corrupted copy after put"
109
130
110
rm -f ${QUOTECOPY}
131
rm -f ${QUOTECOPY}
111
verbose "$tid: put filename with quotes"
132
verbose "$tid: put filename with quotes"
112
echo "put $DATA \"$QUOTECOPY_ARG\"" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
133
echo "put $DATA \"$QUOTECOPY_ARG\"" | \
113
	|| fail "put failed"
134
	${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
114
cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes"
135
cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes"
115
136
137
rm -f "$SPACECOPY"
138
verbose "$tid: put filename with spaces"
139
echo "put $DATA ${SPACECOPY_ARG}" | \
140
	${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "put failed"
141
cmp $DATA "$SPACECOPY" || fail "corrupted copy after put with spaces"
142
116
rm -f ${COPY}.dd/*
143
rm -f ${COPY}.dd/*
117
verbose "$tid: put to directory"
144
verbose "$tid: put to directory"
118
echo "put $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
145
echo "put $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
Lines 148-155 test -f ${COPY}.1 || fail "missing file Link Here
148
cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename"
175
cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename"
149
176
150
verbose "$tid: rename directory"
177
verbose "$tid: rename directory"
151
echo "rename ${COPY}.dd ${COPY}.dd2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \
178
echo "rename ${COPY}.dd ${COPY}.dd2" | \
152
	|| fail "rename directory failed"
179
	${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || \
180
	fail "rename directory failed"
153
test -d ${COPY}.dd && fail "oldname exists after rename directory"
181
test -d ${COPY}.dd && fail "oldname exists after rename directory"
154
test -d ${COPY}.dd2 || fail "missing newname after rename directory"
182
test -d ${COPY}.dd2 || fail "missing newname after rename directory"
155
183
Lines 183-188 echo "lchdir ${COPY}.dd" | ${SFTP} -P ${ Link Here
183
	|| fail "lchdir failed"
211
	|| fail "lchdir failed"
184
212
185
rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 ${BATCH}.*
213
rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 ${BATCH}.*
186
rm -rf ${QUOTECOPY}
214
rm -rf ${QUOTECOPY} "$SPACECOPY" "$GLOBMETACOPY"
187
215
188
216

Return to bug 778