diff --git a/docs/assets/cve.js b/docs/assets/cve.js
index dd749042e1..ed1b8d49a7 100644
--- a/docs/assets/cve.js
+++ b/docs/assets/cve.js
@@ -13,6 +13,7 @@
const detailSection = document.getElementById("cve-details");
const notFoundSection = document.getElementById("not-found");
+ const descriptionBlock = document.getElementById("cve-description-block");
function setLoading(message) {
titleEl.textContent = cveId || "CVE details";
@@ -27,14 +28,37 @@
return "No description available.";
}
+ function hasKevData(kev) {
+ if (!kev || typeof kev !== "object") return false;
+ return Boolean(
+ (kev.short_description && kev.short_description.trim()) ||
+ kev.date_added ||
+ kev.due_date ||
+ kev.required_action ||
+ kev.notes
+ );
+ }
+
function renderFacts(data) {
+ const pocCount = data.poc_count ?? (Array.isArray(data.poc_links) ? data.poc_links.length : Array.isArray(data.poc) ? data.poc.length : undefined);
const items = [];
- if (data.vendor) items.push({ label: "Vendor", value: data.vendor });
- if (data.product) items.push({ label: "Product", value: data.product });
- if (data.epss !== undefined && data.epss !== null) items.push({ label: "EPSS", value: data.epss.toFixed(3) });
- if (data.percentile !== undefined && data.percentile !== null) items.push({ label: "Percentile", value: `${Math.round(data.percentile * 100)}th` });
- if (data.poc_count !== undefined) items.push({ label: "PoCs", value: data.poc_count });
- if (data.kev) items.push({ label: "KEV status", value: data.kev.date_added ? `Added ${data.kev.date_added}` : "Listed" });
+ const vendorValue = data.vendor || "Unknown vendor";
+ const productValue = data.product || "Unknown product";
+ const epssValue = typeof data.epss === "number" ? data.epss.toFixed(3) : "n/a";
+ const percentileValue = typeof data.percentile === "number" ? `${Math.round(data.percentile * 100)}th` : "n/a";
+ const pocValue = pocCount ?? 0;
+
+ items.push({ label: "Vendor", value: vendorValue });
+ items.push({ label: "Product", value: productValue });
+ items.push({ label: "EPSS", value: epssValue });
+ items.push({ label: "Percentile", value: percentileValue });
+ items.push({ label: "PoCs", value: pocValue });
+ if (hasKevData(data.kev)) items.push({ label: "KEV status", value: data.kev.date_added ? `Added ${data.kev.date_added}` : "Listed" });
+
+ if (items.length === 0) {
+ factsEl.innerHTML = `
—No overview data yet.
`;
+ return;
+ }
factsEl.innerHTML = items
.map((item) => `${item.value}${item.label}
`)
@@ -56,13 +80,13 @@
const pills = [];
if (data.vendor) pills.push(`Vendor: ${data.vendor}`);
if (data.product) pills.push(`Product: ${data.product}`);
- if (data.kev) pills.push("On KEV list");
+ if (hasKevData(data.kev)) pills.push("On KEV list");
metaEl.innerHTML = pills.map((text) => `${text}`).join("");
}
function renderKev(kev) {
- if (!kev) {
+ if (!hasKevData(kev)) {
document.getElementById("kev-section").style.display = "none";
return;
}
@@ -109,7 +133,14 @@
titleEl.textContent = data.cve || cveId;
const desc = getDescriptionText(data);
summaryEl.textContent = desc;
- descEl.textContent = desc;
+ const hasDescContent = desc && desc !== "No description available.";
+ if (hasDescContent) {
+ descEl.textContent = desc;
+ descriptionBlock.style.display = "";
+ } else {
+ descEl.textContent = "";
+ descriptionBlock.style.display = "none";
+ }
renderFacts(data);
renderPocs(data.poc_links || data.poc || []);
renderKev(data.kev);
@@ -126,7 +157,14 @@
titleEl.textContent = fallback.cve;
const desc = getDescriptionText(fallback);
summaryEl.textContent = desc;
- descEl.textContent = desc;
+ const hasDescContent = desc && desc !== "No description available.";
+ if (hasDescContent) {
+ descEl.textContent = desc;
+ descriptionBlock.style.display = "";
+ } else {
+ descEl.textContent = "";
+ descriptionBlock.style.display = "none";
+ }
renderFacts(fallback);
renderPocs(fallback.poc_links || fallback.poc || []);
renderKev(null);
@@ -138,6 +176,7 @@
notFoundSection.style.display = "";
detailSection.style.display = "none";
metaEl.innerHTML = "";
+ descriptionBlock.style.display = "none";
titleEl.textContent = cveId;
summaryEl.textContent = "No data found for this CVE.";
}
diff --git a/docs/cve/index.html b/docs/cve/index.html
index 66f9792ba2..0da06dcfa0 100644
--- a/docs/cve/index.html
+++ b/docs/cve/index.html
@@ -31,9 +31,11 @@
Overview
- CVE detail
-
-
+
PoC Links
diff --git a/docs/logic.js b/docs/logic.js
index 1b204f0525..b8c50d7f49 100644
--- a/docs/logic.js
+++ b/docs/logic.js
@@ -54,6 +54,19 @@ function getCveLink(cveId) {
return `
${cveId}`;
}
+function prepareDataset(raw) {
+ if (!Array.isArray(raw)) return [];
+ const descKeyCleaned = (entry) => {
+ const base = entry.desc || '';
+ return replaceStrings.reduce((desc, str) => desc.replace(str, ''), base);
+ };
+ return raw.map(entry => {
+ const descCleaned = descKeyCleaned(entry);
+ const searchText = `${entry.cve || ''} ${descCleaned}`.toLowerCase();
+ return { ...entry, _searchText: searchText };
+ });
+}
+
const controls = {
oldColor: '',
displayResults(results, resultsTableHideable) {
@@ -70,8 +83,7 @@ const controls = {
const negmatch = words.filter(word => word[0] === '-').map(word => word.substring(1));
return dataset.filter(e => {
- const description = replaceStrings.reduce((desc, str) => desc.replace(str, ''), e.desc).toLowerCase();
- const combinedText = (e.cve + description).toLowerCase();
+ const combinedText = e._searchText || '';
const positiveMatch = posmatch.every(word => combinedText.includes(word));
const negativeMatch = negmatch.some(word => combinedText.includes(word));
@@ -95,17 +107,14 @@ const controls = {
noResults.style.display = 'none';
resultsTableHideable.classList.remove('hide');
- const fragment = document.createDocumentFragment();
- results.forEach(r => {
- const el = searchResultFormat
+ const html = results.map(r => {
+ const desc = r.desc || '';
+ return searchResultFormat
.replace('$cve', getCveLink(r.cve))
- .replace('$description', escapeHTML(r.desc))
- .replace('$poc', convertLinksToList(r.poc));
- const wrapper = document.createElement('table');
- wrapper.innerHTML = el;
- fragment.appendChild(wrapper.querySelector('tr'));
- });
- loc.appendChild(fragment);
+ .replace('$description', escapeHTML(desc))
+ .replace('$poc', convertLinksToList(r.poc || []));
+ }).join('');
+ loc.innerHTML = html;
}
},
setColor(loc, indicator) {
@@ -176,7 +185,7 @@ document.addEventListener('DOMContentLoaded', () => {
throw new Error(`Failed to load ${url} (${res.status})`);
}
const data = await res.json();
- window.dataset = Array.isArray(data) ? data : [];
+ window.dataset = prepareDataset(data);
currentSet = window.dataset;
controls.hideResults(results, resultsTableHideable);
noResults.style.display = 'none';