/** * Structured HTML render of a disclosed VH/VulnForge report * (parsed report object preferred; raw yaml fallback). */ import { useMemo } from "react"; import { load as parseYaml } from "js-yaml"; type Anchor = { file_path?: string; line?: number | string; function?: string }; type FlowStep = { step?: number | string; location?: string; description?: string }; type ReportDoc = { metadata?: { title?: string; vuln_type?: string; cwe?: string; cvss_vector?: string; cvss_score?: number | string; ev_priority?: string; ev_score?: number | string; ev_rationale?: string; poc_status?: string; exp_status?: string; affected_versions?: string; anchors?: Anchor[]; }; description?: { background?: string; detailed_description?: string; summary?: string; attack_payload_description?: string; attack_description?: string; impact?: string; combined_impact?: string; remediation?: string; fix_suggestion?: string; }; code?: { dataflow?: FlowStep[]; data_flow?: FlowStep[]; fix_patch?: string; patch?: string; }; references?: unknown; }; function asRecord(v: unknown): Record { if (v && typeof v === "object" && !Array.isArray(v)) return v as Record; return {}; } function str(v: unknown): string { if (v == null) return ""; if (typeof v === "string") return v.trim(); if (typeof v === "number" || typeof v === "boolean") return String(v); return ""; } function Section({ label, children }: { label: string; children: React.ReactNode }) { if (!children) return null; return (

{label}

{children}
); } function Prose({ text }: { text: string }) { if (!text) return null; return (

{text}

); } function normalizeDoc(input: unknown): ReportDoc | null { if (!input || typeof input !== "object") return null; const r = input as Record; return { metadata: asRecord(r.metadata) as ReportDoc["metadata"], description: asRecord(r.description) as ReportDoc["description"], code: asRecord(r.code) as ReportDoc["code"], references: r.references, }; } export type StructuredReport = { metadata: Record; description: Record; code: Record; references: unknown; }; /** Prefer structured `report`; raw yaml only as fallback. */ export function ReportBody({ report, yaml, }: { report?: StructuredReport | null; yaml?: string | null; }) { const doc = useMemo(() => { if (report) return normalizeDoc(report); if (yaml?.trim()) { try { return normalizeDoc(parseYaml(yaml)); } catch { return null; } } return null; }, [report, yaml]); if (!doc) { if (yaml?.trim()) { return (
          {yaml}
        
); } return (

Structured report is not available for this disclosure.

); } const meta = doc.metadata ?? {}; const fullTitle = typeof meta === "object" && "title" in meta ? (meta as { title?: string }).title : undefined; const desc = doc.description ?? {}; const anchors = (meta.anchors ?? []).filter((a) => a && (a.file_path || a.function)); const dataflow = (doc.code?.dataflow ?? doc.code?.data_flow ?? []).filter(Boolean); const refList = Array.isArray(doc.references) ? doc.references.filter((r) => typeof r === "string" && (r as string).trim()) : []; return (
{fullTitle && (

{fullTitle}

)}
{meta.vuln_type && (
Type
{meta.vuln_type}
)} {meta.cvss_score != null && (
CVSS
{meta.cvss_score}
)} {meta.ev_priority && (
EV priority
{meta.ev_priority}
)} {meta.poc_status && (
PoC status
{meta.poc_status}
)} {meta.exp_status && (
EXP status
{meta.exp_status}
)} {meta.affected_versions && (
Affected
{meta.affected_versions}
)} {meta.cvss_vector && (
Vector
{meta.cvss_vector}
)}
{str(meta.ev_rationale) && (
)} {anchors.length > 0 && (
    {anchors.map((a, i) => (
  • {a.file_path} {a.line != null && `:${a.line}`} {a.function && {a.function}}
  • ))}
)} {str(desc.background) && (
)} {(str(desc.detailed_description) || str(desc.summary)) && (
)} {(str(desc.attack_payload_description) || str(desc.attack_description)) && (
{str(desc.attack_description) && } {str(desc.attack_payload_description) && ( )}
)} {(str(desc.impact) || str(desc.combined_impact)) && (
)} {(str(desc.remediation) || str(desc.fix_suggestion)) && (
)} {dataflow.length > 0 && (
    {dataflow.map((st, i) => (
  1. {st.step ?? i + 1}
    {st.location && (

    {st.location}

    )} {st.description && (

    {st.description}

    )}
  2. ))}
)} {(str(doc.code?.fix_patch) || str(doc.code?.patch)) && (
            {str(doc.code?.fix_patch) || str(doc.code?.patch)}
          
)} {refList.length > 0 && (
    {(refList as string[]).map((r, i) => /^https?:\/\//.test(r) ? (
  • {r}
  • ) : (
  • {r}
  • ), )}
)}
); }