Skip to content

fix(libsidecar): write one group member GUID per slot - #84

Open
3kynox wants to merge 1 commit into
walkline:masterfrom
3kynox:fix/libsidecar-group-members-offset
Open

fix(libsidecar): write one group member GUID per slot#84
3kynox wants to merge 1 commit into
walkline:masterfrom
3kynox:fix/libsidecar-group-members-offset

Conversation

@3kynox

@3kynox 3kynox commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Reported by @sudlud while cross-checking this repository against the AzerothCore clustering PR: OnGroupCreated delivers garbage member GUIDs for groups of three or more, and the world server then materializes phantom members out of character cache misses.

The cause is in GroupCreated: the destination pointer is reassigned on every iteration and then advanced by i elements, so it walks a cumulative sum instead of a fixed stride.

Members Slots written Valid slots
2 0, 1 0-1
3 0, 1, 3 0-2
4 0, 1, 3, 6 0-3
5 0, 1, 3, 6, 10 0-4

Two consequences, the second one worth flagging beyond the original report:

  • slot 2 and beyond are never written, so the world server reads whatever malloc returned;
  • the later writes land past the end of the allocated array — 48 bytes past it for a five member group, and it grows quadratically with the group size.

Parties of two are unaffected, which is probably why it went unnoticed.

The rest of the file already indexes from the base pointer (battleground-api.go, petition-api.go, events-guilds.go) or advances by exactly one element (lib.go), so this is an isolated slip rather than a convention.

Fix

The write loop moves into a small writeMemberGUIDs helper that takes an unsafe.Slice over the allocated block and indexes it, which makes an out of range write impossible by construction and lets the logic be tested.

Test

TestWriteMemberGUIDs fills groups of 1, 2, 3 and 5 members into a buffer whose trailing guard slots are poisoned, then checks that every member landed in its own slot and that no guard was touched. Against the previous implementation it fails on the three member case (slot 2 holds 57005, expected 102), and it passes with this change.

The native C++ sidecar is not affected — it passes std::vector::data() — so only deployments running the Go sidecar see the bug.

The destination pointer was reassigned on every iteration and then advanced
by i elements, so the writes landed at 0, 1, 3, 6, 10... instead of 0, 1, 2,
3, 4. A group of three or more members shipped an uninitialized slot to the
world server, and the last writes went past the end of the allocated array.

Reported by sudlud while cross-checking ToCloud9 against the clustering PR.

Index the array instead of walking a pointer, and cover it with a test that
poisons guard slots to catch a write past the end.
Copilot AI review requested due to automatic review settings July 26, 2026 19:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants