Skip to content

Commit 5abe8b6

Browse files
Fix server freezing with /give (#6449)
<!-- EssentialsX bug fix submission guide ==================================== NOTE: Failure to fill out this template properly may result in your PR being delayed or ignored without warning. NOTE: Don't type between any arrows in the template, as this text will be hidden. This includes this header block and any other explanation text blocks. Want to discuss your PR before submitting it? Join the EssentialsX Development server: https://discord.gg/CUN7qVb EssentialsX is GPL ------------------ By contributing to EssentialsX, you agree to license your code under the GNU General Public License version 3, which can be found at the link below: https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE Instructions ------------ If you are submitting a bug fix, please follow the following steps: 1. Fill out the template in full. This includes providing screenshots and a link to the original bug report. If there isn't an existing bug report, we recommend opening a new detailed bug report BEFORE opening your PR to fix it, else your PR may be delayed or rejected without warning. You can open a new bug report by following this link: https://github.com/EssentialsX/Essentials/issues/new/choose 2. When linking logs or config files, do not attach them to the post! Copy and paste any logs into https://gist.github.com/, then paste a link to them in the relevant parts of the template. Do not use Hastebin or Pastebin, as this can cause issues with future reviews. DO NOT drag logs directly into this text box, as we cannot read these! 3. If you are fixing a performance issue, please include a link to a Timings and/or profiler report, both before and after your PR. 4. If you are fixing a visual bug, such as in commands, please include screenshots so that we can more easily review the proposed fix. (You can drag screenshots into the bottom of the editor.) --> ### Information <!-- Replace #nnnn with the number of the original issue. If this PR fixes multiple issues, you should repeat the phrase "fixes #nnnn" for each issue. --> This PR fixes a bug where anyone with access to the /give command could freeze the server. ### Details Currently, if a user has permission to spawn items with metadata, they can freeze or completely crash the server by supplying a massive integer for a book's page number (e.g., `/give <player> written_book 1 page2147483647:payload`). Because there is no upper bound check in `MetaItemStack.java`, the internal `for` loop tries to allocate an `ArrayList` with billions of empty strings to reach that requested page index. This instantly exhausts the JVM heap and triggers an OutOfMemoryError, hard-crashing the server thread, or at least freezing it entirely for seconds. This PR fixes the issue by introducing a hard limit of 100 pages for book metadata parsing. If the requested page exceeds this limit, the loop doesn't execute and it instead throws a newly added `pageLimitExceeded` translatable exception. **Environments tested:** <!-- Type the OS you have used below. --> OS: Windows 11 25H2 26200.7922 <!-- Type the JDK version (from java -version) you have used below. --> Java version: Java 21 (OpenJDK 64-Bit Server VM 21.0.10+7-LTS; Eclipse Adoptium Temurin-21.0.10+7) <!-- Put an "x" inside the boxes for the server software you have tested this bug fix on. If this feature does not apply to a server, strike through the server software using ~~strikethrough~~. If you have tested on other environments, add a new line with relevant details. --> Purpur version 1.21.11-2545 **Demonstration:** <!-- Below this block, include screenshots/log snippets from before and after as necessary. If you have created or used a test case plugin, please link to a download of the plugin, source code and exact version used where possible. --> Before: <img width="1401" height="269" alt="image" src="https://github.com/user-attachments/assets/9453a449-af43-4e77-bdfe-26e63e47b634" /> After: <img width="1104" height="189" alt="image" src="https://github.com/user-attachments/assets/f1783011-92db-4518-9a4d-a831bb847261" /> Co-authored-by: MD <[email protected]>
1 parent b8acd9c commit 5abe8b6

File tree

3 files changed

+10
-2
lines changed

3 files changed

+10
-2
lines changed

Essentials/src/main/java/com/earth2me/essentials/MetaItemStack.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,14 @@ public void addStringMeta(final CommandSource sender, final boolean allowUnsafe,
308308
final BookMeta meta = (BookMeta) stack.getItemMeta();
309309
meta.setTitle(title);
310310
stack.setItemMeta(meta);
311-
} else if (split.length > 1 && split[0].startsWith("page") && split[0].length() > 4 && MaterialUtil.isEditableBook(stack.getType()) && hasMetaPermission(sender, "page", false, true, ess)) {
312-
final int page = NumberUtil.isInt(split[0].substring(4)) ? (Integer.parseInt(split[0].substring(4)) - 1) : 0;
311+
} else if (split.length > 1 && split[0].startsWith("page") && split[0].length() > 4
312+
&& MaterialUtil.isEditableBook(stack.getType())
313+
&& hasMetaPermission(sender, "page", false, true, ess)) {
314+
final int page = NumberUtil.isInt(split[0].substring(4)) ? (Integer.parseInt(split[0].substring(4)) - 1)
315+
: 0;
316+
if (page > 100) {
317+
throw new TranslatableException("pageLimitExceeded");
318+
}
313319
final BookMeta meta = (BookMeta) stack.getItemMeta();
314320
final List<String> pages = meta.hasPages() ? new ArrayList<>(meta.getPages()) : new ArrayList<>();
315321
final List<String> lines = new ArrayList<>();

Essentials/src/main/resources/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ openingDisposal=<primary>Opening disposal menu...
909909
orderBalances=<primary>Ordering balances of<secondary> {0} <primary>users, please wait...
910910
oversizedMute=<dark_red>You may not mute a player for this period of time.
911911
oversizedTempban=<dark_red>You may not ban a player for this period of time.
912+
pageLimitExceeded=<dark_red>Page number exceeds the maximum limit (100).
912913
passengerTeleportFail=<dark_red>You cannot be teleported while carrying passengers.
913914
payCommandDescription=Pays another player from your balance.
914915
payCommandUsage=/<command> <player> <amount>

Essentials/src/main/resources/messages_en.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ openingDisposal=<primary>Opening disposal menu...
904904
orderBalances=<primary>Ordering balances of<secondary> {0} <primary>users, please wait...
905905
oversizedMute=<dark_red>You may not mute a player for this period of time.
906906
oversizedTempban=<dark_red>You may not ban a player for this period of time.
907+
pageLimitExceeded=<dark_red>Page number exceeds the maximum limit (100).
907908
passengerTeleportFail=<dark_red>You cannot be teleported while carrying passengers.
908909
payCommandDescription=Pays another player from your balance.
909910
payCommandUsage=/<command> <player> <amount>

0 commit comments

Comments
 (0)