Fixed SoundBuffer::loadFromStream reading past the end of the stream (fixes #214)

This commit is contained in:
Laurent Gomila 2013-05-09 10:16:50 +02:00
parent 323aa4e3e7
commit 5453d11d18
2 changed files with 50 additions and 33 deletions

View File

@ -126,9 +126,9 @@ bool SoundFile::openRead(const void* data, std::size_t sizeInBytes)
io.tell = &Memory::tell;
// Initialize the memory data
m_memory.DataStart = static_cast<const char*>(data);
m_memory.DataPtr = m_memory.DataStart;
m_memory.TotalSize = sizeInBytes;
m_memory.begin = static_cast<const char*>(data);
m_memory.current = m_memory.begin;
m_memory.size = sizeInBytes;
// Open the sound file
SF_INFO fileInfo;
@ -160,9 +160,13 @@ bool SoundFile::openRead(InputStream& stream)
io.seek = &Stream::seek;
io.tell = &Stream::tell;
// Initialize the stream data
m_stream.source = &stream;
m_stream.size = stream.getSize();
// Open the sound file
SF_INFO fileInfo;
m_file = sf_open_virtual(&io, SFM_READ, &fileInfo, &stream);
m_file = sf_open_virtual(&io, SFM_READ, &fileInfo, &m_stream);
if (!m_file)
{
err() << "Failed to open sound file from stream (" << sf_strerror(m_file) << ")" << std::endl;
@ -313,7 +317,7 @@ int SoundFile::getFormatFromFilename(const std::string& filename)
sf_count_t SoundFile::Memory::getLength(void* user)
{
Memory* memory = static_cast<Memory*>(user);
return memory->TotalSize;
return memory->size;
}
@ -322,12 +326,12 @@ sf_count_t SoundFile::Memory::read(void* ptr, sf_count_t count, void* user)
{
Memory* memory = static_cast<Memory*>(user);
sf_count_t position = memory->DataPtr - memory->DataStart;
if (position + count >= memory->TotalSize)
count = memory->TotalSize - position;
sf_count_t position = tell(user);
if (position + count >= memory->size)
count = memory->size - position;
std::memcpy(ptr, memory->DataPtr, static_cast<std::size_t>(count));
memory->DataPtr += count;
std::memcpy(ptr, memory->current, static_cast<std::size_t>(count));
memory->current += count;
return count;
}
@ -339,18 +343,18 @@ sf_count_t SoundFile::Memory::seek(sf_count_t offset, int whence, void* user)
sf_count_t position = 0;
switch (whence)
{
case SEEK_SET : position = offset; break;
case SEEK_CUR : position = memory->DataPtr - memory->DataStart + offset; break;
case SEEK_END : position = memory->TotalSize - offset; break;
default : position = 0; break;
case SEEK_SET : position = offset; break;
case SEEK_CUR : position = memory->current - memory->begin + offset; break;
case SEEK_END : position = memory->size - offset; break;
default : position = 0; break;
}
if (position >= memory->TotalSize)
position = memory->TotalSize - 1;
if (position >= memory->size)
position = memory->size - 1;
else if (position < 0)
position = 0;
memory->DataPtr = memory->DataStart + position;
memory->current = memory->begin + position;
return position;
}
@ -359,36 +363,45 @@ sf_count_t SoundFile::Memory::seek(sf_count_t offset, int whence, void* user)
sf_count_t SoundFile::Memory::tell(void* user)
{
Memory* memory = static_cast<Memory*>(user);
return memory->DataPtr - memory->DataStart;
return memory->current - memory->begin;
}
////////////////////////////////////////////////////////////
sf_count_t SoundFile::Stream::getLength(void* userData)
{
sf::InputStream* stream = static_cast<sf::InputStream*>(userData);
return stream->getSize();
Stream* stream = static_cast<Stream*>(userData);
return stream->size;
}
////////////////////////////////////////////////////////////
sf_count_t SoundFile::Stream::read(void* ptr, sf_count_t count, void* userData)
{
sf::InputStream* stream = static_cast<sf::InputStream*>(userData);
return stream->read(reinterpret_cast<char*>(ptr), count);
Stream* stream = static_cast<Stream*>(userData);
Int64 position = stream->source->tell();
if (position != -1)
{
count = std::min(count, stream->size - position);
return stream->source->read(reinterpret_cast<char*>(ptr), count);
}
else
{
return -1;
}
}
////////////////////////////////////////////////////////////
sf_count_t SoundFile::Stream::seek(sf_count_t offset, int whence, void* userData)
{
sf::InputStream* stream = static_cast<sf::InputStream*>(userData);
Stream* stream = static_cast<Stream*>(userData);
switch (whence)
{
case SEEK_SET : return stream->seek(offset);
case SEEK_CUR : return stream->seek(stream->tell() + offset);
case SEEK_END : return stream->seek(stream->getSize() - offset);
default : return stream->seek(0);
case SEEK_SET : return stream->source->seek(offset);
case SEEK_CUR : return stream->source->seek(stream->source->tell() + offset);
case SEEK_END : return stream->source->seek(stream->size - offset);
default : return stream->source->seek(0);
}
}
@ -396,8 +409,8 @@ sf_count_t SoundFile::Stream::seek(sf_count_t offset, int whence, void* userData
////////////////////////////////////////////////////////////
sf_count_t SoundFile::Stream::tell(void* userData)
{
sf::InputStream* stream = static_cast<sf::InputStream*>(userData);
return stream->tell();
Stream* stream = static_cast<Stream*>(userData);
return stream->source->tell();
}
} // namespace priv

View File

@ -184,9 +184,9 @@ private :
////////////////////////////////////////////////////////////
struct Memory
{
const char* DataStart;
const char* DataPtr;
sf_count_t TotalSize;
const char* begin;
const char* current;
sf_count_t size;
static sf_count_t getLength(void* user);
static sf_count_t read(void* ptr, sf_count_t count, void* user);
@ -195,11 +195,14 @@ private :
};
////////////////////////////////////////////////////////////
/// \brief Callbacks for opening from stream
/// \brief Data and callbacks for opening from stream
///
////////////////////////////////////////////////////////////
struct Stream
{
InputStream* source;
Int64 size;
static sf_count_t getLength(void* user);
static sf_count_t read(void* ptr, sf_count_t count, void* user);
static sf_count_t seek(sf_count_t offset, int whence, void* user);
@ -211,6 +214,7 @@ private :
////////////////////////////////////////////////////////////
SNDFILE* m_file; ///< File descriptor
Memory m_memory; ///< Memory reading info
Stream m_stream; ///< Stream reading info
std::size_t m_sampleCount; ///< Total number of samples in the file
unsigned int m_channelCount; ///< Number of channels used by the sound
unsigned int m_sampleRate; ///< Number of samples per second