From 822f2894d85a0687991ef49f1a728b3ebcd44433 Mon Sep 17 00:00:00 2001 From: Misode Date: Tue, 10 Dec 2024 22:36:51 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Validate=20the=20size=20of=20the=20?= =?UTF-8?q?random=20range?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/mcfunction/parser/argument.ts | 50 +++++++++++++++++-- .../src/mcfunction/tree/argument.ts | 8 +++ .../java-edition/src/mcfunction/tree/patch.ts | 8 +++ packages/locales/src/locales/en.json | 2 + 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/packages/java-edition/src/mcfunction/parser/argument.ts b/packages/java-edition/src/mcfunction/parser/argument.ts index 00382241c..6221b01a9 100644 --- a/packages/java-edition/src/mcfunction/parser/argument.ts +++ b/packages/java-edition/src/mcfunction/parser/argument.ts @@ -171,7 +171,15 @@ export const argument: mcf.ArgumentParserGetter = ( case 'minecraft:entity_summon': return wrap(core.resourceLocation({ category: 'entity_type' })) case 'minecraft:float_range': - return wrap(range('float')) + return wrap( + range( + 'float', + treeNode.properties?.min, + treeNode.properties?.max, + treeNode.properties?.minSpan, + treeNode.properties?.maxSpan, + ), + ) case 'minecraft:function': return wrap(core.resourceLocation({ category: 'function', allowTag: true })) case 'minecraft:gamemode': @@ -181,7 +189,15 @@ export const argument: mcf.ArgumentParserGetter = ( case 'minecraft:heightmap': return wrap(core.literal(...HeightmapValues)) case 'minecraft:int_range': - return wrap(range('integer')) + return wrap( + range( + 'integer', + treeNode.properties?.min, + treeNode.properties?.max, + treeNode.properties?.minSpan, + treeNode.properties?.maxSpan, + ), + ) case 'minecraft:item_enchantment': return wrap(core.resourceLocation({ category: 'enchantment' })) case 'minecraft:item_predicate': @@ -650,18 +666,24 @@ function range( type: 'float', min?: number, max?: number, + minSpan?: number, + maxSpan?: number, cycleable?: boolean, ): core.Parser function range( type: 'integer', min?: number, max?: number, + minSpan?: number, + maxSpan?: number, cycleable?: boolean, ): core.Parser function range( type: 'float' | 'integer', min?: number, max?: number, + minSpan?: number, + maxSpan?: number, cycleable?: boolean, ): core.Parser { const number: core.Parser = type === 'float' @@ -707,6 +729,21 @@ function range( localize('mcfunction.parser.range.min>max', ans.value[0], ans.value[1]), res, ) + } else if (minSpan !== undefined || maxSpan !== undefined) { + const span = ans.value[0] !== undefined && ans.value[1] !== undefined + ? Math.abs(ans.value[0] - ans.value[1]) + : (ans.value[0] ?? ans.value[1] ?? Infinity) + if (minSpan !== undefined && span < minSpan) { + ctx.err.report( + localize('mcfunction.parser.range.span-too-small', span, minSpan), + res, + ) + } else if (maxSpan !== undefined && span > maxSpan) { + ctx.err.report( + localize('mcfunction.parser.range.span-too-large', span, maxSpan), + res, + ) + } } return ans }, @@ -1234,7 +1271,14 @@ export function selector(ignoreInvalidPrefix = false): core.Parser( - range('float', undefined, undefined, true), + range( + 'float', + undefined, + undefined, + undefined, + undefined, + true, + ), (res, _, ctx) => { if (hasKey(key.value)) { ctx.err.report( diff --git a/packages/java-edition/src/mcfunction/tree/argument.ts b/packages/java-edition/src/mcfunction/tree/argument.ts index dd934210d..0123c3520 100644 --- a/packages/java-edition/src/mcfunction/tree/argument.ts +++ b/packages/java-edition/src/mcfunction/tree/argument.ts @@ -59,8 +59,15 @@ export interface MinecraftEntityAnchorArgumentTreeNode extends mcf.ArgumentTreeN export interface MinecraftEntitySummonArgumentTreeNode extends mcf.ArgumentTreeNode { parser: 'minecraft:entity_summon' } +export interface RangeProperties extends Record { + min: number + max: number + minSpan: number + maxSpan: number +} export interface MinecraftFloatRangeArgumentTreeNode extends mcf.ArgumentTreeNode { parser: 'minecraft:float_range' + properties?: RangeProperties } export interface MinecraftFunctionArgumentTreeNode extends mcf.ArgumentTreeNode { parser: 'minecraft:function' @@ -76,6 +83,7 @@ export interface MinecraftHeightmapArgumentTreeNode extends mcf.ArgumentTreeNode } export interface MinecraftIntRangeArgumentTreeNode extends mcf.ArgumentTreeNode { parser: 'minecraft:int_range' + properties?: RangeProperties } export interface MinecraftItemEnchantmentArgumentTreeNode extends mcf.ArgumentTreeNode { parser: 'minecraft:item_enchantment' diff --git a/packages/java-edition/src/mcfunction/tree/patch.ts b/packages/java-edition/src/mcfunction/tree/patch.ts index 4a8a0af9a..8fa49d9ec 100644 --- a/packages/java-edition/src/mcfunction/tree/patch.ts +++ b/packages/java-edition/src/mcfunction/tree/patch.ts @@ -524,6 +524,10 @@ export function getPatch(release: ReleaseVersion): PartialRootTreeNode { roll: { children: { range: { + properties: { + minSpan: 1, + maxSpan: 2147483646, + }, children: { sequence: { properties: { @@ -538,6 +542,10 @@ export function getPatch(release: ReleaseVersion): PartialRootTreeNode { value: { children: { range: { + properties: { + minSpan: 1, + maxSpan: 2147483646, + }, children: { sequence: { properties: { diff --git a/packages/locales/src/locales/en.json b/packages/locales/src/locales/en.json index e2b484912..efe33c65e 100644 --- a/packages/locales/src/locales/en.json +++ b/packages/locales/src/locales/en.json @@ -141,6 +141,8 @@ "mcfunction.parser.no-permission": "Permission level %0% is required, which is higher than %1% defined in config", "mcfunction.parser.objective.too-long": "Objective names cannot be longer than %0% characters", "mcfunction.parser.range.min>max": "The minimum value %0% is larger than the maximum value %1%", + "mcfunction.parser.range.span-too-large": "The range size %0% is larger than the maximum %1%", + "mcfunction.parser.range.span-too-small": "The range size %0% is smaller than the minimum %1%", "mcfunction.parser.score_holder.fake-name.too-long": "Fake names cannot be longer than %0% characters", "mcfunction.parser.sep": "a space (%0%)", "mcfunction.parser.trailing": "Trailing data encountered: %0%",