Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm
Precedence: bulk
X-No-Archive: yes
List-Id: Zsh Workers List <zsh-workers.zsh.org>
List-Post: <mailto:zsh-workers@zsh.org>
List-Help: <mailto:zsh-workers-help@zsh.org>
X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au
X-Spam-Level: 
X-Spam-Status: No, score=-0.6 required=5.0 tests=BAYES_00,TO_NO_BRKTS_PCNT
	autolearn=no autolearn_force=no version=3.4.1
Date: Sat, 23 Apr 2016 11:51:36 +0200
From: Mikael Berthe <mikael.berthe@lilotux.net>
To: zsh-workers@zsh.org
Subject: Segfault with PCRE   (Re: Strange behavior of [[)
Message-ID: <20160423095136.GA5286@lilotux.net>
References: <5577AE8F.6060902@arthaud.me>
 <9BF380A3-CAEB-46FB-8598-4E80DF45E79D@kba.biglobe.ne.jp>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <9BF380A3-CAEB-46FB-8598-4E80DF45E79D@kba.biglobe.ne.jp>
X-Editor: Vim <http://www.vim.org/>
User-Agent: Mutt/1.5.23 (2014-03-12)
X-Seq: zsh-workers 38307

Hello,

The following lines cause a segfault in zsh on my machines:

  setopt re_match_pcre
  s=test.txt
  [[ $s =~ '^(.*_)?(test)' ]] && echo $match[2]

This occurs only when the first group doesn't match (works fine with
s=1_test.txt).

I think this is related to the patch 37515 (commit 5eae5b58b1b99946),
see below:

* Jun T. <takimoto-j@kba.biglobe.ne.jp> [2016-01-08 14:09 +0100]:
> pcre.c has the same problem:
> 
> % setopt re_match_pcre
> % [[ $'\ua0' =~ . ]] && echo OK
> (zsh hangs; 100% CPU usage)
> 
> The following is a copy of the patch to regex.c in workers/35448.
> Also added a simple test in V07pcre.ztst.
> 
> diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c

(...)

Here ovec[2] = -1 (because there was no match for '(.**)?'),
and we have ipair = ovec + 2, so leftlen is set to -1 below.

> @@ -219,17 +226,23 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar,
>  		    ptr = arg;
>  		    offs = 0;
>  		    /* Find the start offset */
> -		    MB_METACHARINIT();
> -		    while (ptr < arg + ipair[0]) {
> +		    MB_CHARINIT();
> +		    leftlen = ipair[0];
> +		    while (leftlen) {
>  			offs++;
> -			ptr += MB_METACHARLEN(ptr);
> +			clen = MB_CHARLEN(ptr, leftlen);
> +			ptr += clen;
> +			leftlen -= clen;
>  		    }

The following patch fixes the segfault for me:

diff --git a/Src/Modules/pcre.c b/Src/Modules/pcre.c
index e23ab57..5fd6796 100644
--- a/Src/Modules/pcre.c
+++ b/Src/Modules/pcre.c
@@ -228,7 +228,7 @@ zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar,
 		    /* Find the start offset */
 		    MB_CHARINIT();
 		    leftlen = ipair[0];
-		    while (leftlen) {
+		    while (leftlen > 0) {
 			offs++;
 			clen = MB_CHARLEN(ptr, leftlen);
 			ptr += clen;

Regards,
-- 
Mikael

