Files
hermes-agent/apps/desktop/scripts/cli-launchers.test.mjs
ethernet fa9e899d4e desktop: escape the attribute values interpolated into the MSIX fragments
before-build.mjs builds the msix-extensions.xml fragment and the hidden
CLI <Application> entries from string templates, interpolating the
display name and the payload-declared launcher stems raw. A value with
`&`, `<` or `"` would corrupt the manifest makeappx reads (an opaque
0x80080204 at best, a differently named alias at worst). Every
interpolated attribute now goes through xmlAttribute().
2026-09-21 18:51:46 -04:00

24 lines
1.3 KiB
JavaScript

import assert from 'node:assert/strict'
import { test } from 'vitest'
import { appExecutionAliasApplications, appExecutionAliasExtensions, xmlAttribute } from './before-build.mjs'
test('one MSIX extension consumes the launchers declared by the payload', () => {
const names = ['custom-cli', 'another-cli']
const xml = appExecutionAliasExtensions(names)
assert.equal((xml.match(/<uap5:Extension\b/g) ?? []).length, 1)
for (const name of names) assert.ok(xml.includes(`Alias="${name}.exe"`))
assert.ok(xml.includes('custom-cli.exe'))
assert.ok(!xml.includes('windows.service'))
assert.ok(!xml.includes('desktop6:Service'))
assert.equal(appExecutionAliasExtensions([]), '')
})
test('manifest fragments escape every interpolated attribute value', () => {
const xml = appExecutionAliasApplications(['odd"&<name'], { appNamePascal: 'Hermes', displayName: 'Hermes & "Friends" <beta>' })
const values = [...xml.matchAll(/="([^"]*)"/g)].map((m) => m[1].replace(/&#\d+;/g, ''))
assert.ok(values.length > 0 && values.every((v) => !/[&<>"']/.test(v)), xml)
assert.ok(xml.includes('DisplayName="Hermes &#38; &#34;Friends&#34; &#60;beta&#62;"'))
assert.ok(xml.includes('Alias="odd&#34;&#38;&#60;name.exe"'))
assert.equal(xmlAttribute('plain-name'), 'plain-name')
})