mirror of
https://github.com/ksherlock/profuse.git
synced 2024-06-11 08:29:30 +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?
|
// 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();
|
||||||
|
unsigned blocks = (size / 512) - 1;
|
||||||
|
|
||||||
|
|
||||||
|
if (size < 512) return false;
|
||||||
|
if (size % 512) return false;
|
||||||
|
|
||||||
|
// identity.
|
||||||
|
if (std::memcmp(data, IdentityCheck, 16))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// file format.
|
||||||
|
if (Read8(data, 0x10) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// total blocks
|
||||||
|
if (Read32(data, 33) != blocks)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// file number -- must be 1
|
||||||
|
if (Read8(data, 64) != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DavexDiskImage::Validate(MappedFile *f)
|
||||||
{
|
{
|
||||||
#undef __METHOD__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "DavexDiskImage::Validate"
|
#define __METHOD__ "DavexDiskImage::Validate"
|
||||||
|
|
||||||
size_t size = f->length();
|
|
||||||
const void * data = f->address();
|
if (!Validate(f, std::nothrow))
|
||||||
bool ok = false;
|
|
||||||
unsigned blocks = (size / 512) - 1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (size < 512) break;
|
|
||||||
if (size % 512) break;
|
|
||||||
|
|
||||||
// identity.
|
|
||||||
if (std::memcmp(data, IdentityCheck, 16))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// file format.
|
|
||||||
if (Read8(data, 0x10) != 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// total blocks
|
|
||||||
if (Read32(data, 33) != blocks)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// file number -- must be 1
|
|
||||||
if (Read8(data, 64) != 1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ok = true;
|
|
||||||
} while (false);
|
|
||||||
|
|
||||||
|
|
||||||
if (!ok)
|
|
||||||
throw Exception(__METHOD__ ": Invalid file format.");
|
throw Exception(__METHOD__ ": Invalid file format.");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDevicePointer DavexDiskImage::Open(MappedFile *file)
|
BlockDevicePointer DavexDiskImage::Open(MappedFile *file)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __DAVEXDISKIMAGE_H__
|
#define __DAVEXDISKIMAGE_H__
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include <Device/BlockDevice.h>
|
#include <Device/BlockDevice.h>
|
||||||
#include <Device/DiskImage.h>
|
#include <Device/DiskImage.h>
|
||||||
|
@ -22,12 +23,15 @@ public:
|
||||||
|
|
||||||
virtual BlockCachePointer createBlockCache();
|
virtual BlockCachePointer createBlockCache();
|
||||||
|
|
||||||
|
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||||
|
static bool Validate(MappedFile *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DavexDiskImage();
|
DavexDiskImage();
|
||||||
|
|
||||||
DavexDiskImage(MappedFile *);
|
DavexDiskImage(MappedFile *);
|
||||||
static void Validate(MappedFile *);
|
|
||||||
|
|
||||||
bool _changed;
|
bool _changed;
|
||||||
std::string _volumeName;
|
std::string _volumeName;
|
||||||
|
|
|
@ -126,18 +126,33 @@ BlockDevicePointer ProDOSOrderDiskImage::Open(MappedFile *file)
|
||||||
return MAKE_SHARED(ProDOSOrderDiskImage, 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__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "ProDOSOrderDiskImage::Validate"
|
#define __METHOD__ "ProDOSOrderDiskImage::Validate"
|
||||||
|
|
||||||
if (!f || !f->isValid()) throw Exception(__METHOD__ ": File not set.");
|
if (!f || !f->isValid()) throw Exception(__METHOD__ ": File not set.");
|
||||||
|
|
||||||
size_t size = f->length();
|
if (!Validate(f))
|
||||||
|
|
||||||
if (size % 512)
|
|
||||||
throw Exception(__METHOD__ ": Invalid file format.");
|
throw Exception(__METHOD__ ": Invalid file format.");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockCachePointer ProDOSOrderDiskImage::createBlockCache()
|
BlockCachePointer ProDOSOrderDiskImage::createBlockCache()
|
||||||
|
@ -157,6 +172,8 @@ DOSOrderDiskImage::DOSOrderDiskImage(const char *name, bool readOnly) :
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DOSOrderDiskImage::DOSOrderDiskImage(MappedFile *file) :
|
DOSOrderDiskImage::DOSOrderDiskImage(MappedFile *file) :
|
||||||
DiskImage(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__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "DOSOrderDiskImage::Validate"
|
#define __METHOD__ "DOSOrderDiskImage::Validate"
|
||||||
|
|
||||||
if (!f || !f->isValid()) throw Exception(__METHOD__ ": File not set.");
|
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.");
|
throw Exception(__METHOD__ ": Invalid file format.");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,13 +62,14 @@ public:
|
||||||
|
|
||||||
|
|
||||||
virtual BlockCachePointer createBlockCache();
|
virtual BlockCachePointer createBlockCache();
|
||||||
|
|
||||||
|
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||||
|
static bool Validate(MappedFile *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProDOSOrderDiskImage();
|
ProDOSOrderDiskImage();
|
||||||
|
|
||||||
|
|
||||||
ProDOSOrderDiskImage(MappedFile *);
|
ProDOSOrderDiskImage(MappedFile *);
|
||||||
static void Validate(MappedFile *);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DOSOrderDiskImage : public DiskImage {
|
class DOSOrderDiskImage : public DiskImage {
|
||||||
|
@ -78,11 +79,13 @@ public:
|
||||||
static BlockDevicePointer Create(const char *name, size_t blocks);
|
static BlockDevicePointer Create(const char *name, size_t blocks);
|
||||||
static BlockDevicePointer Open(MappedFile *);
|
static BlockDevicePointer Open(MappedFile *);
|
||||||
|
|
||||||
|
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||||
|
static bool Validate(MappedFile *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DOSOrderDiskImage();
|
DOSOrderDiskImage();
|
||||||
|
|
||||||
DOSOrderDiskImage(MappedFile *);
|
DOSOrderDiskImage(MappedFile *);
|
||||||
static void Validate(MappedFile *);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -62,48 +62,6 @@ struct record_thread
|
||||||
NuThreadIdx thread_index;
|
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)
|
static record_thread FindDiskImageThread(NuArchive *archive)
|
||||||
{
|
{
|
||||||
|
@ -245,3 +203,34 @@ BlockDevicePointer SDKImage::Open(const char *name)
|
||||||
return ProDOSOrderDiskImage::Open(&file);
|
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 BlockDevicePointer Open(const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||||
|
static bool Validate(MappedFile *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDKImage();
|
SDKImage();
|
||||||
SDKImage(const SDKImage &);
|
SDKImage(const SDKImage &);
|
||||||
|
|
|
@ -100,42 +100,47 @@ BlockDevicePointer UniversalDiskImage::Open(MappedFile *file)
|
||||||
* TODO -- honor read-only flag.
|
* TODO -- honor read-only flag.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void UniversalDiskImage::Validate(MappedFile *file)
|
|
||||||
|
bool UniversalDiskImage::Validate(MappedFile *file, const std::nothrow_t &)
|
||||||
{
|
{
|
||||||
#undef __METHOD__
|
#undef __METHOD__
|
||||||
#define __METHOD__ "UniversalDiskImage::Validate"
|
#define __METHOD__ "UniversalDiskImage::Validate"
|
||||||
|
|
||||||
const void *data = file->address();
|
const void *data = file->address();
|
||||||
size_t size = file->length();
|
size_t size = file->length();
|
||||||
bool ok = false;
|
|
||||||
unsigned blocks = 0;
|
unsigned blocks = 0;
|
||||||
unsigned offset = 0;
|
unsigned offset = 0;
|
||||||
|
|
||||||
do {
|
|
||||||
|
if (size < 64) return false;
|
||||||
if (size < 64) break;
|
|
||||||
|
|
||||||
if (std::memcmp(data, "2IMG", 4)) break;
|
|
||||||
|
|
||||||
// only prodos supported, for now...
|
|
||||||
// TODO -- Dos Order, Nibble support.
|
|
||||||
if (Read32(data, 0x0c) != 1) break;
|
|
||||||
|
|
||||||
blocks = Read32(data, 0x14);
|
|
||||||
offset = Read32(data, 0x18);
|
|
||||||
|
|
||||||
// file size == blocks * 512
|
|
||||||
if (Read32(data, 0x1c) != blocks * 512) break;
|
|
||||||
|
|
||||||
if (offset + blocks * 512 > size) break;
|
|
||||||
|
|
||||||
ok = true;
|
|
||||||
} while (false);
|
|
||||||
|
|
||||||
if (!ok)
|
if (std::memcmp(data, "2IMG", 4)) return false;
|
||||||
|
|
||||||
|
// only prodos supported, for now...
|
||||||
|
// TODO -- Dos Order, Nibble support.
|
||||||
|
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) return false;
|
||||||
|
|
||||||
|
if (offset + blocks * 512 > size) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UniversalDiskImage::Validate(MappedFile *file)
|
||||||
|
{
|
||||||
|
#undef __METHOD__
|
||||||
|
#define __METHOD__ "UniversalDiskImage::Validate"
|
||||||
|
|
||||||
|
if (!Validate(file, std::nothrow))
|
||||||
throw Exception(__METHOD__ ": Invalid file format.");
|
throw Exception(__METHOD__ ": Invalid file format.");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,16 @@ public:
|
||||||
|
|
||||||
virtual BlockCachePointer createBlockCache();
|
virtual BlockCachePointer createBlockCache();
|
||||||
|
|
||||||
|
|
||||||
|
static bool Validate(MappedFile *, const std::nothrow_t &);
|
||||||
|
static bool Validate(MappedFile *);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
UniversalDiskImage();
|
UniversalDiskImage();
|
||||||
|
|
||||||
UniversalDiskImage(MappedFile *);
|
UniversalDiskImage(MappedFile *);
|
||||||
static void Validate(MappedFile *);
|
|
||||||
|
|
||||||
uint32_t _format;
|
uint32_t _format;
|
||||||
uint32_t _flags;
|
uint32_t _flags;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user