diff --git a/server/api/registry/badge/[type]/[...pkg].get.ts b/server/api/registry/badge/[type]/[...pkg].get.ts index f9c0836807..1466efa828 100644 --- a/server/api/registry/badge/[type]/[...pkg].get.ts +++ b/server/api/registry/badge/[type]/[...pkg].get.ts @@ -13,7 +13,8 @@ const NPM_DOWNLOADS_API = 'https://api.npmjs.org/downloads/point' const OSV_QUERY_API = 'https://api.osv.dev/v1/query' const BUNDLEPHOBIA_API = 'https://bundlephobia.com/api/size' -const SafeStringSchema = v.pipe(v.string(), v.regex(/^[^<>"&]*$/, 'Invalid characters')) +// Allow semver range operators like >= and <= while still rejecting quotes and ampersands. +const SafeStringSchema = v.pipe(v.string(), v.regex(/^[^"&]*$/, 'Invalid characters')) const SafeColorSchema = v.pipe( v.string(), v.transform(value => (value.startsWith('#') ? value : `#${value}`)), diff --git a/test/e2e/badge.spec.ts b/test/e2e/badge.spec.ts index 522e6bec61..bc07b9a8e2 100644 --- a/test/e2e/badge.spec.ts +++ b/test/e2e/badge.spec.ts @@ -188,6 +188,17 @@ test.describe('badge API', () => { expect(body).toContain(customValue) }) + test('custom value parameter supports semver range operators', async ({ page, baseURL }) => { + const customValue = '>=22.13.0' + const url = toLocalUrl( + baseURL, + `/api/registry/badge/engines/nuxt?value=${encodeURIComponent(customValue)}`, + ) + const { body } = await fetchBadge(page, url) + + expect(body).toContain(customValue) + }) + test('style=default keeps current badge renderer', async ({ page, baseURL }) => { const url = toLocalUrl(baseURL, '/api/registry/badge/version/nuxt?style=default') const { body } = await fetchBadge(page, url)