Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/klibc/rt_vsnprintf_std.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,9 @@ static inline output_gadget_t buffer_gadget(char* buffer, size_t buffer_size)
static inline printf_size_t strnlen_s_(const char* str, printf_size_t maxsize)
{
const char* s;
for (s = str; *s && maxsize--; ++s);
// check the bound before dereferencing,
// so that at most maxsize characters are read.
for (s = str; maxsize && *s; ++s, --maxsize);
return (printf_size_t)(s - str);
}

Expand Down Expand Up @@ -1053,7 +1055,14 @@ static inline void format_string_loop(output_gadget_t* output, const char* forma
}
else if (*format == '*') {
const int precision_ = va_arg(args, int);
precision = precision_ > 0 ? (printf_size_t) precision_ : 0U;
if (precision_ < 0)
{
flags &= ~FLAGS_PRECISION;
}
else
{
precision = (printf_size_t)precision_;
}
ADVANCE_IN_FORMAT_STRING(format);
}
}
Expand Down
17 changes: 9 additions & 8 deletions src/klibc/rt_vsnprintf_tiny.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ static char *print_number(char *buf,
static const char large_digits[] = "0123456789ABCDEF";
int i = 0;
int size = 0;
int is_zero = 0;

size = s;

Expand Down Expand Up @@ -151,6 +152,7 @@ static char *print_number(char *buf,
}

i = 0;
is_zero = (num == 0);
if (num == 0)
{
tmp[i++] = '0';
Expand Down Expand Up @@ -253,7 +255,7 @@ static char *print_number(char *buf,
}

/* put number in the temporary buffer */
while (i-- > 0 && (precision_bak != 0))
while (i-- > 0 && !((precision_bak == 0) && is_zero))
{
if (buf < end)
{
Expand Down Expand Up @@ -382,8 +384,12 @@ int rt_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
++fmt;
/* it's the next argument */
precision = va_arg(args, int);
if (precision < 0)
{
precision = -1;
}
}
if (precision < 0)
else
{
precision = 0;
}
Expand Down Expand Up @@ -451,12 +457,7 @@ int rt_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
s = "(null)";
}

for (len = 0; (len != field_width) && (s[len] != '\0'); len++);

if (precision > 0 && len > precision)
{
len = precision;
}
for (len = 0; (precision < 0 || len < precision) && (s[len] != '\0'); len++);

if (!(flags & LEFT))
{
Expand Down
25 changes: 17 additions & 8 deletions src/klibc/utest/TC_rt_sprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,7 @@ SPRINTF_TEST_CASE(specifier)
SPRINTF_TEST_CASE(width)
{
char buffer[base_buffer_size];
#ifdef RT_KLIBC_USING_VSNPRINTF_STANDARD
SPRINTF_CHECK("Hello testing", buffer, "%1s", "Hello testing");
#endif /* RT_KLIBC_USING_VSNPRINTF_STANDARD */
SPRINTF_CHECK("1024", buffer, "%1d", 1024);
SPRINTF_CHECK("-1024", buffer, "%1d", -1024);
SPRINTF_CHECK("1024", buffer, "%1i", 1024);
Expand Down Expand Up @@ -837,10 +835,6 @@ SPRINTF_TEST_CASE(tiny_floating_point_values)
SPRINTF_TEST_CASE(length)
{
char buffer[base_buffer_size];
SPRINTF_CHECK("", buffer, "%.0s", "Hello testing");
SPRINTF_CHECK(" ", buffer, "%20.0s", "Hello testing");
SPRINTF_CHECK("", buffer, "%.s", "Hello testing");
SPRINTF_CHECK(" ", buffer, "%20.s", "Hello testing");
SPRINTF_CHECK(" 1024", buffer, "%20.0d", 1024);
SPRINTF_CHECK(" -1024", buffer, "%20.0d", -1024);
SPRINTF_CHECK(" ", buffer, "%20.d", 0);
Expand Down Expand Up @@ -972,6 +966,19 @@ SPRINTF_TEST_CASE(pointer)
SPRINTF_TEST_CASE(string_length)
{
char buffer[base_buffer_size];
#if !defined(RT_KLIBC_USING_LIBC_VSNPRINTF)
char unterminated[] = { 'A', 'B', 'C' };
#endif

SPRINTF_CHECK("", buffer, "%.0s", "Hello testing");
SPRINTF_CHECK(" ", buffer, "%20.0s", "Hello testing");
SPRINTF_CHECK("", buffer, "%.s", "Hello testing");
SPRINTF_CHECK(" ", buffer, "%20.s", "Hello testing");
SPRINTF_CHECK("", buffer, "%.*s", 0, "Hello testing");
#if !defined(RT_KLIBC_USING_LIBC_VSNPRINTF)
SPRINTF_CHECK("Hello testing", buffer, "%.*s", -1, "Hello testing");
SPRINTF_CHECK("ABC", buffer, "%.3s", unterminated);
#endif
SPRINTF_CHECK("This", buffer, "%.4s", "This is a test");
SPRINTF_CHECK("test", buffer, "%.4s", "test");
SPRINTF_CHECK("123", buffer, "%.7s", "123");
Expand All @@ -989,14 +996,16 @@ SPRINTF_TEST_CASE(misc)
{
char buffer[base_buffer_size];
SPRINTF_CHECK("53000atest-20 bit", buffer, "%u%u%ctest%d %s", 5, 3000, 'a', -20, "bit");
#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS
SPRINTF_CHECK("0.33", buffer, "%.*f", 2, 0.33333333);
SPRINTF_CHECK("1", buffer, "%.*d", -1, 1);
SPRINTF_CHECK("foo", buffer, "%.3s", "foobar");
SPRINTF_CHECK(" ", buffer, "% .0d", 0);
SPRINTF_CHECK("5", buffer, "%.0d", 5);
SPRINTF_CHECK("", buffer, "%.0d", 0);
SPRINTF_CHECK(" 00004", buffer, "%10.5d", 4);
SPRINTF_CHECK("hi x", buffer, "%*sx", -3, "hi");
SPRINTF_CHECK("00123 ", buffer, "%-20.5i", 123);
#ifdef RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS
SPRINTF_CHECK("0.33", buffer, "%.*f", 2, 0.33333333);
SPRINTF_CHECK("-67224.546875000000000000", buffer, "%.18f", -67224.546875);
#endif /* RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS */
#ifdef RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS
Expand Down
Loading