From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Newsgroups: gmane.emacs.bugs Subject: bug#45198: 28.0.50; Sandbox mode Date: Mon, 19 Apr 2021 17:41:58 +0200 Message-ID: References: <5818DFAA-3A9C-4335-BAAF-1227A02C290A@acm.org> <19511709-E42B-4ABD-9823-39EA08A79B1F@gmail.com> <83v98kvr7y.fsf@gnu.org> <9A5BCDF3-6543-46C0-AB56-2311392FC549@gmail.com> <78F41D0B-D2F6-444C-9B5C-9C50CFF2CFBD@acm.org> Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.17\)) Content-Type: multipart/mixed; boundary="Apple-Mail=_59FECC85-2A93-4A38-B1A5-7709DA915415" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="9577"; mail-complaints-to="usenet@ciao.gmane.io" Cc: alan@idiocy.org, 45198@debbugs.gnu.org, stefan@marxist.se, =?UTF-8?Q?Jo=C3=A3o_?= =?UTF-8?Q?T=C3=A1vora?= , Stefan Monnier To: Philipp Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Apr 19 17:43:13 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lYW3L-0002Mc-Vl for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 19 Apr 2021 17:43:12 +0200 Original-Received: from localhost ([::1]:52278 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lYW3L-0003C4-22 for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 19 Apr 2021 11:43:11 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:57488) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lYW3C-0003BU-7T for bug-gnu-emacs@gnu.org; Mon, 19 Apr 2021 11:43:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:40234) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lYW3C-0006Vd-0S for bug-gnu-emacs@gnu.org; Mon, 19 Apr 2021 11:43:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lYW3B-0001ZO-U7 for bug-gnu-emacs@gnu.org; Mon, 19 Apr 2021 11:43:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 19 Apr 2021 15:43:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 45198 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 45198-submit@debbugs.gnu.org id=B45198.16188469345953 (code B ref 45198); Mon, 19 Apr 2021 15:43:01 +0000 Original-Received: (at 45198) by debbugs.gnu.org; 19 Apr 2021 15:42:14 +0000 Original-Received: from localhost ([127.0.0.1]:51774 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lYW2P-0001Xw-Nh for submit@debbugs.gnu.org; Mon, 19 Apr 2021 11:42:14 -0400 Original-Received: from mail1451c50.megamailservers.eu ([91.136.14.51]:42030 helo=mail266c50.megamailservers.eu) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lYW2M-0001Xf-9g for 45198@debbugs.gnu.org; Mon, 19 Apr 2021 11:42:11 -0400 X-Authenticated-User: mattiase@bredband.net DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megamailservers.eu; s=maildub; t=1618846923; bh=xBd6e47VXmRBCuDBMZ53UfFjnQpv+/r6mf8FcgoaPTE=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=Ue47454X4EDzE/vfa/SfAgkDR7iyY2CZgbNAp1UlB+76LcUL875xncEznGKhVjcE4 W9rcn9GVVcTDioKZ+FaTCMXvxlwNjHk5I4Wg3kmFgriHBJm8eQFw7Rcd6FGuaVi1HC 4T6lI0bhKA6D1w1Cjhj95C7fEDGqsksdnfcA9vwY= Feedback-ID: mattiase@acm.or Original-Received: from stanniol.lan (c-b952e353.032-75-73746f71.bbcust.telenor.se [83.227.82.185]) (authenticated bits=0) by mail266c50.megamailservers.eu (8.14.9/8.13.1) with ESMTP id 13JFfwNl003772; Mon, 19 Apr 2021 15:42:00 +0000 In-Reply-To: X-Mailer: Apple Mail (2.3445.104.17) X-CTCH-RefID: str=0001.0A742F16.607DA4CA.0088, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0 X-CTCH-VOD: Unknown X-CTCH-Spam: Unknown X-CTCH-Score: 0.000 X-CTCH-Flags: 0 X-CTCH-ScoreCust: 0.000 X-CSC: 0 X-CHA: v=2.3 cv=VISjYOHX c=1 sm=1 tr=0 a=von4qPfY+hyqc0zmWf0tYQ==:117 a=von4qPfY+hyqc0zmWf0tYQ==:17 a=M51BFTxLslgA:10 a=pGLkceISAAAA:8 a=P_jWLAUnFZnPBouWQNAA:9 a=CjuIK1q_8ugA:10 a=2i1jUgeGfihAGWfHL1kA:9 a=B2y7HmGcmWMA:10 X-Origin-Country: SE X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:204474 Archived-At: --Apple-Mail=_59FECC85-2A93-4A38-B1A5-7709DA915415 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii 17 apr. 2021 kl. 21.42 skrev Philipp : >> --- a/lisp/subr.el >=20 > Should this maybe be in a platform-specific file such as ns-fns.el = (like dos-fns.el, w32-fns.el)? Yes, and thank you for noticing. Now moved. > I don't think we use the "darwin-" prefix anywhere else in Emacs. = Maybe use a "ns-" prefix. As Alan correctly noted this has nothing with NS to do per se, so I'm = staying with darwin- for now. > Also I think such internal functions commonly have an "internal" piece = somewhere in their name, e.g. "ns-enter-sandbox-internal". Maybe, but there is already a platform-specific prefix and a clear note = in the doc string that it's internal. Doesn't that suffice? >> + (darwin-sandbox-init >=20 > Can you also refer to the documents listed below, so that readers = aren't wondering what this syntax means? Thank you but that sounds unlikely since the PROFILE argument is = described as SBPL in the function doc string. >> + (concat "(version 1)\n" >=20 > Since this uses Lisp syntax, maybe use (prin1-to-string `(...))? I'd rather not, since it's not exactly Emacs Lisp syntax. I'd like to = avoiding conflating the two as far as possible. However... >> + (format "(allow file-read* (subpath = %S))\n" dir)) >=20 > Are you sure that the string quoting syntaxes are compatible? It had me concerned when I wrote it too but it didn't seem possible to = cause a false positive that way -- false negatives (access denial) at = worst. In particular, names containing backslashes or double quotes work = correctly. >> + doc: /* Enter a sandbox whose permitted access is curtailed = by PROFILE. >> +Already open descriptors can be used freely. >> +PROFILE is a string in the macOS sandbox profile language, >> +a set of rules in a Lisp-like syntax. >=20 > I'd also refer to the Chromium document here, otherwise C-h f for this = function won't be very useful. I wouldn't worry -- an Emacs developer who doesn't already know it is = more likely to duckduckgo "macos sandbox profile language" and get an = up-to-date reference. >> + if (sandbox_init_with_parameters (SSDATA (profile), 0, NULL, &err) = !=3D 0) >=20 > If you're using SSDATA, better check that the string doesn't contain = embedded null bytes. There is really no way that that could ever be a problem but I added a = check just in case. > Also does this need to be encoded somehow? What happens if the string = contains non-Unicode characters like raw bytes? Then there will be false negatives (permissions not granted) or syntax = errors. This is just a system call wrapper; the caller is responsible = for using reasonable arguments. >> + error ("sandbox error: %s", err); >=20 > This looks like an error that clients could handle, so I'd signal a = specific error symbol here. That error just indicates a programming mistake. Nobody is going to = handle it. >> diff --git a/test/src/emacs-tests.el b/test/src/emacs-tests.el >=20 > This should probably be in subr-tests.el since it tests a function in = subr.el. Right again, moved to a new file. > I like tests that are somewhat repetitive but more decoupled and = easier to read better than tests with factored-out assertions. There is merit to such a style but the more important concern in this = case is to avoid false positives and negatives, and make the tests = robust in that regard. It is very easy to make a mistake that renders a test meaningless, = especially when testing a mechanism that does not alter the value of a = computation but merely allows it to proceed or causes it to fail. The = test has now been rewritten in a kind of oracular-combinatorial style = which is effective in these situations. Doing so also improved coverage. Thank you very much for your review and comments! I'd like to push the = resulting patch but perhaps it and the rest of the sandbox development = should go into a separate branch? --Apple-Mail=_59FECC85-2A93-4A38-B1A5-7709DA915415 Content-Disposition: attachment; filename=0001-Add-macOS-sandboxing-bug-45198.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="0001-Add-macOS-sandboxing-bug-45198.patch" Content-Transfer-Encoding: quoted-printable =46rom=20c5006dc5260f547ff132fd42c580ea0e0fb227a7=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20=3D?UTF-8?q?Mattias=3D20Engdeg=3DC3=3DA5rd?=3D=20= =0ADate:=20Sat,=2017=20Apr=202021=2020:53:39=20+0200=0A= Subject:=20[PATCH]=20Add=20macOS=20sandboxing=20(bug#45198)=0A=0AThis=20= is=20the=20corresponding=20low-level=20sandboxing=20facility=20= corresponding=0Ato=20the=20recently=20added=20Seccomp=20for=20Linux.=20=20= `darwin-sandbox-init`=20gives=0Adirect=20access=20to=20the=20system=20= sandboxing=20call;=20`darwin-sandbox-enter`=20is=0Aa=20wrapper=20that=20= takes=20a=20list=20of=20directories=20under=20which=20files=20can=20be=0A= read.=20=20These=20should=20be=20considered=20internal=20mechanisms=20= for=20now.=0A=0A*=20lisp/darwin-fns.el:=20New=20file.=0A*=20= lisp/loadup.el:=20Load=20it.=0A*=20src/sysdep.c=20= (Fdarwin_sandbox_init):=20New=20function.=0A*=20= test/lisp/darwin-fns-tests.el:=20New=20file.=0A---=0A=20= lisp/darwin-fns.el=20=20=20=20=20=20=20=20=20=20=20=20|=2040=20= ++++++++++++++++=0A=20lisp/loadup.el=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20|=20=202=20+=0A=20src/sysdep.c=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20|=2034=20+++++++++++++=0A=20= test/lisp/darwin-fns-tests.el=20|=2090=20= +++++++++++++++++++++++++++++++++++=0A=204=20files=20changed,=20166=20= insertions(+)=0A=20create=20mode=20100644=20lisp/darwin-fns.el=0A=20= create=20mode=20100644=20test/lisp/darwin-fns-tests.el=0A=0Adiff=20--git=20= a/lisp/darwin-fns.el=20b/lisp/darwin-fns.el=0Anew=20file=20mode=20100644=0A= index=200000000000..e45aaa0c4e=0A---=20/dev/null=0A+++=20= b/lisp/darwin-fns.el=0A@@=20-0,0=20+1,40=20@@=0A+;;;=20darwin-fns.el=20= ---=20Darwin-specific=20functions=20=20-*-=20lexical-binding:=20t=20-*-=0A= +=0A+;;=20Copyright=20(C)=202021=20Free=20Software=20Foundation,=20Inc.=0A= +=0A+;;=20This=20file=20is=20part=20of=20GNU=20Emacs.=0A+=0A+;;=20GNU=20= Emacs=20is=20free=20software:=20you=20can=20redistribute=20it=20and/or=20= modify=0A+;;=20it=20under=20the=20terms=20of=20the=20GNU=20General=20= Public=20License=20as=20published=20by=0A+;;=20the=20Free=20Software=20= Foundation,=20either=20version=203=20of=20the=20License,=20or=0A+;;=20= (at=20your=20option)=20any=20later=20version.=0A+=0A+;;=20GNU=20Emacs=20= is=20distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A= +;;=20but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20= warranty=20of=0A+;;=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20= PARTICULAR=20PURPOSE.=20=20See=20the=0A+;;=20GNU=20General=20Public=20= License=20for=20more=20details.=0A+=0A+;;=20You=20should=20have=20= received=20a=20copy=20of=20the=20GNU=20General=20Public=20License=0A+;;=20= along=20with=20GNU=20Emacs.=20=20If=20not,=20see=20= .=0A+=0A+;;;=20Code:=0A+=0A+(defun=20= darwin-sandbox-enter=20(dirs)=0A+=20=20"Enter=20a=20sandbox=20only=20= permitting=20reading=20files=20under=20DIRS.=0A+DIRS=20is=20a=20list=20= of=20directory=20names.=20=20Most=20other=20operations=20such=20as=0A= +writing=20files=20and=20network=20access=20are=20disallowed.=0A= +Existing=20open=20descriptors=20can=20still=20be=20used=20freely.=0A+=0A= +This=20is=20not=20a=20supported=20interface=20and=20is=20for=20internal=20= use=20only."=0A+=20=20(darwin-sandbox-init=0A+=20=20=20(concat=20= "(version=201)\n"=0A+=20=20=20=20=20=20=20=20=20=20=20"(deny=20= default)\n"=0A+=20=20=20=20=20=20=20=20=20=20=20;;=20Emacs=20seems=20to=20= need=20/dev/null;=20allowing=20it=20does=20no=20harm.=0A+=20=20=20=20=20=20= =20=20=20=20=20"(allow=20file-read*=20(path=20\"/dev/null\"))\n"=0A+=20=20= =20=20=20=20=20=20=20=20=20(mapconcat=20(lambda=20(dir)=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(format=20= "(allow=20file-read*=20(subpath=20%S))\n"=20dir))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20dirs=20""))))=0A+=0A= +(provide=20'darwin-fns)=0A+=0A+;;;=20darwin-fns.el=20ends=20here=0Adiff=20= --git=20a/lisp/loadup.el=20b/lisp/loadup.el=0Aindex=20= d6cfcd6fc8..a6a7251d4b=20100644=0A---=20a/lisp/loadup.el=0A+++=20= b/lisp/loadup.el=0A@@=20-324,6=20+324,8=20@@=0A=20=20=20=20=20=20=20= (load=20"term/pc-win")=0A=20=20=20=20=20=20=20(load=20"ls-lisp")=0A=20=20= =20=20=20=20=20(load=20"disp-table")))=20;=20needed=20to=20setup=20= ibm-pc=20char=20set,=20see=20internal.el=0A+(if=20(eq=20system-type=20= 'darwin)=0A+=20=20=20=20(load=20"darwin-fns"))=0A=20(if=20(featurep=20= 'ns)=0A=20=20=20=20=20(progn=0A=20=20=20=20=20=20=20(load=20= "term/common-win")=0Adiff=20--git=20a/src/sysdep.c=20b/src/sysdep.c=0A= index=20d940acc4e0..4ea1f0050a=20100644=0A---=20a/src/sysdep.c=0A+++=20= b/src/sysdep.c=0A@@=20-4286,8=20+4286,42=20@@=20str_collate=20= (Lisp_Object=20s1,=20Lisp_Object=20s2,=0A=20}=0A=20#endif=09/*=20= WINDOWSNT=20*/=0A=20=0A+#ifdef=20DARWIN_OS=0A+=0A+/*=20This=20function=20= prototype=20is=20not=20in=20the=20platform=20header=20files.=0A+=20=20=20= See=20= https://reverse.put.as/wp-content/uploads/2011/09/Apple-Sandbox-Guide-v1.0= .pdf=0A+=20=20=20and=20= https://chromium.googlesource.com/chromium/src/+/master/sandbox/mac/seatbe= lt_sandbox_design.md=20*/=0A+int=20sandbox_init_with_parameters(const=20= char=20*profile,=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20uint64_t=20flags,=0A+=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20const=20char=20*const=20parameters[],=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20char=20**errorbuf);=0A+=0A+DEFUN=20("darwin-sandbox-init",=20= Fdarwin_sandbox_init,=20Sdarwin_sandbox_init,=0A+=20=20=20=20=20=20=201,=20= 1,=200,=0A+=20=20=20=20=20=20=20doc:=20/*=20Enter=20a=20sandbox=20whose=20= permitted=20access=20is=20curtailed=20by=20PROFILE.=0A+Already=20open=20= descriptors=20can=20be=20used=20freely.=0A+PROFILE=20is=20a=20string=20= in=20the=20macOS=20sandbox=20profile=20language,=0A+a=20set=20of=20rules=20= in=20a=20Lisp-like=20syntax.=0A+=0A+This=20is=20not=20a=20supported=20= interface=20and=20is=20for=20internal=20use=20only.=20*/)=0A+=20=20= (Lisp_Object=20profile)=0A+{=0A+=20=20CHECK_STRING=20(profile);=0A+=20=20= if=20(memchr=20(SSDATA=20(profile),=20'\0',=20SBYTES=20(profile)))=0A+=20= =20=20=20error=20("NUL=20in=20sandbox=20profile");=0A+=20=20char=20*err=20= =3D=20NULL;=0A+=20=20if=20(sandbox_init_with_parameters=20(SSDATA=20= (profile),=200,=20NULL,=20&err)=20!=3D=200)=0A+=20=20=20=20error=20= ("sandbox=20error:=20%s",=20err);=0A+=20=20return=20Qnil;=0A+}=0A+=0A= +#endif=09/*=20DARWIN_OS=20*/=0A+=0A=20void=0A=20syms_of_sysdep=20(void)=0A= =20{=0A=20=20=20defsubr=20(&Sget_internal_run_time);=0A+#ifdef=20= DARWIN_OS=0A+=20=20defsubr=20(&Sdarwin_sandbox_init);=0A+#endif=0A=20}=0A= diff=20--git=20a/test/lisp/darwin-fns-tests.el=20= b/test/lisp/darwin-fns-tests.el=0Anew=20file=20mode=20100644=0Aindex=20= 0000000000..1e426407a1=0A---=20/dev/null=0A+++=20= b/test/lisp/darwin-fns-tests.el=0A@@=20-0,0=20+1,90=20@@=0A+;;;=20= darwin-fns-tests.el=20---=20tests=20for=20darwin-fns.el=20=20-*-=20= lexical-binding:=20t=20-*-=0A+=0A+;;=20Copyright=20(C)=202021=20=20Free=20= Software=20Foundation,=20Inc.=0A+=0A+;;=20This=20file=20is=20part=20of=20= GNU=20Emacs.=0A+=0A+;;=20GNU=20Emacs=20is=20free=20software:=20you=20can=20= redistribute=20it=20and/or=20modify=0A+;;=20it=20under=20the=20terms=20= of=20the=20GNU=20General=20Public=20License=20as=20published=0A+;;=20by=20= the=20Free=20Software=20Foundation,=20either=20version=203=20of=20the=20= License,=0A+;;=20or=20(at=20your=20option)=20any=20later=20version.=0A+=0A= +;;=20GNU=20Emacs=20is=20distributed=20in=20the=20hope=20that=20it=20= will=20be=20useful,=20but=0A+;;=20WITHOUT=20ANY=20WARRANTY;=20without=20= even=20the=20implied=20warranty=20of=0A+;;=20MERCHANTABILITY=20or=20= FITNESS=20FOR=20A=20PARTICULAR=20PURPOSE.=20=20See=20the=20GNU=0A+;;=20= General=20Public=20License=20for=20more=20details.=0A+=0A+;;=20You=20= should=20have=20received=20a=20copy=20of=20the=20GNU=20General=20Public=20= License=0A+;;=20along=20with=20GNU=20Emacs.=20=20If=20not,=20see=20= .=0A+=0A+(require=20'ert)=0A+=0A+(defun=20= darwin-fns-tests--run-emacs=20(expr1=20expr2)=0A+=20=20"Run=20Emacs=20in=20= batch=20mode=20and=20evaluate=20EXPR1=20and=20EXPR2.=0A+Return=20= (EXIT-STATUS=20.=20OUTPUT),=20where=20OUTPUT=20is=20stderr=20and=20= stdout."=0A+=20=20(let=20((emacs=20(expand-file-name=20invocation-name=20= invocation-directory))=0A+=20=20=20=20=20=20=20=20(process-environment=20= nil))=0A+=20=20=20=20(with-temp-buffer=0A+=20=20=20=20=20=20(let=20((res=20= (call-process=20emacs=20nil=20t=20nil=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"--quick"=20= "--batch"=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(format=20"--eval=3D%S"=20expr1)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20(format=20"--eval=3D%S"=20expr2))))=0A+=20=20=20=20=20=20=20=20= (cons=20res=20(buffer-string))))))=0A+=0A+(ert-deftest=20= darwin-fns-sandbox=20()=0A+=20=20(skip-unless=20(eq=20system-type=20= 'darwin))=0A+=20=20;;=20Test=20file=20reading=20and=20writing=20under=20= various=20sandboxing=20conditions.=0A+=20=20(let*=20((some-text=20= "abcdef")=0A+=20=20=20=20=20=20=20=20=20(new-text=20"ghijkl")=0A+=20=20=20= =20=20=20=20=20=20(test-file=20(file-truename=20(make-temp-file=20= "test")))=0A+=20=20=20=20=20=20=20=20=20(file-dir=20(file-name-directory=20= test-file)))=0A+=20=20=20=20(unwind-protect=0A+=20=20=20=20=20=20=20=20= (dolist=20(mode=20'(read=20write))=0A+=20=20=20=20=20=20=20=20=20=20= (ert-info=20((symbol-name=20mode)=20:prefix=20"mode:=20")=0A+=20=20=20=20= =20=20=20=20=20=20=20=20(dolist=20(sandbox=20'(allow-all=20deny-all=20= allow-read))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20(ert-info=20= ((symbol-name=20sandbox)=20:prefix=20"sandbox:=20")=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20;;=20Prepare=20initial=20file=20contents.=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(with-temp-buffer=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(insert=20some-text)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(write-file=20= test-file))=0A+=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let*=20= ((sandbox-form=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(pcase-exhaustive=20sandbox=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20('allow-all=20nil)=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20('deny-all=20'(darwin-sandbox-enter=20nil))=0A+=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20('allow-read=20= `(darwin-sandbox-enter=20'(,file-dir)))))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(action-form=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(pcase-exhaustive=20= mode=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20('read=20`(progn=20(find-file-literally=20,test-file)=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20(message=20"OK:=20%s"=20= (buffer-string))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20('write=20`(with-temp-buffer=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20(insert=20,new-text)=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20(write-file=20,test-file)))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20(allowed=20(or=20(eq=20sandbox=20= 'allow-all)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(and=20(eq=20sandbox=20= 'allow-read)=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(eq=20= mode=20'read))))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(res-out=20(darwin-fns-tests--run-emacs=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20sandbox-form=20action-form))=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20(exit-status=20(car=20res-out))=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (output=20(cdr=20res-out))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(file-contents=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(with-temp-buffer=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (insert-file-contents-literally=20test-file)=0A+=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(buffer-string))))=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20allowed=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(should=20= (equal=20exit-status=200))=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20(should-not=20(equal=20exit-status=200)))=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20(when=20(eq=20mode=20'read)=0A+=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20allowed=0A= +=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= (should=20(equal=20output=20(format=20"OK:=20%s\n"=20some-text)))=0A+=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(should-not=20= (string-search=20some-text=20output))))=0A+=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20(should=20(equal=20file-contents=0A+=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20(if=20(and=20(eq=20mode=20'write)=20allowed)=0A+=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20new-text=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= some-text))))))))=0A+=0A+=20=20=20=20=20=20;;=20Clean=20up.=0A+=20=20=20=20= =20=20(ignore-errors=20(delete-file=20test-file)))))=0A+=0A+=0A+(provide=20= 'darwin-fns-tests)=0A--=20=0A2.21.1=20(Apple=20Git-122.3)=0A=0A= --Apple-Mail=_59FECC85-2A93-4A38-B1A5-7709DA915415--