(MovieCart) Limit reading of image data to single frame

when its likely an MVC file. This avoids reading of GB of data.
This commit is contained in:
Rob Bairos 2021-04-05 09:27:51 -04:00
parent a92a33b4da
commit 44e15ff86f
3 changed files with 40 additions and 2 deletions

View File

@ -19,6 +19,7 @@
#include "Logger.hxx"
#include "CartDetector.hxx"
#include "MovieCart/StreamReader.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bankswitch::Type CartDetector::autodetectType(const ByteBuffer& image, size_t size)
@ -694,11 +695,34 @@ bool CartDetector::isProbablyMDM(const ByteBuffer& image, size_t size)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablyMVC(const ByteBuffer& image, size_t size)
{
// MVC version 0, frame 0
// MVC version 0
uInt8 sig[] = { 'M', 'V', 'C', 0 };
return searchForBytes(image, std::min<size_t>(size, 5), sig, 4);
int sigSize = sizeof(sig);
return searchForBytes(image, std::min<size_t>(size, sigSize+1), sig, sigSize);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
size_t CartDetector::isProbablyMVC(std::istream &in, size_t maxSize)
{
const size_t frameSize = 2 * MVC_FIELD_PAD_SIZE;
bool found = false;
// Returns size of field if stream is probably an MVC movie cartridge
if (maxSize >= frameSize)
{
auto pos = in.tellg();
ByteBuffer image = make_unique<uInt8[]>(frameSize);
in.read(reinterpret_cast<char*>(image.get()), frameSize);
in.seekg(pos);
found = isProbablyMVC(image, frameSize);
}
return found ? frameSize : 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDetector::isProbablySB(const ByteBuffer& image, size_t size)

View File

@ -40,6 +40,13 @@ class CartDetector
*/
static Bankswitch::Type autodetectType(const ByteBuffer& image, size_t size);
/**
MVC cartridges are of arbitary large length
Returns size of frame if stream is probably an MVC movie cartridge
*/
static size_t isProbablyMVC(std::istream &in, size_t size);
private:
/**
Search the image for the specified byte signature

View File

@ -17,6 +17,7 @@
#include "FSNodeFactory.hxx"
#include "FSNode.hxx"
#include "CartDetector.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilesystemNode::FilesystemNode(const AbstractFSNodePtr& realNode)
@ -355,6 +356,12 @@ size_t FilesystemNode::read(ByteBuffer& buffer) const
if (sizeRead == 0)
throw runtime_error("Zero-byte file");
// In the case of MVC (MovieCart) files, contents are streaming data
// of arbitrary length, so just read first frame.
size_t subSize = CartDetector::isProbablyMVC(in, sizeRead);
if (subSize > 0)
sizeRead = subSize;
buffer = make_unique<uInt8[]>(sizeRead);
in.read(reinterpret_cast<char*>(buffer.get()), sizeRead);
}