Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: getMessageAPI so it considers entity codes #5002

Merged
merged 8 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/mermaid/src/Diagram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { log } from './logger.js';
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI.js';
import { detectType, getDiagramLoader } from './diagram-api/detectType.js';
import { UnknownDiagramError } from './errors.js';
import { encodeEntities } from './utils.js';

import type { DetailedError } from './utils.js';
import type { DiagramDefinition, DiagramMetadata } from './diagram-api/types.js';

Expand Down Expand Up @@ -81,6 +83,8 @@ export const getDiagramFromText = async (
text: string,
metadata: Pick<DiagramMetadata, 'title'> = {}
): Promise<Diagram> => {
text = encodeEntities(text);

ad1992 marked this conversation as resolved.
Show resolved Hide resolved
const type = detectType(text, configApi.getConfig());
try {
// Trying to find the diagram
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/dagre-wrapper/createLabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { select } from 'd3';
import { log } from '../logger.js';
import { getConfig } from '../diagram-api/diagramAPI.js';
import { evaluate } from '../diagrams/common/common.js';
import { decodeEntities } from '../mermaidAPI.js';
import { decodeEntities } from '../utils.js';

/**
* @param dom
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/dagre-wrapper/shapes/util.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import createLabel from '../createLabel.js';
import { createText } from '../../rendering-util/createText.js';
import { getConfig } from '../../diagram-api/diagramAPI.js';
import { decodeEntities } from '../../mermaidAPI.js';
import { select } from 'd3';
import { evaluate, sanitizeText } from '../../diagrams/common/common.js';
import { decodeEntities } from '../../utils.js';

export const labelHelper = async (parent, node, _classes, isNode) => {
let classes;
Expand Down
14 changes: 14 additions & 0 deletions packages/mermaid/src/diagram.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,18 @@ Expecting 'TXT', got 'NEWLINE'"
'"No diagram type detected matching given configuration for text: thor TD; A-->B"'
);
});

test('should consider entity codes when present in diagram defination', async () => {
const diagram = await getDiagramFromText(`sequenceDiagram
A->>B: I #9829; you!
B->>A: I #9829; you #infin; times more!`);
// @ts-ignore: we need to add types for sequenceDb which will be done in separate PR
const messages = diagram.db?.getMessages?.();
if (!messages) {
throw new Error('Messages not found!');
}

expect(messages[0].message).toBe('I fl°°9829¶ß you!');
expect(messages[1].message).toBe('I fl°°9829¶ß you fl°infin¶ß times more!');
});
});
3 changes: 1 addition & 2 deletions packages/mermaid/src/mermaidAPI.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ import type { MermaidConfig } from './config.type.js';

import mermaidAPI, { removeExistingElements } from './mermaidAPI.js';
import {
encodeEntities,
decodeEntities,
createCssStyles,
createUserStyles,
appendDivSvgG,
Expand Down Expand Up @@ -68,6 +66,7 @@ vi.mock('stylis', () => {
};
});
import { compile, serialize } from 'stylis';
import { decodeEntities, encodeEntities } from './utils.js';

/**
* @see https://vitest.dev/guide/mocking.html Mock part of a module
Expand Down
40 changes: 1 addition & 39 deletions packages/mermaid/src/mermaidAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import isEmpty from 'lodash-es/isEmpty.js';
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js';
import type { DiagramStyleClassDef } from './diagram-api/types.js';
import { preprocessDiagram } from './preprocess.js';
import { decodeEntities } from './utils.js';

const MAX_TEXTLENGTH = 50_000;
const MAX_TEXTLENGTH_EXCEEDED_MSG =
Expand Down Expand Up @@ -110,43 +111,6 @@ async function parse(text: string, parseOptions?: ParseOptions): Promise<boolean
return true;
}

/**
* @param text - text to be encoded
* @returns
*/
export const encodeEntities = function (text: string): string {
let txt = text;

txt = txt.replace(/style.*:\S*#.*;/g, function (s): string {
return s.substring(0, s.length - 1);
});
txt = txt.replace(/classDef.*:\S*#.*;/g, function (s): string {
return s.substring(0, s.length - 1);
});

txt = txt.replace(/#\w+;/g, function (s) {
const innerTxt = s.substring(1, s.length - 1);

const isInt = /^\+?\d+$/.test(innerTxt);
if (isInt) {
return 'fl°°' + innerTxt + '¶ß';
} else {
return 'fl°' + innerTxt + '¶ß';
}
});

return txt;
};

/**
*
* @param text - text to be decoded
* @returns
*/
export const decodeEntities = function (text: string): string {
return text.replace(/fl°°/g, '&#').replace(/fl°/g, '&').replace(/¶ß/g, ';');
};

// append !important; to each cssClass followed by a final !important, all enclosed in { }
//
/**
Expand Down Expand Up @@ -436,8 +400,6 @@ const render = async function (
appendDivSvgG(root, id, enclosingDivID);
}

text = encodeEntities(text);

// -------------------------------------------------------------------------------
// Create the diagram

Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/rendering-util/createText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import type { Group } from '../diagram-api/types.js';
import type { D3TSpanElement, D3TextElement } from '../diagrams/common/commonTypes.js';
import { log } from '../logger.js';
import { decodeEntities } from '../mermaidAPI.js';
import { markdownToHTML, markdownToLines } from '../rendering-util/handle-markdown-text.js';
import { decodeEntities } from '../utils.js';
import { splitLineToFitWidth } from './splitText.js';
import type { MarkdownLine, MarkdownWord } from './types.js';

Expand Down
37 changes: 37 additions & 0 deletions packages/mermaid/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -888,3 +888,40 @@
parseFontSize,
InitIDGenerator,
};

/**
* @param text - text to be encoded
* @returns
*/
export const encodeEntities = function (text: string): string {
let txt = text;

Check warning on line 898 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L898

Added line #L898 was not covered by tests
txt = txt.replace(/style.*:\S*#.*;/g, function (s): string {
return s.substring(0, s.length - 1);
});

Check warning on line 901 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L901

Added line #L901 was not covered by tests
Comment on lines +899 to +901

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
library input
may run slow on strings starting with 'style' and with many repetitions of 'style'.
This
regular expression
that depends on
library input
may run slow on strings starting with 'style:' and with many repetitions of ':'.
This
regular expression
that depends on
library input
may run slow on strings starting with 'style:#' and with many repetitions of '#'.
txt = txt.replace(/classDef.*:\S*#.*;/g, function (s): string {
return s.substring(0, s.length - 1);
});

Check warning on line 905 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L904-L905

Added lines #L904 - L905 were not covered by tests
txt = txt.replace(/#\w+;/g, function (s) {
const innerTxt = s.substring(1, s.length - 1);

Check warning on line 908 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L908

Added line #L908 was not covered by tests
const isInt = /^\+?\d+$/.test(innerTxt);
if (isInt) {
return 'fl°°' + innerTxt + '¶ß';
} else {

Check warning on line 912 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L912

Added line #L912 was not covered by tests
return 'fl°' + innerTxt + '¶ß';
}
});

Check warning on line 916 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L914-L916

Added lines #L914 - L916 were not covered by tests
return txt;
};

Check warning on line 918 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L918

Added line #L918 was not covered by tests

/**
*
* @param text - text to be decoded
* @returns
*/
export const decodeEntities = function (text: string): string {
return text.replace(/fl°°/g, '&#').replace(/fl°/g, '&').replace(/¶ß/g, ';');
};

Check warning on line 927 in packages/mermaid/src/utils.ts

View check run for this annotation

Codecov / codecov/patch

packages/mermaid/src/utils.ts#L927

Added line #L927 was not covered by tests
Loading