Refuse a symbolic link under experiments/ (#61) - #132
Merged
Conversation
The tree under experiments/ is written by whoever proposes an experiment, so it is the runner's input rather than its environment. A link in it was walked past in silence: an experiment directory reached only through one stated its question to nobody, because every rule about a record reads one the walk found and the walk found none. It is now refused where the walk meets it, and never opened, resolved or descended into. The walk reads through a filesystem it is given rather than through the one the process runs on, and that is the whole reason the refusal can be proved. A fixture that asks the machine for a link cannot be had on every platform the suite runs on: creating one on Windows needs SeCreateSymbolicLinkPrivilege, which an ordinary account does not hold, and os.Symlink returns error 1314 there. A tracked link arrives on such a checkout as a text file, so a case built that way asks about a link on one platform and about a file on another. Record 0007 keeps the default run unelevated and record 0012 runs the suite on windows/amd64, so neither route was available. A directory entry supplied to the walk needs no privilege and behaves the same everywhere. The case and its near neighbour are identical byte for byte and differ only in the line declaring the entry a link, so the refusal is shown to be about the link rather than about the name, the place or the bytes. What that pair leaves unproved is that an operating system reports a link as an entry of that type, which is the standard library's behaviour and not this runner's, and the harness says so where the departure is made. Subjects are unchanged: every refusal still names a path written the way the reader's machine writes one. Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #61
What this changes
A symbolic link anywhere under
experiments/is refused where the walk meetsit, and is never opened, resolved or descended into. That is the half of #61
that PR #106 left, and the loop fixture that depended on it.
The other change is what makes the first one provable. The walk reads through a
filesystem it is given rather than through the one the process runs on. The
public entry is unchanged and still takes a path;
Walkopens the tree andhands it to the walk, and the path it was given is carried alongside for one
purpose, which is building the path a refusal names. Subjects are byte for byte
what they were.
A case may now declare that one of its entries is a link, in a
linksfilebeside the expectation. Two new cases use it:
a-symbolic-link-under-experiments, whoseexperiments/upis declared a linkand whose target is
..an-ordinary-file-where-a-link-would-be, its near neighbourTheir trees are identical byte for byte. The only difference between them is
the one line declaring the entry a link, so the refusal is shown to be about the
link and not about the name, the place or the bytes.
Why the fixture is declared rather than made
#61 offers two routes for the link fixture and the measurement on that issue
closes both.
A link built at run time needs
SeCreateSymbolicLinkPrivilegeon Windows, whichan ordinary account does not hold, and
os.Symlinkreturns windows error 1314there. Record 0007 keeps the default run unelevated, so that route either fails
on a machine for a reason that has nothing to do with the runner, or skips,
which #57 rules out for a platform.
A tracked link arrives on such a checkout as an ordinary file holding its target
as text. A case built that way asks the runner about a link on one platform and
about a text file on another while declaring a single answer for both, and
record 0012 runs the suite on
windows/amd64.A directory entry handed to the walk needs no privilege and is the same on every
platform. The bytes under
tree/are still exactly what the walk read; the onlything the harness supplies is the type of one entry. That departure and its
reason are written at the harness, where the layout of a case is decided, rather
than only here.
What failure it prevents
An experiment reached only through a link stated its question to nobody. Every
rule about a record reads one the walk found, a link was walked past without
being counted or refused, and the run then printed a directory count and a
record count that were both silently short. Nothing went red and nothing said
that anything had been left out, which is the shape this board exists to make
impossible.
What was run
The gate, at this commit:
gofmt -l cmd internalprinting nothing is its passing result. The runner stillrefuses nothing on this tree, and the counts are the ones it printed before:
The standing requirement refused this change before the case existed, which is
the harness doing its job:
Each guard proved by breaking it
Three mutations, each the smallest one that could be made, run and reverted.
The refusal site deleted:
!= 0written as== 0, which is the one-character mistake somebody makeshere. It reddens the near neighbour, which is what that neighbour is for, and it
reddens twelve further cases that carry an ordinary file under
experiments/:It does not redden the refusing case, because that tree also holds a record
file, and with the bit inverted the record file trips the property instead. The
first mutation is what covers that direction.
The harness no longer applying the declaration, which is the mutation that would
otherwise leave the case green against an ordinary file:
TestADeclaredLinkIsReportedAsOneholds the same thing standing, and it alsorefuses the day the entry becomes a link on disk, since a declaration over
something that is already a link proves nothing about the declaration.
The means
Go, in the package that already walks this tree, with a case in the harness that
already proves every other refusal here. Reading through
io/fsadds nolanguage, no runtime and no dependency: it is in the standard library this
module already builds on, and it is the interface the walk was already half
written against, since
fs.DirEntryandfs.SkipDirwere in these signaturesbefore this change. Nothing outside this repository forces a different means.
What this does not do
It does not follow a link to find out where it goes, and it makes no claim about
where one goes. A link under
experiments/pointing at a file inside thisrepository is refused exactly like one pointing outside it. Where a link lands is
a question about a filesystem that no reading here can be right about on every
platform the release targets.
It refuses no link outside
experiments/. The rest of a checkout is somebody'sown arrangement of their own machine, and this board has nothing to say about it.
It is not a sandbox and adds none. The runner runs with the privileges of
whoever started it and reads what it is pointed at.
The loop half of #61 is met by the same case rather than by a second one, and
what that is worth is bounded.
experiments/uppoints at.., so anything thatresolved it would re-enter
experiments/without end, and the suite completingis the evidence that nothing does. What it does not prove is that the refusal is
what stops the loop: a directory walk does not follow links to begin with, so
that tree terminated before this change too.
The pair proves what the runner does when it meets an entry of that type. That
an operating system reports a link as an entry of that type is the standard
library's behaviour rather than this runner's, and no case here proves it.
Reading
Nothing in this change has been read by a second person. The evidence above
stands in place of that reading, and this sentence is here so that the absence
is not mistaken for a review that happened.