From nobody Tue May 02 21:40:14 2023 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Q9tm74Gsbz48BdP for ; Tue, 2 May 2023 21:40:23 +0000 (UTC) (envelope-from steffen@sdaoden.eu) Received: from sdaoden.eu (sdaoden.eu [217.144.132.164]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4Q9tm62QK4z3D3N for ; Tue, 2 May 2023 21:40:22 +0000 (UTC) (envelope-from steffen@sdaoden.eu) Authentication-Results: mx1.freebsd.org; dkim=none; spf=pass (mx1.freebsd.org: domain of steffen@sdaoden.eu designates 217.144.132.164 as permitted sender) smtp.mailfrom=steffen@sdaoden.eu; dmarc=none Date: Tue, 02 May 2023 23:40:14 +0200 Author: Steffen Nurpmeso From: Steffen Nurpmeso To: tech@openbsd.org, tech-userlevel@netbsd.org, freebsd-hackers@freebsd.org Subject: usr.bin/mail: cmd3.c:bangexp(): "borked"?, and BSD fails POSIX compat Message-ID: <20230502214014._zIz6%steffen@sdaoden.eu> Mail-Followup-To: tech@openbsd.org, tech-userlevel@netbsd.org, freebsd-hackers@freebsd.org User-Agent: s-nail v14.9.24-461-g2a5db04708 OpenPGP: id=EE19E1C1F2F7054F8D3954D8308964B51883A0DD; url=https://ftp.sdaoden.eu/steffen.asc; preference=signencrypt BlahBlahBlah: Any stupid boy can crush a beetle. But all the professors in the world can make no bugs. List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spamd-Result: default: False [0.47 / 15.00]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; NEURAL_SPAM_MEDIUM(0.77)[0.771]; R_SPF_ALLOW(-0.20)[+a]; MIME_GOOD(-0.10)[text/plain]; NEURAL_HAM_SHORT(-0.00)[-0.005]; MLMMJ_DEST(0.00)[freebsd-hackers@freebsd.org]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; FROM_EQ_ENVFROM(0.00)[]; RCVD_COUNT_ZERO(0.00)[0]; ARC_NA(0.00)[]; TO_MATCH_ENVRCPT_SOME(0.00)[]; DMARC_NA(0.00)[sdaoden.eu]; FROM_HAS_DN(0.00)[]; ASN(0.00)[asn:15987, ipnet:217.144.128.0/20, country:DE]; RCPT_COUNT_THREE(0.00)[3]; TO_DN_NONE(0.00)[]; SUBJECT_HAS_QUESTION(0.00)[] X-Rspamd-Queue-Id: 4Q9tm62QK4z3D3N X-Spamd-Bar: / X-ThisMailContainsUnwantedMimeParts: N Hallo, and sorry for the cross-post, but so all in one (maybe) go. This is about a niche "feature" of mail, the shell command "bang" (! / ~! in compose mode): ? !echo no!bang no!bang ! ? set bang ? ! echo no!bang !echo nobang nobang ! ? ! ! !echo nobang nobang ! ? ! echo no!bang !echo noecho nobangbang noecho nobangbang ! ? In short: they all do it differently, and they all do it "wrong". - Apple mail simply does not act unless "bang" is set: bangexp() simply returns. - Free-, Net- and OpenBSD do not look for a "bang" variable at all, they simply do bang-style expansion whether that is set or not. - V10 mailx (and the code i maintain) do some mix (expand the "last bang" only if "bang" is set, but know about \! escapes and such. POSIX now says / will say If the bang variable is set, each unescaped occurrence of '!' in command shall be replaced with the command executed by the previous ! command or =CB=9C! command escape. thus - All commands entered for ! and ~! shall be stored. - If "bang" is set, an unquoted ! shall be replaced by that storage. The code everywhere is more or less what Kurt A. Shoens wrote as commit ae3dba0da2068b0de91ef163ea95fe774196a501 Author: Kurt A. Schoens AuthorDate: 1980-10-09 02:48:47 -0800 Commit: Kurt A. Schoens CommitDate: 1980-10-09 02:48:47 -0800 Made shell escapes expand !'s to previous command SCCS-vsn: usr.bin/mail/cmd3.c 1.2 It will fail to properly "bang" a second time if some escaped question mark was present in the first round, while(*cp){ ... if (*cp =3D=3D '!') { BANGEXP ... continue; } ... if (*cp =3D=3D '\\' && cp[1] =3D=3D '!') { ... *cp2++ =3D '!'; cp +=3D 2; changed++; [fallthru] } ... *cp2++ =3D *cp++; and it stores and pushes through the second escape for "\!\!". I am thinking of dropping this entirely, as it can properly work only once if some escape took place, and i do not know how to fix this the right way. (And the line editor has history.) --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) |~~ |..and in spring, hear David Leonard sing.. | |The black bear, The black bear, |blithely holds his own holds himself at leisure |beating it, up and down tossing over his ups and downs with pleasure |~~ |Farewell, dear collar bear