Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions cypress/e2e/attachments.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,49 @@ describe('Test all attachment insertion methods', () => {
cy.closeFile()
})

it('Upload a local image file with RTLO character in name (RTLO is stripped)', () => {
const filename = randHash() + '.md'
cy.uploadFile('empty.md', 'text/markdown', filename)
cy.visit('/apps/files')
cy.openFile(filename)

const requestAlias = 'uploadRTLORequest'
cy.intercept({ method: 'POST', url: '**/text/attachment/upload?**' }).as(requestAlias)

clickOnAttachmentAction(ACTION_UPLOAD_LOCAL_FILE).then(() => {
cy.getEditor()
.find('input[type="file"][data-text-el="attachment-file-input"]')
.selectFile(
[
{
contents: 'cypress/fixtures/github.png',
fileName: 'git\u202e.png',
},
],
{ force: true },
)

return cy
.wait('@' + requestAlias).then((req) => {
const fileName = req.response.body.name // server echoes back name with RTLO
const documentId = req.response.body.documentId

// insertAttachment strips RTLO from the name before building the src URL and the
// alt text. The src URL no longer matches the on-disk filename (which still has
// the RTLO), so the image 404s. The alt text shows the clean name, exposing the
// real file extension instead of the visually spoofed one.
const strippedName = fileName.replaceAll('\u202e', '')
const encodedName = fixedEncodeURIComponent(strippedName)

cy.getEditor()
.find('[data-component="image-view"]')
.should('have.length', 1)
.should('have.attr', 'data-src', `.attachments.${documentId}/${encodedName}`)
})
})
cy.closeFile()
})

it('test if attachment files are in the attachment folder', () => {
cy.visit('/apps/files')

Expand Down
5 changes: 3 additions & 2 deletions src/components/Editor/MediaHandler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,16 @@ export default {
})
},
insertAttachment(name, fileId, mimeType, position = null, dirname = '') {
const sanitizedName = name.replaceAll('\u202E', '')
// inspired by the fixedEncodeURIComponent function suggested in
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
const src = dirname + '/'
+ encodeURIComponent(name).replace(/[!'()*]/g, (c) => {
+ encodeURIComponent(sanitizedName).replace(/[!'()*]/g, (c) => {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
// simply get rid of brackets to make sure link text is valid
// as it does not need to be unique and matching the real file name
const alt = name.replaceAll(/[[\]]/g, '')
const alt = sanitizedName.replaceAll(/[[\]]/g, '')

const chain = position
? this.$editor.chain().focus(position)
Expand Down
Loading