mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-27 07:41:28 -08:00
Improve `doprnt' and its usage. (Bug#8545)
src/doprnt.c (doprnt): Make sure `format' is never accessed beyond `format_end'. Remove support for %l as a conversion specifier. Don't use xrealloc. Improve diagnostics when the %l size modifier is used. Update the commentary. src/eval.c (verror): Simplify calculation of size_t. src/coding.c (Ffind_operation_coding_system): Fix diagnostic error messages.
This commit is contained in:
parent
211ec9072d
commit
94dcfacf12
4 changed files with 45 additions and 27 deletions
|
|
@ -1,3 +1,16 @@
|
||||||
|
2011-04-27 Eli Zaretskii <eliz@gnu.org>
|
||||||
|
|
||||||
|
Improve `doprnt' and its usage. (Bug#8545)
|
||||||
|
* doprnt.c (doprnt): Make sure `format' is never accessed beyond
|
||||||
|
`format_end'. Remove support for %l as a conversion specifier.
|
||||||
|
Don't use xrealloc. Improve diagnostics when the %l size modifier
|
||||||
|
is used. Update the commentary.
|
||||||
|
|
||||||
|
* eval.c (verror): Simplify calculation of size_t.
|
||||||
|
|
||||||
|
* coding.c (Ffind_operation_coding_system): Fix diagnostic error
|
||||||
|
messages.
|
||||||
|
|
||||||
2011-04-27 Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp> (tiny change)
|
2011-04-27 Yoshiaki Kasahara <kasahara@nc.kyushu-u.ac.jp> (tiny change)
|
||||||
|
|
||||||
* buffer.c (init_buffer) [USE_MMAP_FOR_BUFFERS]: Adjust to aliasing
|
* buffer.c (init_buffer) [USE_MMAP_FOR_BUFFERS]: Adjust to aliasing
|
||||||
|
|
|
||||||
|
|
@ -9282,14 +9282,15 @@ usage: (find-operation-coding-system OPERATION ARGUMENTS...) */)
|
||||||
|| !NATNUMP (target_idx = Fget (operation, Qtarget_idx)))
|
|| !NATNUMP (target_idx = Fget (operation, Qtarget_idx)))
|
||||||
error ("Invalid first argument");
|
error ("Invalid first argument");
|
||||||
if (nargs < 1 + XFASTINT (target_idx))
|
if (nargs < 1 + XFASTINT (target_idx))
|
||||||
error ("Too few arguments for operation: %s",
|
error ("Too few arguments for operation `%s'",
|
||||||
SDATA (SYMBOL_NAME (operation)));
|
SDATA (SYMBOL_NAME (operation)));
|
||||||
target = args[XFASTINT (target_idx) + 1];
|
target = args[XFASTINT (target_idx) + 1];
|
||||||
if (!(STRINGP (target)
|
if (!(STRINGP (target)
|
||||||
|| (EQ (operation, Qinsert_file_contents) && CONSP (target)
|
|| (EQ (operation, Qinsert_file_contents) && CONSP (target)
|
||||||
&& STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))
|
&& STRINGP (XCAR (target)) && BUFFERP (XCDR (target)))
|
||||||
|| (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
|
|| (EQ (operation, Qopen_network_stream) && INTEGERP (target))))
|
||||||
error ("Invalid %"pI"dth argument", XFASTINT (target_idx) + 1);
|
error ("Invalid argument %"pI"d of operation `%s'",
|
||||||
|
XFASTINT (target_idx) + 1, SDATA (SYMBOL_NAME (operation)));
|
||||||
if (CONSP (target))
|
if (CONSP (target))
|
||||||
target = XCAR (target);
|
target = XCAR (target);
|
||||||
|
|
||||||
|
|
|
||||||
51
src/doprnt.c
51
src/doprnt.c
|
|
@ -55,7 +55,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
%s means print a string argument.
|
%s means print a string argument.
|
||||||
%S is silently treated as %s, for loose compatibility with `Fformat'.
|
%S is silently treated as %s, for loose compatibility with `Fformat'.
|
||||||
%d means print a `signed int' argument in decimal.
|
%d means print a `signed int' argument in decimal.
|
||||||
%l means print a `long int' argument in decimal.
|
|
||||||
%o means print an `unsigned int' argument in octal.
|
%o means print an `unsigned int' argument in octal.
|
||||||
%x means print an `unsigned int' argument in hex.
|
%x means print an `unsigned int' argument in hex.
|
||||||
%e means print a `double' argument in exponential notation.
|
%e means print a `double' argument in exponential notation.
|
||||||
|
|
@ -65,22 +64,26 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
%c means print a `signed int' argument as a single character.
|
%c means print a `signed int' argument as a single character.
|
||||||
%% means produce a literal % character.
|
%% means produce a literal % character.
|
||||||
|
|
||||||
A %-sequence may contain optional flag, width, and precision specifiers, as
|
A %-sequence may contain optional flag, width, and precision specifiers, and
|
||||||
follows:
|
a length modifier, as follows:
|
||||||
|
|
||||||
%<flags><width><precision>character
|
%<flags><width><precision><length>character
|
||||||
|
|
||||||
where flags is [+ -0l], width is [0-9]+, and precision is .[0-9]+
|
where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length
|
||||||
|
modifier is l.
|
||||||
|
|
||||||
The + flag character inserts a + before any positive number, while a space
|
The + flag character inserts a + before any positive number, while a space
|
||||||
inserts a space before any positive number; these flags only affect %d, %l,
|
inserts a space before any positive number; these flags only affect %d, %o,
|
||||||
%o, %x, %e, %f, and %g sequences. The - and 0 flags affect the width
|
%x, %e, %f, and %g sequences. The - and 0 flags affect the width specifier,
|
||||||
specifier, as described below.
|
as described below. For signed numerical arguments only, the ` ' (space)
|
||||||
|
flag causes the result to be prefixed with a space character if it does not
|
||||||
|
start with a sign (+ or -).
|
||||||
|
|
||||||
The l (lower-case letter ell) flag is a `long' data type modifier: it is
|
The l (lower-case letter ell) length modifier is a `long' data type
|
||||||
supported for %d, %o, and %x conversions of integral arguments, and means
|
modifier: it is supported for %d, %o, and %x conversions of integral
|
||||||
that the respective argument is to be treated as `long int' or `unsigned
|
arguments, must immediately preced the conversion specifier, and means that
|
||||||
long int'. The EMACS_INT data type should use this modifier.
|
the respective argument is to be treated as `long int' or `unsigned long
|
||||||
|
int'. The EMACS_INT data type should use this modifier.
|
||||||
|
|
||||||
The width specifier supplies a lower limit for the length of the printed
|
The width specifier supplies a lower limit for the length of the printed
|
||||||
representation. The padding, if any, normally goes on the left, but it goes
|
representation. The padding, if any, normally goes on the left, but it goes
|
||||||
|
|
@ -166,7 +169,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
||||||
bufsize--;
|
bufsize--;
|
||||||
|
|
||||||
/* Loop until end of format string or buffer full. */
|
/* Loop until end of format string or buffer full. */
|
||||||
while (fmt != format_end && bufsize > 0)
|
while (fmt < format_end && bufsize > 0)
|
||||||
{
|
{
|
||||||
if (*fmt == '%') /* Check for a '%' character */
|
if (*fmt == '%') /* Check for a '%' character */
|
||||||
{
|
{
|
||||||
|
|
@ -178,7 +181,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
||||||
/* Copy this one %-spec into fmtcpy. */
|
/* Copy this one %-spec into fmtcpy. */
|
||||||
string = fmtcpy;
|
string = fmtcpy;
|
||||||
*string++ = '%';
|
*string++ = '%';
|
||||||
while (1)
|
while (fmt < format_end)
|
||||||
{
|
{
|
||||||
*string++ = *fmt;
|
*string++ = *fmt;
|
||||||
if ('0' <= *fmt && *fmt <= '9')
|
if ('0' <= *fmt && *fmt <= '9')
|
||||||
|
|
@ -188,7 +191,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
||||||
%1.1000f and %1000.1f both might need 1000+ bytes.
|
%1.1000f and %1000.1f both might need 1000+ bytes.
|
||||||
Parse the width or precision, checking for overflow. */
|
Parse the width or precision, checking for overflow. */
|
||||||
size_t n = *fmt - '0';
|
size_t n = *fmt - '0';
|
||||||
while ('0' <= fmt[1] && fmt[1] <= '9')
|
while (fmt < format_end
|
||||||
|
&& '0' <= fmt[1] && fmt[1] <= '9')
|
||||||
{
|
{
|
||||||
if (n >= SIZE_MAX / 10
|
if (n >= SIZE_MAX / 10
|
||||||
|| n * 10 > SIZE_MAX - (fmt[1] - '0'))
|
|| n * 10 > SIZE_MAX - (fmt[1] - '0'))
|
||||||
|
|
@ -205,14 +209,15 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
||||||
else if (*fmt == 'l')
|
else if (*fmt == 'l')
|
||||||
{
|
{
|
||||||
long_flag = 1;
|
long_flag = 1;
|
||||||
if (!strchr ("dox", fmt[1]))
|
fmt++;
|
||||||
/* %l as conversion specifier, not as modifier. */
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
fmt++;
|
fmt++;
|
||||||
}
|
}
|
||||||
|
if (fmt > format_end)
|
||||||
|
fmt = format_end;
|
||||||
*string = 0;
|
*string = 0;
|
||||||
|
|
||||||
/* Make the size bound large enough to handle floating point formats
|
/* Make the size bound large enough to handle floating point formats
|
||||||
|
|
@ -225,9 +230,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
||||||
if (size_bound > size_allocated)
|
if (size_bound > size_allocated)
|
||||||
{
|
{
|
||||||
if (big_buffer)
|
if (big_buffer)
|
||||||
big_buffer = (char *) xrealloc (big_buffer, size_bound);
|
xfree (big_buffer);
|
||||||
else
|
big_buffer = (char *) xmalloc (size_bound);
|
||||||
big_buffer = (char *) xmalloc (size_bound);
|
|
||||||
sprintf_buffer = big_buffer;
|
sprintf_buffer = big_buffer;
|
||||||
size_allocated = size_bound;
|
size_allocated = size_bound;
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +239,8 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
||||||
switch (*fmt++)
|
switch (*fmt++)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
error ("Invalid format operation %%%c", fmt[-1]);
|
error ("Invalid format operation %%%s%c",
|
||||||
|
long_flag ? "l" : "", fmt[-1]);
|
||||||
|
|
||||||
/* case 'b': */
|
/* case 'b': */
|
||||||
case 'l':
|
case 'l':
|
||||||
|
|
@ -373,7 +378,7 @@ doprnt (char *buffer, register size_t bufsize, const char *format,
|
||||||
char *save_bufptr = bufptr;
|
char *save_bufptr = bufptr;
|
||||||
|
|
||||||
do { *bufptr++ = *fmt++; }
|
do { *bufptr++ = *fmt++; }
|
||||||
while (--bufsize > 0 && !CHAR_HEAD_P (*fmt));
|
while (fmt < format_end && --bufsize > 0 && !CHAR_HEAD_P (*fmt));
|
||||||
if (!CHAR_HEAD_P (*fmt))
|
if (!CHAR_HEAD_P (*fmt))
|
||||||
{
|
{
|
||||||
bufptr = save_bufptr;
|
bufptr = save_bufptr;
|
||||||
|
|
|
||||||
|
|
@ -1994,8 +1994,7 @@ verror (const char *m, va_list ap)
|
||||||
{
|
{
|
||||||
char buf[4000];
|
char buf[4000];
|
||||||
size_t size = sizeof buf;
|
size_t size = sizeof buf;
|
||||||
size_t size_max =
|
size_t size_max = min (MOST_POSITIVE_FIXNUM, SIZE_MAX);
|
||||||
min (MOST_POSITIVE_FIXNUM, min (INT_MAX, SIZE_MAX - 1)) + 1;
|
|
||||||
size_t mlen = strlen (m);
|
size_t mlen = strlen (m);
|
||||||
char *buffer = buf;
|
char *buffer = buf;
|
||||||
size_t used;
|
size_t used;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue