summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2016-06-27 20:54:02 +0000
committerpfg <pfg@FreeBSD.org>2016-06-27 20:54:02 +0000
commit2e698c8a838e8cc1cd41156fde4b69b1c4b6a89b (patch)
tree107f1846b0b5fc6aa179e1bee183ff7483bfa6e5 /usr.bin
parent79503b63f07526d4feb0aefabd04b7e048143ffb (diff)
downloadFreeBSD-src-2e698c8a838e8cc1cd41156fde4b69b1c4b6a89b.zip
FreeBSD-src-2e698c8a838e8cc1cd41156fde4b69b1c4b6a89b.tar.gz
sed(1): convert sed to use REG_STARTEND more explicitly.
Summarizing the findings in the OpenBSD list: This solves a reproduceable issue with very recent Mesa where REG_NOTBOL combined with a match at the begin of the string causes our regex library to treat the word as not begin of word. Bump __FreeBSD_version: JIC we hit the issue in recent Mesa ports. PR: 209352, 209387 (exp-run) Taken from: openbsd-tech (Martijn van Duren) MFC after: 1 month
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/sed/process.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c
index 950e30d..b9c25c0 100644
--- a/usr.bin/sed/process.c
+++ b/usr.bin/sed/process.c
@@ -70,7 +70,8 @@ static inline int applies(struct s_command *);
static void do_tr(struct s_tr *);
static void flush_appends(void);
static void lputs(char *, size_t);
-static int regexec_e(regex_t *, const char *, int, int, size_t);
+static int regexec_e(regex_t *, const char *, int, int, size_t,
+ size_t);
static void regsub(SPACE *, char *, char *);
static int substitute(struct s_command *);
@@ -271,7 +272,7 @@ new: if (!nflag && !pd)
* (lastline, linenumber, ps).
*/
#define MATCH(a) \
- ((a)->type == AT_RE ? regexec_e((a)->u.r, ps, 0, 1, psl) : \
+ ((a)->type == AT_RE ? regexec_e((a)->u.r, ps, 0, 1, 0, psl) : \
(a)->type == AT_LINE ? linenum == (a)->u.l : lastline())
/*
@@ -371,6 +372,7 @@ substitute(struct s_command *cp)
regex_t *re;
regoff_t slen;
int lastempty, n;
+ size_t le = 0;
char *s;
s = ps;
@@ -382,7 +384,7 @@ substitute(struct s_command *cp)
linenum, fname, cp->u.s->maxbref);
}
}
- if (!regexec_e(re, s, 0, 0, psl))
+ if (!regexec_e(re, s, 0, 0, 0, psl))
return (0);
SS.len = 0; /* Clean substitute space. */
@@ -392,28 +394,30 @@ substitute(struct s_command *cp)
do {
/* Copy the leading retained string. */
- if (n <= 1 && match[0].rm_so)
- cspace(&SS, s, match[0].rm_so, APPEND);
+ if (n <= 1 && match[0].rm_so - le)
+ cspace(&SS, s, match[0].rm_so - le, APPEND);
/* Skip zero-length matches right after other matches. */
- if (lastempty || match[0].rm_so ||
+ if (lastempty || (match[0].rm_so - le) ||
match[0].rm_so != match[0].rm_eo) {
if (n <= 1) {
/* Want this match: append replacement. */
- regsub(&SS, s, cp->u.s->new);
+ regsub(&SS, ps, cp->u.s->new);
if (n == 1)
n = -1;
} else {
/* Want a later match: append original. */
- if (match[0].rm_eo)
- cspace(&SS, s, match[0].rm_eo, APPEND);
+ if (match[0].rm_eo - le)
+ cspace(&SS, s, match[0].rm_eo - le,
+ APPEND);
n--;
}
}
/* Move past this match. */
- s += match[0].rm_eo;
- slen -= match[0].rm_eo;
+ s += (match[0].rm_eo - le);
+ slen -= (match[0].rm_eo - le);
+ le = match[0].rm_eo;
/*
* After a zero-length match, advance one byte,
@@ -424,13 +428,15 @@ substitute(struct s_command *cp)
slen = -1;
else
slen--;
- if (*s != '\0')
+ if (*s != '\0') {
cspace(&SS, s++, 1, APPEND);
+ le++;
+ }
lastempty = 1;
} else
lastempty = 0;
- } while (n >= 0 && slen >= 0 && regexec_e(re, s, REG_NOTBOL, 0, slen));
+ } while (n >= 0 && slen >= 0 && regexec_e(re, ps, 0, 0, le, psl));
/* Did not find the requested number of matches. */
if (n > 1)
@@ -640,7 +646,7 @@ lputs(char *s, size_t len)
static int
regexec_e(regex_t *preg, const char *string, int eflags, int nomatch,
- size_t slen)
+ size_t start, size_t stop)
{
int eval;
@@ -651,8 +657,8 @@ regexec_e(regex_t *preg, const char *string, int eflags, int nomatch,
defpreg = preg;
/* Set anchors */
- match[0].rm_so = 0;
- match[0].rm_eo = slen;
+ match[0].rm_so = start;
+ match[0].rm_eo = stop;
eval = regexec(defpreg, string,
nomatch ? 0 : maxnsub + 1, match, eflags | REG_STARTEND);
OpenPOWER on IntegriCloud