diff options
| author | Paul Eggert | 2015-11-08 22:47:01 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-11-08 22:48:28 -0800 |
| commit | 1087305574fd61256d66eb0c995f8bb74bd91afe (patch) | |
| tree | 9f0052e41a56c785575727931ff4abb8e7dfa7e0 /src/character.c | |
| parent | bcca6a2a028d05af3cb5b31a5a2c997f3f1f1d31 (diff) | |
| download | emacs-1087305574fd61256d66eb0c995f8bb74bd91afe.tar.gz emacs-1087305574fd61256d66eb0c995f8bb74bd91afe.zip | |
Use INT_ADD_WRAPV etc. to check integer overflow
* src/alloc.c (xnmalloc, xnrealloc, xpalloc, Fmake_string):
* src/buffer.c (record_overlay_string, overlay_strings):
* src/casefiddle.c (casify_object):
* src/ccl.c (Fccl_execute_on_string):
* src/character.c (char_width, c_string_width, lisp_string_width)
(count_size_as_multibyte, string_escape_byte8):
* src/coding.c (coding_alloc_by_realloc, produce_chars):
* src/data.c (arith_driver):
* src/dispnew.c (realloc_glyph_pool, init_display):
* src/editfns.c (styled_format):
* src/fns.c (Ffillarray):
* src/ftfont.c (ftfont_shape_by_flt):
* src/gnutls.c (gnutls_hex_string):
* src/gtkutil.c (get_utf8_string):
* src/image.c (x_to_xcolors, x_detect_edges, png_load_body):
* src/keymap.c (Fkey_description):
* src/lisp.h (SAFE_ALLOCA_LISP):
* src/term.c (encode_terminal_code):
* src/tparam.c (tparam1):
* src/xselect.c (x_property_data_to_lisp):
* src/xsmfns.c (smc_save_yourself_CB):
* src/xterm.c (x_term_init):
When checking for integer overflow, prefer INT_MULTIPLY_WRAPV to
more-complicated code involving division and/or
INT_MULTIPLY_OVERFLOW, and similarly for INT_ADD_WRAPV and
subtraction and/or INT_ADD_OVERFLOW.
* src/casefiddle.c (casify_object): Simplify multibyte size check.
* src/character.c: Remove some obsolete ‘#ifdef emacs’s.
* src/data.c (arith_driver): Also check for division overflow,
as that’s now possible given that the accumulator can now contain
any Emacs integer.
* src/lisp.h (lisp_word_count): Remove; no longer used.
Diffstat (limited to 'src/character.c')
| -rw-r--r-- | src/character.c | 63 |
1 files changed, 19 insertions, 44 deletions
diff --git a/src/character.c b/src/character.c index 3e2bf1e70c2..bc2fa4a12da 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -25,14 +25,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | /* At first, see the document in `character.h' to understand the code | 25 | /* At first, see the document in `character.h' to understand the code |
| 26 | in this file. */ | 26 | in this file. */ |
| 27 | 27 | ||
| 28 | #ifdef emacs | ||
| 29 | #include <config.h> | 28 | #include <config.h> |
| 30 | #endif | ||
| 31 | 29 | ||
| 32 | #include <stdio.h> | 30 | #include <stdio.h> |
| 33 | 31 | ||
| 34 | #ifdef emacs | ||
| 35 | |||
| 36 | #include <sys/types.h> | 32 | #include <sys/types.h> |
| 37 | #include <intprops.h> | 33 | #include <intprops.h> |
| 38 | #include "lisp.h" | 34 | #include "lisp.h" |
| @@ -41,12 +37,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 41 | #include "composite.h" | 37 | #include "composite.h" |
| 42 | #include "disptab.h" | 38 | #include "disptab.h" |
| 43 | 39 | ||
| 44 | #else /* not emacs */ | ||
| 45 | |||
| 46 | #include "mulelib.h" | ||
| 47 | |||
| 48 | #endif /* emacs */ | ||
| 49 | |||
| 50 | /* Char-table of information about which character to unify to which | 40 | /* Char-table of information about which character to unify to which |
| 51 | Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */ | 41 | Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */ |
| 52 | Lisp_Object Vchar_unify_table; | 42 | Lisp_Object Vchar_unify_table; |
| @@ -302,9 +292,8 @@ char_width (int c, struct Lisp_Char_Table *dp) | |||
| 302 | if (CHARACTERP (ch)) | 292 | if (CHARACTERP (ch)) |
| 303 | { | 293 | { |
| 304 | int w = CHAR_WIDTH (XFASTINT (ch)); | 294 | int w = CHAR_WIDTH (XFASTINT (ch)); |
| 305 | if (INT_ADD_OVERFLOW (width, w)) | 295 | if (INT_ADD_WRAPV (width, w, &width)) |
| 306 | string_overflow (); | 296 | string_overflow (); |
| 307 | width += w; | ||
| 308 | } | 297 | } |
| 309 | } | 298 | } |
| 310 | } | 299 | } |
| @@ -349,20 +338,16 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision, | |||
| 349 | int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); | 338 | int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); |
| 350 | ptrdiff_t thiswidth = char_width (c, dp); | 339 | ptrdiff_t thiswidth = char_width (c, dp); |
| 351 | 340 | ||
| 352 | if (precision <= 0) | 341 | if (0 < precision && precision - width < thiswidth) |
| 353 | { | ||
| 354 | if (INT_ADD_OVERFLOW (width, thiswidth)) | ||
| 355 | string_overflow (); | ||
| 356 | } | ||
| 357 | else if (precision - width < thiswidth) | ||
| 358 | { | 342 | { |
| 359 | *nchars = i; | 343 | *nchars = i; |
| 360 | *nbytes = i_byte; | 344 | *nbytes = i_byte; |
| 361 | return width; | 345 | return width; |
| 362 | } | 346 | } |
| 347 | if (INT_ADD_WRAPV (thiswidth, width, &width)) | ||
| 348 | string_overflow (); | ||
| 363 | i++; | 349 | i++; |
| 364 | i_byte += bytes; | 350 | i_byte += bytes; |
| 365 | width += thiswidth; | ||
| 366 | } | 351 | } |
| 367 | 352 | ||
| 368 | if (precision > 0) | 353 | if (precision > 0) |
| @@ -436,22 +421,16 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision, | |||
| 436 | thiswidth = char_width (c, dp); | 421 | thiswidth = char_width (c, dp); |
| 437 | } | 422 | } |
| 438 | 423 | ||
| 439 | if (precision <= 0) | 424 | if (0 < precision && precision - width < thiswidth) |
| 440 | { | ||
| 441 | #ifdef emacs | ||
| 442 | if (INT_ADD_OVERFLOW (width, thiswidth)) | ||
| 443 | string_overflow (); | ||
| 444 | #endif | ||
| 445 | } | ||
| 446 | else if (precision - width < thiswidth) | ||
| 447 | { | 425 | { |
| 448 | *nchars = i; | 426 | *nchars = i; |
| 449 | *nbytes = i_byte; | 427 | *nbytes = i_byte; |
| 450 | return width; | 428 | return width; |
| 451 | } | 429 | } |
| 430 | if (INT_ADD_WRAPV (thiswidth, width, &width)) | ||
| 431 | string_overflow (); | ||
| 452 | i += chars; | 432 | i += chars; |
| 453 | i_byte += bytes; | 433 | i_byte += bytes; |
| 454 | width += thiswidth; | ||
| 455 | } | 434 | } |
| 456 | 435 | ||
| 457 | if (precision > 0) | 436 | if (precision > 0) |
| @@ -657,9 +636,8 @@ count_size_as_multibyte (const unsigned char *str, ptrdiff_t len) | |||
| 657 | for (bytes = 0; str < endp; str++) | 636 | for (bytes = 0; str < endp; str++) |
| 658 | { | 637 | { |
| 659 | int n = *str < 0x80 ? 1 : 2; | 638 | int n = *str < 0x80 ? 1 : 2; |
| 660 | if (INT_ADD_OVERFLOW (bytes, n)) | 639 | if (INT_ADD_WRAPV (bytes, n, &bytes)) |
| 661 | string_overflow (); | 640 | string_overflow (); |
| 662 | bytes += n; | ||
| 663 | } | 641 | } |
| 664 | return bytes; | 642 | return bytes; |
| 665 | } | 643 | } |
| @@ -795,6 +773,7 @@ string_escape_byte8 (Lisp_Object string) | |||
| 795 | ptrdiff_t nbytes = SBYTES (string); | 773 | ptrdiff_t nbytes = SBYTES (string); |
| 796 | bool multibyte = STRING_MULTIBYTE (string); | 774 | bool multibyte = STRING_MULTIBYTE (string); |
| 797 | ptrdiff_t byte8_count; | 775 | ptrdiff_t byte8_count; |
| 776 | ptrdiff_t thrice_byte8_count, uninit_nchars, uninit_nbytes; | ||
| 798 | const unsigned char *src, *src_end; | 777 | const unsigned char *src, *src_end; |
| 799 | unsigned char *dst; | 778 | unsigned char *dst; |
| 800 | Lisp_Object val; | 779 | Lisp_Object val; |
| @@ -808,23 +787,23 @@ string_escape_byte8 (Lisp_Object string) | |||
| 808 | if (byte8_count == 0) | 787 | if (byte8_count == 0) |
| 809 | return string; | 788 | return string; |
| 810 | 789 | ||
| 790 | if (INT_MULTIPLY_WRAPV (byte8_count, 3, &thrice_byte8_count)) | ||
| 791 | string_overflow (); | ||
| 792 | |||
| 811 | if (multibyte) | 793 | if (multibyte) |
| 812 | { | 794 | { |
| 813 | if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count | ||
| 814 | || (STRING_BYTES_BOUND - nbytes) / 2 < byte8_count) | ||
| 815 | string_overflow (); | ||
| 816 | |||
| 817 | /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ | 795 | /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ |
| 818 | val = make_uninit_multibyte_string (nchars + byte8_count * 3, | 796 | if (INT_ADD_WRAPV (nchars, thrice_byte8_count, &uninit_nchars) |
| 819 | nbytes + byte8_count * 2); | 797 | || INT_ADD_WRAPV (nbytes, 2 * byte8_count, &uninit_nbytes)) |
| 798 | string_overflow (); | ||
| 799 | val = make_uninit_multibyte_string (uninit_nchars, uninit_nbytes); | ||
| 820 | } | 800 | } |
| 821 | else | 801 | else |
| 822 | { | 802 | { |
| 823 | if ((STRING_BYTES_BOUND - nbytes) / 3 < byte8_count) | ||
| 824 | string_overflow (); | ||
| 825 | |||
| 826 | /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ | 803 | /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ |
| 827 | val = make_uninit_string (nbytes + byte8_count * 3); | 804 | if (INT_ADD_WRAPV (thrice_byte8_count, nbytes, &uninit_nbytes)) |
| 805 | string_overflow (); | ||
| 806 | val = make_uninit_string (uninit_nbytes); | ||
| 828 | } | 807 | } |
| 829 | 808 | ||
| 830 | src = SDATA (string); | 809 | src = SDATA (string); |
| @@ -981,8 +960,6 @@ character is not ASCII nor 8-bit character, an error is signaled. */) | |||
| 981 | return make_number (c); | 960 | return make_number (c); |
| 982 | } | 961 | } |
| 983 | 962 | ||
| 984 | #ifdef emacs | ||
| 985 | |||
| 986 | /* Return true if C is an alphabetic character. */ | 963 | /* Return true if C is an alphabetic character. */ |
| 987 | bool | 964 | bool |
| 988 | alphabeticp (int c) | 965 | alphabeticp (int c) |
| @@ -1131,5 +1108,3 @@ See The Unicode Standard for the meaning of those values. */); | |||
| 1131 | /* The correct char-table is setup in characters.el. */ | 1108 | /* The correct char-table is setup in characters.el. */ |
| 1132 | Vunicode_category_table = Qnil; | 1109 | Vunicode_category_table = Qnil; |
| 1133 | } | 1110 | } |
| 1134 | |||
| 1135 | #endif /* emacs */ | ||