Skip to content

Commit 1430bc3

Browse files
committed
formats/fs_vtech.cpp: Properly recognize end of directory; fix block overrun in file_create; use std::min
1 parent 47891bc commit 1430bc3

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

src/lib/formats/fs_vtech.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "fsblk.h"
88
#include "vt_dsk.h"
99

10+
#include <algorithm>
11+
1012
using namespace fs;
1113

1214
namespace fs { const vtech_image VTECH; }
@@ -16,6 +18,7 @@ namespace fs { const vtech_image VTECH; }
1618
//
1719
// Track 0 sectors 0-14 have the file names. 16 bytes/entry
1820
// offset 0 : File type 'T' (basic), 'B' (binary), or some other letter (application-specific)
21+
// 0x00 = end of directory, 0x01 = deleted file
1922
// offset 1 : 0x3a
2023
// offset 2-9: File name
2124
// offset a : Track number of first file sector
@@ -152,10 +155,12 @@ std::tuple<fsblk_t::block_t::ptr, u32> vtech_impl::file_find(std::string_view na
152155
{
153156
for(int sect = 0; sect != 14; sect++) {
154157
auto bdir = m_blockdev.get(sect);
155-
for(u32 i = 0; i != 8; i ++) {
158+
for(u32 i = 0; i != 8; i++) {
156159
u32 off = i*16;
157160
u8 type = bdir->r8(off);
158-
if(type < 'A' || type > 'Z')
161+
if(type == 0x00)
162+
return std::make_tuple(fsblk_t::block_t::ptr(), 0xffffffff);
163+
if(type == 0x01)
159164
continue;
160165
if(bdir->r8(off+1) != ':')
161166
continue;
@@ -218,10 +223,12 @@ std::pair<std::error_condition, std::vector<dir_entry>> vtech_impl::directory_co
218223

219224
for(int sect = 0; sect != 14; sect++) {
220225
auto bdir = m_blockdev.get(sect);
221-
for(u32 i = 0; i != 8; i ++) {
226+
for(u32 i = 0; i != 8; i++) {
222227
u32 off = i*16;
223228
u8 type = bdir->r8(off);
224-
if(type < 'A' || type > 'Z')
229+
if(type == 0x00)
230+
return res;
231+
if(type == 0x01)
225232
continue;
226233
if(bdir->r8(off+1) != ':')
227234
continue;
@@ -262,10 +269,10 @@ std::error_condition vtech_impl::file_create(const std::vector<std::string> &pat
262269
// Find the key for the next unused entry
263270
for(int sect = 0; sect != 14; sect++) {
264271
auto bdir = m_blockdev.get(sect);
265-
for(u32 i = 0; i != 16; i ++) {
272+
for(u32 i = 0; i != 8; i++) {
266273
u32 off = i*16;
267274
u8 type = bdir->r8(off);
268-
if(type != 'T' && type != 'B') {
275+
if(type == 0x00 || type == 0x01) {
269276
std::string fname = meta.get_string(meta_name::name, "");
270277
fname.resize(8, ' ');
271278

@@ -304,9 +311,7 @@ std::pair<std::error_condition, std::vector<u8>> vtech_impl::file_read(const std
304311
if(track >= 40 || sector >= 16)
305312
break;
306313
auto dblk = m_blockdev.get(track*16 + sector);
307-
int size = len - pos;
308-
if(size > 126)
309-
size = 126;
314+
int size = std::min(len - pos, 126);
310315
dblk->read(0, data.data() + pos, size);
311316
pos += size;
312317
track = dblk->r8(126);
@@ -348,12 +353,10 @@ std::error_condition vtech_impl::file_write(const std::vector<std::string> &path
348353
free_blocks(tofree);
349354

350355
std::vector<std::pair<u8, u8>> blocks = allocate_blocks(need_ns);
351-
for(u32 i=0; i != need_ns; i ++) {
356+
for(u32 i=0; i != need_ns; i++) {
352357
auto dblk = m_blockdev.get(blocks[i].first * 16 + blocks[i].second);
353-
u32 len = new_len - i*126;
354-
if(len > 126)
355-
len = 126;
356-
else if(len < 126)
358+
u32 len = std::min<u32>(new_len - i*126, 126);
359+
if(len < 126)
357360
dblk->fill(0x00);
358361
dblk->write(0, data.data() + 126*i, len);
359362
if(i < need_ns) {

0 commit comments

Comments
 (0)