From 6a9e67a40fc2dde284f4e36d375c6a65dc319763 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 14:17:32 +0000 Subject: [PATCH 1/3] Initial plan From ddd7d7a60e950bca229e1187a94965bd117e8290 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 14:21:01 +0000 Subject: [PATCH 2/3] docs: add KDoc documentation to ensureValidNestingDepth function Co-authored-by: twisti-dev <76837088+twisti-dev@users.noreply.github.com> --- .../player/ppdc/PersistentPlayerDataContainerView.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/ppdc/PersistentPlayerDataContainerView.kt b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/ppdc/PersistentPlayerDataContainerView.kt index b30d0be0..6dee1a38 100644 --- a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/ppdc/PersistentPlayerDataContainerView.kt +++ b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/ppdc/PersistentPlayerDataContainerView.kt @@ -97,6 +97,18 @@ interface PersistentPlayerDataContainerView { */ const val MAX_NESTING_DEPTH = 512 + /** + * Ensures that the nesting depth does not exceed the maximum allowed limit. + * + * This function validates that the provided depth is within acceptable bounds, + * preventing memory exhaustion from extremely deep nested structures. + * + * @param depth The current nesting depth to validate. + * @param exceptionFactory A factory function that creates the exception to throw + * when the depth exceeds the limit. Defaults to [IllegalStateException]. + * @throws Throwable When the depth exceeds [MAX_NESTING_DEPTH]. The specific exception + * type is determined by the [exceptionFactory] parameter. + */ inline fun ensureValidNestingDepth( depth: Int, exceptionFactory: (message: String) -> Throwable = ::IllegalStateException From 68f1471026cea7c0645d0cd309a11dc870c40fc2 Mon Sep 17 00:00:00 2001 From: twisti Date: Sat, 1 Nov 2025 15:26:33 +0100 Subject: [PATCH 3/3] fix: handle uninitialized response in RespondingNettyPacket - Modified `response` to use lazy initialization with `CompletableDeferred` for proper memory handling. - Ensure exception completion if response is accessed after connection garbage collection. --- .../cloud/api/common/netty/packet/RespondingNettyPacket.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/RespondingNettyPacket.kt b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/RespondingNettyPacket.kt index 7f09c100..c94c045d 100644 --- a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/RespondingNettyPacket.kt +++ b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/RespondingNettyPacket.kt @@ -38,7 +38,7 @@ abstract class RespondingNettyPacket

: NettyPacket() { * A deferred response object for awaiting the associated response. */ @InternalApi - val response = CompletableDeferred

() + val response by lazy { CompletableDeferred

() } /** * The connection through which the response will be sent. @@ -120,6 +120,11 @@ abstract class RespondingNettyPacket

: NettyPacket() { if (responseConnection == null) { log.atWarning() .log("Cannot respond to packet ${this::class.simpleName} with session ID $uniqueSessionId: original connection has been garbage collected") + + if ((::response.getDelegate() as Lazy<*>).isInitialized()) { + response.completeExceptionally(IllegalStateException("Original connection has been garbage collected")) + } + return }