[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] feature/gnus-select 0160cc5 029/218: Avoid losing info whe
From: |
Andrew G Cohen |
Subject: |
[Emacs-diffs] feature/gnus-select 0160cc5 029/218: Avoid losing info when formatting integers |
Date: |
Fri, 14 Dec 2018 03:34:49 -0500 (EST) |
branch: feature/gnus-select
commit 0160cc564b9be6e396f04cd077e230a5233226eb
Author: Paul Eggert <address@hidden>
Commit: Andrew G Cohen <address@hidden>
Avoid losing info when formatting integers
* doc/lispref/numbers.texi (Integer Basics): Clarify that
out-of-range integers are treated as floating point only when the
integers are decimal.
* etc/NEWS: Mention changes.
* src/editfns.c (styled_format): Use %.0f when formatting %d or %i
values outside machine integer range, to avoid losing info.
Signal an error for %o or %x values that are too large to be
formatted, to avoid losing info.
---
doc/lispref/numbers.texi | 5 ++-
etc/NEWS | 7 ++++
src/editfns.c | 96 +++++++++++++++++++++---------------------------
3 files changed, 51 insertions(+), 57 deletions(-)
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index e692ee1..f1180cf 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -53,8 +53,9 @@ but many machines provide a wider range. Many examples in
this
chapter assume the minimum integer width of 30 bits.
@cindex overflow
- The Lisp reader reads an integer as a sequence of digits with optional
-initial sign and optional final period. An integer that is out of the
+ The Lisp reader reads an integer as a nonempty sequence
+of decimal digits with optional initial sign and optional
+final period. A decimal integer that is out of the
Emacs range is treated as a floating-point number.
@example
diff --git a/etc/NEWS b/etc/NEWS
index e891789..3ef766b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -302,6 +302,10 @@ as new-style, bind the new variable
'force-new-style-backquotes' to t.
'cl-struct-define' whose name clashes with a builtin type (e.g.,
'integer' or 'hash-table') now signals an error.
+** When formatting a floating-point number as an octal or hexadecimal
+integer, Emacs now signals an error if the number is too large for the
+implementation to format (Bug#30408).
+
* Lisp Changes in Emacs 27.1
@@ -343,6 +347,9 @@ remote systems, which support this check.
If the optional third argument is non-nil, 'make-string' will produce
a multibyte string even if its second argument is an ASCII character.
+** (format "%d" X) no longer mishandles a floating-point number X that
+does not fit in a machine integer (Bug#30408).
+
** New JSON parsing and serialization functions 'json-serialize',
'json-insert', 'json-parse-string', and 'json-parse-buffer'. These
are implemented in C using the Jansson library.
diff --git a/src/editfns.c b/src/editfns.c
index 96bb271..3a34dd0 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -4563,32 +4563,30 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool
message)
and with pM inserted for integer formats.
At most two flags F can be specified at once. */
char convspec[sizeof "%FF.*d" + max (INT_AS_LDBL, pMlen)];
- {
- char *f = convspec;
- *f++ = '%';
- /* MINUS_FLAG and ZERO_FLAG are dealt with later. */
- *f = '+'; f += plus_flag;
- *f = ' '; f += space_flag;
- *f = '#'; f += sharp_flag;
- *f++ = '.';
- *f++ = '*';
- if (float_conversion)
- {
- if (INT_AS_LDBL)
- {
- *f = 'L';
- f += INTEGERP (arg);
- }
- }
- else if (conversion != 'c')
- {
- memcpy (f, pMd, pMlen);
- f += pMlen;
- zero_flag &= ! precision_given;
- }
- *f++ = conversion;
- *f = '\0';
- }
+ char *f = convspec;
+ *f++ = '%';
+ /* MINUS_FLAG and ZERO_FLAG are dealt with later. */
+ *f = '+'; f += plus_flag;
+ *f = ' '; f += space_flag;
+ *f = '#'; f += sharp_flag;
+ *f++ = '.';
+ *f++ = '*';
+ if (float_conversion)
+ {
+ if (INT_AS_LDBL)
+ {
+ *f = 'L';
+ f += INTEGERP (arg);
+ }
+ }
+ else if (conversion != 'c')
+ {
+ memcpy (f, pMd, pMlen);
+ f += pMlen;
+ zero_flag &= ! precision_given;
+ }
+ *f++ = conversion;
+ *f = '\0';
int prec = -1;
if (precision_given)
@@ -4630,29 +4628,20 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool
message)
}
else if (conversion == 'd' || conversion == 'i')
{
- /* For float, maybe we should use "%1.0f"
- instead so it also works for values outside
- the integer range. */
- printmax_t x;
if (INTEGERP (arg))
- x = XINT (arg);
+ {
+ printmax_t x = XINT (arg);
+ sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
+ }
else
{
- double d = XFLOAT_DATA (arg);
- if (d < 0)
- {
- x = TYPE_MINIMUM (printmax_t);
- if (x < d)
- x = d;
- }
- else
- {
- x = TYPE_MAXIMUM (printmax_t);
- if (d < x)
- x = d;
- }
+ strcpy (f - pMlen - 1, "f");
+ double x = XFLOAT_DATA (arg);
+ sprintf_bytes = sprintf (sprintf_buf, convspec, 0, x);
+ char c0 = sprintf_buf[0];
+ bool signedp = ! ('0' <= c0 && c0 <= '9');
+ prec = min (precision, sprintf_bytes - signedp);
}
- sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
}
else
{
@@ -4663,22 +4652,19 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool
message)
else
{
double d = XFLOAT_DATA (arg);
- if (d < 0)
- x = 0;
- else
- {
- x = TYPE_MAXIMUM (uprintmax_t);
- if (d < x)
- x = d;
- }
+ double uprintmax = TYPE_MAXIMUM (uprintmax_t);
+ if (! (0 <= d && d < uprintmax + 1))
+ xsignal1 (Qoverflow_error, arg);
+ x = d;
}
sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
}
/* Now the length of the formatted item is known, except it omits
padding and excess precision. Deal with excess precision
- first. This happens only when the format specifies
- ridiculously large precision. */
+ first. This happens when the format specifies ridiculously
+ large precision, or when %d or %i formats a float that would
+ ordinarily need fewer digits than a specified precision. */
ptrdiff_t excess_precision
= precision_given ? precision - prec : 0;
ptrdiff_t leading_zeros = 0, trailing_zeros = 0;
- [Emacs-diffs] feature/gnus-select 30510cf 026/218: Update from Gnulib, (continued)
- [Emacs-diffs] feature/gnus-select 30510cf 026/218: Update from Gnulib, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select c69a17d 025/218: * lisp/isearch.el (search-exit-option): Add option 'append'., Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 781d997 008/218: Replace some obsolete aliases in code, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 317b4d2 010/218: Fix display of TABs in hscrolled windows with line numbers, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select de2b09f 024/218: Add to "Completion Commands" Info node, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 4efd277 030/218: ; * lisp/org/org-table.el: Replace obsolete alias in comment., Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 52b1442 003/218: Revert last commit, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 1d6e562 021/218: More minor changes in the manual, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 954d7ce 035/218: * test/Makefile.in (check-declare): New PHONY rule., Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 036f0fe 032/218: Fix string-to-number C-level mishandling, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 0160cc5 029/218: Avoid losing info when formatting integers,
Andrew G Cohen <=
- [Emacs-diffs] feature/gnus-select 5276bca 052/218: Make transpose-regions interactive (Bug#30343), Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 5400223 062/218: * lisp/vc/vc-dir.el (vc-dir-unmark): Fix documentation., Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 71da4a5 063/218: ; * lisp/minibuffer.el (completion-cycle-threshold): Fix last change., Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select fbe22b5 014/218: Replace some obsolete aliases in code, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 46738e3 040/218: Improve SVG documentation, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select d25b161 042/218: Fix wrong behavior of 'outline-headers-as-kill' command (Bug#30209), Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 064037f 050/218: * lisp/simple.el (mark-whole-buffer): Clarify its behavior., Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 906b8fb 048/218: Port to NetBSD tzalloc, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select fd1f96f 060/218: Replace use of the obsolete write-contents-hooks, Andrew G Cohen, 2018/12/14
- [Emacs-diffs] feature/gnus-select 7f35e7d 055/218: Improve documentation of Xref, Andrew G Cohen, 2018/12/14