From 825d45eb261e9fa7b546d2526e1a9ab9122c9399 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 6 Apr 2024 08:44:03 +0100 Subject: [PATCH] Fix NPE when rendering turtle's label Minecraft.hitResult may /technically/ be null when rendering a turtle. In vanilla, this doesn't appear to happen, but other mods (e.g. Immersive Portals) may still take advantage of this. This hitResult is then propagated to BlockEntityRenderDispatcher, where the field was /not/ marked as nullable. This meant we didn't even notice the potential of an NPE! Closes #1775 --- .../client/render/TurtleBlockEntityRenderer.java | 2 +- .../main/kotlin/cc/tweaked/linter/MinecraftLibraryModel.kt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java index c52c5a485..caf56621e 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/TurtleBlockEntityRenderer.java @@ -55,7 +55,7 @@ public void render(TurtleBlockEntity turtle, float partialTicks, PoseStack trans // Render the label var label = turtle.getLabel(); var hit = renderer.cameraHitResult; - if (label != null && hit.getType() == HitResult.Type.BLOCK && turtle.getBlockPos().equals(((BlockHitResult) hit).getBlockPos())) { + if (label != null && hit != null && hit.getType() == HitResult.Type.BLOCK && turtle.getBlockPos().equals(((BlockHitResult) hit).getBlockPos())) { var mc = Minecraft.getInstance(); var font = this.font; diff --git a/projects/lints/src/main/kotlin/cc/tweaked/linter/MinecraftLibraryModel.kt b/projects/lints/src/main/kotlin/cc/tweaked/linter/MinecraftLibraryModel.kt index d38c2b100..bdf50167c 100644 --- a/projects/lints/src/main/kotlin/cc/tweaked/linter/MinecraftLibraryModel.kt +++ b/projects/lints/src/main/kotlin/cc/tweaked/linter/MinecraftLibraryModel.kt @@ -7,6 +7,7 @@ import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSetMultimap import com.uber.nullaway.LibraryModels +import com.uber.nullaway.LibraryModels.FieldRef.fieldRef import com.uber.nullaway.LibraryModels.MethodRef.methodRef /** @@ -34,4 +35,9 @@ override fun nonNullReturns(): ImmutableSet = Immutable // Reasoning about nullability of BlockEntity.getLevel() is awkward. For now, assume it's non-null. methodRef("net.minecraft.world.level.block.entity.BlockEntity", "getLevel()"), ) + + override fun nullableFields(): ImmutableSet = ImmutableSet.of( + // This inherits from Minecraft.hitResult, and so can also be null. + fieldRef("net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher", "cameraHitResult"), + ) }