mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-06 01:40:28 +00:00
Make %c
parsing in *scanf()
respect the C standard
Currently, `%c`-style directives always succeed even if there are actually fewer characters in the input than requested. Before the fix, the added test fails like this: ... EXPECT_EQ(2, sscanf("ab", "%c %c %c", &c2, &c3, &c4)) need 2 (or 0x02 or '\2' or ENOENT) = got 3 (or 0x03 or '\3' or ESRCH) ... EXPECT_EQ(0, sscanf("abcd", "%5c", s2)) need 0 (or 0x0 or '\0') = got 1 (or 0x01 or '\1' or EPERM) musl and glibc pass this test.
This commit is contained in:
parent
e5d877ba4f
commit
a57c6067f0
2 changed files with 16 additions and 3 deletions
|
@ -550,6 +550,11 @@ int __vcscanf(int callback(void *), //
|
|||
if (!j && c == -1 && !items) {
|
||||
items = -1;
|
||||
goto Done;
|
||||
} else if (rawmode && j != width) {
|
||||
/* The C standard says that %c "matches a sequence of characters of
|
||||
* **exactly** the number specified by the field width". If we have
|
||||
* fewer characters, what we've just read is invalid. */
|
||||
goto Done;
|
||||
} else if (!rawmode && j < bufsize) {
|
||||
if (charbytes == sizeof(char)) {
|
||||
buf[j] = '\0';
|
||||
|
|
|
@ -69,9 +69,17 @@ TEST(sscanf, testNonDirectiveCharacterMatching) {
|
|||
}
|
||||
|
||||
TEST(sscanf, testCharacter) {
|
||||
char c = 0;
|
||||
EXPECT_EQ(1, sscanf("a", "%c", &c));
|
||||
EXPECT_EQ('a', c);
|
||||
char c1 = 0, c2 = c1, c3 = c2, c4 = c3;
|
||||
char s1[32] = {0}, s2[32] = {0};
|
||||
EXPECT_EQ(1, sscanf("a", "%c", &c1));
|
||||
EXPECT_EQ(2, sscanf("ab", "%c %c %c", &c2, &c3, &c4));
|
||||
EXPECT_EQ(1, sscanf("abcde", "%5c", s1));
|
||||
EXPECT_EQ(0, sscanf("abcd", "%5c", s2));
|
||||
|
||||
EXPECT_EQ('a', c1);
|
||||
EXPECT_EQ('a', c2);
|
||||
EXPECT_EQ('b', c3);
|
||||
EXPECT_STREQ("abcde", &s1[0]);
|
||||
}
|
||||
|
||||
TEST(sscanf, testStringBuffer) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue