1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-11 18:24:43 +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:
Laurent Cozic 2023-09-24 23:58:58 +01:00
parent 329f5a0dda
commit fb9974c76f
3 changed files with 31 additions and 5 deletions

View File

@ -33,8 +33,15 @@ const htmlentities = (s: string): string => {
}; };
const dataUriEncode = (filePath: string): string => { const dataUriEncode = (filePath: string): string => {
const result = Datauri(filePath); try {
return result.content; 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) => { const attributesHtml = (attr: any) => {

View File

@ -7,6 +7,7 @@ import * as fs from 'fs-extra';
import { tempFilePath } from '../../testing/test-utils'; import { tempFilePath } from '../../testing/test-utils';
import { ContentScriptType } from '../../services/plugins/api/types'; import { ContentScriptType } from '../../services/plugins/api/types';
import { FileSystemItem } from './types'; import { FileSystemItem } from './types';
import { readFile } from 'fs/promises';
async function recreateExportDir() { async function recreateExportDir() {
const dir = exportDir(); const dir = exportDir();
@ -120,4 +121,22 @@ describe('interop/InteropService_Exporter_Html', () => {
expect(readFenceContent).toBe(fenceContent); 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>');
}));
}); });

View File

@ -6,7 +6,7 @@ import Folder from '../../models/Folder';
import Note from '../../models/Note'; import Note from '../../models/Note';
import Setting from '../../models/Setting'; import Setting from '../../models/Setting';
import { MarkupToHtml } from '@joplin/renderer'; import { MarkupToHtml } from '@joplin/renderer';
import { ResourceEntity } from '../database/types'; import { NoteEntity, ResourceEntity } from '../database/types';
import { contentScriptsToRendererRules } from '../plugins/utils/loadContentScripts'; import { contentScriptsToRendererRules } from '../plugins/utils/loadContentScripts';
import { basename, friendlySafeFilename, rtrimSlashes, dirname } from '../../path-utils'; import { basename, friendlySafeFilename, rtrimSlashes, dirname } from '../../path-utils';
import htmlpack from '@joplin/htmlpack'; import htmlpack from '@joplin/htmlpack';
@ -48,7 +48,7 @@ export default class InteropService_Exporter_Html extends InteropService_Exporte
this.style_ = themeStyle(Setting.THEME_LIGHT); this.style_ = themeStyle(Setting.THEME_LIGHT);
} }
private async makeDirPath_(item: any, pathPart: string = null) { private async makeDirPath_(item: NoteEntity, pathPart: string = null) {
let output = ''; let output = '';
while (true) { while (true) {
if (item.type_ === BaseModel.TYPE_FOLDER) { 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 target = this.metadata().target;
const linkedResourceIds = await Note.linkedResourceIds(item.body); const linkedResourceIds = await Note.linkedResourceIds(item.body);
const relativePath = target === 'directory' ? rtrimSlashes(await this.makeDirPath_(item, '..')) : ''; const relativePath = target === 'directory' ? rtrimSlashes(await this.makeDirPath_(item, '..')) : '';