aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-07-14 14:57:00 -0700
committerPaul Eggert2011-07-14 14:57:00 -0700
commit39e378da07fe365c6442dc95b937539eb31fe8ef (patch)
tree10c7326987b394c895bf792a67abefc133be36ab /src
parent3f86c085fa6eb34547ac04cf2be31f6cc3681e48 (diff)
downloademacs-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/ChangeLog14
-rw-r--r--src/bidi.c42
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
301static struct bidi_it *bidi_cache; 301static struct bidi_it *bidi_cache;
302static EMACS_INT bidi_cache_size = 0; 302static ptrdiff_t bidi_cache_size = 0;
303enum { elsz = sizeof (struct bidi_it) }; 303enum { elsz = sizeof (struct bidi_it) };
304static EMACS_INT bidi_cache_idx; /* next unused cache slot */ 304static ptrdiff_t bidi_cache_idx; /* next unused cache slot */
305static EMACS_INT bidi_cache_last_idx; /* slot of last cache hit */ 305static ptrdiff_t bidi_cache_last_idx; /* slot of last cache hit */
306static EMACS_INT bidi_cache_start = 0; /* start of cache for this 306static 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
338static inline void 338static inline void
339bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it) 339bidi_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. */
355static inline EMACS_INT 355static inline ptrdiff_t
356bidi_cache_search (EMACS_INT charpos, int level, int dir) 356bidi_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. */
420static EMACS_INT 420static ptrdiff_t
421bidi_cache_find_level_change (int level, int dir, int before) 421bidi_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
460static inline void 460static inline void
461bidi_cache_ensure_space (EMACS_INT idx) 461bidi_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
473static inline void 477static inline void
474bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) 478bidi_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)
528static inline bidi_type_t 532static inline bidi_type_t
529bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) 533bidi_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. */
563static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE]; 567static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE];
564static int bidi_cache_sp; 568static 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
2123bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) 2127bidi_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;
2300void 2304void
2301bidi_dump_cached_states (void) 2305bidi_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)