Desktop,Mobile: Plugins: Legacy editor API: Fix delayed crash caused by out-of-bounds inputs (#11714)

pull/11795/head^2
Henry Heino 2025-02-06 10:12:43 -08:00 committed by GitHub
parent 786e55c972
commit f25e1a5e80
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 3 deletions

View File

@ -185,4 +185,29 @@ describe('CodeMirror5Emulation', () => {
expect(lastThis).toBe(codeMirror); expect(lastThis).toBe(codeMirror);
}); });
it('.markText should support specifying ranges outside the document', () => {
const codeMirror = makeCodeMirrorEmulation('Test...');
const testClassName = 'out-of-range-test-mark';
codeMirror.markText(
// In range
{ line: 0, ch: 4 },
// Out of range
{ line: 0, ch: 1002 },
{ className: testClassName },
);
const dom = codeMirror.editor.dom;
expect(dom.querySelectorAll(`.${testClassName}`)).toHaveLength(1);
});
it('.markText should throw when given non-integer boundaries', () => {
const codeMirror = makeCodeMirrorEmulation('Test...');
expect(() => codeMirror.markText(
{ line: 0, ch: 4.2 },
{ line: 0, ch: 5 },
)).toThrow(/is not an integer/i);
});
}); });

View File

@ -37,6 +37,10 @@ interface DocumentPositionRange {
to: DocumentPosition; to: DocumentPosition;
} }
const clampPositionToDoc = (doc: Text, pos: number) => {
return Math.min(Math.max(0, pos), doc.length);
};
const documentPositionFromPos = (doc: Text, pos: number): DocumentPosition => { const documentPositionFromPos = (doc: Text, pos: number): DocumentPosition => {
const line = doc.lineAt(pos); const line = doc.lineAt(pos);
return { return {
@ -48,7 +52,12 @@ const documentPositionFromPos = (doc: Text, pos: number): DocumentPosition => {
const posFromDocumentPosition = (doc: Text, pos: DocumentPosition) => { const posFromDocumentPosition = (doc: Text, pos: DocumentPosition) => {
const line = doc.line(pos.line + 1); const line = doc.line(pos.line + 1);
return line.from + pos.ch; const result = line.from + pos.ch;
if (!Number.isInteger(result)) {
throw new Error(`Document position ${result} (${pos.line}:${pos.ch}) is not an integer`);
}
return result;
}; };
export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation { export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation {
@ -420,8 +429,8 @@ export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation {
const doc = this.editor.state.doc; const doc = this.editor.state.doc;
return this._decorator.markText( return this._decorator.markText(
posFromDocumentPosition(doc, from), clampPositionToDoc(doc, posFromDocumentPosition(doc, from)),
posFromDocumentPosition(doc, to), clampPositionToDoc(doc, posFromDocumentPosition(doc, to)),
options, options,
); );
} }