Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.4:ARM
openssh.18131
openssh-bsc1148566-scp-handle-quotes-while-chec...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssh-bsc1148566-scp-handle-quotes-while-checking-filenames-from-serv.patch of Package openssh.18131
@@ -, +, @@ --- scp.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 124 insertions(+), 19 deletions(-) --- a/scp.c +++ a/scp.c @@ -645,33 +645,62 @@ append(char *cp, char ***ap, size_t *np) } /* - * Finds the start and end of the first brace pair in the pattern. + * Finds the start and end of the first meta (braces or quotes) pair in the pattern. * returns 0 on success or -1 for invalid patterns. */ static int -find_brace(const char *pattern, int *startp, int *endp) +find_meta_pair(const char *pattern, int *startp, int *endp) { int i; int in_bracket, brace_level; + int in_single_qoutes, in_double_qoutes; *startp = *endp = -1; in_bracket = brace_level = 0; + in_single_qoutes = in_double_qoutes = 0; + for (i = 0; i < INT_MAX && *endp < 0 && pattern[i] != '\0'; i++) { switch (pattern[i]) { case '\\': /* skip next character */ - if (pattern[i + 1] != '\0') + if (!in_single_qoutes && pattern[i + 1] != '\0') i++; break; + case '\'': + if (in_bracket || in_double_qoutes) + break; + if (in_single_qoutes) { + *endp = i; + } else { + *startp = i; + } + in_single_qoutes = !in_single_qoutes; + break; + case '"': + if (in_bracket || in_single_qoutes) + break; + if (in_double_qoutes) { + *endp = i; + } else { + *startp = i; + } + in_double_qoutes = !in_double_qoutes; + break; case '[': + if (in_single_qoutes || in_double_qoutes) + break; in_bracket = 1; break; case ']': + if (in_single_qoutes || in_double_qoutes) + break; in_bracket = 0; break; case '{': if (in_bracket) break; + if (in_single_qoutes || in_double_qoutes) + break; if (pattern[i + 1] == '}') { /* Protect a single {}, for find(1), like csh */ i++; /* skip */ @@ -684,6 +713,8 @@ find_brace(const char *pattern, int *startp, int *endp) case '}': if (in_bracket) break; + if (in_single_qoutes || in_double_qoutes) + break; if (*startp < 0) { /* Unbalanced brace */ return -1; @@ -696,6 +727,9 @@ find_brace(const char *pattern, int *startp, int *endp) /* unbalanced brackets/braces */ if (*endp < 0 && (*startp >= 0 || in_bracket)) return -1; + /* unbalanced qoutes */ + if (in_single_qoutes || in_double_qoutes) + return -1; return 0; } @@ -738,6 +772,56 @@ emit_expansion(const char *pattern, int brace_start, int brace_end, return 0; } + +/* Expand string with qoutes and put the result to *patternsp array. + */ +static int +emit_quote_expansion(const char *pattern, int quote_start, int quote_end, + int single_quotes, char ***patternsp, size_t *npatternsp) +{ + char *cp; + int o = 0, tail_len = strlen(pattern + quote_end + 1); + int i; + + if ((cp = malloc(strlen(pattern) + 1)) == NULL) + return -1; + + /* Pattern before initial quote */ + if (quote_start > 0) { + memcpy(cp, pattern, quote_start); + o = quote_start; + } + + if (single_quotes) { + /* Single quoted selection */ + if (quote_end - quote_start > 0) { + memcpy(cp + o, pattern + quote_start + 1, + quote_end - quote_start - 1); + o += quote_end - quote_start - 1; + } + } else { + /* Double quoted selection has to handle '\' */ + for (i = quote_start + 1; i < quote_end; i++) { + if ((pattern[i] == '\\') && (i < quote_end - 1)) { + i++; + } + cp[o++] = pattern[i]; + } + } + + /* Remainder of pattern after closing brace */ + if (tail_len > 0) { + memcpy(cp + o, pattern + quote_end + 1, tail_len); + o += tail_len; + } + cp[o] = '\0'; + if (append(cp, patternsp, npatternsp) != 0) { + free(cp); + return -1; + } + return 0; +} + /* * Expand the first encountered brace in pattern, appending the expanded * patterns it yielded to the *patternsp array. @@ -748,21 +832,13 @@ emit_expansion(const char *pattern, int brace_start, int brace_end, * pattern was invalid via *invalid. */ static int -brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp, - int *expanded, int *invalid) +brace_expand_one(const char *pattern, int brace_start, int brace_end, + char ***patternsp, size_t *npatternsp, int *expanded, int *invalid) { int i; - int in_bracket, brace_start, brace_end, brace_level; + int in_bracket, brace_level; int sel_start, sel_end; - *invalid = *expanded = 0; - - if (find_brace(pattern, &brace_start, &brace_end) != 0) { - *invalid = 1; - return 0; - } else if (brace_start == -1) - return 0; - in_bracket = brace_level = 0; for (i = sel_start = brace_start + 1; i < brace_end; i++) { switch (pattern[i]) { @@ -811,9 +887,38 @@ brace_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp, return 0; } -/* Expand braces from pattern. Returns 0 on success, -1 on failure */ + +static int pattern_meta_expand_one(const char *pattern, char ***patternsp, size_t *npatternsp, + int *expanded, int *invalid) +{ + int meta_start, meta_end; + + *invalid = *expanded = 0; + + if (find_meta_pair(pattern, &meta_start, &meta_end) != 0) { + *invalid = 1; + return 0; + } else if (meta_start == -1) + return 0; + + if (pattern[meta_start] == '\'' || pattern[meta_start] == '"') + { + if (emit_quote_expansion(pattern, meta_start, meta_end, pattern[meta_start] == '\'', + patternsp, npatternsp) != 0) { + return -1; + } + *invalid = 0; + *expanded = 1; + return 0; + } + + return brace_expand_one(pattern, meta_start, meta_end, patternsp, npatternsp, + expanded, invalid); +} + +/* Expand braces and quotes from pattern. Returns 0 on success, -1 on failure */ static int -brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp) +pattern_meta_expand(const char *pattern, char ***patternsp, size_t *npatternsp) { char *cp, *cp2, **active = NULL, **done = NULL; size_t i, nactive = 0, ndone = 0; @@ -832,13 +937,13 @@ brace_expand(const char *pattern, char ***patternsp, size_t *npatternsp) while (nactive > 0) { cp = active[nactive - 1]; nactive--; - if (brace_expand_one(cp, &active, &nactive, + if (pattern_meta_expand_one(cp, &active, &nactive, &expanded, &invalid) == -1) { free(cp); goto fail; } if (invalid) - fatal("%s: invalid brace pattern \"%s\"", __func__, cp); + fatal("%s: invalid filename pattern \"%s\"", __func__, cp); if (expanded) { /* * Current entry expanded to new entries on the @@ -1271,7 +1376,7 @@ sink(int argc, char **argv, const char *src) * Prepare to try to restrict incoming filenames to match * the requested destination file glob. */ - if (brace_expand(src, &patterns, &npatterns) != 0) + if (pattern_meta_expand(src, &patterns, &npatterns) != 0) fatal("%s: could not expand pattern", __func__); } for (first = 1;; first = 0) { --
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor