pull/2754/merge
Bharat Rajagopalan 2 weeks ago committed by GitHub
commit b920c4658f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -32,6 +32,68 @@ module.exports = {
allowedAttrs.push('allow')
}
//Changes to keep interactive plantuml object tag
//only allow specific attributes for plantuml object node
if (typeof pumlImageFormat !== 'undefined' &&
pumlImageFormat &&
pumlImageFormat == 'svg') {
allowedTags.push('object')
allowedAttrs.push('data')
allowedAttrs.push('type')
allowedAttrs.push('style')
allowedAttrs.push('class')
allowedAttrs.push('alt')
}
DOMPurify.addHook('uponSanitizeElement', (node, data) => {
// keep object node only if it is
// authorised plantuml using the configured plantuml server
// force attribute values to configured params
// insert the plantuml inside the object as text for search
let isPumlNode=false
if (data.tagName === 'object' &&
typeof pumlServer !== 'undefined' && pumlServer &&
typeof pumlObjectStyle !== 'undefined' && pumlObjectStyle &&
typeof pumlObjectType !== 'undefined' && pumlObjectType &&
typeof pumlObjectClass !== 'undefined' && pumlObjectClass
) {
//console.log ("Found object node - validating")
//remove node if it doesn't conform to plantuml structure
if (!( 'data' in node.attributes
&& 'class' in node.attributes
&& 'style' in node.attributes
&& 'type' in node.attributes
&& 'alt' in node.attributes)
) {
//console.log ("Attribute mismatch - removing object node")
return node.parentNode.removeChild(node)
}
dataAttribute = node.getAttribute ('data')
//only allow configured plantuml server and image format in url
if (dataAttribute
&& dataAttribute.startsWith(`${pumlServer}/${pumlImageFormat}`)
) {
//console.log ("Plantuml node found - setting atribute values")
isPumlNode=true
node.setAttribute ('type', pumlObjectType)
node.setAttribute ('style', pumlObjectStyle)
node.setAttribute ('class', pumlObjectClass)
node.setAttribute ('alt', '')
}
//if not a plantuml node, then sanitise it
if (!isPumlNode) {
console.log ("Removing unknown object node")
return node.parentNode.removeChild(node)
}
}
})
//End changes to keep interactive plantuml object tag
input = DOMPurify.sanitize(input, {
ADD_ATTR: allowedAttrs,
ADD_TAGS: allowedTags

@ -114,14 +114,78 @@ module.exports = {
const zippedCode = encode64(zlib.deflateRawSync('@startuml\n' + contents + '\n@enduml').toString('binary'))
token = state.push('uml_diagram', 'img', 0)
// alt is constructed from children. No point in populating it here.
token.attrs = [ [ 'src', `${server}/${imageFormat}/${zippedCode}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
//Interactive plantuml changes start here
//Global variables that will be used in html-security
pumlImageFormat = imageFormat
pumlServer = server
pumlObjectType = 'image/svg+xml'
pumlObjectStyle = 'max-width:100%;height:auto'
pumlObjectClass = 'uml-diagram prefetch-candidate'
if (imageFormat === 'png') {
//non-interactive and not searchable - use the img tag
token = state.push('uml_diagram', 'img', 0)
// alt is constructed from children. No point in populating it here.
token.attrs = [ [ 'src' , `${server}/${imageFormat}/${zippedCode}` ],
[ 'alt' , '' ],
['class', pumlObjectClass ]
]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
}
else if (imageFormat === 'svg') {
// render svg interactively with object tag
/* <object data=<plantumlserver>/<format>/plantuml
alt='' class='uml-diagram prefetch-candidate'
style='max-width:100%;height:auto' type='image/svg+xml' > */
token = state.push('uml_diagram_obj', 'object', 0)
token.attrs = [ [ 'data' , `${server}/${imageFormat}/${zippedCode}`],
[ 'alt' , '' ],
[ 'class', pumlObjectClass ],
[ 'style', pumlObjectStyle ],
[ 'type', pumlObjectType ]
]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
//backup img node for object render failure
//void element - doesn't need to be closed in html
/* <img src=data=<plantumlserver>/<format>/plantuml alt=''
class='uml-diagram prefetch-candidate'
type='image/svg+xml'> */
token = state.push('uml_diagram_img', 'img', 0)
// alt is constructed from children. No point in populating it here.
token.attrs = [ [ 'src' , `${server}/${imageFormat}/${zippedCode}` ],
[ 'alt' , '' ],
['class', pumlObjectClass]
]
token.block = true
token.children = altToken
token.info = params
token.map = [ startLine, nextLine ]
token.markup = markup
//close object tag - </object>
token = state.push('uml_diagram_close', 'object', -1)
}
//Create hidden text inside html for wikijs search index
// text won't be visible or occupy any space but will be searchable
//i.e. <p style='display:none'>@startuml...@enduml</p>
token = state.push ('hidden', 'p', 0)
token.attrs = [ [ 'style', 'display:none'] ]
token = state.push ('text', '', 0)
token.content = contents
token = state.push('hidden_close', 'p', -1)
//Interactive plantuml changes end here
state.line = nextLine + (autoClosed ? 1 : 0)

Loading…
Cancel
Save