diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | libio/tst_swprintf.c | 52 | ||||
-rw-r--r-- | libio/vswprintf.c | 26 |
3 files changed, 59 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog index f15b09a413..a9c4e8d489 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2001-08-09 Ulrich Drepper <drepper@redhat.com> + * libio/vswprintf.c (_IO_vswprintf): Fix return value handling + which is different from snprintf. + * libio/tst_swprintf.c: Add tests for too small output buffer. + * stdio-common/vfscanf.c: Fix handling of %[] for COMPILE_WSCANF. * libio/Makefile (tests): Add tst-swscanf. * libio/tst-swscanf.c: New file. diff --git a/libio/tst_swprintf.c b/libio/tst_swprintf.c index 67d10a006d..dc16db0a0c 100644 --- a/libio/tst_swprintf.c +++ b/libio/tst_swprintf.c @@ -1,42 +1,76 @@ #include <stdio.h> #include <wchar.h> +#include <sys/types.h> + + +static wchar_t buf[100]; +#define nbuf (sizeof (buf) / sizeof (buf[0])) +static const struct +{ + size_t n; + const char *str; + ssize_t exp; +} tests[] = + { + { nbuf, "hello world", 11 }, + { 0, "hello world", -1 }, + { 0, "", -1 }, + { nbuf, "", 0 } + }; int main (int argc, char *argv[]) { - wchar_t buf[100]; int n; int result = 0; puts ("test 1"); - n = swprintf (buf, sizeof (buf) / sizeof (buf[0]), L"Hello %s", "world"); + n = swprintf (buf, nbuf, L"Hello %s", "world"); if (n != 11) { printf ("incorrect return value: %d instead of 11\n", n); result = 1; } - - if (wcscmp (buf, L"Hello world") != 0) + else if (wcscmp (buf, L"Hello world") != 0) { printf ("incorrect string: L\"%ls\" instead of L\"Hello world\"\n", buf); result = 1; } puts ("test 2"); - n = swprintf (buf, sizeof (buf) / sizeof (buf[0]), L"Is this >%g< 3.1?", - 3.1); + n = swprintf (buf, nbuf, L"Is this >%g< 3.1?", 3.1); if (n != 18) -{ + { printf ("incorrect return value: %d instead of 18\n", n); result = 1; } - - if (wcscmp (buf, L"Is this >3.1< 3.1?") != 0) + else if (wcscmp (buf, L"Is this >3.1< 3.1?") != 0) { printf ("incorrect string: L\"%ls\" instead of L\"Is this >3.1< 3.1?\"\n", buf); result = 1; } + for (n = 0; n < sizeof (tests) / sizeof (tests[0]); ++n) + { + ssize_t res = swprintf (buf, tests[n].n, L"%s", tests[n].str); + + if (tests[n].exp < 0 && res >= 0) + { + printf ("swprintf (buf, %Zu, L\"%%s\", \"%s\") expected to fail\n", + tests[n].n, tests[n].str); + result = 1; + } + else if (tests[n].exp >= 0 && tests[n].exp != res) + { + printf ("swprintf (buf, %Zu, L\"%%s\", \"%s\") expected to return %Zd, but got %Zd\n", + tests[n].n, tests[n].str, tests[n].exp, res); + result = 1; + } + else + printf ("swprintf (buf, %Zu, L\"%%s\", \"%s\") OK\n", + tests[n].n, tests[n].str); + } + return result; } diff --git a/libio/vswprintf.c b/libio/vswprintf.c index 25274926f6..00dc62c902 100644 --- a/libio/vswprintf.c +++ b/libio/vswprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994, 1997, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1994, 1997, 1999, 2000, 2001 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 @@ -54,11 +54,6 @@ _IO_wstrn_overflow (fp, c) if (fp->_wide_data->_IO_buf_base != snf->overflow_buf) { - /* Terminate the string. We know that there is room for at - least one more character since we initialized the stream with - a size to make this possible. */ - *fp->_wide_data->_IO_write_ptr = '\0'; - _IO_wsetb (fp, snf->overflow_buf, snf->overflow_buf + (sizeof (snf->overflow_buf) / sizeof (wchar_t)), 0); @@ -120,13 +115,10 @@ _IO_vswprintf (string, maxlen, format, args) sf.f._sbf._f._lock = &lock; #endif - /* We need to handle the special case where MAXLEN is 0. Use the - overflow buffer right from the start. */ if (maxlen == 0) - { - string = sf.overflow_buf; - maxlen = sizeof (sf.overflow_buf) / sizeof (wchar_t); - } + /* Since we have to write at least the terminating L'\0' a buffer + length of zero always makes the function fail. */ + return -1; _IO_no_init (&sf.f._sbf._f, 0, 0, &wd, &_IO_wstrn_jumps); _IO_fwide (&sf.f._sbf._f, 1); @@ -134,8 +126,14 @@ _IO_vswprintf (string, maxlen, format, args) _IO_wstr_init_static (&sf.f._sbf._f, string, maxlen - 1, string); ret = _IO_vfwprintf ((_IO_FILE *) &sf.f._sbf, format, args); - if (sf.f._sbf._f._wide_data->_IO_buf_base != sf.overflow_buf) - *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0'; + if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) + /* ISO C99 requires swprintf/vswprintf to return an error if the + output does not fit int he provided buffer. */ + return -1; + + /* Terminate the string. */ + *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0'; + return ret; } |