From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27376 invoked by alias); 30 Jan 2018 18:41:06 -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: List-Unsubscribe: X-Seq: 42332 Received: (qmail 13592 invoked by uid 1010); 30 Jan 2018 18:41:06 -0000 X-Qmail-Scanner-Diagnostics: from mailout1.w1.samsung.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(210.118.77.11):SA:0(-1.9/5.0):. Processed in 13.37671 secs); 30 Jan 2018 18:41:06 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS, SPF_PASS,T_DKIM_INVALID,T_RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.1 X-Envelope-From: p.stephenson@samsung.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20180130183047euoutp0177f78c7dccd67514caa8013027df91da~OqgFY5ykp0216302163euoutp01U DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1517337047; bh=ToelrdvxTcl7olMIEx0Nhw2NPYFIo0nrCeYQ5yvuczs=; h=Date:From:To:Subject:In-reply-to:References:From; b=A5KMGvr4j1G9fvUPO6cPBdzdaEQFOKSt+1TgqiS+n6d2PqttT7SxRF6YKz+YLw4l5 /q3UqmaqOMFRwsRPd+4ra96aA4l/pBgq8pVjYgUO0l7mnFdQFB8y+MtOWCmzfDRwAb /PM3hiD5l1AEd08qR+gBEoVQYhoJH7QlGexG095w= X-AuditID: cbfec7f1-f793a6d00000326b-37-5a70b9d62d96 Date: Tue, 30 Jan 2018 18:30:42 +0000 From: Peter Stephenson To: zsh-workers@zsh.org Subject: Re: [BUG] printf truncates large values Message-id: <20180130183042.7e013804@pwslap01u.europe.root.pri> In-reply-to: <20180130164021.GA521@cventin.lip.ens-lyon.fr> Organization: Samsung Cambridge Solution Centre X-Mailer: Claws Mail 3.7.9 (GTK+ 2.22.0; i386-redhat-linux-gnu) MIME-version: 1.0 Content-type: text/plain; charset="US-ASCII" Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrAIsWRmVeSWpSXmKPExsWy7djPc7rXdhZEGfz+x2FxsPkhkwOjx6qD H5gCGKO4bFJSczLLUov07RK4Mq79aWAt+CFR8ejCE8YGxrVCXYycHBICJhKfJ3QwQdhiEhfu rWfrYuTiEBJYyigx4UgnE4TTyyRxau19dpiOrT+mQFUtY5T49HQRM4QzjUni3ukOKOcMo8S6 WWdZIZyzjBKTt75gBelnEVCVuPiumQ3EZhMwlJi6aTYjiC0iIC5xdu15FhBbWMBAovPmbbAa XgF7iW8XP4DVcApYS8z9PBmshl9AX+Lq309Ql9tLzLxyhhGiXlDix+R7YDXMAjoS27Y9Zoew 5SU2r3kLdp2EwBw2iTNrXrBBNLtILLi0A+o5YYlXx7dA2TISlyd3s0DY/YwST7p9IZpnMEqc PrMDqtlaou/2RUaIDXwSk7ZNB9rAARTnlehogwaxh8TjTR+hZjpKzNy1hBESKn1Acz70ME5g VJiF5PBZSA6fheTwBYzMqxhFUkuLc9NTi430ihNzi0vz0vWS83M3MQLTwel/xz/uYHx/wuoQ owAHoxIPb0JVQZQQa2JZcWXuIUYJDmYlEV6R1flRQrwpiZVVqUX58UWlOanFhxilOViUxHlt o9oihQTSE0tSs1NTC1KLYLJMHJxSDYwrji+ZvWd51en/Ozf9X2X6NXnaK9dl+osnZ5ndSe1I Xqn60P3pLn7j/Pe5Uzf+y+uceP7KzYlSij8eL9bdcd351GyXv9+3nHivvnC/23uuY8FS27f6 HqqfleTtu+5kpvLMbSu9xe92K6zN/fN56QWxQ3+ck17s9g+rOHml66i/weVMbR338M2r7ymx FGckGmoxFxUnAgD7qFYRAwMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrALMWRmVeSWpSXmKPExsVy+t/xy7pXdxZEGfx+pWZxsPkhkwOjx6qD H5gCGKO4bFJSczLLUov07RK4Mq79aWAt+CFR8ejCE8YGxrVCXYycHBICJhJbf0xhg7DFJC7c Ww9mCwksYZRYuCuki5ELyJ7BJHH/6kZGCOcco8SleU/YIJyzjBItRx+zgrSwCKhKXHzXDNbO JmAoMXXTbEYQW0RAXOLs2vMsILawgIFE583bYDW8AvYS3y5+AKvhFLCWmPt5MgvE0AmMEt/W XGAGSfAL6Etc/fuJCeI+e4mZV84wQjQLSvyYfA9sKLOAlsTmbU2sELa8xOY1b5khflCXuHF3 N/sERuFZSFpmIWmZhaRlASPzKkaR1NLi3PTcYiO94sTc4tK8dL3k/NxNjMBw3nbs55YdjF3v gg8xCnAwKvHwclYURAmxJpYVV+YeYpTgYFYS4RVZnR8lxJuSWFmVWpQfX1Sak1p8iFGag0VJ nLd3z+pIIYH0xJLU7NTUgtQimCwTB6dUA6Odeimf9kRHuz27GOr+S+Z+twl+vfajd81Uf8s0 T8aL2X5uMltqV4SpMvvrWAmUPnOING9IsGcTrb3b+UD3SW+bcre09m1Zu54ns+3K6h3MEq49 9Zru1rFz/xn9kq4eH8uMTqHJQjtXrp/B2GxjeLn8aMwUSc5bhzbM8znyyWTKgUSTA7MMlViK MxINtZiLihMBFEsFwmMCAAA= X-CMS-MailID: 20180130183045eucas1p1a7e903a8684231980973d98a98f59b3b X-Msg-Generator: CA CMS-TYPE: 201P X-CMS-RootMailID: 20180130164832epcas1p1460baafa538692bcc1f9b169f00f0bc5 X-RootMTR: 20180130164832epcas1p1460baafa538692bcc1f9b169f00f0bc5 References: <20180130164021.GA521@cventin.lip.ens-lyon.fr> On Tue, 30 Jan 2018 17:40:21 +0100 Vincent Lefevre wrote: > On a 64-bit x86_64 machine, with zsh 5.4.2: > > cventin% printf "%x\n" 10865468317030705979 > zsh: number truncated after 19 digits: 10865468317030705979 > f1430962f7cd785 This is not because of the standard integer representation, it relates to whatever type we picked for zlong (and the corresponding unsigned type, zulong, which has the same length). The problem is this goes through math evaluation (mathevali()) regardless of the fact that it's a constant, so becomes a zlong. This means we lose track of the fact it's actually unsigned. The only easyish fix is to scan for a constant and avoid the mathevali() in that case. So I copied and adapted zstrtol_underscore() to do that. Anything more requires propagating full-length unsigned values separately through the integer code, which is a large undertaking not entirely without its own problems. pws diff --git a/Src/builtin.c b/Src/builtin.c index 0211f27..fb59738 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -5243,7 +5243,10 @@ bin_print(char *name, char **args, Options ops, int func) *d++ = 'l'; #endif *d++ = 'l', *d++ = *c, *d = '\0'; - zulongval = (curarg) ? mathevali(curarg) : 0; + if (!curarg) + zulongval = (zulong)0; + else if (!zstrtoul_underscore(curarg, &zulongval)) + zulongval = mathevali(curarg); if (errflag) { zulongval = 0; errflag &= ~ERRFLAG_ERROR; diff --git a/Src/utils.c b/Src/utils.c index 74fdac3..3b589aa 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -2455,6 +2455,67 @@ zstrtol_underscore(const char *s, char **t, int base, int underscore) return neg ? -(zlong)calc : (zlong)calc; } +/* + * If s represents a complete unsigned integer (and nothing else) + * return 1 and set retval to the value. Otherwise return 0. + * + * Underscores are always allowed. + * + * Sensitive to OCTAL_ZEROES. + */ + +/**/ +mod_export int +zstrtoul_underscore(const char *s, zulong *retval) +{ + zulong calc = 0, newcalc = 0, base; + + if (*s == '+') + s++; + + if (*s != '0') + base = 10; + else if (*++s == 'x' || *s == 'X') + base = 16, s++; + else if (*s == 'b' || *s == 'B') + base = 2, s++; + else + base = isset(OCTALZEROES) ? 8 : 10; + if (base < 2 || base > 36) { + return 0; + } else if (base <= 10) { + for (; (*s >= '0' && *s < ('0' + base)) || + *s == '_'; s++) { + if (*s == '_') + continue; + newcalc = calc * base + *s - '0'; + if (newcalc < calc) + { + return 0; + } + calc = newcalc; + } + } else { + for (; idigit(*s) || (*s >= 'a' && *s < ('a' + base - 10)) + || (*s >= 'A' && *s < ('A' + base - 10)) + || *s == '_'; s++) { + if (*s == '_') + continue; + newcalc = calc*base + (idigit(*s) ? (*s - '0') : (*s & 0x1f) + 9); + if (newcalc < calc) + { + return 0; + } + calc = newcalc; + } + } + + if (*s) + return 0; + *retval = calc; + return 1; +} + /**/ mod_export int setblock_fd(int turnonblocking, int fd, long *modep)