d from commit 1fd018972a18b682521bb8f004dfd162327e5db2) --- lib/libc/stdlib/strfmon.3 | 12 +++++++++++- lib/libc/stdlib/strfmon.c | 4 +++- lib/libc/tests/stdlib/strfmon_test.c | 8 ++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/libc/stdlib/strfmon.3 b/lib/libc/stdlib/strfmon.3 index 20cc560d401d..d537d9d05fa7 100644 --- a/lib/libc/stdlib/strfmon.3 +++ b/lib/libc/stdlib/strfmon.3 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 6, 2023 +.Dd November 24, 2025 .Dt STRFMON 3 .Os .Sh NAME @@ -182,6 +182,16 @@ function will fail if: Conversion stopped due to lack of space in the buffer. .It Bq Er EINVAL The format string is invalid. +.It Bq Er EINVAL +The +.Cm + +flag was included in a conversion specification and the locale's +.Va positive_sign +and +.Va negative_sign +values would both be returned by +.Xr localeconv 3 +as empty strings. .It Bq Er ENOMEM Not enough memory for temporary buffers. .El diff --git a/lib/libc/stdlib/strfmon.c b/lib/libc/stdlib/strfmon.c index 230d194233f5..b19d9fc43369 100644 --- a/lib/libc/stdlib/strfmon.c +++ b/lib/libc/stdlib/strfmon.c @@ -171,7 +171,9 @@ literal: flags &= ~(NEED_GROUPING); continue; case '+': /* use locale defined signs */ - if (flags & SIGN_POSN_USED) + if ((flags & SIGN_POSN_USED) || + ((lc->positive_sign[0] == '\0') && + (lc->negative_sign[0] == '\0'))) goto format_error; flags |= (SIGN_POSN_USED | LOCALE_POSN); continue; diff --git a/lib/libc/tests/stdlib/strfmon_test.c b/lib/libc/tests/stdlib/strfmon_test.c index 3c97d61ba82c..165ddcc2ab56 100644 --- a/lib/libc/tests/stdlib/strfmon_test.c +++ b/lib/libc/tests/stdlib/strfmon_test.c @@ -234,11 +234,11 @@ ATF_TC_BODY(strfmon_plus_or_parenthesis, tc) if (setlocale(LC_MONETARY, "C") == NULL) atf_tc_skip("unable to setlocale(): %s", tests[i].locale); - /* ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1, - "[%+n] [%+n]", 123.45, -123.45)); XXX */ + ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1, + "[%+n] [%+n]", 123.45, -123.45)); - /* ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1, - "[%+i] [%+i]", 123.45, -123.45)); XXX */ + ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1, + "[%+i] [%+i]", 123.45, -123.45)); } ATF_TC(strfmon_l);