From d6c0e1e2ffbf7913ab69d51cc794d48d41c8fcb1 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 27 Oct 2014 12:19:25 +0800 Subject: [BUILTIN] Handle embedded NULs correctly in printf https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=379227 On Sat, Jul 22, 2006 at 12:48:38PM +0200, A Mennucc wrote: > Package: dash > Version: 0.5.3-3 > Severity: normal > > hi > > here are the examples > > $ bash -c 'echo -n -e "A\0102C\00D\0E" | hexdump -c' > 0000000 A B C \0 D \0 E > 0000007 > > $ /bin/echo -n -e "A\0102C\00D\0E" | hexdump -c > 0000000 A B C \0 D \0 E > 0000007 > > $ zsh -c 'echo -n -e "A\0102C\00D\0E" | hexdump -c' > 0000000 A B C \0 D \0 E > 0000007 > > $ dash -c 'echo -n "A\0102C\00D\0E" | hexdump -c' > 0000000 A B C > 0000003 > > and also > > $ dash -c 'echo -n "ABC\0DEFGH" | hexdump -c' > 0000000 A B C > 0000003 > > As you see, dash 's builtin echo truncates the output at the first \0 > > a. > > -- System Information: > Debian Release: testing/unstable > APT prefers unstable > APT policy: (500, 'unstable'), (500, 'testing') > Architecture: i386 (i686) > Shell: /bin/sh linked to /bin/bash > Kernel: Linux 2.6.16-1-k7 > Locale: LANG=it_IT.UTF-8, LC_CTYPE=it_IT.UTF-8 (charmap=UTF-8) > > Versions of packages dash depends on: > ii libc6 2.3.6-15 GNU C Library: Shared libraries > > dash recommends no packages. > > -- debconf information: > * dash/sh: false > > -- > Andrea Mennucc > "E' un mondo difficile. Che vita intensa!" (Tonino Carotone) This patch fixes handling of embedded NULs using an approach similar to the one taken by NetBSD. In particular, we first determine the length of the output string, and then use a sequence of Xs of the same length as input to the underlying C printf to determine the amount of leading and trailing padding. Finally we replace the Xs with the actual string before writing it out. In order to print out the temporary string containing Xs and padding, a new helper xasprintf is added. Unlike asprintf though, our xasprintf prints to the ash stack rather than using straight malloc memory. Signed-off-by: Herbert Xu --- src/output.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/output.h') diff --git a/src/output.h b/src/output.h index f853e9d..c43d493 100644 --- a/src/output.h +++ b/src/output.h @@ -63,6 +63,7 @@ extern struct output memout; extern struct output *out1; extern struct output *out2; +void outmem(const char *, size_t, struct output *); void outstr(const char *, struct output *); #ifndef USE_GLIBC_STDIO void outcslow(int, struct output *); @@ -75,6 +76,7 @@ void out1fmt(const char *, ...) __attribute__((__format__(__printf__,1,2))); int fmtstr(char *, size_t, const char *, ...) __attribute__((__format__(__printf__,3,4))); +int xasprintf(char **, const char *, ...); #ifndef USE_GLIBC_STDIO void doformat(struct output *, const char *, va_list); #endif @@ -115,6 +117,7 @@ static inline void outc(int ch, struct output *file) #endif #define out1c(c) outc((c), out1) #define out2c(c) outcslow((c), out2) +#define out1mem(s, l) outmem((s), (l), out1) #define out1str(s) outstr((s), out1) #define out2str(s) outstr((s), out2) #define outerr(f) (f)->flags -- cgit 1.4.1