mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-07 09:25:33 +00:00
fix(common): check for invalid markers
- pattern parser update Fixes: 12467
This commit is contained in:
parent
c057112c9f
commit
fb4f22da66
2 changed files with 35 additions and 2 deletions
|
|
@ -81,7 +81,12 @@ export class MarkerParser {
|
|||
/**
|
||||
* Pattern for matching a marker reference, OR the special marker \m{.}
|
||||
*/
|
||||
public static readonly REFERENCE = /\\m{([0-9A-Za-z_]{1,32}|\.)}/g;
|
||||
public static readonly REFERENCE = /(?<!\\)(?:\\\\)*\\m{([0-9A-Za-z_]{1,32}|\.)}/g;
|
||||
|
||||
/**
|
||||
* Pattern for matching a broken marker reference (assuming REFERENCE was not matched)
|
||||
*/
|
||||
public static readonly BROKEN_REFERENCE = /(?<!\\)(?:\\\\)*\\m{([^}\\{}]*)/g;
|
||||
|
||||
/**
|
||||
* parse a string into marker references
|
||||
|
|
@ -95,6 +100,21 @@ export class MarkerParser {
|
|||
return matchArray(str, MarkerParser.REFERENCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* parse a string for broken marker references
|
||||
* @param str input string such as "\m{a} … \m{.}"
|
||||
* @returns `[]` or an array of all broken markers referenced
|
||||
*/
|
||||
public static allBrokenReferences(str: string): string[] {
|
||||
if (!str) {
|
||||
return [];
|
||||
}
|
||||
// exclude valid markers
|
||||
str = str.replaceAll(this.REFERENCE, '');
|
||||
return matchArray(str, MarkerParser.BROKEN_REFERENCE);
|
||||
}
|
||||
|
||||
|
||||
private static markerCodeToString(n: number, forMatch?: boolean): string {
|
||||
if (!forMatch) {
|
||||
return String.fromCharCode(n);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ describe('Test of Pattern Parsers', () => {
|
|||
// indirectly tests REFERENCE
|
||||
it('should match reference strings', () => {
|
||||
const cases: string[][] = [
|
||||
['\\m{acute}', 'acute'],
|
||||
['\\m{acute} but not \\\\m{chronic}', 'acute'], // second marker is escaped
|
||||
['\\m{acute}≈\\m{acute}', 'acute acute'], // not deduped
|
||||
['\\m{grave}≠\\m{acute}', 'grave acute'],
|
||||
[MarkerParser.ANY_MARKER, MarkerParser.ANY_MARKER_ID],
|
||||
|
|
@ -55,6 +55,19 @@ describe('Test of Pattern Parsers', () => {
|
|||
assert.deepEqual(MarkerParser.allReferences(str), [], `expected no markers: ${str}`);
|
||||
}
|
||||
});
|
||||
it('should match broken reference strings', () => {
|
||||
const cases: string[][] = [
|
||||
// hyphenated marker id - illegal
|
||||
['\\m{chronic} \\m{a-cute} \\\\m{a-choo}', 'a-cute'], // \\m{a-choo} is literal
|
||||
// marker through end of line
|
||||
['\\m{chronic} \\m{oopsIforGot to terminate it', 'oopsIforGot to terminate it'],
|
||||
// marker terminated by other valid marker
|
||||
['\\m{chronic} \\m{what \\m{does} \\m{this button do?', 'what ', 'this button do?'],
|
||||
];
|
||||
for (const [str, ...reflist] of cases) {
|
||||
assert.sameDeepMembers(MarkerParser.allBrokenReferences(str), reflist, `for ${str}`);
|
||||
}
|
||||
});
|
||||
it('should be able to emit sentinel values', () => {
|
||||
assert.equal(MarkerParser.markerOutput(295), '\uFFFF\u0008\u0127', 'Wrong sentinel value emitted');
|
||||
assert.equal(MarkerParser.markerOutput(MarkerParser.ANY_MARKER_INDEX), '\uFFFF\u0008\uD7FF', 'Wrong sentinel value emitted for ANY_MARKER_INDEX');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue