Merge pull request #58 from lioncash/leak

MemoryWriter: Prevent potential leak within save()
This commit is contained in:
Phillip Stephens 2019-09-06 01:01:27 -07:00 committed by GitHub
commit 9aad64e740
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 17 deletions

View File

@ -10,7 +10,7 @@
namespace athena::io { namespace athena::io {
MemoryWriter::MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership) MemoryWriter::MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership)
: m_data((atUint8*)data), m_length(length), m_position(0), m_bufferOwned(takeOwnership) { : m_data(data), m_length(length), m_bufferOwned(takeOwnership) {
if (!data) { if (!data) {
atError(fmt("data cannot be NULL")); atError(fmt("data cannot be NULL"));
setError(); setError();
@ -156,7 +156,7 @@ void MemoryWriter::setData(atUint8* data, atUint64 length, bool takeOwnership) {
if (m_bufferOwned) if (m_bufferOwned)
delete m_data; delete m_data;
m_data = (atUint8*)data; m_data = data;
m_length = length; m_length = length;
m_position = 0; m_position = 0;
m_bufferOwned = takeOwnership; m_bufferOwned = takeOwnership;
@ -185,11 +185,11 @@ void MemoryWriter::save(std::string_view filename) {
return; return;
} }
if (!filename.empty()) if (!filename.empty()) {
m_filepath = filename; m_filepath = filename;
}
FILE* out = fopen(m_filepath.c_str(), "wb"); std::unique_ptr<FILE, decltype(&std::fclose)> out{std::fopen(m_filepath.c_str(), "wb"), std::fclose};
if (!out) { if (!out) {
atError(fmt("Unable to open file '{}'"), m_filepath); atError(fmt("Unable to open file '{}'"), m_filepath);
setError(); setError();
@ -200,22 +200,24 @@ void MemoryWriter::save(std::string_view filename) {
atUint64 blocksize = BLOCKSZ; atUint64 blocksize = BLOCKSZ;
do { do {
if (blocksize > m_length - done) if (blocksize > m_length - done) {
blocksize = m_length - done; blocksize = m_length - done;
}
atInt64 ret = fwrite(m_data + done, 1, blocksize, out); const atInt64 ret = std::fwrite(m_data + done, 1, blocksize, out.get());
if (ret < 0) { if (ret < 0) {
atError(fmt("Error writing data to disk")); atError(fmt("Error writing data to disk"));
setError(); setError();
return; return;
} else if (ret == 0) }
if (ret == 0) {
break; break;
}
done += blocksize; done += blocksize;
} while (done < m_length); } while (done < m_length);
fclose(out);
} }
void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length) { void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length) {
@ -258,15 +260,14 @@ void MemoryCopyWriter::resize(atUint64 newSize) {
} }
// Allocate and copy new buffer // Allocate and copy new buffer
atUint8* newArray = new atUint8[newSize]; auto newArray = std::make_unique<atUint8[]>(newSize);
memset(newArray, 0, newSize); if (m_dataCopy) {
std::memmove(newArray.get(), m_dataCopy.get(), m_length);
if (m_dataCopy) }
memmove(newArray, m_dataCopy.get(), m_length); m_dataCopy = std::move(newArray);
m_dataCopy.reset(newArray);
// Swap the pointer and size out for the new ones. // Swap the pointer and size out for the new ones.
m_data = newArray; m_data = m_dataCopy.get();
m_length = newSize; m_length = newSize;
} }