Skip to content

Commit 3d9d8a8

Browse files
committed
add memory optimization and UTF-8 safety
1 parent feea304 commit 3d9d8a8

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

src/graph-builder/graph-core/5-load-save.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ class GraphLoadSave extends GraphUndoRedo {
4343
}
4444
if (format === 'PNG-EMBEDDED') {
4545
const b64Uri = this.cy.png({ full: true });
46-
const b64Data = b64Uri.split(',')[1];
47-
const buffer = new Uint8Array(window.atob(b64Data).split('').map((c) => c.charCodeAt(0)));
46+
const binaryString = window.atob(b64Uri.split(',')[1]);
47+
const buffer = new Uint8Array(binaryString.length);
48+
for (let i = 0; i < binaryString.length; i += 1) {
49+
buffer[i] = binaryString.charCodeAt(i);
50+
}
4851
const chunks = extractChunks(buffer);
4952
chunks.splice(-1, 0, textChunk.encode('graphml', this.getGraphML()));
5053
const newBuffer = new Uint8Array(encodeChunks(chunks));
@@ -54,8 +57,11 @@ class GraphLoadSave extends GraphUndoRedo {
5457
}
5558
if (format === 'JPG-EMBEDDED') {
5659
const b64Uri = this.cy.jpg({ full: true });
57-
const b64Data = b64Uri.split(',')[1];
58-
const buffer = new Uint8Array(window.atob(b64Data).split('').map((c) => c.charCodeAt(0)));
60+
const binaryString = window.atob(b64Uri.split(',')[1]);
61+
const buffer = new Uint8Array(binaryString.length);
62+
for (let i = 0; i < binaryString.length; i += 1) {
63+
buffer[i] = binaryString.charCodeAt(i);
64+
}
5965
const graphMLStr = this.getGraphML();
6066
const graphMLBytes = new TextEncoder().encode(graphMLStr);
6167

src/toolbarActions/toolbarFunctions.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,18 +223,30 @@ const readFile = async (state, setState, file, fileHandle) => {
223223
try {
224224
const buffer = new Uint8Array(x.target.result);
225225
let pos = 2; // skip SOI
226-
let graphMLData = '';
226+
const comSegments = [];
227227
while (pos < buffer.length) {
228228
if (buffer[pos] !== 0xFF) break;
229229
const marker = buffer[pos + 1];
230230
if (marker === 0xDA) break; // SOS - Start of Scan
231231
const len = (buffer[pos + 2] * 256) + buffer[pos + 3];
232232
if (marker === 0xFE) { // COM Comment segment
233-
graphMLData += new TextDecoder().decode(buffer.slice(pos + 4, pos + 2 + len));
233+
comSegments.push(buffer.slice(pos + 4, pos + 2 + len));
234234
}
235235
pos += 2 + len;
236236
}
237237

238+
let graphMLData = '';
239+
if (comSegments.length > 0) {
240+
const totalLength = comSegments.reduce((sum, seg) => sum + seg.length, 0);
241+
const allBytes = new Uint8Array(totalLength);
242+
let offset = 0;
243+
for (let i = 0; i < comSegments.length; i += 1) {
244+
allBytes.set(comSegments[i], offset);
245+
offset += comSegments[i].length;
246+
}
247+
graphMLData = new TextDecoder().decode(allBytes);
248+
}
249+
238250
if (graphMLData) {
239251
parser(graphMLData).then(({ authorName }) => {
240252
setState({

0 commit comments

Comments
 (0)