From 9136ec134c97a8aff2917760c03134f52945ff3c Mon Sep 17 00:00:00 2001 From: "deraadt@openbsd.org" Date: Mon, 12 Sep 2016 01:22:38 +0000 Subject: upstream commit Add MAXIMUM(), MINIMUM(), and ROUNDUP() to misc.h, then use those definitions rather than pulling and unknown namespace pollution. ok djm markus dtucker Upstream-ID: 712cafa816c9f012a61628b66b9fbd5687223fb8 --- scp.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'scp.c') diff --git a/scp.c b/scp.c index 43ca3fa09..c67cd71df 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.186 2016/05/25 23:48:45 schwarze Exp $ */ +/* $OpenBSD: scp.c,v 1.187 2016/09/12 01:22:38 deraadt Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -74,7 +74,6 @@ #include "includes.h" #include -#include #ifdef HAVE_SYS_STAT_H # include #endif @@ -383,7 +382,7 @@ main(int argc, char **argv) setlocale(LC_CTYPE, ""); /* Copy argv, because we modify it */ - newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv)); + newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv)); for (n = 0; n < argc; n++) newargv[n] = xstrdup(argv[n]); argv = newargv; @@ -1343,7 +1342,7 @@ allocbuf(BUF *bp, int fd, int blksize) run_err("fstat: %s", strerror(errno)); return (0); } - size = roundup(stb.st_blksize, blksize); + size = ROUNDUP(stb.st_blksize, blksize); if (size == 0) size = blksize; #else /* HAVE_STRUCT_STAT_ST_BLKSIZE */ -- cgit v1.2.3 From dda78a03af32e7994f132d923c2046e98b7c56c8 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 12 Dec 2016 13:57:10 +1100 Subject: Force Turkish locales back to C/POSIX; bz#2643 Turkish locales are unique in their handling of the letters 'i' and 'I' (yes, they are different letters) and OpenSSH isn't remotely prepared to deal with that. For now, the best we can do is to force OpenSSH to use the C/POSIX locale and try to preserve the UTF-8 encoding if possible. ok dtucker@ --- scp.c | 2 +- sftp.c | 2 +- ssh.c | 3 ++- utf8.c | 42 ++++++++++++++++++++++++++++++++++++++++++ utf8.h | 1 + 5 files changed, 47 insertions(+), 3 deletions(-) (limited to 'scp.c') diff --git a/scp.c b/scp.c index c67cd71df..b4db85198 100644 --- a/scp.c +++ b/scp.c @@ -379,7 +379,7 @@ main(int argc, char **argv) /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); - setlocale(LC_CTYPE, ""); + msetlocale(); /* Copy argv, because we modify it */ newargv = xcalloc(MAXIMUM(argc + 1, 1), sizeof(*newargv)); diff --git a/sftp.c b/sftp.c index af6e3a69a..2b8fdabfb 100644 --- a/sftp.c +++ b/sftp.c @@ -2272,7 +2272,7 @@ main(int argc, char **argv) ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); - setlocale(LC_CTYPE, ""); + msetlocale(); __progname = ssh_get_progname(argv[0]); memset(&args, '\0', sizeof(args)); diff --git a/ssh.c b/ssh.c index 8aa8daae4..ee0b16dc2 100644 --- a/ssh.c +++ b/ssh.c @@ -109,6 +109,7 @@ #include "version.h" #include "ssherr.h" #include "myproposal.h" +#include "utf8.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" @@ -589,7 +590,7 @@ main(int ac, char **av) */ umask(022); - setlocale(LC_CTYPE, ""); + msetlocale(); /* * Initialize option structure to indicate that no values have been diff --git a/utf8.c b/utf8.c index f563d3738..87fa9e89a 100644 --- a/utf8.c +++ b/utf8.c @@ -27,6 +27,7 @@ # include #endif #include +#include #include #include #include @@ -288,3 +289,44 @@ mprintf(const char *fmt, ...) va_end(ap); return ret; } + +/* + * Set up libc for multibyte output in the user's chosen locale. + * + * XXX: we are known to have problems with Turkish (i/I confusion) so we + * deliberately fall back to the C locale for now. Longer term we should + * always prefer to select C.[encoding] if possible, but there's no + * standardisation in locales between systems, so we'll need to survey + * what's out there first. + */ +void +msetlocale(void) +{ + const char *vars[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL }; + char *cp; + int i; + + /* + * We can't yet cope with dotless/dotted I in Turkish locales, + * so fall back to the C locale for these. + */ + for (i = 0; vars[i] != NULL; i++) { + if ((cp = getenv(vars[i])) == NULL) + continue; + if (strncasecmp(cp, "TR", 2) != 0) + break; + /* + * If we're in a UTF-8 locale then prefer to use + * the C.UTF-8 locale (or equivalent) if it exists. + */ + if ((strcasestr(cp, "UTF-8") != NULL || + strcasestr(cp, "UTF8") != NULL) && + (setlocale(LC_CTYPE, "C.UTF-8") != NULL || + setlocale(LC_CTYPE, "POSIX.UTF-8") != NULL)) + return; + setlocale(LC_CTYPE, "C"); + return; + } + /* We can handle this locale */ + setlocale(LC_CTYPE, ""); +} diff --git a/utf8.h b/utf8.h index 43ce1d55d..88c5a34a3 100644 --- a/utf8.h +++ b/utf8.h @@ -22,3 +22,4 @@ int fmprintf(FILE *, const char *, ...) int vfmprintf(FILE *, const char *, va_list); int snmprintf(char *, size_t, int *, const char *, ...) __attribute__((format(printf, 4, 5))); +void msetlocale(void); -- cgit v1.2.3