strfmon: Avoid an out-of-bounds access

Avoid an out-of-bounds access when trying to set the space_char using an
international currency format (%i) and the C/POSIX locale.

The current code tries to read the SPACE from int_curr_symbol[3]:

    currency_symbol = strdup(lc->int_curr_symbol);
    space_char = *(currency_symbol+3);

But on C/POSIX locales, int_curr_symbol is empty.

Three implementations have been examined: NetBSD[1], Darwin[2], and
Illumos[3].  Only NetBSD has fixed it[4].

Darwin and NetBSD also trim the mandatory final SPACE character after
reading it.

    Locale         Format    Darwin/NetBSD    FreeBSD/Illumos
    en_US.UTF-8    [%i]      [USD123.45]      [USD 123.45]
    fr_FR.UTF-8    [%i]      [123,45 EUR]     [123,45 EUR ]

This commit only fixes the out-of-bounds access.

[1]: https://github.com/NetBSD/src/blob/trunk/lib/libc/stdlib/strfmon.c
[2]: https://opensource.apple.com/source/Libc/Libc-1439.141.1/stdlib/NetBSD/strfmon.c.auto.html
[3]: https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/locale/strfmon.c
[4]: 3d7b5d498a

Reviewed by:	kib
PR:	267282
Github PR:	#619
MFC after:	1 week
This commit is contained in:
Jose Luis Duran 2022-10-13 12:51:27 -03:00 committed by Konstantin Belousov
parent 0afd11d50f
commit 9e03b903e3
2 changed files with 4 additions and 3 deletions

View File

@ -239,8 +239,9 @@ vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
free(currency_symbol);
if (flags & USE_INTL_CURRENCY) {
currency_symbol = strdup(lc->int_curr_symbol);
if (currency_symbol != NULL)
space_char = *(currency_symbol+3);
if (currency_symbol != NULL &&
strlen(currency_symbol) > 3)
space_char = currency_symbol[3];
} else
currency_symbol = strdup(lc->currency_symbol);

View File

@ -197,7 +197,7 @@ ATF_TC_BODY(strfmon_international_currency_code, tc)
} tests[] = {
{ "en_US.UTF-8", "[USD 123.45]" }, /* XXX */
{ "de_DE.UTF-8", "[123,45 EUR ]" }, /* XXX */
{ "C", "[123.45]" }, /* XXX OOB access */
{ "C", "[123.45]" },
};
size_t i;
char actual[100];