mojira.dev
MC-311786

Running `/test run` with a `rotationSteps` value that is out of range causes an error

The rotationSteps argument of the /test run command allows any integer as a value and throws an error when the value is less than 0 or greater than 3, instead of the command failing to parse.

How to reproduce:

  1. Execute the following command:

    /test run minecraft:always_pass 1 true 4

Expected result:

The /test run command would not parse when the value of the rotationSteps argument is less than 0 or greater than 3.

Observed result:

When the value of the rotationSteps argument is less than 0 or greater than 3, he /test run command throws an error and prints the message "An unexpected error occurred while trying to execute that command" to the chat, with the following hover event:

rotationSteps must be a value from 0-3. Got value <value>

Stack trace:

java.lang.IllegalArgumentException: rotationSteps must be a value from 0-3. Got value <value>
	at net.minecraft.gametest.framework.StructureUtils.getRotationForRotationSteps(StructureUtils.java:46)
	at net.minecraft.gametest.framework.TestCommand.lambda$toGameTestInfo$1(TestCommand.java:471)
	at java.base/java.util.stream.ReferencePipeline$7$1FlatMap.accept(ReferencePipeline.java:288)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:722)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:315)
	at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:635)
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:291)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:652)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:658)
	at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:663)
	at net.minecraft.gametest.framework.TestCommand.run(TestCommand.java:198)
	at net.minecraft.gametest.framework.TestCommand.lambda$runWithRetryOptionsAndBuildInfo$1(TestCommand.java:323)
	at com.mojang.brigadier.context.ContextChain.runExecutable(ContextChain.java:73)
	at net.minecraft.commands.execution.tasks.ExecuteCommand.execute(ExecuteCommand.java:29)
	at net.minecraft.commands.execution.tasks.ExecuteCommand.execute(ExecuteCommand.java:13)
	at net.minecraft.commands.execution.UnboundEntryAction.lambda$bind$0(UnboundEntryAction.java:8)
	at net.minecraft.commands.execution.CommandQueueEntry.execute(CommandQueueEntry.java:8)
	at net.minecraft.commands.execution.ExecutionContext.runCommandQueue(ExecutionContext.java:106)
	at net.minecraft.commands.Commands.executeCommandInContext(Commands.java:438)
	at net.minecraft.commands.Commands.performCommand(Commands.java:370)
	at net.minecraft.server.network.ServerGamePacketListenerImpl.performUnsignedChatCommand(ServerGamePacketListenerImpl.java:1717)
	at net.minecraft.server.network.ServerGamePacketListenerImpl.lambda$handleChatCommand$0(ServerGamePacketListenerImpl.java:1705)
	at net.minecraft.server.TickTask.run(TickTask.java:18)
	at net.minecraft.util.thread.BlockableEventLoop.doRunTask(BlockableEventLoop.java:173)
	at net.minecraft.util.thread.ReentrantBlockableEventLoop.doRunTask(ReentrantBlockableEventLoop.java:23)
	at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:912)
	at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:193)
	at net.minecraft.util.thread.BlockableEventLoop.pollTask(BlockableEventLoop.java:147)
	at net.minecraft.server.MinecraftServer.pollTaskInternal(MinecraftServer.java:894)
	at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:888)
	at net.minecraft.util.thread.BlockableEventLoop.managedBlock(BlockableEventLoop.java:156)
	at net.minecraft.server.MinecraftServer.waitUntilNextTick(MinecraftServer.java:859)
	at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:758)
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:310)
	at java.base/java.lang.Thread.run(Thread.java:1474)

Code analysis:

The following code analysis uses 26.3 Pre-Release 3’s code, decompiled using Vineflower.

In the net.minecraft.gametest.framework.TestCommand class, the run <tests> and runfailed subcommands are registered using the runWithRetryOptionsAndBuildInfo method. The start of that method is shown below:

private static ArgumentBuilder<CommandSourceStack, ?> runWithRetryOptionsAndBuildInfo(
   final ArgumentBuilder<CommandSourceStack, ?> runArgument, final InCommandFunction<CommandContext<CommandSourceStack>, TestFinder> finder
) {
   return runWithRetryOptions(
      runArgument,
      finder,
      then -> then.then(
         ((RequiredArgumentBuilder)Commands.argument("rotationSteps", IntegerArgumentType.integer())
               .executes(
...

The rotationSteps argument has a type of IntegerArgumentType.integer(), which allows any integer to be specified for that argument. For the command to fail to parse integers less than 0 or greater than 3, the argument type would need to be IntegerArgumentType.integer(0, 3) instead.

Comments 1

[Mod] ManosSef

Björn

Community Consensus

Platform

Low

Commands, Debug

26.2, 26.3 Pre-Release 3

26.4 Snapshot 1

Retrieved