Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
[libc] scanf: do not count suppressed conversions in the return value scanf_main() incremented the result for every successful conversion except %n, including assignment-suppressed ones ("%*d") and "%%". C requires the number of input items *assigned*. Example: sscanf("12 34", "%*d%d", &x) returned 2 instead of 1; sscanf("420jpeg", "%*d%*[pP]%d", &x) returned 1 without writing x (breaks x264's y4m colorspace/bit depth parsing). Still present in llvm main as of 2026-10. diff --git a/libc/src/stdio/scanf_core/scanf_main.h b/libc/src/stdio/scanf_core/scanf_main.h index f975d85..e1eb5fb 100644 --- a/libc/src/stdio/scanf_core/scanf_main.h +++ b/libc/src/stdio/scanf_core/scanf_main.h @@ -32,9 +32,10 @@ int scanf_main(Reader
*reader, const char *__restrict str, cur_section = parser.get_next_section()) { if (cur_section.has_conv) { ret_val = convert(reader, cur_section); - // The %n (current position) conversion doesn't increment the number of - // assignments. - if (cur_section.conv_name != 'n') + // Only assigned items count: not %n (current position), not %% and not + // conversions with assignment suppression ('*', the NO_WRITE flag). + if (cur_section.conv_name != 'n' && cur_section.conv_name != '%' && + (cur_section.flags & FormatFlags::NO_WRITE) == 0) conversions += ret_val == READ_OK ? 1 : 0; } else { ret_val = raw_match(reader, cur_section.raw_string);
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)