mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	If we know the terminal outside tmux is not UTF-8, replace UTF-8 in
error messages and whatnot with underscores the same as we do when we draw UTF-8 characters as part of the screen.
This commit is contained in:
		@@ -133,7 +133,7 @@ void
 | 
			
		||||
cmd_load_buffer_callback(struct client *c, int closed, void *data)
 | 
			
		||||
{
 | 
			
		||||
	const char	*bufname = data;
 | 
			
		||||
	char		*pdata, *cause;
 | 
			
		||||
	char		*pdata, *cause, *saved;
 | 
			
		||||
	size_t		 psize;
 | 
			
		||||
 | 
			
		||||
	if (!closed)
 | 
			
		||||
@@ -154,6 +154,11 @@ cmd_load_buffer_callback(struct client *c, int closed, void *data)
 | 
			
		||||
 | 
			
		||||
	if (paste_set(pdata, psize, bufname, &cause) != 0) {
 | 
			
		||||
		/* No context so can't use server_client_msg_error. */
 | 
			
		||||
		if (~c->flags & CLIENT_UTF8) {
 | 
			
		||||
			saved = cause;
 | 
			
		||||
			cause = utf8_sanitize(saved);
 | 
			
		||||
			free(saved);
 | 
			
		||||
		}
 | 
			
		||||
		evbuffer_add_printf(c->stderr_data, "%s", cause);
 | 
			
		||||
		server_push_stderr(c);
 | 
			
		||||
		free(pdata);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								cmd-queue.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								cmd-queue.c
									
									
									
									
									
								
							@@ -69,14 +69,21 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
 | 
			
		||||
	struct client	*c = cmdq->client;
 | 
			
		||||
	struct window	*w;
 | 
			
		||||
	va_list		 ap;
 | 
			
		||||
	char		*tmp, *msg;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
 | 
			
		||||
	if (c == NULL)
 | 
			
		||||
		/* nothing */;
 | 
			
		||||
	else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
 | 
			
		||||
		evbuffer_add_vprintf(c->stdout_data, fmt, ap);
 | 
			
		||||
 | 
			
		||||
		if (~c->flags & CLIENT_UTF8) {
 | 
			
		||||
			vasprintf(&tmp, fmt, ap);
 | 
			
		||||
			msg = utf8_sanitize(tmp);
 | 
			
		||||
			free(tmp);
 | 
			
		||||
			evbuffer_add(c->stdout_data, msg, strlen(msg));
 | 
			
		||||
			free(msg);
 | 
			
		||||
		} else
 | 
			
		||||
			evbuffer_add_vprintf(c->stdout_data, fmt, ap);
 | 
			
		||||
		evbuffer_add(c->stdout_data, "\n", 1);
 | 
			
		||||
		server_push_stdout(c);
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -101,6 +108,7 @@ cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
 | 
			
		||||
	va_list		 ap;
 | 
			
		||||
	char		*msg;
 | 
			
		||||
	size_t		 msglen;
 | 
			
		||||
	char		*tmp;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	msglen = xvasprintf(&msg, fmt, ap);
 | 
			
		||||
@@ -109,9 +117,14 @@ cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
 | 
			
		||||
	if (c == NULL)
 | 
			
		||||
		cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
 | 
			
		||||
	else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
 | 
			
		||||
		if (~c->flags & CLIENT_UTF8) {
 | 
			
		||||
			tmp = msg;
 | 
			
		||||
			msg = utf8_sanitize(tmp);
 | 
			
		||||
			free(tmp);
 | 
			
		||||
			msglen = strlen(msg);
 | 
			
		||||
		}
 | 
			
		||||
		evbuffer_add(c->stderr_data, msg, msglen);
 | 
			
		||||
		evbuffer_add(c->stderr_data, "\n", 1);
 | 
			
		||||
 | 
			
		||||
		server_push_stderr(c);
 | 
			
		||||
		c->retval = 1;
 | 
			
		||||
	} else {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							@@ -2189,6 +2189,7 @@ u_int		 utf8_combine(const struct utf8_data *);
 | 
			
		||||
int		 utf8_split(u_int, struct utf8_data *);
 | 
			
		||||
u_int		 utf8_split2(u_int, u_char *);
 | 
			
		||||
int		 utf8_strvis(char *, const char *, size_t, int);
 | 
			
		||||
char		*utf8_sanitize(const char *);
 | 
			
		||||
struct utf8_data *utf8_fromcstr(const char *);
 | 
			
		||||
char		*utf8_tocstr(struct utf8_data *);
 | 
			
		||||
u_int		 utf8_cstrwidth(const char *);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								utf8.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								utf8.c
									
									
									
									
									
								
							@@ -585,6 +585,50 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
 | 
			
		||||
	return (dst - start);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Sanitize a string, changing any UTF-8 characters to '_'. Caller should free
 | 
			
		||||
 * the returned string. Anything not valid printable ASCII or UTF-8 is
 | 
			
		||||
 * stripped.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
utf8_sanitize(const char *src)
 | 
			
		||||
{
 | 
			
		||||
	char			*dst;
 | 
			
		||||
	size_t			 n;
 | 
			
		||||
	int			 more;
 | 
			
		||||
	struct utf8_data	 utf8data;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
 | 
			
		||||
	dst = NULL;
 | 
			
		||||
 | 
			
		||||
	n = 0;
 | 
			
		||||
	while (*src != '\0') {
 | 
			
		||||
		dst = xreallocarray(dst, n + 1, sizeof *dst);
 | 
			
		||||
		if (utf8_open(&utf8data, *src)) {
 | 
			
		||||
			more = 1;
 | 
			
		||||
			while (*++src != '\0' && more)
 | 
			
		||||
				more = utf8_append(&utf8data, *src);
 | 
			
		||||
			if (!more) {
 | 
			
		||||
				dst = xreallocarray(dst, n + utf8data.width,
 | 
			
		||||
				    sizeof *dst);
 | 
			
		||||
				for (i = 0; i < utf8data.width; i++)
 | 
			
		||||
					dst[n++] = '_';
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			src -= utf8data.have;
 | 
			
		||||
		}
 | 
			
		||||
		if (*src > 0x1f && *src < 0x7f)
 | 
			
		||||
			dst[n] = *src;
 | 
			
		||||
		src++;
 | 
			
		||||
 | 
			
		||||
		n++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dst = xreallocarray(dst, n + 1, sizeof *dst);
 | 
			
		||||
	dst[n] = '\0';
 | 
			
		||||
	return (dst);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Convert a string into a buffer of UTF-8 characters. Terminated by size == 0.
 | 
			
		||||
 * Caller frees.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user