(see also PR#15179):
When looking up names which directory components (i.e. having slashes,
except when of the form `./name'), FindFile()/DirLookup() first looks
the final filename component in the cache for each directory on the search
path and then proceeds to match the prefixed directory components by
comparing them to the trailing directory components of the the search
path being probed.
This is not correct. When looking for `bar/target' in a path `.../src/foo',
you want it to come up with `.../src/foo/bar/target' (if it exists). There's
no point in comparing the the `bar' prefix on the target to the `foo' suffix
on the search path. Indeed, this will cause a false match if those prefix
and suffix components are actually equal and search path itself also has a
file called `target'. For example, looking for `foo/target' in `.../src/foo'
will spuriously match `.../src/foo/target', not `.../src/foo/foo/target'.
This last bug prompted the change in dir.c, rev 1.27, which happens
to partially workaround it by avoiding the above matching code in the
case of the `curdir' search path entry (at the cost of incurring an
exorbitant amount of cache misses). The situation is unchanged however,
when processing other entries on the search path (e.g. those other than
`dot' and `cur').
Drop the prefix matching code in DirLookup() entirely and use DirFindDot()
and DirLookup() only for names without proper directory components (i.e.
`target' and `./target). Otherwise, non-absolute names are dealt with by
DirLookupSubdir(), while absolute names can be checked for an exact match
of the directory components prefix against the directories on the current
search path. This allows for the use of the file cache to check the
existence of the file and additionally, provides a shortcut out of
Dir_FindFile() if we have the prefix match but not a cache entry (this
is especially beneficial for searches in .CURDIR when it's not equal
to `dot').