summaryrefslogtreecommitdiff
path: root/editors/tweak/patches/patch-keytab.c
blob: 294d56316ffb9789f99bf13f5d7ab5ab1c212a6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
$NetBSD: patch-keytab.c,v 1.1 2021/11/01 21:33:26 fcambus Exp $

Fix buffer overflow in 'unknown key sequence' error report.

Upstream commit ad97e1337e1e1df934b7f3674fa6c9f7e8eb603f.

--- keytab.c.orig	2021-11-01 18:58:59.087368560 +0000
+++ keytab.c
@@ -1,5 +1,6 @@
 #include "tweak.h"
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -61,16 +62,33 @@ void bind_key (char *sequence, int len, 
 /*
  * Format an ASCII code into a printable description of the key stroke.
  */
-static void strkey (char *s, int k) {
-    k &= 255;			       /* force unsigned */
-    if (k==27)
-	strcpy(s, " ESC");
-    else if (k<32 || k==127)
-	sprintf(s, " ^%c", k ^ 64);
-    else if (k<127)
-	sprintf(s, " %c", k);
-    else
-	sprintf(s, " <0x%2X>", k);
+struct strkey_state {
+    char *s, *end;
+    bool truncated;
+};
+static void strkey (struct strkey_state *sks, int k) {
+    char thisbuf[32];
+
+    if (sks->truncated)
+        return;
+
+    if (sks->end - sks->s < 16) {
+        sks->truncated = true;
+        strcpy(thisbuf, " ...");
+    } else {
+        k &= 255;			       /* force unsigned */
+        if (k==27)
+            strcpy(thisbuf, " ESC");
+        else if (k<32 || k==127)
+            sprintf(thisbuf, " ^%c", k ^ 64);
+        else if (k<127)
+            sprintf(thisbuf, " %c", k);
+        else
+            sprintf(thisbuf, " <0x%2X>", k);
+    }
+
+    strcpy(sks->s, thisbuf);
+    sks->s += strlen(sks->s);
 }
 
 /*
@@ -89,12 +107,18 @@ void proc_key (void) {
     safe_update = FALSE;
 #endif
     strcpy(message, "Unknown key sequence");
-    strkey(message+strlen(message), last_char);
+
+    struct strkey_state sks;
+    sks.s = message + strlen(message);
+    sks.end = message + sizeof(message);
+    sks.truncated = false;
+
+    strkey(&sks, last_char);
     kt = base[(unsigned char) last_char];
     if (!kt) {
 	display_beep();
 	while (display_input_to_flush())
-	    strkey(message+strlen(message), display_getkey());
+	    strkey(&sks, display_getkey());
 	return;
     }
 
@@ -108,12 +132,12 @@ void proc_key (void) {
 #if defined(unix) && !defined(GO32)
 	safe_update = FALSE;
 #endif
-	strkey(message+strlen(message), last_char);
+	strkey(&sks, last_char);
 	kt = kt->e.extended[(unsigned char) last_char];
 	if (!kt) {
 	    display_beep();
 	    while (display_input_to_flush())
-		strkey(message+strlen(message), display_getkey());
+		strkey(&sks, display_getkey());
 	    return;
 	}
     }