Skip to content

Commit 4c94bd6

Browse files
mbani01skwowet
authored andcommitted
feat: enable nuget in osv worker [CM-1276] (#4270)
Signed-off-by: Mouad BANI <mouad-mb@outlook.com> Signed-off-by: Yeganathan S <63534555+skwowet@users.noreply.github.com>
1 parent 0d2f212 commit 4c94bd6

4 files changed

Lines changed: 33 additions & 3 deletions

File tree

backend/.env.dist.local

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ OSSPCKGS_GCP_CREDENTIALS_B64=e30=
195195
# maven/all.zip 404s). The allowlist check and DB storage normalize to lowercase
196196
# internally per ADR-0001 §OSV "Ecosystem normalization", so downstream stays lowercase.
197197
OSV_BULK_BASE_URL=https://osv-vulnerabilities.storage.googleapis.com
198-
OSV_ECOSYSTEMS=npm,Maven,cargo
198+
OSV_ECOSYSTEMS=npm,Maven,cargo,NuGet
199199
OSV_TMP_DIR=/tmp/osv
200200
OSV_BATCH_SIZE=500
201201
OSV_DERIVE_BATCH_SIZE=1000

services/apps/packages_worker/src/osv/__tests__/versionCompare.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,34 @@ describe('compareVersion — maven (ComparableVersion-style)', () => {
8383
})
8484
})
8585

86+
describe('compareVersion — nuget (semver)', () => {
87+
it.each([
88+
['1.0.0', '2.0.0', -1],
89+
['2.0.0', '1.0.0', 1],
90+
['1.0.0', '1.0.0', 0],
91+
['1.10.0', '1.9.0', 1], // numeric, not lex
92+
['1.0.0-alpha', '1.0.0', -1], // prerelease < release
93+
['1.0.0-beta', '1.0.0-rc', -1],
94+
// Real-world CVE boundary: Newtonsoft.Json < 13.0.1 deserialization vuln
95+
['13.0.0', '13.0.1', -1],
96+
['13.0.1', '13.0.1', 0],
97+
['13.0.2', '13.0.1', 1],
98+
])('compareVersion("nuget", %s, %s) sign = %s', (a, b, expected) => {
99+
expect(sign(compareVersion('nuget', a, b))).toBe(expected)
100+
})
101+
102+
it('returns null for unparseable nuget versions', () => {
103+
expect(compareVersion('nuget', 'not-a-version', '1.0.0')).toBeNull()
104+
})
105+
106+
it('rejects titlecase "NuGet" — production storage is always lowercase', () => {
107+
// OSV records arrive with ecosystem="NuGet"; parseOsvRecord lowercases to
108+
// "nuget" before writing to packages-db. The comparator is keyed on the
109+
// same lowercase form. A titlecase call means the caller skipped normalization.
110+
expect(compareVersion('NuGet', '1.0.0', '2.0.0')).toBeNull()
111+
})
112+
})
113+
86114
describe('compareVersion — unsupported ecosystems', () => {
87115
it('returns null for ecosystems we have no comparator for', () => {
88116
expect(compareVersion('PyPI', '1.0.0', '2.0.0')).toBeNull()

services/apps/packages_worker/src/osv/schedule.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const SCHEDULE_ID = 'osv-advisories-sync'
1111
// validate the env input against this list and refuse to register the
1212
// schedule on a mismatch — better a loud startup error than a silent miss.
1313
// Add new entries here when v1 expands beyond npm + Maven.
14-
const VALID_ECOSYSTEMS = ['npm', 'Maven', 'cargo'] as const
14+
const VALID_ECOSYSTEMS = ['npm', 'Maven', 'cargo', 'NuGet'] as const
1515

1616
function getEcosystems(): string[] {
1717
const raw = process.env.OSV_ECOSYSTEMS

services/apps/packages_worker/src/osv/versionCompare.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,13 @@ function compareMaven(a: string, b: string): number | null {
126126
return 0
127127
}
128128

129+
const SEMVER_ECOSYSTEMS = new Set(['npm', 'cargo', 'nuget'])
130+
129131
// Ecosystem names are stored lowercase in packages-db per ADR-0001 §OSV
130132
// "Ecosystem normalization" — 'npm', 'maven', 'cargo'. Callers (deriveCriticalFlag)
131133
// pull the value straight from the DB so the literals here must match.
132134
export function compareVersion(ecosystem: string, a: string, b: string): number | null {
133-
if (ecosystem === 'npm' || ecosystem === 'cargo') return compareSemver(a, b)
135+
if (SEMVER_ECOSYSTEMS.has(ecosystem)) return compareSemver(a, b)
134136
if (ecosystem === 'maven') return compareMaven(a, b)
135137
return null
136138
}

0 commit comments

Comments
 (0)