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

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

Reply via email to