@@ -103,11 +103,24 @@ Future<shelf.Response> handleDartDoc(
103103 redirectPath,
104104 if (! redirectPath.endsWith ('.html' )) 'index.html' ,
105105 ]));
106- return redirectResponse ( pkgDocUrl (
106+ final newDocUrl = pkgDocUrl (
107107 package,
108108 version: resolvedDocUrlVersion.urlSegment,
109109 relativePath: newPath,
110- ));
110+ );
111+
112+ // Sanity check to prevent redirecting outside of the generated document content,
113+ // as it shouldn't happen under normal operations. It may be a dartdoc bug or the
114+ // worker may have been compromised.
115+ final docUrlRoot =
116+ pkgDocUrl (package, version: resolvedDocUrlVersion.urlSegment);
117+ if (! newDocUrl.startsWith (docUrlRoot)) {
118+ _logger.shout ('$package ${resolvedDocUrlVersion .version } file $path '
119+ 'redirects outside of the documentation root: $newDocUrl ' );
120+ return notFoundHandler (request);
121+ }
122+
123+ return redirectResponse (newDocUrl);
111124 }
112125
113126 if (cachedStatusCode == DocPageStatusCode .redirect) {
@@ -156,20 +169,7 @@ Future<shelf.Response> handleDartDoc(
156169 if (page.isEmpty () &&
157170 redirectPath != null &&
158171 p.isRelative (redirectPath)) {
159- final newPath = p.normalize (p.joinAll ([
160- p.dirname (path),
161- redirectPath,
162- if (! redirectPath.endsWith ('.html' )) 'index.html' ,
163- ]));
164- if (await taskBackend.hasDartdocTaskResult (
165- package, version, newPath)) {
166- return (DocPageStatus .redirect (redirectPath), null );
167- } else {
168- return (
169- DocPageStatus .missing ('Dartdoc redirect is missing.' ),
170- null , // bytes
171- );
172- }
172+ return (DocPageStatus .redirect (redirectPath), null );
173173 }
174174
175175 final html = page.render (DartDocPageOptions (
0 commit comments