From a50201481d36dd8b857a9266718bb99780686f89 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Thu, 5 Jan 2012 20:01:25 +0100 Subject: [PATCH 1/3] TinyGL: Do not underflow on specular light calculation When casting from float to int, the value can underflow making the index negative which causes a segmentation fault when accessing the array. Fixes #320 --- graphics/tinygl/light.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/graphics/tinygl/light.cpp b/graphics/tinygl/light.cpp index 9ee025c8f18..a4d3823e28b 100644 --- a/graphics/tinygl/light.cpp +++ b/graphics/tinygl/light.cpp @@ -294,9 +294,11 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) { // testing specular buffer code // dot_spec= pow(dot_spec,m->shininess) specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess); - idx = (int)(dot_spec * SPECULAR_BUFFER_SIZE); - if (idx > SPECULAR_BUFFER_SIZE) + tmp = dot_spec * SPECULAR_BUFFER_SIZE; + if (tmp > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE; + else + idx = (int)tmp; dot_spec = specbuf->buf[idx]; lR += dot_spec * l->specular.v[0] * m->specular.v[0]; From 5dcdf6f9cc27830ba12e304006b5343ec19b0841 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Thu, 5 Jan 2012 20:31:56 +0100 Subject: [PATCH 2/3] GRIM: Do not access past the last _chores array entry Protect accesses to the _chores array. The change in Costume::isChoring() is due to a segmentation fault, the rest are just defensive. --- engines/grim/costume.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/engines/grim/costume.cpp b/engines/grim/costume.cpp index db0abef554b..3261d8f401f 100644 --- a/engines/grim/costume.cpp +++ b/engines/grim/costume.cpp @@ -407,10 +407,18 @@ Model *Costume::getModel() { } void Costume::setChoreLastFrame(int num) { + if (num < 0 || num >= _numChores) { + Debug::warning(Debug::Chores, "Requested chore number %d is outside the range of chores (0-%d)", num, _numChores); + return; + } _chores[num]->setLastFrame(); } void Costume::setChoreLooping(int num, bool val) { + if (num < 0 || num >= _numChores) { + Debug::warning(Debug::Chores, "Requested chore number %d is outside the range of chores (0-%d)", num, _numChores); + return; + } _chores[num]->setLooping(val); } @@ -511,6 +519,10 @@ int Costume::isChoring(const char *name, bool excludeLooping) { } int Costume::isChoring(int num, bool excludeLooping) { + if (num < 0 || num >= _numChores) { + Debug::warning(Debug::Chores, "Requested chore number %d is outside the range of chores (0-%d)", num, _numChores); + return -1; + } if (_chores[num]->_playing && !(excludeLooping && _chores[num]->_looping)) return num; else From f8aaad7e7d76831dbc3abb11a4d1f30afcdd7b56 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Thu, 5 Jan 2012 20:34:26 +0100 Subject: [PATCH 3/3] GRIM: Fix _numChores range tests for negative values Fold the nested check into the outter one, otherwise negative values are not catched. --- engines/grim/costume.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/engines/grim/costume.cpp b/engines/grim/costume.cpp index 3261d8f401f..200582c49e1 100644 --- a/engines/grim/costume.cpp +++ b/engines/grim/costume.cpp @@ -489,11 +489,9 @@ void Costume::stopChores() { } void Costume::fadeChoreIn(int chore, int msecs) { - if (chore >= _numChores) { - if (chore < 0 || chore >= _numChores) { - Debug::warning(Debug::Chores, "Requested chore number %d is outside the range of chores (0-%d)", chore, _numChores); - return; - } + if (chore < 0 || chore >= _numChores) { + Debug::warning(Debug::Chores, "Requested chore number %d is outside the range of chores (0-%d)", chore, _numChores); + return; } _chores[chore]->fadeIn(msecs); if (Common::find(_playingChores.begin(), _playingChores.end(), _chores[chore]) == _playingChores.end()) @@ -501,11 +499,9 @@ void Costume::fadeChoreIn(int chore, int msecs) { } void Costume::fadeChoreOut(int chore, int msecs) { - if (chore >= _numChores) { - if (chore < 0 || chore >= _numChores) { - Debug::warning(Debug::Chores, "Requested chore number %d is outside the range of chores (0-%d)", chore, _numChores); - return; - } + if (chore < 0 || chore >= _numChores) { + Debug::warning(Debug::Chores, "Requested chore number %d is outside the range of chores (0-%d)", chore, _numChores); + return; } _chores[chore]->fadeOut(msecs); }