fix: accept commented Baileys hotfix variant

This commit is contained in:
Frank Yang
2026-04-14 15:04:42 +08:00
parent 762fdfb1b3
commit 7ca5c8ee5c
2 changed files with 70 additions and 11 deletions

View File

@@ -66,6 +66,12 @@ const BAILEYS_MEDIA_HOTFIX_SEQUENTIAL_REPLACEMENT = [
" await originalFinishPromise;",
" logger?.debug('encrypted data successfully');",
].join("\n");
const BAILEYS_MEDIA_HOTFIX_FINISH_PROMISES_RE =
/const\s+encFinishPromise\s*=\s*once\(encFileWriteStream,\s*'finish'\);\s*\n[\s\S]*const\s+originalFinishPromise\s*=\s*originalFileStream\s*\?\s*once\(originalFileStream,\s*'finish'\)\s*:\s*Promise\.resolve\(\);/u;
const BAILEYS_MEDIA_HOTFIX_PROMISE_ALL_RE =
/await\s+Promise\.all\(\[\s*encFinishPromise\s*,\s*originalFinishPromise\s*\]\);/u;
const BAILEYS_MEDIA_HOTFIX_SEQUENTIAL_AWAITS_RE =
/await\s+encFinishPromise;\s*(?:\/\/[^\n]*\n|\s)*await\s+originalFinishPromise;/u;
const BAILEYS_MEDIA_DISPATCHER_NEEDLE = [
" const response = await fetch(url, {",
" dispatcher: fetchAgent,",
@@ -283,7 +289,10 @@ export function applyBaileysEncryptedStreamFinishHotfix(params = {}) {
const encryptedStreamAlreadyPatched =
patchedText.includes(BAILEYS_MEDIA_HOTFIX_REPLACEMENT) ||
patchedText.includes(BAILEYS_MEDIA_HOTFIX_SEQUENTIAL_REPLACEMENT);
patchedText.includes(BAILEYS_MEDIA_HOTFIX_SEQUENTIAL_REPLACEMENT) ||
(BAILEYS_MEDIA_HOTFIX_FINISH_PROMISES_RE.test(patchedText) &&
(BAILEYS_MEDIA_HOTFIX_PROMISE_ALL_RE.test(patchedText) ||
BAILEYS_MEDIA_HOTFIX_SEQUENTIAL_AWAITS_RE.test(patchedText)));
if (!encryptedStreamAlreadyPatched) {
if (!patchedText.includes(BAILEYS_MEDIA_HOTFIX_NEEDLE)) {

View File

@@ -67,8 +67,9 @@ function createBaileysMessagesMediaSource(params?: {
dispatcherPatched?: boolean;
encryptedStreamPatched?: boolean;
encryptedStreamPatchedSequentially?: boolean;
encryptedStreamPatchedSequentiallyWithComments?: boolean;
}) {
const encryptedLines = params?.encryptedStreamPatchedSequentially
const encryptedLines = params?.encryptedStreamPatchedSequentiallyWithComments
? [
" encFileWriteStream.write(mac);",
" const encFinishPromise = once(encFileWriteStream, 'finish');",
@@ -76,11 +77,14 @@ function createBaileysMessagesMediaSource(params?: {
" encFileWriteStream.end();",
" originalFileStream?.end?.();",
" stream.destroy();",
" // Wait for write streams to fully flush to disk before returning encFilePath.",
" // Without this await, the caller may open a read stream on the file before",
" // the OS has created it, causing a race-condition ENOENT crash.",
" await encFinishPromise;",
" await originalFinishPromise;",
" logger?.debug('encrypted data successfully');",
]
: params?.encryptedStreamPatched
: params?.encryptedStreamPatchedSequentially
? [
" encFileWriteStream.write(mac);",
" const encFinishPromise = once(encFileWriteStream, 'finish');",
@@ -88,16 +92,28 @@ function createBaileysMessagesMediaSource(params?: {
" encFileWriteStream.end();",
" originalFileStream?.end?.();",
" stream.destroy();",
" await Promise.all([encFinishPromise, originalFinishPromise]);",
" await encFinishPromise;",
" await originalFinishPromise;",
" logger?.debug('encrypted data successfully');",
]
: [
" encFileWriteStream.write(mac);",
" encFileWriteStream.end();",
" originalFileStream?.end?.();",
" stream.destroy();",
" logger?.debug('encrypted data successfully');",
];
: params?.encryptedStreamPatched
? [
" encFileWriteStream.write(mac);",
" const encFinishPromise = once(encFileWriteStream, 'finish');",
" const originalFinishPromise = originalFileStream ? once(originalFileStream, 'finish') : Promise.resolve();",
" encFileWriteStream.end();",
" originalFileStream?.end?.();",
" stream.destroy();",
" await Promise.all([encFinishPromise, originalFinishPromise]);",
" logger?.debug('encrypted data successfully');",
]
: [
" encFileWriteStream.write(mac);",
" encFileWriteStream.end();",
" originalFileStream?.end?.();",
" stream.destroy();",
" logger?.debug('encrypted data successfully');",
];
const dispatcherLines = params?.dispatcherPatched
? [
" const response = await fetch(url, {",
@@ -339,6 +355,40 @@ describe("stageBundledPluginRuntimeDeps", () => {
);
});
it("patches the Baileys dispatcher guard when sequential awaits include comments", async () => {
const repoRoot = makeRepoRoot(
"openclaw-stage-bundled-runtime-hotfix-dispatcher-sequential-comments-",
);
const targetPath = path.join(
repoRoot,
"node_modules",
"@whiskeysockets",
"baileys",
"lib",
"Utils",
"messages-media.js",
);
writeRepoFile(
repoRoot,
"node_modules/@whiskeysockets/baileys/lib/Utils/messages-media.js",
createBaileysMessagesMediaSource({ encryptedStreamPatchedSequentiallyWithComments: true }),
);
const { applyBaileysEncryptedStreamFinishHotfix } = await loadPostinstallBundledPluginsModule();
const result = applyBaileysEncryptedStreamFinishHotfix({ packageRoot: repoRoot });
expect(result).toEqual({
applied: true,
reason: "patched",
targetPath,
});
expect(fs.readFileSync(targetPath, "utf8")).toContain(
"...(fetchAgent?.dispatch ? { dispatcher: fetchAgent } : {}),",
);
expect(fs.readFileSync(targetPath, "utf8")).toContain("await encFinishPromise;");
expect(fs.readFileSync(targetPath, "utf8")).toContain("await originalFinishPromise;");
});
it("patches the Baileys dispatcher guard when the flush hotfix uses sequential awaits", async () => {
const repoRoot = makeRepoRoot("openclaw-stage-bundled-runtime-hotfix-dispatcher-sequential-");
const targetPath = path.join(