diff options
Diffstat (limited to 'sftp.c')
-rw-r--r-- | sftp.c | 36 |
1 files changed, 26 insertions, 10 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp.c,v 1.136 2012/06/22 14:36:33 dtucker Exp $ */ | 1 | /* $OpenBSD: sftp.c,v 1.142 2013/02/08 00:41:12 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -54,10 +54,6 @@ typedef void EditLine; | |||
54 | # include <util.h> | 54 | # include <util.h> |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | #ifdef HAVE_LIBUTIL_H | ||
58 | # include <libutil.h> | ||
59 | #endif | ||
60 | |||
61 | #include "xmalloc.h" | 57 | #include "xmalloc.h" |
62 | #include "log.h" | 58 | #include "log.h" |
63 | #include "pathnames.h" | 59 | #include "pathnames.h" |
@@ -991,6 +987,10 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, | |||
991 | state = MA_START; | 987 | state = MA_START; |
992 | i = j = 0; | 988 | i = j = 0; |
993 | for (;;) { | 989 | for (;;) { |
990 | if ((size_t)argc >= sizeof(argv) / sizeof(*argv)){ | ||
991 | error("Too many arguments."); | ||
992 | return NULL; | ||
993 | } | ||
994 | if (isspace(arg[i])) { | 994 | if (isspace(arg[i])) { |
995 | if (state == MA_UNQUOTED) { | 995 | if (state == MA_UNQUOTED) { |
996 | /* Terminate current argument */ | 996 | /* Terminate current argument */ |
@@ -1141,7 +1141,7 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, | |||
1141 | 1141 | ||
1142 | /* Figure out which command we have */ | 1142 | /* Figure out which command we have */ |
1143 | for (i = 0; cmds[i].c != NULL; i++) { | 1143 | for (i = 0; cmds[i].c != NULL; i++) { |
1144 | if (strcasecmp(cmds[i].c, argv[0]) == 0) | 1144 | if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0) |
1145 | break; | 1145 | break; |
1146 | } | 1146 | } |
1147 | cmdnum = cmds[i].n; | 1147 | cmdnum = cmds[i].n; |
@@ -1695,7 +1695,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1695 | { | 1695 | { |
1696 | glob_t g; | 1696 | glob_t g; |
1697 | char *tmp, *tmp2, ins[3]; | 1697 | char *tmp, *tmp2, ins[3]; |
1698 | u_int i, hadglob, pwdlen, len, tmplen, filelen; | 1698 | u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs; |
1699 | const LineInfo *lf; | 1699 | const LineInfo *lf; |
1700 | 1700 | ||
1701 | /* Glob from "file" location */ | 1701 | /* Glob from "file" location */ |
@@ -1704,6 +1704,9 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1704 | else | 1704 | else |
1705 | xasprintf(&tmp, "%s*", file); | 1705 | xasprintf(&tmp, "%s*", file); |
1706 | 1706 | ||
1707 | /* Check if the path is absolute. */ | ||
1708 | isabs = tmp[0] == '/'; | ||
1709 | |||
1707 | memset(&g, 0, sizeof(g)); | 1710 | memset(&g, 0, sizeof(g)); |
1708 | if (remote != LOCAL) { | 1711 | if (remote != LOCAL) { |
1709 | tmp = make_absolute(tmp, remote_path); | 1712 | tmp = make_absolute(tmp, remote_path); |
@@ -1738,7 +1741,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1738 | goto out; | 1741 | goto out; |
1739 | 1742 | ||
1740 | tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc); | 1743 | tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc); |
1741 | tmp = path_strip(tmp2, remote_path); | 1744 | tmp = path_strip(tmp2, isabs ? NULL : remote_path); |
1742 | xfree(tmp2); | 1745 | xfree(tmp2); |
1743 | 1746 | ||
1744 | if (tmp == NULL) | 1747 | if (tmp == NULL) |
@@ -1747,8 +1750,18 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1747 | tmplen = strlen(tmp); | 1750 | tmplen = strlen(tmp); |
1748 | filelen = strlen(file); | 1751 | filelen = strlen(file); |
1749 | 1752 | ||
1750 | if (tmplen > filelen) { | 1753 | /* Count the number of escaped characters in the input string. */ |
1751 | tmp2 = tmp + filelen; | 1754 | cesc = isesc = 0; |
1755 | for (i = 0; i < filelen; i++) { | ||
1756 | if (!isesc && file[i] == '\\' && i + 1 < filelen){ | ||
1757 | isesc = 1; | ||
1758 | cesc++; | ||
1759 | } else | ||
1760 | isesc = 0; | ||
1761 | } | ||
1762 | |||
1763 | if (tmplen > (filelen - cesc)) { | ||
1764 | tmp2 = tmp + filelen - cesc; | ||
1752 | len = strlen(tmp2); | 1765 | len = strlen(tmp2); |
1753 | /* quote argument on way out */ | 1766 | /* quote argument on way out */ |
1754 | for (i = 0; i < len; i++) { | 1767 | for (i = 0; i < len; i++) { |
@@ -1762,6 +1775,8 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, | |||
1762 | case '\t': | 1775 | case '\t': |
1763 | case '[': | 1776 | case '[': |
1764 | case ' ': | 1777 | case ' ': |
1778 | case '#': | ||
1779 | case '*': | ||
1765 | if (quote == '\0' || tmp2[i] == quote) { | 1780 | if (quote == '\0' || tmp2[i] == quote) { |
1766 | if (el_insertstr(el, ins) == -1) | 1781 | if (el_insertstr(el, ins) == -1) |
1767 | fatal("el_insertstr " | 1782 | fatal("el_insertstr " |
@@ -1917,6 +1932,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) | |||
1917 | return (-1); | 1932 | return (-1); |
1918 | } | 1933 | } |
1919 | } else { | 1934 | } else { |
1935 | /* XXX this is wrong wrt quoting */ | ||
1920 | if (file2 == NULL) | 1936 | if (file2 == NULL) |
1921 | snprintf(cmd, sizeof cmd, "get %s", dir); | 1937 | snprintf(cmd, sizeof cmd, "get %s", dir); |
1922 | else | 1938 | else |