fix: marked兼容、保存竞态、关闭死锁、XSS防护、行号虚拟化、CSP加固

This commit is contained in:
thzxx
2026-05-18 17:23:26 +08:00
parent 320980030e
commit 1a5ec08728
3 changed files with 188 additions and 22 deletions
+27 -6
View File
@@ -8,6 +8,7 @@ let pendingFilePath = null;
let fileWatcher = null;
let closeTimeout = null;
let isClosing = false; // Prevent re-entrant close
let isSelfWriting = false; // Skip fs.watch events triggered by our own writes
// ===== Single Instance Lock =====
const gotTheLock = app.requestSingleInstanceLock();
@@ -81,7 +82,15 @@ function createWindow() {
isClosing = true;
e.preventDefault();
try {
mainWindow.webContents.send('window:confirmClose');
// 检查 webContents 是否仍可用
if (!mainWindow.webContents.isDestroyed()) {
mainWindow.webContents.send('window:confirmClose');
} else {
// 渲染进程已销毁,直接关闭
mainWindow.removeAllListeners('close');
mainWindow.close();
return;
}
} catch (err) {
mainWindow.removeAllListeners('close');
mainWindow.close();
@@ -89,6 +98,7 @@ function createWindow() {
}
// 5s safety timeout in case renderer is unresponsive
closeTimeout = setTimeout(() => {
closeTimeout = null;
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.removeAllListeners('close');
mainWindow.close();
@@ -109,6 +119,8 @@ function startWatching(filePath) {
try {
fileWatcher = fs.watch(filePath, (eventType) => {
if (eventType === 'change' && mainWindow && !mainWindow.isDestroyed()) {
// 跳过自身写入触发的 change 事件
if (isSelfWriting) return;
mainWindow.webContents.send('file:externallyModified', filePath);
}
});
@@ -174,13 +186,22 @@ function switchActiveFile(filePath) {
function saveToPath(filePath, content) {
stopWatching();
try {
isSelfWriting = true;
fs.writeFileSync(filePath, content, 'utf-8');
// 写入后短暂延迟再恢复监听,让 fs.watch 错过自身写入的事件
isSelfWriting = false;
} catch (err) {
isSelfWriting = false;
startWatching(activeFilePath); // Restore watcher on failure
return { success: false, error: err.message };
}
activeFilePath = filePath;
startWatching(filePath);
// 延迟 300ms 重新监听,确保文件系统的 change 事件已过期
setTimeout(() => {
if (activeFilePath === filePath) {
startWatching(filePath);
}
}, 300);
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.setTitle(`MarkLite - ${path.basename(filePath)}`);
}
@@ -283,11 +304,11 @@ ipcMain.handle('window:forceClose', () => {
clearTimeout(closeTimeout);
closeTimeout = null;
}
// 窗口已销毁则无需操作(超时兜底可能已经关闭了窗口)
if (!mainWindow || mainWindow.isDestroyed()) return;
stopWatching();
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.removeAllListeners('close');
mainWindow.close();
}
mainWindow.removeAllListeners('close');
mainWindow.close();
});
ipcMain.handle('window:cancelClose', () => {