fmtcheck(3bsd)

πŸ“¦
version 0.12.2 Β· 2 versions
  • 0.12.2 Β· alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian bookworm, debian trixie, epel 10, epel 9, fedora 43, fedora 44, nixos 26.05, opensuse-leap 16.0, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking (latest)
  • 0.11.5 Β· ubuntu jammy
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, debian bookworm, debian trixie, epel 10, epel 9, fedora 43, fedora 44, nixos 26.05, opensuse-leap 16.0, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– fmtcheck β€” the girl who sanitizes your user-supplied printf(3)-style format strings πŸ’–

okay so bestie, welcome to fmtcheck(3bsd), a lil utility straight out of the BSD world, living in the LOCAL section. she's here to stop you from getting absolutely wrecked by a format string you didn't write yourself. 🫢


πŸ“š LIBRARY

Utility functions from BSD systems β€” that's libbsd, and you link her with -lbsd. periodt.


✨ SYNOPSIS ✨

#include <stdio.h>
(See libbsd(7) for include usage.)

const char *
fmtcheck(const char *fmt_suspect, const char *fmt_default);

yes, that include comment is really in there, i'm not being quirky β€” go read libbsd(7) for the include usage deets.


πŸŽ€ DESCRIPTION πŸŽ€

so what's her job? fmtcheck scans fmt_suspect and fmt_default and figures out two things:

  • will fmt_suspect eat the same argument types as fmt_default? πŸ‘€
  • is fmt_suspect even a valid format string at all?

because here's the tea: the printf(3) family of functions can not verify the types of arguments that they are passed at run-time. like, they literally cannot. so in some cases β€” think catgets(3) β€” it's useful or even necessary to use a user-supplied format string with no guarantee that the format string matches the specified parameters. 😭

and that's exactly the situation fmtcheck was designed for, as in:

printf(fmtcheck(user_format, standard_format), arg1, arg2);

iconic. she checks the vibe of your format string before it ever reaches printf.

now, in the check, field widths, fillers, precisions, etc. are ignored β€” unless the field width or precision is an asterisk β€˜*’ instead of a digit string. πŸ‘‘ also, any text other than the format specifiers is completely ignored. so don't stress about the prose, she only cares about the specs.

note that the formats may be quite different as long as they accept the same parameters. πŸ’…

for example, this:

"%ld %o %30s %#llx %-10.*e %n"

is compatible with this:

"This number %lu %d%% and string %s has %qd numbers and %.*g floats (%n)."

slay. but watch out, because these are NOT equivalent:

  • "%o" is not equivalent to "%lx" β€” the first requires an integer and the second requires a long. different vibes entirely. πŸ’€
  • "%p" is not equivalent to "%lu" β€” the first requires a pointer and the second requires a long. also not the same bestie!! πŸ™ˆ

🌈 RETURN VALUES 🌈

here's the moment of truth:

  • if fmt_suspect is a valid format and consumes the same argument types as fmt_default β€” she returns fmt_suspect. βœ… you're safe, main character energy.
  • otherwise β€” she returns fmt_default. πŸ›Ÿ the fallback comes in clutch and saves your whole program.

πŸ‘€ SEE ALSO


and that's the whole page, bestie!! πŸ¦‹πŸŒΈ this one's from the Debian crew, dated June 14, 2014, and yes, it's filed right there under fmtcheck(3bsd) in the LOCAL section. mwah. πŸ’…βœ¨πŸ’–

πŸ“¦ where this page comes from