Skip to content

Commit aef971e

Browse files
authored
Merge branch 'Zettlr:develop' into develop
2 parents 76eb163 + 543ddb3 commit aef971e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+678
-1660
lines changed

.yarn/releases/yarn-4.6.0.cjs

Lines changed: 0 additions & 934 deletions
This file was deleted.

.yarnrc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ enableTelemetry: false
66

77
nodeLinker: node-modules
88

9-
yarnPath: .yarn/releases/yarn-4.6.0.cjs
9+
npmMinimalAgeGate: "7d"

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,33 @@
1818
`smooth`.
1919
- Fixed a small bug that could throw off switching between different file
2020
manager modes.
21+
- Fixed the cursor scroll margin again. This means that, after years of it not
22+
working, as you type there will now be some margin towards the top or bottom
23+
of the editor window, preventing the cursor to "stick" to the edge of the
24+
editor.
25+
- Update `pt-PT` translations (#6282).
2126

2227
## Under the Hood
2328

29+
- Switch from `sanitize-html` to `DOMPurify` for HTML sanitization, since the
30+
latter has much, much less issues with various types of exotic XML-type tags
31+
such as MathML.
32+
- Updated Electron to `v41.1.1`.
2433
- Security: Disallow any and all inline-JavaScript across all browser windows.
2534
- Security: Enforce loading remote resources using HTTPS.
35+
- Security: Generously spread HTML sanitization across the application. The
36+
following changes have been made:
37+
- Moved HTML sanitization to the edge (directly to the injection sinks)
38+
- Removed HTML sanitization from the translation helpers. The reason is that
39+
DOMPurify does not work out of the box in the main process, so we also
40+
removed the sanitization from the renderer-translation helper. However, this
41+
is safe since we do not insert the translations into HTML injection sinks.
42+
Also, this way we can apply DOM sanitization at the edge, and no longer at
43+
the beginning of the chain.
44+
- This also means that HTML is no longer allowed in translation strings.
45+
- Armed the `v-html`-rule again, and removed all `v-html` directives, and in
46+
instances where this was not possible, explicitly disable this with a
47+
reason.
2648

2749
# 4.3.1
2850

eslint.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export default [
189189
// provided HTML to only contain safe tags. The only stuff we currently
190190
// put in there is translation strings, which we sanitise in the trans()
191191
// function. NOTE to keep this on my mind!
192-
'vue/no-v-html': 'off'
192+
'vue/no-v-html': 'error'
193193

194194
////////////////////////// END VUE RULES /////////////////////////////////
195195
}

package.json

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,33 +76,34 @@
7676
"@codemirror/lint": "^6.9.5",
7777
"@codemirror/search": "^6.6.0",
7878
"@codemirror/state": "^6.6.0",
79-
"@codemirror/view": "^6.40.0",
79+
"@codemirror/view": "^6.41.0",
8080
"@lezer/common": "^1.5.1",
8181
"@lezer/highlight": "^1.2.3",
8282
"@lezer/lr": "^1.4.8",
8383
"@lezer/markdown": "^1.6.3",
8484
"@replit/codemirror-emacs": "^6.1.0",
8585
"@replit/codemirror-lang-nix": "^6.0.1",
8686
"@replit/codemirror-vim": "^6.3.0",
87-
"adm-zip": "^0.5.16",
87+
"adm-zip": "^0.5.17",
8888
"archiver": "^7.0.1",
8989
"astrocite": "^0.16.4",
9090
"bcp-47": "^2.1.0",
91-
"biblatex-csl-converter": "^3.4.0",
91+
"biblatex-csl-converter": "^3.5.5",
9292
"chalk": "^5.6.2",
9393
"chokidar": "^5.0.0",
9494
"citeproc": "^2.4.63",
9595
"d3": "^7.9.0",
96+
"dompurify": "^3.3.3",
9697
"fix-path": "^5.0.0",
9798
"gemoji": "^8.1.0",
98-
"gettext-parser": "^9.0.1",
99+
"gettext-parser": "^9.0.2",
99100
"got": "^11.8.6",
100101
"katex": "^0.16.44",
101102
"ky": "^1.14.3",
102103
"lang-criticmarkup": "^0.3.0",
103104
"luxon": "^3.7.2",
104105
"md5": "^2.3.0",
105-
"mermaid": "^11.13.0",
106+
"mermaid": "^11.14.0",
106107
"nodehun": "^3.0.2",
107108
"pinia": "^3.0.4",
108109
"rehype-parse": "^9.0.1",
@@ -136,13 +137,12 @@
136137
"remark-stringify": "^11.0.0",
137138
"rimraf": "^6.1.3",
138139
"sanitize-filename": "^1.6.4",
139-
"sanitize-html": "^2.17.2",
140140
"semver": "^7.7.4",
141141
"tippy.js": "^6.3.7",
142142
"underscore": "^1.13.8",
143143
"unified": "^11.0.5",
144144
"uuid": "^13.0.0",
145-
"vue": "^3.5.31",
145+
"vue": "^3.5.32",
146146
"vue-virtual-scroller": "^2.0.0-beta.8",
147147
"w3c-keyname": "^2.2.8",
148148
"yaml": "^2.8.3"
@@ -162,11 +162,11 @@
162162
"@electron-forge/maker-zip": "^7.11.1",
163163
"@electron-forge/plugin-fuses": "^7.11.1",
164164
"@electron-forge/plugin-webpack": "^7.11.1",
165-
"@electron/fuses": "^2.1.0",
165+
"@electron/fuses": "^2.1.1",
166166
"@electron/notarize": "^3.1.1",
167167
"@eslint/config-inspector": "^1.5.0",
168168
"@stylistic/eslint-plugin": "^5.10.0",
169-
"@types/adm-zip": "^0.5.7",
169+
"@types/adm-zip": "^0.5.8",
170170
"@types/archiver": "^7.0.0",
171171
"@types/command-exists": "^1.2.3",
172172
"@types/d3": "^7.4.3",
@@ -176,33 +176,32 @@
176176
"@types/md5": "^2.3.6",
177177
"@types/mocha": "^10.0.10",
178178
"@types/node": "^22.19.15",
179-
"@types/sanitize-html": "^2.16.1",
180179
"@types/semver": "^7.7.1",
181180
"@types/showdown": "^2.0.6",
182181
"@types/underscore": "^1.13.0",
183-
"@typescript-eslint/eslint-plugin": "^8.57.2",
184-
"@typescript-eslint/parser": "^8.57.2",
182+
"@typescript-eslint/eslint-plugin": "^8.58.0",
183+
"@typescript-eslint/parser": "^8.58.0",
185184
"@vercel/webpack-asset-relocator-loader": "1.7.3",
186185
"copy-webpack-plugin": "^14.0.0",
187186
"cross-env": "^10.1.0",
188187
"css-loader": "^7.1.4",
189188
"csso": "^5.0.5",
190-
"electron": "^40.8.0",
189+
"electron": "^41.1.1",
191190
"electron-builder": "^26.8.2",
192191
"electron-devtools-installer": "^4.0.0",
193192
"eslint": "^10.1.0",
194193
"eslint-plugin-import": "^2.32.0",
195194
"eslint-plugin-n": "^17.24.0",
196195
"eslint-plugin-promise": "^7.2.1",
197196
"eslint-plugin-vue": "^10.8.0",
198-
"jsdom": "^27.4.0",
197+
"jsdom": "^29.0.1",
199198
"less": "^4.6.4",
200199
"less-loader": "^12.3.2",
201200
"mocha": "^11.7.5",
202201
"node-loader": "^2.1.0",
203202
"nyc": "^18.0.0",
204203
"style-loader": "^4.0.0",
205-
"ts-loader": "^9.5.4",
204+
"ts-loader": "^9.5.7",
206205
"ts-node": "^10.9.2",
207206
"tsconfig-paths": "^4.2.0",
208207
"typescript": "^5.9.3",

source/app/service-providers/updates/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,9 +455,11 @@ export default class UpdateProvider extends ProviderContract {
455455

456456
// Adapt the rest of the state
457457
state.tagName = parsedResponse.tag_name
458+
// NOTE: We do not sanitize the HTML here. Instead we sanitize it in the
459+
// update window directly.
458460
state.changelog = await md2html(parsedResponse.body, {
459461
onCitation: (_c1, _c2) => undefined,
460-
zknLinkFormat: 'link|title', sanitizeHTML: true
462+
zknLinkFormat: 'link|title'
461463
})
462464
state.prerelease = parsedResponse.prerelease
463465
state.releasePage = parsedResponse.html_url

source/common/i18n-main.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
* END HEADER
1313
*/
1414

15-
import sanitizeHtml from 'sanitize-html'
1615
import { po, type GetTextTranslations } from 'gettext-parser'
1716
import getLanguageFile from './util/get-language-file'
1817
import { promises as fs } from 'fs'
@@ -82,12 +81,5 @@ export function trans (msgid: string, ...args: any[]): string {
8281
transString = transString.replace('%s', String(a)) // Always replace one %s with an arg
8382
}
8483

85-
// Finally, before returning the translation, sanitize it. As these are only
86-
// translation strings, we can basically only allow a VERY small subset of all
87-
// tags.
88-
const safeString = sanitizeHtml(transString, {
89-
allowedTags: [ 'em', 'strong', 'kbd' ]
90-
})
91-
92-
return safeString
84+
return transString
9385
}

source/common/i18n-renderer.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* END HEADER
1414
*/
1515

16-
import sanitizeHtml from 'sanitize-html'
1716
const ipcRenderer = window.ipc
1817

1918
let i18nData: any
@@ -65,12 +64,5 @@ export function trans (msgid: string, ...args: any[]): string {
6564
transString = transString.replace('%s', String(a)) // Always replace one %s with an arg
6665
}
6766

68-
// Finally, before returning the translation, sanitize it. As these are only
69-
// translation strings, we can basically only allow a VERY small subset of all
70-
// tags.
71-
const safeString = sanitizeHtml(transString, {
72-
allowedTags: [ 'em', 'strong', 'kbd' ]
73-
})
74-
75-
return safeString
67+
return transString
7668
}

