diff options
| author | Paul Eggert | 2017-02-16 07:52:57 -0800 |
|---|---|---|
| committer | Paul Eggert | 2017-02-16 07:54:12 -0800 |
| commit | 8929746489bb257d1e29c3bab629b3b67e3117d2 (patch) | |
| tree | f8da7874aa0e643bf9450fb358c9a9e6a4810559 /src/bytecode.c | |
| parent | 064541af6a71bf45d530fe34b7e00c8123ee93d8 (diff) | |
| download | emacs-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.c | 29 |
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 | ||