Skip to content

Commit

Permalink
fix: enum size validation (#2413)
Browse files Browse the repository at this point in the history
* fix: enum size validation

* chore: changeset

* chore: linting

* chore: pr release

* chore: remove pr release
  • Loading branch information
danielbate authored May 29, 2024
1 parent 5a6ca46 commit af3c143
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/modern-students-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/abi-coder": patch
---

fix: `enum` size validation
2 changes: 1 addition & 1 deletion .github/workflows/pr-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ jobs:
message: |
This PR is published in NPM with version **${{ steps.release.outputs.published_version }}**
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
13 changes: 8 additions & 5 deletions packages/abi-coder/src/encoding/coders/EnumCoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { toNumber } from '@fuel-ts/math';
import { concat } from '@fuel-ts/utils';
import type { RequireExactlyOne } from 'type-fest';

import { OPTION_CODER_TYPE, WORD_SIZE } from '../../utils/constants';
import { OPTION_CODER_TYPE } from '../../utils/constants';
import { hasNestedOption } from '../../utils/utilities';

import type { TypesOfCoder } from './AbstractCoder';
Expand Down Expand Up @@ -36,7 +36,7 @@ export class EnumCoder<TCoders extends Record<string, Coder>> extends Coder<
constructor(name: string, coders: TCoders) {
const caseIndexCoder = new BigNumberCoder('u64');
const encodedValueSize = Object.values(coders).reduce(
(max, coder) => Math.max(max, coder.encodedLength),
(min, coder) => Math.min(min, coder.encodedLength),
0
);
super(`enum ${name}`, `enum ${name}`, caseIndexCoder.encodedLength + encodedValueSize);
Expand Down Expand Up @@ -80,7 +80,7 @@ export class EnumCoder<TCoders extends Record<string, Coder>> extends Coder<
}

decode(data: Uint8Array, offset: number): [DecodedValueOf<TCoders>, number] {
if (this.#shouldValidateLength && data.length < this.#encodedValueSize) {
if (this.#shouldValidateLength && data.length < this.encodedLength) {
throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid enum data size.`);
}

Expand All @@ -93,9 +93,12 @@ export class EnumCoder<TCoders extends Record<string, Coder>> extends Coder<
`Invalid caseIndex "${caseIndex}". Valid cases: ${Object.keys(this.coders)}.`
);
}

const valueCoder = this.coders[caseKey];
const offsetAndCase = offset + WORD_SIZE;
const offsetAndCase = offset + this.#caseIndexCoder.encodedLength;

if (this.#shouldValidateLength && data.length < offsetAndCase + valueCoder.encodedLength) {
throw new FuelError(ErrorCode.DECODE_ERROR, `Invalid enum data size.`);
}

const [decoded, newOffset] = valueCoder.decode(data, offsetAndCase);

Expand Down
22 changes: 22 additions & 0 deletions packages/fuel-gauge/src/options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,26 @@ describe('Options Tests', () => {

expect(value).toStrictEqual(undefined);
});

it('echoes option enum diff sizes', async () => {
const { value } = await contractInstance.functions.echo_enum_diff_sizes(undefined).call();

expect(value).toStrictEqual(undefined);

const { value: value2 } = await contractInstance.functions
.echo_enum_diff_sizes({ a: U8_MAX })
.call();

expect(value2).toStrictEqual({ a: U8_MAX });

const { value: value3 } = await contractInstance.functions
.echo_enum_diff_sizes({
b: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c',
})
.call();

expect(value3).toStrictEqual({
b: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c',
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ struct SomeStruct {
b: u64,
}

enum DiffSizeEnum {
a: u8,
b: b256,
}

storage {
stuff: StorageMap<Identity, SomeStruct> = StorageMap {},
}
Expand All @@ -71,6 +76,7 @@ abi OptionContract {
fn echo_array_option(arg: [Option<u16>; 3]) -> [Option<u16>; 3];
fn print_enum_option_array() -> GardenVector;
fn echo_deeply_nested_option(arg: DeepStruct) -> DeepStruct;
fn echo_enum_diff_sizes(arg: Option<DiffSizeEnum>) -> Option<DiffSizeEnum>;
}

impl OptionContract for Contract {
Expand Down Expand Up @@ -110,4 +116,8 @@ impl OptionContract for Contract {
fn echo_deeply_nested_option(arg: DeepStruct) -> DeepStruct {
arg
}

fn echo_enum_diff_sizes(arg: Option<DiffSizeEnum>) -> Option<DiffSizeEnum> {
arg
}
}

0 comments on commit af3c143

Please sign in to comment.