From owner-svn-src-all@freebsd.org Wed May 25 15:42:40 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C239CB4AE81; Wed, 25 May 2016 15:42:40 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 94E8E1C02; Wed, 25 May 2016 15:42:40 +0000 (UTC) (envelope-from pfg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4PFgdME076997; Wed, 25 May 2016 15:42:39 GMT (envelope-from pfg@FreeBSD.org) Received: (from pfg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4PFgdRG076996; Wed, 25 May 2016 15:42:39 GMT (envelope-from pfg@FreeBSD.org) Message-Id: <201605251542.u4PFgdRG076996@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: pfg set sender to pfg@FreeBSD.org using -f From: "Pedro F. Giffuni" Date: Wed, 25 May 2016 15:42:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300684 - head/usr.bin/sed X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 May 2016 15:42:40 -0000 Author: pfg Date: Wed May 25 15:42:39 2016 New Revision: 300684 URL: https://svnweb.freebsd.org/changeset/base/300684 Log: sed: 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. Thanks to Martijn van Duren and Ingo Schwarze for taking the time to solve this in the least invasive way. PR: 209352, 209387 Taken from: openbsd-tech (Martijn van Duren) MFC after: 1 month Modified: head/usr.bin/sed/process.c Modified: head/usr.bin/sed/process.c ============================================================================== --- head/usr.bin/sed/process.c Wed May 25 15:35:23 2016 (r300683) +++ head/usr.bin/sed/process.c Wed May 25 15:42:39 2016 (r300684) @@ -71,7 +71,8 @@ static inline int applies(struct s_comm 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 *); @@ -281,7 +282,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()) /* @@ -381,6 +382,7 @@ substitute(struct s_command *cp) regex_t *re; regoff_t slen; int lastempty, n; + size_t le = 0; char *s; s = ps; @@ -392,7 +394,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. */ @@ -402,28 +404,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, @@ -434,13 +438,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) @@ -652,7 +658,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; @@ -663,8 +669,8 @@ regexec_e(regex_t *preg, const char *str 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);