From efb36d5fc0fe56a98f5795c53dfa109887cd5aae Mon Sep 17 00:00:00 2001 From: mat Date: Mon, 12 Jan 2026 09:38:47 -1030 Subject: fix memory leaks in azalea-protocol --- azalea-protocol/src/packets/game/c_merchant_offers.rs | 13 ++++++++++++- azalea-protocol/src/packets/game/c_update_advancements.rs | 6 +++--- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'azalea-protocol/src/packets') diff --git a/azalea-protocol/src/packets/game/c_merchant_offers.rs b/azalea-protocol/src/packets/game/c_merchant_offers.rs index 7bbf92c4..957060b4 100644 --- a/azalea-protocol/src/packets/game/c_merchant_offers.rs +++ b/azalea-protocol/src/packets/game/c_merchant_offers.rs @@ -2,6 +2,7 @@ use std::{ any::Any, fmt::{self, Debug}, io::{self, Cursor, Write}, + mem::ManuallyDrop, }; use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError}; @@ -54,8 +55,13 @@ impl ItemCost { pub fn into_item_stack(self) -> ItemStackData { let mut component_patch = DataComponentPatch::default(); for component in self.components.expected { + let component = ManuallyDrop::new(component); + // SAFETY: DataComponentUnion does not run any destructors unless it's dropped + // through drop_as, so since TypedDataComponent is now ManuallyDrop, the value + // will stay in memory. + let value = unsafe { std::ptr::read(&component.value) }; unsafe { - component_patch.unchecked_insert_component(component.kind, Some(component.value)); + component_patch.unchecked_insert_component(component.kind, Some(value)); } } // TODO: add a fast way to iterate over default components, and insert the ones @@ -129,6 +135,11 @@ impl Clone for TypedDataComponent { } } } +impl Drop for TypedDataComponent { + fn drop(&mut self) { + unsafe { self.value.drop_as(self.kind) }; + } +} impl PartialEq for TypedDataComponent { fn eq(&self, other: &Self) -> bool { if self.kind != other.kind { diff --git a/azalea-protocol/src/packets/game/c_update_advancements.rs b/azalea-protocol/src/packets/game/c_update_advancements.rs index 62881b9d..24baebc5 100644 --- a/azalea-protocol/src/packets/game/c_update_advancements.rs +++ b/azalea-protocol/src/packets/game/c_update_advancements.rs @@ -22,7 +22,7 @@ pub struct ClientboundUpdateAdvancements { #[derive(AzBuf, Clone, Debug, PartialEq)] pub struct Advancement { pub parent_id: Option, - pub display: Option, + pub display: Option>, pub requirements: Vec>, pub sends_telemetry_event: bool, } @@ -134,7 +134,7 @@ mod tests { id: Identifier::new("minecraft:test"), value: Advancement { parent_id: None, - display: Some(DisplayInfo { + display: Some(Box::new(DisplayInfo { title: FormattedText::from("title".to_owned()), description: FormattedText::from("description".to_owned()), icon: ItemStack::Empty, @@ -144,7 +144,7 @@ mod tests { background: None, x: 0.0, y: 0.0, - }), + })), requirements: Vec::new(), sends_telemetry_event: false, }, -- cgit v1.2.3