diff options
| author | Paul Eggert | 2011-07-14 14:57:00 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-14 14:57:00 -0700 |
| commit | 39e378da07fe365c6442dc95b937539eb31fe8ef (patch) | |
| tree | 10c7326987b394c895bf792a67abefc133be36ab /src | |
| parent | 3f86c085fa6eb34547ac04cf2be31f6cc3681e48 (diff) | |
| download | emacs-39e378da07fe365c6442dc95b937539eb31fe8ef.tar.gz emacs-39e378da07fe365c6442dc95b937539eb31fe8ef.zip | |
* bidi.c: Integer size and overflow fixes.
(bidi_cache_size, bidi_cache_idx, bidi_cache_last_idx)
(bidi_cache_start, bidi_cache_fetch_state, bidi_cache_search)
(bidi_cache_find_level_change, bidi_cache_ensure_space)
(bidi_cache_iterator_state, bidi_cache_find, bidi_cache_start_stack)
(bidi_find_other_level_edge):
Use ptrdiff_t instead of EMACS_INT where either will do.
This works better on 32-bit hosts configured --with-wide-int.
(bidi_cache_ensure_space): Check for size-calculation overflow.
Use % rather than repeated addition, for better worst-case speed.
Don't set bidi_cache_size until after xrealloc returns, because it
might not return.
(bidi_dump_cached_states): Use ptrdiff_t, not int, to avoid overflow.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/bidi.c | 42 |
2 files changed, 37 insertions, 19 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b683a7f55cd..c19786fb72c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -2,6 +2,20 @@ | |||
| 2 | 2 | ||
| 3 | Integer signedness and overflow and related fixes. (Bug#9079) | 3 | Integer signedness and overflow and related fixes. (Bug#9079) |
| 4 | 4 | ||
| 5 | * bidi.c: Integer size and overflow fixes. | ||
| 6 | (bidi_cache_size, bidi_cache_idx, bidi_cache_last_idx) | ||
| 7 | (bidi_cache_start, bidi_cache_fetch_state, bidi_cache_search) | ||
| 8 | (bidi_cache_find_level_change, bidi_cache_ensure_space) | ||
| 9 | (bidi_cache_iterator_state, bidi_cache_find, bidi_cache_start_stack) | ||
| 10 | (bidi_find_other_level_edge): | ||
| 11 | Use ptrdiff_t instead of EMACS_INT where either will do. | ||
| 12 | This works better on 32-bit hosts configured --with-wide-int. | ||
| 13 | (bidi_cache_ensure_space): Check for size-calculation overflow. | ||
| 14 | Use % rather than repeated addition, for better worst-case speed. | ||
| 15 | Don't set bidi_cache_size until after xrealloc returns, because it | ||
| 16 | might not return. | ||
| 17 | (bidi_dump_cached_states): Use ptrdiff_t, not int, to avoid overflow. | ||
| 18 | |||
| 5 | * alloc.c (__malloc_size_t): Remove. | 19 | * alloc.c (__malloc_size_t): Remove. |
| 6 | All uses replaced by size_t. See Andreas Schwab's note | 20 | All uses replaced by size_t. See Andreas Schwab's note |
| 7 | <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9079#8>. | 21 | <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9079#8>. |
diff --git a/src/bidi.c b/src/bidi.c index c83ee549923..1999606639b 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -299,11 +299,11 @@ bidi_copy_it (struct bidi_it *to, struct bidi_it *from) | |||
| 299 | 299 | ||
| 300 | #define BIDI_CACHE_CHUNK 200 | 300 | #define BIDI_CACHE_CHUNK 200 |
| 301 | static struct bidi_it *bidi_cache; | 301 | static struct bidi_it *bidi_cache; |
| 302 | static EMACS_INT bidi_cache_size = 0; | 302 | static ptrdiff_t bidi_cache_size = 0; |
| 303 | enum { elsz = sizeof (struct bidi_it) }; | 303 | enum { elsz = sizeof (struct bidi_it) }; |
| 304 | static EMACS_INT bidi_cache_idx; /* next unused cache slot */ | 304 | static ptrdiff_t bidi_cache_idx; /* next unused cache slot */ |
| 305 | static EMACS_INT bidi_cache_last_idx; /* slot of last cache hit */ | 305 | static ptrdiff_t bidi_cache_last_idx; /* slot of last cache hit */ |
| 306 | static EMACS_INT 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 | /* Reset the cache state to the empty state. We only reset the part | 309 | /* Reset the cache state to the empty state. We only reset the part |
| @@ -336,7 +336,7 @@ bidi_cache_shrink (void) | |||
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | static inline void | 338 | static inline void |
| 339 | bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it) | 339 | bidi_cache_fetch_state (ptrdiff_t idx, struct bidi_it *bidi_it) |
| 340 | { | 340 | { |
| 341 | int current_scan_dir = bidi_it->scan_dir; | 341 | int current_scan_dir = bidi_it->scan_dir; |
| 342 | 342 | ||
| @@ -352,10 +352,10 @@ bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it) | |||
| 352 | level less or equal to LEVEL. if LEVEL is -1, disregard the | 352 | level less or equal to LEVEL. if LEVEL is -1, disregard the |
| 353 | resolved levels in cached states. DIR, if non-zero, means search | 353 | resolved levels in cached states. DIR, if non-zero, means search |
| 354 | in that direction from the last cache hit. */ | 354 | in that direction from the last cache hit. */ |
| 355 | static inline EMACS_INT | 355 | static inline ptrdiff_t |
| 356 | bidi_cache_search (EMACS_INT charpos, int level, int dir) | 356 | bidi_cache_search (EMACS_INT charpos, int level, int dir) |
| 357 | { | 357 | { |
| 358 | EMACS_INT i, i_start; | 358 | ptrdiff_t i, i_start; |
| 359 | 359 | ||
| 360 | if (bidi_cache_idx > bidi_cache_start) | 360 | if (bidi_cache_idx > bidi_cache_start) |
| 361 | { | 361 | { |
| @@ -417,12 +417,12 @@ bidi_cache_search (EMACS_INT charpos, int level, int dir) | |||
| 417 | C, searching backwards (DIR = -1) for LEVEL = 2 will return the | 417 | C, searching backwards (DIR = -1) for LEVEL = 2 will return the |
| 418 | index of slot B or A, depending whether BEFORE is, respectively, | 418 | index of slot B or A, depending whether BEFORE is, respectively, |
| 419 | non-zero or zero. */ | 419 | non-zero or zero. */ |
| 420 | static EMACS_INT | 420 | static ptrdiff_t |
| 421 | bidi_cache_find_level_change (int level, int dir, int before) | 421 | bidi_cache_find_level_change (int level, int dir, int before) |
| 422 | { | 422 | { |
| 423 | if (bidi_cache_idx) | 423 | if (bidi_cache_idx) |
| 424 | { | 424 | { |
| 425 | EMACS_INT i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1; | 425 | ptrdiff_t i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1; |
| 426 | int incr = before ? 1 : 0; | 426 | int incr = before ? 1 : 0; |
| 427 | 427 | ||
| 428 | xassert (!dir || bidi_cache_last_idx >= 0); | 428 | xassert (!dir || bidi_cache_last_idx >= 0); |
| @@ -458,22 +458,26 @@ bidi_cache_find_level_change (int level, int dir, int before) | |||
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | static inline void | 460 | static inline void |
| 461 | bidi_cache_ensure_space (EMACS_INT idx) | 461 | bidi_cache_ensure_space (ptrdiff_t idx) |
| 462 | { | 462 | { |
| 463 | /* Enlarge the cache as needed. */ | 463 | /* Enlarge the cache as needed. */ |
| 464 | if (idx >= bidi_cache_size) | 464 | if (idx >= bidi_cache_size) |
| 465 | { | 465 | { |
| 466 | while (idx >= bidi_cache_size) | 466 | ptrdiff_t new_size; |
| 467 | bidi_cache_size += BIDI_CACHE_CHUNK; | 467 | ptrdiff_t max_size = |
| 468 | bidi_cache = | 468 | min (PTRDIFF_MAX, SIZE_MAX) / elsz / BIDI_CACHE_CHUNK * BIDI_CACHE_CHUNK; |
| 469 | (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz); | 469 | if (max_size <= idx) |
| 470 | memory_full (SIZE_MAX); | ||
| 471 | new_size = idx - idx % BIDI_CACHE_CHUNK + BIDI_CACHE_CHUNK; | ||
| 472 | bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, new_size * elsz); | ||
| 473 | bidi_cache_size = new_size; | ||
| 470 | } | 474 | } |
| 471 | } | 475 | } |
| 472 | 476 | ||
| 473 | static inline void | 477 | static inline void |
| 474 | bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | 478 | bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) |
| 475 | { | 479 | { |
| 476 | EMACS_INT idx; | 480 | ptrdiff_t idx; |
| 477 | 481 | ||
| 478 | /* We should never cache on backward scans. */ | 482 | /* We should never cache on backward scans. */ |
| 479 | if (bidi_it->scan_dir == -1) | 483 | if (bidi_it->scan_dir == -1) |
| @@ -528,7 +532,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 528 | static inline bidi_type_t | 532 | static inline bidi_type_t |
| 529 | bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) | 533 | bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) |
| 530 | { | 534 | { |
| 531 | EMACS_INT i = bidi_cache_search (charpos, level, bidi_it->scan_dir); | 535 | ptrdiff_t i = bidi_cache_search (charpos, level, bidi_it->scan_dir); |
| 532 | 536 | ||
| 533 | if (i >= bidi_cache_start) | 537 | if (i >= bidi_cache_start) |
| 534 | { | 538 | { |
| @@ -560,7 +564,7 @@ bidi_peek_at_next_level (struct bidi_it *bidi_it) | |||
| 560 | /* 5-slot stack for saving the start of the previous level of the | 564 | /* 5-slot stack for saving the start of the previous level of the |
| 561 | cache. xdisp.c maintains a 5-slot stack for its iterator state, | 565 | cache. xdisp.c maintains a 5-slot stack for its iterator state, |
| 562 | and we need the same size of our stack. */ | 566 | and we need the same size of our stack. */ |
| 563 | static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE]; | 567 | static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; |
| 564 | static int bidi_cache_sp; | 568 | static int bidi_cache_sp; |
| 565 | 569 | ||
| 566 | /* Push the bidi iterator state in preparation for reordering a | 570 | /* Push the bidi iterator state in preparation for reordering a |
| @@ -2123,7 +2127,7 @@ static void | |||
| 2123 | bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) | 2127 | bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) |
| 2124 | { | 2128 | { |
| 2125 | int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; | 2129 | int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; |
| 2126 | EMACS_INT idx; | 2130 | ptrdiff_t idx; |
| 2127 | 2131 | ||
| 2128 | /* Try the cache first. */ | 2132 | /* Try the cache first. */ |
| 2129 | if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) | 2133 | if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) |
| @@ -2300,7 +2304,7 @@ void bidi_dump_cached_states (void) EXTERNALLY_VISIBLE; | |||
| 2300 | void | 2304 | void |
| 2301 | bidi_dump_cached_states (void) | 2305 | bidi_dump_cached_states (void) |
| 2302 | { | 2306 | { |
| 2303 | int i; | 2307 | ptrdiff_t i; |
| 2304 | int ndigits = 1; | 2308 | int ndigits = 1; |
| 2305 | 2309 | ||
| 2306 | if (bidi_cache_idx == 0) | 2310 | if (bidi_cache_idx == 0) |