From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=3.4.4 Received: from zero.zsh.org (zero.zsh.org [IPv6:2a02:898:31:0:48:4558:7a:7368]) by inbox.vuxu.org (Postfix) with ESMTP id E635921C2D for ; Thu, 27 Jun 2024 04:02:00 +0200 (CEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1719453720; b=PuWauMABKvHsVxD7MDoN85ohHwSzQyO4wj9RcwVOrW8SPKwBFCMF0lj4KFj2h6m8StSE/p03fY qss6kjCvqkj0CGCwDc0cT7297jjVQzHoZ900IvHWYVcJeVJeW3X9BVGSvDukkOACllphFHXFwO RRYLVQXT/J4l6Jo1nEadzQ2ENfQy0U6Eyl9M52QROKzabiZ/wQNx+VBI2lduHl20u3vPmS/u8u 8ECJQXU5p+ye9OZLwRWqax2bjRp4q/3C86ECcvxp2S0P/DMnPbKle7iLP02eNjiK9EAbK1oMrZ 0PKNwtuUQwxqPOq8G8VLb+eX4zrlMTrWesViIlHlQmPCyQ==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (mail-ed1-f50.google.com) smtp.remote-ip=209.85.208.50; dkim=pass header.d=gmail.com header.s=20230601 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1719453720; bh=fbZUgCiMcSi76/W91JX+greSXlohLL2r2QD7SmRA31o=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Type:Cc:To:Subject:Message-ID:Date:From:In-Reply-To: References:MIME-Version:DKIM-Signature:DKIM-Signature; b=fLC8zQipRACvyAynmqCx2gDjI9l+DDfbGnv12Bo158l9eDYZ5B7b4M7pOZPNd00fuz57rO8jOL 4XXWLWFSmgcD0iZWCsRx7fcNqjFuqUMMioZ/ibNh0yNaiOnZgxISUavnCTsp+oBevBKQJqWx85 cNKjDP5NZxJqXC2g3l00xuuaG2JcHdvFEbovQhhAQ7WVgkIEE/iH/tGsGB8uBR+JTHg7oqzTfx 1YpiO+WiOIkm6+rmNKO28Mmwh1Kxx4Dyxer1Oki1giQaPfVdb/9enZnUcNvKe59GVZ2Tq0MPRR 7/Ii+ZlDstpkgjfNPdhDzjhTy0HUeZxircSakwZFRAO4FA==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Type:Cc:To:Subject:Message-ID :Date:From:In-Reply-To:References:MIME-Version:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID; bh=CQorNIXCusQ0Tm+s01gGTzxPjdokD1ziEbny/A+ia/U=; b=DkJjS74VI/uNeErRB8POR81rpZ 8b2w01jV9rSfhWcdvaaobv26qCCVa/PXLNDCVzTVsREruHxlCBxOHvMc6+3c/32Iyq3YE14G7MY3f VgFlG2Av2icmFmYbQC9vNVRMtzQKeOLzOrn9SoWoqLmxCK8vvVjEk7qGx6Zt+slyzNFHFmNoWqZ5s 5uzVn4KyBdwo+PnyR9zCiShCQS9juwWAf3JA7tN+1tpcVXV0WcDoxAySwn3NFLOKJ4H0bb2tsxVia 7s3enKL3x96VCl0l+KMxvjab2BkjZ/0ecTg7p08VEtA5bxLJrnWlHTOSOcWHJvBs6TrmXekEKv+Kq dqNC9svQ==; Received: by zero.zsh.org with local id 1sMeSU-000Fr8-Nz; Thu, 27 Jun 2024 02:01:58 +0000 Authentication-Results: zsh.org; iprev=pass (mail-ed1-f50.google.com) smtp.remote-ip=209.85.208.50; dkim=pass header.d=gmail.com header.s=20230601 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none Received: from mail-ed1-f50.google.com ([209.85.208.50]:56602) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_128_GCM_SHA256:128) id 1sMeRs-000FXm-GN; Thu, 27 Jun 2024 02:01:21 +0000 Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-57cd26347d3so1091039a12.1 for ; Wed, 26 Jun 2024 19:01:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719453680; x=1720058480; darn=zsh.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=CQorNIXCusQ0Tm+s01gGTzxPjdokD1ziEbny/A+ia/U=; b=DHs6ToPPIJs+h43IOX+LlMW7WGqOqbRymzv5RD8/SGXq8wk94oSn2AXBl2i5yc+dza r2qV9fr4zylohIyir9EIftRyG1+nPH3fKyX1ZSmf4BOEJwWCsBjO9Z++wg1+6vk1ME/u JoJ+4veNIH5VOb5cUEEYkXSsGhts/YIfBUss8BMsUdAyf5djsxU/eBkYYgpF83D7r/I2 XXUlZEezdaZqcrY3mqVHX4EHa+0Jtc6Yry8KbkEM3Q/2awTuYegp3g/77tJZWjfcRcN7 FBhEECBXexnSHmdV/MoFvyLvrXcUk/KHRZJiA8shdyM2Rz3RQAlc8DkjyC+B+Kaynzrc ce4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719453680; x=1720058480; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=CQorNIXCusQ0Tm+s01gGTzxPjdokD1ziEbny/A+ia/U=; b=OCsBeaCX6cKHJnby88dvaobxY6+5Eju79QKOqgogC0vvKxVg6XmjVbH/xESda5aDnc rYge261T0g4JyLiPp8ih1ND6dvkqCTdNWMgy6xgpKLamo7TlbIVk8yW3VUFjiaLTdhbn ylgS3kPdfyd506/sXJBPA/29tj+GW3IUqOKiPrQKkEH0TQVFwjNXpc1xmxSpyRqK1rz+ MMHdV68a/n1VHWWf3Da5qWziglb9XZDeZGqXMZeywAELY/6NZGOCzOkr/ESqNlRaFYDr HMC7TnikTx9taS3c0VvdYZYR+aVAfSj9e+V3rlBSpOTqllPM5s3qsiaQ1B8ZLDglKPNw IXBg== X-Gm-Message-State: AOJu0YxdPrLtJH6AliIQs8qr9FvtjREyks5nc+lTYntTRve1OXlrwqps 6XbQarkuVhbhRsQVwm1vECXUq439osQmjHtz6MaohS6WrGFsl6U9Kit1ZdWMTyB5FgDRKQb0zcB gJRTHN6wHctTZeHEy1Iyvk2MqlrVTHvac X-Google-Smtp-Source: AGHT+IF+R7/4fibYI8kJSoKY5iqMjhRmJlNmj1vGUFs/2hTgdfw1Tv6OTdIBeTcw4sg7+nzTc6TQ03rO4pgkaVJsyiw= X-Received: by 2002:a50:8715:0:b0:578:67db:7529 with SMTP id 4fb4d7f45d1cf-57d4bd56300mr7894380a12.4.1719453679446; Wed, 26 Jun 2024 19:01:19 -0700 (PDT) MIME-Version: 1.0 References: <5d54375e-8673-45f0-b5ac-f5e0e233d56f@inlv.org> <2a5f0fa7-23bf-4069-b237-d304965f142e@app.fastmail.com> <33ca21c3-69f8-49f7-9350-2ff9cc4febca@app.fastmail.com> In-Reply-To: From: Philippe Altherr Date: Thu, 27 Jun 2024 04:01:08 +0200 Message-ID: Subject: Re: errexit and (Z)ERR trap regression To: Bart Schaefer Cc: zsh-workers@zsh.org Content-Type: multipart/mixed; boundary="000000000000c5b99d061bd58132" X-Seq: 52977 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: --000000000000c5b99d061bd58132 Content-Type: multipart/alternative; boundary="000000000000c5b99b061bd58130" --000000000000c5b99b061bd58130 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable > > This doesn't seem necessary to me. For one thing, it's equivalent to: > noerrexit =3D oldnoerrexit; > if (isandor || isnot) > noerrexit |=3D NOERREXIT_EXIT | NOERREXIT_RETURN; I agree that it's equivalent but I disagree that it (or something similar) isn't necessary ;-) But assigning (noerrexit =3D oldnoerrexit) presumes that noerrexit was > (improperly?) cleared at or after the point where olderrexit was > recorded. Which is indeed the problem. To see it, let's take a wider view of the code at hand: int oldnoerrexit =3D noerrexit; // ... while (wc_code(code) =3D=3D WC_SUBLIST) { // ... * noerrexit =3D oldnoerrexit;* * if (isandor || isnot)* * noerrexit |=3D NOERREXIT_EXIT | NOERREXIT_RETURN;* switch (WC_SUBLIST_TYPE(code)) { case WC_SUBLIST_END: // ... case WC_SUBLIST_AND: // ... case WC_SUBLIST_OR: // ... } // ... } sublist_done: noerrexit =3D oldnoerrexit; It's true that in the first iteration of the while loop, the noerrexit =3D oldnoerrexit is always a nop. However, that isn't the case for subsequent iterations and in particular for the last iteration where it's important to always restore noerrexit to its original value (i.e., oldnoerrexit) even if that value isn't equal to 0. Now that I see this code under this angle, I think that a better version is one where noerrexit =3D oldnoerrexit is placed after the switch statement. This way it's easier to grasp why it's necessary (or why it's not a nop). Ideally we would then also drop the noerrexit =3D oldnoerrexit after the sublist_done label. Unfortunately, that's not possible because the switch statement contains multiple goto statements that jump to the label and that bypass any noerrexit =3D oldnoerrexit after the switch statement. > Here are two other examples fixed by this patch: > > > > zsh -c 'trap "echo Trapped!" ERR; true && if true; then false; fi' > > zsh -c 'trap "echo Trapped!" ERR; true && {false} always {true}' > These two cases also pass with my patch from workers/52973. Do you > have an example where my patch doesn't work? Yes, these two cases were just meant to highlight slightly different code paths that also trigger the bug. And yes, I managed to build an example that fails with your patch. I think that the following is a minimal example, i.e., both && and the braces around the false are needed to trigger the bug: zsh -c 'set -o ERR_RETURN; f() { true && { false }; echo "NOT REACHED"; }; f && true' In this example "f" in "f && true" is evaluated with "errnoexit =3D NOERREXIT_EXIT | NOERREXIT_RETURN". The call to "f" clears the NOERREXIT_RETURN bit. Thus "true && { false }" is evaluated with "errnoexit =3D NOERREXIT_EXIT" and "olderrnoexit" is initialized to th= at value in "execlist". The evaluation of "true" sets "errnoexit" to "NOERREXIT_EXIT | NOERREXIT_RETURN". Now, if "errnoexit" is left unchanged, as is the case in version 5.9, or set to 0 only if "olderrnoexit" is equal to 0, then "{ false }" is evaluated with "errnoexit =3D NOERREXIT_EXIT | NOERREXIT_RETURN" and fails to trigger ERR_RETURN. With my path "errnoexit" is restored to "NOERREXIT_EXIT", which enables "{ false }" to trigger ERR_RETURN. Below is an updated patch with the cleaner and simpler fix described above and a new test case for the ERR_RETURN example. Philippe On Wed, Jun 26, 2024 at 11:43=E2=80=AFPM Bart Schaefer wrote: > On Wed, Jun 26, 2024 at 5:43=E2=80=AFAM Philippe Altherr > wrote: > > > > I think that the correct fix is the following: > > > > if (isandor || isnot) > > noerrexit =3D oldnoerrexit | NOERREXIT_EXIT | NOERREXIT_RETURN; > > else > > noerrexit =3D oldnoerrexit; > > This doesn't seem necessary to me. For one thing, it's equivalent to: > > noerrexit =3D oldnoerrexit; > if (isandor || isnot) > noerrexit |=3D NOERREXIT_EXIT | NOERREXIT_RETURN; > > But assigning (noerrexit =3D oldnoerrexit) presumes that noerrexit was > (improperly?) cleared at or after the point where olderrexit was > recorded. If that were the situation, then -- > > > For reminder, here is the current code: > > > > if (isandor || isnot) > > noerrexit |=3D NOERREXIT_EXIT | NOERREXIT_RETURN; > > -- would be insufficient for the existing test cases, I think. That > is, either (olderrexit =3D=3D noerrexit), or it's not necessary to > OR-together olderrexit with the new values. > > > Here are two other examples fixed by this patch: > > > > zsh -c 'trap "echo Trapped!" ERR; true && if true; then false; fi' > > zsh -c 'trap "echo Trapped!" ERR; true && {false} always {true}' > > These two cases also pass with my patch from workers/52973. Do you > have an example where my patch doesn't work? > --000000000000c5b99b061bd58130 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
This doe= sn't seem necessary to me.=C2=A0 For one thing, it's equivalent to:=

