0001-awk-fix-handling-of-literal-backslashes-in-replaceme.patch (2187B)
1 From c281b87c89918c05eddbb1101fb87999437a2505 Mon Sep 17 00:00:00 2001 2 From: Yao Zi <ziyao@disroot.org> 3 Date: Thu, 14 Nov 2024 11:11:50 +0000 4 Subject: [PATCH] awk: fix handling of literal backslashes in replacement 5 6 According to POSIX standard, a backslash in the replacement of sub() 7 should be treated as a literal backslash if it is not preceded by a '&' 8 or another backslash. But busybox awk skips it unconditionally, 9 regardless of the following character. For example, 10 11 $ echo "abc" | busybox awk 'sub(/abc/, "\\d")' 12 d 13 14 where \d is expected here. This is known to break rsync's documentation 15 converter. 16 17 Let's check the next character before skipping the backslash, following 18 POSIX standard and behavior of GNU awk. 19 20 Link: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html 21 Link: https://github.com/RsyncProject/rsync/blob/62bb9bba022ce6a29f8c92307d5569c338b2f711/help-from-md.awk#L22 22 Fixes: 5f84c5633 ("awk: fix backslash handling in sub() builtins") 23 Signed-off-by: Yao Zi <ziyao@disroot.org> 24 --- 25 editors/awk.c | 7 ++++++- 26 testsuite/awk.tests | 5 +++++ 27 2 files changed, 11 insertions(+), 1 deletion(-) 28 29 diff --git a/editors/awk.c b/editors/awk.c 30 index 64e752f4b..40f5ba7f7 100644 31 --- a/editors/awk.c 32 +++ b/editors/awk.c 33 @@ -2636,8 +2636,13 @@ static int awk_sub(node *rn, const char *repl, int nm, var *src, var *dest /*,in 34 resbuf = qrealloc(resbuf, residx + replen + n, &resbufsize); 35 memcpy(resbuf + residx, sp + pmatch[j].rm_so - start_ofs, n); 36 residx += n; 37 - } else 38 + } else { 39 +/* '\\' and '&' following a backslash keep its original meaning, any other 40 + * occurrence of a '\\' should be treated as literal */ 41 + if (bslash && c != '\\' && c != '&') 42 + resbuf[residx++] = '\\'; 43 resbuf[residx++] = c; 44 + } 45 bslash = 0; 46 } 47 } 48 diff --git a/testsuite/awk.tests b/testsuite/awk.tests 49 index be25f6696..61b3bc7d6 100755 50 --- a/testsuite/awk.tests 51 +++ b/testsuite/awk.tests 52 @@ -617,4 +617,9 @@ testing 'awk gsub erroneous word start match' \ 53 'abc\n' \ 54 '' '' 55 56 +testing 'awk sub literal backslash in replacement' \ 57 + 'awk '$sq'sub(/abc/, "\\\d")'$sq \ 58 + '\d\n' \ 59 + '' 'abc\n' 60 + 61 exit $FAILCOUNT 62 -- 63 2.47.1 64