From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#9079: integer overflow etc. issues (e.g., image crashes Emacs) Date: Thu, 14 Jul 2011 15:02:06 -0700 Organization: UCLA Computer Science Department Message-ID: <4E1F675E.1020907@cs.ucla.edu> References: <4E1EA0FB.5070903@cs.ucla.edu> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1310681010 22663 80.91.229.12 (14 Jul 2011 22:03:30 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 14 Jul 2011 22:03:30 +0000 (UTC) Cc: 9079@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Jul 15 00:03:26 2011 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1QhU0D-00047z-Oy for geb-bug-gnu-emacs@m.gmane.org; Fri, 15 Jul 2011 00:03:26 +0200 Original-Received: from localhost ([::1]:44189 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QhU0C-0003bv-I5 for geb-bug-gnu-emacs@m.gmane.org; Thu, 14 Jul 2011 18:03:24 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:47855) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QhTzt-0003bR-Pk for bug-gnu-emacs@gnu.org; Thu, 14 Jul 2011 18:03:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QhTzs-0003Hl-15 for bug-gnu-emacs@gnu.org; Thu, 14 Jul 2011 18:03:05 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:50486) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QhTzr-0003Gr-MH for bug-gnu-emacs@gnu.org; Thu, 14 Jul 2011 18:03:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1QhTzq-0002yW-Mg; Thu, 14 Jul 2011 18:03:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 14 Jul 2011 22:03:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 9079 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 9079-submit@debbugs.gnu.org id=B9079.131068093611375 (code B ref 9079); Thu, 14 Jul 2011 22:03:02 +0000 Original-Received: (at 9079) by debbugs.gnu.org; 14 Jul 2011 22:02:16 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QhTz4-0002xP-PY for submit@debbugs.gnu.org; Thu, 14 Jul 2011 18:02:16 -0400 Original-Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QhTz2-0002xD-Rk for 9079@debbugs.gnu.org; Thu, 14 Jul 2011 18:02:14 -0400 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 3610F39E80E1; Thu, 14 Jul 2011 15:02:07 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Original-Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4M+x1IIrA7Ev; Thu, 14 Jul 2011 15:02:06 -0700 (PDT) Original-Received: from [131.179.64.200] (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 5138039E80E0; Thu, 14 Jul 2011 15:02:06 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.18) Gecko/20110621 Fedora/3.1.11-1.fc14 Thunderbird/3.1.11 In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Thu, 14 Jul 2011 18:03:02 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:49096 Archived-At: OK, here's an updated version of the bidi.c part of that patch, reflecting the bidi changes just made to the trunk. * 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. === modified file 'src/bidi.c' --- src/bidi.c 2011-07-14 21:46:32 +0000 +++ src/bidi.c 2011-07-14 21:46:40 +0000 @@ -299,11 +299,11 @@ #define BIDI_CACHE_CHUNK 200 static struct bidi_it *bidi_cache; -static EMACS_INT bidi_cache_size = 0; +static ptrdiff_t bidi_cache_size = 0; enum { elsz = sizeof (struct bidi_it) }; -static EMACS_INT bidi_cache_idx; /* next unused cache slot */ -static EMACS_INT bidi_cache_last_idx; /* slot of last cache hit */ -static EMACS_INT bidi_cache_start = 0; /* start of cache for this +static ptrdiff_t bidi_cache_idx; /* next unused cache slot */ +static ptrdiff_t bidi_cache_last_idx; /* slot of last cache hit */ +static ptrdiff_t bidi_cache_start = 0; /* start of cache for this "stack" level */ /* Reset the cache state to the empty state. We only reset the part @@ -336,7 +336,7 @@ } static inline void -bidi_cache_fetch_state (EMACS_INT idx, struct bidi_it *bidi_it) +bidi_cache_fetch_state (ptrdiff_t idx, struct bidi_it *bidi_it) { int current_scan_dir = bidi_it->scan_dir; @@ -352,10 +352,10 @@ level less or equal to LEVEL. if LEVEL is -1, disregard the resolved levels in cached states. DIR, if non-zero, means search in that direction from the last cache hit. */ -static inline EMACS_INT +static inline ptrdiff_t bidi_cache_search (EMACS_INT charpos, int level, int dir) { - EMACS_INT i, i_start; + ptrdiff_t i, i_start; if (bidi_cache_idx > bidi_cache_start) { @@ -417,12 +417,12 @@ C, searching backwards (DIR = -1) for LEVEL = 2 will return the index of slot B or A, depending whether BEFORE is, respectively, non-zero or zero. */ -static EMACS_INT +static ptrdiff_t bidi_cache_find_level_change (int level, int dir, int before) { if (bidi_cache_idx) { - EMACS_INT i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1; + ptrdiff_t i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1; int incr = before ? 1 : 0; xassert (!dir || bidi_cache_last_idx >= 0); @@ -458,22 +458,26 @@ } static inline void -bidi_cache_ensure_space (EMACS_INT idx) +bidi_cache_ensure_space (ptrdiff_t idx) { /* Enlarge the cache as needed. */ if (idx >= bidi_cache_size) { - while (idx >= bidi_cache_size) - bidi_cache_size += BIDI_CACHE_CHUNK; - bidi_cache = - (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz); + ptrdiff_t new_size; + ptrdiff_t max_size = + min (PTRDIFF_MAX, SIZE_MAX) / elsz / BIDI_CACHE_CHUNK * BIDI_CACHE_CHUNK; + if (max_size <= idx) + memory_full (SIZE_MAX); + new_size = idx - idx % BIDI_CACHE_CHUNK + BIDI_CACHE_CHUNK; + bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, new_size * elsz); + bidi_cache_size = new_size; } } static inline void bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved) { - EMACS_INT idx; + ptrdiff_t idx; /* We should never cache on backward scans. */ if (bidi_it->scan_dir == -1) @@ -528,7 +532,7 @@ static inline bidi_type_t bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it) { - EMACS_INT i = bidi_cache_search (charpos, level, bidi_it->scan_dir); + ptrdiff_t i = bidi_cache_search (charpos, level, bidi_it->scan_dir); if (i >= bidi_cache_start) { @@ -560,7 +564,7 @@ /* 5-slot stack for saving the start of the previous level of the cache. xdisp.c maintains a 5-slot stack for its iterator state, and we need the same size of our stack. */ -static EMACS_INT bidi_cache_start_stack[IT_STACK_SIZE]; +static ptrdiff_t bidi_cache_start_stack[IT_STACK_SIZE]; static int bidi_cache_sp; /* Push the bidi iterator state in preparation for reordering a @@ -2123,7 +2127,7 @@ bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag) { int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir; - EMACS_INT idx; + ptrdiff_t idx; /* Try the cache first. */ if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) @@ -2300,7 +2304,7 @@ void bidi_dump_cached_states (void) { - int i; + ptrdiff_t i; int ndigits = 1; if (bidi_cache_idx == 0)