Skip to content

Commit

Permalink
fix: bytes.slice and bytes.at not handling negative or missing values…
Browse files Browse the repository at this point in the history
… correctly
  • Loading branch information
tristanmenzel committed Oct 10, 2024
1 parent b2a2a56 commit e6b5ba5
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/algo-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@algorandfoundation/algorand-typescript",
"version": "0.0.1-alpha.8",
"version": "0.0.1-alpha.9",
"description": "This package contains definitions for the types which comprise Algorand TypeScript which can be compiled to run on the Algorand Virtual Machine using the Puya compiler.",
"private": false,
"main": "index.js",
Expand All @@ -18,7 +18,7 @@
"build:4-copy-pkg-json": "tstk copy-package-json -c",
"build:5-copy-readme": "copyfiles ./README.md ./dist",
"watch": "rollup -c -w --configPlugin typescript",
"test": "vitest run "
"test": "vitest run"
},
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
Expand Down
56 changes: 56 additions & 0 deletions packages/algo-ts/src/impl/primitives.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { describe, expect, it } from 'vitest'
import { AvmError } from './errors'
import { arrayUtil } from './primitives'

describe('ArrayUtil', () => {
describe('arrayAt', () => {
it.each([
[[1, 2, 3], 0, 1],
[[1, 2, 3], 1, 2],
[[1, 2, 3], 2, 3],
[[1, 2, 3], -1, 3],
[[1, 2, 3], -2, 2],
[[1, 2, 3], -3, 1],
[[1, 2, 3], 4, AvmError],
[[1, 2, 3], -4, AvmError],
[new Uint8Array([1, 2, 3]), 0, new Uint8Array([1])],
[new Uint8Array([1, 2, 3]), 1, new Uint8Array([2])],
[new Uint8Array([1, 2, 3]), 2, new Uint8Array([3])],
[new Uint8Array([1, 2, 3]), -1, new Uint8Array([3])],
[new Uint8Array([1, 2, 3]), -2, new Uint8Array([2])],
[new Uint8Array([1, 2, 3]), -3, new Uint8Array([1])],
[new Uint8Array([1, 2, 3]), 4, AvmError],
[new Uint8Array([1, 2, 3]), -4, AvmError],
])('%s.at(%d) results in %s', (theArray, theIndex, theResult) => {
if (theResult === AvmError) {
expect(() => arrayUtil.arrayAt(theArray, theIndex)).toThrow(theResult)
} else {
expect(arrayUtil.arrayAt(theArray, theIndex)).toEqual(theResult)
}
})
})
describe('arraySlice', () => {
it.each([
[[1, 2, 3], [], [1, 2, 3]],
[[1, 2, 3], [0], [1, 2, 3]],
[[1, 2, 3], [1], [2, 3]],
[[1, 2, 3], [2], [3]],
[[1, 2, 3], [-1], [3]],
[[1, 2, 3], [-2], [2, 3]],
[[1, 2, 3], [-3], [1, 2, 3]],
[[1, 2, 3], [4], []],
[[1, 2, 3], [-4], [1, 2, 3]],
[new Uint8Array([1, 2, 3]), [], new Uint8Array([1, 2, 3])],
[new Uint8Array([1, 2, 3]), [0], new Uint8Array([1, 2, 3])],
[new Uint8Array([1, 2, 3]), [1], new Uint8Array([2, 3])],
[new Uint8Array([1, 2, 3]), [2], new Uint8Array([3])],
[new Uint8Array([1, 2, 3]), [-1], new Uint8Array([3])],
[new Uint8Array([1, 2, 3]), [-2], new Uint8Array([2, 3])],
[new Uint8Array([1, 2, 3]), [-3], new Uint8Array([1, 2, 3])],
[new Uint8Array([1, 2, 3]), [4], new Uint8Array([])],
[new Uint8Array([1, 2, 3]), [-4], new Uint8Array([1, 2, 3])],
])('%s.at(%d) results in %s', (theArray, [start, stop], theResult) => {
expect(arrayUtil.arraySlice(theArray, start, stop)).toEqual(theResult)
})
})
})
22 changes: 11 additions & 11 deletions packages/algo-ts/src/impl/primitives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,8 @@ export class BytesCls extends AlgoTsPrimitiveCls {
return new BytesCls(arrayUtil.arrayAt(this.#v, i))
}

slice(start: StubUint64Compat, end: StubUint64Compat): BytesCls {
const startNumber = start instanceof Uint64Cls ? start.asNumber() : start
const endNumber = end instanceof Uint64Cls ? end.asNumber() : end
const sliced = arrayUtil.arraySlice(this.#v, startNumber, endNumber)
slice(start: undefined | StubUint64Compat, end: undefined | StubUint64Compat): BytesCls {
const sliced = arrayUtil.arraySlice(this.#v, start, end)
return new BytesCls(sliced)
}

Expand Down Expand Up @@ -356,23 +354,25 @@ export class BytesCls extends AlgoTsPrimitiveCls {
}
}

export const arrayUtil = new (class {
export const arrayUtil = new (class ArrayUtil {
arrayAt(arrayLike: Uint8Array, index: StubUint64Compat): Uint8Array
arrayAt<T>(arrayLike: T[], index: StubUint64Compat): T
arrayAt<T>(arrayLike: T[] | Uint8Array, index: StubUint64Compat): T | Uint8Array
arrayAt<T>(arrayLike: T[] | Uint8Array, index: StubUint64Compat): T | Uint8Array {
const indexNum = getNumber(index)
if (arrayLike instanceof Uint8Array) {
const res = arrayLike.slice(indexNum, indexNum + 1)
const res = arrayLike.slice(indexNum, indexNum === -1 ? undefined : indexNum + 1)
avmInvariant(res.length, 'Index out of bounds')
return res
}
return arrayLike.at(indexNum) ?? avmError('Index out of bounds')
}
arraySlice(arrayLike: Uint8Array, start: StubUint64Compat, end: StubUint64Compat): Uint8Array
arraySlice<T>(arrayLike: T[], start: StubUint64Compat, end: StubUint64Compat): T[]
arraySlice<T>(arrayLike: T[] | Uint8Array, start: StubUint64Compat, end: StubUint64Compat) {
const startNum = getNumber(start)
const endNum = getNumber(end)
arraySlice(arrayLike: Uint8Array, start: undefined | StubUint64Compat, end: undefined | StubUint64Compat): Uint8Array
arraySlice<T>(arrayLike: T[], start: undefined | StubUint64Compat, end: undefined | StubUint64Compat): T[]
arraySlice<T>(arrayLike: T[] | Uint8Array, start: undefined | StubUint64Compat, end: undefined | StubUint64Compat): Uint8Array | T[]
arraySlice<T>(arrayLike: T[] | Uint8Array, start: undefined | StubUint64Compat, end: undefined | StubUint64Compat) {
const startNum = start === undefined ? undefined : getNumber(start)
const endNum = end === undefined ? undefined : getNumber(end)
if (arrayLike instanceof Uint8Array) {
return arrayLike.slice(startNum, endNum)
} else {
Expand Down
3 changes: 3 additions & 0 deletions packages/algo-ts/src/primitives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ export type bytes = {

equals(other: BytesCompat): boolean

slice(): bytes
slice(start: Uint64Compat): bytes
slice(start: Uint64Compat, end: Uint64Compat): bytes
slice(start?: Uint64Compat, end?: Uint64Compat): bytes

toString(): string
Expand Down

0 comments on commit e6b5ba5

Please sign in to comment.