aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-08-29 12:14:47 -0700
committerPaul Eggert2011-08-29 12:14:47 -0700
commitaca216ff01bab0741e718036a3c6d887994904c6 (patch)
tree68a321d62dccfc5f6c8787ca176346c78c870266 /src
parenta66ff6d8b7f1ba4a8ef4d52f7d66b7804ba97091 (diff)
downloademacs-aca216ff01bab0741e718036a3c6d887994904c6.tar.gz
emacs-aca216ff01bab0741e718036a3c6d887994904c6.zip
* print.c (float_to_string): Detect width overflow more reliably.
(print_object): Make sprintf buffer a bit bigger, to avoid potential buffer overrun. Don't assume list length fits in 'int'. Treat print length of 0 as 0, not as infinity; to be consistent with other uses of print length in this function. Don't overflow print length index. Don't assume hash table size fits in 'long', or that vectorlike size fits in 'unsigned long'.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/print.c35
2 files changed, 27 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 362109acbe6..d1d11df1900 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -77,6 +77,14 @@
77 * nsterm.m ((NSSize)windowWillResize): Use esprintf, not sprintf, 77 * nsterm.m ((NSSize)windowWillResize): Use esprintf, not sprintf,
78 in case result does not fit in int. 78 in case result does not fit in int.
79 79
80 * print.c (float_to_string): Detect width overflow more reliably.
81 (print_object): Make sprintf buffer a bit bigger, to avoid potential
82 buffer overrun. Don't assume list length fits in 'int'. Treat
83 print length of 0 as 0, not as infinity; to be consistent with other
84 uses of print length in this function. Don't overflow print length
85 index. Don't assume hash table size fits in 'long', or that
86 vectorlike size fits in 'unsigned long'.
87
802011-08-26 Paul Eggert <eggert@cs.ucla.edu> 882011-08-26 Paul Eggert <eggert@cs.ucla.edu>
81 89
82 Integer and memory overflow issues (Bug#9196). 90 Integer and memory overflow issues (Bug#9196).
diff --git a/src/print.c b/src/print.c
index 35f89860843..f47dc985e96 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1016,12 +1016,15 @@ float_to_string (char *buf, double data)
1016 { 1016 {
1017 width = 0; 1017 width = 0;
1018 do 1018 do
1019 width = (width * 10) + (*cp++ - '0'); 1019 {
1020 width = (width * 10) + (*cp++ - '0');
1021 if (DBL_DIG < width)
1022 goto lose;
1023 }
1020 while (*cp >= '0' && *cp <= '9'); 1024 while (*cp >= '0' && *cp <= '9');
1021 1025
1022 /* A precision of zero is valid only for %f. */ 1026 /* A precision of zero is valid only for %f. */
1023 if (width > DBL_DIG 1027 if (width == 0 && *cp != 'f')
1024 || (width == 0 && *cp != 'f'))
1025 goto lose; 1028 goto lose;
1026 } 1029 }
1027 1030
@@ -1314,7 +1317,9 @@ print_prune_string_charset (Lisp_Object string)
1314static void 1317static void
1315print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag) 1318print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag)
1316{ 1319{
1317 char buf[40]; 1320 char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT),
1321 max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t),
1322 40))];
1318 1323
1319 QUIT; 1324 QUIT;
1320 1325
@@ -1614,8 +1619,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1614 PRINTCHAR ('('); 1619 PRINTCHAR ('(');
1615 1620
1616 { 1621 {
1617 EMACS_INT print_length; 1622 printmax_t i, print_length;
1618 int i;
1619 Lisp_Object halftail = obj; 1623 Lisp_Object halftail = obj;
1620 1624
1621 /* Negative values of print-length are invalid in CL. 1625 /* Negative values of print-length are invalid in CL.
@@ -1623,7 +1627,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1623 if (NATNUMP (Vprint_length)) 1627 if (NATNUMP (Vprint_length))
1624 print_length = XFASTINT (Vprint_length); 1628 print_length = XFASTINT (Vprint_length);
1625 else 1629 else
1626 print_length = 0; 1630 print_length = TYPE_MAXIMUM (printmax_t);
1627 1631
1628 i = 0; 1632 i = 0;
1629 while (CONSP (obj)) 1633 while (CONSP (obj))
@@ -1634,7 +1638,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1634 /* Simple but imcomplete way. */ 1638 /* Simple but imcomplete way. */
1635 if (i != 0 && EQ (obj, halftail)) 1639 if (i != 0 && EQ (obj, halftail))
1636 { 1640 {
1637 sprintf (buf, " . #%d", i / 2); 1641 sprintf (buf, " . #%"pMd, i / 2);
1638 strout (buf, -1, -1, printcharfun); 1642 strout (buf, -1, -1, printcharfun);
1639 goto end_of_list; 1643 goto end_of_list;
1640 } 1644 }
@@ -1654,15 +1658,16 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1654 } 1658 }
1655 } 1659 }
1656 1660
1657 if (i++) 1661 if (i)
1658 PRINTCHAR (' '); 1662 PRINTCHAR (' ');
1659 1663
1660 if (print_length && i > print_length) 1664 if (print_length <= i)
1661 { 1665 {
1662 strout ("...", 3, 3, printcharfun); 1666 strout ("...", 3, 3, printcharfun);
1663 goto end_of_list; 1667 goto end_of_list;
1664 } 1668 }
1665 1669
1670 i++;
1666 print_object (XCAR (obj), printcharfun, escapeflag); 1671 print_object (XCAR (obj), printcharfun, escapeflag);
1667 1672
1668 obj = XCDR (obj); 1673 obj = XCDR (obj);
@@ -1798,19 +1803,17 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
1798 PRINTCHAR (' '); 1803 PRINTCHAR (' ');
1799 strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun); 1804 strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun);
1800 PRINTCHAR (' '); 1805 PRINTCHAR (' ');
1801 sprintf (buf, "%ld/%ld", (long) h->count, 1806 sprintf (buf, "%"pI"d/%"pI"d", h->count, ASIZE (h->next));
1802 (long) ASIZE (h->next));
1803 strout (buf, -1, -1, printcharfun); 1807 strout (buf, -1, -1, printcharfun);
1804 } 1808 }
1805 sprintf (buf, " 0x%lx", (unsigned long) h); 1809 sprintf (buf, " %p", h);
1806 strout (buf, -1, -1, printcharfun); 1810 strout (buf, -1, -1, printcharfun);
1807 PRINTCHAR ('>'); 1811 PRINTCHAR ('>');
1808#endif 1812#endif
1809 /* Implement a readable output, e.g.: 1813 /* Implement a readable output, e.g.:
1810 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ 1814 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */
1811 /* Always print the size. */ 1815 /* Always print the size. */
1812 sprintf (buf, "#s(hash-table size %ld", 1816 sprintf (buf, "#s(hash-table size %"pI"d", ASIZE (h->next));
1813 (long) ASIZE (h->next));
1814 strout (buf, -1, -1, printcharfun); 1817 strout (buf, -1, -1, printcharfun);
1815 1818
1816 if (!NILP (h->test)) 1819 if (!NILP (h->test))
@@ -2038,7 +2041,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag
2038 if (MISCP (obj)) 2041 if (MISCP (obj))
2039 sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj)); 2042 sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj));
2040 else if (VECTORLIKEP (obj)) 2043 else if (VECTORLIKEP (obj))
2041 sprintf (buf, "(PVEC 0x%08lx)", (unsigned long) ASIZE (obj)); 2044 sprintf (buf, "(PVEC 0x%08"pI"x)", ASIZE (obj));
2042 else 2045 else
2043 sprintf (buf, "(0x%02x)", (int) XTYPE (obj)); 2046 sprintf (buf, "(0x%02x)", (int) XTYPE (obj));
2044 strout (buf, -1, -1, printcharfun); 2047 strout (buf, -1, -1, printcharfun);