aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-graphics/xorg-app/xterm/CVE-2023-40359.patch
blob: 342a8d872531ca441c30d29dc44114593bc29234 (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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
From 41ba5cf31da5e43477811b28009d64d3f643fd29 Mon Sep 17 00:00:00 2001
From: "Thomas E. Dickey" <dickey@invisible-island.net>
Date: Wed, 8 Mar 2023 01:06:03 +0000
Subject: [PATCH] snapshot of project "xterm", label xterm-379c

Upstream-Status: Backport from https://github.com/ThomasDickey/xterm-snapshots/commit/41ba5cf31da5e43477811b28009d64d3f643fd29
CVE: CVE-2023-40359

Signed-off-by: Rohini Sangam <rsangam@mvista.com>

---
 graphics_regis.c | 235 +++++++++++++++++++++++++++--------------------
 1 file changed, 133 insertions(+), 102 deletions(-)

diff --git a/graphics_regis.c b/graphics_regis.c
index 479bb79..cf14437 100644
--- a/graphics_regis.c
+++ b/graphics_regis.c
@@ -1,8 +1,8 @@
-/* $XTermId: graphics_regis.c,v 1.129 2022/02/21 13:33:08 tom Exp $ */
+/* $XTermId: graphics_regis.c,v 1.139 2023/03/08 01:06:03 tom Exp $ */
 
 /*
- * Copyright 2014-2021,2022 by Ross Combs
- * Copyright 2014-2021,2022 by Thomas E. Dickey
+ * Copyright 2014-2022,2023 by Ross Combs
+ * Copyright 2014-2022,2023 by Thomas E. Dickeiy
  *
  *                         All Rights Reserved
  *
@@ -119,6 +119,14 @@ typedef struct RegisTextControls {
     int       slant; /* for italic/oblique */
 } RegisTextControls;
 
+#define S_QUOTE '\''
+#define D_QUOTE '"'
+
+#define isQuote(ch)   ((ch) == S_QUOTE || (ch) == D_QUOTE)
+#define PickQuote(ch) ((ch) == S_QUOTE ? D_QUOTE : S_QUOTE)
+
+#define isName(c) ((c) == '_' || isalnum(CharOf(c)))
+
 #define FixedCopy(dst, src, len) strncpy(dst, src, len - 1)[len - 1] = '\0'
 #define CopyFontname(dst, src) FixedCopy(dst, src, (size_t) REGIS_FONTNAME_LEN)
 
@@ -538,8 +546,8 @@ draw_or_save_patterned_pixel(RegisGraphicsContext *context, int x, int y)
 static int
 sort_points(void const *l, void const *r)
 {
-    RegisPoint const *const lp = l;
-    RegisPoint const *const rp = r;
+    RegisPoint const *const lp = (RegisPoint const *) l;
+    RegisPoint const *const rp = (RegisPoint const *) r;
 
     if (lp->y < rp->y)
 	return -1;
@@ -3151,6 +3159,37 @@ extract_regis_command(RegisDataFragment *input, char *command)
     return 1;
 }
 
