
























@@ -114,6 +114,20 @@ function sanitizeGalleryPreview(
114114return value === null ? null : sanitizeGalleryText(value, params);
115115}
116116117+function sanitizeGalleryStringArray(
118+values: Iterable<unknown>,
119+params: {
120+extraRoots?: readonly string[];
121+repoRoot: string;
122+},
123+) {
124+return readOrderedStringArray(
125+Array.from(values)
126+.filter((value): value is string => typeof value === "string")
127+.map((value) => sanitizeGalleryText(value, params)),
128+);
129+}
130+117131async function realpathIfExists(filePath: string): Promise<string | null> {
118132return fs.realpath(filePath).catch(() => null);
119133}
@@ -422,11 +436,11 @@ async function buildArtifactView(params: {
422436 ? "Evidence artifact is not declared by this evidence summary."
423437 : "Evidence artifact not found.",
424438href: null,
425-kind: params.artifact.kind,
439+kind: sanitizeGalleryText(params.artifact.kind, params),
426440 mediaKind,
427441path: displayPath,
428442preview: null,
429-source: params.artifact.source,
443+source: sanitizeGalleryText(params.artifact.source, params),
430444};
431445}
432446const hrefArtifactPath =
@@ -437,7 +451,7 @@ async function buildArtifactView(params: {
437451exists: true,
438452error: null,
439453href: artifactHref(params.hrefEvidencePath, hrefArtifactPath),
440-kind: params.artifact.kind,
454+kind: sanitizeGalleryText(params.artifact.kind, params),
441455 mediaKind,
442456path: displayPath,
443457preview: await readPreview(realFile, mediaKind)
@@ -453,7 +467,7 @@ async function buildArtifactView(params: {
453467repoRoot: params.repoRoot,
454468}),
455469),
456-source: params.artifact.source,
470+source: sanitizeGalleryText(params.artifact.source, params),
457471};
458472}
459473@@ -489,19 +503,26 @@ function readStringArray(values: Iterable<unknown>) {
489503return readOrderedStringArray(values).toSorted();
490504}
491505492-function readMatrixDimensionIds(value: unknown, fallback: readonly string[]): string[] {
493-if (!Array.isArray(value)) {
494-return readOrderedStringArray(fallback);
506+function readMatrixDimensionIds(params: {
507+extraRoots: readonly string[];
508+fallback: readonly string[];
509+repoRoot: string;
510+value: unknown;
511+}): string[] {
512+if (!Array.isArray(params.value)) {
513+return sanitizeGalleryStringArray(params.fallback, params);
495514}
496-const ids = readOrderedStringArray(
497-value.map((entry) => {
515+const ids = sanitizeGalleryStringArray(
516+params.value.map((entry) => {
498517if (typeof entry === "string") {
499518return entry;
500519}
501520return readString(readRecord(entry)?.id);
502521}),
522+params,
503523);
504-for (const fallbackId of fallback) {
524+for (const rawFallbackId of params.fallback) {
525+const fallbackId = sanitizeGalleryText(rawFallbackId, params);
505526if (!ids.includes(fallbackId)) {
506527ids.push(fallbackId);
507528}
@@ -549,35 +570,41 @@ function readMatrixCells(params: {
549570 : [];
550571const entriesByCell = buildUxMatrixEvidenceEntryIndex(params.summaryEntries);
551572return rawCells.flatMap((cell): QaEvidenceMatrixCellView[] => {
552-const surface = readString(cell.surface);
553-const stage = readString(cell.stage);
554-const status = readString(cell.status) ?? "proof-gap";
555-if (!surface || !stage) {
573+const rawSurface = readString(cell.surface);
574+const rawStage = readString(cell.stage);
575+const rawStatus = readString(cell.status) ?? "proof-gap";
576+if (!rawSurface || !rawStage) {
556577return [];
557578}
558579const entry =
559-status === "proof-gap" ? null : (entriesByCell.get(`${surface}:${stage}`) ?? null);
580+rawStatus === "proof-gap" ? null : (entriesByCell.get(`${rawSurface}:${rawStage}`) ?? null);
560581const artifacts = entry?.execution?.artifacts ?? [];
561582const runner = readRecord(cell.runner);
583+const sanitizeCellString = (value: string) =>
584+sanitizeGalleryText(value, {
585+extraRoots: params.extraRoots,
586+repoRoot: params.repoRoot,
587+});
562588const readRunnerString = (value: unknown) => {
563589const text = readString(value);
564-return text
565- ? sanitizeGalleryText(text, {
566-extraRoots: params.extraRoots,
567-repoRoot: params.repoRoot,
568-})
569- : null;
590+return text ? sanitizeCellString(text) : null;
570591};
571592return [
572593{
573-artifactKinds: readStringArray(artifacts.map((artifact) => artifact.kind)),
594+artifactKinds: readStringArray(
595+artifacts.map((artifact) => sanitizeCellString(artifact.kind)),
596+),
574597artifactPaths: artifacts.map((artifact) =>
575598displayGalleryPath(artifact.path, {
576599extraRoots: params.extraRoots,
577600repoRoot: params.repoRoot,
578601}),
579602),
580-coverageIds: readStringArray(Array.isArray(cell.coverageIds) ? cell.coverageIds : []),
603+coverageIds: readStringArray(
604+(Array.isArray(cell.coverageIds) ? cell.coverageIds : []).map((coverageId) =>
605+typeof coverageId === "string" ? sanitizeCellString(coverageId) : coverageId,
606+),
607+),
581608runner: runner
582609 ? {
583610availability: readRunnerString(runner.availability),
@@ -586,11 +613,11 @@ function readMatrixCells(params: {
586613workflow: readRunnerString(runner.workflow),
587614}
588615 : null,
589- stage,
590- status,
591- surface,
592-testId: entry?.test.id ?? null,
593-title: entry?.test.title ?? null,
616+stage: sanitizeCellString(rawStage),
617+status: sanitizeCellString(rawStatus),
618+surface: sanitizeCellString(rawSurface),
619+testId: entry?.test.id ? sanitizeCellString(entry.test.id) : null,
620+title: entry?.test.title ? sanitizeCellString(entry.test.title) : null,
594621},
595622];
596623});
@@ -670,6 +697,9 @@ async function buildProducerContext(params: {
670697const manifest = await readJsonIfExists(manifestPath, allowedRoots);
671698const matrix = await readJsonIfExists(matrixPath, allowedRoots);
672699const releaseLedger = await readJsonIfExists(releaseLedgerPath, allowedRoots);
700+const run = readRecord(manifest?.run);
701+const runId = readString(run?.runId);
702+const runStatus = readString(run?.status);
673703const producerFiles = Object.fromEntries(
674704await Promise.all(
675705UX_MATRIX_PRODUCER_FILES.map(async (file) => [
@@ -702,23 +732,27 @@ async function buildProducerContext(params: {
702732manifest && producerFiles.manifest
703733 ? {
704734 ...producerFiles.manifest,
705-runId: readString(readRecord(manifest.run)?.runId),
706-runStatus: readString(readRecord(manifest.run)?.status),
735+runId: runId ? sanitizeGalleryText(runId, params) : null,
736+runStatus: runStatus ? sanitizeGalleryText(runStatus, params) : null,
707737}
708738 : null,
709739matrix: matrix
710740 ? {
711741cells: matrixCells,
712742counts: readCountRecord(matrix.counts),
713743path: toRepoRelativePath(repoRoot, matrixPath),
714-stages: readMatrixDimensionIds(
715-matrix.stages,
716-matrixCells.map((cell) => cell.stage),
717-),
718-surfaces: readMatrixDimensionIds(
719-matrix.surfaces,
720-matrixCells.map((cell) => cell.surface),
721-),
744+stages: readMatrixDimensionIds({
745+extraRoots: params.extraRoots,
746+fallback: matrixCells.map((cell) => cell.stage),
747+ repoRoot,
748+value: matrix.stages,
749+}),
750+surfaces: readMatrixDimensionIds({
751+extraRoots: params.extraRoots,
752+fallback: matrixCells.map((cell) => cell.surface),
753+ repoRoot,
754+value: matrix.surfaces,
755+}),
722756}
723757 : null,
724758preflight: {
@@ -788,6 +822,11 @@ export async function buildQaEvidenceGalleryModel(params: {
788822const entries = await Promise.all(
789823summary.entries.map(async (entry): Promise<QaEvidenceGalleryEntryView> => {
790824counts[entry.result.status] += 1;
825+const sanitizeEntryText = (value: string) =>
826+sanitizeGalleryText(value, {
827+extraRoots: [requestedRepoRoot],
828+ repoRoot,
829+});
791830return {
792831artifacts: await Promise.all(
793832(entry.execution?.artifacts ?? []).map((artifact) =>
@@ -803,23 +842,23 @@ export async function buildQaEvidenceGalleryModel(params: {
803842),
804843),
805844),
806-coverage: entry.coverage,
845+coverage: entry.coverage.map((coverage) => ({
846+id: sanitizeEntryText(coverage.id),
847+role: sanitizeEntryText(coverage.role),
848+})),
807849failureReason: entry.result.failure?.reason
808- ? sanitizeGalleryText(entry.result.failure.reason, {
809-extraRoots: [requestedRepoRoot],
810- repoRoot,
811-})
850+ ? sanitizeEntryText(entry.result.failure.reason)
812851 : null,
813-id: entry.test.id,
814-kind: entry.test.kind,
852+id: sanitizeEntryText(entry.test.id),
853+kind: sanitizeEntryText(entry.test.kind),
815854sourcePath: entry.test.source?.path
816855 ? displayGalleryPath(entry.test.source.path, {
817856extraRoots: [requestedRepoRoot],
818857 repoRoot,
819858})
820859 : null,
821860status: entry.result.status,
822-title: entry.test.title,
861+title: sanitizeEntryText(entry.test.title),
823862};
824863}),
825864);
@@ -829,7 +868,9 @@ export async function buildQaEvidenceGalleryModel(params: {
829868evidenceMode: summary.evidenceMode,
830869evidencePath: hrefEvidencePath,
831870generatedAt: summary.generatedAt,
832-profile: summary.profile ?? null,
871+profile: summary.profile
872+ ? sanitizeGalleryText(summary.profile, { extraRoots: [requestedRepoRoot], repoRoot })
873+ : null,
833874producerContext: await buildProducerContext({
834875 evidencePath,
835876extraRoots: [requestedRepoRoot],
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。