From 8c376787a1c20c65b3fce77cdc65d6408e82a8ca Mon Sep 17 00:00:00 2001 From: Avinash Kumar Deepak Date: Fri, 27 Mar 2026 13:02:57 +0530 Subject: [PATCH] fix: harden invalid graphml import handling --- src/graph-builder/graph-core/5-load-save.js | 2 ++ src/graph-builder/graphml/parser/index.js | 30 +++++++++++++-------- src/toolbarActions/toolbarFunctions.js | 2 ++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/graph-builder/graph-core/5-load-save.js b/src/graph-builder/graph-core/5-load-save.js index a042ce9..da74be7 100644 --- a/src/graph-builder/graph-core/5-load-save.js +++ b/src/graph-builder/graph-core/5-load-save.js @@ -231,6 +231,8 @@ class GraphLoadSave extends GraphUndoRedo { localStorageManager.save(this.id, graphObject); this.loadGraphFromLocalStorage(); this.lastSavedActionIndex = this.curActionIndex; + }).catch(() => { + toast.error('Invalid GraphML file.'); }); } diff --git a/src/graph-builder/graphml/parser/index.js b/src/graph-builder/graphml/parser/index.js index 7597df0..d4f0018 100644 --- a/src/graph-builder/graphml/parser/index.js +++ b/src/graph-builder/graphml/parser/index.js @@ -4,18 +4,26 @@ import { parseNode, parseEdge, parseDetails, parseActionHistory, } from './parseProperties'; -const parser = (graphMlCnt) => new Promise((resolve) => { +const parser = (graphMlCnt) => new Promise((resolve, reject) => { new xml2js.Parser().parseString(graphMlCnt, (err, grahMLObj) => { - const grahML = new PropFromArr(grahMLObj); - const nodes = grahML.parseProps('graphml.graph.node', 1).map(parseNode); - const edges = grahML.parseProps('graphml.graph.edge', 1).map(parseEdge); - const { - id, projectName, serverID, authorName, - } = parseDetails(grahML); - const actionHistory = parseActionHistory(grahML); - resolve({ - id, projectName, edges, nodes, actionHistory, serverID, authorName, - }); + if (err || !grahMLObj) { + reject(err || new Error('Invalid GraphML file.')); + return; + } + try { + const grahML = new PropFromArr(grahMLObj); + const nodes = grahML.parseProps('graphml.graph.node', 1).map(parseNode); + const edges = grahML.parseProps('graphml.graph.edge', 1).map(parseEdge); + const { + id, projectName, serverID, authorName, + } = parseDetails(grahML); + const actionHistory = parseActionHistory(grahML); + resolve({ + id, projectName, edges, nodes, actionHistory, serverID, authorName, + }); + } catch { + reject(new Error('Invalid GraphML file.')); + } }); }); export default parser; diff --git a/src/toolbarActions/toolbarFunctions.js b/src/toolbarActions/toolbarFunctions.js index 5093ec2..9dda574 100644 --- a/src/toolbarActions/toolbarFunctions.js +++ b/src/toolbarActions/toolbarFunctions.js @@ -160,6 +160,8 @@ const readFile = async (state, setState, file, fileHandle) => { projectName, graphML: x.target.result, fileHandle, fileName: file.name, authorName, }, }); + }).catch(() => { + toast.error('Invalid GraphML file.'); }); }; if (fileHandle) fr.readAsText(await fileHandle.getFile());