From 2b8ce3cd91af1d20a446b4eb2a09aa14b8cde0fb Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 6 Jun 2026 15:09:10 +0200 Subject: [PATCH] feat(furni-editor): server-side sort for the editor search Read sortField/sortDir from the search packet and ORDER BY a whitelisted items_base column (id/sprite_id/item_name/public_name/type/interaction_type) with a stable id tie-break, so sorting orders the whole result set instead of just the page the client received. Column names come from a fixed whitelist (never raw input) so the dynamic ORDER BY stays injection-safe. --- .../furnieditor/FurniEditorSearchEvent.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/furnieditor/FurniEditorSearchEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/furnieditor/FurniEditorSearchEvent.java index 769f41cd..274a5dbd 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/furnieditor/FurniEditorSearchEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/furnieditor/FurniEditorSearchEvent.java @@ -27,6 +27,8 @@ public class FurniEditorSearchEvent extends MessageHandler { String query = this.packet.readString(); String type = this.packet.readString(); int page = this.packet.readInt(); + String sortField = this.packet.readString(); + String sortDir = this.packet.readString(); // Input validation if (query.length() > 100) { @@ -92,10 +94,25 @@ public class FurniEditorSearchEvent extends MessageHandler { } } + // Resolve a SAFE ORDER BY from the whitelisted sort field/direction + // (column names are never taken from raw user input — injection-proof). + String orderColumn; + switch (sortField == null ? "" : sortField) { + case "spriteId": orderColumn = "sprite_id"; break; + case "itemName": orderColumn = "item_name"; break; + case "publicName": orderColumn = "public_name"; break; + case "type": orderColumn = "type"; break; + case "interactionType": orderColumn = "interaction_type"; break; + case "id": + default: orderColumn = "id"; break; + } + String orderDir = "desc".equalsIgnoreCase(sortDir) ? "DESC" : "ASC"; + // Count total int total = 0; String countSql = "SELECT COUNT(*) FROM items_base " + whereClause; - String dataSql = "SELECT * FROM items_base " + whereClause + " ORDER BY id ASC LIMIT ? OFFSET ?"; + String dataSql = "SELECT * FROM items_base " + whereClause + + " ORDER BY " + orderColumn + " " + orderDir + ", id ASC LIMIT ? OFFSET ?"; List> items = new ArrayList<>();