Skip to content

Commit

Permalink
Merge pull request #1660 from michel-iwaniec/bugfix_script_engine_init
Browse files Browse the repository at this point in the history
Fix bug with out-of-bounds memory writes on 8-bit values in init script
  • Loading branch information
chrismaltby authored Jan 14, 2025
2 parents 02f5ee2 + 71fe78a commit 059dd53
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix issue where changing the dimensions of a sprite png image could cause the sprite editor's tile palette to display incorrectly
- Fix line numbers in code editor for GBVM scripts with more than 999 lines
- Fix issue preventing projects being created with the name "project"
- Fix issue without-of-bounds memory writes on 8-bit values in engine field initialisation [@michel-iwaniec](https://github.com/michel-iwaniec)
- Fix issue preventing checkbox type working in engine fields [@pau-tomas](https://github.com/pau-tomas)
- Fix UI palette text control code. Palette indices now go from 1 to 8, because zero byte is a string terminator [@untoxa](https://github.com/untoxa)
- Fix issue where migrating old projects could cause gbvm symbols to become empty, preventing build from completing (opening a broken project will now automatically fix this issue)
Expand Down
7 changes: 6 additions & 1 deletion src/lib/compiler/compileBootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "./generateGBVMData";
import { dirEnum } from "./helpers";
import { PrecompiledAvatarData } from "./compileAvatars";
import { gbvmSetConstForCType } from "shared/lib/engineFields/engineFieldToCType";

interface InitialState {
startX: number;
Expand Down Expand Up @@ -88,12 +89,16 @@ ${usedEngineFields
_script_engine_init::
${usedEngineFields
.map((engineField) => {
if (engineField.cType === "define") {
return "";
}
const engineValue = engineFieldValues.find((v) => v.id === engineField.key);
const value =
engineValue && engineValue.value !== undefined
? engineValue.value
: engineField.defaultValue;
return ` VM_SET_CONST_INT16 _${engineField.key}, ${value}`;
const gbvmSetConstInstruction = gbvmSetConstForCType(engineField.cType);
return ` ${gbvmSetConstInstruction} _${engineField.key}, ${value}`;
})
.join("\n")}
Expand Down
14 changes: 14 additions & 0 deletions src/shared/lib/engineFields/engineFieldToCType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { EngineFieldCType } from "store/features/engine/engineState";
import { assertUnreachable } from "shared/lib/helpers/assert";

export const is16BitCType = (cType: EngineFieldCType): boolean => {
return cType === "WORD" || cType === "UWORD";
Expand Down Expand Up @@ -35,3 +36,16 @@ export const clampToCType = (
const max = maxForCType(cType);
return Math.max(min, Math.min(max, value));
};

export const gbvmSetConstForCType = (
cType: Exclude<EngineFieldCType, "define">
): string => {
if (cType === "WORD" || cType === "UWORD") {
return "VM_SET_CONST_INT16";
}
if (cType === "BYTE" || cType === "UBYTE") {
return "VM_SET_CONST_INT8";
}
assertUnreachable(cType);
return "UNREACHABLE";
};

0 comments on commit 059dd53

Please sign in to comment.