mirror of
https://github.com/github/awesome-copilot.git
synced 2026-08-25 10:21:40 +00:00
Fix codespell and CodeQL findings in website components
- Fix real typos flagged by codespell: 'Couldn't' -> 'Couldn't' (plain apostrophe, matching convention elsewhere in JSX) and 'Unparseable' -> 'Unparsable' in catalogFilters.ts - DetailChassis.tsx: replace sequential HTML entity unescaping with a single-pass replace to avoid double-unescape/injection risk flagged by CodeQL - SyntaxHighlightedCode.tsx: make the markup HTML comment regex match newlines so multi-line comments cannot break out of the token (Bad HTML filtering regexp) - pagefindSearch.ts: strip HTML tags in a loop until stable so nested/ malformed markup can't survive a single-pass strip (Incomplete multi-character sanitization) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80686fef-efe3-4cdd-8cd6-bfa61a5d0af6
This commit is contained in:
@@ -368,7 +368,7 @@ function RecipeFileView({
|
|||||||
if (status === "error" || text === undefined) {
|
if (status === "error" || text === undefined) {
|
||||||
return (
|
return (
|
||||||
<Text as="p" size="200" variant="muted">
|
<Text as="p" size="200" variant="muted">
|
||||||
Couldn't load this file. <a href={githubUrl}>View it on GitHub</a>.
|
Couldn't load this file. <a href={githubUrl}>View it on GitHub</a>.
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,11 +402,20 @@ export function buildDetailToc(markdownHtml: string): {
|
|||||||
(match, attrs: string, inner: string) => {
|
(match, attrs: string, inner: string) => {
|
||||||
const label = inner
|
const label = inner
|
||||||
.replace(/<[^>]+>/g, "")
|
.replace(/<[^>]+>/g, "")
|
||||||
.replace(/&/g, "&")
|
.replace(/<|>|"|'|&/g, (entity) => {
|
||||||
.replace(/</g, "<")
|
switch (entity) {
|
||||||
.replace(/>/g, ">")
|
case "<":
|
||||||
.replace(/"/g, '"')
|
return "<";
|
||||||
.replace(/'/g, "'")
|
case ">":
|
||||||
|
return ">";
|
||||||
|
case """:
|
||||||
|
return '"';
|
||||||
|
case "'":
|
||||||
|
return "'";
|
||||||
|
default:
|
||||||
|
return "&";
|
||||||
|
}
|
||||||
|
})
|
||||||
.trim();
|
.trim();
|
||||||
if (!label) return match;
|
if (!label) return match;
|
||||||
|
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ function FileView({
|
|||||||
if (status === "error" || text === undefined) {
|
if (status === "error" || text === undefined) {
|
||||||
return (
|
return (
|
||||||
<Text as="p" size="200" variant="muted">
|
<Text as="p" size="200" variant="muted">
|
||||||
Couldn't load this file. <a href={githubUrl}>View it on GitHub</a>.
|
Couldn't load this file. <a href={githubUrl}>View it on GitHub</a>.
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const rules: Record<CodeLanguage, readonly TokenRule[]> = {
|
|||||||
{ kind: "punctuation", expression: /[{}[\],:]/y },
|
{ kind: "punctuation", expression: /[{}[\],:]/y },
|
||||||
],
|
],
|
||||||
markup: [
|
markup: [
|
||||||
{ kind: "comment", expression: /<!--.*?-->/y },
|
{ kind: "comment", expression: /<!--[\s\S]*?-->/y },
|
||||||
{ kind: "tag", expression: /<\/?[A-Za-z][\w:-]*/y },
|
{ kind: "tag", expression: /<\/?[A-Za-z][\w:-]*/y },
|
||||||
{ kind: "attr-name", expression: /[A-Za-z_:][\w:.-]*(?=\s*=)/y },
|
{ kind: "attr-name", expression: /[A-Za-z_:][\w:.-]*(?=\s*=)/y },
|
||||||
{ kind: "string", expression: /"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/y },
|
{ kind: "string", expression: /"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/y },
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export const updatedBuckets: { label: string; max: number }[] = [
|
|||||||
{ label: "Older", max: Number.POSITIVE_INFINITY },
|
{ label: "Older", max: Number.POSITIVE_INFINITY },
|
||||||
];
|
];
|
||||||
|
|
||||||
/** Whole days between `lastUpdated` and now. Unparseable dates sort as oldest. */
|
/** Whole days between `lastUpdated` and now. Unparsable dates sort as oldest. */
|
||||||
export function daysSince(lastUpdated: string | undefined): number {
|
export function daysSince(lastUpdated: string | undefined): number {
|
||||||
if (!lastUpdated) return Number.POSITIVE_INFINITY;
|
if (!lastUpdated) return Number.POSITIVE_INFINITY;
|
||||||
const then = Date.parse(lastUpdated);
|
const then = Date.parse(lastUpdated);
|
||||||
|
|||||||
@@ -15,6 +15,19 @@ type PagefindResultData = {
|
|||||||
meta?: Record<string, string | undefined>;
|
meta?: Record<string, string | undefined>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Strip HTML tags, repeating until no more tags remain so a malformed or
|
||||||
|
* nested markup fragment (e.g. `<<script>script>`) can't survive a single pass. */
|
||||||
|
function stripTags(html: string): string {
|
||||||
|
let text = html;
|
||||||
|
let previous: string;
|
||||||
|
do {
|
||||||
|
previous = text;
|
||||||
|
text = text.replace(/<[^>]*>/g, " ");
|
||||||
|
} while (text !== previous);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type PagefindModule = {
|
type PagefindModule = {
|
||||||
options?: (opts: Record<string, unknown>) => Promise<void>;
|
options?: (opts: Record<string, unknown>) => Promise<void>;
|
||||||
init?: () => Promise<void>;
|
init?: () => Promise<void>;
|
||||||
@@ -127,7 +140,7 @@ export async function searchPagefind(
|
|||||||
if (!title) continue;
|
if (!title) continue;
|
||||||
items.push({
|
items.push({
|
||||||
title,
|
title,
|
||||||
description: entry.excerpt?.replace(/<[^>]*>/g, "") ?? "",
|
description: entry.excerpt ? stripTags(entry.excerpt) : "",
|
||||||
category: categoryOf(entry.url.split(/[?#]/)[0]),
|
category: categoryOf(entry.url.split(/[?#]/)[0]),
|
||||||
href: entry.url,
|
href: entry.url,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user