all: try to protect access to journal_strs and sign_locs against bad index...

This commit is contained in:
ALONSO Laurent
2021-10-22 15:22:57 +02:00
committed by Celtic Minstrel
parent a51ba34650
commit 47fd08904f
10 changed files with 92 additions and 34 deletions

View File

@@ -317,6 +317,7 @@
E2B4A69624541D7100857D44 /* sfml-system.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2513E8F245343E30066C6B1 /* sfml-system.framework */; };
E2B4A69724541D7100857D44 /* sfml-window.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2513E90245343E30066C6B1 /* sfml-window.framework */; };
E2B4A69824541D7100857D44 /* SFML.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2513E92245343E40066C6B1 /* SFML.framework */; };
E2DC79012722F25800D6876A /* area.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E2DC79002722F25800D6876A /* area.cpp */; };
E2FE7CB127142B07008D567E /* boe.minimap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E2FE7CB027142B07008D567E /* boe.minimap.cpp */; };
/* End PBXBuildFile section */
@@ -857,6 +858,7 @@
E26D45A026FCBBF4007984E6 /* keycodes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = keycodes.hpp; sourceTree = "<group>"; };
E2AE6DAE24CC876500792E44 /* libboost_filesystem-mt.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libboost_filesystem-mt.dylib"; path = "/usr/local/Cellar/boost/1.75.0_2/lib/libboost_filesystem-mt.dylib"; sourceTree = "<absolute>"; };
E2AE6DB324CC879300792E44 /* libboost_system-mt.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libboost_system-mt.dylib"; path = "/usr/local/Cellar/boost/1.75.0_2/lib/libboost_system-mt.dylib"; sourceTree = "<absolute>"; };
E2DC79002722F25800D6876A /* area.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = area.cpp; sourceTree = "<group>"; };
E2DF0BFA2538C031000C7A1A /* texture.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = texture.hpp; sourceTree = "<group>"; };
E2FE7CB027142B07008D567E /* boe.minimap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = boe.minimap.cpp; sourceTree = "<group>"; };
E2FE7CB727142B16008D567E /* boe.minimap.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = boe.minimap.hpp; sourceTree = "<group>"; };
@@ -1179,6 +1181,7 @@
9185BD941EA01BCC0027C346 /* scenario */ = {
isa = PBXGroup;
children = (
E2DC79002722F25800D6876A /* area.cpp */,
91279D3D0F9D1D6A007B0D52 /* item.cpp */,
91279CC10F9D19DA007B0D52 /* monster.cpp */,
91E5C79D0F9F60FA00C21460 /* outdoors.cpp */,
@@ -1993,6 +1996,7 @@
919CC25C1B37735C00273FDA /* town.cpp in Sources */,
919CC25F1B37736E00273FDA /* vehicle.cpp in Sources */,
919CC2601B37737200273FDA /* estreams.cpp in Sources */,
E2DC79012722F25800D6876A /* area.cpp in Sources */,
919CC2611B37738100273FDA /* gzstream.cpp in Sources */,
919CC2621B37738A00273FDA /* ticpp.cpp in Sources */,
919CC2631B37739000273FDA /* tinystr.cpp in Sources */,

View File

@@ -268,10 +268,10 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head
else if(i >= 4 && i < 10)
scenario.intro_strs[i-4] = tmp;
else if(i >= 10 && i < 60)
scenario.journal_strs[i-10] = tmp;
scenario.get_journal_string(i-10) = tmp;
else if(i >= 60 && i < 160) {
if(i % 2 == 0) scenario.special_items[(i-60)/2].name = tmp;
else scenario.special_items[(i-60)/2].descr = tmp;
if(i % 2 == 0) scenario.get_special_item((i-60)/2).name = tmp;
else scenario.get_special_item((i-60)/2).descr = tmp;
} else if(i >= 260) continue; // These were never ever used, for some reason.
else
scenario.get_special_string(i-160) = tmp;
@@ -894,9 +894,9 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
game->GetText(&scenario.get_special_string(strnum), false);
} else if(type == "journal") {
game->GetAttribute("id", &strnum);
if(strnum >= scenario.journal_strs.size()) // changeme: add a maximum and discard data if not in a range
if(strnum >= scenario.journal_strs.size() && strnum<10000)
scenario.journal_strs.resize(strnum + 1);
game->GetText(&scenario.journal_strs[strnum], false);
game->GetText(&scenario.get_journal_string(strnum), false);
} else throw xBadNode(type, game->Row(), game->Column(), fname);
}
if(!reqs.empty())
@@ -1643,9 +1643,9 @@ void readOutdoorsFromXml(ticpp::Document&& data, cOutdoors& out) {
} else if(type == "sign") {
int sign;
elem->GetAttribute("id", &sign);
if(sign >= out.sign_locs.size())
if(sign >= out.sign_locs.size() && sign<10000)
out.sign_locs.resize(sign + 1);
elem->GetText(&out.sign_locs[sign].text, false);
elem->GetText(&out.get_sign_loc(sign).text, false);
} else if(type == "area") {
if(num_rects >= out.area_desc.size())
out.area_desc.resize(num_rects + 1);
@@ -1776,9 +1776,9 @@ void readTownFromXml(ticpp::Document&& data, cTown*& town, cScenario& scen) {
} else if(type == "sign") {
int sign;
elem->GetAttribute("id", &sign);
if(sign >= town->sign_locs.size())
if(sign >= town->sign_locs.size() && sign<10000)
town->sign_locs.resize(sign + 1);
elem->GetText(&town->sign_locs[sign].text, false);
elem->GetText(&town->get_sign_loc(sign).text, false);
} else if(type == "string") {
int str;
elem->GetAttribute("id", &str);
@@ -2001,7 +2001,7 @@ void loadOutMapData(map_data&& data, location which, cScenario& scen) {
else throw xMapParseError(map_out_bad_field, feat.second, y, x, data.file);
break;
case eMapFeature::SIGN:
if(feat.second >= out.sign_locs.size())
if(feat.second<0 || feat.second >= out.sign_locs.size())
break;
static_cast<location&>(out.sign_locs[feat.second]) = loc(x,y);
break;
@@ -2042,7 +2042,7 @@ void loadTownMapData(map_data&& data, int which, cScenario& scen) {
what->exists = true;
break;
case eMapFeature::SIGN:
if(feat.second >= town.sign_locs.size())
if(feat.second<0 || feat.second >= town.sign_locs.size())
break;
static_cast<location&>(town.sign_locs[feat.second]) = loc(x,y);
break;
@@ -2352,7 +2352,7 @@ bool load_town_v1(fs::path scen_file, short which_town, cTown& the_town, legacy:
else if(i >= 20 && i < 120)
the_town.get_special_string(i-20) = tmp;
else if(i >= 120 && i < 140)
the_town.sign_locs[i-120].text = tmp;
the_town.get_sign_loc(i-120).text = tmp;
}
len = sizeof(legacy::talking_record_type);
@@ -2464,7 +2464,7 @@ bool load_outdoors_v1(fs::path scen_file, location which_out,cOutdoors& the_out,
else if(i >= 10 && i < 100)
the_out.get_special_string(i-10) = tmp;
else if(i >= 100 && i < 108)
the_out.sign_locs[i-100].text = tmp;
the_out.get_sign_loc(i-100).text = tmp;
}
if(fclose(file_id) != 0) {

View File

@@ -1151,9 +1151,9 @@ void do_sign(short town_num, short which_sign, short sign_type) {
pict.setPict(univ.get_terrain(sign_type).get_picture_num());
if(town_num >= 200)
sign_text = univ.out->sign_locs[which_sign].text;
sign_text = univ.out->get_sign_loc(which_sign).text;
else
sign_text = univ.town->sign_locs[which_sign].text;
sign_text = univ.town->get_sign_loc(which_sign).text;
sign->getControl("sign").setText(sign_text);
sign.show();

View File

@@ -628,7 +628,7 @@ void journal() {
}
void add_to_journal(short event) {
if(univ.party.add_to_journal(univ.scenario.journal_strs[event], univ.party.calc_day()))
if(univ.party.add_to_journal(univ.scenario.get_journal_string(event), univ.party.calc_day()))
ASB("Something was added to your journal.");
}

28
src/scenario/area.cpp Normal file
View File

@@ -0,0 +1,28 @@
//
// area.cpp
// Common
//
// Created by alonso on 22/10/2021.
//
#include "area.hpp"
static sign_loc_t getBadSignLoc()
{
return sign_loc_t(-1,-1,"Bad Sign");
}
sign_loc_t const &cArea::get_sign_loc(int num) const
{
if (num>=0 && num<sign_locs.size())
return sign_locs[num];
static sign_loc_t bad_sign=getBadSignLoc();
return bad_sign;
}
sign_loc_t &cArea::get_sign_loc(int num)
{
if (num>=0 && num<sign_locs.size())
return sign_locs[num];
static sign_loc_t bad_sign;
bad_sign=getBadSignLoc();
return bad_sign;
}

View File

@@ -47,6 +47,9 @@ public:
bool is_on_map(location loc) const {
return loc.x < max_dim && loc.y < max_dim && loc.x >= 0 && loc.y >= 0;
}
sign_loc_t const &get_sign_loc(int num) const;
sign_loc_t &get_sign_loc(int num);
};
#endif

View File

@@ -241,6 +241,27 @@ static cQuest getBadQuest() {
return badQuest;
}
std::string &cScenario::get_journal_string(int id)
{
if (id>=0 && id<journal_strs.size())
return journal_strs[id];
if (id>=0 && id<200) {
journal_strs.resize(id+1);
return journal_strs[id];
}
static std::string badString;
badString="Bad Journal String";
return badString;
}
std::string const &cScenario::get_journal_string(int id) const
{
if (id>=0 && id<journal_strs.size())
return journal_strs[id];
static std::string badString="Bad Journal String";
return badString;
}
cQuest const &cScenario::get_quest(int quest) const
{
if (quest>=0 && quest<quests.size())

View File

@@ -52,12 +52,14 @@ public:
cItem const &get_item(item_num_t item) const;
cItem &get_item(item_num_t item);
std::string &get_journal_string(int id);
std::string const &get_journal_string(int id) const;
cQuest const &get_quest(int quest) const;
cQuest &get_quest(int quest);
cSpecItem const &get_special_item(item_num_t item) const;
cSpecItem &get_special_item(item_num_t item);
cShop const &get_shop(int shop) const;
cShop &get_shop(int shop);
cSpecItem const &get_special_item(item_num_t item) const;
cSpecItem &get_special_item(item_num_t item);
std::string &get_special_string(int id);
std::string const &get_special_string(int id) const;
cTerrain const &get_terrain(ter_num_t ter) const;

View File

@@ -527,11 +527,11 @@ static bool handle_rb_action(location the_point, bool option_hit) {
scenario.journal_strs.pop_back();
else if(j == size_before)
scenario.journal_strs.resize(size_before + 8, "*");
else scenario.journal_strs[j] = "*";
else scenario.get_journal_string(j) = "*";
} else {
if(j == size_before)
scenario.journal_strs.emplace_back("*");
if(!edit_text_str(j,STRS_JOURNAL) && j == size_before && scenario.journal_strs[j] == "*")
if(!edit_text_str(j,STRS_JOURNAL) && j == size_before && scenario.get_journal_string(j) == "*")
scenario.journal_strs.pop_back();
}
start_string_editing(STRS_JOURNAL,size_before == scenario.journal_strs.size());
@@ -567,11 +567,11 @@ static bool handle_rb_action(location the_point, bool option_hit) {
current_terrain->sign_locs.pop_back();
else if(j == size_before)
break;
else current_terrain->sign_locs[j] = {-1, -1, "*"};
else current_terrain->get_sign_loc(j) = {-1, -1, "*"};
} else {
if(j == size_before)
current_terrain->sign_locs.emplace_back(-1,-1,"*");
if(!edit_text_str(j,STRS_OUT_SIGN) && j == size_before && current_terrain->sign_locs[j].text == "*")
if(!edit_text_str(j,STRS_OUT_SIGN) && j == size_before && current_terrain->get_sign_loc(j).text == "*")
current_terrain->sign_locs.pop_back();
}
start_string_editing(STRS_OUT_SIGN,size_before == current_terrain->sign_locs.size());
@@ -586,11 +586,11 @@ static bool handle_rb_action(location the_point, bool option_hit) {
town->sign_locs.pop_back();
else if(j == size_before)
break;
else town->sign_locs[j] = {-1, -1, "*"};
else town->get_sign_loc(j) = {-1, -1, "*"};
} else {
if(j == size_before)
town->sign_locs.emplace_back(-1,-1,"*");
if(!edit_text_str(j,STRS_TOWN_SIGN) && j == size_before && town->sign_locs[j].text == "*")
if(!edit_text_str(j,STRS_TOWN_SIGN) && j == size_before && town->get_sign_loc(j).text == "*")
town->sign_locs.pop_back();
}
start_string_editing(STRS_TOWN_SIGN,size_before == town->sign_locs.size());
@@ -2559,15 +2559,15 @@ void start_string_editing(eStrMode mode,short just_redo_text) {
set_rb(i,RB_TOWN_STR, i,str.str());
break;
case 3:
str << i << " - " << scenario.journal_strs[i].substr(0,30);
str << i << " - " << scenario.get_journal_string(i).substr(0,30);
set_rb(i,RB_JOURNAL, i,str.str());
break;
case 4:
str << i << " - " << current_terrain->sign_locs[i].text.substr(0,30);
str << i << " - " << current_terrain->get_sign_loc(i).text.substr(0,30);
set_rb(i,RB_OUT_SIGN, i,str.str());
break;
case 5:
str << i << " - " << town->sign_locs[i].text.substr(0,30);
str << i << " - " << town->get_sign_loc(i).text.substr(0,30);
set_rb(i,RB_TOWN_SIGN, i,str.str());
break;
case 6:

View File

@@ -71,9 +71,9 @@ static std::string& fetch_str(eStrMode str_mode, size_t which) {
case 0: return scenario.get_special_string(which);
case 1: return current_terrain->get_special_string(which);
case 2: return town->get_special_string(which);
case 3: return scenario.journal_strs[which];
case 4: return current_terrain->sign_locs[which].text;
case 5: return town->sign_locs[which].text;
case 3: return scenario.get_journal_string(which);
case 4: return current_terrain->get_sign_loc(which).text;
case 5: return town->get_sign_loc(which).text;
case 6: return current_terrain->area_desc[which].descr;
case 7: return town->area_desc[which].descr;
}
@@ -88,12 +88,12 @@ static std::string str_info(eStrMode str_mode, size_t which) {
sout << which;
break;
case 4:
sout << "(" << current_terrain->sign_locs[which].x;
sout << ", " << current_terrain->sign_locs[which].y << ")";
sout << "(" << current_terrain->get_sign_loc(which).x;
sout << ", " << current_terrain->get_sign_loc(which).y << ")";
break;
case 5:
sout << "(" << town->sign_locs[which].x;
sout << ", " << town->sign_locs[which].y << ")";
sout << "(" << town->get_sign_loc(which).x;
sout << ", " << town->get_sign_loc(which).y << ")";
break;
case 6:
sout << "(" << current_terrain->area_desc[which].left;