Skip to content

Commit fa9eb59

Browse files
committed
C4MapCreatorS2: Disallow script execution in sections as they are loaded in a separate thread
1 parent a455eaa commit fa9eb59

File tree

5 files changed

+28
-14
lines changed

5 files changed

+28
-14
lines changed

src/C4Landscape.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ std::unique_ptr<CSurface8> C4Landscape::CreateMap(C4Random &random)
565565
return surfaceMap;
566566
}
567567

568-
std::unique_ptr<CSurface8> C4Landscape::CreateMapS2(C4Group &ScenFile, C4Random &random)
568+
std::unique_ptr<CSurface8> C4Landscape::CreateMapS2(C4Group &ScenFile, C4Random &random, const bool allowScript)
569569
{
570570
// file present?
571571
if (!ScenFile.AccessEntry(C4CFN_DynLandscape)) return nullptr;
@@ -575,7 +575,7 @@ std::unique_ptr<CSurface8> C4Landscape::CreateMapS2(C4Group &ScenFile, C4Random
575575
pMapCreator = new C4MapCreatorS2(Section, random, &Section.C4S.Landscape, &Section.TextureMap, &Section.Material, Game.Parameters.StartupPlayerCount);
576576

577577
// read file
578-
pMapCreator->ReadFile(C4CFN_DynLandscape, &ScenFile, random);
578+
pMapCreator->ReadFile(C4CFN_DynLandscape, &ScenFile, random, allowScript);
579579
// render landscape
580580
// keep map creator until script callbacks have been done
581581
return pMapCreator->Render(nullptr);
@@ -736,7 +736,7 @@ bool C4Landscape::InitEmpty(C4Random &random, const bool loadSky, bool &landscap
736736
return FinalizeInit(landscapeLoaded, nullptr);
737737
}
738738

739-
bool C4Landscape::Init(C4Group &hGroup, C4Group *const saveGameGroup, C4Random &random, bool fOverloadCurrent, bool fLoadSky, bool &rfLoaded, bool fSavegame)
739+
bool C4Landscape::Init(C4Group &hGroup, C4Group *const saveGameGroup, C4Random &random, const bool allowScript, bool fOverloadCurrent, bool fLoadSky, bool &rfLoaded, bool fSavegame)
740740
{
741741
PrepareInit(random, fOverloadCurrent);
742742

@@ -801,7 +801,7 @@ bool C4Landscape::Init(C4Group &hGroup, C4Group *const saveGameGroup, C4Random &
801801

802802
// dynamic map from file
803803
if (!sfcMap)
804-
if (sfcMap = CreateMapS2(hGroup, random))
804+
if (sfcMap = CreateMapS2(hGroup, random, allowScript))
805805
if (!fLandscapeModeSet) Mode = C4LSC_Dynamic;
806806

807807
// Dynamic map by scenario

src/C4Landscape.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class C4Landscape
141141
bool SaveMap(C4Group &hGroup);
142142
bool SaveInitial();
143143
bool SaveTextures(C4Group &hGroup);
144-
bool Init(C4Group &hGroup, C4Group *const saveGameGroup, C4Random &random, bool fOverloadCurrent, bool fLoadSky, bool &rfLoaded, bool fSavegame);
144+
bool Init(C4Group &hGroup, C4Group *const saveGameGroup, C4Random &random, bool allowScript, bool fOverloadCurrent, bool fLoadSky, bool &rfLoaded, bool fSavegame);
145145
bool InitEmpty(C4Random &random, bool loadSky, bool &landscapeLoaded);
146146
bool MapToLandscape();
147147
bool ApplyDiff(C4Group &hGroup);
@@ -300,7 +300,7 @@ class C4Landscape
300300
bool AssignMap(std::unique_ptr<CSurface8> map, C4Random &random, bool overloadCurrent, bool loadSky, bool savegame);
301301
bool FinalizeInit(bool &landscapeLoaded, C4Group *groupForDiff);
302302
std::unique_ptr<CSurface8> CreateMap(C4Random &random); // create map by landscape attributes
303-
std::unique_ptr<CSurface8> CreateMapS2(C4Group &ScenFile, C4Random &random); // create map by def file
303+
std::unique_ptr<CSurface8> CreateMapS2(C4Group &ScenFile, C4Random &random, bool allowScript); // create map by def file
304304
CSurface8 *CreateEmptyMap(std::int32_t width, std::int32_t height);
305305
bool Relight(C4Rect To);
306306
bool ApplyLighting(C4Rect To);

src/C4MapCreatorS2.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#include <cassert>
2828

29+
bool AlgoScript(C4MCOverlay *pOvrl, int32_t iX, int32_t iY);
30+
2931
// C4MCCallbackArray
3032

3133
C4MCCallbackArray::C4MCCallbackArray(C4AulFunc *pSFunc, C4MapCreatorS2 *pMapCreator)
@@ -352,6 +354,10 @@ bool C4MCOverlay::SetField(C4MCParser *pParser, const char *szField, const char
352354
pAlgo = GetAlgo(StrPar);
353355
// check validity
354356
if (!pAlgo) throw C4MCParserErr(pParser, C4MCErr_AlgoNotFound, StrPar);
357+
if (!pParser->AllowScript() && pAlgo->Function == &AlgoScript)
358+
{
359+
throw C4MCParserErr{pParser, C4MCErr_ScriptNotAllowed};
360+
}
355361
// store
356362
this->*(pAttr->algorithm) = pAlgo;
357363
break;
@@ -365,6 +371,10 @@ bool C4MCOverlay::SetField(C4MCParser *pParser, const char *szField, const char
365371
break;
366372
case C4MCV_ScriptFunc:
367373
{
374+
if (!pParser->AllowScript())
375+
{
376+
throw C4MCParserErr{pParser, C4MCErr_ScriptNotAllowed};
377+
}
368378
// get script func of main script
369379
C4AulFunc *pSFunc = Game.Script.GetSFunc(StrPar, AA_PROTECTED);
370380
if (!pSFunc) throw C4MCParserErr(pParser, C4MCErr_SFuncNotFound, StrPar);
@@ -718,12 +728,12 @@ void C4MapCreatorS2::Clear()
718728
CallbackArrays.Clear();
719729
}
720730

721-
bool C4MapCreatorS2::ReadFile(const char *szFilename, C4Group *pGrp, C4Random &random)
731+
bool C4MapCreatorS2::ReadFile(const char *szFilename, C4Group *pGrp, C4Random &random, const bool allowScript)
722732
{
723733
// create parser and read file
724734
try
725735
{
726-
C4MCParser(this, random).ParseFile(szFilename, pGrp);
736+
C4MCParser(this, random, allowScript).ParseFile(szFilename, pGrp);
727737
}
728738
catch (const C4MCParserErr &err)
729739
{
@@ -739,7 +749,7 @@ bool C4MapCreatorS2::ReadScript(const char *szScript, C4Random &random)
739749
// create parser and read
740750
try
741751
{
742-
C4MCParser(this, random).Parse(szScript);
752+
C4MCParser(this, random, true).Parse(szScript);
743753
}
744754
catch (const C4MCParserErr &err)
745755
{
@@ -808,8 +818,8 @@ void C4MCParserErr::show() const
808818

809819
// parser
810820

811-
C4MCParser::C4MCParser(C4MapCreatorS2 *pMapCreator, C4Random &random)
812-
: MapCreator{pMapCreator}, random{random}
821+
C4MCParser::C4MCParser(C4MapCreatorS2 *pMapCreator, C4Random &random, const bool allowScript)
822+
: MapCreator{pMapCreator}, random{random}, allowScript{allowScript}
813823
{
814824
// reset some fields
815825
Code = nullptr; CPos = nullptr; *Filename = 0;

src/C4MapCreatorS2.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#define C4MCErr_MatNotFound "material '{}' not found"
6464
#define C4MCErr_TexNotFound "texture '{}' not found"
6565
#define C4MCErr_AlgoNotFound "algorithm '{}' not found"
66+
#define C4MCErr_ScriptNotAllowed "script execution is not allowed"
6667
#define C4MCErr_SFuncNotFound "script func '{}' not found in scenario script"
6768
#define C4MCErr_PointOnlyOvl "point only allowed in overlays"
6869

@@ -356,7 +357,7 @@ class C4MapCreatorS2 : public C4MCNode
356357

357358
void Default(C4Random &random); // set default data
358359
void Clear(); // clear any data
359-
bool ReadFile(const char *szFilename, C4Group *pGrp, C4Random &random); // read defs of file
360+
bool ReadFile(const char *szFilename, C4Group *pGrp, C4Random &random, bool allowScript); // read defs of file
360361
bool ReadScript(const char *szScript, C4Random &random); // reads def directly from mem
361362

362363
public:
@@ -414,6 +415,7 @@ class C4MCParser
414415
private:
415416
C4MapCreatorS2 *MapCreator; // map creator parsing into
416417
C4Random &random; // random generator to use
418+
bool allowScript; // whether the script algorithm is allowed
417419
char *Code; // loaded code
418420
const char *CPos; // current parser pos in code
419421
C4MCTokenType CurrToken; // last token read
@@ -427,13 +429,15 @@ class C4MCParser
427429
void ParseValue(C4MCNode *pToNode, const char *szFieldName); // Set Field
428430

429431
public:
430-
C4MCParser(C4MapCreatorS2 *pMapCreator, C4Random &random);
432+
C4MCParser(C4MapCreatorS2 *pMapCreator, C4Random &random, bool allowScript);
431433
~C4MCParser();
432434

433435
void Clear(); // clear stuff
434436

435437
void ParseFile(const char *szFilename, C4Group *pGrp); // load and parse file
436438
void Parse(const char *szScript); // load and parse from mem
437439

440+
bool AllowScript() const noexcept { return allowScript; }
441+
438442
friend class C4MCParserErr;
439443
};

src/C4Section.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ bool C4Section::InitMaterialTexture(C4Section *const fallback)
394394
bool C4Section::InitSecondPart(C4Random &random)
395395
{
396396
LandscapeLoaded = false;
397-
if (!(emptyLandscape ? Landscape.InitEmpty(random, true, LandscapeLoaded) : Landscape.Init(Group, SaveGameGroup ? &*SaveGameGroup : nullptr, random, false, true, LandscapeLoaded, C4S.Head.SaveGame)))
397+
if (!(emptyLandscape ? Landscape.InitEmpty(random, true, LandscapeLoaded) : Landscape.Init(Group, SaveGameGroup ? &*SaveGameGroup : nullptr, random, name.empty(), false, true, LandscapeLoaded, C4S.Head.SaveGame)))
398398
{
399399
LogFatal(C4ResStrTableKey::IDS_ERR_GBACK);
400400
return false;

0 commit comments

Comments
 (0)