From 83771b538fe1f62042fc28f12f52bbe10c6070d3 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Fri, 31 May 2019 11:12:29 -0400 Subject: [PATCH] fs: check for file size bounds in GetC --- apps/zasm/glue.asm | 1 + apps/zasm/util.asm | 10 -------- kernel/core.asm | 15 +++++++++--- kernel/fs.asm | 55 ++++++++++++++++++++++++++++++++++++++++-- tools/emul/user.h | 1 + tools/emul/zasm/glue.asm | 35 ++++++++++++++------------- tools/tests/unit/test_core.asm | 21 ++++++++++++++++ tools/tests/zasm/test7.asm | 1 + 8 files changed, 107 insertions(+), 32 deletions(-) diff --git a/apps/zasm/glue.asm b/apps/zasm/glue.asm index 8d03714..1c7cf4e 100644 --- a/apps/zasm/glue.asm +++ b/apps/zasm/glue.asm @@ -36,6 +36,7 @@ ; fsGetC ; fsSeek ; fsTell +; cpHLDE ; FS_HANDLE_SIZE ; *** Variables *** diff --git a/apps/zasm/util.asm b/apps/zasm/util.asm index 41841f1..4208510 100644 --- a/apps/zasm/util.asm +++ b/apps/zasm/util.asm @@ -12,16 +12,6 @@ callHL: jp (hl) ret -; Compare HL with DE and sets Z and C in the same way as a regular cp X where -; HL is A and DE is X. -cpHLDE: - ld a, h - cp d - ret nz ; if not equal, flags are correct - ld a, l - cp e - ret ; flags are correct - ; HL - DE -> HL subDEFromHL: push af diff --git a/kernel/core.asm b/kernel/core.asm index c0a78e6..b82a421 100644 --- a/kernel/core.asm +++ b/kernel/core.asm @@ -22,6 +22,7 @@ addDE: .end: ld e, a pop af +noop: ; piggy backing on the first "ret" we have ret ; copy (DE) into DE, little endian style (addresses in z80 are always have @@ -71,6 +72,16 @@ subHL: pop af ret +; Compare HL with DE and sets Z and C in the same way as a regular cp X where +; HL is A and DE is X. +cpHLDE: + ld a, h + cp d + ret nz ; if not equal, flags are correct + ld a, l + cp e + ret ; flags are correct + ; Write the contents of HL in (DE) writeHLinDE: push af @@ -84,14 +95,12 @@ writeHLinDE: ret ; jump to the location pointed to by IX. This allows us to call IX instead of -; just jumping it. We use IX because we never use this for arguments. +; just jumping it. We use IX because we seldom use this for arguments. callIX: jp (ix) - ret callIY: jp (iy) - ret ; Ensures that Z is unset (more complicated than it sounds...) unsetZ: diff --git a/kernel/fs.asm b/kernel/fs.asm index 7f5da51..13bf653 100644 --- a/kernel/fs.asm +++ b/kernel/fs.asm @@ -87,7 +87,8 @@ ; Size in bytes of a FS handle: ; * 4 bytes for starting offset of the FS block ; * 2 bytes for current position relative to block's position -.equ FS_HANDLE_SIZE 6 +; * 2 bytes for file size +.equ FS_HANDLE_SIZE 8 .equ FS_ERR_NO_FS 0x5 .equ FS_ERR_NOT_FOUND 0x6 @@ -387,6 +388,11 @@ fsOpen: ; Current pos ld hl, FS_METASIZE call writeHLinDE + inc de + inc de + ; file size + ld hl, (FS_META+FS_META_FSIZE_OFFSET) + call writeHLinDE pop af pop de pop hl @@ -429,11 +435,37 @@ fsAdvanceH: pop af ret +; Sets Z according to whether file handle at (DE) is within bounds, that is, if +; current position is smaller than file size. +fsHandleWithinBounds: + push hl + ; current pos in HL, adjusted to remove FS_METASIZE + call fsTell + push de + push de \ pop ix + ; file size + ld e, (ix+6) + ld d, (ix+7) + call cpHLDE + pop de + pop hl + jr nc, .outOfBounds ; HL >= DE + cp a ; ensure Z + ret +.outOfBounds: + jp unsetZ ; returns + ; Read a byte in handle at (DE), put it into A and advance the handle's ; position. ; Z is set on success, unset if handle is at the end of the file. -; TODO: detect end of file fsGetC: + call fsHandleWithinBounds + jr z, .proceed + ; We want to unset Z, but also return 0 to ensure that a GetC that + ; doesn't check Z doesn't end up with false data. + xor a + jp unsetZ ; returns +.proceed: push ix call fsPlaceH push ix ; Save handle in IX for fsAdvanceH @@ -514,3 +546,22 @@ fsOn: pop de pop hl ret + +; Sets Z according to whether we have a filesystem mounted. +fsIsOn: + ; check whether (FS_GETC) is zero + push hl + push de + ld hl, (FS_GETC) + ld de, 0 + call cpHLDE + jr nz, .mounted + ; if equal, it means our FS is not mounted + call unsetZ + jr .end +.mounted: + cp a ; ensure Z +.end: + pop de + pop hl + ret diff --git a/tools/emul/user.h b/tools/emul/user.h index cf0a76e..88d8121 100644 --- a/tools/emul/user.h +++ b/tools/emul/user.h @@ -20,3 +20,4 @@ .equ fsGetC 0x2d .equ fsSeek 0x30 .equ fsTell 0x33 +.equ cpHLDE 0x36 diff --git a/tools/emul/zasm/glue.asm b/tools/emul/zasm/glue.asm index 09dd7a9..2b54c26 100644 --- a/tools/emul/zasm/glue.asm +++ b/tools/emul/zasm/glue.asm @@ -9,23 +9,24 @@ jp init ; 3 bytes ; *** JUMP TABLE *** -jp strncmp -jp addDE -jp addHL -jp upcase -jp unsetZ -jp intoDE -jp intoHL -jp writeHLinDE -jp findchar -jp parseHex -jp parseHexPair -jp blkSel -jp fsFindFN -jp fsOpen -jp fsGetC -jp fsSeek -jp fsTell +jp strncmp +jp addDE +jp addHL +jp upcase +jp unsetZ +jp intoDE +jp intoHL +jp writeHLinDE +jp findchar +jp parseHex +jp parseHexPair +jp blkSel +jp fsFindFN +jp fsOpen +jp fsGetC +jp fsSeek +jp fsTell +jp cpHLDE #include "core.asm" #include "parse.asm" diff --git a/tools/tests/unit/test_core.asm b/tools/tests/unit/test_core.asm index aa0c7ab..9724853 100644 --- a/tools/tests/unit/test_core.asm +++ b/tools/tests/unit/test_core.asm @@ -8,6 +8,7 @@ test: ld hl, 0xffff ld sp, hl + ; *** subHL *** ld hl, 0x123 ld a, 0x25 call subHL @@ -41,6 +42,26 @@ test: jp nz, fail call nexttest + ; *** cpHLDE *** + ld hl, 0x42 + ld de, 0x42 + call cpHLDE + jp nz, fail + jp c, fail + call nexttest + + ld de, 0x4242 + call cpHLDE + jp z, fail + jp nc, fail + call nexttest + + ld hl, 0x4243 + call cpHLDE + jp z, fail + jp c, fail + call nexttest + ; success xor a halt diff --git a/tools/tests/zasm/test7.asm b/tools/tests/zasm/test7.asm index 041f81b..54ea35a 100644 --- a/tools/tests/zasm/test7.asm +++ b/tools/tests/zasm/test7.asm @@ -20,6 +20,7 @@ .equ fsGetC 0x2d .equ fsSeek 0x30 .equ fsTell 0x33 +.equ cpHLDE 0x36 #include "zasm/const.asm" #include "zasm/util.asm"