EMI: Fix wrap around of Layers/Frames

This patch makes sure, that Layer::_frame is smaller than numLayers
of the bitmap in order to prevent out-of-bounds access to
BitmapData::_layers.
This commit is contained in:
Christian Krause 2015-05-16 10:32:36 +02:00
parent 52010ff229
commit b186c21f85
6 changed files with 16 additions and 4 deletions

View File

@ -452,6 +452,11 @@ int Bitmap::getNumImages() const {
return _data->_numImages;
}
int Bitmap::getNumLayers() const {
_data->load();
return _data->_numLayers;
}
void Bitmap::freeData() {
--_data->_refCount;
if (_data->_refCount < 1) {

View File

@ -156,6 +156,7 @@ public:
void setActiveImage(int n);
int getNumImages() const;
int getNumLayers() const;
int getActiveImage() const { return _currImage; }
bool getHasTransparency() const { return _data->_hasTransparency; }
int getFormat() const { return _data->_format; }

View File

@ -44,6 +44,11 @@ void Layer::draw() {
}
void Layer::setFrame(int frame) {
int numframes = _bitmap->getNumLayers();
if (frame >= numframes || frame < 0) {
warning("Layer::setFrame: invalid frame number: %d, numLayers: %d", frame, numframes);
return;
}
_frame = frame;
}
@ -53,10 +58,8 @@ void Layer::setSortOrder(int order) {
void Layer::advanceFrame(int num) {
_frame += num;
int numframes = _bitmap->getNumImages();
while (_frame >= numframes) {
_frame -= numframes;
}
int numframes = _bitmap->getNumLayers();
_frame %= numframes;
}
void Layer::saveState(SaveGame *state) {

View File

@ -1163,6 +1163,7 @@ void GfxOpenGL::drawBitmap(const Bitmap *bitmap, int dx, int dy, uint32 layer) {
GLuint *textures = (GLuint *)bitmap->getTexIds();
float *texc = data->_texc;
assert(layer < data->_numLayers);
uint32 offset = data->_layers[layer]._offset;
for (uint32 i = offset; i < offset + data->_layers[layer]._numImages; ++i) {
glBindTexture(GL_TEXTURE_2D, textures[data->_verts[i]._texid]);

View File

@ -1351,6 +1351,7 @@ void GfxOpenGLS::drawBitmap(const Bitmap *bitmap, int dx, int dy, uint32 layer)
shader->use();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quadEBO);
assert(layer < data->_numLayers);
uint32 offset = data->_layers[layer]._offset;
for (uint32 i = offset; i < offset + data->_layers[layer]._numImages; ++i) {
glBindTexture(GL_TEXTURE_2D, textures[data->_verts[i]._texid]);

View File

@ -996,6 +996,7 @@ void GfxTinyGL::drawBitmap(const Bitmap *bitmap, int x, int y, uint32 layer) {
Graphics::BlitImage **b = (Graphics::BlitImage **)bitmap->getTexIds();
assert(layer < data->_numLayers);
uint32 offset = data->_layers[layer]._offset;
for (uint32 i = offset; i < offset + data->_layers[layer]._numImages; ++i) {
const BitmapData::Vert &v = data->_verts[i];