strfmon: EINVAL if the '+' flag and both signs are empty
According to the Open Group Base Specifications Issue 8[1], strfmon(3) should return EINVAL when the '+' flag was included in a conversion specification and the locale's positive_sign and negative_sign values would both be returned by localeconv(3) as empty strings. Austin Group Defect 1199[2] is applied, adding the [EINVAL] error. [1]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/strfmon.html [2]: https://www.austingroupbugs.net/view.php?id=1199 Reviewed by: kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D53912
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd December 6, 2023
|
.Dd November 24, 2025
|
||||||
.Dt STRFMON 3
|
.Dt STRFMON 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -182,6 +182,16 @@ function will fail if:
|
|||||||
Conversion stopped due to lack of space in the buffer.
|
Conversion stopped due to lack of space in the buffer.
|
||||||
.It Bq Er EINVAL
|
.It Bq Er EINVAL
|
||||||
The format string is invalid.
|
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
|
.It Bq Er ENOMEM
|
||||||
Not enough memory for temporary buffers.
|
Not enough memory for temporary buffers.
|
||||||
.El
|
.El
|
||||||
|
|||||||
@@ -171,7 +171,9 @@ vstrfmon_l(char *__restrict s, size_t maxsize, locale_t loc,
|
|||||||
flags &= ~(NEED_GROUPING);
|
flags &= ~(NEED_GROUPING);
|
||||||
continue;
|
continue;
|
||||||
case '+': /* use locale defined signs */
|
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;
|
goto format_error;
|
||||||
flags |= (SIGN_POSN_USED | LOCALE_POSN);
|
flags |= (SIGN_POSN_USED | LOCALE_POSN);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -234,11 +234,11 @@ ATF_TC_BODY(strfmon_plus_or_parenthesis, tc)
|
|||||||
if (setlocale(LC_MONETARY, "C") == NULL)
|
if (setlocale(LC_MONETARY, "C") == NULL)
|
||||||
atf_tc_skip("unable to setlocale(): %s", tests[i].locale);
|
atf_tc_skip("unable to setlocale(): %s", tests[i].locale);
|
||||||
|
|
||||||
/* ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1,
|
ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1,
|
||||||
"[%+n] [%+n]", 123.45, -123.45)); XXX */
|
"[%+n] [%+n]", 123.45, -123.45));
|
||||||
|
|
||||||
/* ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1,
|
ATF_CHECK_ERRNO(EINVAL, strfmon(actual, sizeof(actual) - 1,
|
||||||
"[%+i] [%+i]", 123.45, -123.45)); XXX */
|
"[%+i] [%+i]", 123.45, -123.45));
|
||||||
}
|
}
|
||||||
|
|
||||||
ATF_TC(strfmon_l);
|
ATF_TC(strfmon_l);
|
||||||
|
|||||||
Reference in New Issue
Block a user