Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"message": "Const enums are forbidden to increase interoperability. Use regular enums instead."
}
],
"no-console": "error"
"no-console": "error",
"no-eval": "error"
}
}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ For more details on the contents of a release, see [the GitHub release page] (ht

_**Note:** Yet to be released breaking changes appear here._

**Breaking Changes**:
- `StylesheetCodec.allowEval` is now set to `false` by default to prevent unwanted use of the eval function, as it carries a possible security risk.

## 0.16.0

Release date: `2025-03-02`
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/editor/EditorPopupMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Editor from './Editor';

import { PopupMenuItem } from '../types';
import { isNullish } from '../util/Utils';
import { doEval } from '../internal/utils';

/**
* Creates popupmenus for mouse events.
Expand Down Expand Up @@ -194,7 +195,7 @@ export class EditorPopupMenu {
if (isNullish(condition) || conditions[condition]) {
let as = item.getAttribute('as')!;
as = Translations.get(as) || as;
const funct = eval(getTextContent(<Text>(<unknown>item)));
const funct = doEval(getTextContent(<Text>(<unknown>item)));
const action = item.getAttribute('action');
let icon = item.getAttribute('icon');
const iconCls = item.getAttribute('iconCls');
Expand Down Expand Up @@ -317,7 +318,7 @@ export class EditorPopupMenu {
const condNodes = this.config!.getElementsByTagName('condition');

for (const condNode of Array.from(condNodes)) {
const funct = eval(getTextContent(<Text>(<unknown>condNode)));
const funct = doEval(getTextContent(<Text>(<unknown>condNode)));
const name = condNode.getAttribute('name');

if (!isNullish(name) && typeof funct === 'function') {
Expand Down
23 changes: 23 additions & 0 deletions packages/core/src/internal/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright 2025-present The maxGraph project Contributors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
* @internal
*/
export const doEval = (expression: string): any => {
// eslint-disable-next-line no-eval -- valid here as we want this function to be the only place in the codebase that uses eval
return eval(expression);
};
3 changes: 2 additions & 1 deletion packages/core/src/serialization/ObjectCodec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { isInteger, isNumeric } from '../util/mathUtils';
import { getTextContent, isElement } from '../util/domUtils';
import { load } from '../util/MaxXmlRequest';
import type Codec from './Codec';
import { doEval } from '../internal/utils';

/**
* Generic codec for JavaScript objects that implements a mapping between
Expand Down Expand Up @@ -820,7 +821,7 @@ class ObjectCodec {
value = child.getAttribute('value');

if (value == null && ObjectCodec.allowEval) {
value = eval(getTextContent(<Text>(<unknown>child)));
value = doEval(getTextContent(<Text>(<unknown>child)));
}
} else {
value = dec.decode(child, template);
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/serialization/codecs/StylesheetCodec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { clone } from '../../util/cloneUtils';
import { GlobalConfig } from '../../util/config';
import { isNumeric } from '../../util/mathUtils';
import { getTextContent, isElement } from '../../util/domUtils';
import { doEval } from '../../internal/utils';

/**
* Codec for {@link Stylesheet}s.
Expand All @@ -41,9 +42,9 @@ export class StylesheetCodec extends ObjectCodec {
*
* **WARNING**: Enabling this switch carries a possible security risk.
*
* @default true
* @default false
*/
static allowEval = true;
static allowEval = false;

/**
* Encodes a stylesheet. See {@link decode} for a description of the format.
Expand Down Expand Up @@ -162,7 +163,7 @@ export class StylesheetCodec extends ObjectCodec {
let value = null;

if (text && StylesheetCodec.allowEval) {
value = eval(text);
value = doEval(text);
} else {
value = entry.getAttribute('value');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { getClientX, getClientY } from '../../../util/EventUtils';
import InternalEvent from '../../../view/event/InternalEvent';
import { getChildNodes, getTextContent, isElement } from '../../../util/domUtils';
import Translations from '../../../i18n/Translations';
import { doEval } from '../../../internal/utils';

/**
* Custom codec for configuring {@link EditorToolbar}s.
Expand Down Expand Up @@ -157,7 +158,7 @@ export class EditorToolbarCodec extends ObjectCodec {
if (action != null) {
elt = into.addItem(as, icon, action, pressedIcon);
} else if (mode != null) {
funct = EditorToolbarCodec.allowEval ? eval(text) : null;
funct = EditorToolbarCodec.allowEval ? doEval(text) : null;
elt = into.addMode(as, icon, mode, pressedIcon, funct);
} else if (template != null || (text != null && text.length > 0)) {
let cell = template ? editor.templates[template] : null;
Expand All @@ -171,7 +172,7 @@ export class EditorToolbarCodec extends ObjectCodec {
let insertFunction = null;

if (text != null && text.length > 0 && EditorToolbarCodec.allowEval) {
insertFunction = eval(text);
insertFunction = doEval(text);
}

elt = into.addPrototype(
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/view/GraphView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import StyleRegistry from './style/StyleRegistry';
import type TooltipHandler from './plugins/TooltipHandler';
import type { EdgeStyleFunction, MouseEventListener } from '../types';
import { TranslationsConfig } from '../i18n/config';
import { doEval } from '../internal/utils';

/**
* @class GraphView
Expand Down Expand Up @@ -1327,7 +1328,7 @@ export class GraphView extends EventSource {
let tmp = StyleRegistry.getValue(edgeStyle);

if (!tmp && this.isAllowEval()) {
tmp = eval(edgeStyle);
tmp = doEval(edgeStyle);
}

edgeStyle = tmp;
Expand Down Expand Up @@ -1594,7 +1595,7 @@ export class GraphView extends EventSource {
if (typeof perimeter === 'string') {
let tmp = StyleRegistry.getValue(perimeter);
if (tmp == null && this.isAllowEval()) {
tmp = eval(perimeter);
tmp = doEval(perimeter);
}
perimeter = tmp;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/view/geometry/node/StencilShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { getChildNodes, getTextContent, isElement } from '../../../util/domUtils
import Point from '../Point';
import AbstractCanvas2D from '../../canvas/AbstractCanvas2D';
import { AlignValue, ColorValue, VAlignValue } from '../../../types';
import { doEval } from '../../../internal/utils';

/**
* Configure global settings for stencil shapes.
Expand Down Expand Up @@ -193,7 +194,7 @@ class StencilShape extends Shape {
const text = getTextContent(<Text>(<unknown>node));

if (text && StencilShapeConfig.allowEval) {
const funct = eval(text);
const funct = doEval(text);

if (typeof funct === 'function') {
result = funct(shape);
Expand Down