Repository navigation
JS-2774 S5332: Add the identifier URL inventory and matcher #8279
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| /* | ||
| * SonarQube JavaScript Plugin | ||
| * Copyright (C) SonarSource Sàrl | ||
| * mailto:info AT sonarsource DOT com | ||
| * | ||
| * You can redistribute and/or modify this program under the terms of | ||
| * the Sonar Source-Available License Version 1, as published by SonarSource Sàrl. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| * See the Sonar Source-Available License for more details. | ||
| * | ||
| * You should have received a copy of the Sonar Source-Available License | ||
| * along with this program; if not, see https://sonarsource.com/license/ssal/ | ||
| */ | ||
| import { strict as assert } from 'node:assert'; | ||
| import { describe, it } from 'node:test'; | ||
| import identifierUrls from '@sonarsource/analyzer-commons-configurations/identifier-urls.json' with { type: 'json' }; | ||
| import { isKnownIdentifierUrl } from './identifier-urls.js'; | ||
|
|
||
| describe('S5332 identifier URL matcher', () => { | ||
| it('uses an empty identifier inventory', () => { | ||
| assert.deepEqual(identifierUrls, {}); | ||
| }); | ||
|
|
||
| it('does not match URLs when the inventory is empty', () => { | ||
| assert.equal(isKnownIdentifierUrl('http://identifier.invalid/schema'), false); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| /* | ||
| * SonarQube JavaScript Plugin | ||
| * Copyright (C) SonarSource Sàrl | ||
| * mailto:info AT sonarsource DOT com | ||
| * | ||
| * You can redistribute and/or modify this program under the terms of | ||
| * the Sonar Source-Available License Version 1, as published by SonarSource Sàrl. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| * See the Sonar Source-Available License for more details. | ||
| * | ||
| * You should have received a copy of the Sonar Source-Available License | ||
| * along with this program; if not, see https://sonarsource.com/license/ssal/ | ||
| */ | ||
|
|
||
| import identifierUrls from '@sonarsource/analyzer-commons-configurations/identifier-urls.json' with { type: 'json' }; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🚨 Bug: Imported identifier-urls.json is not in any published Commons packageThis commit swaps the inline map for The fix is to publish a Commons release that includes Was this helpful? React with 👍 / 👎 |
||
|
|
||
| // The inventory is maintained in Analyzer Commons; keep the matching semantics aligned. | ||
| // A match identifies a possible identifier; the caller must also check its use in the AST. | ||
| const IDENTIFIER_URLS = new Map<string, RegExp>( | ||
| Object.entries<string>(identifierUrls).map(([domain, pattern]) => [domain, new RegExp(pattern)]), | ||
| ); | ||
|
Comment on lines
+22
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| /** | ||
| * The Commons npm package shares the inventory as JSON. Its Java matcher, | ||
| * CleartextProtocolFilter.isKnownIdentifier(), is not exposed through that package. | ||
| * SonarJS therefore performs URL parsing and regex matching here in Node.js using the shared data. | ||
| */ | ||
| export function isKnownIdentifierUrl(value: string): boolean { | ||
| // Do not use URL.hostname (drops ports), URL.host (normalizes :80), or a lowercased | ||
| // URL (changes identifier spelling). Only the authority is case-insensitive. | ||
| const match = /^http:\/\/([^\s/?#\\]+)([/?#][^\s\\]*)?$/i.exec(value); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Cross-PR: Whitespace-padded identifier URLs match in Java but not SonarJS · SonarSource/sonar-analyzer-commons #590Breaks when sonar-analyzer-commons#590 merges and a later Commons release adds inventory entries, and SonarJS then checks an identifier URL literal that has leading or trailing whitespace. How
Fix
Compared Strip surrounding whitespace before matching, like Java Was this helpful? React with 👍 / 👎 |
||
| if (!match) { | ||
| return false; | ||
| } | ||
| const remainder = match[2] ?? ''; | ||
| const suffix = remainder.startsWith('/') ? remainder : `/${remainder}`; | ||
| return IDENTIFIER_URLS.get(match[1].toLowerCase())?.test(suffix) === true; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Quality: Matcher parsing logic is no longer tested; empty-map test is vacuous
This commit removes the roughly 100 lines of matcher tests. The two tests left only check that the shipped inventory is
{}and that one URL returnsfalse. With an emptyIDENTIFIER_URLSmap,isKnownIdentifierUrlreturnsfalsefor any input, so the second test passes no matter what the authority regex, port handling, case folding, orsuffixlogic inidentifier-urls.ts:34-40does. None of that parsing code is exercised. ThedeepEqual(identifierUrls, {})test also fails as soon as a Commons bump fills in the inventory, and it locks in the current state where the S5332 identifier exception does nothing. A fix is to have the matcher take the inventory as input, e.g.createIdentifierUrlMatcher(inventory), and restore the parsing tests against fixture data, without asserting on the contents of the published JSON.Build the matcher from an inventory you pass in, so tests can supply fixture data:
Was this helpful? React with 👍 / 👎