diff options
| author | Paul Eggert | 2011-07-28 13:27:41 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-28 13:27:41 -0700 |
| commit | bc18e09ddf639fbd59e6d2ef238fdaf4e31fb6a3 (patch) | |
| tree | 92b2658f32b047a669af18f44589ead0635c515a /src | |
| parent | 722e028b38b63a4f32be9670359a1344befd1578 (diff) | |
| download | emacs-bc18e09ddf639fbd59e6d2ef238fdaf4e31fb6a3.tar.gz emacs-bc18e09ddf639fbd59e6d2ef238fdaf4e31fb6a3.zip | |
* bidi.c: Integer overflow fix.
(bidi_shelve_header_size): New constant.
(bidi_cache_ensure_space, bidi_shelve_cache): Use it.
(bidi_cache_ensure_space): Avoid integer overflow when allocating.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/bidi.c | 30 |
2 files changed, 26 insertions, 11 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b3125b2c183..0d5b41ea205 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2011-07-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * bidi.c: Integer overflow fix. | ||
| 4 | (bidi_shelve_header_size): New constant. | ||
| 5 | (bidi_cache_ensure_space, bidi_shelve_cache): Use it. | ||
| 6 | (bidi_cache_ensure_space): Avoid integer overflow when allocating. | ||
| 7 | |||
| 1 | 2011-07-19 Paul Eggert <eggert@cs.ucla.edu> | 8 | 2011-07-19 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 9 | ||
| 3 | Use ptrdiff_t for composition IDs. | 10 | Use ptrdiff_t for composition IDs. |
diff --git a/src/bidi.c b/src/bidi.c index 697ebb92856..a1e5721f350 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -306,6 +306,21 @@ static ptrdiff_t bidi_cache_last_idx; /* slot of last cache hit */ | |||
| 306 | static ptrdiff_t bidi_cache_start = 0; /* start of cache for this | 306 | static ptrdiff_t bidi_cache_start = 0; /* start of cache for this |
| 307 | "stack" level */ | 307 | "stack" level */ |
| 308 | 308 | ||
| 309 | /* 5-slot stack for saving the start of the previous level of the | ||
| 310 | cache. xdisp.c maintains a 5-slot stack for its iterator state, | ||
| 311 | and we need the same size of our stack. */ | ||
| 312 | static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; | ||
| 313 | static int bidi_cache_sp; | ||
| 314 | |||
| 315 | /* Size of header used by bidi_shelve_cache. */ | ||
| 316 | enum | ||
| 317 | { | ||
| 318 | bidi_shelve_header_size = | ||
| 319 | (sizeof (bidi_cache_idx) + sizeof (bidi_cache_start_stack) | ||
| 320 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) | ||
| 321 | + sizeof (bidi_cache_last_idx)) | ||
| 322 | }; | ||
| 323 | |||
| 309 | /* Reset the cache state to the empty state. We only reset the part | 324 | /* Reset the cache state to the empty state. We only reset the part |
| 310 | of the cache relevant to iteration of the current object. Previous | 325 | of the cache relevant to iteration of the current object. Previous |
| 311 | objects, which are pushed on the display iterator's stack, are left | 326 | objects, which are pushed on the display iterator's stack, are left |
| @@ -471,7 +486,8 @@ bidi_cache_ensure_space (ptrdiff_t idx) | |||
| 471 | max (BUF_BYTES_MAX, STRING_BYTES_BOUND); | 486 | max (BUF_BYTES_MAX, STRING_BYTES_BOUND); |
| 472 | 487 | ||
| 473 | /* Also, it cannot be larger than what C can represent. */ | 488 | /* Also, it cannot be larger than what C can represent. */ |
| 474 | ptrdiff_t c_bound = min (PTRDIFF_MAX, SIZE_MAX) / elsz; | 489 | ptrdiff_t c_bound = |
| 490 | (min (PTRDIFF_MAX, SIZE_MAX) - bidi_shelve_header_size) / elsz; | ||
| 475 | 491 | ||
| 476 | if (min (string_or_buffer_bound, c_bound) <= idx) | 492 | if (min (string_or_buffer_bound, c_bound) <= idx) |
| 477 | memory_full (SIZE_MAX); | 493 | memory_full (SIZE_MAX); |
| @@ -568,11 +584,6 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it) | |||
| 568 | /*********************************************************************** | 584 | /*********************************************************************** |
| 569 | Pushing and popping the bidi iterator state | 585 | Pushing and popping the bidi iterator state |
| 570 | ***********************************************************************/ | 586 | ***********************************************************************/ |
| 571 | /* 5-slot stack for saving the start of the previous level of the | ||
| 572 | cache. xdisp.c maintains a 5-slot stack for its iterator state, | ||
| 573 | and we need the same size of our stack. */ | ||
| 574 | static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; | ||
| 575 | static int bidi_cache_sp; | ||
| 576 | 587 | ||
| 577 | /* Push the bidi iterator state in preparation for reordering a | 588 | /* Push the bidi iterator state in preparation for reordering a |
| 578 | different object, e.g. display string found at certain buffer | 589 | different object, e.g. display string found at certain buffer |
| @@ -629,11 +640,8 @@ bidi_shelve_cache (void) | |||
| 629 | if (bidi_cache_idx == 0) | 640 | if (bidi_cache_idx == 0) |
| 630 | return NULL; | 641 | return NULL; |
| 631 | 642 | ||
| 632 | databuf = xmalloc (sizeof (bidi_cache_idx) | 643 | databuf = xmalloc (bidi_shelve_header_size |
| 633 | + bidi_cache_idx * sizeof (struct bidi_it) | 644 | + bidi_cache_idx * sizeof (struct bidi_it)); |
| 634 | + sizeof (bidi_cache_start_stack) | ||
| 635 | + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) | ||
| 636 | + sizeof (bidi_cache_last_idx)); | ||
| 637 | memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); | 645 | memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); |
| 638 | memcpy (databuf + sizeof (bidi_cache_idx), | 646 | memcpy (databuf + sizeof (bidi_cache_idx), |
| 639 | bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); | 647 | bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); |