mirror of
https://github.com/SFML/SFML.git
synced 2024-12-01 15:51:04 +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;
|
io.tell = &Memory::tell;
|
||||||
|
|
||||||
// Initialize the memory data
|
// Initialize the memory data
|
||||||
m_memory.DataStart = static_cast<const char*>(data);
|
m_memory.begin = static_cast<const char*>(data);
|
||||||
m_memory.DataPtr = m_memory.DataStart;
|
m_memory.current = m_memory.begin;
|
||||||
m_memory.TotalSize = sizeInBytes;
|
m_memory.size = sizeInBytes;
|
||||||
|
|
||||||
// Open the sound file
|
// Open the sound file
|
||||||
SF_INFO fileInfo;
|
SF_INFO fileInfo;
|
||||||
@ -160,9 +160,13 @@ bool SoundFile::openRead(InputStream& stream)
|
|||||||
io.seek = &Stream::seek;
|
io.seek = &Stream::seek;
|
||||||
io.tell = &Stream::tell;
|
io.tell = &Stream::tell;
|
||||||
|
|
||||||
|
// Initialize the stream data
|
||||||
|
m_stream.source = &stream;
|
||||||
|
m_stream.size = stream.getSize();
|
||||||
|
|
||||||
// Open the sound file
|
// Open the sound file
|
||||||
SF_INFO fileInfo;
|
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)
|
if (!m_file)
|
||||||
{
|
{
|
||||||
err() << "Failed to open sound file from stream (" << sf_strerror(m_file) << ")" << std::endl;
|
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)
|
sf_count_t SoundFile::Memory::getLength(void* user)
|
||||||
{
|
{
|
||||||
Memory* memory = static_cast<Memory*>(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);
|
Memory* memory = static_cast<Memory*>(user);
|
||||||
|
|
||||||
sf_count_t position = memory->DataPtr - memory->DataStart;
|
sf_count_t position = tell(user);
|
||||||
if (position + count >= memory->TotalSize)
|
if (position + count >= memory->size)
|
||||||
count = memory->TotalSize - position;
|
count = memory->size - position;
|
||||||
|
|
||||||
std::memcpy(ptr, memory->DataPtr, static_cast<std::size_t>(count));
|
std::memcpy(ptr, memory->current, static_cast<std::size_t>(count));
|
||||||
memory->DataPtr += count;
|
memory->current += count;
|
||||||
return 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;
|
sf_count_t position = 0;
|
||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
case SEEK_SET : position = offset; break;
|
case SEEK_SET : position = offset; break;
|
||||||
case SEEK_CUR : position = memory->DataPtr - memory->DataStart + offset; break;
|
case SEEK_CUR : position = memory->current - memory->begin + offset; break;
|
||||||
case SEEK_END : position = memory->TotalSize - offset; break;
|
case SEEK_END : position = memory->size - offset; break;
|
||||||
default : position = 0; break;
|
default : position = 0; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position >= memory->TotalSize)
|
if (position >= memory->size)
|
||||||
position = memory->TotalSize - 1;
|
position = memory->size - 1;
|
||||||
else if (position < 0)
|
else if (position < 0)
|
||||||
position = 0;
|
position = 0;
|
||||||
|
|
||||||
memory->DataPtr = memory->DataStart + position;
|
memory->current = memory->begin + position;
|
||||||
return 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)
|
sf_count_t SoundFile::Memory::tell(void* user)
|
||||||
{
|
{
|
||||||
Memory* memory = static_cast<Memory*>(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_count_t SoundFile::Stream::getLength(void* userData)
|
||||||
{
|
{
|
||||||
sf::InputStream* stream = static_cast<sf::InputStream*>(userData);
|
Stream* stream = static_cast<Stream*>(userData);
|
||||||
return stream->getSize();
|
return stream->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
sf_count_t SoundFile::Stream::read(void* ptr, sf_count_t count, void* userData)
|
sf_count_t SoundFile::Stream::read(void* ptr, sf_count_t count, void* userData)
|
||||||
{
|
{
|
||||||
sf::InputStream* stream = static_cast<sf::InputStream*>(userData);
|
Stream* stream = static_cast<Stream*>(userData);
|
||||||
return stream->read(reinterpret_cast<char*>(ptr), count);
|
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_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)
|
switch (whence)
|
||||||
{
|
{
|
||||||
case SEEK_SET : return stream->seek(offset);
|
case SEEK_SET : return stream->source->seek(offset);
|
||||||
case SEEK_CUR : return stream->seek(stream->tell() + offset);
|
case SEEK_CUR : return stream->source->seek(stream->source->tell() + offset);
|
||||||
case SEEK_END : return stream->seek(stream->getSize() - offset);
|
case SEEK_END : return stream->source->seek(stream->size - offset);
|
||||||
default : return stream->seek(0);
|
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_count_t SoundFile::Stream::tell(void* userData)
|
||||||
{
|
{
|
||||||
sf::InputStream* stream = static_cast<sf::InputStream*>(userData);
|
Stream* stream = static_cast<Stream*>(userData);
|
||||||
return stream->tell();
|
return stream->source->tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
@ -184,9 +184,9 @@ private :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
struct Memory
|
struct Memory
|
||||||
{
|
{
|
||||||
const char* DataStart;
|
const char* begin;
|
||||||
const char* DataPtr;
|
const char* current;
|
||||||
sf_count_t TotalSize;
|
sf_count_t size;
|
||||||
|
|
||||||
static sf_count_t getLength(void* user);
|
static sf_count_t getLength(void* user);
|
||||||
static sf_count_t read(void* ptr, sf_count_t count, 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
|
struct Stream
|
||||||
{
|
{
|
||||||
|
InputStream* source;
|
||||||
|
Int64 size;
|
||||||
|
|
||||||
static sf_count_t getLength(void* user);
|
static sf_count_t getLength(void* user);
|
||||||
static sf_count_t read(void* ptr, sf_count_t count, 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);
|
static sf_count_t seek(sf_count_t offset, int whence, void* user);
|
||||||
@ -211,6 +214,7 @@ private :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SNDFILE* m_file; ///< File descriptor
|
SNDFILE* m_file; ///< File descriptor
|
||||||
Memory m_memory; ///< Memory reading info
|
Memory m_memory; ///< Memory reading info
|
||||||
|
Stream m_stream; ///< Stream reading info
|
||||||
std::size_t m_sampleCount; ///< Total number of samples in the file
|
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_channelCount; ///< Number of channels used by the sound
|
||||||
unsigned int m_sampleRate; ///< Number of samples per second
|
unsigned int m_sampleRate; ///< Number of samples per second
|
||||||
|
Loading…
Reference in New Issue
Block a user