(options)
| 124 | } |
| 125 | |
| 126 | export const buildOptions = function (options) { |
| 127 | const built = Object.assign({}, defaultOptions, options); |
| 128 | |
| 129 | // Validate property names to prevent prototype pollution |
| 130 | const propertyNameOptions = [ |
| 131 | { value: built.attributeNamePrefix, name: 'attributeNamePrefix' }, |
| 132 | { value: built.attributesGroupName, name: 'attributesGroupName' }, |
| 133 | { value: built.textNodeName, name: 'textNodeName' }, |
| 134 | { value: built.cdataPropName, name: 'cdataPropName' }, |
| 135 | { value: built.commentPropName, name: 'commentPropName' } |
| 136 | ]; |
| 137 | |
| 138 | for (const { value, name } of propertyNameOptions) { |
| 139 | if (value) { |
| 140 | validatePropertyName(value, name); |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | if (built.onDangerousProperty === null) { |
| 145 | built.onDangerousProperty = defaultOnDangerousProperty; |
| 146 | } |
| 147 | |
| 148 | // Always normalize processEntities for backward compatibility and validation |
| 149 | built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities); |
| 150 | built.unpairedTagsSet = new Set(built.unpairedTags); |
| 151 | // Convert old-style stopNodes for backward compatibility |
| 152 | if (built.stopNodes && Array.isArray(built.stopNodes)) { |
| 153 | built.stopNodes = built.stopNodes.map(node => { |
| 154 | if (typeof node === 'string' && node.startsWith('*.')) { |
| 155 | // Old syntax: *.tagname meant "tagname anywhere" |
| 156 | // Convert to new syntax: ..tagname |
| 157 | return '..' + node.substring(2); |
| 158 | } |
| 159 | return node; |
| 160 | }); |
| 161 | } |
| 162 | //console.debug(built.processEntities) |
| 163 | return built; |
| 164 | }; |
no test coverage detected