-
Type:
Bug
-
Resolution: Fixed
-
Priority:
Minor
-
None
-
Affects Version/s: None
-
Environment:
n/a (This issue was identified through static analysis of the Bukkit source code
(branch: Master), not via a running server instance)
-
Not tested on runtime but identified via source code analysis (master branch)
-
Yes
The problem is that the private StandardMessenger#removeFromOutgoing method incorrectly removes entries from the wrong map when cleaning up. The location is in "src\main\java\org\bukkit\plugin\messaging\StandardMessenger.java" on line 63.
StandardMessenger maintains two internal maps:
- outgoingByChannel (channel → plugins)
- outgoingByPlugin (plugin → channels)
These structures are expected to remain consistent mirrors of each other.
The bug was validated with helper methods and two JUnit tests. The relevant source code and tests are pasted in the files. For a quick summary, the first test prevents premature removal from outgoingByChannel. It registers one channel (test:channel) for two seperate plugins (plugin1 and plugin2). When we unregister test:channel from plugin1, it incorrectly removes test:channel from the outgoingByChannel map, but we would expect plugin1 to be removed, since it does not link to any channel anymore. The second reason why test:channel should not be removed from the outgoingByChannel map is that it is still linked to the second plugin.
The second test ensures proper cleanup from outgoingByPlugin when the last channel is removed. It registers one plugin with one test channel. When we unregister the plugin with the respective test channel, the plugin map entry is not removed from the outgoingByPlugin, when we would expect both the plugin map and channel to be removed since they are both empty.
This has not yet been verified on a running server, so it is unclear whether this results in observable API issues, but it looks like it violates the expected internal invariant between the two data structures.