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 <c-vankar@ti.com> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
This commit is contained in:

committed by
Tom Rini

parent
0928e3cc71
commit
1bc125beca
@@ -211,6 +211,7 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
|
|||||||
bool lz = false;
|
bool lz = false;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
bool islong = false;
|
bool islong = false;
|
||||||
|
bool force_char = false;
|
||||||
|
|
||||||
ch = *(fmt++);
|
ch = *(fmt++);
|
||||||
if (ch == '-')
|
if (ch == '-')
|
||||||
@@ -300,6 +301,8 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
|
|||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
out(info, (char)(va_arg(va, int)));
|
out(info, (char)(va_arg(va, int)));
|
||||||
|
/* For the case when it's \0 char */
|
||||||
|
force_char = true;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
p = va_arg(va, char*);
|
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)
|
while (width-- > 0)
|
||||||
info->putc(info, lz ? '0' : ' ');
|
info->putc(info, lz ? '0' : ' ');
|
||||||
if (p) {
|
if (p) {
|
||||||
while ((ch = *p++))
|
while ((ch = *p++) || force_char) {
|
||||||
info->putc(info, ch);
|
info->putc(info, ch);
|
||||||
|
force_char = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user