Documenting sscanf()'s and fscanf's underflow

php.internals

mickmackusa

99 days ago
Hi all, may I request that the documentation pages for sscanf() and fscanf() be reviewed? Last week, I tripped over a bug in my code because, despite using and loving sscanf() for many years, the function unexpectedly returned -1 for the number of successful captures when I expected 0. I've documented the encounter here: https://stackoverflow.com/q/79942833/2943403 I have been doing a fair amount of Google searching, but either my keywords are not ideal or there really is no mention of this floating around (even the C++ pages that I read don't mention it). Thanks, mickmackusa

Jordi Kroon

99 days ago
On 24/05/2026 10:38 pm, mickmackusa wrote:
> Hi all, may I request that the documentation pages for sscanf() and > fscanf() be reviewed? > > Last week, I tripped over a bug in my code because, despite using and > loving sscanf() for many years, the function unexpectedly returned -1 > for the number of successful captures when I expected 0. > > I've documented the encounter here: https://stackoverflow.com/ > q/79942833/2943403 <https://stackoverflow.com/q/79942833/2943403> > > I have been doing a fair amount of Google searching, but either my > keywords are not ideal or there really is no mention of this floating > around (even the C++ pages that I read don't mention it). > > Thanks, > mickmackusa
`sscanf()` and `fscanf()` may return -1 when the end of the input is reached before any value has been successfully parsed. That behaviour is currently missing from the documentation. I opened a PR to cover this: https://github.com/php/doc-en/pull/5580 Specific commit: https://github.com/php/doc-en/commit/7af7c98e4f7c983581dc05c58b958bb6c0c1267b Feel free to check and reply in the PR conversation if you think the wording should be adjusted.
-- Regards, Jordi Kroon

hakre

98 days ago
On Sunday 24 May 2026 22:38:16 (+02:00), mickmackusa wrote:
> Hi all, may I request that the documentation pages for sscanf() and > fscanf() be reviewed?
Thank you for the detailed documentation on SO and invoking some initiative here on the list.
> I have been doing a fair amount of Google searching, but either my
keywords
> are not ideal or there really is no mention of this floating around
(even
> the C++ pages that I read don't mention it).
C++ might be a red herring, sscanf is more ANSI C and for PHP the original code from TCL8.3.0: <https://www.tcl-lang.org/software/tcltk/relnotes/tcl8.3.0.txt> "The main site for Tcl/Tk source distributions is SourceForge" [1], that version's sources and manual: * tcl8.3.0.tar.gz -- 2001-07-30 2.5 MB * tcl8.3.0.html.tar.gz -- 2001-07-30 582.1 kB <https://sourceforge.net/projects/tcl/files/Tcl/8.3.0/*> For sscanf ANSI C I have found The Unix Heritage Society <https://www.tuhs.org> an invaluable resource to learn about ANSI draft interpretations as they have archives of Usenet comp.std.c in indexable hypertext documents as well as gzipped tarballs: <https://www.tuhs.org/Usenet/comp.std.c/> I found it helpful in context of PHP to understand the communication in the user's network (Usenet/USENIX network) with the Unix-to-Unix Copy Protocol (UUCP) and also the nomenclature of C and other computer lanugages standardization processes. To give an example for questions like why the PHP implementation of fscanf() might be reading one line at a time as you briefly mentioned off-list IIRC, I found a message 'Hints for using "scanf"' [2] that helped me to reflect such kind of thoughts. Let me illustrate with an excerpt of the exemplary message written by Martin Weitzel in January 1990:
> If you want to analyze interactive (or unpredictable) input, > my advice is to read a complete line with "fgets" (avoid "gets"!!) > or read up to some other significant token with "gets/fgets". > After that, use "sscanf" on the buffer you just read.
In our sources we can find the following lines: buf = php_stream_get_line((php_stream *) what, NULL, 0, &len); if (buf == NULL) { RETURN_FALSE; } result = php_sscanf_internal(buf, format, argc, args, 0, return_value); This is PHP's way of fgets() followed by sscanf() on the buffer, as illustrated by M. Weitzel back in 1990. As you requested, I illustrative now "reviewed" the manual page for the fscanf() function [3] in this regard:
> Each call to fscanf() reads one line from the file.
Find out more about networked computing not only in comp.infosystems.www.authoring.cgi (check June 8 '95) but also in the comp.* hierarchy when you want to research in the archives. best -- hakre p.s. I took some time yesterday to document an example listing of how to make use of the "underflow behavior", e.g. for testing in GH-19088 [4] in case of interest. [1]: https://www.tcl-lang.org/software/tcltk/download.html [2]: https://www.tuhs.org/Usenet/comp.std.c/1990-January/000290.html [3]: https://web.archive.org/web/20170812235246/http://php.net/fscanf [4]: https://github.com/php/php-src/issues/19088#issuecomment-4534153067