lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200615074910.19267-19-jslaby@suse.cz>
Date:   Mon, 15 Jun 2020 09:48:51 +0200
From:   Jiri Slaby <jslaby@...e.cz>
To:     gregkh@...uxfoundation.org
Cc:     linux-serial@...r.kernel.org, linux-kernel@...r.kernel.org,
        Jiri Slaby <jslaby@...e.cz>
Subject: [PATCH 19/38] vc: move normal char processing from do_con_write

vc_con_write_normal now handles the complex normal characters
processing. It is no longer a part of do_con_write. So this patch makes
do_con_write pretty clean and obvious.

Signed-off-by: Jiri Slaby <jslaby@...e.cz>
---
 drivers/tty/vt/vt.c | 198 ++++++++++++++++++++++++--------------------
 1 file changed, 109 insertions(+), 89 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 45d32844e61b..893f72dc812c 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2726,21 +2726,116 @@ static bool vc_is_control(struct vc_data *vc, int tc, int c)
 	return false;
 }
 
+static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
+		struct vc_draw_region *draw)
+{
+	int next_c;
+	unsigned char vc_attr;
+	u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff;
+	u8 width = 1;
+	bool inverse = false;
+
+	if (vc->vc_utf && !vc->vc_disp_ctrl) {
+		if (is_double_width(c))
+			width = 2;
+	}
+
+	/* Now try to find out how to display it */
+	tc = conv_uni_to_pc(vc, tc);
+	if (tc & ~charmask) {
+		if (tc == -1 || tc == -2)
+			return -1; /* nothing to display */
+
+		/* Glyph not found */
+		if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) &&
+				!(c & ~charmask)) {
+			/*
+			 * In legacy mode use the glyph we get by a 1:1
+			 * mapping.
+			 * This would make absolutely no sense with Unicode in
+			 * mind, but do this for ASCII characters since a font
+			 * may lack Unicode mapping info and we don't want to
+			 * end up with having question marks only.
+			 */
+			tc = c;
+		} else {
+			/*
+			 * Display U+FFFD. If it's not found, display an inverse
+			 * question mark.
+			 */
+			tc = conv_uni_to_pc(vc, 0xfffd);
+			if (tc < 0) {
+				inverse = true;
+				tc = conv_uni_to_pc(vc, '?');
+				if (tc < 0)
+					tc = '?';
+			}
+		}
+	}
+
+	if (!inverse) {
+		vc_attr = vc->vc_attr;
+	} else {
+		vc_attr = vc_invert_attr(vc);
+		con_flush(vc, draw);
+	}
+
+	next_c = c;
+	while (1) {
+		if (vc->vc_need_wrap || vc->vc_decim)
+			con_flush(vc, draw);
+		if (vc->vc_need_wrap) {
+			cr(vc);
+			lf(vc);
+		}
+		if (vc->vc_decim)
+			insert_char(vc, 1);
+		vc_uniscr_putc(vc, next_c);
+		scr_writew(himask ?
+			     ((vc_attr << 8) & ~himask) +
+			     ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+			     (vc_attr << 8) + tc,
+			   (u16 *)vc->vc_pos);
+		if (con_should_update(vc) && draw->x < 0) {
+			draw->x = vc->state.x;
+			draw->from = vc->vc_pos;
+		}
+		if (vc->state.x == vc->vc_cols - 1) {
+			vc->vc_need_wrap = vc->vc_decawm;
+			draw->to = vc->vc_pos + 2;
+		} else {
+			vc->state.x++;
+			draw->to = (vc->vc_pos += 2);
+		}
+
+		if (!--width)
+			break;
+
+		/* A space is printed in the second column */
+		tc = conv_uni_to_pc(vc, ' ');
+		if (tc < 0)
+			tc = ' ';
+		next_c = ' ';
+	}
+	notify_write(vc, c);
+
+	if (inverse)
+		con_flush(vc, draw);
+
+	return 0;
+}
+
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
 	struct vc_draw_region draw = {
 		.x = -1,
 	};
