mirror of
https://github.com/ksherlock/profuse.git
synced 2025-01-18 12:29:44 +00:00
add no-throwing validation code.
git-svn-id: https://profuse.googlecode.com/svn/branches/profuse_interim@376 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
c6165e16d2
commit
5ab8fd3d87
@ -47,42 +47,48 @@ DavexDiskImage::~DavexDiskImage()
|
||||
// scan and update usedBlocks?
|
||||
}
|
||||
|
||||
void DavexDiskImage::Validate(MappedFile *f)
|
||||
bool DavexDiskImage::Validate(MappedFile *f, const std::nothrow_t &)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "DavexDiskImage::Validate"
|
||||
|
||||
size_t size = f->length();
|
||||
const void * data = f->address();
|
||||
bool ok = false;
|
||||
unsigned blocks = (size / 512) - 1;
|
||||
|
||||
do {
|
||||
if (size < 512) break;
|
||||
if (size % 512) break;
|
||||
|
||||
if (size < 512) return false;
|
||||
if (size % 512) return false;
|
||||
|
||||
// identity.
|
||||
if (std::memcmp(data, IdentityCheck, 16))
|
||||
break;
|
||||
return false;
|
||||
|
||||
// file format.
|
||||
if (Read8(data, 0x10) != 0)
|
||||
break;
|
||||
return false;
|
||||
|
||||
// total blocks
|
||||
if (Read32(data, 33) != blocks)
|
||||
break;
|
||||
return false;
|
||||
|
||||
// file number -- must be 1
|
||||
if (Read8(data, 64) != 1)
|
||||
break;
|
||||
return false;
|
||||
|
||||
ok = true;
|
||||
} while (false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DavexDiskImage::Validate(MappedFile *f)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "DavexDiskImage::Validate"
|
||||
|
||||
|
||||
if (!ok)
|
||||
if (!Validate(f, std::nothrow))
|
||||
throw Exception(__METHOD__ ": Invalid file format.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BlockDevicePointer DavexDiskImage::Open(MappedFile *file)
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __DAVEXDISKIMAGE_H__
|
||||
|
||||
#include <string>
|
||||
#include <new>
|
||||
|
||||
#include <Device/BlockDevice.h>
|
||||
#include <Device/DiskImage.h>
|
||||
@ -22,12 +23,15 @@ public:
|
||||
|
||||
virtual BlockCachePointer createBlockCache();
|
||||
|
||||
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||
static bool Validate(MappedFile *);
|
||||
|
||||
private:
|
||||
|
||||
DavexDiskImage();
|
||||
|
||||
DavexDiskImage(MappedFile *);
|
||||
static void Validate(MappedFile *);
|
||||
|
||||
|
||||
bool _changed;
|
||||
std::string _volumeName;
|
||||
|
@ -126,18 +126,33 @@ BlockDevicePointer ProDOSOrderDiskImage::Open(MappedFile *file)
|
||||
return MAKE_SHARED(ProDOSOrderDiskImage, file);
|
||||
}
|
||||
|
||||
void ProDOSOrderDiskImage::Validate(MappedFile *f)
|
||||
|
||||
bool ProDOSOrderDiskImage::Validate(MappedFile *f, const std::nothrow_t &)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "ProDOSOrderDiskImage::Validate"
|
||||
|
||||
|
||||
size_t size = f->length();
|
||||
|
||||
if (size % 512)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ProDOSOrderDiskImage::Validate(MappedFile *f)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "ProDOSOrderDiskImage::Validate"
|
||||
|
||||
if (!f || !f->isValid()) throw Exception(__METHOD__ ": File not set.");
|
||||
|
||||
size_t size = f->length();
|
||||
|
||||
if (size % 512)
|
||||
if (!Validate(f))
|
||||
throw Exception(__METHOD__ ": Invalid file format.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BlockCachePointer ProDOSOrderDiskImage::createBlockCache()
|
||||
@ -157,6 +172,8 @@ DOSOrderDiskImage::DOSOrderDiskImage(const char *name, bool readOnly) :
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
DOSOrderDiskImage::DOSOrderDiskImage(MappedFile *file) :
|
||||
DiskImage(file)
|
||||
{
|
||||
@ -182,16 +199,30 @@ BlockDevicePointer DOSOrderDiskImage::Open(MappedFile *file)
|
||||
|
||||
}
|
||||
|
||||
void DOSOrderDiskImage::Validate(MappedFile *f)
|
||||
bool DOSOrderDiskImage::Validate(MappedFile *f, const std::nothrow_t &)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "DOSOrderDiskImage::Validate"
|
||||
|
||||
size_t size = f->length();
|
||||
|
||||
if (size % 512)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool DOSOrderDiskImage::Validate(MappedFile *f)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "DOSOrderDiskImage::Validate"
|
||||
|
||||
if (!f || !f->isValid()) throw Exception(__METHOD__ ": File not set.");
|
||||
|
||||
size_t size = f->length();
|
||||
|
||||
if (size % 512)
|
||||
if (!Validate(f))
|
||||
throw Exception(__METHOD__ ": Invalid file format.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -63,12 +63,13 @@ public:
|
||||
|
||||
virtual BlockCachePointer createBlockCache();
|
||||
|
||||
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||
static bool Validate(MappedFile *);
|
||||
|
||||
private:
|
||||
ProDOSOrderDiskImage();
|
||||
|
||||
|
||||
ProDOSOrderDiskImage(MappedFile *);
|
||||
static void Validate(MappedFile *);
|
||||
};
|
||||
|
||||
class DOSOrderDiskImage : public DiskImage {
|
||||
@ -78,11 +79,13 @@ public:
|
||||
static BlockDevicePointer Create(const char *name, size_t blocks);
|
||||
static BlockDevicePointer Open(MappedFile *);
|
||||
|
||||
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||
static bool Validate(MappedFile *);
|
||||
|
||||
private:
|
||||
DOSOrderDiskImage();
|
||||
|
||||
DOSOrderDiskImage(MappedFile *);
|
||||
static void Validate(MappedFile *);
|
||||
};
|
||||
|
||||
|
||||
|
@ -62,48 +62,6 @@ struct record_thread
|
||||
NuThreadIdx thread_index;
|
||||
};
|
||||
|
||||
/*
|
||||
* callback function to scan contents.
|
||||
* (not used).
|
||||
*
|
||||
*/
|
||||
static NuResult ContentFunction(NuArchive *archive, void *vp)
|
||||
{
|
||||
const NuRecord *record = (const NuRecord *)vp;
|
||||
|
||||
/*
|
||||
* The application must not attempt to retain a copy of "pRecord"
|
||||
* after the callback returns, as the structure may be freed.
|
||||
* Anything of interest should be copied out.
|
||||
*/
|
||||
|
||||
|
||||
for (unsigned i = 0; i < NuRecordGetNumThreads(record); ++i)
|
||||
{
|
||||
const NuThread *thread = NuGetThread(record, i);
|
||||
|
||||
|
||||
printf("%ld, %ld\n", (long)record->recordIdx, (long)thread->threadIdx);
|
||||
|
||||
if (NuGetThreadID(thread) == kNuThreadIDDiskImage)
|
||||
{
|
||||
record_thread *rt;
|
||||
|
||||
NuGetExtraData(archive, (void **)&rt);
|
||||
if (rt)
|
||||
{
|
||||
rt->record_index = record->recordIdx;
|
||||
rt->thread_index = thread->threadIdx;
|
||||
}
|
||||
|
||||
return kNuAbort;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
static record_thread FindDiskImageThread(NuArchive *archive)
|
||||
{
|
||||
@ -245,3 +203,34 @@ BlockDevicePointer SDKImage::Open(const char *name)
|
||||
return ProDOSOrderDiskImage::Open(&file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SDKImage::Validate(MappedFile * f, const std::nothrow_t &)
|
||||
{
|
||||
// NuFile, alternating ASCII.
|
||||
static const char IdentityCheck[6] = { 0x4E, 0xF5, 0x46, 0xE9, 0x6C, 0xE5 };
|
||||
|
||||
if (f->length() < sizeof(IdentityCheck))
|
||||
return false;
|
||||
|
||||
if (std::memcmp(f->address(), IdentityCheck, sizeof(IdentityCheck)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool SDKImage::Validate(MappedFile * f)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "SDKImage::Validate"
|
||||
|
||||
if (!Validate(f))
|
||||
throw Exception(__METHOD__ ": Invalid file format.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -18,6 +18,9 @@ namespace Device {
|
||||
static BlockDevicePointer Open(const char *name);
|
||||
|
||||
|
||||
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||
static bool Validate(MappedFile *);
|
||||
|
||||
private:
|
||||
SDKImage();
|
||||
SDKImage(const SDKImage &);
|
||||
|
@ -100,42 +100,47 @@ BlockDevicePointer UniversalDiskImage::Open(MappedFile *file)
|
||||
* TODO -- honor read-only flag.
|
||||
*
|
||||
*/
|
||||
void UniversalDiskImage::Validate(MappedFile *file)
|
||||
|
||||
bool UniversalDiskImage::Validate(MappedFile *file, const std::nothrow_t &)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "UniversalDiskImage::Validate"
|
||||
|
||||
const void *data = file->address();
|
||||
size_t size = file->length();
|
||||
bool ok = false;
|
||||
|
||||
unsigned blocks = 0;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
|
||||
if (size < 64) break;
|
||||
if (size < 64) return false;
|
||||
|
||||
if (std::memcmp(data, "2IMG", 4)) break;
|
||||
if (std::memcmp(data, "2IMG", 4)) return false;
|
||||
|
||||
// only prodos supported, for now...
|
||||
// TODO -- Dos Order, Nibble support.
|
||||
if (Read32(data, 0x0c) != 1) break;
|
||||
if (Read32(data, 0x0c) != 1) return false;
|
||||
|
||||
blocks = Read32(data, 0x14);
|
||||
offset = Read32(data, 0x18);
|
||||
|
||||
// file size == blocks * 512
|
||||
if (Read32(data, 0x1c) != blocks * 512) break;
|
||||
if (Read32(data, 0x1c) != blocks * 512) return false;
|
||||
|
||||
if (offset + blocks * 512 > size) break;
|
||||
if (offset + blocks * 512 > size) return false;
|
||||
|
||||
ok = true;
|
||||
} while (false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
bool UniversalDiskImage::Validate(MappedFile *file)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "UniversalDiskImage::Validate"
|
||||
|
||||
if (!Validate(file, std::nothrow))
|
||||
throw Exception(__METHOD__ ": Invalid file format.");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,12 +22,15 @@ public:
|
||||
virtual BlockCachePointer createBlockCache();
|
||||
|
||||
|
||||
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||
static bool Validate(MappedFile *);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
UniversalDiskImage();
|
||||
|
||||
UniversalDiskImage(MappedFile *);
|
||||
static void Validate(MappedFile *);
|
||||
|
||||
uint32_t _format;
|
||||
uint32_t _flags;
|
||||
|
Loading…
x
Reference in New Issue
Block a user