Bug 219926 - sscanf(3): Inconsistent return value on match failures with patterns like "%*s%u" when compared to other implementations
Summary: sscanf(3): Inconsistent return value on match failures with patterns like "%*...
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-standards (Nobody)
Depends on:
Reported: 2017-06-11 14:13 UTC by Tobias Kortkamp
Modified: 2017-06-12 19:33 UTC (History)
1 user (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Kortkamp freebsd_committer 2017-06-11 14:13:55 UTC
When using a pattern that starts with "%*s" followed by one or more
other conversions, the sscanf(3) implementation in FreeBSD's libc
behaves differently than the sscanf() implementations in other libcs.
For example running this small test program on a bunch of different
systems gives the following results:

#include <stdio.h>

main(int argc, char *argv[])
	unsigned int i;
	int n = sscanf("foo", "%*s%u", &i);
	printf("n = %d\n", n);
	return 0;

n = 0 on FreeBSD 11.0 and 12.0-CURRENT
n = 0 on DragonFly BSD 4.6.0rc2
n = 0 on NetBSD 7.0.1
n = -1 on Ubuntu 16.04 (Glibc 2.23)
n = -1 on Alpine Linux (musl 1.1.16)
n = -1 on OpenBSD 6.1

Glibc, musl, and OpenBSD's libc all return EOF in this case.

netpbm's ppmtoarbtxt uses a similar pattern and would fail to work
correctly on FreeBSD because it expects that EOF is returned after a
match failure.  This has been worked around now upstream by not using
"%*s" first in the pattern.  But I'm wondering if this a bug or if
this is ok?
Comment 1 Conrad Meyer freebsd_committer 2017-06-11 16:11:42 UTC
The C11 standard says:

3 The sscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the sscanf function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.

So the question is — is "%*s" a conversion?

From the fscanf part of C11:

Each conversion specification is introduced by the character %.
After the %, the following appear in sequence:
— An optional assignment-suppressing character *.
— An optional decimal integer greater than zero that specifies the maximum field width (in characters).
— An optional length modifier that specifies the size of the receiving object.
— A conversion specifier character that specifies the type of conversion to be applied.

So... maybe?