mirror of
https://github.com/0xMarcio/cve.git
synced 2026-10-27 16:51:03 +00:00
Rank on how well the query matches, not just whether it does
Unquoted words were scored independently, so "active directory" matched a description holding "active session" and "working directory" as strongly as a real AD advisory, and the newest-first tie-break then put the wrong one on top. Reward the words appearing together. Plain substring matching also meant "rce" hit "open source" and "sudo" hit "pseudo"; require a term to start a word, while still allowing it to match into one so "word" finds "wordpress". Weight matches near the start of a description, in coarse buckets so a few characters never outweigh recency: "log4j rce" now leads with Log4j2 rather than GeoTools.
This commit is contained in:
1 parent
9d49abebff
commit
56a945f9bb
1 file changed
+44
-5
+44
-5
@@ -108,6 +108,29 @@ function pocSpace(entry) {
|
||||
return entry._pocSpace;
|
||||
}
|
||||
|
||||
// Plain substring matching made "rce" hit "open source" and "sudo" hit
|
||||
// "pseudo". Require the term to start a word; matching into the end of one is
|
||||
// still allowed so that "word" finds "wordpress".
|
||||
function wordStart(text, term) {
|
||||
let at = text.indexOf(term);
|
||||
while (at > 0) {
|
||||
const code = text.charCodeAt(at - 1);
|
||||
if (!((code > 96 && code < 123) || (code > 47 && code < 58))) return at;
|
||||
at = text.indexOf(term, at + 1);
|
||||
}
|
||||
return at;
|
||||
}
|
||||
|
||||
// A term in the opening of an advisory is what it is about; one buried deep in
|
||||
// the prose is usually incidental. Coarse buckets so that a few characters of
|
||||
// difference never outweighs the newest-first tie-break.
|
||||
function leadBonus(index) {
|
||||
if (index < 0) return 0;
|
||||
if (index < 80) return 80;
|
||||
if (index < 300) return 40;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function descSpace(entry) {
|
||||
if (entry._descSpace === undefined) {
|
||||
entry._descSpace = normalizeToSpaces(entry._descText);
|
||||
@@ -149,15 +172,17 @@ const controls = {
|
||||
if (matcher.isPhrase) {
|
||||
const phrase = matcher.phrase;
|
||||
if (!phrase) return 0;
|
||||
if (descSpace(entry).includes(phrase)) return 200;
|
||||
if (pocSpace(entry).includes(phrase)) return 80;
|
||||
const at = wordStart(descSpace(entry), phrase);
|
||||
if (at >= 0) return 200 + leadBonus(at);
|
||||
if (wordStart(pocSpace(entry), phrase) >= 0) return 80;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const raw = matcher.raw;
|
||||
if (entry._cveText.includes(raw)) return 600;
|
||||
if (entry._descText.includes(raw)) return 240;
|
||||
if (pocText(entry).includes(raw)) return 80;
|
||||
const at = wordStart(entry._descText, raw);
|
||||
if (at >= 0) return 240 + leadBonus(at);
|
||||
if (wordStart(pocText(entry), raw) >= 0) return 80;
|
||||
if (matcher.loose) {
|
||||
if (matcher.loose.test(entry._descText)) return 160;
|
||||
if (matcher.loose.test(pocText(entry))) return 60;
|
||||
@@ -167,7 +192,12 @@ const controls = {
|
||||
doSearch(match, dataset) {
|
||||
const terms = match.match(/-?"[^"]+"|-?\S+/g) || [];
|
||||
const cleaned = terms.map(term => term.replace(/^(-?)"/, '$1').replace(/"$/, ''));
|
||||
const posmatch = cleaned.filter(term => term && term[0] !== '-').map(buildMatcher).filter(Boolean);
|
||||
const positive = cleaned.filter(term => term && term[0] !== '-');
|
||||
const posmatch = positive.map(buildMatcher).filter(Boolean);
|
||||
// Unquoted words are matched independently, so "active directory" also
|
||||
// hits a description holding "active session" and "working directory".
|
||||
// Reward the words appearing together to keep those below real matches.
|
||||
const adjacent = positive.length > 1 ? positive.join(' ').toLowerCase() : '';
|
||||
const negmatch = cleaned
|
||||
.filter(term => term && term[0] === '-')
|
||||
.map(term => term.substring(1))
|
||||
@@ -195,6 +225,15 @@ const controls = {
|
||||
const hasNegative = negmatch.some(matcher => this.scoreEntry(entry, matcher) > 0);
|
||||
if (hasNegative) continue;
|
||||
|
||||
if (adjacent) {
|
||||
const at = wordStart(entry._descText, adjacent);
|
||||
if (at >= 0) {
|
||||
score += 300 + leadBonus(at);
|
||||
} else if (wordStart(pocText(entry), adjacent) >= 0) {
|
||||
score += 100;
|
||||
}
|
||||
}
|
||||
|
||||
entry._score = score;
|
||||
results.push(entry);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user