From 320b197d3f38fe916c484181852e43624a4e8ff7 Mon Sep 17 00:00:00 2001 From: GtxFury <32810165+GtxFury@users.noreply.github.com> Date: Wed, 22 Apr 2026 22:56:46 +0800 Subject: [PATCH 1/4] Update README Added promotional images and links to README. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 2a60eb7..0a2e95a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ + + + 友情推荐 + 友情推荐 From 4c6d709a4722b8e56127ac3cb768c5e6037021a7 Mon Sep 17 00:00:00 2001 From: GtxFury <32810165+GtxFury@users.noreply.github.com> Date: Wed, 22 Apr 2026 22:57:35 +0800 Subject: [PATCH 2/4] Update Updated image source link for the first screenshot in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a2e95a..87cf2df 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ - 友情推荐 + 友情推荐 友情推荐 From 4000058e1d00e94cea571fcd1b7ebc90a3754243 Mon Sep 17 00:00:00 2001 From: GtxFury <32810165+GtxFury@users.noreply.github.com> Date: Thu, 23 Apr 2026 08:01:15 +0800 Subject: [PATCH 3/4] Update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 87cf2df..5206019 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ - 友情推荐 + 友情推荐 友情推荐 From 72c145e6f8ce5a97ccf5a0df300a273bc80f8c2e Mon Sep 17 00:00:00 2001 From: lunping98 Date: Wed, 24 Jun 2026 10:17:52 +0800 Subject: [PATCH 4/4] fix: bound captured mihomo output --- .../main-process/bounded-output-buffer.js | 22 ++++++++++++++ electron/main-process/mihomo-service.js | 5 ++-- package.json | 1 + test/bounded-output-buffer.test.js | 30 +++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 electron/main-process/bounded-output-buffer.js create mode 100644 test/bounded-output-buffer.test.js diff --git a/electron/main-process/bounded-output-buffer.js b/electron/main-process/bounded-output-buffer.js new file mode 100644 index 0000000..ab98de2 --- /dev/null +++ b/electron/main-process/bounded-output-buffer.js @@ -0,0 +1,22 @@ +const DEFAULT_MAX_OUTPUT_CHARS = 256 * 1024; + +function appendBoundedOutput(currentOutput, nextChunk, maxChars = DEFAULT_MAX_OUTPUT_CHARS) { + if (!Number.isFinite(maxChars) || maxChars <= 0) { + return ''; + } + + const current = typeof currentOutput === 'string' ? currentOutput : ''; + const next = Buffer.isBuffer(nextChunk) ? nextChunk.toString() : String(nextChunk ?? ''); + const combined = current + next; + + if (combined.length <= maxChars) { + return combined; + } + + return combined.slice(-maxChars); +} + +module.exports = { + DEFAULT_MAX_OUTPUT_CHARS, + appendBoundedOutput, +}; diff --git a/electron/main-process/mihomo-service.js b/electron/main-process/mihomo-service.js index 41bdf75..133b06d 100644 --- a/electron/main-process/mihomo-service.js +++ b/electron/main-process/mihomo-service.js @@ -17,6 +17,7 @@ module.exports = function initMihomoService(context) { const { applyOverrides } = require('../ipc-handlers/overrides'); const { getMihomoControllerParam, cleanupSocketFile } = require('../utils/socket-path'); const { RunningMode, setRunningMode, getRunningMode, isServiceMode, getSocketPath, getServiceSocketPath, getSidecarSocketPath } = require('../utils/running-mode'); + const { appendBoundedOutput } = require('./bounded-output-buffer'); console.log('[mihomo-service] applyOverrides函数已导入:', typeof applyOverrides); async function waitForProcessExit(proc, timeoutMs = 5000) { @@ -1200,7 +1201,7 @@ module.exports = function initMihomoService(context) { spawnedProcess.stdout.on('data', (data) => { const logContent = data.toString(); - stdoutOutput += logContent; // 收集 stdout 输出 + stdoutOutput = appendBoundedOutput(stdoutOutput, logContent); // 收集最近的 stdout 输出 console.log(`mihomo stdout: ${logContent}`); // 检测 TUN 启动失败 @@ -1258,7 +1259,7 @@ module.exports = function initMihomoService(context) { spawnedProcess.stderr.on('data', (data) => { const errorText = data.toString(); - stderrOutput += errorText; // 收集 stderr 输出 + stderrOutput = appendBoundedOutput(stderrOutput, errorText); // 收集最近的 stderr 输出 console.error(`mihomo stderr: ${errorText}`); safeSend('mihomo-error', errorText); process.stderr.write(data); diff --git a/package.json b/package.json index 4301bb5..694776d 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "build": "next build", "start": "next start", "lint": "next lint", + "test": "node --test", "rebuild:native": "electron-rebuild -f -w better-sqlite3", "postinstall": "electron-builder install-app-deps", "prepare": "node scripts/prepare.mjs", diff --git a/test/bounded-output-buffer.test.js b/test/bounded-output-buffer.test.js new file mode 100644 index 0000000..7511ab6 --- /dev/null +++ b/test/bounded-output-buffer.test.js @@ -0,0 +1,30 @@ +const assert = require('node:assert/strict'); +const test = require('node:test'); + +const { + DEFAULT_MAX_OUTPUT_CHARS, + appendBoundedOutput, +} = require('../electron/main-process/bounded-output-buffer'); + +test('appendBoundedOutput keeps short output unchanged', () => { + const output = appendBoundedOutput('hello', '\nworld', 32); + + assert.equal(output, 'hello\nworld'); +}); + +test('appendBoundedOutput caps retained output and keeps newest content', () => { + let output = ''; + + output = appendBoundedOutput(output, '12345', 10); + output = appendBoundedOutput(output, '67890', 10); + output = appendBoundedOutput(output, 'abcde', 10); + + assert.equal(output, '67890abcde'); + assert.equal(output.length, 10); +}); + +test('appendBoundedOutput truncates a single large chunk to the configured limit', () => { + const output = appendBoundedOutput('', 'x'.repeat(DEFAULT_MAX_OUTPUT_CHARS + 5), 16); + + assert.equal(output, 'x'.repeat(16)); +});