From 9537c506b4538c9d1bb65b42303bfcdaa047da20 Mon Sep 17 00:00:00 2001 From: isherryforever Date: Mon, 7 Sep 2026 21:46:18 +0800 Subject: [PATCH] fix stream listpack decode bug Fix stream listpack decoding when an entry has a different number of fields than the master entry. The master field count was mutated, breaking subsequent samefields entries (ArrayIndexOutOfBoundsException / NumberFormatException). Fixes #124 Reproduce: XADD order_events * order_id 1001 status waiting amount 99 XADD order_events * order_id 1002 status waiting amount 50 XADD order_events * order_id 1003 status processing amount 80 # 4 fields -> differs from master -> corrupts field count XADD order_events * order_id 1004 status refunded amount 99 reason user_canceled # 3 fields -> samefields again -> crashes XADD order_events * order_id 1005 status done amount 88 XADD order_events * order_id 1006 status waiting amount 120 ./bin/rct -f mem -s /data/dump.rdb -o memory_1.csv --- .../redis/rdb/cli/ext/rct/MemoryRdbVisitor.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/moilioncircle/redis/rdb/cli/ext/rct/MemoryRdbVisitor.java b/src/main/java/com/moilioncircle/redis/rdb/cli/ext/rct/MemoryRdbVisitor.java index 59271d48..d5897c50 100644 --- a/src/main/java/com/moilioncircle/redis/rdb/cli/ext/rct/MemoryRdbVisitor.java +++ b/src/main/java/com/moilioncircle/redis/rdb/cli/ext/rct/MemoryRdbVisitor.java @@ -953,8 +953,8 @@ protected Event doApplyStreamListPacks(RedisInputStream in, int version, byte[] if (!delete) length++; } } else { - numFields = Integer.parseInt(Strings.toString(listPackEntry(listPack))); - for (int i = 0; i < numFields; i++) { + int entryFields = Integer.parseInt(Strings.toString(listPackEntry(listPack))); + for (int i = 0; i < entryFields; i++) { byte[] field = listPackEntry(listPack); byte[] value = listPackEntry(listPack); max = Math.max(max, calc.calcElement(value)); @@ -1048,8 +1048,8 @@ protected Event doApplyStreamListPacks2(RedisInputStream in, int version, byte[] if (!delete) length++; } } else { - numFields = Integer.parseInt(Strings.toString(listPackEntry(listPack))); - for (int i = 0; i < numFields; i++) { + int entryFields = Integer.parseInt(Strings.toString(listPackEntry(listPack))); + for (int i = 0; i < entryFields; i++) { byte[] field = listPackEntry(listPack); byte[] value = listPackEntry(listPack); max = Math.max(max, calc.calcElement(value)); @@ -1149,8 +1149,8 @@ protected Event doApplyStreamListPacks3(RedisInputStream in, int version, byte[] if (!delete) length++; } } else { - numFields = Integer.parseInt(Strings.toString(listPackEntry(listPack))); - for (int i = 0; i < numFields; i++) { + int entryFields = Integer.parseInt(Strings.toString(listPackEntry(listPack))); + for (int i = 0; i < entryFields; i++) { byte[] field = listPackEntry(listPack); byte[] value = listPackEntry(listPack); max = Math.max(max, calc.calcElement(value));