const renderer = require('syzoj-renderer'); const XSS = require('xss'); const xssWhiteList = Object.assign({}, require('xss/lib/default').whiteList); delete xssWhiteList.audio; delete xssWhiteList.video; for (const tag in xssWhiteList) { xssWhiteList[tag] = xssWhiteList[tag].concat(['style', 'class']); } const xss = new XSS.FilterXSS({ whiteList: xssWhiteList, stripIgnoreTag: true, onTagAttr: (tag, name, value, isWhiteAttr) => { if (tag.toLowerCase() === 'img' && name.toLowerCase() === 'src' && value.startsWith('data:image/')) { return name + '="' + XSS.escapeAttrValue(value) + '"'; } } }); const Redis = require('redis'); const util = require('util'); const redis = Redis.createClient(process.argv[2]); const redisCache = { get: util.promisify(redis.get).bind(redis), set: util.promisify(redis.set).bind(redis) }; async function highlight(code, lang) { return await renderer.highlight(code, lang, redisCache, { wrapper: null }); } async function markdown(markdownCode) { function filter(html) { html = xss.process(html); if (html) { html = `
`; } return html; }; return await renderer.markdown(markdownCode, redisCache, filter); } process.on('message', async msg => { if (msg.type === 'markdown') { process.send({ id: msg.id, result: await markdown(msg.source) }); } else if (msg.type === 'highlight') { process.send({ id: msg.id, result: await highlight(msg.source.code, msg.source.lang) }); } }); process.on('disconnect', () => process.exit());