Use FEP-c16b: Formatting MFM functions #410

Open
ilja wants to merge 11 commits from ilja/akkoma-fe:use_fep-c16b_formatting_mfm_functions into develop
2 changed files with 35 additions and 4 deletions
Showing only changes of commit 6666a273a4 - Show all commits

View file

@ -194,14 +194,16 @@ export default {
// Turn data-mfm- attributes into a string for the `style` attribute
// If they have a value different than `true`, they need to be added to `style`
// e.g. `attrs={'data-mfm-some': '1deg', 'data-mfm-thing': '5s'}` => "--mfm-some: 1deg;--mfm-thing: 5s;"
// Note that we only add the value to `style` when they contain only letters, numbers, dot, hash, or plus or minus signs
// At the moment of writing, this should be enough for legitimite purposes and reduces the chance of injection by using special characters
let mfm_style = Object.keys(attrs).filter(
(key) => key.startsWith('data-mfm-') && attrs[key] !== true
(key) => key.startsWith('data-mfm-') && attrs[key] !== true && /^[a-zA-Z0-9.\-+#]*$/.test(attrs[key])
).map(
(key) => '--mfm-' + key.substr(9) + ': ' + attrs[key] + ';'
).reduce((a,v) => a+v, "")
if (mfm_style !== "") {
).reduce((a,v) => a+v, '')
if (mfm_style !== '') {
return [
opener.slice(0,-1) + " style=\"" + mfm_style + "\">",
opener.slice(0,-1) + ' style="' + mfm_style + '">',
children.map(processItem),
closer
]

View file

@ -40,6 +40,35 @@ describe('RichContent', () => {
expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(html))
})
it('does not allow injection through MFM data- attributes', () => {
const html_ok = '<span class="mfm-spin" data-mfm-speed="-0.2s" data-mfm-color="#000" data-mfm-deg="+30">brrr</span>'
const expected_ok = '<span class="mfm-spin" data-mfm-speed="-0.2s" data-mfm-color="#000" data-mfm-deg="+30" style="--mfm-speed: -0.2s; --mfm-color: #000; --mfm-deg: +30;">brrr</span>'
const wrapper_ok = shallowMount(RichContent, {
global,
props: {
attentions,
handleLinks: true,
greentext: true,
emoji: [],
html: html_ok
}
})
const html_nok = '<span class="mfm-spin" data-mfm-speed="<" data-mfm-color="\\">brrr</span>'
const wrapper_nok = shallowMount(RichContent, {
global,
props: {
attentions,
handleLinks: true,
greentext: true,
emoji: [],
html: html_nok
}
})
expect(wrapper_ok.html()).to.eql(compwrap(expected_ok))
expect(wrapper_nok.html()).to.eql(compwrap(html_nok))
})
it('unescapes everything as needed', () => {
const html = [
p('Testing &#39;em all'),