A request for /css/app.css must turn into a file path inside the folder tinyserve serves.
A request for /../../etc/passwd must not. This mistake, path traversal, has leaked files
from real servers for decades, and it is exactly where naive string handling fails.
Write resolveInRoot(root, urlPath) with the [`node:path`](https://nodejs.org/api/path.html)
module.
root is an absolute folder, e.g. '/srv/site' (it may end with a slash).urlPath is the already-decoded path of the request; it always starts with /.., .., double or trailing slash — what path.resolve produces), or null when it is not inside root.
root itself is inside: '/' maps to '/srv/site'.\0) returns null.resolveInRoot('/srv/site', '/etc/passwd'); // '/srv/site/etc/passwd' — not '/etc/passwd'
resolveInRoot('/srv/site', '/../site-backup/db'); // null — '/srv/site-backup' starts with '/srv/site'!
resolveInRoot('/srv/site', '/..config'); // '/srv/site/..config' — a normal file namepath.resolve(root, '/etc/passwd') returns /etc/passwd: an absolute argument wins.full.startsWith(root) accepts the sibling folder /srv/site-backup. Compare with path.relative(root, full) instead.
Sample tests