=C2=A0 n= oerrexit =3D oldnoerrexit;
=C2=A0 if = (isandor || isnot)
=C2=A0 =C2= =A0 noerrexit |=3D NOERREXIT_EXIT | NOERREXIT_RETURN;

I agree that it's equivalent but I disagree that it (= or something similar) isn't necessary ;-)

But assigning (noerrexit =3D oldno= errexit) presumes that noerrexit was
(improperly?) cleared at or after t= he point where olderrexit was
recorded.

= Which is indeed the problem. To see it, let's take a wider view of the = code at hand:

=C2=A0 =C2=A0 int oldnoerrexit =3D n= oerrexit;
=C2=A0 =C2=A0 // ...
=C2=A0 =C2=A0 while (wc_= code(code) =3D=3D WC_SUBLIST) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // ..= .
=C2=A0 =C2=A0 =C2=A0 =C2=A0 noerrexit =3D oldnoerrexit;<= /div>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (isandor || isnot)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 noerrexit |=3D NOERREXIT_EXI= T | NOERREXIT_RETURN;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 switch= (WC_SUBLIST_TYPE(code)) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 case WC_SUBLIST_END: // ...
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 case WC_SUBLIST_AND: // ...
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 case WC_SUBLIST_OR: // ...
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // = ...
=C2=A0 =C2=A0 }
=C2=A0 =C2=A0 sublist_done:
=C2=A0 =C2=A0 noerrexit =3D oldnoerrexit;

