diff --git a/libs/base/sim/control.ts b/libs/base/sim/control.ts index 849c3ac65..70048c713 100644 --- a/libs/base/sim/control.ts +++ b/libs/base/sim/control.ts @@ -20,6 +20,7 @@ namespace pxsim.BufferMethods { } export function hash(buf: RefBuffer, bits: number) { + BufferMethods.typeCheck(buf); bits |= 0 if (bits < 1) return 0 diff --git a/libs/cable/sim/cable.ts b/libs/cable/sim/cable.ts index ee3bebdde..d0ad15860 100644 --- a/libs/cable/sim/cable.ts +++ b/libs/cable/sim/cable.ts @@ -1,5 +1,6 @@ namespace pxsim.network { export function cableSendPacket(buf: RefBuffer): void { + BufferMethods.typeCheck(buf); const state = getCableState(); state.send(buf); } @@ -12,7 +13,7 @@ namespace pxsim.network { export function onCablePacket(body: RefAction): void { const state = getCableState(); state.listen(body); - } + } export function onCableError(body: RefAction): void { const state = getCableState(); diff --git a/libs/core/sim/neopixel.ts b/libs/core/sim/neopixel.ts index 2636673d0..5ca087318 100644 --- a/libs/core/sim/neopixel.ts +++ b/libs/core/sim/neopixel.ts @@ -49,6 +49,7 @@ namespace pxsim { } export function sendBufferAsm(buffer: RefBuffer, pin: number) { + BufferMethods.typeCheck(buffer); const b = board(); if (!b) return; const p = b.edgeConnectorState.getPin(pin); @@ -63,6 +64,7 @@ namespace pxsim { namespace pxsim.light { // Currently only modifies the builtin pixels export function sendBuffer(pin: { id: number }, clk: { id: number }, mode: number, b: RefBuffer) { + BufferMethods.typeCheck(b); const state = neopixelState(pin.id); if (!state) return; state.mode = mode & 0xff; diff --git a/libs/core/sim/pins.ts b/libs/core/sim/pins.ts index 89d114c72..778b04e82 100644 --- a/libs/core/sim/pins.ts +++ b/libs/core/sim/pins.ts @@ -152,7 +152,7 @@ namespace pxsim.pins { markUsed(scl); return b && b.edgeConnectorState && b.edgeConnectorState.createI2C(sda, scl); } - + export function createSPI(mosi: DigitalInOutPin, miso: DigitalInOutPin, sck: DigitalInOutPin) { const b = board() as EdgeConnectorBoard; markUsed(mosi); @@ -168,6 +168,7 @@ namespace pxsim.I2CMethods { } export function writeBuffer(i2c: I2C, address: number, buf: RefBuffer, repeat?: boolean): number { + BufferMethods.typeCheck(buf); return 0; } } @@ -179,6 +180,8 @@ namespace pxsim.SPIMethods { } export function transfer(device: pxsim.SPI, command: RefBuffer, response: RefBuffer) { + BufferMethods.typeCheck(command); + BufferMethods.typeCheck(response); device.transfer(command, response); } diff --git a/libs/core/sim/serial.ts b/libs/core/sim/serial.ts index 4488c7d1b..e4390b371 100644 --- a/libs/core/sim/serial.ts +++ b/libs/core/sim/serial.ts @@ -16,6 +16,7 @@ namespace pxsim.SerialDeviceMethods { } export function writeBuffer(device: SerialDevice, buffer: RefBuffer) { + BufferMethods.typeCheck(buffer); device.writeBuffer(buffer); } diff --git a/libs/infrared/sim/ir.ts b/libs/infrared/sim/ir.ts index daaa3451c..bbaf1c00c 100644 --- a/libs/infrared/sim/ir.ts +++ b/libs/infrared/sim/ir.ts @@ -1,5 +1,6 @@ namespace pxsim.network { export function infraredSendPacket(buf: RefBuffer): void { + BufferMethods.typeCheck(buf); const state = getInfraredState(); state.send(buf); } @@ -12,7 +13,7 @@ namespace pxsim.network { export function onInfraredPacket(body: RefAction): void { const state = getInfraredState(); state.listen(body); - } + } export function onInfraredError(body: RefAction): void { const state = getInfraredState(); diff --git a/libs/music/sim/music.ts b/libs/music/sim/music.ts index 457a92c09..eacec432e 100644 --- a/libs/music/sim/music.ts +++ b/libs/music/sim/music.ts @@ -43,6 +43,7 @@ namespace pxsim.music { } export function setTone(buffer: RefBuffer) { + BufferMethods.typeCheck(buffer); // TODO: implement set tone in the audio context } diff --git a/libs/radio/sim/radio.ts b/libs/radio/sim/radio.ts index e9ff84731..9429633de 100644 --- a/libs/radio/sim/radio.ts +++ b/libs/radio/sim/radio.ts @@ -14,12 +14,13 @@ namespace pxsim.radio { state.setTransmitPower(power); } - export function setFrequencyBand(band: number) { + export function setFrequencyBand(band: number) { const state = pxsim.getRadioState(); state.setFrequencyBand(band); } export function sendRawPacket(buf: RefBuffer) { + BufferMethods.typeCheck(buf); let cb = getResume(); const state = pxsim.getRadioState(); if (state.enable) { diff --git a/libs/screen/sim/image.ts b/libs/screen/sim/image.ts index 561dbb395..5d2a6ea2d 100644 --- a/libs/screen/sim/image.ts +++ b/libs/screen/sim/image.ts @@ -64,34 +64,53 @@ namespace pxsim.ImageMethods { export function XX(x: number) { return (x << 16) >> 16 } export function YY(x: number) { return x >> 16 } - export function width(img: RefImage) { return img._width } + export function width(img: RefImage) { + typeCheck(img); + return img._width; + } - export function height(img: RefImage) { return img._height } + export function height(img: RefImage) { + typeCheck(img); + return img._height; + } - export function isMono(img: RefImage) { return img._bpp == 1 } + export function isMono(img: RefImage) { + typeCheck(img); + return img._bpp == 1 + } - export function isStatic(img: RefImage) { return img.gcIsStatic() } + export function isStatic(img: RefImage) { + typeCheck(img); + return img.gcIsStatic() + } - export function revision(img: RefImage) { return img.revision } + export function revision(img: RefImage) { + typeCheck(img); + return img.revision + } export function setPixel(img: RefImage, x: number, y: number, c: number) { + typeCheck(img); img.makeWritable() if (img.inRange(x, y)) img.data[img.pix(x, y)] = img.color(c) } export function getPixel(img: RefImage, x: number, y: number) { + typeCheck(img); if (img.inRange(x, y)) return img.data[img.pix(x, y)] return 0 } export function fill(img: RefImage, c: number) { + typeCheck(img); img.makeWritable() img.data.fill(img.color(c)) } export function fillRect(img: RefImage, x: number, y: number, w: number, h: number, c: number) { + typeCheck(img); if (w == 0 || h == 0 || x >= img._width || y >= img._height || x + w - 1 < 0 || y + h - 1 < 0) return; img.makeWritable() @@ -114,6 +133,8 @@ namespace pxsim.ImageMethods { } export function mapRect(img: RefImage, x: number, y: number, w: number, h: number, c: RefBuffer) { + typeCheck(img); + BufferMethods.typeCheck(c); if (c.data.length < 16) return img.makeWritable() @@ -138,6 +159,7 @@ namespace pxsim.ImageMethods { } export function equals(img: RefImage, other: RefImage) { + typeCheck(img); if (!other || img._bpp != other._bpp || img._width != other._width || img._height != other._height) { return false; } @@ -153,6 +175,8 @@ namespace pxsim.ImageMethods { } export function getRows(img: RefImage, x: number, dst: RefBuffer) { + typeCheck(img); + BufferMethods.typeCheck(dst); x |= 0 if (!img.inRange(x, 0)) return @@ -172,6 +196,8 @@ namespace pxsim.ImageMethods { } export function setRows(img: RefImage, x: number, src: RefBuffer) { + typeCheck(img); + BufferMethods.typeCheck(src); x |= 0 if (!img.inRange(x, 0)) return @@ -191,12 +217,14 @@ namespace pxsim.ImageMethods { } export function clone(img: RefImage) { + typeCheck(img); let r = new RefImage(img._width, img._height, img._bpp) r.data.set(img.data) return r } export function flipX(img: RefImage) { + typeCheck(img); img.makeWritable() const w = img._width const h = img._height @@ -207,6 +235,7 @@ namespace pxsim.ImageMethods { export function flipY(img: RefImage) { + typeCheck(img); img.makeWritable() const w = img._width const h = img._height @@ -225,6 +254,7 @@ namespace pxsim.ImageMethods { } export function transposed(img: RefImage) { + typeCheck(img); const w = img._width const h = img._height const d = img.data @@ -244,6 +274,8 @@ namespace pxsim.ImageMethods { } export function copyFrom(img: RefImage, from: RefImage) { + typeCheck(img); + typeCheck(from); if (img._width != from._width || img._height != from._height || img._bpp != from._bpp) return; @@ -251,6 +283,7 @@ namespace pxsim.ImageMethods { } export function scroll(img: RefImage, dx: number, dy: number) { + typeCheck(img); img.makeWritable() dx |= 0 dy |= 0 @@ -276,6 +309,7 @@ namespace pxsim.ImageMethods { } export function replace(img: RefImage, from: number, to: number) { + typeCheck(img); to &= 0xf; const d = img.data for (let i = 0; i < d.length; ++i) @@ -283,6 +317,7 @@ namespace pxsim.ImageMethods { } export function doubledX(img: RefImage) { + typeCheck(img); const w = img._width const h = img._height const d = img.data @@ -300,6 +335,7 @@ namespace pxsim.ImageMethods { } export function doubledY(img: RefImage) { + typeCheck(img); const w = img._width const h = img._height const d = img.data @@ -324,10 +360,13 @@ namespace pxsim.ImageMethods { export function doubled(img: RefImage) { + typeCheck(img); return doubledX(doubledY(img)) } function drawImageCore(img: RefImage, from: RefImage, x: number, y: number, clear: boolean, check: boolean) { + typeCheck(img); + typeCheck(from); x |= 0 y |= 0 @@ -441,6 +480,7 @@ namespace pxsim.ImageMethods { } export function drawLine(img: RefImage, x0: number, y0: number, x1: number, y1: number, c: number) { + typeCheck(img); x0 |= 0 y0 |= 0 x1 |= 0 @@ -525,6 +565,8 @@ namespace pxsim.ImageMethods { } export function drawIcon(img: RefImage, icon: RefBuffer, x: number, y: number, color: number) { + typeCheck(img); + BufferMethods.typeCheck(icon); const src: Uint8Array = icon.data if (!image.isValidImage(icon)) return @@ -586,6 +628,7 @@ namespace pxsim.ImageMethods { } export function fillCircle(img: RefImage, cx: number, cy: number, r: number, c: number) { + typeCheck(img); let x = r - 1; let y = 0; let dx = 1; @@ -730,6 +773,7 @@ namespace pxsim.ImageMethods { } export function fillTriangle(img: RefImage, x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, c: number) { + typeCheck(img); if (x1 < x0) { [x1, x0] = [x0, x1]; [y1, y0] = [y0, y1]; @@ -785,6 +829,8 @@ namespace pxsim.ImageMethods { } export function _fillTriangle(img: RefImage, args: RefCollection) { + typeCheck(img); + Array_.typeCheck(args); fillTriangle( img, args.getAt(0) | 0, @@ -858,6 +904,8 @@ namespace pxsim.ImageMethods { } export function blitRow(img: RefImage, x: number, y: number, from: RefImage, fromX: number, fromH: number) { + typeCheck(img); + typeCheck(from); x |= 0 y |= 0 fromX |= 0 @@ -885,6 +933,9 @@ namespace pxsim.ImageMethods { } export function blit(dst: RefImage, src: RefImage, args: RefCollection): boolean { + typeCheck(dst); + typeCheck(src); + Array_.typeCheck(args); const xDst = args.getAt(0) as number; const yDst = args.getAt(1) as number; const wDst = args.getAt(2) as number; @@ -1064,6 +1115,10 @@ namespace pxsim.ImageMethods { } export function drawScaledRotatedImage(dst: RefImage, src: RefImage, args: RefCollection) { + typeCheck(dst); + typeCheck(src); + Array_.typeCheck(args); + const xDst = args.getAt(0) as number; const yDst = args.getAt(1) as number; if (xDst >= dst._width || yDst >= dst._height) { @@ -1127,6 +1182,10 @@ namespace pxsim.ImageMethods { } export function _checkOverlapsScaledRotatedImage(dst: RefImage, src: RefImage, args: RefCollection): boolean { + typeCheck(dst); + typeCheck(src); + Array_.typeCheck(args); + const xDst = args.getAt(0) as number; const yDst = args.getAt(1) as number; if (xDst >= dst._width || yDst >= dst._height) { @@ -1195,6 +1254,9 @@ namespace pxsim.ImageMethods { } export function _checkOverlapsTwoScaledRotatedImages(dst: RefImage, src: RefImage, args: RefCollection): boolean { + typeCheck(dst); + typeCheck(src); + const xDst = args.getAt(0) as number; const yDst = args.getAt(1) as number; const dstArgs = parseShearArgs(dst, args, 2); @@ -1339,6 +1401,12 @@ namespace pxsim.ImageMethods { return false; } + + export function typeCheck(value: RefImage) { + if (!(value instanceof RefImage)) { + pxsim.throwFailedCastError(value, "Image"); + } + } } @@ -1400,6 +1468,7 @@ namespace pxsim.image { } export function ofBuffer(buf: RefBuffer): RefImage { + BufferMethods.typeCheck(buf); const src: Uint8Array = buf.data let srcP = 4 @@ -1460,6 +1529,7 @@ namespace pxsim.image { } export function toBuffer(img: RefImage): RefBuffer { + ImageMethods.typeCheck(img); let col = byteHeight(img._height, img._bpp) let sz = 8 + img._width * col let r = new Uint8Array(sz) @@ -1503,6 +1573,7 @@ namespace pxsim.image { } export function doubledIcon(buf: RefBuffer): RefBuffer { + BufferMethods.typeCheck(buf); let img = ofBuffer(buf) if (!img) return null @@ -1513,6 +1584,7 @@ namespace pxsim.image { namespace pxsim.pxtcore { export function updateScreen(img: RefImage) { + ImageMethods.typeCheck(img); const state = getScreenState(); if (state) state.showImage(img) @@ -1523,6 +1595,7 @@ namespace pxsim.pxtcore { state.updateStats(s); } export function setPalette(b: RefBuffer) { + BufferMethods.typeCheck(b); const state = getScreenState(); if (state) state.setPalette(b) @@ -1533,6 +1606,7 @@ namespace pxsim.pxtcore { state.setupScreenStatusBar(barHeight); } export function updateScreenStatusBar(img: RefImage) { + ImageMethods.typeCheck(img); const state = getScreenState(); if (state) state.updateScreenStatusBar(img); diff --git a/libs/settings/sim/settings.ts b/libs/settings/sim/settings.ts index 6badf0c1a..b55ffa320 100644 --- a/libs/settings/sim/settings.ts +++ b/libs/settings/sim/settings.ts @@ -26,6 +26,7 @@ namespace pxsim.settings { } export function _set(key: string, buf: RefBuffer) { + BufferMethods.typeCheck(buf); key = encodeKey(key) const storage = board().storedState const prev = storage[key] diff --git a/libs/shader/sim/shader.ts b/libs/shader/sim/shader.ts index 9132a119d..2e215f52f 100644 --- a/libs/shader/sim/shader.ts +++ b/libs/shader/sim/shader.ts @@ -2,6 +2,8 @@ namespace pxsim.ShaderMethods { export function _mergeImage(dst: RefImage, src: RefImage, xy: number) { + ImageMethods.typeCheck(dst); + ImageMethods.typeCheck(src); mergeImage(dst, src, pxsim.ImageMethods.XX(xy), pxsim.ImageMethods.YY(xy)); } @@ -19,6 +21,9 @@ namespace pxsim.ShaderMethods { } export function _mapImage(dst: RefImage, src: RefImage, xy: number, buf: RefBuffer) { + ImageMethods.typeCheck(dst); + ImageMethods.typeCheck(src); + BufferMethods.typeCheck(buf); mapImage(dst, src, pxsim.ImageMethods.XX(xy), pxsim.ImageMethods.YY(xy), buf); } diff --git a/libs/storage/sim/storage.ts b/libs/storage/sim/storage.ts index 42f6d0153..1720cbfea 100644 --- a/libs/storage/sim/storage.ts +++ b/libs/storage/sim/storage.ts @@ -5,6 +5,7 @@ namespace pxsim.storage { } export function appendBuffer(filename: string, data: RefBuffer): void { + BufferMethods.typeCheck(data); const state = storageState(); let buf = state.files[filename]; if (!buf) buf = state.files[filename] = []; @@ -13,6 +14,7 @@ namespace pxsim.storage { } export function overwriteWithBuffer(filename: string, data: RefBuffer): void { + BufferMethods.typeCheck(data); const state = storageState(); const buf = []; for (let i = 0; i < data.data.length; ++i) diff --git a/libs/wifi---esp32/sim/wifisockets.ts b/libs/wifi---esp32/sim/wifisockets.ts index 3599b62e4..ead1587c0 100644 --- a/libs/wifi---esp32/sim/wifisockets.ts +++ b/libs/wifi---esp32/sim/wifisockets.ts @@ -207,6 +207,7 @@ namespace pxsim._wifi { } export async function socketWrite(fd: int32, data: RefBuffer): Promise { + BufferMethods.typeCheck(data); const sock = getSock(fd) if (!sock) return -11 @@ -284,6 +285,7 @@ namespace pxsim._wifi { namespace pxsim.crypto { export function _sha256(bufs: RefCollection): Promise { + Array_.typeCheck(bufs); let len = 0 const buffers = bufs.toArray().filter(e => e instanceof RefBuffer).map((b: RefBuffer) => { len += b.data.length