@chbo297/infoflow 2026.3.17 → 2026.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/infoflow-req-parse.ts +56 -0
package/package.json
CHANGED
|
@@ -9,6 +9,55 @@ import { handlePrivateChatMessage, handleGroupChatMessage } from "./bot.js";
|
|
|
9
9
|
import type { ResolvedInfoflowAccount } from "./channel.js";
|
|
10
10
|
import { getInfoflowParseLog, formatInfoflowError, logVerbose } from "./logging.js";
|
|
11
11
|
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Large-integer precision protection
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
// Infoflow message IDs (e.g. 1859713223686736431) exceed Number.MAX_SAFE_INTEGER (2^53-1).
|
|
17
|
+
// JSON.parse silently truncates these to imprecise values.
|
|
18
|
+
// We extract precise strings from raw JSON text via regex and patch the parsed object.
|
|
19
|
+
const ID_KEYS = ["messageid", "msgid", "MsgId", "msgkey"] as const;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Patches large integer ID fields in `obj` with precise string values
|
|
23
|
+
* extracted from `rawText` via regex, bypassing JSON.parse precision loss.
|
|
24
|
+
* Only patches values with 16+ digits (smaller integers are safe).
|
|
25
|
+
*/
|
|
26
|
+
function patchPreciseIds(rawText: string, obj: Record<string, unknown>): void {
|
|
27
|
+
for (const key of ID_KEYS) {
|
|
28
|
+
const re = new RegExp(`"${key}"\\s*:\\s*(\\d{16,})`, "g");
|
|
29
|
+
const preciseValues: string[] = [];
|
|
30
|
+
let m;
|
|
31
|
+
while ((m = re.exec(rawText)) !== null) {
|
|
32
|
+
preciseValues.push(m[1]);
|
|
33
|
+
}
|
|
34
|
+
if (preciseValues.length > 0) {
|
|
35
|
+
patchField(obj, key, preciseValues, 0);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Recursively walks `obj` and replaces numeric fields named `key` with precise strings (in order). */
|
|
41
|
+
function patchField(obj: unknown, key: string, values: string[], idx: number): number {
|
|
42
|
+
if (obj == null || typeof obj !== "object") return idx;
|
|
43
|
+
if (Array.isArray(obj)) {
|
|
44
|
+
for (const item of obj) {
|
|
45
|
+
idx = patchField(item, key, values, idx);
|
|
46
|
+
}
|
|
47
|
+
return idx;
|
|
48
|
+
}
|
|
49
|
+
const rec = obj as Record<string, unknown>;
|
|
50
|
+
if (key in rec && typeof rec[key] === "number" && idx < values.length) {
|
|
51
|
+
rec[key] = values[idx++];
|
|
52
|
+
}
|
|
53
|
+
for (const v of Object.values(rec)) {
|
|
54
|
+
if (v != null && typeof v === "object") {
|
|
55
|
+
idx = patchField(v, key, values, idx);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return idx;
|
|
59
|
+
}
|
|
60
|
+
|
|
12
61
|
const DEDUP_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
13
62
|
const DEDUP_MAX_SIZE = 1000;
|
|
14
63
|
|
|
@@ -309,10 +358,13 @@ function tryDecryptAndDispatch(params: DecryptDispatchParams): ParseResult {
|
|
|
309
358
|
continue; // Try next account
|
|
310
359
|
}
|
|
311
360
|
|
|
361
|
+
logVerbose(`[infoflow] ${chatType}: decryptedContent=(${decryptedContent})`);
|
|
362
|
+
|
|
312
363
|
// Parse as JSON first, then try fallback parser (XML for private)
|
|
313
364
|
let msgData: Record<string, unknown> | null = null;
|
|
314
365
|
try {
|
|
315
366
|
msgData = JSON.parse(decryptedContent) as Record<string, unknown>;
|
|
367
|
+
patchPreciseIds(decryptedContent, msgData);
|
|
316
368
|
} catch {
|
|
317
369
|
if (fallbackParser) {
|
|
318
370
|
msgData = fallbackParser(decryptedContent);
|
|
@@ -357,6 +409,7 @@ function handlePrivateMessage(messageJsonStr: string, targets: WebhookTarget[]):
|
|
|
357
409
|
let messageJson: Record<string, unknown>;
|
|
358
410
|
try {
|
|
359
411
|
messageJson = JSON.parse(messageJsonStr) as Record<string, unknown>;
|
|
412
|
+
patchPreciseIds(messageJsonStr, messageJson);
|
|
360
413
|
} catch {
|
|
361
414
|
getInfoflowParseLog().error(`[infoflow] private: invalid messageJson`);
|
|
362
415
|
return { handled: true, statusCode: 400, body: "invalid messageJson" };
|
|
@@ -430,3 +483,6 @@ export const _parseXmlMessage = parseXmlMessage;
|
|
|
430
483
|
export function _resetMessageCache(): void {
|
|
431
484
|
messageCache.clear();
|
|
432
485
|
}
|
|
486
|
+
|
|
487
|
+
/** @internal */
|
|
488
|
+
export const _patchPreciseIds = patchPreciseIds;
|