From unknown Tue Jun 17 20:15:57 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#8602 <8602@debbugs.gnu.org> To: bug#8602 <8602@debbugs.gnu.org> Subject: Status: Lisp reader mishandles large non-base-10 integers on 64-bit hosts Reply-To: bug#8602 <8602@debbugs.gnu.org> Date: Wed, 18 Jun 2025 03:15:57 +0000 retitle 8602 Lisp reader mishandles large non-base-10 integers on 64-bit ho= sts reassign 8602 emacs submitter 8602 Paul Eggert severity 8602 normal thanks From debbugs-submit-bounces@debbugs.gnu.org Sun May 01 23:03:12 2011 Received: (at submit) by debbugs.gnu.org; 2 May 2011 03:03:12 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QGjPk-0002wN-9a for submit@debbugs.gnu.org; Sun, 01 May 2011 23:03:12 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QGjPe-0002vo-4Y for submit@debbugs.gnu.org; Sun, 01 May 2011 23:03:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QGjPY-0003Hz-3V for submit@debbugs.gnu.org; Sun, 01 May 2011 23:03:00 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:52971) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QGjPY-0003Hv-22 for submit@debbugs.gnu.org; Sun, 01 May 2011 23:03:00 -0400 Received: from eggs.gnu.org ([140.186.70.92]:43114) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QGjPX-0005zd-5x for bug-gnu-emacs@gnu.org; Sun, 01 May 2011 23:02:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QGjPW-0003Hl-5S for bug-gnu-emacs@gnu.org; Sun, 01 May 2011 23:02:59 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:32880) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QGjPV-0003Hf-Or for bug-gnu-emacs@gnu.org; Sun, 01 May 2011 23:02:58 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 95C3D39E80F5 for ; Sun, 1 May 2011 20:02:56 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu 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 iBU+t4mGSUWe for ; Sun, 1 May 2011 20:02:56 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id E186439E8083 for ; Sun, 1 May 2011 20:02:55 -0700 (PDT) Message-ID: <4DBE1EDF.7050306@cs.ucla.edu> Date: Sun, 01 May 2011 20:02:55 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Thunderbird/3.1.8 MIME-Version: 1.0 To: bug-gnu-emacs@gnu.org Subject: Lisp reader mishandles large non-base-10 integers on 64-bit hosts Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -4.7 (----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.7 (----) In the Emacs trunk I found some more problems with the Lisp reader and large integers. It uses a floating-point number to keep track of the integer's value, which leads to incorrect answers with large integers on 64-bit hosts. In some cases the errors are fairly extreme. I plan to install the following patch after some more testing. * lread.c (read_integer): Be more consistent with string-to-number. Use string_to_number to do the actual conversion; this avoids rounding errors and fixes some other screwups. Without this fix, for example, #x1fffffffffffffff was misread as -2305843009213693952. (digit_to_number): Move earlier, for benefit of read_integer. Return -1 if the digit is out of range for the base, -2 if it is not a digit in any supported base. === modified file 'src/lread.c' --- src/lread.c 2011-04-29 07:55:25 +0000 +++ src/lread.c 2011-05-02 02:18:43 +0000 @@ -2245,6 +2245,26 @@ } } +/* Return the digit that CHARACTER stands for in the given BASE. + Return -1 if CHARACTER is out of range for BASE, + and -2 if CHARACTER is not valid for any supported BASE. */ +static inline int +digit_to_number (int character, int base) +{ + int digit; + + if ('0' <= character && character <= '9') + digit = character - '0'; + else if ('a' <= character && character <= 'z') + digit = character - 'a' + 10; + else if ('A' <= character && character <= 'Z') + digit = character - 'A' + 10; + else + return -2; + + return digit < base ? digit : -1; +} + /* Read an integer in radix RADIX using READCHARFUN to read characters. RADIX must be in the interval [2..36]; if it isn't, a read error is signaled . Value is the integer read. Signals an @@ -2254,59 +2274,64 @@ static Lisp_Object read_integer (Lisp_Object readcharfun, int radix) { - int ndigits = 0, invalid_p, c, sign = 0; - /* We use a floating point number because */ - double number = 0; + /* Room for sign, leading 0, other digits, trailing null byte. */ + char buf[1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1]; + + int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ if (radix < 2 || radix > 36) - invalid_p = 1; + valid = 0; else { - number = ndigits = invalid_p = 0; - sign = 1; + char *p = buf; + int c, digit; c = READCHAR; - if (c == '-') + if (c == '-' || c == '+') { + *p++ = c; c = READCHAR; - sign = -1; - } - else if (c == '+') - c = READCHAR; - - while (c >= 0) - { - int digit; - - if (c >= '0' && c <= '9') - digit = c - '0'; - else if (c >= 'a' && c <= 'z') - digit = c - 'a' + 10; - else if (c >= 'A' && c <= 'Z') - digit = c - 'A' + 10; + } + + if (c == '0') + { + *p++ = c; + valid = 1; + + /* Ignore redundant leading zeros, so the buffer doesn't + fill up with them. */ + do + c = READCHAR; + while (c == '0'); + } + + while (-1 <= (digit = digit_to_number (c, radix))) + { + if (digit == -1) + valid = 0; + if (valid < 0) + valid = 1; + + if (p < buf + sizeof buf - 1) + *p++ = c; else - { - UNREAD (c); - break; - } - - if (digit < 0 || digit >= radix) - invalid_p = 1; - - number = radix * number + digit; - ++ndigits; + valid = 0; + c = READCHAR; } + + if (c >= 0) + UNREAD (c); + *p = '\0'; } - if (ndigits == 0 || invalid_p) + if (! valid) { - char buf[50]; sprintf (buf, "integer, radix %d", radix); invalid_syntax (buf, 0); } - return make_fixnum_or_float (sign * number); + return string_to_number (buf, radix, 0); } @@ -3165,23 +3190,6 @@ } -static inline int -digit_to_number (int character, int base) -{ - int digit; - - if ('0' <= character && character <= '9') - digit = character - '0'; - else if ('a' <= character && character <= 'z') - digit = character - 'a' + 10; - else if ('A' <= character && character <= 'Z') - digit = character - 'A' + 10; - else - return -1; - - return digit < base ? digit : -1; -} - #define LEAD_INT 1 #define DOT_CHAR 2 #define TRAIL_INT 4 From debbugs-submit-bounces@debbugs.gnu.org Fri May 06 03:30:08 2011 Received: (at 8602-done) by debbugs.gnu.org; 6 May 2011 07:30:08 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QIFUG-00031b-82 for submit@debbugs.gnu.org; Fri, 06 May 2011 03:30:08 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1QIFUC-00030V-8W; Fri, 06 May 2011 03:30:05 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id AA3A539E8118; Fri, 6 May 2011 00:29:57 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu 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 nku4im7TOEsc; Fri, 6 May 2011 00:29:57 -0700 (PDT) Received: from [192.168.1.10] (pool-71-189-109-235.lsanca.fios.verizon.net [71.189.109.235]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 2BCF039E8113; Fri, 6 May 2011 00:29:57 -0700 (PDT) Message-ID: <4DC3A374.1090401@cs.ucla.edu> Date: Fri, 06 May 2011 00:29:56 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 MIME-Version: 1.0 To: 8545@debbugs.gnu.org, 8600-done@debbugs.gnu.org, 8601-done@debbugs.gnu.org, 8602-done@debbugs.gnu.org Subject: Merged fixes for 8600, 8601, 8602, and (partially) for 8545 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Score: -3.0 (---) X-Debbugs-Envelope-To: 8602-done X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -3.0 (---) I committed to the Emacs trunk a merge (bzr 104134) that has fixes for the following bugs: * Bug#8600 - The fix removes the garbage element of code_space. * Bug#8601 - Here I assumed that the "* 2" is a typo. * Bug#8602 - This fixes some large-int-to-float screwups in the Lisp reader. * Bug#8545 - This fixes the bug where the code should have called va_copy, but didn't. Also, I changed a limit so that the MOST_POSITIVE_FIXNUM limit for strings applies to their length, i.e., does not include the null termination byte. Stefan hasn't had time to chime in, but if this last change turns out to be incorrect I will back it out. This merge doesn't entirely fix Bug#8545, so I'll leave that bug open; the others I'll close. From unknown Tue Jun 17 20:15:57 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Fri, 03 Jun 2011 11:24:05 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator