aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
authorPaul Eggert2011-05-27 12:37:32 -0700
committerPaul Eggert2011-05-27 12:37:32 -0700
commit0f6990a78ae5016d8ae73253cdb4739adf0197e7 (patch)
tree78c7860e14d7cf6bc73526174493a02e606dfc13 /src/editfns.c
parentfb1ac845caea7da6ba98b93c3d67fa67c651b8ef (diff)
parentb57f7e0a357aacf98ec5be826f7227f37e9806b8 (diff)
downloademacs-0f6990a78ae5016d8ae73253cdb4739adf0197e7.tar.gz
emacs-0f6990a78ae5016d8ae73253cdb4739adf0197e7.zip
Merge: Integer overflow fixes.
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c911
1 files changed, 528 insertions, 383 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 881e0c7f3e2..8b48355fbfa 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -45,9 +45,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
45#endif 45#endif
46 46
47#include <ctype.h> 47#include <ctype.h>
48#include <float.h>
48#include <limits.h> 49#include <limits.h>
49#include <intprops.h> 50#include <intprops.h>
50#include <strftime.h> 51#include <strftime.h>
52#include <verify.h>
51 53
52#include "intervals.h" 54#include "intervals.h"
53#include "buffer.h" 55#include "buffer.h"
@@ -57,13 +59,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
57#include "window.h" 59#include "window.h"
58#include "blockinput.h" 60#include "blockinput.h"
59 61
60#ifdef STDC_HEADERS
61#include <float.h>
62#define MAX_10_EXP DBL_MAX_10_EXP
63#else
64#define MAX_10_EXP 310
65#endif
66
67#ifndef NULL 62#ifndef NULL
68#define NULL 0 63#define NULL 0
69#endif 64#endif
@@ -3525,14 +3520,21 @@ usage: (propertize STRING &rest PROPERTIES) */)
3525 RETURN_UNGCPRO (string); 3520 RETURN_UNGCPRO (string);
3526} 3521}
3527 3522
3528 3523/* pWIDE is a conversion for printing large decimal integers (possibly with a
3529/* Number of bytes that STRING will occupy when put into the result. 3524 trailing "d" that is ignored). pWIDElen is its length. signed_wide and
3530 MULTIBYTE is nonzero if the result should be multibyte. */ 3525 unsigned_wide are signed and unsigned types for printing them. Use widest
3531 3526 integers if available so that more floating point values can be converted. */
3532#define CONVERTED_BYTE_SIZE(MULTIBYTE, STRING) \ 3527#ifdef PRIdMAX
3533 (((MULTIBYTE) && ! STRING_MULTIBYTE (STRING)) \ 3528# define pWIDE PRIdMAX
3534 ? count_size_as_multibyte (SDATA (STRING), SBYTES (STRING)) \ 3529enum { pWIDElen = sizeof PRIdMAX - 2 }; /* Don't count trailing "d". */
3535 : SBYTES (STRING)) 3530typedef intmax_t signed_wide;
3531typedef uintmax_t unsigned_wide;
3532#else
3533# define pWIDE pI
3534enum { pWIDElen = sizeof pI - 1 };
3535typedef EMACS_INT signed_wide;
3536typedef EMACS_UINT unsigned_wide;
3537#endif
3536 3538
3537DEFUN ("format", Fformat, Sformat, 1, MANY, 0, 3539DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
3538 doc: /* Format a string out of a format-string and arguments. 3540 doc: /* Format a string out of a format-string and arguments.
@@ -3583,11 +3585,17 @@ specifier truncates the string to the given width.
3583usage: (format STRING &rest OBJECTS) */) 3585usage: (format STRING &rest OBJECTS) */)
3584 (size_t nargs, register Lisp_Object *args) 3586 (size_t nargs, register Lisp_Object *args)
3585{ 3587{
3586 register size_t n; /* The number of the next arg to substitute */ 3588 EMACS_INT n; /* The number of the next arg to substitute */
3587 register size_t total; /* An estimate of the final length */ 3589 char initial_buffer[4000];
3588 char *buf, *p; 3590 char *buf = initial_buffer;
3591 EMACS_INT bufsize = sizeof initial_buffer;
3592 EMACS_INT max_bufsize = min (MOST_POSITIVE_FIXNUM + 1, SIZE_MAX);
3593 char *p;
3594 Lisp_Object buf_save_value IF_LINT (= {0});
3589 register char *format, *end, *format_start; 3595 register char *format, *end, *format_start;
3590 int nchars; 3596 EMACS_INT formatlen, nchars;
3597 /* Nonzero if the format is multibyte. */
3598 int multibyte_format = 0;
3591 /* Nonzero if the output should be a multibyte string, 3599 /* Nonzero if the output should be a multibyte string,
3592 which is true if any of the inputs is one. */ 3600 which is true if any of the inputs is one. */
3593 int multibyte = 0; 3601 int multibyte = 0;
@@ -3596,14 +3604,6 @@ usage: (format STRING &rest OBJECTS) */)
3596 multibyte character of the previous string. This flag tells if we 3604 multibyte character of the previous string. This flag tells if we
3597 must consider such a situation or not. */ 3605 must consider such a situation or not. */
3598 int maybe_combine_byte; 3606 int maybe_combine_byte;
3599 char *this_format;
3600 /* Precision for each spec, or -1, a flag value meaning no precision
3601 was given in that spec. Element 0, corresponding to the format
3602 string itself, will not be used. Element NARGS, corresponding to
3603 no argument, *will* be assigned to in the case that a `%' and `.'
3604 occur after the final format specifier. */
3605 int *precision = (int *) (alloca ((nargs + 1) * sizeof (int)));
3606 int longest_format;
3607 Lisp_Object val; 3607 Lisp_Object val;
3608 int arg_intervals = 0; 3608 int arg_intervals = 0;
3609 USE_SAFE_ALLOCA; 3609 USE_SAFE_ALLOCA;
@@ -3611,458 +3611,603 @@ usage: (format STRING &rest OBJECTS) */)
3611 /* discarded[I] is 1 if byte I of the format 3611 /* discarded[I] is 1 if byte I of the format
3612 string was not copied into the output. 3612 string was not copied into the output.
3613 It is 2 if byte I was not the first byte of its character. */ 3613 It is 2 if byte I was not the first byte of its character. */
3614 char *discarded = 0; 3614 char *discarded;
3615 3615
3616 /* Each element records, for one argument, 3616 /* Each element records, for one argument,
3617 the start and end bytepos in the output string, 3617 the start and end bytepos in the output string,
3618 whether the argument has been converted to string (e.g., due to "%S"),
3618 and whether the argument is a string with intervals. 3619 and whether the argument is a string with intervals.
3619 info[0] is unused. Unused elements have -1 for start. */ 3620 info[0] is unused. Unused elements have -1 for start. */
3620 struct info 3621 struct info
3621 { 3622 {
3622 int start, end, intervals; 3623 EMACS_INT start, end;
3624 int converted_to_string;
3625 int intervals;
3623 } *info = 0; 3626 } *info = 0;
3624 3627
3625 /* It should not be necessary to GCPRO ARGS, because 3628 /* It should not be necessary to GCPRO ARGS, because
3626 the caller in the interpreter should take care of that. */ 3629 the caller in the interpreter should take care of that. */
3627 3630
3631 CHECK_STRING (args[0]);
3632 format_start = SSDATA (args[0]);
3633 formatlen = SBYTES (args[0]);
3634
3635 /* Allocate the info and discarded tables. */
3636 {
3637 EMACS_INT i;
3638 if ((SIZE_MAX - formatlen) / sizeof (struct info) <= nargs)
3639 memory_full ();
3640 SAFE_ALLOCA (info, struct info *, (nargs + 1) * sizeof *info + formatlen);
3641 discarded = (char *) &info[nargs + 1];
3642 for (i = 0; i < nargs + 1; i++)
3643 {
3644 info[i].start = -1;
3645 info[i].intervals = info[i].converted_to_string = 0;
3646 }
3647 memset (discarded, 0, formatlen);
3648 }
3649
3628 /* Try to determine whether the result should be multibyte. 3650 /* Try to determine whether the result should be multibyte.
3629 This is not always right; sometimes the result needs to be multibyte 3651 This is not always right; sometimes the result needs to be multibyte
3630 because of an object that we will pass through prin1, 3652 because of an object that we will pass through prin1,
3631 and in that case, we won't know it here. */ 3653 and in that case, we won't know it here. */
3632 for (n = 0; n < nargs; n++) 3654 multibyte_format = STRING_MULTIBYTE (args[0]);
3633 { 3655 multibyte = multibyte_format;
3634 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n])) 3656 for (n = 1; !multibyte && n < nargs; n++)
3635 multibyte = 1; 3657 if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n]))
3636 /* Piggyback on this loop to initialize precision[N]. */ 3658 multibyte = 1;
3637 precision[n] = -1;
3638 }
3639 precision[nargs] = -1;
3640
3641 CHECK_STRING (args[0]);
3642 /* We may have to change "%S" to "%s". */
3643 args[0] = Fcopy_sequence (args[0]);
3644
3645 /* GC should never happen here, so abort if it does. */
3646 abort_on_gc++;
3647 3659
3648 /* If we start out planning a unibyte result, 3660 /* If we start out planning a unibyte result,
3649 then discover it has to be multibyte, we jump back to retry. 3661 then discover it has to be multibyte, we jump back to retry. */
3650 That can only happen from the first large while loop below. */
3651 retry: 3662 retry:
3652 3663
3653 format = SSDATA (args[0]); 3664 p = buf;
3654 format_start = format; 3665 nchars = 0;
3655 end = format + SBYTES (args[0]); 3666 n = 0;
3656 longest_format = 0;
3657
3658 /* Make room in result for all the non-%-codes in the control string. */
3659 total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]) + 1;
3660
3661 /* Allocate the info and discarded tables. */
3662 {
3663 size_t nbytes = (nargs+1) * sizeof *info;
3664 size_t i;
3665 if (!info)
3666 info = (struct info *) alloca (nbytes);
3667 memset (info, 0, nbytes);
3668 for (i = 0; i < nargs + 1; i++)
3669 info[i].start = -1;
3670 if (!discarded)
3671 SAFE_ALLOCA (discarded, char *, SBYTES (args[0]));
3672 memset (discarded, 0, SBYTES (args[0]));
3673 }
3674 3667
3675 /* Add to TOTAL enough space to hold the converted arguments. */ 3668 /* Scan the format and store result in BUF. */
3669 format = format_start;
3670 end = format + formatlen;
3671 maybe_combine_byte = 0;
3676 3672
3677 n = 0;
3678 while (format != end) 3673 while (format != end)
3679 if (*format++ == '%') 3674 {
3680 { 3675 /* The values of N and FORMAT when the loop body is entered. */
3681 EMACS_INT thissize = 0; 3676 EMACS_INT n0 = n;
3682 EMACS_INT actual_width = 0; 3677 char *format0 = format;
3683 char *this_format_start = format - 1;
3684 int field_width = 0;
3685 3678
3686 /* General format specifications look like 3679 /* Bytes needed to represent the output of this conversion. */
3680 EMACS_INT convbytes;
3687 3681
3688 '%' [flags] [field-width] [precision] format 3682 if (*format == '%')
3683 {
3684 /* General format specifications look like
3689 3685
3690 where 3686 '%' [flags] [field-width] [precision] format
3691 3687
3692 flags ::= [-+ #0]+ 3688 where
3693 field-width ::= [0-9]+
3694 precision ::= '.' [0-9]*
3695 3689
3696 If a field-width is specified, it specifies to which width 3690 flags ::= [-+0# ]+
3697 the output should be padded with blanks, if the output 3691 field-width ::= [0-9]+
3698 string is shorter than field-width. 3692 precision ::= '.' [0-9]*
3699 3693
3700 If precision is specified, it specifies the number of 3694 If a field-width is specified, it specifies to which width
3701 digits to print after the '.' for floats, or the max. 3695 the output should be padded with blanks, if the output
3702 number of chars to print from a string. */ 3696 string is shorter than field-width.
3703 3697
3704 while (format != end 3698 If precision is specified, it specifies the number of
3705 && (*format == '-' || *format == '0' || *format == '#' 3699 digits to print after the '.' for floats, or the max.
3706 || * format == ' ' || *format == '+')) 3700 number of chars to print from a string. */
3707 ++format;
3708 3701
3709 if (*format >= '0' && *format <= '9') 3702 int minus_flag = 0;
3710 { 3703 int plus_flag = 0;
3711 for (field_width = 0; *format >= '0' && *format <= '9'; ++format) 3704 int space_flag = 0;
3712 field_width = 10 * field_width + *format - '0'; 3705 int sharp_flag = 0;
3713 } 3706 int zero_flag = 0;
3707 EMACS_INT field_width;
3708 int precision_given;
3709 uintmax_t precision = UINTMAX_MAX;
3710 char *num_end;
3711 char conversion;
3714 3712
3715 /* N is not incremented for another few lines below, so refer to 3713 while (1)
3716 element N+1 (which might be precision[NARGS]). */ 3714 {
3717 if (*format == '.') 3715 switch (*++format)
3718 { 3716 {
3719 ++format; 3717 case '-': minus_flag = 1; continue;
3720 for (precision[n+1] = 0; *format >= '0' && *format <= '9'; ++format) 3718 case '+': plus_flag = 1; continue;
3721 precision[n+1] = 10 * precision[n+1] + *format - '0'; 3719 case ' ': space_flag = 1; continue;
3722 } 3720 case '#': sharp_flag = 1; continue;
3721 case '0': zero_flag = 1; continue;
3722 }
3723 break;
3724 }
3723 3725
3724 /* Extra +1 for 'l' that we may need to insert into the 3726 /* Ignore flags when sprintf ignores them. */
3725 format. */ 3727 space_flag &= ~ plus_flag;
3726 if (format - this_format_start + 2 > longest_format) 3728 zero_flag &= ~ minus_flag;
3727 longest_format = format - this_format_start + 2;
3728 3729
3729 if (format == end)
3730 error ("Format string ends in middle of format specifier");
3731 if (*format == '%')
3732 format++;
3733 else if (++n >= nargs)
3734 error ("Not enough arguments for format string");
3735 else if (*format == 'S')
3736 { 3730 {
3737 /* For `S', prin1 the argument and then treat like a string. */ 3731 uintmax_t w = strtoumax (format, &num_end, 10);
3738 register Lisp_Object tem; 3732 if (max_bufsize <= w)
3739 tem = Fprin1_to_string (args[n], Qnil); 3733 string_overflow ();
3740 if (STRING_MULTIBYTE (tem) && ! multibyte) 3734 field_width = w;
3741 {
3742 multibyte = 1;
3743 goto retry;
3744 }
3745 args[n] = tem;
3746 /* If we restart the loop, we should not come here again
3747 because args[n] is now a string and calling
3748 Fprin1_to_string on it produces superflous double
3749 quotes. So, change "%S" to "%s" now. */
3750 *format = 's';
3751 goto string;
3752 } 3735 }
3753 else if (SYMBOLP (args[n])) 3736 precision_given = *num_end == '.';
3754 { 3737 if (precision_given)
3755 args[n] = SYMBOL_NAME (args[n]); 3738 precision = strtoumax (num_end + 1, &num_end, 10);
3756 if (STRING_MULTIBYTE (args[n]) && ! multibyte) 3739 format = num_end;
3757 { 3740
3758 multibyte = 1; 3741 if (format == end)
3759 goto retry; 3742 error ("Format string ends in middle of format specifier");
3760 } 3743
3761 goto string; 3744 memset (&discarded[format0 - format_start], 1, format - format0);
3762 } 3745 conversion = *format;
3763 else if (STRINGP (args[n])) 3746 if (conversion == '%')
3764 { 3747 goto copy_char;
3765 string:
3766 if (*format != 's' && *format != 'S')
3767 error ("Format specifier doesn't match argument type");
3768 /* In the case (PRECISION[N] > 0), THISSIZE may not need
3769 to be as large as is calculated here. Easy check for
3770 the case PRECISION = 0. */
3771 thissize = precision[n] ? CONVERTED_BYTE_SIZE (multibyte, args[n]) : 0;
3772 /* The precision also constrains how much of the argument
3773 string will finally appear (Bug#5710). */
3774 actual_width = lisp_string_width (args[n], -1, NULL, NULL);
3775 if (precision[n] != -1)
3776 actual_width = min (actual_width, precision[n]);
3777 }
3778 /* Would get MPV otherwise, since Lisp_Int's `point' to low memory. */
3779 else if (INTEGERP (args[n]) && *format != 's')
3780 {
3781 /* The following loop assumes the Lisp type indicates
3782 the proper way to pass the argument.
3783 So make sure we have a flonum if the argument should
3784 be a double. */
3785 if (*format == 'e' || *format == 'f' || *format == 'g')
3786 args[n] = Ffloat (args[n]);
3787 else
3788 if (*format != 'd' && *format != 'o' && *format != 'x'
3789 && *format != 'i' && *format != 'X' && *format != 'c')
3790 error ("Invalid format operation %%%c", *format);
3791
3792 thissize = 30 + (precision[n] > 0 ? precision[n] : 0);
3793 if (*format == 'c')
3794 {
3795 if (! ASCII_CHAR_P (XINT (args[n]))
3796 /* Note: No one can remember why we have to treat
3797 the character 0 as a multibyte character here.
3798 But, until it causes a real problem, let's
3799 don't change it. */
3800 || XINT (args[n]) == 0)
3801 {
3802 if (! multibyte)
3803 {
3804 multibyte = 1;
3805 goto retry;
3806 }
3807 args[n] = Fchar_to_string (args[n]);
3808 thissize = SBYTES (args[n]);
3809 }
3810 }
3811 }
3812 else if (FLOATP (args[n]) && *format != 's')
3813 {
3814 if (! (*format == 'e' || *format == 'f' || *format == 'g'))
3815 {
3816 if (*format != 'd' && *format != 'o' && *format != 'x'
3817 && *format != 'i' && *format != 'X' && *format != 'c')
3818 error ("Invalid format operation %%%c", *format);
3819 /* This fails unnecessarily if args[n] is bigger than
3820 most-positive-fixnum but smaller than MAXINT.
3821 These cases are important because we sometimes use floats
3822 to represent such integer values (typically such values
3823 come from UIDs or PIDs). */
3824 /* args[n] = Ftruncate (args[n], Qnil); */
3825 }
3826
3827 /* Note that we're using sprintf to print floats,
3828 so we have to take into account what that function
3829 prints. */
3830 /* Filter out flag value of -1. */
3831 thissize = (MAX_10_EXP + 100
3832 + (precision[n] > 0 ? precision[n] : 0));
3833 }
3834 else
3835 {
3836 /* Anything but a string, convert to a string using princ. */
3837 register Lisp_Object tem;
3838 tem = Fprin1_to_string (args[n], Qt);
3839 if (STRING_MULTIBYTE (tem) && ! multibyte)
3840 {
3841 multibyte = 1;
3842 goto retry;
3843 }
3844 args[n] = tem;
3845 goto string;
3846 }
3847
3848 thissize += max (0, field_width - actual_width);
3849 total += thissize + 4;
3850 }
3851
3852 abort_on_gc--;
3853
3854 /* Now we can no longer jump to retry.
3855 TOTAL and LONGEST_FORMAT are known for certain. */
3856
3857 this_format = (char *) alloca (longest_format + 1);
3858
3859 /* Allocate the space for the result.
3860 Note that TOTAL is an overestimate. */
3861 SAFE_ALLOCA (buf, char *, total);
3862
3863 p = buf;
3864 nchars = 0;
3865 n = 0;
3866
3867 /* Scan the format and store result in BUF. */
3868 format = SSDATA (args[0]);
3869 format_start = format;
3870 end = format + SBYTES (args[0]);
3871 maybe_combine_byte = 0;
3872 while (format != end)
3873 {
3874 if (*format == '%')
3875 {
3876 int minlen;
3877 int negative = 0;
3878 char *this_format_start = format;
3879
3880 discarded[format - format_start] = 1; 3748 discarded[format - format_start] = 1;
3881 format++; 3749 format++;
3882 3750
3883 while (strchr ("-+0# ", *format)) 3751 ++n;
3752 if (! (n < nargs))
3753 error ("Not enough arguments for format string");
3754
3755 /* For 'S', prin1 the argument, and then treat like 's'.
3756 For 's', princ any argument that is not a string or
3757 symbol. But don't do this conversion twice, which might
3758 happen after retrying. */
3759 if ((conversion == 'S'
3760 || (conversion == 's'
3761 && ! STRINGP (args[n]) && ! SYMBOLP (args[n]))))
3884 { 3762 {
3885 if (*format == '-') 3763 if (! info[n].converted_to_string)
3886 { 3764 {
3887 negative = 1; 3765 Lisp_Object noescape = conversion == 'S' ? Qnil : Qt;
3766 args[n] = Fprin1_to_string (args[n], noescape);
3767 info[n].converted_to_string = 1;
3768 if (STRING_MULTIBYTE (args[n]) && ! multibyte)
3769 {
3770 multibyte = 1;
3771 goto retry;
3772 }
3888 } 3773 }
3889 discarded[format - format_start] = 1; 3774 conversion = 's';
3890 ++format;
3891 } 3775 }
3776 else if (conversion == 'c')
3777 {
3778 if (FLOATP (args[n]))
3779 {
3780 double d = XFLOAT_DATA (args[n]);
3781 args[n] = make_number (FIXNUM_OVERFLOW_P (d) ? -1 : d);
3782 }
3892 3783
3893 minlen = atoi (format); 3784 if (INTEGERP (args[n]) && ! ASCII_CHAR_P (XINT (args[n])))
3785 {
3786 if (!multibyte)
3787 {
3788 multibyte = 1;
3789 goto retry;
3790 }
3791 args[n] = Fchar_to_string (args[n]);
3792 info[n].converted_to_string = 1;
3793 }
3894 3794
3895 while ((*format >= '0' && *format <= '9') || *format == '.') 3795 if (info[n].converted_to_string)
3896 { 3796 conversion = 's';
3897 discarded[format - format_start] = 1; 3797 zero_flag = 0;
3898 format++;
3899 } 3798 }
3900 3799
3901 if (*format++ == '%') 3800 if (SYMBOLP (args[n]))
3902 { 3801 {
3903 *p++ = '%'; 3802 args[n] = SYMBOL_NAME (args[n]);
3904 nchars++; 3803 if (STRING_MULTIBYTE (args[n]) && ! multibyte)
3905 continue; 3804 {
3805 multibyte = 1;
3806 goto retry;
3807 }
3906 } 3808 }
3907 3809
3908 ++n; 3810 if (conversion == 's')
3909
3910 discarded[format - format_start - 1] = 1;
3911 info[n].start = nchars;
3912
3913 if (STRINGP (args[n]))
3914 { 3811 {
3915 /* handle case (precision[n] >= 0) */ 3812 /* handle case (precision[n] >= 0) */
3916 3813
3917 int width, padding; 3814 EMACS_INT width, padding, nbytes;
3918 EMACS_INT nbytes, start;
3919 EMACS_INT nchars_string; 3815 EMACS_INT nchars_string;
3920 3816
3817 EMACS_INT prec = -1;
3818 if (precision_given && precision <= TYPE_MAXIMUM (EMACS_INT))
3819 prec = precision;
3820
3921 /* lisp_string_width ignores a precision of 0, but GNU 3821 /* lisp_string_width ignores a precision of 0, but GNU
3922 libc functions print 0 characters when the precision 3822 libc functions print 0 characters when the precision
3923 is 0. Imitate libc behavior here. Changing 3823 is 0. Imitate libc behavior here. Changing
3924 lisp_string_width is the right thing, and will be 3824 lisp_string_width is the right thing, and will be
3925 done, but meanwhile we work with it. */ 3825 done, but meanwhile we work with it. */
3926 3826
3927 if (precision[n] == 0) 3827 if (prec == 0)
3928 width = nchars_string = nbytes = 0; 3828 width = nchars_string = nbytes = 0;
3929 else if (precision[n] > 0)
3930 width = lisp_string_width (args[n], precision[n],
3931 &nchars_string, &nbytes);
3932 else 3829 else
3933 { /* no precision spec given for this argument */ 3830 {
3934 width = lisp_string_width (args[n], -1, NULL, NULL); 3831 EMACS_INT nch, nby;
3935 nbytes = SBYTES (args[n]); 3832 width = lisp_string_width (args[n], prec, &nch, &nby);
3936 nchars_string = SCHARS (args[n]); 3833 if (prec < 0)
3834 {
3835 nchars_string = SCHARS (args[n]);
3836 nbytes = SBYTES (args[n]);
3837 }
3838 else
3839 {
3840 nchars_string = nch;
3841 nbytes = nby;
3842 }
3937 } 3843 }
3938 3844
3939 /* If spec requires it, pad on right with spaces. */ 3845 convbytes = nbytes;
3940 padding = minlen - width; 3846 if (convbytes && multibyte && ! STRING_MULTIBYTE (args[n]))
3941 if (! negative) 3847 convbytes = count_size_as_multibyte (SDATA (args[n]), nbytes);
3942 while (padding-- > 0)
3943 {
3944 *p++ = ' ';
3945 ++nchars;
3946 }
3947 3848
3948 info[n].start = start = nchars; 3849 padding = width < field_width ? field_width - width : 0;
3949 nchars += nchars_string;
3950 3850
3951 if (p > buf 3851 if (max_bufsize - padding <= convbytes)
3952 && multibyte 3852 string_overflow ();
3953 && !ASCII_BYTE_P (*((unsigned char *) p - 1)) 3853 convbytes += padding;
3954 && STRING_MULTIBYTE (args[n]) 3854 if (convbytes <= buf + bufsize - p)
3955 && !CHAR_HEAD_P (SREF (args[n], 0))) 3855 {
3956 maybe_combine_byte = 1; 3856 if (! minus_flag)
3857 {
3858 memset (p, ' ', padding);
3859 p += padding;
3860 nchars += padding;
3861 }
3957 3862
3958 p += copy_text (SDATA (args[n]), (unsigned char *) p, 3863 if (p > buf
3959 nbytes, 3864 && multibyte
3960 STRING_MULTIBYTE (args[n]), multibyte); 3865 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
3866 && STRING_MULTIBYTE (args[n])
3867 && !CHAR_HEAD_P (SREF (args[n], 0)))
3868 maybe_combine_byte = 1;
3961 3869
3962 info[n].end = nchars; 3870 p += copy_text (SDATA (args[n]), (unsigned char *) p,
3871 nbytes,
3872 STRING_MULTIBYTE (args[n]), multibyte);
3963 3873
3964 if (negative) 3874 info[n].start = nchars;
3965 while (padding-- > 0) 3875 nchars += nchars_string;
3966 { 3876 info[n].end = nchars;
3967 *p++ = ' ';
3968 nchars++;
3969 }
3970 3877
3971 /* If this argument has text properties, record where 3878 if (minus_flag)
3972 in the result string it appears. */ 3879 {
3973 if (STRING_INTERVALS (args[n])) 3880 memset (p, ' ', padding);
3974 info[n].intervals = arg_intervals = 1; 3881 p += padding;
3882 nchars += padding;
3883 }
3884
3885 /* If this argument has text properties, record where
3886 in the result string it appears. */
3887 if (STRING_INTERVALS (args[n]))
3888 info[n].intervals = arg_intervals = 1;
3889
3890 continue;
3891 }
3975 } 3892 }
3976 else if (INTEGERP (args[n]) || FLOATP (args[n])) 3893 else if (! (conversion == 'c' || conversion == 'd'
3894 || conversion == 'e' || conversion == 'f'
3895 || conversion == 'g' || conversion == 'i'
3896 || conversion == 'o' || conversion == 'x'
3897 || conversion == 'X'))
3898 error ("Invalid format operation %%%c",
3899 STRING_CHAR ((unsigned char *) format - 1));
3900 else if (! (INTEGERP (args[n]) || FLOATP (args[n])))
3901 error ("Format specifier doesn't match argument type");
3902 else
3977 { 3903 {
3978 int this_nchars; 3904 enum
3979 3905 {
3980 memcpy (this_format, this_format_start, 3906 /* Maximum precision for a %f conversion such that the
3981 format - this_format_start); 3907 trailing output digit might be nonzero. Any precisions
3982 this_format[format - this_format_start] = 0; 3908 larger than this will not yield useful information. */
3909 USEFUL_PRECISION_MAX =
3910 ((1 - DBL_MIN_EXP)
3911 * (FLT_RADIX == 2 || FLT_RADIX == 10 ? 1
3912 : FLT_RADIX == 16 ? 4
3913 : -1)),
3914
3915 /* Maximum number of bytes generated by any format, if
3916 precision is no more than DBL_USEFUL_PRECISION_MAX.
3917 On all practical hosts, %f is the worst case. */
3918 SPRINTF_BUFSIZE =
3919 sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX
3920 };
3921 verify (0 < USEFUL_PRECISION_MAX);
3922
3923 int prec;
3924 EMACS_INT padding, sprintf_bytes;
3925 uintmax_t excess_precision, numwidth;
3926 uintmax_t leading_zeros = 0, trailing_zeros = 0;
3927
3928 char sprintf_buf[SPRINTF_BUFSIZE];
3929
3930 /* Copy of conversion specification, modified somewhat.
3931 At most three flags F can be specified at once. */
3932 char convspec[sizeof "%FFF.*d" + pWIDElen];
3933
3934 /* Avoid undefined behavior in underlying sprintf. */
3935 if (conversion == 'd' || conversion == 'i')
3936 sharp_flag = 0;
3937
3938 /* Create the copy of the conversion specification, with
3939 any width and precision removed, with ".*" inserted,
3940 and with pWIDE inserted for integer formats. */
3941 {
3942 char *f = convspec;
3943 *f++ = '%';
3944 *f = '-'; f += minus_flag;
3945 *f = '+'; f += plus_flag;
3946 *f = ' '; f += space_flag;
3947 *f = '#'; f += sharp_flag;
3948 *f = '0'; f += zero_flag;
3949 *f++ = '.';
3950 *f++ = '*';
3951 if (conversion == 'd' || conversion == 'i'
3952 || conversion == 'o' || conversion == 'x'
3953 || conversion == 'X')
3954 {
3955 memcpy (f, pWIDE, pWIDElen);
3956 f += pWIDElen;
3957 zero_flag &= ~ precision_given;
3958 }
3959 *f++ = conversion;
3960 *f = '\0';
3961 }
3983 3962
3984 if (format[-1] == 'e' || format[-1] == 'f' || format[-1] == 'g') 3963 prec = -1;
3985 sprintf (p, this_format, XFLOAT_DATA (args[n])); 3964 if (precision_given)
3965 prec = min (precision, USEFUL_PRECISION_MAX);
3966
3967 /* Use sprintf to format this number into sprintf_buf. Omit
3968 padding and excess precision, though, because sprintf limits
3969 output length to INT_MAX.
3970
3971 There are four types of conversion: double, unsigned
3972 char (passed as int), wide signed int, and wide
3973 unsigned int. Treat them separately because the
3974 sprintf ABI is sensitive to which type is passed. Be
3975 careful about integer overflow, NaNs, infinities, and
3976 conversions; for example, the min and max macros are
3977 not suitable here. */
3978 if (conversion == 'e' || conversion == 'f' || conversion == 'g')
3979 {
3980 double x = (INTEGERP (args[n])
3981 ? XINT (args[n])
3982 : XFLOAT_DATA (args[n]));
3983 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
3984 }
3985 else if (conversion == 'c')
3986 {
3987 /* Don't use sprintf here, as it might mishandle prec. */
3988 sprintf_buf[0] = XINT (args[n]);
3989 sprintf_bytes = prec != 0;
3990 }
3991 else if (conversion == 'd')
3992 {
3993 /* For float, maybe we should use "%1.0f"
3994 instead so it also works for values outside
3995 the integer range. */
3996 signed_wide x;
3997 if (INTEGERP (args[n]))
3998 x = XINT (args[n]);
3999 else
4000 {
4001 double d = XFLOAT_DATA (args[n]);
4002 if (d < 0)
4003 {
4004 x = TYPE_MINIMUM (signed_wide);
4005 if (x < d)
4006 x = d;
4007 }
4008 else
4009 {
4010 x = TYPE_MAXIMUM (signed_wide);
4011 if (d < x)
4012 x = d;
4013 }
4014 }
4015 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
4016 }
3986 else 4017 else
3987 { 4018 {
3988 if (sizeof (EMACS_INT) > sizeof (int) 4019 /* Don't sign-extend for octal or hex printing. */
3989 && format[-1] != 'c') 4020 unsigned_wide x;
4021 if (INTEGERP (args[n]))
4022 x = XUINT (args[n]);
4023 else
3990 { 4024 {
3991 /* Insert 'l' before format spec. */ 4025 double d = XFLOAT_DATA (args[n]);
3992 this_format[format - this_format_start] 4026 if (d < 0)
3993 = this_format[format - this_format_start - 1]; 4027 x = 0;
3994 this_format[format - this_format_start - 1] = 'l'; 4028 else
3995 this_format[format - this_format_start + 1] = 0; 4029 {
4030 x = TYPE_MAXIMUM (unsigned_wide);
4031 if (d < x)
4032 x = d;
4033 }
3996 } 4034 }
4035 sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);
4036 }
3997 4037
3998 if (INTEGERP (args[n])) 4038 /* Now the length of the formatted item is known, except it omits
4039 padding and excess precision. Deal with excess precision
4040 first. This happens only when the format specifies
4041 ridiculously large precision. */
4042 excess_precision = precision - prec;
4043 if (excess_precision)
4044 {
4045 if (conversion == 'e' || conversion == 'f'
4046 || conversion == 'g')
3999 { 4047 {
4000 if (format[-1] == 'c') 4048 if ((conversion == 'g' && ! sharp_flag)
4001 sprintf (p, this_format, (int) XINT (args[n])); 4049 || ! ('0' <= sprintf_buf[sprintf_bytes - 1]
4002 else if (format[-1] == 'd') 4050 && sprintf_buf[sprintf_bytes - 1] <= '9'))
4003 sprintf (p, this_format, XINT (args[n])); 4051 excess_precision = 0;
4004 /* Don't sign-extend for octal or hex printing. */
4005 else 4052 else
4006 sprintf (p, this_format, XUINT (args[n])); 4053 {
4054 if (conversion == 'g')
4055 {
4056 char *dot = strchr (sprintf_buf, '.');
4057 if (!dot)
4058 excess_precision = 0;
4059 }
4060 }
4061 trailing_zeros = excess_precision;
4007 } 4062 }
4008 else if (format[-1] == 'c')
4009 sprintf (p, this_format, (int) XFLOAT_DATA (args[n]));
4010 else if (format[-1] == 'd')
4011 /* Maybe we should use "%1.0f" instead so it also works
4012 for values larger than MAXINT. */
4013 sprintf (p, this_format, (EMACS_INT) XFLOAT_DATA (args[n]));
4014 else 4063 else
4015 /* Don't sign-extend for octal or hex printing. */ 4064 leading_zeros = excess_precision;
4016 sprintf (p, this_format, (EMACS_UINT) XFLOAT_DATA (args[n])); 4065 }
4066
4067 /* Compute the total bytes needed for this item, including
4068 excess precision and padding. */
4069 numwidth = sprintf_bytes + excess_precision;
4070 padding = numwidth < field_width ? field_width - numwidth : 0;
4071 if (max_bufsize - sprintf_bytes <= excess_precision
4072 || max_bufsize - padding <= numwidth)
4073 string_overflow ();
4074 convbytes = numwidth + padding;
4075
4076 if (convbytes <= buf + bufsize - p)
4077 {
4078 /* Copy the formatted item from sprintf_buf into buf,
4079 inserting padding and excess-precision zeros. */
4080
4081 char *src = sprintf_buf;
4082 char src0 = src[0];
4083 int exponent_bytes = 0;
4084 int signedp = src0 == '-' || src0 == '+' || src0 == ' ';
4085 int significand_bytes;
4086 if (zero_flag && '0' <= src[signedp] && src[signedp] <= '9')
4087 {
4088 leading_zeros += padding;
4089 padding = 0;
4090 }
4091
4092 if (excess_precision
4093 && (conversion == 'e' || conversion == 'g'))
4094 {
4095 char *e = strchr (src, 'e');
4096 if (e)
4097 exponent_bytes = src + sprintf_bytes - e;
4098 }
4099
4100 if (! minus_flag)
4101 {
4102 memset (p, ' ', padding);
4103 p += padding;
4104 nchars += padding;
4105 }
4106
4107 *p = src0;
4108 src += signedp;
4109 p += signedp;
4110 memset (p, '0', leading_zeros);
4111 p += leading_zeros;
4112 significand_bytes = sprintf_bytes - signedp - exponent_bytes;
4113 memcpy (p, src, significand_bytes);
4114 p += significand_bytes;
4115 src += significand_bytes;
4116 memset (p, '0', trailing_zeros);
4117 p += trailing_zeros;
4118 memcpy (p, src, exponent_bytes);
4119 p += exponent_bytes;
4120
4121 info[n].start = nchars;
4122 nchars += leading_zeros + sprintf_bytes + trailing_zeros;
4123 info[n].end = nchars;
4124
4125 if (minus_flag)
4126 {
4127 memset (p, ' ', padding);
4128 p += padding;
4129 nchars += padding;
4130 }
4131
4132 continue;
4017 } 4133 }
4134 }
4135 }
4136 else
4137 copy_char:
4138 {
4139 /* Copy a single character from format to buf. */
4140
4141 char *src = format;
4142 unsigned char str[MAX_MULTIBYTE_LENGTH];
4018 4143
4144 if (multibyte_format)
4145 {
4146 /* Copy a whole multibyte character. */
4019 if (p > buf 4147 if (p > buf
4020 && multibyte
4021 && !ASCII_BYTE_P (*((unsigned char *) p - 1)) 4148 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
4022 && !CHAR_HEAD_P (*((unsigned char *) p))) 4149 && !CHAR_HEAD_P (*format))
4023 maybe_combine_byte = 1; 4150 maybe_combine_byte = 1;
4024 this_nchars = strlen (p); 4151
4025 if (multibyte) 4152 do
4026 p += str_to_multibyte ((unsigned char *) p, 4153 format++;
4027 buf + total - 1 - p, this_nchars); 4154 while (! CHAR_HEAD_P (*format));
4155
4156 convbytes = format - format0;
4157 memset (&discarded[format0 + 1 - format_start], 2, convbytes - 1);
4158 }
4159 else
4160 {
4161 unsigned char uc = *format++;
4162 if (! multibyte || ASCII_BYTE_P (uc))
4163 convbytes = 1;
4028 else 4164 else
4029 p += this_nchars; 4165 {
4030 nchars += this_nchars; 4166 int c = BYTE8_TO_CHAR (uc);
4031 info[n].end = nchars; 4167 convbytes = CHAR_STRING (c, str);
4168 src = (char *) str;
4169 }
4032 } 4170 }
4033 4171
4034 } 4172 if (convbytes <= buf + bufsize - p)
4035 else if (STRING_MULTIBYTE (args[0]))
4036 {
4037 /* Copy a whole multibyte character. */
4038 if (p > buf
4039 && multibyte
4040 && !ASCII_BYTE_P (*((unsigned char *) p - 1))
4041 && !CHAR_HEAD_P (*format))
4042 maybe_combine_byte = 1;
4043 *p++ = *format++;
4044 while (! CHAR_HEAD_P (*format))
4045 { 4173 {
4046 discarded[format - format_start] = 2; 4174 memcpy (p, src, convbytes);
4047 *p++ = *format++; 4175 p += convbytes;
4176 nchars++;
4177 continue;
4048 } 4178 }
4049 nchars++;
4050 } 4179 }
4051 else if (multibyte)
4052 {
4053 /* Convert a single-byte character to multibyte. */
4054 int len = copy_text ((unsigned char *) format, (unsigned char *) p,
4055 1, 0, 1);
4056 4180
4057 p += len; 4181 /* There wasn't enough room to store this conversion or single
4058 format++; 4182 character. CONVBYTES says how much room is needed. Allocate
4059 nchars++; 4183 enough room (and then some) and do it again. */
4060 } 4184 {
4061 else 4185 EMACS_INT used = p - buf;
4062 *p++ = *format++, nchars++; 4186
4187 if (max_bufsize - used < convbytes)
4188 string_overflow ();
4189 bufsize = used + convbytes;
4190 bufsize = bufsize < max_bufsize / 2 ? bufsize * 2 : max_bufsize;
4191
4192 if (buf == initial_buffer)
4193 {
4194 buf = xmalloc (bufsize);
4195 sa_must_free = 1;
4196 buf_save_value = make_save_value (buf, 0);
4197 record_unwind_protect (safe_alloca_unwind, buf_save_value);
4198 memcpy (buf, initial_buffer, used);
4199 }
4200 else
4201 XSAVE_VALUE (buf_save_value)->pointer = buf = xrealloc (buf, bufsize);
4202
4203 p = buf + used;
4204 }
4205
4206 format = format0;
4207 n = n0;
4063 } 4208 }
4064 4209
4065 if (p > buf + total) 4210 if (bufsize < p - buf)
4066 abort (); 4211 abort ();
4067 4212
4068 if (maybe_combine_byte) 4213 if (maybe_combine_byte)
@@ -4089,7 +4234,7 @@ usage: (format STRING &rest OBJECTS) */)
4089 if (CONSP (props)) 4234 if (CONSP (props))
4090 { 4235 {
4091 EMACS_INT bytepos = 0, position = 0, translated = 0; 4236 EMACS_INT bytepos = 0, position = 0, translated = 0;
4092 int argn = 1; 4237 EMACS_INT argn = 1;
4093 Lisp_Object list; 4238 Lisp_Object list;
4094 4239
4095 /* Adjust the bounds of each text property 4240 /* Adjust the bounds of each text property