Fix printf-family function not treating negative precisions as if they had been omitted

The C standard states that, within the context of a printf-family
function, when specifying the precision of a conversion specification:

> A negative precision argument is taken as if the precision were
> omitted.
- C Standard, 7.23.6.1. The fprintf function

Cosmopolitan currently fails to do so and treats a negative precision
as if it had a value of 0, which is non-conforming.

This patch fixes this.
This commit is contained in:
Gabriel Ravier 2023-03-23 21:58:14 +01:00
parent 792b1c84c0
commit e816e97762
2 changed files with 22 additions and 1 deletions

View file

@ -16,10 +16,11 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/fmt.h"
#include "libc/assert.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/fmt.internal.h"
#include "libc/fmt/internal.h"
#include "libc/fmt/itoa.h"
@ -255,6 +256,7 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
}
if (prec < 0) {
prec = 0;
flags &= ~FLAGS_PRECISION;
}
// evaluate length field

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/fmt.h"
#include "libc/limits.h"
#include "libc/log/log.h"
#include "libc/math.h"
@ -84,6 +85,24 @@ TEST(fmt, b) {
}
TEST(fmt, s) {
EXPECT_STREQ("123456", _gc(xasprintf("%4.*s", -5, "123456")));
EXPECT_STREQ("123456789", _gc(xasprintf("%4.*s", -5, "123456789")));
EXPECT_STREQ("12345678901234567890",
_gc(xasprintf("%4.*s", -5, "12345678901234567890")));
EXPECT_STREQ("123456789012345678901234567890",
_gc(xasprintf("%4.*s", -5, "123456789012345678901234567890")));
EXPECT_STREQ(
"1234567890123456789012345678901234567890",
_gc(xasprintf("%4.*s", -5, "1234567890123456789012345678901234567890")));
EXPECT_STREQ(
"12345678901234567890123456789012345678901234567890",
_gc(xasprintf("%4.*s", -5,
"12345678901234567890123456789012345678901234567890")));
EXPECT_STREQ(
"123456789012345678901234567890123456789012345678901234567890",
_gc(xasprintf(
"%4.*s", -5,
"123456789012345678901234567890123456789012345678901234567890")));
EXPECT_STREQ("Wide character output test",
_gc(xasprintf("%S", L"Wide character output test")));
}