Skip to content

Commit fb0951d

Browse files
committed
Only do cheap sanity check for the redirect target path.
1 parent 2cc31a1 commit fb0951d

File tree

2 files changed

+16
-28
lines changed

2 files changed

+16
-28
lines changed

app/lib/task/backend.dart

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -869,18 +869,6 @@ class TaskBackend {
869869
return index;
870870
}
871871

872-
/// Whether the task result for the given [package]/[version] has any result
873-
/// dartdoc-generated file in [path].
874-
Future<bool> hasDartdocTaskResult(
875-
String package, String version, String path) async {
876-
version = canonicalizeVersion(version)!;
877-
final index = await _taskResultIndex(package, version);
878-
if (index == null) {
879-
return false;
880-
}
881-
return index.lookup('doc/$path') != null;
882-
}
883-
884872
/// Return gzipped result from task for the given [package]/[version] or
885873
/// `null`.
886874
Future<List<int>?> gzippedTaskResult(

app/lib/task/handlers.dart

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)