bitter-ability-32190
10/27/2022, 8:16 PMpytest.param(
CreateDigest(
[
FileContent("file.txt", b"four\n"),
SymlinkEntry("a/dirlink", "../b/c/d"),
SymlinkEntry("b/c/d/link", "../../file.txt"),
]
),
# NOTE: No "b/c/d/link", because that'd result in "a/file.txt"
("a/dirlink/link", "file.txt"),
("a", "a/dirlink", "b", "b/c", "b/c/d"),
id="symlink-makes-updir-valid",
),
Please let me know your favorite evil symlink scenario, and we'll turn the testing up to 11.broad-processor-92400
10/27/2022, 11:03 PMlhs -> rhs is a link called lhs pointing to a file rhs, i.e. created via ln -s rhs lhs)
.
├── broken -> doesnt_exist
├── dir
│ ├── parent -> ..
│ ├── self -> .
│ ├── self_obtusely -> ../dir
│ └── self_very_obtusely -> self/self/self/self/self_obtusely/parent/dir/parent/dir/parent/dir/self
├── escape
│ ├── absolute -> /etc/passwd
│ └── traversal -> ../../../../../../../../../../../../etc/passwd
└── loop
├── chain1 -> chain2
├── chain2 -> chain3
├── chain3 -> chain1
├── self -> self
├── via_chain -> chain1/file.txt
└── via_self -> self/file.txt
Most of these are ... going out of my way to be difficult, but:
• I imagine the escape/absolute one could come in practice, e.g. a Python venv seems to have an absolute symlink to its interpreter.
• readlink -f dir/self_very_obtusely confirms that it is pointing to dir/
• Naive tooling may infinite-loop on some of the loop ones too.bitter-ability-32190
10/28/2022, 1:31 AMbitter-ability-32190
11/02/2022, 2:23 PMself_obtusely is gnarly. Since the preceder is ., you can't just go resolve the parent directory but lopping off the component above it. You need to resolve that, then go up one!bitter-ability-32190
11/02/2022, 2:31 PM"." is the evilest symlink in existance