Repository navigation
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates Resolver.resolve to reject package: and dart: URIs that fall outside known roots, and canonicalizes known roots to ensure paths reached through symlinks resolve correctly. The changes are accompanied by comprehensive unit tests. The review feedback suggests a robustness improvement in resolver.dart to fall back to a normalized absolute path when resolving symbolic links for roots, preventing potential mismatches when comparing absolute paths against relative roots.
liamappelbe
left a comment
There was a problem hiding this comment.
Approved with comments.
|
Done @liamappelbe — moved symlink resolution and root containment into _resolveLinksWithinKnownRoots() and updated all call sites. Thanks! |
03c1d1d to
927b7ff
Compare
|
Also cleaned up the odd formatter indentation by extracting the known-root initialization into _createKnownRoots(). I squashed the PR down to a single commit as well. |
927b7ff to
707e908
Compare
|
@liamappelbe Formatting is fixed and the PR is squashed to one commit. Could you |
|
Hi @j0xh-sec. Sorry for the slow response. I've been on vacation. If you reopen this PR I'd be happy to merge it. |
|
The original fork was accidentally deleted, which automatically closed this PR and prevented reopening it. I've restored the changes in #2764, including the original fix and regression tests. Further updates will be tracked there. Thanks @liamappelbe for your review ! |
Summary
Completes the containment check added in #2534.
#2534 added
_isWithinKnownRootsto thefile:branch ofResolver.resolve(), on the basis — stated in its own_knownRootsdoc comment — that coveragesourceentries are untrusted and their resolved contents are read into formatter output. Thepackage:anddart:branches were left without the same check, so they can still resolve outside the known roots.The gap
Plain
..does not traverse, becauseUri.parseperforms RFC 3986 dot-segment removal before the resolver sees the path. ButUri.pathSegmentspercent-decodes after that, so an encoded separator survives as a single segment:packageNamestaysfoo(the package lookup succeeds), andp.join(packagePath, ...)+resolveSymbolicLinksthen walk out of the package root. The same applies todart:. The resolved path's contents are read byformat_coverage --pretty-printandfilterIgnored, so wherever coverage JSON crosses a trust boundary this reads files outside the roots.Change
_isWithinKnownRootscheck to thepackage:anddart:branches, mirroringfile:.resolveSymbolicLinks, since the paths they are compared against are canonicalized the same way. Without this, a root reached through a symlink (a symlinked pub cache, or/var->/private/varon macOS) would never contain its own files and legitimate resolution would start returningnull.Tests
Three added: a
package:encoded-separator escape returnsnull, adart:escape returnsnull, and apackage:URI through a symlinked root still resolves.dart analyze,dart format --set-exit-if-changed, and the fullcoveragesuite pass.Notes
Resolver.BazelResolverreturns relative paths (resolved by the caller against the cwd) rather than paths within these roots, so it is a different shape — happy to follow up on it separately if you'd like.