summaryrefslogtreecommitdiff
path: root/include/printf.h
diff options
context:
space:
mode:
authorCraig Hesling <hesling@chromium.org>2019-06-13 18:22:27 -0700
committerCommit Bot <commit-bot@chromium.org>2019-07-18 01:11:49 +0000
commitaa5923a716aa155a1710ea85ef587a0c58711372 (patch)
treef3c65dea7be9517bd8657cceb4448df6e94151c0 /include/printf.h
parentdca00fcd76546d28f64dfc805c548d9fb34a7ba4 (diff)
downloadchrome-ec-aa5923a716aa155a1710ea85ef587a0c58711372.tar.gz
printf: Fix hexdump and string 0 precision
This patch addresses a few issues with the current formatter. The major points are as follows: 1. Cannot specify precision 0 (truncate all) for string or hexdump 2. Forced safe precision for malformed strings 3. No padding when using hexdump 4. Bad error EC_ERROR_INVAL in vsnprintf 5. Documentation errors For (1), no piece of code explicitly sets the precision to 0 in order to invoke the default behavior, which is currently no precision limit. You can check using the following grep line: grep -rI '%[\*0-9]\{0,20\}\.0\{1,20\}[a-zA-Z]' However, there are many cases where the precision is used to limit the character output (as it should be). grep -rI '%[\*0-9]\{0,20\}\.[\*0-9]\{1,20\}[a-zA-Z]' There are many more instances that use variable precision without checking if the precision is zero. One of which is the following: crrev.com/4a4e2c71a0f6aaa50e0728922f84a7d54c14380a/test/host_command_fuzz.c#116 https://clusterfuzz.com/testcase-detail/5699023975088128 Our current implementation will insert ERROR and stop processing, if a precision of zero is detected when using the hexdump flag. This results in a badly formatted console line or runtime string, when the intended behavior would be to simply read no bytes. In the aforementioned fuzzer case, outputting ERROR triggers a false positive. Our printf should handle explicit zero precision similar to stdlib's printf, which means truncating all the way to zero positions, if specified. For (2), our current implementation uses strlen to identify the length of the input string, regardless of the set precision. Since this is an embedded platform, we should use strnlen to impose safe limits, when a precision is specified. For (3), our implementation should support padding and adjusting of all formatter types, since that is a primary feature of a printf formatter. The remaining commented code highlights odd behavior that should be fixed at some point, but is not critical. BUG=chromium:974084 TEST=Checked for any format lines that rely on a set precision of 0 grep -rI '%[\*0-9]\{0,20\}\.[\*0-9]\{1,20\}[a-zA-Z]' TEST=make run-printf V=1 BRANCH=none Change-Id: I897c53cce20a701fcbe8fb9572eb878817525cc3 Signed-off-by: Craig Hesling <hesling@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1659835 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'include/printf.h')
-rw-r--r--include/printf.h9
1 files changed, 5 insertions, 4 deletions
diff --git a/include/printf.h b/include/printf.h
index 7d9c2ab5e2..ea1445a526 100644
--- a/include/printf.h
+++ b/include/printf.h
@@ -68,7 +68,7 @@
* @param context Context pointer to pass to addchar()
* @param format Format string (see above for acceptable formats)
* @param args Parameters
- * @return EC_SUCCESS, or non-zero if output was truncated.
+ * @return EC_SUCCESS, or EC_ERROR_OVERFLOW if the output was truncated.
*/
__stdlib_compat int vfnprintf(int (*addchar)(void *context, int c),
void *context, const char *format, va_list args);
@@ -81,12 +81,12 @@ __stdlib_compat int vfnprintf(int (*addchar)(void *context, int c),
* @param str Destination string
* @param size Size of destination in bytes
* @param format Format string
- * @return EC_SUCCESS, or non-zero if output was truncated.
+ * @return EC_SUCCESS, or EC_ERROR_OVERFLOW if the output was truncated.
*/
__stdlib_compat int snprintf(char *str, int size, const char *format, ...);
/**
- * Print formatted outut to a string.
+ * Print formatted output to a string.
*
* Guarantees null-termination if size!=0.
*
@@ -94,7 +94,8 @@ __stdlib_compat int snprintf(char *str, int size, const char *format, ...);
* @param size Size of destination in bytes
* @param format Format string
* @param args Parameters
- * @return EC_SUCCESS, or non-zero if output was truncated.
+ * @return The string length written to str, or a negative value on error.
+ * The negative values can be -EC_ERROR_INVAL or -EC_ERROR_OVERFLOW.
*/
__stdlib_compat int vsnprintf(char *str, int size, const char *format,
va_list args);