-	int c, next_c, tc, n = 0;
+	int c, tc, n = 0;
 	unsigned int currcons;
 	struct vc_data *vc;
-	unsigned char vc_attr;
 	struct vt_notifier_param param;
-	u16 himask, charmask;
-	u8 width;
 	bool rescan;
-	bool inverse;
 
 	if (in_interrupt())
 		return count;
@@ -2761,8 +2856,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 		return 0;
 	}
 
-	himask = vc->vc_hi_font_mask;
-	charmask = himask ? 0x1ff : 0xff;
 
 	/* undraw cursor first */
 	if (con_is_fg(vc))
@@ -2778,8 +2871,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 rescan_last_byte:
 		c = orig;
 		rescan = false;
-		inverse = false;
-		width = 1;
 
 		tc = vc_translate(vc, &c, &rescan);
 		if (tc == -1)
@@ -2790,88 +2881,17 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 					&param) == NOTIFY_STOP)
 			continue;
 
-		if (!vc_is_control(vc, tc, c)) {
-			if (vc->vc_utf && !vc->vc_disp_ctrl) {
-				if (is_double_width(c))
-					width = 2;
-			}
-			/* Now try to find out how to display it */
-			tc = conv_uni_to_pc(vc, tc);
-			if (tc & ~charmask) {
-				if (tc == -1 || tc == -2) {
-				    continue; /* nothing to display */
-				}
-				/* Glyph not found */
-				if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
-				    /* In legacy mode use the glyph we get by a 1:1 mapping.
-				       This would make absolutely no sense with Unicode in mind,
-				       but do this for ASCII characters since a font may lack
-				       Unicode mapping info and we don't want to end up with
-				       having question marks only. */
-				    tc = c;
-				} else {
-				    /* Display U+FFFD. If it's not found, display an inverse question mark. */
-				    tc = conv_uni_to_pc(vc, 0xfffd);
-				    if (tc < 0) {
-					inverse = true;
-					tc = conv_uni_to_pc(vc, '?');
-					if (tc < 0) tc = '?';
-				    }
-				}
-			}
-
-			if (!inverse) {
-				vc_attr = vc->vc_attr;
-			} else {
-				vc_attr = vc_invert_attr(vc);
-				con_flush(vc, &draw);
-			}
-
-			next_c = c;
-			while (1) {
-				if (vc->vc_need_wrap || vc->vc_decim)
-					con_flush(vc, &draw);
-				if (vc->vc_need_wrap) {
-					cr(vc);
-					lf(vc);
-				}
-				if (vc->vc_decim)
-					insert_char(vc, 1);
-				vc_uniscr_putc(vc, next_c);
-				scr_writew(himask ?
-					     ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
-					     (vc_attr << 8) + tc,
-					   (u16 *) vc->vc_pos);
-				if (con_should_update(vc) && draw.x < 0) {
-					draw.x = vc->state.x;
-					draw.from = vc->vc_pos;
-				}
-				if (vc->state.x == vc->vc_cols - 1) {
-					vc->vc_need_wrap = vc->vc_decawm;
-					draw.to = vc->vc_pos + 2;
-				} else {
-					vc->state.x++;
-					draw.to = (vc->vc_pos += 2);
-				}
-
-				if (!--width) break;
-
-				tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
-				if (tc < 0) tc = ' ';
-				next_c = ' ';
-			}
-			notify_write(vc, c);
-
-			if (inverse)
-				con_flush(vc, &draw);
-
-			if (rescan)
-				goto rescan_last_byte;
-
+		if (vc_is_control(vc, tc, c)) {
+			con_flush(vc, &draw);
+			do_con_trol(tty, vc, orig);
 			continue;
 		}
-		con_flush(vc, &draw);
-		do_con_trol(tty, vc, orig);
+
+		if (vc_con_write_normal(vc, tc, c, &draw) < 0)
+			continue;
+
+		if (rescan)
+			goto rescan_last_byte;
 	}
 	con_flush(vc, &draw);
 	vc_uniscr_debug_check(vc);
-- 
2.27.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