Upstream 0f968ceb7bc1a65773979ef419872ce43677c790 Original by Paolo Bonzini <bonzini@gnu.org> - 2012-04-13 Modified by Martin Briza (original patch didn't apply clearly) * sed/compile.c (convert_number): Remove default_char argument, expect buf to point to it. Remove maxdigits argument and compute it on the fly. (normalize_text): Unify calls to convert_number under the convert label. For TEXT_REPLACEMENT add a backslash to the output if convert_number returns ch == '&'. -- diff -rpu sed-4.2.1/sed/compile.c sed-4.2.1-modified/sed/compile.c --- sed-4.2.1/sed/compile.c 2009-06-17 14:54:43.000000000 +0200 +++ sed-4.2.1-modified/sed/compile.c 2012-06-12 16:46:19.310301149 +0200 @@ -300,20 +300,19 @@ add_then_next(b, ch) return inchar(); } -static char * convert_number P_((char *, char *, const char *, int, int, int)); +static char * convert_number P_((char *, char *, const char *, int)); static char * -convert_number(result, buf, bufend, base, maxdigits, default_char) +convert_number(result, buf, bufend, base) char *result; char *buf; const char *bufend; int base; - int maxdigits; - int default_char; { int n = 0; + int max = 1; char *p; - for (p=buf; p < bufend && maxdigits-- > 0; ++p) + for (p=buf+1; p < bufend && max <= 255; ++p, max *= base) { int d = -1; switch (*p) @@ -339,8 +338,8 @@ convert_number(result, buf, bufend, base break; n = n * base + d; } - if (p == buf) - *result = default_char; + if (p == buf+1) + *result = *buf; else *result = n; return p; @@ -1417,6 +1416,8 @@ normalize_text(buf, len, buftype) const char *bufend = buf + len; char *p = buf; char *q = buf; + char ch; + int base; /* This variable prevents normalizing text within bracket subexpressions when conforming to POSIX. If 0, we @@ -1464,14 +1465,12 @@ normalize_text(buf, len, buftype) case 'v': *q++ = '\v'; p++; continue; case 'd': /* decimal byte */ - p = convert_number(q, p+1, bufend, 10, 3, 'd'); - q++; - continue; + base = 10; + goto convert; case 'x': /* hexadecimal byte */ - p = convert_number(q, p+1, bufend, 16, 2, 'x'); - q++; - continue; + base = 16; + goto convert; #ifdef REG_PERL case '0': case '1': case '2': case '3': @@ -1480,8 +1479,8 @@ normalize_text(buf, len, buftype) && p+1 < bufend && p[1] >= '0' && p[1] <= '9') { - p = convert_number(q, p, bufend, 8, 3, *p); - q++; + base = 8; + goto convert; } else { @@ -1495,8 +1494,8 @@ normalize_text(buf, len, buftype) case 'o': /* octal byte */ if (!(extended_regexp_flags & REG_PERL)) { - p = convert_number(q, p+1, bufend, 8, 3, 'o'); - q++; + base = 8; + goto convert; } else { @@ -1508,10 +1507,16 @@ normalize_text(buf, len, buftype) continue; #else case 'o': /* octal byte */ - p = convert_number(q, p+1, bufend, 8, 3, 'o'); - q++; - continue; + base = 8; #endif +convert: + p = convert_number(&ch, p, bufend, base); + + /* for an ampersand in a replacement, pass the \ up one level */ + if (buftype == TEXT_REPLACEMENT && ch == '&') + *q++ = '\\'; + *q++ = ch; + continue; case 'c': if (++p < bufend) diff -rpu sed-4.2.1/testsuite/Makefile.am sed-4.2.1-modified/testsuite/Makefile.am --- sed-4.2.1/testsuite/Makefile.am 2009-06-25 20:55:35.000000000 +0200 +++ sed-4.2.1-modified/testsuite/Makefile.am 2012-06-12 16:45:56.875331158 +0200 @@ -24,7 +24,7 @@ SEDTESTS += \ fasts uniq manis khadafy linecnt eval distrib 8to7 y-bracket \ y-newline allsub cv-vars classes middle bsd stdin flipcase \ insens subwrite writeout readin insert utf8-1 utf8-2 utf8-3 utf8-4 \ - badenc inplace-hold brackets \ + badenc inplace-hold brackets amp-escape\ help version file quiet \ factor binary3 binary2 binary dc @@ -39,6 +39,7 @@ EXTRA_DIST = \ 8bit.good 8bit.inp 8bit.sed \ 8to7.good 8to7.inp 8to7.sed \ allsub.good allsub.inp allsub.sed \ + amp-escape.good amp-escape.inp amp-escape.sed \ appquit.good appquit.inp appquit.sed \ binary.good binary.inp binary.sed binary2.sed binary3.sed \ bkslashes.good bkslashes.inp bkslashes.sed \ diff -rpu sed-4.2.1/testsuite/Makefile.tests sed-4.2.1-modified/testsuite/Makefile.tests --- sed-4.2.1/testsuite/Makefile.tests 2009-06-25 20:55:35.000000000 +0200 +++ sed-4.2.1-modified/testsuite/Makefile.tests 2012-06-12 16:46:17.195303978 +0200 @@ -21,7 +21,7 @@ SKIP = :>$@.skip; exit 77 enable sep inclib 8bit 8to7 newjis xabcx dollar noeol bkslashes \ numsub head madding mac-mf empty xbxcx xbxcx3 recall recall2 xemacs \ appquit fasts uniq manis linecnt khadafy allsub flipcase space modulo \ -y-bracket y-newline insert brackets:: +y-bracket y-newline insert brackets amp-escape:: $(SEDENV) $(SED) -f $(srcdir)/$@.sed \ < $(srcdir)/$@.inp | $(TR) -d \\r > $@.out $(CMP) $(srcdir)/$@.good $@.out