[PATCH] awk: allow printf('%c') to output NUL, closes 13486
Denys Vlasenko
vda.linux at googlemail.com
Tue Feb 2 12:53:03 UTC 2021
Applied, thanks!
On Wed, Jan 27, 2021 at 12:19 PM Ron Yorston <rmy at pobox.com> wrote:
>
> Treat the output of printf as binary rather than a null-terminated
> string so that NUL characters can be output.
>
> This is considered to be a GNU extension, though it's also available
> in mawk and FreeBSD's awk.
>
> function old new delta
> evaluate 3487 3504 +17
> awk_printf 504 519 +15
> ------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 2/0 up/down: 32/0) Total: 32 bytes
>
> Signed-off-by: Ron Yorston <rmy at pobox.com>
> ---
> editors/awk.c | 18 +++++++++++++++---
> testsuite/awk.tests | 5 +++++
> 2 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/editors/awk.c b/editors/awk.c
> index 2c15f9e4e..b4f6a3741 100644
> --- a/editors/awk.c
> +++ b/editors/awk.c
> @@ -2155,7 +2155,10 @@ static int fmt_num(char *b, int size, const char *format, double n, int int_as_i
> }
>
> /* formatted output into an allocated buffer, return ptr to buffer */
> -static char *awk_printf(node *n)
> +#if !ENABLE_FEATURE_AWK_GNU_EXTENSIONS
> +# define awk_printf(a, b) awk_printf(a)
> +#endif
> +static char *awk_printf(node *n, int *len)
> {
> char *b = NULL;
> char *fmt, *s, *f;
> @@ -2209,6 +2212,10 @@ static char *awk_printf(node *n)
> nvfree(v);
> b = xrealloc(b, i + 1);
> b[i] = '\0';
> +#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
> + if (len)
> + *len = i;
> +#endif
> return b;
> }
>
> @@ -2666,6 +2673,7 @@ static var *evaluate(node *op, var *res)
> case XC( OC_PRINT ):
> case XC( OC_PRINTF ): {
> FILE *F = stdout;
> + IF_FEATURE_AWK_GNU_EXTENSIONS(int len;)
>
> if (op->r.n) {
> rstream *rsm = newfile(R.s);
> @@ -2703,8 +2711,12 @@ static var *evaluate(node *op, var *res)
> fputs(getvar_s(intvar[ORS]), F);
>
> } else { /* OC_PRINTF */
> - char *s = awk_printf(op1);
> + char *s = awk_printf(op1, &len);
> +#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
> + fwrite(s, len, 1, F);
> +#else
> fputs(s, F);
> +#endif
> free(s);
> }
> fflush(F);
> @@ -2978,7 +2990,7 @@ static var *evaluate(node *op, var *res)
> break;
>
> case XC( OC_SPRINTF ):
> - setvar_p(res, awk_printf(op1));
> + setvar_p(res, awk_printf(op1, NULL));
> break;
>
> case XC( OC_UNARY ): {
> diff --git a/testsuite/awk.tests b/testsuite/awk.tests
> index 92c83d719..cf9b722dc 100755
> --- a/testsuite/awk.tests
> +++ b/testsuite/awk.tests
> @@ -383,6 +383,11 @@ testing "awk errors on missing delete arg" \
> "awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" ""
> SKIP=
>
> +optional FEATURE_AWK_GNU_EXTENSIONS
> +testing "awk printf('%c') can output NUL" \
> + "awk '{printf(\"hello%c null\n\", 0)}'" "hello\0 null\n" "" "\n"
> +SKIP=
> +
> # testing "description" "command" "result" "infile" "stdin"
> testing 'awk negative field access' \
> 'awk 2>&1 -- '\''{ $(-1) }'\' \
> --
> 2.29.2
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
More information about the busybox
mailing list