Thousands separator in C's printf()
Apr. 25th, 2022 03:19 pm I just learned that you can tell C to insert thousands separators when converting numbers to strings,
On Mac, it's not documented in man printf, but it is in https://en.wikipedia.org/wiki/Printf_format_string and in https://man7.org/linux/man-pages/man3/printf.3.html Of course, although it is documented, it doesn't actually work, as described in http://earlh.com/blog/2011/06/13/thousands-separator-in-printf-in-c/
The fix that that last link points to: setlocale(LC_ALL, ""); also doesn't work:
What that does is switch the C stdio system from its default POSIX locale to whatever locale is specified in the environment variables. To actually specify that you want commas, you need something like this working example:
Oddly, I was just reading about specifying locales in the environment variables earlier this month:
https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt describes a privilege escalation exploit on Linux where an attacker can get root by running a program that specifies a made-up locale, which causes the Linux utility to load a handler for that locale: a binary supplied by the attacker that gives the attacker a root shell.
Source code of the attack: https://github.com/PwnFunction/CVE-2021-4034
and more info: https://www.youtube.com/watch?v=eTcVLqKpZJc
Thanks to Kitt Oster for teaching me about apostrophes in percent specifiers in printf format strings.
On Mac, it's not documented in man printf, but it is in https://en.wikipedia.org/wiki/Printf_format_string and in https://man7.org/linux/man-pages/man3/printf.3.html Of course, although it is documented, it doesn't actually work, as described in http://earlh.com/blog/2011/06/13/thousands-separator-in-printf-in-c/
The fix that that last link points to: setlocale(LC_ALL, ""); also doesn't work:
What that does is switch the C stdio system from its default POSIX locale to whatever locale is specified in the environment variables. To actually specify that you want commas, you need something like this working example:
#include <stdio.h>
#include <locale.h>
int main(int argc, const char * argv[]) {
setlocale(LC_NUMERIC, "en_US");
printf("%'ld!\n", (long) 10000000);
return 0;
}
Oddly, I was just reading about specifying locales in the environment variables earlier this month:
https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt describes a privilege escalation exploit on Linux where an attacker can get root by running a program that specifies a made-up locale, which causes the Linux utility to load a handler for that locale: a binary supplied by the attacker that gives the attacker a root shell.
Source code of the attack: https://github.com/PwnFunction/CVE-2021-4034
and more info: https://www.youtube.com/watch?v=eTcVLqKpZJc
Thanks to Kitt Oster for teaching me about apostrophes in percent specifiers in printf format strings.