Skip to content

Commit a5f94e5

Browse files
Release 0.0.26 (#82)
1 parent 4c6ab3f commit a5f94e5

7 files changed

Lines changed: 552 additions & 145 deletions

File tree

SECURITY.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
2+
3+
## Security
4+
5+
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6+
7+
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8+
9+
## Reporting Security Issues
10+
11+
**Please do not report security vulnerabilities through public GitHub issues.**
12+
13+
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14+
15+
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16+
17+
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18+
19+
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20+
21+
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22+
* Full paths of source file(s) related to the manifestation of the issue
23+
* The location of the affected source code (tag/branch/commit or direct URL)
24+
* Any special configuration required to reproduce the issue
25+
* Step-by-step instructions to reproduce the issue
26+
* Proof-of-concept or exploit code (if possible)
27+
* Impact of the issue, including how an attacker might exploit the issue
28+
29+
This information will help us triage your report more quickly.
30+
31+
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32+
33+
## Preferred Languages
34+
35+
We prefer all communications to be in English.
36+
37+
## Policy
38+
39+
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40+
41+
<!-- END MICROSOFT SECURITY.MD BLOCK -->

dist/build.js

Lines changed: 151 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -92858,6 +92858,8 @@ const GRAPH_PADDING_BOTTOM = 80;
9285892858
const GRAPH_PADDING_LEFT = 80;
9285992859
const CELL_WIDTH = 70;
9286092860
const CELL_HEIGHT = 70;
92861+
const STANDARD_NODE_DISTANCE = 173;
92862+
const IDEAL_LONG_LABEL_NODE_DISTANCE = 240;
9286192863

9286292864
class PolygonRoot {
9286392865
constructor(cell, fillColor, strokeColor, strokeWidth) {
@@ -92915,7 +92917,7 @@ class GraphNodeLayoutHelper {
9291592917
else {
9291692918
this.layoutPoints.push(new Point(xPosition, yPosition));
9291792919
}
92918-
92920+
9291992921
return;
9292092922
}
9292192923

@@ -93152,12 +93154,7 @@ azdataQueryPlan.prototype.init = function (container, iconPaths, badgeIconPaths)
9315293154
let splitLabel = cell.value.label.split(/\r\n|\n/);
9315393155
let cellLabel = splitLabel.map(str => {
9315493156
let label = '';
93155-
if (str.length > 20) {
93156-
label += str.substring(0, 17) + '...';
93157-
}
93158-
else {
93159-
label += str;
93160-
}
93157+
label += str;
9316193158

9316293159
return label;
9316393160
});
@@ -93303,16 +93300,16 @@ azdataQueryPlan.prototype.placeGraphNodes = function () {
9330393300
var startY = (this.paddingY + 150) / 2;
9330493301

9330593302
// Recursively layout all nodes starting with root
93306-
this.SetNodePositionRecursive(this.queryPlanGraph, startX, startY);
93303+
this.setNodePositionRecursive(this.queryPlanGraph, startX, startY);
9330793304
}
9330893305

93309-
azdataQueryPlan.prototype.SetNodePositionRecursive = function (node, x, y) {
93306+
azdataQueryPlan.prototype.setNodePositionRecursive = function (node, x, y) {
9331093307

9331193308
// Recursively setting all the x positions in the graph.
9331293309
this.setNodeXPositionRecursive(node, x);
9331393310
var layoutHelper = new GraphNodeLayoutHelper();
9331493311
this.setNodeYPositionRecursive(node, layoutHelper, this.spacingY, y);
93315-
93312+
this.adjustGraphNodeHorizontalPositions(node);
9331693313
}
9331793314

9331893315
azdataQueryPlan.prototype.setNodeXPositionRecursive = function (node, x) {
@@ -93324,7 +93321,7 @@ azdataQueryPlan.prototype.setNodeXPositionRecursive = function (node, x) {
9332493321

9332593322
// Using a mxUtils function to determine how much space is needed for the label.
9332693323
// Cleaning the label string as mention in the mxGraph docs https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxUtils-js.html#mxUtils.getSizeForString
93327-
var cleanedLabel = node.label.replace(/\n/g, "<br>");
93324+
var cleanedLabel = node.label.replace(/\n|\r\n/g, "<br>");
9332893325

9332993326
// Assuming default stylings for
9333093327
var size = mxUtils.getSizeForString(cleanedLabel, mxConstants.DEFAULT_FONTSIZE,
@@ -93346,12 +93343,11 @@ azdataQueryPlan.prototype.setNodeXPositionRecursive = function (node, x) {
9334693343
// This will later help us in determining the y coordinates for them.
9334793344
node.maxChildrenXPosition = node.position.x;
9334893345
// Display each child node at the X position just computed
93349-
node.children.forEach(n => {
93350-
n.parent = node;
93351-
this.setNodeXPositionRecursive(n, x);
93352-
node.maxChildrenXPosition = Math.max(node.maxChildrenXPosition, n.maxChildrenXPosition);
93346+
node.children.forEach(childNode => {
93347+
childNode.parent = node;
93348+
this.setNodeXPositionRecursive(childNode, x);
93349+
node.maxChildrenXPosition = Math.max(node.maxChildrenXPosition, childNode.maxChildrenXPosition);
9335393350
});
93354-
9335593351
}
9335693352

9335793353
azdataQueryPlan.prototype.setNodeYPositionRecursive = function (node, layoutHelper, y) {
@@ -93372,6 +93368,65 @@ azdataQueryPlan.prototype.setNodeYPositionRecursive = function (node, layoutHelp
9337293368
layoutHelper.updateNodeLayout(leftPosition, yToUpdate);
9337393369
}
9337493370

93371+
azdataQueryPlan.prototype.adjustGraphNodeHorizontalPositions = function (node) {
93372+
let levelsTable = this.getNodesByHorizontalLevel(node);
93373+
93374+
Object.keys(levelsTable).map(key => {
93375+
for (let levelNodeIndex = 1; levelNodeIndex < levelsTable[key].length; ++levelNodeIndex) {
93376+
let previousNode = levelsTable[key][levelNodeIndex - 1];
93377+
let currentNode = levelsTable[key][levelNodeIndex]
93378+
93379+
let previousLabel = previousNode.label.split(/\r\n|\n/).filter(str => str.length > 20);
93380+
if (previousLabel.length !== 0) {
93381+
let distanceFromPreviousNode = currentNode.position.x - previousNode.position.x;
93382+
if (distanceFromPreviousNode <= STANDARD_NODE_DISTANCE) {
93383+
let shiftToRightAmount = IDEAL_LONG_LABEL_NODE_DISTANCE - distanceFromPreviousNode;
93384+
currentNode.position.x += shiftToRightAmount;
93385+
93386+
this.shiftParentAndChildNodePositionsHorizontally(currentNode.parent, shiftToRightAmount);
93387+
}
93388+
}
93389+
}
93390+
});
93391+
}
93392+
93393+
azdataQueryPlan.prototype.shiftParentAndChildNodePositionsHorizontally = function (parent, shiftAmount) {
93394+
let stack = [...parent.children];
93395+
93396+
while (stack.length !== 0) {
93397+
let currentNode = stack.pop();
93398+
let currentNodeParent = currentNode.parent;
93399+
if (currentNode.position.x - currentNodeParent.position.x < IDEAL_LONG_LABEL_NODE_DISTANCE) {
93400+
currentNode.position.x += shiftAmount;
93401+
}
93402+
93403+
for (let childIndex = 0; childIndex < currentNode.children.length; ++childIndex) {
93404+
stack.push(currentNode.children[childIndex]);
93405+
}
93406+
}
93407+
}
93408+
93409+
azdataQueryPlan.prototype.getNodesByHorizontalLevel = function (node) {
93410+
let table = {};
93411+
let stack = [node];
93412+
93413+
while (stack.length !== 0) {
93414+
let entry = stack.pop();
93415+
if (entry.position.y in table) {
93416+
table[entry.position.y].push(entry);
93417+
}
93418+
else {
93419+
table[entry.position.y] = [];
93420+
table[entry.position.y].push(entry);
93421+
}
93422+
93423+
for (let i = 0; i < entry.children.length; ++i) {
93424+
stack.push(entry.children[i]);
93425+
}
93426+
}
93427+
93428+
return table;
93429+
}
9337593430

9337693431
azdataQueryPlan.prototype.zoomIn = function () {
9337793432
if (this.graph.view.getScale() * this.graph.zoomFactor <= 2) {
@@ -93512,7 +93567,7 @@ azdataQueryPlan.prototype.redrawBadges = function () {
9351293567
* @param {*} strokeWidth thickness of the stroke
9351393568
*/
9351493569
azdataQueryPlan.prototype.drawPolygon = function (cell, fillColor, strokeColor, strokeWidth) {
93515-
if(!this.polygonModels){
93570+
if (!this.polygonModels) {
9351693571
this.polygonModels = [];
9351793572
}
9351893573
this.polygonModels.push({
@@ -93536,26 +93591,29 @@ azdataQueryPlan.prototype.removeDrawnPolygons = function () {
9353693591
}
9353793592

9353893593
azdataQueryPlan.prototype.renderPolygons = function () {
93539-
if(this.drawnPolygons?.length > 0){
93594+
if (this.drawnPolygons?.length > 0) {
9354093595
this.drawnPolygons.forEach(polygon => {
9354193596
polygon.destroy();
9354293597
});
9354393598
}
9354493599
this.drawnPolygons = [];
93545-
this.polygonModels.forEach(p => {
93546-
const points = this.getPolygonPerimeter(p.root);
93547-
const scale = this.graph.view.getScale();
93548-
var polygon = new mxPolygon(
93549-
points.map(point => new mxPoint(point.x * scale, point.y * scale)),
93550-
p.fillColor,
93551-
p.strokeColor,
93552-
p.strokeWidth
93553-
);
93554-
this.drawnPolygons.push(polygon);
93555-
polygon.init(this.graph.getView().getBackgroundPane());
93556-
polygon.isDashed = true;
93557-
polygon.redraw();
93558-
});
93600+
93601+
if (this.polygonModels) {
93602+
this.polygonModels.forEach(p => {
93603+
const points = this.getPolygonPerimeter(p.root);
93604+
const scale = this.graph.view.getScale();
93605+
var polygon = new mxPolygon(
93606+
points.map(point => new mxPoint(point.x * scale, point.y * scale)),
93607+
p.fillColor,
93608+
p.strokeColor,
93609+
p.strokeWidth
93610+
);
93611+
this.drawnPolygons.push(polygon);
93612+
polygon.init(this.graph.getView().getBackgroundPane());
93613+
polygon.isDashed = true;
93614+
polygon.redraw();
93615+
});
93616+
}
9355993617
}
9356093618

9356193619
/**
@@ -93566,8 +93624,10 @@ azdataQueryPlan.prototype.renderPolygons = function () {
9356693624
azdataQueryPlan.prototype.getPolygonPerimeter = function (cell) {
9356793625
let points = [];
9356893626
points = points.concat(this.getLeftSidePoints(cell));
93569-
points = points.concat(this.getBottomSidePoints(cell));
93570-
points = points.concat(this.getRightSidePoints(cell));
93627+
93628+
let rightSidePoints = this.getRightSidePoints(cell);
93629+
points = points.concat(this.getBottomSidePoints(cell, rightSidePoints[0].x));
93630+
points = points.concat(rightSidePoints);
9357193631

9357293632
return points;
9357393633
}
@@ -93584,7 +93644,7 @@ azdataQueryPlan.prototype.getLeftSidePoints = function (cell) {
9358493644
let points = [];
9358593645
let xPosition = cell.geometry.x - 15; // subtracting to push the x coordinate to the left.
9358693646
points.push({ x: xPosition, y: cell.geometry.y });
93587-
points.push({ x: xPosition, y: cell.geometry.y + NODE_HEIGHT })
93647+
points.push({ x: xPosition, y: cell.geometry.y + NODE_HEIGHT });
9358893648

9358993649
return points;
9359093650
}
@@ -93594,27 +93654,66 @@ azdataQueryPlan.prototype.getLeftSidePoints = function (cell) {
9359493654
* @param {*} cell The starting node where highlighting will begin.
9359593655
* @returns An array of points for the bottom side of the polygon.
9359693656
*/
93597-
azdataQueryPlan.prototype.getBottomSidePoints = function (cell) {
93657+
azdataQueryPlan.prototype.getBottomSidePoints = function (cell, polygonRightSideConstraint) {
9359893658
let points = [];
93599-
var stack = [cell];
93659+
let bottomSideLeafNodes = this.getBottomSideLeafNodes(cell, polygonRightSideConstraint);
93660+
93661+
for (let index = 0; index < bottomSideLeafNodes.length; ++index) {
93662+
let leafNode = bottomSideLeafNodes[index].value;
93663+
let leftOfLeafNode = leafNode;
93664+
93665+
// Finds the left most node directly to the left of the leaf node.
93666+
while (leftOfLeafNode.position.y === leftOfLeafNode.parent.position.y) {
93667+
leftOfLeafNode = leftOfLeafNode.parent;
93668+
}
93669+
93670+
if (points.length === 0) {
93671+
let parent = leftOfLeafNode.parent;
93672+
let auxiliaryPoint = { x: leftOfLeafNode.position.x - NODE_WIDTH, y: parent.position.y + NODE_HEIGHT };
93673+
points.push(auxiliaryPoint);
93674+
}
93675+
else if (points.length !== 0 && points[points.length - 1].y - NODE_HEIGHT !== leftOfLeafNode.position.y) {
93676+
let auxiliaryPoint = { x: leftOfLeafNode.position.x - NODE_WIDTH, y: points[points.length - 1].y };
93677+
points.push(auxiliaryPoint);
93678+
}
93679+
93680+
points.push({ x: leftOfLeafNode.position.x - NODE_WIDTH, y: leftOfLeafNode.position.y + NODE_HEIGHT });
93681+
93682+
if (leftOfLeafNode.position.x < leafNode.position.x) {
93683+
points.push({ x: leafNode.position.x + NODE_WIDTH, y: leafNode.position.y + NODE_HEIGHT});
93684+
}
93685+
}
93686+
93687+
return points;
93688+
}
93689+
93690+
azdataQueryPlan.prototype.getBottomSideLeafNodes = function (cell, polygonRightSideConstraint) {
93691+
let leafNodeTable = {};
93692+
let stack = [cell];
9360093693

9360193694
while (stack.length !== 0) {
9360293695
let entry = stack.pop();
93603-
points.push({ x: entry.geometry.x + NODE_HEIGHT, y: entry.geometry.y + NODE_WIDTH });
93604-
93605-
if (entry?.value?.children?.length > 0) {
93606-
let nextNode = this.graph.model.getCell(entry.value.children[entry.value.children.length - 1].id);
9360793696

93608-
if (entry.value.children.length > 1) {
93609-
let auxiliaryPoint = { x: entry.geometry.x + NODE_WIDTH, y: nextNode.geometry.y + NODE_HEIGHT };
93610-
points.push(auxiliaryPoint);
93697+
if (entry.value.children.length === 0 && entry.geometry.x <= polygonRightSideConstraint) {
93698+
if (entry.geometry.x in leafNodeTable) {
93699+
let previouslyCachedEntry = leafNodeTable[entry.geometry.x];
93700+
if (entry.geometry.y > previouslyCachedEntry.geometry.y) {
93701+
leafNodeTable[entry.geometry.x] = entry;
93702+
}
93703+
}
93704+
else {
93705+
leafNodeTable[entry.geometry.x] = entry;
9361193706
}
93707+
}
9361293708

93613-
stack.push(nextNode);
93709+
for (let nodeIndex = 0; nodeIndex < entry.value.children.length; ++nodeIndex) {
93710+
stack.push(this.graph.model.getCell(entry.value.children[nodeIndex].id));
9361493711
}
9361593712
}
9361693713

93617-
return points;
93714+
let leafNodes = Object.keys(leafNodeTable).map(key => leafNodeTable[key])
93715+
93716+
return leafNodes;
9361893717
}
9361993718

9362093719
/**
@@ -93629,8 +93728,12 @@ azdataQueryPlan.prototype.getRightSidePoints = function (cell) {
9362993728
for (let nodeIndex = 0; nodeIndex < leafNodes.length; ++nodeIndex) {
9363093729
let leafNode = leafNodes[nodeIndex];
9363193730

93632-
points.push({ x: leafNode.geometry.x + NODE_WIDTH, y: leafNode.geometry.y + NODE_HEIGHT });
93633-
points.push({ x: leafNode.geometry.x + NODE_WIDTH, y: leafNode.geometry.y });
93731+
let longestSubLabel = Math.max(...(leafNode.value.label.split(/\r\n|\n/).map(str => str.length)));
93732+
// These values to work best for drawing regions around labels of different lengths, so the label is always inside the polygon.
93733+
let additionalRightSideSpacing = longestSubLabel % 10 * 25;
93734+
93735+
points.push({ x: leafNode.geometry.x + NODE_WIDTH + additionalRightSideSpacing, y: leafNode.geometry.y + NODE_HEIGHT });
93736+
points.push({ x: leafNode.geometry.x + NODE_WIDTH + additionalRightSideSpacing, y: leafNode.geometry.y });
9363493737
}
9363593738

9363693739
return points;

0 commit comments

Comments
 (0)