diff options
| author | Eli Zaretskii | 2021-10-31 16:16:38 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2021-10-31 16:16:38 +0200 |
| commit | d1523bc78ce138336173efbc56ff3a35ea90b2d7 (patch) | |
| tree | 4702a5baa4ae09592e728b017a62889f529edafb /src/keymap.c | |
| parent | 90bd80d47b7601d8a9a3936a02d085731500c4c9 (diff) | |
| download | emacs-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.c | 66 |
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 | } |