diff options
author | Alistair Delva <adelva@google.com> | 2020-08-21 00:00:13 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-08-21 00:00:13 +0000 |
commit | ed358b3546c776c1c677fd88eb8f716cf6187510 (patch) | |
tree | 3c6134bcb2cda4b9dccc57b4a8b997a945aab62d /openbsd-compat/bsd-cygwin_util.c | |
parent | 22246b08952d746a7cc5a292570636cf4277598f (diff) | |
parent | 44a1065de8a58c51a021243a28bfa01e87822e4f (diff) |
Merge changes I934c73d4,I28cdc9a0,I9e734da9,I3c079d86
* changes:
UPSTREAM: depend
UPSTREAM: upstream: avoid possible NULL deref; from Pedro Martelletto
Revert "upstream: fix compilation with DEBUG_KEXDH; bz#3160 ok dtucker@"
Merge upstream-master into master
Diffstat (limited to 'openbsd-compat/bsd-cygwin_util.c')
-rw-r--r-- | openbsd-compat/bsd-cygwin_util.c | 156 |
1 files changed, 153 insertions, 3 deletions
diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index a2d82126..54628e26 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -36,15 +36,19 @@ #include <fcntl.h> #include <string.h> #include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <wchar.h> +#include <wctype.h> #include "xmalloc.h" -int +int binary_open(const char *filename, int flags, ...) { va_list ap; mode_t mode; - + va_start(ap, flags); mode = va_arg(ap, mode_t); va_end(ap); @@ -68,7 +72,7 @@ cygwin_ssh_privsep_user() if (cygwin_internal (CW_CYGNAME_FROM_WINNAME, "sshd", cyg_privsep_user, sizeof cyg_privsep_user) != 0) #endif - strcpy (cyg_privsep_user, "sshd"); + strlcpy(cyg_privsep_user, "sshd", sizeof(cyg_privsep_user)); } return cyg_privsep_user; } @@ -116,4 +120,150 @@ free_windows_environment(char **p) free(p); } +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + * + * The Cygwin version of this function must be case-insensitive and take + * Unicode characters into account. + */ + +static int +__match_pattern (const wchar_t *s, const wchar_t *pattern) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + __match_pattern(s + 1, pattern + 1)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (__match_pattern(s, pattern)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && towlower(*pattern) != towlower(*s)) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +static int +_match_pattern(const char *s, const char *pattern) +{ + wchar_t *ws; + wchar_t *wpattern; + size_t len; + int ret; + + if ((len = mbstowcs(NULL, s, 0)) < 0) + return 0; + ws = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t)); + mbstowcs(ws, s, len + 1); + if ((len = mbstowcs(NULL, pattern, 0)) < 0) + return 0; + wpattern = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t)); + mbstowcs(wpattern, pattern, len + 1); + ret = __match_pattern (ws, wpattern); + free(ws); + free(wpattern); + return ret; +} + +/* + * Tries to match the string against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int +cygwin_ug_match_pattern_list(const char *string, const char *pattern) +{ + char sub[1024]; + int negated; + int got_positive; + u_int i, subi, len = strlen(pattern); + + got_positive = 0; + for (i = 0; i < len;) { + /* Check if the subpattern is negated. */ + if (pattern[i] == '!') { + negated = 1; + i++; + } else + negated = 0; + + /* + * Extract the subpattern up to a comma or end. Convert the + * subpattern to lowercase. + */ + for (subi = 0; + i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; + subi++, i++) + sub[subi] = pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, then skip it. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the string. */ + if (_match_pattern(string, sub)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} + #endif /* HAVE_CYGWIN */ |