You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Desktop: Fixes #8305: Ensure that notes that contain invalid links can still be exported as HTML or PDF
This commit is contained in:
		| @@ -33,8 +33,15 @@ const htmlentities = (s: string): string => { | ||||
| }; | ||||
|  | ||||
| const dataUriEncode = (filePath: string): string => { | ||||
| 	const result = Datauri(filePath); | ||||
| 	return result.content; | ||||
| 	try { | ||||
| 		const result = Datauri(filePath); | ||||
| 		return result.content; | ||||
| 	} catch (error) { | ||||
| 		// If the file path is invalid, the Datauri will throw an exception. | ||||
| 		// Instead, since we can just ignore that particular file. | ||||
| 		// Fixes https://github.com/laurent22/joplin/issues/8305 | ||||
| 		return ''; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| const attributesHtml = (attr: any) => { | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import * as fs from 'fs-extra'; | ||||
| import { tempFilePath } from '../../testing/test-utils'; | ||||
| import { ContentScriptType } from '../../services/plugins/api/types'; | ||||
| import { FileSystemItem } from './types'; | ||||
| import { readFile } from 'fs/promises'; | ||||
|  | ||||
| async function recreateExportDir() { | ||||
| 	const dir = exportDir(); | ||||
| @@ -120,4 +121,22 @@ describe('interop/InteropService_Exporter_Html', () => { | ||||
| 		expect(readFenceContent).toBe(fenceContent); | ||||
| 	})); | ||||
|  | ||||
| 	test('should not throw an error on invalid resource paths', (async () => { | ||||
| 		const service = InteropService.instance(); | ||||
| 		const folder1 = await Folder.save({ title: 'folder1' }); | ||||
| 		await Note.save({ title: 'note1', parent_id: folder1.id, body: '[a link starts with slash](/)' }); | ||||
|  | ||||
| 		const filePath = `${exportDir()}/test.html`; | ||||
|  | ||||
| 		await service.export({ | ||||
| 			path: filePath, | ||||
| 			format: 'html', | ||||
| 			packIntoSingleFile: true, | ||||
| 			target: FileSystemItem.File, | ||||
| 		}); | ||||
|  | ||||
| 		const content = await readFile(filePath, 'utf-8'); | ||||
| 		expect(content).toContain('<a data-from-md="" title="/" href="" download="">a link starts with slash</a>'); | ||||
| 	})); | ||||
|  | ||||
| }); | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import Folder from '../../models/Folder'; | ||||
| import Note from '../../models/Note'; | ||||
| import Setting from '../../models/Setting'; | ||||
| import { MarkupToHtml } from '@joplin/renderer'; | ||||
| import { ResourceEntity } from '../database/types'; | ||||
| import { NoteEntity, ResourceEntity } from '../database/types'; | ||||
| import { contentScriptsToRendererRules } from '../plugins/utils/loadContentScripts'; | ||||
| import { basename, friendlySafeFilename, rtrimSlashes, dirname } from '../../path-utils'; | ||||
| import htmlpack from '@joplin/htmlpack'; | ||||
| @@ -48,7 +48,7 @@ export default class InteropService_Exporter_Html extends InteropService_Exporte | ||||
| 		this.style_ = themeStyle(Setting.THEME_LIGHT); | ||||
| 	} | ||||
|  | ||||
| 	private async makeDirPath_(item: any, pathPart: string = null) { | ||||
| 	private async makeDirPath_(item: NoteEntity, pathPart: string = null) { | ||||
| 		let output = ''; | ||||
| 		while (true) { | ||||
| 			if (item.type_ === BaseModel.TYPE_FOLDER) { | ||||
| @@ -64,7 +64,7 @@ export default class InteropService_Exporter_Html extends InteropService_Exporte | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private async processNoteResources_(item: any) { | ||||
| 	private async processNoteResources_(item: NoteEntity) { | ||||
| 		const target = this.metadata().target; | ||||
| 		const linkedResourceIds = await Note.linkedResourceIds(item.body); | ||||
| 		const relativePath = target === 'directory' ? rtrimSlashes(await this.makeDirPath_(item, '..')) : ''; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user