aboutsummaryrefslogtreecommitdiffstats
path: root/src/bidi.c
diff options
context:
space:
mode:
authorPaul Eggert2011-07-27 17:48:01 -0700
committerPaul Eggert2011-07-27 17:48:01 -0700
commit044c22e545acef592ed95e4e3bb9f8aeff67291a (patch)
tree167a4c706b62b12ea979bdf6ad47e70b66bb0394 /src/bidi.c
parentdbf38e02c9ade4979418f24a99962cfef170b957 (diff)
parent8265d3bb30544e58683fc16e23f9908f3d5d0abc (diff)
downloademacs-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.c51
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
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,33 @@ 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
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
473static inline void 484static inline void
474bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) 485bidi_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)
528static inline bidi_type_t 539static inline bidi_type_t
529bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) 540bidi_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. */
563static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE]; 574static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE];
564static int bidi_cache_sp; 575static 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
2123bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) 2134bidi_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;
2300void 2311void
2301bidi_dump_cached_states (void) 2312bidi_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)