Skip to content

Commit 2cbaceb

Browse files
Copilotmgifford
andauthored
Add defensive input validation and non-string input test for generateViolationId
Agent-Logs-Url: https://github.com/mgifford/daily-dap/sessions/9f0ef740-63b7-4d90-a93d-228cb1518e0b Co-authored-by: mgifford <116832+mgifford@users.noreply.github.com>
1 parent 2a4523d commit 2cbaceb

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

src/publish/render-pages.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ function formatCompact(n) {
3636
* @returns {string} A short stable identifier, e.g. "DAP-a1b2c3d4"
3737
*/
3838
export function generateViolationId(pageUrl, ruleId, selector = '') {
39-
const normalizedUrl = pageUrl
39+
const safeUrl = typeof pageUrl === 'string' ? pageUrl : '';
40+
const safeRuleId = typeof ruleId === 'string' ? ruleId : '';
41+
const safeSelector = typeof selector === 'string' ? selector : '';
42+
const normalizedUrl = safeUrl
4043
.replace(/^https?:\/\//i, '')
4144
.replace(/\/+$/, '')
4245
.toLowerCase();
43-
const seed = `${normalizedUrl}|${ruleId}|${selector}`;
46+
const seed = `${normalizedUrl}|${safeRuleId}|${safeSelector}`;
4447
const hash = createHash('sha256').update(seed).digest('hex').slice(0, 8);
4548
return `DAP-${hash}`;
4649
}
@@ -1835,7 +1838,9 @@ function renderAxeFindingItems(items = [], pageUrl = '', ruleId = '') {
18351838
return items
18361839
.map(
18371840
(item, index) => {
1838-
const elementId = pageUrl && ruleId ? generateViolationId(pageUrl, ruleId, item.selector ?? '') : '';
1841+
const elementId = typeof pageUrl === 'string' && pageUrl.length > 0 && typeof ruleId === 'string' && ruleId.length > 0
1842+
? generateViolationId(pageUrl, ruleId, item.selector ?? '')
1843+
: '';
18391844
return `
18401845
<div class="axe-item">
18411846
<p><strong>Element ${index + 1}</strong>${elementId ? ` <code class="violation-id" title="Stable identifier for this accessibility violation">${escapeHtml(elementId)}</code>` : ''}</p>

tests/unit/render-pages.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,12 @@ test('generateViolationId produces finding-level ID when selector is empty', ()
777777
assert.match(id, /^DAP-[0-9a-f]{8}$/, 'Should be DAP- followed by 8 hex characters');
778778
});
779779

780+
test('generateViolationId handles non-string inputs gracefully', () => {
781+
const id = generateViolationId(null, undefined, 42);
782+
assert.ok(id.startsWith('DAP-'), 'Should still return a DAP-prefixed ID with non-string inputs');
783+
assert.match(id, /^DAP-[0-9a-f]{8}$/, 'Should be DAP- followed by 8 hex characters');
784+
});
785+
780786
test('buildFindingCopyText includes page URL and finding details', () => {
781787
const pageUrl = 'https://informeddelivery.usps.com';
782788
const finding = {

0 commit comments

Comments
 (0)