It's true that in the first iteration of the while loop, the=C2=A0no= errexit =3D oldnoerrexit=C2=A0is always a nop. However, that isn't the = case for subsequent iterations and in particular for the last iteration whe= re it's important to always restore=C2=A0noerrexit to its original valu= e (i.e., oldnoerrexit) even if that value isn't equal to 0.
<= br>
Now that I see this code under this angle, I think that a bet= ter version is one where noerrexit =3D oldnoerrexit=C2=A0is placed after th= e switch statement. This way it's easier to grasp why it's necessar= y (or why it's not a nop). Ideally we would then also drop the=C2=A0noe= rrexit =3D oldnoerrexit after the sublist_done label. Unfortunately, that&#= 39;s not possible because the switch statement contains multiple goto state= ments that jump to the label and that bypass any noerrexit =3D oldnoerrexit= after the switch statement.

> Here are tw= o other examples fixed by this patch:
>
>=C2=A0 =C2=A0= =C2=A0zsh -c 'trap "echo Trapped!" ERR; true && if t= rue; then false; fi'
>= =C2=A0 =C2=A0 =C2=A0zsh -c 'trap "echo Trapped!" ERR; true &a= mp;& {false} always {true}'

These two cases also pass with my patch from workers/52973.=C2=A0 Do youhave an example where my patch doesn't work?

Yes, these two cases were just meant to highlight slightly differen= t code paths that also trigger the bug. And yes, I managed to build an exam= ple that fails with your patch. I think that the following is a minimal exa= mple, i.e., both && and the braces around the false are needed to t= rigger the bug:

zsh -c 'set -o ERR_RETURN; f()= { true && { false }; echo "NOT REACHED"; =C2=A0}; f &= ;& true'

In this example "f"= in "f && true" is evaluated with "errnoexit=C2=A0= =3D=C2=A0NOERREXIT_EXIT | NOERREXIT_RETURN". The call to "f"= clears the=C2=A0NOERREXIT_RETURN bit. Thus "true && { false }= " is evaluated with=C2=A0"errnoexit =3D NOERREXIT_EXIT" and = "olderrnoexit" is initialized to that value in "execlist&quo= t;. The evaluation of "true" sets "errnoexit" to "= NOERREXIT_EXIT | NOERREXIT_RETURN". Now, if "errnoexit" is l= eft unchanged, as is the case in version 5.9, or set to 0 only if=C2=A0&quo= t;olderrnoexit" is equal to 0, then "{ false }" is evaluated= with "errnoexit=C2=A0=3D=C2=A0NOERREXIT_EXIT | NOERREXIT_RETURN"= and fails to trigger ERR_RETURN. With my path "errnoexit" is res= tored to "NOERREXIT_EXIT", which enables "{ false }" to= trigger ERR_RETURN.

Below is an updated patch wit= h the cleaner and simpler fix described above and a new test case for the E= RR_RETURN example.

Philippe


On= Wed, Jun 26, 2024 at 11:43=E2=80=AFPM Bart Schaefer <schaefer@brasslantern.com&= gt; wrote:
On We= d, Jun 26, 2024 at 5:43=E2=80=AFAM Philippe Altherr
<philipp= e.altherr@gmail.com> wrote:
>
> I think that the correct fix is the following:
>
>=C2=A0 =C2=A0 =C2=A0if (isandor || isnot)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0noerrexit =3D oldnoerrexit | NOERREXI= T_EXIT | NOERREXIT_RETURN;
>=C2=A0 =C2=A0 =C2=A0else
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0noerrexit =3D oldnoerrexit;

This doesn't seem necessary to me.=C2=A0 For one thing, it's equiva= lent to:

=C2=A0 noerrexit =3D oldnoerrexit;
=C2=A0 if (isandor || isnot)
=C2=A0 =C2=A0 noerrexit |=3D NOERREXIT_EXIT | NOERREXIT_RETURN;

But assigning (noerrexit =3D oldnoerrexit) presumes that noerrexit was
(improperly?) cleared at or after the point where olderrexit was
recorded.=C2=A0 If that were the situation, then --

> For reminder, here is the current code:
>
>=C2=A0 =C2=A0 =C2=A0if (isandor || isnot)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0noerrexit |=3D NOERREXIT_EXIT | NOERR= EXIT_RETURN;

-- would be insufficient for the existing test cases, I think.=C2=A0 That is, either (olderrexit =3D=3D noerrexit), or it's not necessary to
OR-together olderrexit with the new values.

> Here are two other examples fixed by this patch:
>
>=C2=A0 =C2=A0 =C2=A0zsh -c 'trap "echo Trapped!" ERR; tru= e && if true; then false; fi'
>=C2=A0 =C2=A0 =C2=A0zsh -c 'trap "echo Trapped!" ERR; tru= e && {false} always {true}'

These two cases also pass with my patch from workers/52973.=C2=A0 Do you have an example where my patch doesn't work?
--000000000000c5b99b061bd58130-- --000000000000c5b99d061bd58132 Content-Type: text/plain; charset="US-ASCII"; name="noerrexit-list-subcommands.txt" Content-Disposition: attachment; filename="noerrexit-list-subcommands.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lxwm3zqa0 ZGlmZiAtLWdpdCBhL1NyYy9leGVjLmMgYi9TcmMvZXhlYy5jCmluZGV4IGU5NTVlODVkZi4uYTQ3 MzkzOGVjIDEwMDY0NAotLS0gYS9TcmMvZXhlYy5jCisrKyBiL1NyYy9leGVjLmMKQEAgLTE1Njgs NiArMTU2OCw3IEBAIGV4ZWNsaXN0KEVzdGF0ZSBzdGF0ZSwgaW50IGRvbnRfY2hhbmdlX2pvYiwg aW50IGV4aXRpbmcpCiAJICAgIH0KIAkgICAgc3RhdGUtPnBjID0gbmV4dDsKIAkgICAgY29kZSA9 ICpzdGF0ZS0+cGMrKzsKKwkgICAgbm9lcnJleGl0ID0gb2xkbm9lcnJleGl0OwogCX0KIAlzdGF0 ZS0+cGMtLTsKIHN1Ymxpc3RfZG9uZToKZGlmZiAtLWdpdCBhL1Rlc3QvQzAzdHJhcHMuenRzdCBi L1Rlc3QvQzAzdHJhcHMuenRzdAppbmRleCBkZTU3NzY1YTAuLjg3YjdmZDFmNyAxMDA2NDQKLS0t IGEvVGVzdC9DMDN0cmFwcy56dHN0CisrKyBiL1Rlc3QvQzAzdHJhcHMuenRzdApAQCAtOTk1LDYg Kzk5NSwzMyBAQCBGOk11c3QgYmUgdGVzdGVkIHdpdGggYSB0b3AtbGV2ZWwgc2NyaXB0IHJhdGhl ciB0aGFuIHNvdXJjZSBvciBmdW5jdGlvbgogP2xvb3AgMAogP2xvb3AgMQogCisgICggc2V0IC1l OyB0cnVlICYmIHtmYWxzZTsgZWNobyBOT1QgUkVBQ0hFRH0gKQorICAoIHRyYXAgInByaW50IFRy YXBwZWQhIiBFUlI7IHRydWUgJiYge2ZhbHNlfSApCisgICggdHJhcCAicHJpbnQgVHJhcHBlZCEi IEVSUjsgdHJ1ZSAmJiBpZiB0cnVlOyB0aGVuIGZhbHNlOyBmaSApCisgICggdHJhcCAicHJpbnQg VHJhcHBlZCEiIEVSUjsgdHJ1ZSAmJiB7ZmFsc2V9IGFsd2F5cyB7dHJ1ZX0gKQorICAoIHRydWUg JiYgKHNldCAtZTsgZmFsc2U7IGVjaG8gTk9UIFJFQUNIRUQpICkKKyAgKCB0cnVlICYmICh0cmFw ICJwcmludCBUcmFwcGVkISIgRVJSOyBmYWxzZSkgKQorICAoIHRydWUgJiYgeyBzZXQgLWU7IGZh bHNlOyBlY2hvIE5PVCBSRUFDSEVEIH0gKQorICAoIHRydWUgJiYgeyB0cmFwICJwcmludCBUcmFw cGVkISIgRVJSOyBmYWxzZSB9ICkKKyAgKCBzZXQgLWU7IHRydWUgJiYgKGZhbHNlOyBlY2hvIG9u ZSkgfHwgZWNobyB0d28gKQorICAoIHNldCAtZTsgdHJ1ZSAmJiB7IGZhbHNlOyBlY2hvIG9uZTsg fSB8fCBlY2hvIHR3byApCiswOkVSUl9FWElUIGlzIHRyaWdnZXJlZCBieSBsYXN0IGNvbW1hbmQg aW4gYW4gQU5ELU9SIGxpc3QKKz5UcmFwcGVkIQorPlRyYXBwZWQhCis+VHJhcHBlZCEKKz5UcmFw cGVkIQorPlRyYXBwZWQhCis+b25lCis+b25lCisKKyAgKCBzZXQgLW8gRVJSX1JFVFVSTjsgZigp IHsgZmFsc2U7IGVjaG8gTk9UIFJFQUNIRUQ7ICB9OyBmIHx8IHRydWU7IGVjaG8gT0sgKQorICAo IHNldCAtbyBFUlJfUkVUVVJOOyBmKCkgeyB0cnVlICYmIGZhbHNlOyBlY2hvIE5PVCBSRUFDSEVE OyAgfTsgZiB8fCB0cnVlOyBlY2hvIE9LICkKKyAgKCBzZXQgLW8gRVJSX1JFVFVSTjsgZigpIHsg dHJ1ZSAmJiB7IGZhbHNlIH07IGVjaG8gTk9UIFJFQUNIRUQ7ICB9OyBmIHx8IHRydWU7IGVjaG8g T0sgKQorMDpFUlJfUkVUVVJOIGlzIHRyaWdnZXJlZCBpbiBmdW5jdGlvbiBjYWxscyBvbiB0aGUg bGVmdCBvZiBhbiBBTkQtT1IKKz5PSworPk9LCis+T0sKKwogICBpZiB6bW9kbG9hZCB6c2gvc3lz dGVtIDI+L2Rldi9udWxsOyB0aGVuCiAgICgKICAgICB0cmFwICdlY2hvIFRFUk07IGV4aXQgMicg VEVSTQo= --000000000000c5b99d061bd58132--