Skip to content

Commit 4f4cc8d

Browse files
authored
test: parity regression guard for alias-branch template delimiter neutralization (#31712)
1 parent c609547 commit 4f4cc8d

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

actions/setup/js/sanitize_content.test.cjs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
1+
import { describe, it, expect, beforeEach, beforeAll, afterEach, vi } from "vitest";
22

33
describe("sanitize_content.cjs", () => {
44
let mockCore;
@@ -2751,4 +2751,43 @@ describe("sanitize_content.cjs", () => {
27512751
expect(result).toContain("\\{\\{"); // template escaped
27522752
});
27532753
});
2754+
2755+
describe("parity: sanitizeContent alias-branch vs sanitizeContentCore for template syntax (regression)", () => {
2756+
// Regression guard: sanitizeContent with allowedAliases must produce the same
2757+
// template-delimiter escaping as sanitizeContentCore. In v0.68.3 this parity was
2758+
// broken because the alias branch did not call neutralizeTemplateDelimiters.
2759+
//
2760+
// Parity verification is the right level of abstraction here: if the alias branch
2761+
// ever stops calling neutralizeTemplateDelimiters (or any equivalent escaping step),
2762+
// its output will contain raw template syntax while sanitizeContentCore output will
2763+
// have it escaped, causing these tests to fail and exposing the regression.
2764+
let sanitizeContentCore;
2765+
2766+
beforeAll(async () => {
2767+
const coreModule = await import("./sanitize_content_core.cjs");
2768+
sanitizeContentCore = coreModule.sanitizeContentCore;
2769+
});
2770+
2771+
const templateParityInputs = [
2772+
{ name: "Jinja2/Liquid double braces", input: "Result: {{ secret.token }}" },
2773+
{ name: "JavaScript template literal", input: "Value: ${ expression }" },
2774+
{ name: "Jekyll/Liquid directive", input: "{% if condition %}value{% endif %}" },
2775+
{ name: "ERB delimiter", input: "<%= config.adminToken %>" },
2776+
{ name: "Jinja2 comment", input: "{# this is a comment #}" },
2777+
{
2778+
name: "all five patterns together",
2779+
input: "{{ var }}, ${ js }, {% tag %}, <%= erb %>, {# comment #}",
2780+
},
2781+
];
2782+
2783+
for (const { name, input } of templateParityInputs) {
2784+
it(`alias-branch and core produce identical template escaping for: ${name}`, async () => {
2785+
// Use an alias that will never match any mention in the input so the alias
2786+
// branch code-path is exercised without altering mention escaping.
2787+
const aliasResult = sanitizeContent(input, { allowedAliases: ["nobody"] });
2788+
const coreResult = sanitizeContentCore(input);
2789+
expect(aliasResult).toBe(coreResult);
2790+
});
2791+
}
2792+
});
27542793
});

0 commit comments

Comments
 (0)