source/common/modules/markdown-editor/editor-extension-sets.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ function getCoreExtensions (options: CoreExtensionOptions): Extension[] {
165165
const themes = getMainEditorThemes()
166166

167167
return [
168+
EditorView.cursorScrollMargin.of({ x: 50, y: 50 }), // Corresponds to the padding set to the MainEditor.vue for now
168169
// Both vim and emacs modes need to be included first, before any other
169170
// keymap.
170171
inputModeCompartment.of(inputMode),

source/common/modules/markdown-editor/renderers/render-citations.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { CITEPROC_MAIN_DB } from '@dts/common/citeproc'
2121
import { citationMenu } from '../context-menu/citation-menu'
2222
import { configField } from '../util/configuration'
2323
import { type Citation, NODES, nodeToCiteItem } from '../parser/citation-parser'
24+
import DOMPurify from 'dompurify'
2425

2526
class CitationWidget extends WidgetType {
2627
constructor (readonly citation: Citation, readonly rawCitation: string, readonly node: SyntaxNode) {
@@ -67,7 +68,7 @@ class CitationWidget extends WidgetType {
6768
const elem = document.createElement('span')
6869
elem.classList.add('citeproc-citation')
6970
if (renderedCitation !== undefined) {
70-
elem.innerHTML = renderedCitation
71+
elem.innerHTML = DOMPurify.sanitize(renderedCitation)
7172
} else {
7273
elem.innerText = this.rawCitation
7374
elem.classList.add('error')

0 commit comments

Comments
 (0)