From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2648 invoked by alias); 19 Sep 2015 19:57:57 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 36559 Received: (qmail 162 invoked from network); 19 Sep 2015 19:57:55 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.0 X-Originating-IP: [80.3.228.158] X-Spam: 0 X-Authority: v=2.1 cv=P+nH/X0u c=1 sm=1 tr=0 a=P+FLVI8RzFchTbbqTxIDRw==:117 a=P+FLVI8RzFchTbbqTxIDRw==:17 a=NLZqzBF-AAAA:8 a=kj9zAlcOel0A:10 a=hybgWK3jNYxuAgEnl_sA:9 a=CjuIK1q_8ugA:10 Date: Sat, 19 Sep 2015 20:57:51 +0100 From: Peter Stephenson To: Markus Trippelsdorf Cc: zsh-workers@zsh.org Subject: Re: Two issues found with -fsanitize=undefined Message-ID: <20150919205751.5338bddc@ntlworld.com> In-Reply-To: <20150917075759.GA24365@x4> References: <20150917075759.GA24365@x4> X-Mailer: Claws Mail 3.11.1 (GTK+ 2.24.28; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Thu, 17 Sep 2015 09:57:59 +0200 Markus Trippelsdorf wrote: > 1) > pattern.c:2645:12: runtime error: signed integer overflow: 1234567890123456789 * 10 cannot be represented in type 'long int' > Test ./D02glob.ztst failed: error output differs from expected as shown above for: This might shut the compiler up, although the existing code should do the right thing anyway. I don't have gcc 5. pws diff --git a/Src/pattern.c b/Src/pattern.c index 3b55ccf..af56bd9 100644 --- a/Src/pattern.c +++ b/Src/pattern.c @@ -220,8 +220,10 @@ typedef union upat *Upat; #if defined(ZSH_64_BIT_TYPE) || defined(LONG_IS_64_BIT) typedef zlong zrange_t; #define ZRANGE_T_IS_SIGNED (1) +#define ZRANGE_MAX ZLONG_MAX #else typedef unsigned long zrange_t; +#define ZRANGE_MAX ULONG_MAX #endif #ifdef MULTIBYTE_SUPPORT @@ -2641,19 +2643,30 @@ patmatch(Upat prog) start = compend = patinput; comp = 0; while (patinput < patinend && idigit(*patinput)) { - if (comp) - comp *= 10; - comp += *patinput - '0'; + int out_of_range = 0; + int digit = *patinput - '0'; + if (comp > ZRANGE_MAX / (zlong)10) { + out_of_range = 1; + } else { + zrange_t c10 = comp ? comp * 10 : 0; + if (ZRANGE_MAX - c10 < digit) { + out_of_range = 1; + } else { + comp = c10; + comp += digit; + } + } patinput++; compend++; - if (comp & ((zrange_t)1 << (sizeof(comp)*8 - + if (out_of_range || + (comp & ((zrange_t)1 << (sizeof(comp)*8 - #ifdef ZRANGE_T_IS_SIGNED 2 #else 1 #endif - ))) { + )))) { /* * Out of range (allowing for signedness, which * we need if we are using zlongs). diff --git a/Src/zsh.h b/Src/zsh.h index 4e2cb65..9c7e5d9 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -36,6 +36,12 @@ */ #ifdef ZSH_64_BIT_TYPE typedef ZSH_64_BIT_TYPE zlong; +#if defind(ZLONG_IS_LONG_LONG) && defined(LLONG_MAX) +#define ZLONG_MAX LLONG_MAX +#else +/* umm... */ +#define ZLONG_MAX ((zlong)9223372036854775807) +#endif #ifdef ZSH_64_BIT_UTYPE typedef ZSH_64_BIT_UTYPE zulong; #else @@ -44,6 +50,7 @@ typedef unsigned zlong zulong; #else typedef long zlong; typedef unsigned long zulong; +#define ZLONG_MAX LONG_MAX #endif /*