From: Alexander Sverdlin Date: Thu, 20 Feb 2025 12:49:07 +0000 (+0100) Subject: tiny-printf: emit \0 as %c X-Git-Tag: v2025.07-rc1~18^2~66 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1bc125becaa5e612923a9cfa1ec8e9f0b88ac28e;p=pandora-u-boot.git tiny-printf: emit \0 as %c The current code has a problematic corner case with formar "%c" and 0 as parameter. The proper zero byte is being emitted into digit buffer but the final copy into outstr expects null-terminated string and doesn't copy the required \0 byte. This has lead to malformed TFTP packets, refer to tftp_send() which relies on %c to generate multiple zero-terminated strings in one buffer. Introduce a variable to force the copy of one character in this case. The new behaviour is consistent with non-tiny implementation. Reported-by: Chintan Vankar Signed-off-by: Alexander Sverdlin --- diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c index 0503c17341f..faf55d7f327 100644 --- a/lib/tiny-printf.c +++ b/lib/tiny-printf.c @@ -211,6 +211,7 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va) bool lz = false; int width = 0; bool islong = false; + bool force_char = false; ch = *(fmt++); if (ch == '-') @@ -300,6 +301,8 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va) break; case 'c': out(info, (char)(va_arg(va, int))); + /* For the case when it's \0 char */ + force_char = true; break; case 's': p = va_arg(va, char*); @@ -317,8 +320,10 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va) while (width-- > 0) info->putc(info, lz ? '0' : ' '); if (p) { - while ((ch = *p++)) + while ((ch = *p++) || force_char) { info->putc(info, ch); + force_char = false; + } } } }