[git commit] awk: fix printf "%-10c", 0

Denys Vlasenko vda.linux at googlemail.com
Mon Jul 12 09:27:11 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=8d269ef85984f6476e7fdbec2c5a70f3b5c48a72
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
awk_printf                                           596     626     +30

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 editors/awk.c       | 9 +++++----
 testsuite/awk.tests | 8 ++++++++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/editors/awk.c b/editors/awk.c
index 465033f5f..437d87ecf 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2360,10 +2360,11 @@ static char *awk_printf(node *n, size_t *len)
 		 */
 		if (c == 'c') {
 			char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg);
-			s = xasprintf(s, cc);
-			/* + 1 if cc == NUL: handle printf "%c" 0 case
-			 * (and printf "%22c" 0 etc, but still fails for e.g. printf "%-22c" 0) */
-			slen = strlen(s) + (cc == '\0');
+			char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */);
+			slen = strlen(r);
+			if (cc == '\0') /* if cc is NUL, re-format the string with it */
+				sprintf(r, s, cc);
+			s = r;
 		} else {
 			if (c == 's') {
 				s = xasprintf(s, getvar_s(arg));
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
index 242c897d1..3cddb4dd4 100755
--- a/testsuite/awk.tests
+++ b/testsuite/awk.tests
@@ -415,6 +415,14 @@ testing "awk printf('%c') can output NUL" \
 	"awk '{printf(\"hello%c null\n\", 0)}'" "hello\0 null\n" "" "\n"
 SKIP=
 
+optional FEATURE_AWK_GNU_EXTENSIONS
+testing "awk printf('%-10c') can output NUL" \
+	"awk 'BEGIN { printf \"[%-10c]\n\", 0 }' | od -tx1" "\
+0000000 5b 00 20 20 20 20 20 20 20 20 20 5d 0a
+0000015
+" "" ""
+SKIP=
+
 # testing "description" "command" "result" "infile" "stdin"
 testing 'awk negative field access' \
 	'awk 2>&1 -- '\''{ $(-1) }'\' \


More information about the busybox-cvs mailing list