# ArgusCore Fix Backlog Tracks the incremental security/stability/correctness/blizzlike maintenance pass. One fix per entry. See repo root workflow conventions for process rules. Legend: `[ ]` open · `[WIP]` in progress · `[DONE]` shipped --- ## P0 — Security / Corruption ### [WIP] Core/Player - Vendor purchase quantity desync (validate-vs-deliver truncation) **Subsystem:** Entities/Player, item vendor purchase **Problem:** `Player::BuyItemFromVendorSlot(..., uint32 count, ...)` validates stock limits, gold price, and extended-cost reagent/currency ownership against the full client-supplied `count` (an `int32` read directly off `CMSG_BUY_ITEM`'s `Quantity` field, widened to `uint32`). It then forwards `count` into `Player::_StoreOrEquipNewItem(..., uint8 count, ...)`, which silently narrows it to `count % 256`. Actual item delivery, reagent/currency consumption (`DestroyItemCount`/`RemoveCurrency`), and vendor stock decrement (`UpdateVendorItemCurrentCount`) all use the truncated value, while the "can you afford/own this" checks earlier used the untruncated value. A single crafted packet with `Quantity > 255` desyncs what was validated from what actually executes — a client-triggerable economic integrity fault. **Files:** `src/server/game/Entities/Player/Player.cpp` (`BuyItemFromVendorSlot`, `_StoreOrEquipNewItem`), `src/server/game/Handlers/ItemHandler.cpp` (`HandleBuyItemOpcode`) **Reference:** None directly ported; DestinyCore keeps `count` as `uint8` end-to-end (no widening, so no desync there). ArgusCore widened the outer function to `uint32` without updating the inner one. **Fix:** Clamp `count` to `uint8` range immediately after the existing `if (count < 1) count = 1;` cheat guard in `BuyItemFromVendorSlot`, before any validation runs, so every downstream check validates the exact quantity that will be charged and delivered. **Test:** See commit / manual test instructions below. --- ## P1 — Stability ### [ ] Core/Unit - TriggerAuraHeartbeat iterator invalidation **Subsystem:** Entities/Unit, Spells/Auras **Problem:** `Unit::TriggerAuraHeartbeat()` (`Unit.cpp:513-519`) iterates `m_appliedAuras` (a `std::multimap`) with a plain range-based `for` while calling `Aura::Heartbeat()`, which invokes arbitrary `AuraScript::OnHeartbeat` hooks. If a heartbeat hook removes the aura currently being visited (a normal aura-scripting pattern — "cancel self if condition no longer met"), `Unit::_UnapplyAura` erases that exact map node mid-loop, which is undefined behavior for the range-for's hidden iterator. **Files:** `src/server/game/Entities/Unit/Unit.cpp` **Reference:** Not present in DestinyCore (the heartbeat-aura mechanic is Legion-specific). Fix is precedented in-tree: `Unit::AtEnterCombat()` / `Unit::AtExitCombat()` (same file, ~line 8774) invoke the same class of arbitrary aura-script hook over the same container using an erase-safe idiom (capture the pointer, advance the iterator, *then* invoke the hook). **Fix:** Convert `TriggerAuraHeartbeat`'s loop to the same erase-safe idiom already used by `AtEnterCombat`/`AtExitCombat`. **Status:** Not started — next in queue after the vendor purchase fix. ### [ ] Core/Vehicle - Null seat dereference in VehicleHandler **Subsystem:** Handlers/VehicleHandler, Entities/Vehicle **Problem:** `HandleRequestVehiclePrevSeat`, `HandleRequestVehicleNextSeat`, `HandleMoveChangeVehicleSeats`, and `HandleRequestVehicleSwitchSeat` (`VehicleHandler.cpp:45-113`) call `Vehicle::GetSeatForPassenger()`, which is documented to return null if the passenger isn't currently seated, and dereference the result without a null check (contrast `CombatHandler.cpp:51-52`, which at least `ASSERT`s). A rapid double-send of a vehicle-seat opcode during a seat-change race window is a plausible client-triggerable null deref. **Files:** `src/server/game/Handlers/VehicleHandler.cpp` **Reference:** Same missing check exists in DestinyCore — inherited from upstream TrinityCore, not ArgusCore-specific. Lower priority than the heartbeat bug since it's long-standing and shared across forks, but still a live crash bug. **Status:** Not started. ### [ ] Core/Loot - Unguarded division in HandleLootMoneyOpcode **Subsystem:** Handlers/LootHandler **Problem:** `uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size()));` (`LootHandler.cpp:~168`) has no guard against `playersNear` being empty. In normal play the looter is always included, so this is low-exploitability today, but it's an unguarded integer division on a client-triggerable path (`CMSG_LOOT_MONEY`). **Files:** `src/server/game/Handlers/LootHandler.cpp` **Reference:** Same pattern exists in DestinyCore; not ArgusCore-specific. **Status:** Not started — low priority, defensive-only. --- ## P2 — Core Correctness ### [ ] Core/Bank - Slot/PackSlot argument order inconsistency **Subsystem:** Handlers/BankHandler **Problem:** `HandleAutoBankReagentOpcode` calls `GetItemByPos(autoBankReagent.PackSlot, autoBankReagent.Slot)` while `HandleAutoStoreBankReagentOpcode` calls `GetItemByPos(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot)` — reversed argument order relative to its sibling. Each packet's `Read()` implementation reads the two fields in different wire order, so this may be self-consistent and not an actual bug — needs verification against a real client packet capture before touching it. **Files:** `src/server/game/Handlers/BankHandler.cpp` **Status:** Needs verification, not confirmed as a bug. Low priority. --- ## P3 — Blizzlike Gameplay (Not populated by this pass — see `ROADMAP.md` / `plans/00-arguscore-analysis-and-roadmap.md` for the active class-spell-porting and content workstreams, which are tracked separately from this security/stability backlog.) --- ## P4 — Performance / Cleanup (Not populated by this pass.) --- ## Notes on scope This backlog is deliberately shallow on first pass — it reflects two targeted, read-only audits (item/gold/trade exploit surface; crash/stability surface) rather than an exhaustive line-by-line review. Areas checked and found solidly guarded during this pass (not re-audited unless something changes nearby): `TradeHandler`, `MailHandler` (including mail money/COD overflow guards), `AuctionHouseHandler`, `GuildHandler`/`Guild.cpp` bank-item moves, `VoidStorageHandler`, movement/teleport coordinate validation (`MovementHandler.cpp`, `ValidateMovementInfo`), `Spell.cpp`/ `SpellEffects.cpp` target-pointer handling, `LootHandler.cpp` target/master-loot lookups, `Group.cpp` aura/member iteration.