Skip to content

Commit c31bef5

Browse files
authored
Release v3.6.4 (#1935)
1 parent 9df0527 commit c31bef5

37 files changed

Lines changed: 432 additions & 150 deletions

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
08-12-2022 (v3.6.4)
2+
3+
* dia.Paper - preserve contextmenu events hierarchy
4+
* dia.Paper - fix element user-drag property
5+
* Vectorizer - fix RegEx to avoid potential ReDoS attacks
6+
* Geometry - fix RegEx to avoid potential ReDoS attacks
7+
18
28-11-2022 (v3.6.3)
29

310
* dia.Cell - prevent exception when `removeProp()` called on non-existing top-level attribute

dist/geometry.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! JointJS v3.6.3 (2022-11-28) - JavaScript diagramming library
1+
/*! JointJS v3.6.4 (2022-12-08) - JavaScript diagramming library
22
33
44
This Source Code Form is subject to the terms of the Mozilla Public
@@ -1633,12 +1633,25 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
16331633
var rect = Rect;
16341634

16351635
function parsePoints(svgString) {
1636-
svgString = svgString.trim();
1637-
if (svgString === '') { return []; }
1636+
1637+
// Step 1: Discard surrounding spaces
1638+
var trimmedString = svgString.trim();
1639+
if (trimmedString === '') { return []; }
1640+
16381641
var points = [];
1639-
var coords = svgString.split(/\s*,\s*|\s+/);
1640-
var n = coords.length;
1641-
for (var i = 0; i < n; i += 2) {
1642+
1643+
// Step 2: Split at commas (+ their surrounding spaces) or at multiple spaces
1644+
// ReDoS mitigation: Have an anchor at the beginning of each alternation
1645+
// Note: This doesn't simplify double (or more) commas - causes empty coords
1646+
// This regex is used by `split()`, so it doesn't need to use /g
1647+
var coords = trimmedString.split(/\b\s*,\s*|,\s*|\s+/);
1648+
1649+
var numCoords = coords.length;
1650+
for (var i = 0; i < numCoords; i += 2) {
1651+
// Step 3: Convert each coord to number
1652+
// Note: If the coord cannot be converted to a number, it will be `NaN`
1653+
// Note: If the coord is empty ("", e.g. from ",," input), it will be `0`
1654+
// Note: If we end up with an odd number of coords, the last point's second coord will be `NaN`
16421655
points.push({ x: +coords[i], y: +coords[i + 1] });
16431656
}
16441657
return points;

dist/geometry.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/joint.core.css

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/joint.core.js

Lines changed: 97 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! JointJS v3.6.3 (2022-11-28) - JavaScript diagramming library
1+
/*! JointJS v3.6.4 (2022-12-08) - JavaScript diagramming library
22

33

44
This Source Code Form is subject to the terms of the Mozilla Public
@@ -3134,12 +3134,25 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
31343134
var rect = Rect;
31353135

31363136
function parsePoints(svgString) {
3137-
svgString = svgString.trim();
3138-
if (svgString === '') { return []; }
3137+
3138+
// Step 1: Discard surrounding spaces
3139+
var trimmedString = svgString.trim();
3140+
if (trimmedString === '') { return []; }
3141+
31393142
var points = [];
3140-
var coords = svgString.split(/\s*,\s*|\s+/);
3141-
var n = coords.length;
3142-
for (var i = 0; i < n; i += 2) {
3143+
3144+
// Step 2: Split at commas (+ their surrounding spaces) or at multiple spaces
3145+
// ReDoS mitigation: Have an anchor at the beginning of each alternation
3146+
// Note: This doesn't simplify double (or more) commas - causes empty coords
3147+
// This regex is used by `split()`, so it doesn't need to use /g
3148+
var coords = trimmedString.split(/\b\s*,\s*|,\s*|\s+/);
3149+
3150+
var numCoords = coords.length;
3151+
for (var i = 0; i < numCoords; i += 2) {
3152+
// Step 3: Convert each coord to number
3153+
// Note: If the coord cannot be converted to a number, it will be `NaN`
3154+
// Note: If the coord is empty ("", e.g. from ",," input), it will be `0`
3155+
// Note: If we end up with an odd number of coords, the last point's second coord will be `NaN`
31433156
points.push({ x: +coords[i], y: +coords[i + 1] });
31443157
}
31453158
return points;
@@ -9342,37 +9355,61 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
93429355
};
93439356
};
93449357

9345-
V.transformRegex = /(\w+)\(([^,)]+),?([^)]+)?\)/gi;
9358+
// Note: This regex allows multiple commas as separator which is incorrect in SVG
9359+
// This regex is used by `split()`, so it doesn't need to use /g
93469360
V.transformSeparatorRegex = /[ ,]+/;
9347-
V.transformationListRegex = /^(\w+)\((.*)\)/;
9361+
// Note: All following regexes are more restrictive than SVG specification
9362+
// ReDoS mitigation: Use an anchor at the beginning of the match
9363+
// ReDoS mitigation: Avoid backtracking (uses `[^()]+` instead of `.*?`)
9364+
// ReDoS mitigation: Don't match initial `(` inside repeated part
9365+
// The following regex needs to use /g (= cannot use capturing groups)
9366+
V.transformRegex = /\b\w+\([^()]+\)/g;
9367+
// The following regexes need to use capturing groups (= cannot use /g)
9368+
V.transformFunctionRegex = /\b(\w+)\(([^()]+)\)/;
9369+
V.transformTranslateRegex = /\btranslate\(([^()]+)\)/;
9370+
V.transformRotateRegex = /\brotate\(([^()]+)\)/;
9371+
V.transformScaleRegex = /\bscale\(([^()]+)\)/;
93489372

93499373
V.transformStringToMatrix = function(transform) {
93509374

9375+
// Initialize result matrix as identity matrix
93519376
var transformationMatrix = V.createSVGMatrix();
9352-
var matches = transform && transform.match(V.transformRegex);
9353-
if (!matches) {
9377+
9378+
// Note: Multiple transform functions are allowed in `transform` string
9379+
// `match()` returns `null` if none found
9380+
var transformMatches = transform && transform.match(V.transformRegex);
9381+
if (!transformMatches) {
9382+
// Return identity matrix
93549383
return transformationMatrix;
93559384
}
93569385

9357-
for (var i = 0, n = matches.length; i < n; i++) {
9358-
var transformationString = matches[i];
9386+
var numMatches = transformMatches.length;
9387+
for (var i = 0; i < numMatches; i++) {
93599388

9360-
var transformationMatch = transformationString.match(V.transformationListRegex);
9361-
if (transformationMatch) {
9362-
var sx, sy, tx, ty, angle;
9389+
var transformMatch = transformMatches[i];
9390+
// Use same regex as above, but with capturing groups
9391+
// `match()` returns values of capturing groups as `[1]`, `[2]`
9392+
var transformFunctionMatch = transformMatch.match(V.transformFunctionRegex);
9393+
if (transformFunctionMatch) {
9394+
9395+
var sx = (void 0), sy = (void 0), tx = (void 0), ty = (void 0), angle = (void 0);
93639396
var ctm = V.createSVGMatrix();
9364-
var args = transformationMatch[2].split(V.transformSeparatorRegex);
9365-
switch (transformationMatch[1].toLowerCase()) {
9397+
var transformFunction = transformFunctionMatch[1].toLowerCase();
9398+
var args = transformFunctionMatch[2].split(V.transformSeparatorRegex);
9399+
switch (transformFunction) {
9400+
93669401
case 'scale':
93679402
sx = parseFloat(args[0]);
93689403
sy = (args[1] === undefined) ? sx : parseFloat(args[1]);
93699404
ctm = ctm.scaleNonUniform(sx, sy);
93709405
break;
9406+
93719407
case 'translate':
93729408
tx = parseFloat(args[0]);
93739409
ty = parseFloat(args[1]);
93749410
ctm = ctm.translate(tx, ty);
93759411
break;
9412+
93769413
case 'rotate':
93779414
angle = parseFloat(args[0]);
93789415
tx = parseFloat(args[1]) || 0;
@@ -9383,14 +9420,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
93839420
ctm = ctm.rotate(angle);
93849421
}
93859422
break;
9423+
93869424
case 'skewx':
93879425
angle = parseFloat(args[0]);
93889426
ctm = ctm.skewX(angle);
93899427
break;
9428+
93909429
case 'skewy':
93919430
angle = parseFloat(args[0]);
93929431
ctm = ctm.skewY(angle);
93939432
break;
9433+
93949434
case 'matrix':
93959435
ctm.a = parseFloat(args[0]);
93969436
ctm.b = parseFloat(args[1]);
@@ -9399,10 +9439,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
93999439
ctm.e = parseFloat(args[4]);
94009440
ctm.f = parseFloat(args[5]);
94019441
break;
9442+
94029443
default:
94039444
continue;
94049445
}
94059446

9447+
// Multiply current transformation into result matrix
94069448
transformationMatrix = transformationMatrix.multiply(ctm);
94079449
}
94089450

@@ -9431,16 +9473,21 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
94319473

94329474
var separator = V.transformSeparatorRegex;
94339475

9434-
// Allow reading transform string with a single matrix
9476+
// Special handling for `transform` with one or more matrix functions
94359477
if (transform.trim().indexOf('matrix') >= 0) {
94369478

9479+
// Convert EVERYTHING in `transform` string to a matrix
9480+
// Will combine ALL matrixes * ALL translates * ALL scales * ALL rotates
9481+
// Note: In non-matrix case, we only take first one of each (if any)
94379482
var matrix = V.transformStringToMatrix(transform);
94389483
var decomposedMatrix = V.decomposeMatrix(matrix);
94399484

9485+
// Extract `translate`, `scale`, `rotate` from matrix
94409486
translate = [decomposedMatrix.translateX, decomposedMatrix.translateY];
94419487
scale = [decomposedMatrix.scaleX, decomposedMatrix.scaleY];
94429488
rotate = [decomposedMatrix.rotation];
94439489

9490+
// Rewrite `transform` string in `translate scale rotate` format
94449491
var transformations = [];
94459492
if (translate[0] !== 0 || translate[1] !== 0) {
94469493
transformations.push('translate(' + translate + ')');
@@ -9455,15 +9502,18 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
94559502

94569503
} else {
94579504

9458-
var translateMatch = transform.match(/translate\((.*?)\)/);
9505+
// Extract `translate`, `rotate`, `scale` functions from `transform` string
9506+
// Note: We only detect the first match of each (if any)
9507+
// `match()` returns value of capturing group as `[1]`
9508+
var translateMatch = transform.match(V.transformTranslateRegex);
94599509
if (translateMatch) {
94609510
translate = translateMatch[1].split(separator);
94619511
}
9462-
var rotateMatch = transform.match(/rotate\((.*?)\)/);
9512+
var rotateMatch = transform.match(V.transformRotateRegex);
94639513
if (rotateMatch) {
94649514
rotate = rotateMatch[1].split(separator);
94659515
}
9466-
var scaleMatch = transform.match(/scale\((.*?)\)/);
9516+
var scaleMatch = transform.match(V.transformScaleRegex);
94679517
if (scaleMatch) {
94689518
scale = scaleMatch[1].split(separator);
94699519
}
@@ -29899,7 +29949,8 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
2989929949

2990029950
if (evt.button === 2) {
2990129951
this.contextMenuFired = true;
29902-
this.contextMenuTrigger($.Event(evt, { type: 'contextmenu', data: evt.data }));
29952+
var contextmenuEvt = $.Event(evt, { type: 'contextmenu', data: evt.data });
29953+
this.contextMenuTrigger(contextmenuEvt);
2990329954
} else {
2990429955
var view = this.findView(evt.target);
2990529956

@@ -30162,12 +30213,21 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
3016230213

3016330214
onmagnet: function(evt) {
3016430215

30165-
this.magnetEvent(evt, function(view, evt, _, x, y) {
30166-
view.onmagnet(evt, x, y);
30167-
});
30216+
if (evt.button === 2) {
30217+
this.contextMenuFired = true;
30218+
this.magnetContextMenuFired = true;
30219+
var contextmenuEvt = $.Event(evt, { type: 'contextmenu', data: evt.data });
30220+
this.magnetContextMenuTrigger(contextmenuEvt);
30221+
if (contextmenuEvt.isPropagationStopped()) {
30222+
evt.stopPropagation();
30223+
}
30224+
} else {
30225+
this.magnetEvent(evt, function(view, evt, _, x, y) {
30226+
view.onmagnet(evt, x, y);
30227+
});
30228+
}
3016830229
},
3016930230

30170-
3017130231
magnetpointerdblclick: function(evt) {
3017230232

3017330233
this.magnetEvent(evt, function(view, evt, magnet, x, y) {
@@ -30176,8 +30236,17 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
3017630236
},
3017730237

3017830238
magnetcontextmenu: function(evt) {
30179-
3018030239
if (this.options.preventContextMenu) { evt.preventDefault(); }
30240+
30241+
if (this.magnetContextMenuFired) {
30242+
this.magnetContextMenuFired = false;
30243+
return;
30244+
}
30245+
30246+
this.magnetContextMenuTrigger(evt);
30247+
},
30248+
30249+
magnetContextMenuTrigger: function(evt) {
3018130250
this.magnetEvent(evt, function(view, evt, magnet, x, y) {
3018230251
view.magnetcontextmenu(evt, magnet, x, y);
3018330252
});
@@ -32772,7 +32841,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
3277232841
Control: Control
3277332842
});
3277432843

32775-
var version = "3.6.3";
32844+
var version = "3.6.4";
3277632845

3277732846
var Vectorizer = V;
3277832847
var layout = { PortLabel: PortLabel, Port: Port };

dist/joint.core.min.css

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/joint.core.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/joint.css

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/joint.d.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*! JointJS v3.6.3 (2022-11-28) - JavaScript diagramming library
1+
/*! JointJS v3.6.4 (2022-12-08) - JavaScript diagramming library
22
33
44
This Source Code Form is subject to the terms of the Mozilla Public
@@ -1776,8 +1776,11 @@ export namespace dia {
17761776
doubleToolMarkup?: string;
17771777
vertexMarkup: string;
17781778
arrowHeadMarkup: string;
1779+
defaultLabel?: Link.Label; // default label props
1780+
/**
1781+
* @deprecated use `defaultLabel.markup` instead
1782+
*/
17791783
labelMarkup?: string | MarkupJSON; // default label markup
1780-
labelProps?: Link.Label; // default label props
17811784

17821785
isElement(): boolean;
17831786

0 commit comments

Comments
 (0)