859bc749b0593a83e1c8cd7149f956b620a24a73
braney
  Sat Sep 19 18:14:15 2026 -0700
trashDirTester: pin which file paths the cart accepts

hg/lib/cart.c screens every cart variable that names a server-made file through
these functions, so they decide whether a saved session still works.  Both ways
of being wrong are invisible: a path wrongly refused brings the session back
without its custom track or its region list and says nothing, and a path
wrongly accepted says nothing either.

That is what #38303 cost.  A check shipped in v503 discarded the saved region
list from 583 sessions on the RR and 66 on euro, and hgwdev, code review and
hgwbeta were all clean, because the corpus that shows it is only on the
production central.

Four rules pinned, each of which cost a bug or a review round: only the
configured directory is symlink-resolved and never the path from the cart; the
resolved spelling of that directory is accepted as well as the configured one,
since /userdata on the RR is a symlink and saved sessions hold both spellings;
only an absolute directory is resolved, because a relative one would be
resolved against the caller's working directory; and the acceptance runs one
direction only.  pathIsUnderDir's own edges are here too, including the sibling
directory that merely starts the same way and the name that begins with "..".

The fixture is a directory, a symlink to it and three confs naming the same
place three ways, since hgConfig caches what it read and one process can only
answer for one spelling.  Nothing machine-specific reaches the output.

Watched to fail and then pass: with the pre-#38303 code, which did not resolve
at all, the resolved spelling comes back refused and the diff is that one line.
Recorded as sandbox-ab in utils/testRegistry.

refs #38303, refs #37623, refs #38391

diff --git src/utils/testRegistry/registry.tsv src/utils/testRegistry/registry.tsv
index dc474afdb78..89163a4aac3 100644
--- src/utils/testRegistry/registry.tsv
+++ src/utils/testRegistry/registry.tsv
@@ -64,26 +64,26 @@
 38225	504	-	-	perf	-	needs one: the malloc step size now comes from hg.conf; the test has to read the knob back and see it applied
 38233	504	-	-	perf	-	needs one: RefSeq status is asked once per track, not once per gene; the test has to count the queries, not the seconds
 38236	504	-	rm38236.docent.yaml	library	-	needs one: a quickLift chain with no aligned block in the window must not crash
 38248	504	-	rm38248.docent.yaml	library	-	needs one: a deprecated versioned NP_ accession has to resolve to RefSeq Historical
 38249	504	hg/lib/tests/quickLiftTester.c	rm38249.docent.yaml	library	unrecorded	the target strand of a reverse complemented protein, found in the #38349 review
 38253	504	-	-	perf	-	needs one: item coverage is built from feature runs, not one counter per base; the test has to go red if a per-base pass comes back
 38254	504	-	-	invisible	-	needs one: a composite subtrack's visibility has to settle before the parallel loaders start
 38256	504	hg/utils/hubCheck/tests/makefile::relPath	-	library	unrecorded	a local hub given by a relative path: bigDataUrl resolved once, not twice
 38260	504	hg/utils/hubCheck/tests/makefile::missingFile	-	library	unrecorded	hubCheck must say something about a bigDataUrl it cannot open
 38268	504	-	rm38268.docent.yaml	invisible	-	needs one: the tightened dataVersion path check
 38272	504	-	rm38272.docent.yaml	invisible	-	needs one: a GenArk quickLift source assembly must not be looked for in MySQL
 38273	504	-	-	perf	-	needs one: a collection's hub file is copied when it is written, not on every session load; the test has to count the copies
 38283	504	-	rm38283.docent.yaml	library	-	needs one: description page variables substituted once, and in the container
 38285	504	hg/lib/tests/input/hgvs/validTerms.txt	rm38285.docent.yaml	library	unrecorded	bare codon numbers and ranges, with expected/hgvs/validTerms.txt beside it
 38302	504	-	rm38302.docent.yaml	invisible	-	needs one: an activation token that is missing, empty or older than seven days is invalid
-38303	504	-	rm38303.docent.yaml	invisible	-	needs one: a session file path spelled through a symlinked config directory, which broke 583 saved sessions
+38303	504	hg/lib/tests/trashDirTester.c	rm38303.docent.yaml	invisible	sandbox-ab	a session file path spelled through a symlinked config directory, which broke 583 saved sessions
 38309	504	-	rm38309.docent.yaml	invisible	-	needs one: exonFrames must not be read past the end on a transcript's last exon
 38313	504	-	-	library	-	needs one: a user's own __ sessions must not be hidden from My Sessions
 38317	504	-	-	invisible	-	needs one: doKnownGene must not read an uninitialised stack refLink
 38318	504	hg/lib/tests/sessionDataTester.c	-	invisible	unrecorded	the returned path must be freeable through kent's own handler stack
 38320	504	lib/tests/faSpeedReadTest.c	-	invisible	unrecorded	the buffer grower and its caller must agree on the size
 38323	504	-	-	library	-	needs one: an api key made on one geo mirror has to work on all of them
 38328	504	-	-	invisible	-	needs one: the liftOver accession list passed as an slName list
 38335	504	lib/tests/cgiParseTest.c	rm38335.docent.yaml	invisible	unrecorded	a pair with no =value must not lose the variable
 38340	504	hg/hgSession/tests/backupParseTest.c	-	invisible	unrecorded	the same pair, read back out of a session backup
 38340	504	lib/tests/cgiCookieTest.c	-	invisible	unrecorded	the same pair in a cookie header