diff mbox series

tiny-printf: emit \0 as %c

Message ID 20250220124908.3396843-1-alexander.sverdlin@siemens.com
State New
Headers show
Series tiny-printf: emit \0 as %c | expand

Commit Message

A. Sverdlin Feb. 20, 2025, 12:49 p.m. UTC
From: Alexander Sverdlin <alexander.sverdlin@siemens.com>

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 <c-vankar@ti.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
---
 lib/tiny-printf.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
diff mbox series

Patch

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;
+				}
 			}
 		}
 	}