aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode.c
diff options
context:
space:
mode:
authorPaul Eggert2017-02-16 07:52:57 -0800
committerPaul Eggert2017-02-16 07:54:12 -0800
commit8929746489bb257d1e29c3bab629b3b67e3117d2 (patch)
treef8da7874aa0e643bf9450fb358c9a9e6a4810559 /src/bytecode.c
parent064541af6a71bf45d530fe34b7e00c8123ee93d8 (diff)
downloademacs-8929746489bb257d1e29c3bab629b3b67e3117d2.tar.gz
emacs-8929746489bb257d1e29c3bab629b3b67e3117d2.zip
Add sanity checks for Bswitch hash tables
* src/bytecode.c (exec_byte_code) [BYTE_CODE_SAFE]: Check that operand is a hash table and hashes to ints.
Diffstat (limited to 'src/bytecode.c')
-rw-r--r--src/bytecode.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index af94d03b17d..4414b077bb9 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1415,13 +1415,15 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1415 1415
1416 CASE (Bswitch): 1416 CASE (Bswitch):
1417 { 1417 {
1418 /*TODO: Perhaps introduce another byte-code for switch when the 1418 /* TODO: Perhaps introduce another byte-code for switch when the
1419 number of cases is less, which uses a simple vector for linear 1419 number of cases is less, which uses a simple vector for linear
1420 search as the jump table. */ 1420 search as the jump table. */
1421 Lisp_Object jmp_table = POP; 1421 Lisp_Object jmp_table = POP;
1422 if (BYTE_CODE_SAFE && !HASH_TABLE_P (jmp_table))
1423 emacs_abort ();
1422 Lisp_Object v1 = POP; 1424 Lisp_Object v1 = POP;
1423 ptrdiff_t i; 1425 ptrdiff_t i;
1424 struct Lisp_Hash_Table *h = XHASH_TABLE(jmp_table); 1426 struct Lisp_Hash_Table *h = XHASH_TABLE (jmp_table);
1425 1427
1426 /* h->count is a faster approximation for HASH_TABLE_SIZE (h) 1428 /* h->count is a faster approximation for HASH_TABLE_SIZE (h)
1427 here. */ 1429 here. */
@@ -1429,9 +1431,9 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1429 { /* Do a linear search if there are not many cases 1431 { /* Do a linear search if there are not many cases
1430 FIXME: 5 is arbitrarily chosen. */ 1432 FIXME: 5 is arbitrarily chosen. */
1431 Lisp_Object hash_code = h->test.cmpfn 1433 Lisp_Object hash_code = h->test.cmpfn
1432 ? make_number(h->test.hashfn (&h->test, v1)) : Qnil; 1434 ? make_number (h->test.hashfn (&h->test, v1)) : Qnil;
1433 1435
1434 for (i = h->count; 0 <= --i;) 1436 for (i = h->count; 0 <= --i; )
1435 if (EQ (v1, HASH_KEY (h, i)) 1437 if (EQ (v1, HASH_KEY (h, i))
1436 || (h->test.cmpfn 1438 || (h->test.cmpfn
1437 && EQ (hash_code, HASH_HASH (h, i)) 1439 && EQ (hash_code, HASH_HASH (h, i))
@@ -1440,13 +1442,16 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1440 1442
1441 } 1443 }
1442 else 1444 else
1443 i = hash_lookup(h, v1, NULL); 1445 i = hash_lookup (h, v1, NULL);
1444 1446
1445 if (i >= 0) 1447 if (i >= 0)
1446 { 1448 {
1447 op = XINT (HASH_VALUE (h, i)); 1449 Lisp_Object val = HASH_VALUE (h, i);
1448 goto op_branch; 1450 if (BYTE_CODE_SAFE && !INTEGERP (val))
1449 } 1451 emacs_abort ();
1452 op = XINT (val);
1453 goto op_branch;
1454 }
1450 } 1455 }
1451 NEXT; 1456 NEXT;
1452 1457