* [PATCH] Fix snprintf
@ 2003-05-26 16:41 Jakub Jelinek
2003-05-27 7:40 ` Ulrich Drepper
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2003-05-26 16:41 UTC (permalink / raw)
To: Ulrich Drepper, Roland McGrath; +Cc: Glibc hackers
Hi!
ATM sprintf creates at most 64M string, furthermore although snprintf
is given size_t for max length, it is casted to int and thus it might be
much smaller limit than the one given by the user (consider e.g.
sprintf (buf, 0x100000010, fmt, args)).
2003-05-26 Jakub Jelinek <jakub@redhat.com>
* libio/strops.c (_IO_str_init_static): Change into a wrapper around
_IO_str_init_static_internal.
(_IO_str_init_static_internal): Moved from _IO_str_init_static,
change size argument to _IO_size_t, don't limit sprintf to 64M.
(_IO_str_init_readonly): Call _IO_str_init_static_internal.
* libio/wstrops.c (_IO_wstr_init_static): Change size argument to
_IO_size_t, don't limit swprintf to 256M.
(_IO_wstr_init_readonly): Remove.
* libio/libioP.h (_IO_str_init_static_internal, _IO_wstr_init_static):
Adjust prototypes.
(_IO_wstr_init_readonly): Remove prototype.
* libio/iovsprintf.c (_IO_vsprintf): Use
_IO_str_init_static_internal instead of INTUSE(_IO_str_init_static).
* libio/iovsscanf.c (_IO_vsscanf): Likewise.
* libio/memstream.c (open_memstream): Likewise.
* libio/obprintf.c (_IO_obstack_vfprintf): Likewise.
* libio/vasprintf.c (_IO_vasprintf): Likewise.
* libio/vsnprintf.c (_IO_vsnprintf): Likewise.
* stdio-common/tst-sprintf.c (main): Add new test.
--- libc/libio/strops.c.jj 2002-02-28 06:31:50.000000000 -0500
+++ libc/libio/strops.c 2003-05-26 08:34:39.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -63,33 +63,22 @@
#endif
void
-_IO_str_init_static (sf, ptr, size, pstart)
+_IO_str_init_static_internal (sf, ptr, size, pstart)
_IO_strfile *sf;
char *ptr;
- int size;
+ _IO_size_t size;
char *pstart;
{
_IO_FILE *fp = &sf->_sbf._f;
+ char *end;
if (size == 0)
- size = strlen (ptr);
- else if (size < 0)
- {
- /* If size is negative 'the characters are assumed to
- continue indefinitely.' This is kind of messy ... */
- int s;
- size = 512;
- /* Try increasing powers of 2, as long as we don't wrap around. */
- for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
- size = s;
- /* Try increasing size as much as we can without wrapping around. */
- for (s = size >> 1; s > 0; s >>= 1)
- {
- if (ptr + size + s > ptr)
- size += s;
- }
- }
- INTUSE(_IO_setb) (fp, ptr, ptr + size, 0);
+ end = __rawmemchr (ptr, '\0');
+ else if ((_IO_size_t) ptr + size > (_IO_size_t) ptr)
+ end = ptr + size;
+ else
+ end = (char *) -1;
+ INTUSE(_IO_setb) (fp, ptr, end, 0);
fp->_IO_write_base = ptr;
fp->_IO_read_base = ptr;
@@ -97,19 +86,28 @@ _IO_str_init_static (sf, ptr, size, psta
if (pstart)
{
fp->_IO_write_ptr = pstart;
- fp->_IO_write_end = ptr + size;
+ fp->_IO_write_end = end;
fp->_IO_read_end = pstart;
}
else
{
fp->_IO_write_ptr = ptr;
fp->_IO_write_end = ptr;
- fp->_IO_read_end = ptr+size;
+ fp->_IO_read_end = end;
}
/* A null _allocate_buffer function flags the strfile as being static. */
sf->_s._allocate_buffer = (_IO_alloc_type) 0;
}
-INTDEF(_IO_str_init_static)
+
+void
+_IO_str_init_static (sf, ptr, size, pstart)
+ _IO_strfile *sf;
+ char *ptr;
+ int size;
+ char *pstart;
+{
+ return _IO_str_init_static_internal (sf, ptr, size < 0 ? -1 : size, pstart);
+}
void
_IO_str_init_readonly (sf, ptr, size)
@@ -117,7 +115,7 @@ _IO_str_init_readonly (sf, ptr, size)
const char *ptr;
int size;
{
- INTUSE(_IO_str_init_static) (sf, (char *) ptr, size, NULL);
+ _IO_str_init_static_internal (sf, (char *) ptr, size < 0 ? -1 : size, NULL);
sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES;
}
--- libc/libio/libioP.h.jj 2003-05-13 16:58:06.000000000 -0400
+++ libc/libio/libioP.h 2003-05-26 09:27:06.000000000 -0400
@@ -619,8 +619,7 @@ extern void _IO_str_init_readonly __P ((
extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *));
/* And the wide character versions. */
-extern void _IO_wstr_init_static __P ((_IO_FILE *, wchar_t *, int, wchar_t *));
-extern void _IO_wstr_init_readonly __P ((_IO_FILE *, const char *, int));
+extern void _IO_wstr_init_static __P ((_IO_FILE *, wchar_t *, _IO_size_t, wchar_t *));
extern _IO_ssize_t _IO_wstr_count __P ((_IO_FILE *));
extern _IO_wint_t _IO_wstr_overflow __P ((_IO_FILE *, _IO_wint_t));
extern _IO_wint_t _IO_wstr_underflow __P ((_IO_FILE *));
@@ -710,7 +709,7 @@ extern int _IO_str_pbackfail_internal __
extern _IO_off64_t _IO_str_seekoff_internal __P ((_IO_FILE *, _IO_off64_t,
int, int));
extern void _IO_str_init_static_internal __P ((struct _IO_strfile_ *, char *,
- int, char *));
+ _IO_size_t, char *));
extern struct _IO_jump_t _IO_file_jumps_internal attribute_hidden;
extern struct _IO_jump_t _IO_wfile_jumps_internal attribute_hidden;
--- libc/libio/iovsprintf.c.jj 2002-02-28 06:31:50.000000000 -0500
+++ libc/libio/iovsprintf.c 2003-05-26 08:35:43.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -42,7 +42,7 @@ _IO_vsprintf (string, format, args)
#endif
_IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
_IO_JUMPS ((struct _IO_FILE_plus *) &sf._sbf) = &_IO_str_jumps;
- INTUSE(_IO_str_init_static) (&sf, string, -1, string);
+ _IO_str_init_static_internal (&sf, string, -1, string);
ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf._sbf, format, args);
_IO_putc_unlocked ('\0', (_IO_FILE *) &sf._sbf);
return ret;
--- libc/libio/iovsscanf.c.jj 2002-02-28 06:31:50.000000000 -0500
+++ libc/libio/iovsscanf.c 2003-05-26 08:36:27.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997-2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -41,7 +41,7 @@ _IO_vsscanf (string, format, args)
#endif
_IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
_IO_JUMPS ((struct _IO_FILE_plus *) &sf._sbf) = &_IO_str_jumps;
- INTUSE(_IO_str_init_static) (&sf, (char*)string, 0, NULL);
+ _IO_str_init_static_internal (&sf, (char*)string, 0, NULL);
ret = INTUSE(_IO_vfscanf) ((_IO_FILE *) &sf._sbf, format, args, NULL);
return ret;
}
--- libc/libio/memstream.c.jj 2002-08-12 09:27:47.000000000 -0400
+++ libc/libio/memstream.c 2003-05-26 08:37:45.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995,1996,1997,1999,2000,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1995-1997,1999,2000,2002,2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -114,7 +114,7 @@ open_memstream (bufloc, sizeloc)
return NULL;
_IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps);
_IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps;
- INTUSE(_IO_str_init_static) (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
+ _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
new_f->fp._sf._s._free_buffer = (_IO_free_type) free;
--- libc/libio/obprintf.c.jj 2002-02-28 06:31:50.000000000 -0500
+++ libc/libio/obprintf.c 2003-05-26 08:38:56.000000000 -0400
@@ -1,5 +1,5 @@
/* Print output of stream to given obstack.
- Copyright (C) 1996,1997,1999,2000,2001,2002 Free Software Foundation, Inc.
+ Copyright (C) 1996,1997,1999-2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -153,9 +153,9 @@ _IO_obstack_vprintf (struct obstack *obs
assert (size != 0);
}
- INTUSE(_IO_str_init_static) ((struct _IO_strfile_ *) &new_f.ofile,
- obstack_base (obstack),
- size, obstack_next_free (obstack));
+ _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile,
+ obstack_base (obstack),
+ size, obstack_next_free (obstack));
/* Now allocate the rest of the current chunk. */
assert (size == (new_f.ofile.file.file._IO_write_end
- new_f.ofile.file.file._IO_write_base));
--- libc/libio/vasprintf.c.jj 2002-02-28 06:31:50.000000000 -0500
+++ libc/libio/vasprintf.c 2003-05-26 08:39:54.000000000 -0400
@@ -54,7 +54,7 @@ _IO_vasprintf (result_ptr, format, args)
#endif
_IO_no_init ((_IO_FILE *) &sf._sbf, _IO_USER_LOCK, -1, NULL, NULL);
_IO_JUMPS ((struct _IO_FILE_plus *) &sf._sbf) = &_IO_str_jumps;
- INTUSE(_IO_str_init_static) (&sf, string, init_string_size, string);
+ _IO_str_init_static_internal (&sf, string, init_string_size, string);
sf._sbf._f._flags &= ~_IO_USER_BUF;
sf._s._allocate_buffer = (_IO_alloc_type) malloc;
sf._s._free_buffer = (_IO_free_type) free;
--- libc/libio/vsnprintf.c.jj 2002-02-28 06:31:50.000000000 -0500
+++ libc/libio/vsnprintf.c 2003-05-26 08:45:19.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994,1997,1999,2000,2001,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1994,1997,1999-2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -126,7 +126,7 @@ _IO_vsnprintf (string, maxlen, format, a
_IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
_IO_JUMPS ((struct _IO_FILE_plus *) &sf.f._sbf) = &_IO_strn_jumps;
string[0] = '\0';
- INTUSE(_IO_str_init_static) (&sf.f, string, maxlen - 1, string);
+ _IO_str_init_static_internal (&sf.f, string, maxlen - 1, string);
ret = INTUSE(_IO_vfprintf) ((_IO_FILE *) &sf.f._sbf, format, args);
if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf)
--- libc/libio/wstrops.c.jj 2002-08-27 17:19:42.000000000 -0400
+++ libc/libio/wstrops.c 2003-05-26 09:25:41.000000000 -0400
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1997,1998,1999,2001,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1997-1999,2001-2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -67,28 +67,20 @@ void
_IO_wstr_init_static (fp, ptr, size, pstart)
_IO_FILE *fp;
wchar_t *ptr;
- int size;
+ _IO_size_t size;
wchar_t *pstart;
{
+ wchar_t *end;
+
if (size == 0)
- size = __wcslen (ptr);
- else if (size < 0)
- {
- /* If size is negative 'the characters are assumed to
- continue indefinitely.' This is kind of messy ... */
- int s;
- size = 512;
- /* Try increasing powers of 2, as long as we don't wrap around. */
- for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
- size = s;
- /* Try increasing size as much as we can without wrapping around. */
- for (s = size >> 1; s > 0; s >>= 1)
- {
- if (ptr + size + s > ptr)
- size += s;
- }
- }
- INTUSE(_IO_wsetb) (fp, ptr, ptr + size, 0);
+ end = ptr + __wcslen (ptr);
+ else if ((_IO_size_t) ptr + size * sizeof (wchar_t) > (_IO_size_t) ptr)
+ end = ptr + size;
+ else
+ /* Even for misaligned ptr make sure there is integral number of wide
+ characters. */
+ end = ptr + (-1 - (_IO_size_t) ptr) / sizeof (wchar_t);
+ INTUSE(_IO_wsetb) (fp, ptr, end, 0);
fp->_wide_data->_IO_write_base = ptr;
fp->_wide_data->_IO_read_base = ptr;
@@ -96,29 +88,19 @@ _IO_wstr_init_static (fp, ptr, size, pst
if (pstart)
{
fp->_wide_data->_IO_write_ptr = pstart;
- fp->_wide_data->_IO_write_end = ptr + size;
+ fp->_wide_data->_IO_write_end = end;
fp->_wide_data->_IO_read_end = pstart;
}
else
{
fp->_wide_data->_IO_write_ptr = ptr;
fp->_wide_data->_IO_write_end = ptr;
- fp->_wide_data->_IO_read_end = ptr + size;
+ fp->_wide_data->_IO_read_end = end;
}
/* A null _allocate_buffer function flags the strfile as being static. */
(((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
}
-void
-_IO_wstr_init_readonly (fp, ptr, size)
- _IO_FILE *fp;
- const char *ptr;
- int size;
-{
- _IO_wstr_init_static (fp, (wchar_t *) ptr, size, NULL);
- fp->_IO_file_flags |= _IO_NO_WRITES;
-}
-
_IO_wint_t
_IO_wstr_overflow (fp, c)
_IO_FILE *fp;
--- libc/stdio-common/tst-sprintf.c.jj 2001-12-14 02:17:17.000000000 -0500
+++ libc/stdio-common/tst-sprintf.c 2003-05-26 12:21:00.000000000 -0400
@@ -11,9 +11,30 @@ main (void)
if (sprintf (buf, "%.0ls", L"foo") != 0
|| strlen (buf) != 0)
{
- puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output\n");
+ puts ("sprintf (buf, \"%.0ls\", L\"foo\") produced some output");
result = 1;
}
+#define SIZE (1024*70000)
+#define STR(x) #x
+
+ char *dst = malloc (SIZE + 1);
+
+ if (dst == NULL)
+ {
+ puts ("memory allocation failure");
+ result = 1;
+ }
+ else
+ {
+ sprintf (dst, "%*s", SIZE, "");
+ if (strnlen (dst, SIZE + 1) != SIZE)
+ {
+ puts ("sprintf (dst, \"%*s\", " STR(SIZE) ", \"\") did not produce enough output");
+ result = 1;
+ }
+ free (dst);
+ }
+
return result;
}
Jakub
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Fix snprintf
2003-05-26 16:41 [PATCH] Fix snprintf Jakub Jelinek
@ 2003-05-27 7:40 ` Ulrich Drepper
0 siblings, 0 replies; 2+ messages in thread
From: Ulrich Drepper @ 2003-05-27 7:40 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Roland McGrath, Glibc hackers
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Jakub Jelinek wrote:
> ATM sprintf creates at most 64M string, furthermore although snprintf
> is given size_t for max length, it is casted to int and thus it might be
> much smaller limit than the one given by the user (consider e.g.
> sprintf (buf, 0x100000010, fmt, args)).
I've applied the patch. Thanks,
- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat `--' drepper at redhat.com `---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
iD8DBQE+0xY72ijCOnn/RHQRAsqSAKCA8D14F/k6iTgxGH60EMKiCaazxQCgnFyy
hBcBC+KZWL5fjGJtmWoJhho=
=A7Dw
-----END PGP SIGNATURE-----
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-05-27 7:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-26 16:41 [PATCH] Fix snprintf Jakub Jelinek
2003-05-27 7:40 ` Ulrich Drepper
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).