Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix out of bounds access in cata_tiles::draw #34216

Merged
merged 1 commit into from
Sep 25, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions src/cata_tiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,9 +977,11 @@ void tileset_loader::load_tile_spritelists( JsonObject &entry,
struct tile_render_info {
const tripoint pos;
int height_3d = 0; // accumulator for 3d tallness of sprites rendered here so far
lit_level ll;
bool invisible[5];
tile_render_info( const tripoint &pos, const int height_3d, const bool ( &invisible )[5] )
: pos( pos ), height_3d( height_3d ) {
tile_render_info( const tripoint &pos, const int height_3d, const lit_level ll,
const bool ( &invisible )[5] )
: pos( pos ), height_3d( height_3d ), ll( ll ) {
std::copy( invisible, invisible + 5, this->invisible );
}
};
Expand Down Expand Up @@ -1097,16 +1099,23 @@ void cata_tiles::draw( const point &dest, const tripoint &center, int width, int
const int &x = pos.x;
const int &y = pos.y;

lit_level ll;
bool invisible[5]; // invisible to normal eyes
invisible[0] = false;

if( y < min_visible_y || y > max_visible_y || x < min_visible_x || x > max_visible_x ) {
if( has_draw_override( pos ) || has_memory_at( pos ) ) {
if( has_memory_at( pos ) ) {
ll = LL_MEMORIZED;
invisible[0] = true;
} else if( has_draw_override( pos ) ) {
ll = LL_DARK;
invisible[0] = true;
} else {
apply_vision_effects( pos, offscreen_type );
continue;
}
} else {
ll = ch.visibility_cache[x][y];
}

// Add scent value to the overlay_strings list for every visible tile when displaying scent
Expand Down Expand Up @@ -1183,7 +1192,7 @@ void cata_tiles::draw( const point &dest, const tripoint &center, int width, int
}

if( !invisible[0] &&
apply_vision_effects( pos, g->m.get_visibility( ch.visibility_cache[x][y], cache ) ) ) {
apply_vision_effects( pos, g->m.get_visibility( ll, cache ) ) ) {

const Creature *critter = g->critter_at( pos, true );
if( has_draw_override( pos ) || has_memory_at( pos ) ||
Expand All @@ -1204,9 +1213,9 @@ void cata_tiles::draw( const point &dest, const tripoint &center, int width, int
int height_3d = 0;

// light level is now used for choosing between grayscale filter and normal lit tiles.
draw_terrain( pos, ch.visibility_cache[x][y], height_3d, invisible );
draw_terrain( pos, ll, height_3d, invisible );

draw_points.emplace_back( pos, height_3d, invisible );
draw_points.emplace_back( pos, height_3d, ll, invisible );
}
const std::array<decltype( &cata_tiles::draw_furniture ), 10> drawing_layers = {{
&cata_tiles::draw_furniture, &cata_tiles::draw_graffiti, &cata_tiles::draw_trap,
Expand All @@ -1220,7 +1229,7 @@ void cata_tiles::draw( const point &dest, const tripoint &center, int width, int
for( auto f : drawing_layers ) {
// ... draw all the points we drew terrain for, in the same order
for( auto &p : draw_points ) {
( this->*f )( p.pos, ch.visibility_cache[p.pos.x][p.pos.y], p.height_3d, p.invisible );
( this->*f )( p.pos, p.ll, p.height_3d, p.invisible );
}
}
// display number of monsters to spawn in mapgen preview
Expand Down