This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
problem in swscanf
- From: Shoichi Sakon <s-sakon at ap dot jp dot nec dot com>
- To: "newlib at sourceware dot org" <newlib at sourceware dot org>
- Date: Mon, 3 Aug 2015 10:11:53 +0000
- Subject: problem in swscanf
- Authentication-results: sourceware.org; auth=none
- Deferred-delivery: Mon, 3 Aug 2015 10:11:00 +0000
Hi,
It seems there is a problem in swscanf.
Here is a test program.
----------------------------------------------------------
#include <stdio.h>
#include <wchar.h>
#define SIZE 100
main() {
const wchar_t *ws = L"ab cd ef";
wchar_t x[SIZE],y[SIZE],z[SIZE];
int ret;
ret = swscanf(ws, L"%3$l[ab] %2$ls %1$lc",x,y,z);
wprintf(L"ret=%d x=%lc y=%ls z=%ls\n",ret,*x,y,z);
}
-----------------------------------------------------------
In case of l[], ls or lc format, it does not handle %n$ properly,
null character is not add, and/or return value is not correct.
I made an experimental patch to try to correct them.
Please take a look.
diff -u newlib/libc/stdio/vfwscanf.c.orig newlib/libc/stdio/vfwscanf.c
--- newlib/libc/stdio/vfwscanf.c.orig 2013-12-20 03:50:00.000000000 +0900
+++ newlib/libc/stdio/vfwscanf.c 2015-08-03 18:53:04.548889253 +0900
@@ -777,7 +777,7 @@
if (flags & LONG)
{
if (!(flags & SUPPRESS))
- p = va_arg(ap, wchar_t *);
+ p = GET_ARG(N, ap, wchar_t *);
n = 0;
while (width-- != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF)
{
@@ -794,7 +794,7 @@
else
{
if (!(flags & SUPPRESS))
- mbp = va_arg(ap, char *);
+ mbp = GET_ARG(N, ap, char *);
n = 0;
memset ((_PTR)&mbs, '\0', sizeof (mbstate_t));
while (width != 0 && (wi = _fgetwc_r (rptr, fp)) != WEOF)
@@ -849,7 +849,7 @@
}
else if (flags & LONG)
{
- p0 = p = va_arg(ap, wchar_t *);
+ p0 = p = GET_ARG(N, ap, wchar_t *);
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width-- != 0 && INCCL (wi))
*p++ = (wchar_t) wi;
@@ -858,11 +858,13 @@
n = p - p0;
if (n == 0)
goto match_failure;
+ *p = L'\0';
+ nassigned++;
}
else
{
if (!(flags & SUPPRESS))
- mbp = va_arg(ap, char *);
+ mbp = GET_ARG(N, ap, char *);
n = 0;
memset ((_PTR) &mbs, '\0', sizeof (mbstate_t));
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
@@ -914,7 +916,7 @@
}
else if (flags & LONG)
{
- p0 = p = va_arg(ap, wchar_t *);
+ p0 = p = GET_ARG(N, ap, wchar_t *);
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width-- != 0 && !iswspace (wi))
{
@@ -923,13 +925,13 @@
}
if (wi != WEOF)
_ungetwc_r (rptr, wi, fp);
- *p = '\0';
+ *p = L'\0';
nassigned++;
}
else
{
if (!(flags & SUPPRESS))
- mbp = va_arg(ap, char *);
+ mbp = GET_ARG(N, ap, char *);
memset ((_PTR) &mbs, '\0', sizeof (mbstate_t));
while ((wi = _fgetwc_r (rptr, fp)) != WEOF
&& width != 0 && !iswspace (wi))
---
Shoichi Sakon
NEC Corp.