Skip to content

Commit

Permalink
Merge pull request #154 from npr/fix-109
Browse files Browse the repository at this point in the history
ampersand encoding fixes
  • Loading branch information
universalhandle committed Feb 24, 2023
2 parents 7acfbd4 + 4e494e6 commit 7af28ab
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/constants.ts
@@ -0,0 +1 @@
export const nonEntityAmpersandRegex = /&(?![A-Za-z]+;|#\d+;)/g;
5 changes: 3 additions & 2 deletions src/writers/BaseWriter.ts
Expand Up @@ -7,6 +7,7 @@ import { LocalNameSet } from "@oozcitak/dom/lib/serializer/LocalNameSet"
import { NamespacePrefixMap } from "@oozcitak/dom/lib/serializer/NamespacePrefixMap"
import { namespace as infraNamespace } from "@oozcitak/infra"
import { xml_isName, xml_isLegalChar, xml_isPubidChar } from "@oozcitak/dom/lib/algorithm"
import { nonEntityAmpersandRegex } from "../constants"

/**
* Pre-serializes XML nodes.
Expand Down Expand Up @@ -928,7 +929,7 @@ export abstract class BaseWriter<T extends BaseWriterOptions, U extends XMLSeria
* 5. Replace any occurrences of ">" in markup by "&gt;".
* 6. Return the value of markup.
*/
const markup = node.data.replace(/(?!&([^&; ]*);)&/g, '&amp;')
const markup = node.data.replace(nonEntityAmpersandRegex, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')

Expand Down Expand Up @@ -1597,7 +1598,7 @@ export abstract class BaseWriter<T extends BaseWriterOptions, U extends XMLSeria
* grammar requirement in the XML specification's AttValue production by
* also replacing ">" characters.
*/
return value.replace(/(?!&([^&; ]*);)&/g, '&amp;')
return value.replace(nonEntityAmpersandRegex, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
Expand Down
6 changes: 6 additions & 0 deletions test/writers/XMLWriter.test.ts
Expand Up @@ -389,6 +389,10 @@ describe('XMLWriter', () => {
test('escape text data', () => {
const ele = $$.create().ele('root').txt('&<>')
expect(ele.toString()).toBe('<root>&amp;&lt;&gt;</root>')
const ele1 = $$.create().ele('root').txt('&<>;')
expect(ele1.toString()).toBe('<root>&amp;&lt;&gt;;</root>')
const ele2 = $$.create().ele('root').txt('& amp;')
expect(ele2.toString()).toBe('<root>&amp; amp;</root>')
})

test('escape attribute value', () => {
Expand All @@ -397,6 +401,8 @@ describe('XMLWriter', () => {
const ele2 = $$.create().ele('root').att('att', 'val')
Object.defineProperty((ele2.node as Element).attributes.item(0), "value", { value: null })
expect(ele2.toString()).toBe('<root att=""/>')
const ele3 = $$.create().ele('root').att('att', '"&<>;')
expect(ele3.toString()).toBe('<root att="&quot;&amp;&lt;&gt;;"/>')
})

test('duplicate attribute name not well-formed', () => {
Expand Down

0 comments on commit 7af28ab

Please sign in to comment.