diff options
| author | Paul Eggert | 2011-07-27 17:48:01 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-27 17:48:01 -0700 |
| commit | 044c22e545acef592ed95e4e3bb9f8aeff67291a (patch) | |
| tree | 167a4c706b62b12ea979bdf6ad47e70b66bb0394 /src/bidi.c | |
| parent | dbf38e02c9ade4979418f24a99962cfef170b957 (diff) | |
| parent | 8265d3bb30544e58683fc16e23f9908f3d5d0abc (diff) | |
| download | emacs-044c22e545acef592ed95e4e3bb9f8aeff67291a.tar.gz emacs-044c22e545acef592ed95e4e3bb9f8aeff67291a.zip | |
Merge: Integer signedness and overflow and related fixes.
Fixes: debbugs:9079
Diffstat (limited to 'src/bidi.c')
| -rw-r--r-- | src/bidi.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/src/bidi.c b/src/bidi.c index 412dc94cb86..697ebb92856 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,33 @@ 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 | |
| 468 | bidi_cache = | 468 | /* The bidi cache cannot be larger than the largest Lisp string |
| 469 | (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz); | 469 | or buffer. */ |
| 470 | ptrdiff_t string_or_buffer_bound = | ||
| 471 | max (BUF_BYTES_MAX, STRING_BYTES_BOUND); | ||
| 472 | |||
| 473 | /* Also, it cannot be larger than what C can represent. */ | ||
| 474 | ptrdiff_t c_bound = min (PTRDIFF_MAX, SIZE_MAX) / elsz; | ||
| 475 | |||
| 476 | if (min (string_or_buffer_bound, c_bound) <= idx) | ||
| 477 | memory_full (SIZE_MAX); | ||
| 478 | new_size = idx - idx % BIDI_CACHE_CHUNK + BIDI_CACHE_CHUNK; | ||
| 479 | bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, new_size * elsz); | ||
| 480 | bidi_cache_size = new_size; | ||
| 470 | } | 481 | } |
| 471 | } | 482 | } |
| 472 | 483 | ||
| 473 | static inline void | 484 | static inline void |
| 474 | bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | 485 | bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) |
| 475 | { | 486 | { |
| 476 | EMACS_INT idx; | 487 | ptrdiff_t idx; |
| 477 | 488 | ||
| 478 | /* We should never cache on backward scans. */ | 489 | /* We should never cache on backward scans. */ |
| 479 | if (bidi_it->scan_dir == -1) | 490 | if (bidi_it->scan_dir == -1) |
| @@ -528,7 +539,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) | |||
| 528 | static inline bidi_type_t | 539 | static inline bidi_type_t |
| 529 | bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) | 540 | bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) |
| 530 | { | 541 | { |
| 531 | EMACS_INT i = bidi_cache_search (charpos, level, bidi_it->scan_dir); | 542 | ptrdiff_t i = bidi_cache_search (charpos, level, bidi_it->scan_dir); |
| 532 | 543 | ||
| 533 | if (i >= bidi_cache_start) | 544 | if (i >= bidi_cache_start) |
| 534 | { | 545 | { |
| @@ -560,7 +571,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 | 571 | /* 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, | 572 | cache. xdisp.c maintains a 5-slot stack for its iterator state, |
| 562 | and we need the same size of our stack. */ | 573 | and we need the same size of our stack. */ |
| 563 | static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE]; | 574 | static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; |
| 564 | static int bidi_cache_sp; | 575 | static int bidi_cache_sp; |
| 565 | 576 | ||
| 566 | /* Push the bidi iterator state in preparation for reordering a | 577 | /* Push the bidi iterator state in preparation for reordering a |
| @@ -2123,7 +2134,7 @@ static void | |||
| 2123 | bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) | 2134 | bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) |
| 2124 | { | 2135 | { |
| 2125 | int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; | 2136 | int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; |
| 2126 | EMACS_INT idx; | 2137 | ptrdiff_t idx; |
| 2127 | 2138 | ||
| 2128 | /* Try the cache first. */ | 2139 | /* Try the cache first. */ |
| 2129 | if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) | 2140 | if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) |
| @@ -2300,7 +2311,7 @@ void bidi_dump_cached_states (void) EXTERNALLY_VISIBLE; | |||
| 2300 | void | 2311 | void |
| 2301 | bidi_dump_cached_states (void) | 2312 | bidi_dump_cached_states (void) |
| 2302 | { | 2313 | { |
| 2303 | int i; | 2314 | ptrdiff_t i; |
| 2304 | int ndigits = 1; | 2315 | int ndigits = 1; |
| 2305 | 2316 | ||
| 2306 | if (bidi_cache_idx == 0) | 2317 | if (bidi_cache_idx == 0) |
| @@ -2308,7 +2319,7 @@ bidi_dump_cached_states (void) | |||
| 2308 | fprintf (stderr, "The cache is empty.\n"); | 2319 | fprintf (stderr, "The cache is empty.\n"); |
| 2309 | return; | 2320 | return; |
| 2310 | } | 2321 | } |
| 2311 | fprintf (stderr, "Total of %"pI"d state%s in cache:\n", | 2322 | fprintf (stderr, "Total of %"pD"d state%s in cache:\n", |
| 2312 | bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s"); | 2323 | bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s"); |
| 2313 | 2324 | ||
| 2314 | for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10) | 2325 | for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10) |