mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
Merge pull request #5520 from iansan5653/fix-sandbox-utf16
Fix `sandbox` mode with UTF-16 characters
This commit is contained in:
commit
1e43ad1ee3
@ -19,4 +19,4 @@ The `parseError` function will not be called.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:64](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L64)
|
[mermaidAPI.ts:65](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L65)
|
||||||
|
@ -18,4 +18,4 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:71](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L71)
|
[mermaidAPI.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L72)
|
||||||
|
@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:94](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L94)
|
[mermaidAPI.ts:95](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L95)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ The diagram type, e.g. 'flowchart', 'sequence', etc.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:84](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L84)
|
[mermaidAPI.ts:85](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L85)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -63,4 +63,4 @@ The svg code for the rendered graph.
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:80](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L80)
|
[mermaidAPI.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L81)
|
||||||
|
@ -26,7 +26,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:74](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L74)
|
[mermaidAPI.ts:75](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L75)
|
||||||
|
|
||||||
## Variables
|
## Variables
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ the cleaned up svgCode
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:222](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L222)
|
[mermaidAPI.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L223)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -180,7 +180,7 @@ the string with all the user styles
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:153](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L153)
|
[mermaidAPI.ts:154](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L154)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ the string with all the user styles
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:199](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L199)
|
[mermaidAPI.ts:200](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L200)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:138](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L138)
|
[mermaidAPI.ts:139](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L139)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -252,7 +252,6 @@ Put the svgCode into an iFrame. Return the iFrame code
|
|||||||
`string`
|
`string`
|
||||||
|
|
||||||
- the code with the iFrame that now contains the svgCode
|
- the code with the iFrame that now contains the svgCode
|
||||||
TODO replace btoa(). Replace with buf.toString('base64')?
|
|
||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
|
@ -69,6 +69,7 @@ vi.mock('stylis', () => {
|
|||||||
import { compile, serialize } from 'stylis';
|
import { compile, serialize } from 'stylis';
|
||||||
import { decodeEntities, encodeEntities } from './utils.js';
|
import { decodeEntities, encodeEntities } from './utils.js';
|
||||||
import { Diagram } from './Diagram.js';
|
import { Diagram } from './Diagram.js';
|
||||||
|
import { toBase64 } from './utils/base64.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see https://vitest.dev/guide/mocking.html Mock part of a module
|
* @see https://vitest.dev/guide/mocking.html Mock part of a module
|
||||||
@ -176,7 +177,7 @@ describe('mermaidAPI', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('putIntoIFrame', () => {
|
describe('putIntoIFrame', () => {
|
||||||
const inputSvgCode = 'this is the SVG code';
|
const inputSvgCode = 'this is the SVG code ⛵';
|
||||||
|
|
||||||
it('uses the default SVG iFrame height is used if no svgElement given', () => {
|
it('uses the default SVG iFrame height is used if no svgElement given', () => {
|
||||||
const result = putIntoIFrame(inputSvgCode);
|
const result = putIntoIFrame(inputSvgCode);
|
||||||
@ -199,11 +200,10 @@ describe('mermaidAPI', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('sets src to base64 version of <body style="IFRAME_SVG_BODY_STYLE">svgCode<//body>', () => {
|
it('sets src to base64 version of <body style="IFRAME_SVG_BODY_STYLE">svgCode<//body>', () => {
|
||||||
const base64encodedSrc = btoa('<body style="' + 'margin:0' + '">' + inputSvgCode + '</body>');
|
const base64encodedSrc = toBase64(`<body style="margin:0">${inputSvgCode}</body>`);
|
||||||
const expectedRegExp = new RegExp('src="data:text/html;base64,' + base64encodedSrc + '"');
|
const expectedSrc = `src="data:text/html;charset=UTF-8;base64,${base64encodedSrc}"`;
|
||||||
|
|
||||||
const result = putIntoIFrame(inputSvgCode);
|
const result = putIntoIFrame(inputSvgCode);
|
||||||
expect(result).toMatch(expectedRegExp);
|
expect(result).toContain(expectedSrc);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('uses the height and appends px from the svgElement given', () => {
|
it('uses the height and appends px from the svgElement given', () => {
|
||||||
|
@ -31,6 +31,7 @@ import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.
|
|||||||
import type { DiagramMetadata, DiagramStyleClassDef } from './diagram-api/types.js';
|
import type { DiagramMetadata, DiagramStyleClassDef } from './diagram-api/types.js';
|
||||||
import { preprocessDiagram } from './preprocess.js';
|
import { preprocessDiagram } from './preprocess.js';
|
||||||
import { decodeEntities } from './utils.js';
|
import { decodeEntities } from './utils.js';
|
||||||
|
import { toBase64 } from './utils/base64.js';
|
||||||
|
|
||||||
const MAX_TEXTLENGTH = 50_000;
|
const MAX_TEXTLENGTH = 50_000;
|
||||||
const MAX_TEXTLENGTH_EXCEEDED_MSG =
|
const MAX_TEXTLENGTH_EXCEEDED_MSG =
|
||||||
@ -248,14 +249,13 @@ export const cleanUpSvgCode = (
|
|||||||
* @param svgCode - the svg code to put inside the iFrame
|
* @param svgCode - the svg code to put inside the iFrame
|
||||||
* @param svgElement - the d3 node that has the current svgElement so we can get the height from it
|
* @param svgElement - the d3 node that has the current svgElement so we can get the height from it
|
||||||
* @returns - the code with the iFrame that now contains the svgCode
|
* @returns - the code with the iFrame that now contains the svgCode
|
||||||
* TODO replace btoa(). Replace with buf.toString('base64')?
|
|
||||||
*/
|
*/
|
||||||
export const putIntoIFrame = (svgCode = '', svgElement?: D3Element): string => {
|
export const putIntoIFrame = (svgCode = '', svgElement?: D3Element): string => {
|
||||||
const height = svgElement?.viewBox?.baseVal?.height
|
const height = svgElement?.viewBox?.baseVal?.height
|
||||||
? svgElement.viewBox.baseVal.height + 'px'
|
? svgElement.viewBox.baseVal.height + 'px'
|
||||||
: IFRAME_HEIGHT;
|
: IFRAME_HEIGHT;
|
||||||
const base64encodedSrc = btoa('<body style="' + IFRAME_BODY_STYLE + '">' + svgCode + '</body>');
|
const base64encodedSrc = toBase64(`<body style="${IFRAME_BODY_STYLE}">${svgCode}</body>`);
|
||||||
return `<iframe style="width:${IFRAME_WIDTH};height:${height};${IFRAME_STYLES}" src="data:text/html;base64,${base64encodedSrc}" sandbox="${IFRAME_SANDBOX_OPTS}">
|
return `<iframe style="width:${IFRAME_WIDTH};height:${height};${IFRAME_STYLES}" src="data:text/html;charset=UTF-8;base64,${base64encodedSrc}" sandbox="${IFRAME_SANDBOX_OPTS}">
|
||||||
${IFRAME_NOT_SUPPORTED_MSG}
|
${IFRAME_NOT_SUPPORTED_MSG}
|
||||||
</iframe>`;
|
</iframe>`;
|
||||||
};
|
};
|
||||||
|
6
packages/mermaid/src/utils/base64.ts
Normal file
6
packages/mermaid/src/utils/base64.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export function toBase64(str: string) {
|
||||||
|
// ref: https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
|
||||||
|
const utf8Bytes = new TextEncoder().encode(str);
|
||||||
|
const utf8Str = Array.from(utf8Bytes, (byte) => String.fromCodePoint(byte)).join('');
|
||||||
|
return btoa(utf8Str);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user