fix(critical): safeSend infinite recursion + queueMicrotask, plus 6 audit findings
This commit is contained in:
parent
ddf2710fc6
commit
6cd7498f70
@ -277,7 +277,12 @@ class ConfigStore {
|
||||
if (fs.existsSync(this.filePath)) {
|
||||
const existing = fs.readFileSync(this.filePath, 'utf-8');
|
||||
if (existing && existing.trim().length > 2) {
|
||||
fs.writeFileSync(backupPath, existing, 'utf-8');
|
||||
let isValid = false;
|
||||
try {
|
||||
const parsed = JSON.parse(existing);
|
||||
isValid = parsed && typeof parsed === 'object' && (parsed.hosters || parsed.hosterSettings || parsed.globalSettings);
|
||||
} catch {}
|
||||
if (isValid) fs.writeFileSync(backupPath, existing, 'utf-8');
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
@ -316,6 +316,7 @@ class UploadManager extends EventEmitter {
|
||||
|
||||
const DEDUP_CHUNK = 200;
|
||||
for (let i = 0; i < tasks.length; i += DEDUP_CHUNK) {
|
||||
if (signal.aborted) break;
|
||||
const end = Math.min(i + DEDUP_CHUNK, tasks.length);
|
||||
for (let j = i; j < end; j++) {
|
||||
const task = tasks[j];
|
||||
@ -334,6 +335,7 @@ class UploadManager extends EventEmitter {
|
||||
const SPAWN_CHUNK = 100;
|
||||
const promises = [];
|
||||
for (let i = 0; i < tasks.length; i += SPAWN_CHUNK) {
|
||||
if (signal.aborted) break;
|
||||
const end = Math.min(i + SPAWN_CHUNK, tasks.length);
|
||||
for (let j = i; j < end; j++) promises.push(this._runJob(tasks[j], results, signal));
|
||||
if (end < tasks.length) await new Promise(setImmediate);
|
||||
|
||||
@ -382,7 +382,7 @@ class VidmolyUploader {
|
||||
}
|
||||
}
|
||||
|
||||
if (best && (bestScore > 0 || newFiles.length === 1)) {
|
||||
if (best && bestScore > 0) {
|
||||
return this._buildUrlsFromCode(best.file_code);
|
||||
}
|
||||
}
|
||||
|
||||
5
main.js
5
main.js
@ -231,7 +231,7 @@ function rotLog(msg, ts) {
|
||||
function safeSend(channel, data) {
|
||||
if (!mainWindow || mainWindow.isDestroyed()) return false;
|
||||
try {
|
||||
safeSend(channel, data);
|
||||
mainWindow.webContents.send(channel, data);
|
||||
return true;
|
||||
} catch (err) {
|
||||
debugLog(`safeSend(${channel}) failed: ${err && err.message ? err.message : err}`);
|
||||
@ -1155,7 +1155,8 @@ app.on('before-quit', () => {
|
||||
if (remoteServer) { remoteServer.stop(); remoteServer = null; }
|
||||
destroyCaptureWindow();
|
||||
} catch {}
|
||||
destroyDropTargetWindow();
|
||||
try { destroyDropTargetWindow(); } catch {}
|
||||
try { if (tray && !tray.isDestroyed()) { tray.destroy(); tray = null; } } catch {}
|
||||
// Flush pending log buffers synchronously so no lines are lost.
|
||||
try {
|
||||
if (_debugLogBuffer.length) {
|
||||
|
||||
@ -2500,7 +2500,7 @@ function _computeQueueStats() {
|
||||
}
|
||||
|
||||
_queueStatsCache = { total, remaining, inProgress, done, errors, bytesRemaining, totalSize, remainingSize, inProgressBytes };
|
||||
queueMicrotask(() => { _queueStatsCache = null; });
|
||||
(typeof queueMicrotask === 'function' ? queueMicrotask : (fn) => Promise.resolve().then(fn))(() => { _queueStatsCache = null; });
|
||||
return _queueStatsCache;
|
||||
}
|
||||
|
||||
@ -3691,7 +3691,10 @@ async function deleteAccount(accountId) {
|
||||
// Fire-and-forget the persist. The earlier `await getConfig()` round-trip
|
||||
// was redundant (we already have the truth in memory) and was the main
|
||||
// source of perceived lag on add/delete.
|
||||
window.api.saveConfig({ hosters: config.hosters }).catch(() => {});
|
||||
window.api.saveConfig({ hosters: config.hosters }).catch((err) => {
|
||||
if (window.api && window.api.debugLog) window.api.debugLog(`deleteAccount saveConfig failed: ${err && err.message ? err.message : err}`);
|
||||
showCopyToast('Account-Löschung konnte nicht persistiert werden — bitte erneut versuchen.');
|
||||
});
|
||||
}
|
||||
|
||||
function readAccountCredsFromModal(authType) {
|
||||
@ -3897,6 +3900,15 @@ async function _commitAccount(ctx, creds, validatedStatus, validatedMessage) {
|
||||
const idx = config.hosters[ctx.hosterName].findIndex(a => a.id === accountId);
|
||||
if (idx >= 0) {
|
||||
config.hosters[ctx.hosterName][idx] = { ...config.hosters[ctx.hosterName][idx], ...creds };
|
||||
} else {
|
||||
_accountModalBusy = false;
|
||||
const _sb = document.getElementById('saveAccountBtn'); if (_sb) _sb.disabled = false;
|
||||
const _st = document.getElementById('accountModalStatus');
|
||||
if (_st) {
|
||||
_st.textContent = 'Account nicht mehr in der Config — wurde extern gelöscht. Modal schließen und neu anlegen.';
|
||||
_st.className = 'account-modal-status error';
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
accountId = `${ctx.hosterName}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
||||
@ -4844,4 +4856,15 @@ function updateStatsPanel() {
|
||||
}
|
||||
|
||||
// --- Start ---
|
||||
init();
|
||||
init().catch((err) => {
|
||||
try {
|
||||
if (window.api && window.api.debugLog) window.api.debugLog(`init failed: ${err && err.stack ? err.stack : err}`);
|
||||
const root = document.getElementById('app') || document.body;
|
||||
if (root) {
|
||||
const banner = document.createElement('div');
|
||||
banner.style.cssText = 'position:fixed;top:0;left:0;right:0;background:#5a1e1e;color:#fff;padding:8px;z-index:99999;font-family:sans-serif;font-size:13px';
|
||||
banner.textContent = 'Initialisierung fehlgeschlagen: ' + (err && err.message ? err.message : err) + ' — bitte Diagnose-Paket exportieren oder Programm neu starten.';
|
||||
root.appendChild(banner);
|
||||
}
|
||||
} catch {}
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user