mirror of
https://github.com/SFML/SFML.git
synced 2024-11-29 06:41:05 +08:00
Fixed SoundBuffer::loadFromStream reading past the end of the stream (fixes #214)
This commit is contained in:
parent
323aa4e3e7
commit
5453d11d18
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user