Fix 9 bugs and add 103 tests for core anonymization, config, and routing (#669)

This commit is contained in:
Thomas Durieux
2026-04-15 09:41:00 +02:00
committed by GitHub
parent 261eaa8d79
commit 188066e91d
23 changed files with 2630 additions and 39 deletions
+10 -5
View File
@@ -129,10 +129,10 @@ router.get("/repos", async (req, res) => {
}
const query = [];
if (req.query.search) {
query.push({ repoId: { $regex: req.query.search } });
const escaped = (req.query.search as string).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
query.push({ repoId: { $regex: escaped } });
}
const status: { status: string }[] = [];
query.push({ $or: status });
if (ready) {
status.push({ status: "ready" });
}
@@ -151,6 +151,9 @@ router.get("/repos", async (req, res) => {
status.push({ status: "preparing" });
status.push({ status: "download" });
}
if (status.length > 0) {
query.push({ $or: status });
}
const skipIndex = (page - 1) * limit;
const [total, results] = await Promise.all([
AnonymizedRepositoryModel.find({
@@ -199,7 +202,8 @@ router.get("/users", async (req, res) => {
}
let query = {};
if (req.query.search) {
query = { username: { $regex: req.query.search } };
const escaped = (req.query.search as string).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
query = { username: { $regex: escaped } };
}
res.json({
@@ -270,10 +274,11 @@ router.get("/conferences", async (req, res) => {
}
let query = {};
if (req.query.search) {
const escaped = (req.query.search as string).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
query = {
$or: [
{ name: { $regex: req.query.search } },
{ conferenceID: { $regex: req.query.search } },
{ name: { $regex: escaped } },
{ conferenceID: { $regex: escaped } },
],
};
}
+1 -1
View File
@@ -32,7 +32,7 @@ router.get(
try {
if (!(await repo.isReady())) {
throw new AnonymousError("repository_not_ready", {
object: this,
object: repo,
httpStatus: 503,
});
}
+1 -1
View File
@@ -70,7 +70,7 @@ router.get(
.on("error", () => {
handleError(
new AnonymousError("file_not_found", {
object: this,
object: req.params.repoId,
httpStatus: 404,
}),
res
+4 -2
View File
@@ -20,12 +20,12 @@ export async function getPullRequest(
pullRequest.options.expirationMode == "redirect"
) {
res.redirect(
`http://github.com/${pullRequest.source.repositoryFullName}/pull/${pullRequest.source.pullRequestId}`
`https://github.com/${pullRequest.source.repositoryFullName}/pull/${pullRequest.source.pullRequestId}`
);
return null;
}
pullRequest.check();
await pullRequest.check();
}
return pullRequest;
} catch (error) {
@@ -105,6 +105,8 @@ export function handleError(
let errorCode = error;
if (error instanceof Error) {
errorCode = error.message;
} else if (typeof error !== "string") {
errorCode = String(error);
}
let status = 500;
if (error.httpStatus) {
+13 -4
View File
@@ -8,6 +8,15 @@ import * as sanitizeHtml from "sanitize-html";
import { streamToString } from "../../core/anonymize-utils";
import { IFile } from "../../core/model/files/files.types";
function escapeHtml(str: string): string {
return str
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
const sanitizeOptions: sanitizeHtml.IOptions = {
allowedTags: sanitizeHtml.defaults.allowedTags.concat([
"img",
@@ -120,12 +129,12 @@ async function webView(req: express.Request, res: express.Response) {
});
} else {
// print list of files in the root repository
const body = `<div class="container p-3"><h2>Content of ${filePath}</h2><div class="list-group">${candidates
const body = `<div class="container p-3"><h2>Content of ${escapeHtml(filePath)}</h2><div class="list-group">${candidates
.map(
(c) =>
`<a class="list-group-item list-group-item-action" href="${
c.name + (c.size == null ? "/" : "")
}">${c.name + (c.size == null ? "/" : "")}</a>`
encodeURI(c.name) + (c.size == null ? "/" : "")
}">${escapeHtml(c.name) + (c.size == null ? "/" : "")}</a>`
)
.join("")}</div></div>`;
const html = `<!DOCTYPE html><html><head><title>Content</title></head><link rel="stylesheet" href="/css/all.min.css" /><body>${body}</body></html>`;
@@ -142,7 +151,7 @@ async function webView(req: express.Request, res: express.Response) {
if (f.extension() == "md") {
const content = await streamToString(await f.anonymizedContent());
const body = sanitizeHtml(marked.marked(content, { headerIds: false, mangle: false }), sanitizeOptions);
const html = `<!DOCTYPE html><html><head><title>Content</title></head><link rel="stylesheet" href="/css/all.min.css" /><body><div class="container p-3 file-content markdown-body">${body}<div></body></html>`;
const html = `<!DOCTYPE html><html><head><title>Content</title></head><link rel="stylesheet" href="/css/all.min.css" /><body><div class="container p-3 file-content markdown-body">${body}</div></body></html>`;
res.contentType("text/html").send(html);
} else {
f.send(res);