diff options
| author | Paul Eggert | 2011-07-28 18:22:19 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-28 18:22:19 -0700 |
| commit | fee31f82d5279a6faeb2d4cef808e9d7fce2f210 (patch) | |
| tree | 1bcce2fe8f01c58d4cd8958629254b894d622371 | |
| parent | fe6442b1151a0f4021181e968479459f50df63f1 (diff) | |
| download | emacs-fee31f82d5279a6faeb2d4cef808e9d7fce2f210.tar.gz emacs-fee31f82d5279a6faeb2d4cef808e9d7fce2f210.zip | |
* term.c: Integer and memory overflow issues.
(max_frame_lines): Remove; unused.
(encode_terminal_src_size, encode_terminal_dst_size): Now ptrdiff_t,
not int.
(encode_terminal_code, calculate_costs): Check for size
calculation overflow.
(encode_terminal_code): Use ptrdiff_t, not int, to record glyph
table lengths and related sizes. Don't update size until alloc
done. Redo calculations to avoid overflow.
(calculate_costs): Don't bother calling xmalloc when xrealloc will do.
| -rw-r--r-- | src/ChangeLog | 11 | ||||
| -rw-r--r-- | src/term.c | 84 |
2 files changed, 53 insertions, 42 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d1db5e48daf..7485afb00f4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,16 @@ | |||
| 1 | 2011-07-29 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-07-29 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | * term.c: Integer and memory overflow issues. | ||
| 4 | (max_frame_lines): Remove; unused. | ||
| 5 | (encode_terminal_src_size, encode_terminal_dst_size): Now ptrdiff_t, | ||
| 6 | not int. | ||
| 7 | (encode_terminal_code, calculate_costs): Check for size | ||
| 8 | calculation overflow. | ||
| 9 | (encode_terminal_code): Use ptrdiff_t, not int, to record glyph | ||
| 10 | table lengths and related sizes. Don't update size until alloc | ||
| 11 | done. Redo calculations to avoid overflow. | ||
| 12 | (calculate_costs): Don't bother calling xmalloc when xrealloc will do. | ||
| 13 | |||
| 3 | * sysdep.c: Integer and memory overflow issues. | 14 | * sysdep.c: Integer and memory overflow issues. |
| 4 | (system_process_attributes): Use ptrdiff_t, not int, for command | 15 | (system_process_attributes): Use ptrdiff_t, not int, for command |
| 5 | line length. Do not attempt to address one before the beginning | 16 | line length. Do not attempt to address one before the beginning |
diff --git a/src/term.c b/src/term.c index 22056451cb9..bc6fa8f80f9 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -136,10 +136,6 @@ enum no_color_bit | |||
| 136 | 136 | ||
| 137 | static int max_frame_cols; | 137 | static int max_frame_cols; |
| 138 | 138 | ||
| 139 | /* The largest frame height in any call to calculate_costs. */ | ||
| 140 | |||
| 141 | static int max_frame_lines; | ||
| 142 | |||
| 143 | /* Non-zero if we have dropped our controlling tty and therefore | 139 | /* Non-zero if we have dropped our controlling tty and therefore |
| 144 | should not open a frame on stdout. */ | 140 | should not open a frame on stdout. */ |
| 145 | static int no_controlling_tty; | 141 | static int no_controlling_tty; |
| @@ -497,8 +493,8 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos) | |||
| 497 | static unsigned char *encode_terminal_src; | 493 | static unsigned char *encode_terminal_src; |
| 498 | static unsigned char *encode_terminal_dst; | 494 | static unsigned char *encode_terminal_dst; |
| 499 | /* Allocated sizes of the above buffers. */ | 495 | /* Allocated sizes of the above buffers. */ |
| 500 | static int encode_terminal_src_size; | 496 | static ptrdiff_t encode_terminal_src_size; |
| 501 | static int encode_terminal_dst_size; | 497 | static ptrdiff_t encode_terminal_dst_size; |
| 502 | 498 | ||
| 503 | /* Encode SRC_LEN glyphs starting at SRC to terminal output codes. | 499 | /* Encode SRC_LEN glyphs starting at SRC to terminal output codes. |
| 504 | Set CODING->produced to the byte-length of the resulting byte | 500 | Set CODING->produced to the byte-length of the resulting byte |
| @@ -509,8 +505,8 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi | |||
| 509 | { | 505 | { |
| 510 | struct glyph *src_end = src + src_len; | 506 | struct glyph *src_end = src + src_len; |
| 511 | unsigned char *buf; | 507 | unsigned char *buf; |
| 512 | int nchars, nbytes, required; | 508 | ptrdiff_t nchars, nbytes, required; |
| 513 | register int tlen = GLYPH_TABLE_LENGTH; | 509 | ptrdiff_t tlen = GLYPH_TABLE_LENGTH; |
| 514 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; | 510 | register Lisp_Object *tbase = GLYPH_TABLE_BASE; |
| 515 | Lisp_Object charset_list; | 511 | Lisp_Object charset_list; |
| 516 | 512 | ||
| @@ -518,13 +514,13 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi | |||
| 518 | multibyte-form. But, it may be enlarged on demand if | 514 | multibyte-form. But, it may be enlarged on demand if |
| 519 | Vglyph_table contains a string or a composite glyph is | 515 | Vglyph_table contains a string or a composite glyph is |
| 520 | encountered. */ | 516 | encountered. */ |
| 521 | required = MAX_MULTIBYTE_LENGTH * src_len; | 517 | if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len) |
| 518 | memory_full (SIZE_MAX); | ||
| 519 | required = src_len; | ||
| 520 | required *= MAX_MULTIBYTE_LENGTH; | ||
| 522 | if (encode_terminal_src_size < required) | 521 | if (encode_terminal_src_size < required) |
| 523 | { | 522 | { |
| 524 | if (encode_terminal_src) | 523 | encode_terminal_src = xrealloc (encode_terminal_src, required); |
| 525 | encode_terminal_src = xrealloc (encode_terminal_src, required); | ||
| 526 | else | ||
| 527 | encode_terminal_src = xmalloc (required); | ||
| 528 | encode_terminal_src_size = required; | 524 | encode_terminal_src_size = required; |
| 529 | } | 525 | } |
| 530 | 526 | ||
| @@ -544,19 +540,23 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi | |||
| 544 | if (src->u.cmp.automatic) | 540 | if (src->u.cmp.automatic) |
| 545 | { | 541 | { |
| 546 | gstring = composition_gstring_from_id (src->u.cmp.id); | 542 | gstring = composition_gstring_from_id (src->u.cmp.id); |
| 547 | required = src->slice.cmp.to + 1 - src->slice.cmp.from; | 543 | required = src->slice.cmp.to - src->slice.cmp.from + 1; |
| 548 | } | 544 | } |
| 549 | else | 545 | else |
| 550 | { | 546 | { |
| 551 | cmp = composition_table[src->u.cmp.id]; | 547 | cmp = composition_table[src->u.cmp.id]; |
| 552 | required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len; | 548 | required = cmp->glyph_len; |
| 549 | required *= MAX_MULTIBYTE_LENGTH; | ||
| 553 | } | 550 | } |
| 554 | 551 | ||
| 555 | if (encode_terminal_src_size < nbytes + required) | 552 | if (encode_terminal_src_size - nbytes < required) |
| 556 | { | 553 | { |
| 557 | encode_terminal_src_size = nbytes + required; | 554 | ptrdiff_t size; |
| 558 | encode_terminal_src = xrealloc (encode_terminal_src, | 555 | if (min (PTRDIFF_MAX, SIZE_MAX) - nbytes < required) |
| 559 | encode_terminal_src_size); | 556 | memory_full (SIZE_MAX); |
| 557 | size = nbytes + required; | ||
| 558 | encode_terminal_src = xrealloc (encode_terminal_src, size); | ||
| 559 | encode_terminal_src_size = size; | ||
| 560 | buf = encode_terminal_src + nbytes; | 560 | buf = encode_terminal_src + nbytes; |
| 561 | } | 561 | } |
| 562 | 562 | ||
| @@ -627,11 +627,15 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi | |||
| 627 | if (NILP (string)) | 627 | if (NILP (string)) |
| 628 | { | 628 | { |
| 629 | nbytes = buf - encode_terminal_src; | 629 | nbytes = buf - encode_terminal_src; |
| 630 | if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH) | 630 | if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH) |
| 631 | { | 631 | { |
| 632 | encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH; | 632 | ptrdiff_t size; |
| 633 | encode_terminal_src = xrealloc (encode_terminal_src, | 633 | if (min (PTRDIFF_MAX, SIZE_MAX) - MAX_MULTIBYTE_LENGTH |
| 634 | encode_terminal_src_size); | 634 | < nbytes) |
| 635 | memory_full (SIZE_MAX); | ||
| 636 | size = nbytes + MAX_MULTIBYTE_LENGTH; | ||
| 637 | encode_terminal_src = xrealloc (encode_terminal_src, size); | ||
| 638 | encode_terminal_src_size = size; | ||
| 635 | buf = encode_terminal_src + nbytes; | 639 | buf = encode_terminal_src + nbytes; |
| 636 | } | 640 | } |
| 637 | if (CHAR_BYTE8_P (c) | 641 | if (CHAR_BYTE8_P (c) |
| @@ -659,11 +663,14 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi | |||
| 659 | if (! STRING_MULTIBYTE (string)) | 663 | if (! STRING_MULTIBYTE (string)) |
| 660 | string = string_to_multibyte (string); | 664 | string = string_to_multibyte (string); |
| 661 | nbytes = buf - encode_terminal_src; | 665 | nbytes = buf - encode_terminal_src; |
| 662 | if (encode_terminal_src_size < nbytes + SBYTES (string)) | 666 | if (encode_terminal_src_size - nbytes < SBYTES (string)) |
| 663 | { | 667 | { |
| 664 | encode_terminal_src_size = nbytes + SBYTES (string); | 668 | ptrdiff_t size; |
| 665 | encode_terminal_src = xrealloc (encode_terminal_src, | 669 | if (min (PTRDIFF_MAX, SIZE_MAX) - SBYTES (string) < nbytes) |
| 666 | encode_terminal_src_size); | 670 | memory_full (SIZE_MAX); |
| 671 | size = nbytes + SBYTES (string); | ||
| 672 | encode_terminal_src = xrealloc (encode_terminal_src, size); | ||
| 673 | encode_terminal_src_size = size; | ||
| 667 | buf = encode_terminal_src + nbytes; | 674 | buf = encode_terminal_src + nbytes; |
| 668 | } | 675 | } |
| 669 | memcpy (buf, SDATA (string), SBYTES (string)); | 676 | memcpy (buf, SDATA (string), SBYTES (string)); |
| @@ -684,12 +691,9 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi | |||
| 684 | coding->source = encode_terminal_src; | 691 | coding->source = encode_terminal_src; |
| 685 | if (encode_terminal_dst_size == 0) | 692 | if (encode_terminal_dst_size == 0) |
| 686 | { | 693 | { |
| 694 | encode_terminal_dst = xrealloc (encode_terminal_dst, | ||
| 695 | encode_terminal_src_size); | ||
| 687 | encode_terminal_dst_size = encode_terminal_src_size; | 696 | encode_terminal_dst_size = encode_terminal_src_size; |
| 688 | if (encode_terminal_dst) | ||
| 689 | encode_terminal_dst = xrealloc (encode_terminal_dst, | ||
| 690 | encode_terminal_dst_size); | ||
| 691 | else | ||
| 692 | encode_terminal_dst = xmalloc (encode_terminal_dst_size); | ||
| 693 | } | 697 | } |
| 694 | coding->destination = encode_terminal_dst; | 698 | coding->destination = encode_terminal_dst; |
| 695 | coding->dst_bytes = encode_terminal_dst_size; | 699 | coding->dst_bytes = encode_terminal_dst_size; |
| @@ -1156,18 +1160,14 @@ calculate_costs (struct frame *frame) | |||
| 1156 | char_ins_del_vector (i.e., char_ins_del_cost) isn't used because | 1160 | char_ins_del_vector (i.e., char_ins_del_cost) isn't used because |
| 1157 | X turns off char_ins_del_ok. */ | 1161 | X turns off char_ins_del_ok. */ |
| 1158 | 1162 | ||
| 1159 | max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); | ||
| 1160 | max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); | 1163 | max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); |
| 1164 | if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2 < max_frame_cols) | ||
| 1165 | memory_full (SIZE_MAX); | ||
| 1161 | 1166 | ||
| 1162 | if (char_ins_del_vector != 0) | 1167 | char_ins_del_vector |
| 1163 | char_ins_del_vector | 1168 | = (int *) xrealloc (char_ins_del_vector, |
| 1164 | = (int *) xrealloc (char_ins_del_vector, | 1169 | (sizeof (int) |
| 1165 | (sizeof (int) | 1170 | + 2 * max_frame_cols * sizeof (int))); |
| 1166 | + 2 * max_frame_cols * sizeof (int))); | ||
| 1167 | else | ||
| 1168 | char_ins_del_vector | ||
| 1169 | = (int *) xmalloc (sizeof (int) | ||
| 1170 | + 2 * max_frame_cols * sizeof (int)); | ||
| 1171 | 1171 | ||
| 1172 | memset (char_ins_del_vector, 0, | 1172 | memset (char_ins_del_vector, 0, |
| 1173 | (sizeof (int) + 2 * max_frame_cols * sizeof (int))); | 1173 | (sizeof (int) + 2 * max_frame_cols * sizeof (int))); |