+/*
+ *  * Check a ReGIS alphabet name before reporting it, to pick an appropriate
+ *   * delimiter.  If the string is empty, or contains nonreportable characters,
+ *    * just return NUL.
+ *     */
+static int
+pick_quote(const char *value)
+{
+    Bool s_quote = False;
+    Bool d_quote = False;
+
+    if (*value != '\0') {
+	while (*value != '\0') {
+	    int ch = CharOf(*value++);
+	    if (ch == D_QUOTE)
+		d_quote = True;
+	    else if (ch == S_QUOTE)
+		s_quote = True;
+	    else if (!isName(ch))
+		s_quote = d_quote = True;
+	}
+    } else {
+	s_quote = d_quote = True;
+    }
+    return ((s_quote && d_quote)
+	    ? 0
+	    : (s_quote
+	       ? D_QUOTE
+	       : S_QUOTE));
+}
+
 static int
 extract_regis_string(RegisDataFragment *input, char *out, unsigned maxlen)
 {
@@ -3166,7 +3205,7 @@ extract_regis_string(RegisDataFragment *input, char *out, unsigned maxlen)
 	return 0;
 
     ch = peek_fragment(input);
-    if (ch != '\'' && ch != '"')
+    if (!isQuote(ch))
 	return 0;
     open_quote_ch = ch;
     outlen = 0U;
@@ -3246,7 +3285,7 @@ extract_regis_parenthesized_data(RegisDataFragment *input,
     for (; input->pos < input->len; input->pos++, output->len++) {
 	char prev_ch = ch;
 	ch = input->start[input->pos];
-	if (ch == '\'' || ch == '"') {
+	if (isQuote(ch)) {
 	    if (open_quote_ch == '\0') {
 		open_quote_ch = ch;
 	    } else {
@@ -3314,7 +3353,7 @@ extract_regis_option(RegisDataFragment *input,
     if (ch == ';' || ch == ',' ||
 	ch == '(' || ch == ')' ||
 	ch == '[' || ch == ']' ||
-	ch == '"' || ch == '\'' ||
+	isQuote(ch) ||
 	isdigit(CharOf(ch))) {
 	return 0;
     }
@@ -3330,7 +3369,7 @@ extract_regis_option(RegisDataFragment *input,
 	TRACE(("looking at char '%c' in option '%c'\n", ch, *option));
 	/* FIXME: any special rules for commas? */
 	/* FIXME: handle escaped quotes */
-	if (ch == '\'' || ch == '"') {
+	if (isQuote(ch)) {
 	    if (open_quote_ch == ch) {
 		open_quote_ch = '\0';
 	    } else {
@@ -5008,6 +5047,7 @@ parse_regis_command(RegisParseState *state)
 static int
 parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 {
+    XtermWidget xw = context->display_graphic->xw;
     RegisDataFragment optionarg;
 
     if (!extract_regis_option(&state->input, &state->option, &optionarg))
@@ -5586,13 +5626,18 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 		       state->option, fragment_to_tempstr(&optionarg)));
 		break;
 	    } {
-		char reply[64];
+		unsigned err_code = 0U;
+		unsigned err_char = 0U;
 
 		TRACE(("got report last error condition\n"));
 		/* FIXME: implement after adding error tracking */
-		sprintf(reply, "\"%u,%u\"\r", 0U, 0U);
-		unparseputs(context->display_graphic->xw, reply);
-		unparse_end(context->display_graphic->xw);
+		unparseputc(xw, D_QUOTE);
+		unparseputn(xw, err_code);
+		unparseputc(xw, ',');
+		unparseputn(xw, err_char);
+		unparseputc(xw, D_QUOTE);
+		unparseputc(xw, '\r');
+		unparse_end(xw);
 	    }
 	    break;
 	case 'I':
@@ -5639,8 +5684,8 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 		/* FIXME: implement arrow key movement */
 		/* FIXME: implement button/key collection */
 
-		unparseputs(context->display_graphic->xw, "\r");
-		unparse_end(context->display_graphic->xw);
+                unparseputc(xw, '\r');
+		unparse_end(xw);
 
 		skip_regis_whitespace(&optionarg);
 		if (!fragment_consumed(&optionarg)) {
@@ -5657,25 +5702,22 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 	    if (!fragment_consumed(&optionarg)) {
 		TRACE(("DATA_ERROR: unexpected arguments to ReGIS report command option '%c' arg \"%s\"\n",
 		       state->option, fragment_to_tempstr(&optionarg)));
-		break;
-	    } {
-		char buffer[32];
-
-		if (state->load_index == MAX_REGIS_ALPHABETS) {
-		    /* If this happens something went wrong elsewhere. */
-		    TRACE(("DATA_ERROR: unable to report current load alphabet\n"));
-		    unparseputs(context->display_graphic->xw, "A0\"\"\r");
-		    unparse_end(context->display_graphic->xw);
-		    break;
+	    } else if (state->load_index == MAX_REGIS_ALPHABETS) {
+		/* If this happens something went wrong elsewhere. */
+		TRACE(("DATA_ERROR: unable to report current load alphabet\n"));
+		unparseputs(xw, "A0\"\"\r");
+		unparse_end(xw);
+	    } else {
+		int delim = pick_quote(state->load_name);
+		if (delim != '\0') {
+		    unparseputs(xw, "A");
+		    unparseputn(xw, state->load_alphabet);
+		    unparseputc(xw, delim);
+		    unparseputs(xw, state->load_name);
+		    unparseputc(xw, delim);
 		}
-
-		unparseputs(context->display_graphic->xw, "A");
-		sprintf(buffer, "%u", state->load_alphabet);
-		unparseputs(context->display_graphic->xw, buffer);
-		unparseputs(context->display_graphic->xw, "\"");
-		unparseputs(context->display_graphic->xw, state->load_name);
-		unparseputs(context->display_graphic->xw, "\"\r");
-		unparse_end(context->display_graphic->xw);
+		unparseputc(xw, '\r');
+		unparse_end(xw);
 	    }
 	    break;
 	case 'M':
@@ -5717,13 +5759,18 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 		}
 
 		if (name == '=') {
-		    char reply[64];
+		    unsigned max_available = 1000U;
+		    unsigned cur_available = max_available;
 
 		    TRACE(("got report macrograph storage request\n"));
 		    /* FIXME: Implement when macrographs are supported. */
-		    sprintf(reply, "\"%u,%u\"\r", 1000U, 1000U);
-		    unparseputs(context->display_graphic->xw, reply);
-		    unparse_end(context->display_graphic->xw);
+		    unparseputc(xw, D_QUOTE);
+		    unparseputn(xw, cur_available);
+		    unparseputc(xw, ',');
+		    unparseputn(xw, max_available);
+		    unparseputc(xw, D_QUOTE);
+		    unparseputc(xw, '\r');
+		    unparse_end(xw);
 		} else if (name < 'A' || name > 'Z') {
 		    TRACE(("DATA_ERROR: invalid macrograph name: \"%c\"\n", name));
 		    /* FIXME: what should happen? */
@@ -5732,12 +5779,13 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 		    char temp[8];
 
 		    TRACE(("got report macrograph request for name '%c'\n", name));
-		    sprintf(temp, "@=%c", name);
-		    unparseputs(context->display_graphic->xw, temp);
+		    unparseputs(xw, "@=");
+		    unparseputc(xw, name);
 		    /* FIXME: Allow this to be disabled for security reasons. */
 		    /* FIXME: implement when macrographs are supported. */
-		    unparseputs(context->display_graphic->xw, "@;\r");
-		    unparse_end(context->display_graphic->xw);
+		    unparseputs(xw, "@;");
+		    unparseputc(xw, '\r');
+		    unparse_end(xw);
 		}
 	    }
 	    break;
@@ -5785,78 +5833,61 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 		TRACE(("got report cursor position (output=%d)\n", output));
 
 		/* FIXME: look into supporting ANSI locator reports (DECLRP) */
+                unparseputc(xw, L_BLOK);
 		if (output == 1) {
-		    char reply[64];
+		    /* FIXME: verify in absolute, not user, coordinates */
+		    unparseputn(xw, (unsigned) context->graphics_output_cursor_x);
+		    unparseputc(xw, ',');
+		    unparseputn(xw, (unsigned) context->graphics_output_cursor_y);
+		} else if (context->multi_input_mode) {
+		    /* FIXME: track input coordinates */
+		    unsigned x = 0, y = 0;	/* placeholders */
+
+                    /* send CSI240~[x,y]\r with current input cursor location */
+
+		    /* FIXME: verify no leading char or button sequence */
+		    /* FIXME: should we ever send an eight-bit CSI? */
 
 		    /* FIXME: verify in absolute, not user, coordinates */
-		    sprintf(reply, "[%d,%d]\r",
-			    context->graphics_output_cursor_x,
-			    context->graphics_output_cursor_y);
-		    unparseputs(context->display_graphic->xw, reply);
-		    unparse_end(context->display_graphic->xw);
+		    TRACE(("sending multi-mode input report at %u,%u\n", x, y));
+		    unparseputn(xw, x);
+		    unparseputc(xw, ',');
+		    unparseputn(xw, y);
 		} else {
-		    char reply[64];
-		    int x, y;
-
-		    if (context->multi_input_mode) {
-			/* FIXME: track input coordinates */
-			x = y = 0;	/* placeholders */
-
-			/* send CSI240~[x,y]\r with current input cursor location */
-
-			/* FIXME: verify no leading char or button sequence */
-			/* FIXME: should we ever send an eight-bit CSI? */
-			/* FIXME: verify in absolute, not user, coordinates */
-			TRACE(("sending multi-mode input report at %d,%d\n",
-			       x, y));
-			sprintf(reply, "[%d,%d]\r", x, y);
-			unparseputs(context->display_graphic->xw, reply);
-			unparse_end(context->display_graphic->xw);
-			break;
-		    } else {
-			char ch;
-
-			/* FIXME: wait for first non-arrow keypress or mouse click, and don't update graphics while waiting */
-			ch = ' ';	/* placeholder */
-			x = y = 0;	/* placeholders */
-
-			/* send <key or button>[x,y]\r to report input cursor location */
-
-			/* null button: CSI240~ */
-			/* left button: CSI241~ */
-			/* middle button: CSI243~ */
-			/* right button: CSI245~ */
-			/* extra button: CSI247~ */
-			/* FIXME: support DECLBD to change button assignments */
-			/* FIXME: verify no leading char or button sequence */
-			TRACE(("sending one-shot input report with %c at %d,%d\n",
-			       ch, x, y));
-#if 0				/* FIXME - dead code */
-			if (ch == '\r') {
-			    /* Return only reports the location. */
-			    sprintf(reply, "[%d,%d]\r", x, y);
-			} else if (ch == '\177') {
-			    /* DEL exits locator mode reporting nothing. */
-			    sprintf(reply, "\r");
-			} else
-#endif
-			{
-			    sprintf(reply, "%c[%d,%d]\r", ch, x, y);
-			}
-			unparseputs(context->display_graphic->xw, reply);
-			unparse_end(context->display_graphic->xw);
-			/* FIXME: exit one-shot mode and disable input cursor */
-			break;
+
+		    char ch = ' ';	/* placeholder */
+		    unsigned x = 0, y = 0;	/* placeholders */
+
+		    /* FIXME: wait for first non-arrow keypress or mouse click, and don't update graphics while waiting */
+		    /* send <key or button>[x,y]\r to report input cursor location */
+
+		    /* null button: CSI240~ */
+		    /* left button: CSI241~ */
+		    /* middle button: CSI243~ */
+		    /* right button: CSI245~ */
+		    /* extra button: CSI247~ */
+		    /* FIXME: support DECLBD to change button assignments */
+		    /* FIXME: verify no leading char or button sequence */
+		    TRACE(("sending one-shot input report with %c at %u,%u\n",
+			   ch, x, y));
+		    if (ch != '\177') {
+			unparseputn(xw, x);
+			unparseputc(xw, ',');
+			unparseputn(xw, y);
 		    }
+                    /* FIXME: exit one-shot mode and disable input cursor */
 		}
+                unparseputc(xw, R_BLOK);
+		unparseputc(xw, '\r');
+		unparse_end(xw);
 	    }
 	    break;
 	default:
 	    TRACE(("DATA_ERROR: sending empty report for unknown ReGIS report command option '%c' arg \"%s\"\n",
 		   state->option, fragment_to_tempstr(&optionarg)));
 	    /* Unknown report request types must receive empty reports. */
-	    unparseputs(context->display_graphic->xw, "\r");
-	    unparse_end(context->display_graphic->xw);
+	    unparseputs(xw, "\r");
+	    unparse_end(xw);
 	    break;
 	}
 	break;
@@ -6154,7 +6185,7 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context)
 
 		TRACE(("using display page number: %d\n", page));
 		context->display_page = (unsigned) page;
-		map_regis_graphics_pages(context->display_graphic->xw, context);
+		map_regis_graphics_pages(xw, context);
 	    }
 	    break;
 	case 'T':
-- 
2.35.7