diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 03e536aca..65a7fc110 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -328,6 +328,12 @@ bool FilesystemNode::rename(const string& newfile) return (_realNode && _realNode->exists()) ? _realNode->rename(newfile) : false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +size_t FilesystemNode::getSize() const +{ + return (_realNode && _realNode->exists()) ? _realNode->getSize() : 0; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - size_t FilesystemNode::read(ByteBuffer& buffer, size_t size) const { diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index 10802157d..fc9587ec3 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -243,6 +243,13 @@ class FilesystemNode */ bool rename(const string& newfile); + /** + * Get the size of the current node path. + * + * @return Size (in bytes) of the current node path. + */ + size_t getSize() const; + /** * Read data (binary format) into the given buffer. * @@ -438,6 +445,13 @@ class AbstractFSNode */ virtual bool rename(const string& newfile) = 0; + /** + * Get the size of the current node path. + * + * @return Size (in bytes) of the current node path. + */ + virtual size_t getSize() const { return 0; } + /** * Read data (binary format) into the given buffer. * diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index d2c9606d6..36f17cf82 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -787,10 +787,22 @@ ByteBuffer OSystem::openROM(const FilesystemNode& rom, size_t& size, if(!isValidROM && showErrorMessage) throw runtime_error("Unrecognized ROM file type"); - // Next check for a proper file size: - // Streaming ROMs read only a portion of the file - // TODO: Otherwise, cap the size to the maximum Cart size + // Next check for a proper file size + // Streaming ROMs read only a portion of the file + // Otherwise the size to read is 0 (meaning read the entire file) const size_t sizeToRead = CartDetector::isProbablyMVC(rom); + const bool isStreaming = sizeToRead > 0; + + // Make sure we only read up to the maximum supported cart size + const bool isValidSize = isValidROM && (isStreaming || + rom.getSize() <= Cartridge::maxSize()); + if(!isValidSize) + { + if(showErrorMessage) + throw runtime_error("ROM file too large"); + else + return nullptr; + } // Now we can try to open the file ByteBuffer image; diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx index 79aaec46c..3582f4cbe 100644 --- a/src/unix/FSNodePOSIX.cxx +++ b/src/unix/FSNodePOSIX.cxx @@ -180,6 +180,13 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode) con return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +size_t FilesystemNodePOSIX::getSize() const +{ + struct stat st; + return (stat(_path.c_str(), &st) == 0) ? st.st_size : 0; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNodePOSIX::makeDir() { diff --git a/src/unix/FSNodePOSIX.hxx b/src/unix/FSNodePOSIX.hxx index 762debc4a..1c7a8f10d 100644 --- a/src/unix/FSNodePOSIX.hxx +++ b/src/unix/FSNodePOSIX.hxx @@ -73,6 +73,7 @@ class FilesystemNodePOSIX : public AbstractFSNode bool makeDir() override; bool rename(const string& newfile) override; + size_t getSize() const override; bool getChildren(AbstractFSList& list, ListMode mode) const override; AbstractFSNodePtr getParent() const override;