aboutsummaryrefslogtreecommitdiffstats
path: root/src/keymap.c
diff options
context:
space:
mode:
authorEli Zaretskii2021-10-31 16:16:38 +0200
committerEli Zaretskii2021-10-31 16:16:38 +0200
commitd1523bc78ce138336173efbc56ff3a35ea90b2d7 (patch)
tree4702a5baa4ae09592e728b017a62889f529edafb /src/keymap.c
parent90bd80d47b7601d8a9a3936a02d085731500c4c9 (diff)
downloademacs-d1523bc78ce138336173efbc56ff3a35ea90b2d7.tar.gz
emacs-d1523bc78ce138336173efbc56ff3a35ea90b2d7.zip
Avoid signaling errors in lookup-key
* src/keymap.c (Flookup_key): Handle KEY vectors where not all components are symbols. (Bug#51527
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c66
1 files changed, 39 insertions, 27 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 5ff13ba1d57..08f37dbd8b5 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -1314,36 +1314,44 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1314 "foo-bar-baz". */ 1314 "foo-bar-baz". */
1315 for (int i = 0; i < key_len; i++) 1315 for (int i = 0; i < key_len; i++)
1316 { 1316 {
1317 Lisp_Object key_item = Fsymbol_name (AREF (key, i)); 1317 Lisp_Object item = AREF (key, i);
1318 Lisp_Object new_item; 1318 if (!SYMBOLP (item))
1319 if (!STRING_MULTIBYTE (key_item)) 1319 ASET (new_key, i, item);
1320 new_item = Fdowncase (key_item);
1321 else 1320 else
1322 { 1321 {
1323 USE_SAFE_ALLOCA; 1322 Lisp_Object key_item = Fsymbol_name (item);
1324 ptrdiff_t size = SCHARS (key_item), n; 1323 Lisp_Object new_item;
1325 if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &n)) 1324 if (!STRING_MULTIBYTE (key_item))
1326 n = PTRDIFF_MAX; 1325 new_item = Fdowncase (key_item);
1327 unsigned char *dst = SAFE_ALLOCA (n); 1326 else
1328 unsigned char *p = dst;
1329 ptrdiff_t j_char = 0, j_byte = 0;
1330
1331 while (j_char < size)
1332 { 1327 {
1333 int ch = fetch_string_char_advance (key_item, &j_char, &j_byte); 1328 USE_SAFE_ALLOCA;
1334 Lisp_Object ch_conv = CHAR_TABLE_REF (tables[tbl_num], ch); 1329 ptrdiff_t size = SCHARS (key_item), n;
1335 if (!NILP (ch_conv)) 1330 if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &n))
1336 CHAR_STRING (XFIXNUM (ch_conv), p); 1331 n = PTRDIFF_MAX;
1337 else 1332 unsigned char *dst = SAFE_ALLOCA (n);
1338 CHAR_STRING (ch, p); 1333 unsigned char *p = dst;
1339 p = dst + j_byte; 1334 ptrdiff_t j_char = 0, j_byte = 0;
1335
1336 while (j_char < size)
1337 {
1338 int ch = fetch_string_char_advance (key_item,
1339 &j_char, &j_byte);
1340 Lisp_Object ch_conv = CHAR_TABLE_REF (tables[tbl_num],
1341 ch);
1342 if (!NILP (ch_conv))
1343 CHAR_STRING (XFIXNUM (ch_conv), p);
1344 else
1345 CHAR_STRING (ch, p);
1346 p = dst + j_byte;
1347 }
1348 new_item = make_multibyte_string ((char *) dst,
1349 SCHARS (key_item),
1350 SBYTES (key_item));
1351 SAFE_FREE ();
1340 } 1352 }
1341 new_item = make_multibyte_string ((char *) dst, 1353 ASET (new_key, i, Fintern (new_item, Qnil));
1342 SCHARS (key_item),
1343 SBYTES (key_item));
1344 SAFE_FREE ();
1345 } 1354 }
1346 ASET (new_key, i, Fintern (new_item, Qnil));
1347 } 1355 }
1348 1356
1349 /* Check for match. */ 1357 /* Check for match. */
@@ -1356,6 +1364,9 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1356 "foo-bar-baz". */ 1364 "foo-bar-baz". */
1357 for (int i = 0; i < key_len; i++) 1365 for (int i = 0; i < key_len; i++)
1358 { 1366 {
1367 if (!SYMBOLP (AREF (new_key, i)))
1368 continue;
1369
1359 Lisp_Object lc_key = Fsymbol_name (AREF (new_key, i)); 1370 Lisp_Object lc_key = Fsymbol_name (AREF (new_key, i));
1360 1371
1361 /* If there are no spaces in this symbol, just skip it. */ 1372 /* If there are no spaces in this symbol, just skip it. */
@@ -1378,8 +1389,9 @@ recognize the default bindings, just as `read-key-sequence' does. */)
1378 if (dst[i] == ' ') 1389 if (dst[i] == ' ')
1379 dst[i] = '-'; 1390 dst[i] = '-';
1380 } 1391 }
1381 Lisp_Object 1392 Lisp_Object new_it =
1382 new_it = make_multibyte_string ((char *) dst, SCHARS (lc_key), SBYTES (lc_key)); 1393 make_multibyte_string ((char *) dst,
1394 SCHARS (lc_key), SBYTES (lc_key));
1383 ASET (new_key, i, Fintern (new_it, Qnil)); 1395 ASET (new_key, i, Fintern (new_it, Qnil));
1384 SAFE_FREE (); 1396 SAFE_FREE ();
1385 } 1397 }