mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
- made GL nodes loader more resilient to broken data
https://forum.zdoom.org/viewtopic.php?t=66086
This commit is contained in:
parent
09dcb247cf
commit
b40e0ae38d
1 changed files with 68 additions and 17 deletions
|
@ -206,6 +206,8 @@ bool MapLoader::LoadGLVertexes(FileReader &lump)
|
||||||
lump.Seek(0, FileReader::SeekSet);
|
lump.Seek(0, FileReader::SeekSet);
|
||||||
auto glbuf = lump.Read();
|
auto glbuf = lump.Read();
|
||||||
auto gllen=lump.GetLength();
|
auto gllen=lump.GetLength();
|
||||||
|
if (gllen < 4)
|
||||||
|
return false;
|
||||||
auto gldata = glbuf.Data();
|
auto gldata = glbuf.Data();
|
||||||
|
|
||||||
if (*(int *)gldata == gNd5)
|
if (*(int *)gldata == gNd5)
|
||||||
|
@ -279,28 +281,51 @@ bool MapLoader::LoadGLSegs(FileReader &lump)
|
||||||
lump.Seek(0, FileReader::SeekSet);
|
lump.Seek(0, FileReader::SeekSet);
|
||||||
auto data = lump.Read();
|
auto data = lump.Read();
|
||||||
int numsegs = (int)lump.GetLength();
|
int numsegs = (int)lump.GetLength();
|
||||||
|
if (numsegs < 4)
|
||||||
|
return false;
|
||||||
auto &segs = Level->segs;
|
auto &segs = Level->segs;
|
||||||
|
const unsigned numverts = Level->vertexes.Size();
|
||||||
|
const unsigned numlines = Level->lines.Size();
|
||||||
|
|
||||||
if (!format5 && memcmp(data.Data(), "gNd3", 4))
|
if (!format5 && memcmp(data.Data(), "gNd3", 4))
|
||||||
{
|
{
|
||||||
numsegs/=sizeof(glseg_t);
|
numsegs/=sizeof(glseg_t);
|
||||||
Level->segs.Alloc(numsegs);
|
segs.Alloc(numsegs);
|
||||||
memset(&segs[0],0,sizeof(seg_t)*numsegs);
|
memset(&segs[0],0,sizeof(seg_t)*numsegs);
|
||||||
|
|
||||||
glseg_t * ml = (glseg_t*)data.Data();
|
glseg_t * ml = (glseg_t*)data.Data();
|
||||||
for(i = 0; i < numsegs; i++)
|
for(i = 0; i < numsegs; i++)
|
||||||
{
|
{
|
||||||
// check for gl-vertices
|
// check for gl-vertices
|
||||||
segs[i].v1 = &Level->vertexes[checkGLVertex(LittleShort(ml->v1))];
|
const unsigned v1idx = checkGLVertex(LittleShort(ml->v1));
|
||||||
segs[i].v2 = &Level->vertexes[checkGLVertex(LittleShort(ml->v2))];
|
if (v1idx >= numverts)
|
||||||
segs[i].PartnerSeg = ml->partner == 0xFFFF ? nullptr : &segs[LittleShort(ml->partner)];
|
return false;
|
||||||
|
segs[i].v1 = &Level->vertexes[v1idx];
|
||||||
|
|
||||||
|
const unsigned v2idx = checkGLVertex(LittleShort(ml->v2));
|
||||||
|
if (v2idx >= numverts)
|
||||||
|
return false;
|
||||||
|
segs[i].v2 = &Level->vertexes[v2idx];
|
||||||
|
|
||||||
|
const int partner = LittleShort(ml->partner);
|
||||||
|
if (partner == 0xFFFF)
|
||||||
|
segs[i].PartnerSeg = nullptr;
|
||||||
|
else if (partner >= numsegs)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
segs[i].PartnerSeg = &segs[partner];
|
||||||
|
|
||||||
if(ml->linedef != 0xffff)
|
if(ml->linedef != 0xffff)
|
||||||
{
|
{
|
||||||
ldef = &Level->lines[LittleShort(ml->linedef)];
|
const unsigned lineidx = LittleShort(ml->linedef);
|
||||||
|
if (lineidx >= numlines)
|
||||||
|
return false;
|
||||||
|
ldef = &Level->lines[lineidx];
|
||||||
segs[i].linedef = ldef;
|
segs[i].linedef = ldef;
|
||||||
|
|
||||||
|
|
||||||
ml->side=LittleShort(ml->side);
|
ml->side=LittleShort(ml->side);
|
||||||
|
if (ml->side > 1)
|
||||||
|
return false;
|
||||||
segs[i].sidedef = ldef->sidedef[ml->side];
|
segs[i].sidedef = ldef->sidedef[ml->side];
|
||||||
if (ldef->sidedef[ml->side] != nullptr)
|
if (ldef->sidedef[ml->side] != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -336,25 +361,42 @@ bool MapLoader::LoadGLSegs(FileReader &lump)
|
||||||
{
|
{
|
||||||
if (!format5) numsegs-=4;
|
if (!format5) numsegs-=4;
|
||||||
numsegs/=sizeof(glseg3_t);
|
numsegs/=sizeof(glseg3_t);
|
||||||
Level->segs.Alloc(numsegs);
|
segs.Alloc(numsegs);
|
||||||
memset(&segs[0],0,sizeof(seg_t)*numsegs);
|
memset(&segs[0],0,sizeof(seg_t)*numsegs);
|
||||||
|
|
||||||
glseg3_t * ml = (glseg3_t*)(data.Data() + (format5? 0:4));
|
glseg3_t * ml = (glseg3_t*)(data.Data() + (format5? 0:4));
|
||||||
for(i = 0; i < numsegs; i++)
|
for(i = 0; i < numsegs; i++)
|
||||||
{ // check for gl-vertices
|
{ // check for gl-vertices
|
||||||
segs[i].v1 = &Level->vertexes[checkGLVertex3(LittleLong(ml->v1))];
|
const unsigned v1idx = checkGLVertex3(LittleLong(ml->v1));
|
||||||
segs[i].v2 = &Level->vertexes[checkGLVertex3(LittleLong(ml->v2))];
|
if (v1idx >= numverts)
|
||||||
|
return false;
|
||||||
|
segs[i].v1 = &Level->vertexes[v1idx];
|
||||||
|
|
||||||
|
const unsigned v2idx = checkGLVertex3(LittleLong(ml->v2));
|
||||||
|
if (v2idx >= numverts)
|
||||||
|
return false;
|
||||||
|
segs[i].v2 = &Level->vertexes[v2idx];
|
||||||
|
|
||||||
const uint32_t partner = LittleLong(ml->partner);
|
const uint32_t partner = LittleLong(ml->partner);
|
||||||
segs[i].PartnerSeg = UINT_MAX == partner ? nullptr : &segs[partner];
|
if (partner == UINT_MAX)
|
||||||
|
segs[i].PartnerSeg = nullptr;
|
||||||
|
else if (partner >= (uint32_t)numsegs)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
segs[i].PartnerSeg = &segs[partner];
|
||||||
|
|
||||||
if(ml->linedef != 0xffff) // skip minisegs
|
if(ml->linedef != 0xffff) // skip minisegs
|
||||||
{
|
{
|
||||||
ldef = &Level->lines[LittleLong(ml->linedef)];
|
const unsigned lineidx = LittleShort(ml->linedef);
|
||||||
|
if (lineidx >= numlines)
|
||||||
|
return false;
|
||||||
|
ldef = &Level->lines[lineidx];
|
||||||
segs[i].linedef = ldef;
|
segs[i].linedef = ldef;
|
||||||
|
|
||||||
|
|
||||||
ml->side=LittleShort(ml->side);
|
ml->side=LittleShort(ml->side);
|
||||||
|
if (ml->side > 1)
|
||||||
|
return false;
|
||||||
segs[i].sidedef = ldef->sidedef[ml->side];
|
segs[i].sidedef = ldef->sidedef[ml->side];
|
||||||
if (ldef->sidedef[ml->side] != nullptr)
|
if (ldef->sidedef[ml->side] != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -400,8 +442,11 @@ bool MapLoader::LoadGLSubsectors(FileReader &lump)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
int numsubsectors = (int)lump.GetLength();
|
int numsubsectors = (int)lump.GetLength();
|
||||||
|
if (numsubsectors < 4)
|
||||||
|
return false;
|
||||||
lump.Seek(0, FileReader::SeekSet);
|
lump.Seek(0, FileReader::SeekSet);
|
||||||
auto datab = lump.Read();
|
auto datab = lump.Read();
|
||||||
|
const unsigned numsegs = Level->segs.Size();
|
||||||
|
|
||||||
if (numsubsectors == 0)
|
if (numsubsectors == 0)
|
||||||
{
|
{
|
||||||
|
@ -419,12 +464,15 @@ bool MapLoader::LoadGLSubsectors(FileReader &lump)
|
||||||
for (i=0; i<numsubsectors; i++)
|
for (i=0; i<numsubsectors; i++)
|
||||||
{
|
{
|
||||||
subsectors[i].numlines = LittleShort(data[i].numsegs );
|
subsectors[i].numlines = LittleShort(data[i].numsegs );
|
||||||
subsectors[i].firstline = &Level->segs[LittleShort(data[i].firstseg)];
|
|
||||||
|
|
||||||
if (subsectors[i].numlines == 0)
|
if (subsectors[i].numlines == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned firstseg = LittleShort(data[i].firstseg);
|
||||||
|
if (firstseg >= numsegs)
|
||||||
|
return false;
|
||||||
|
subsectors[i].firstline = &Level->segs[firstseg];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -438,12 +486,15 @@ bool MapLoader::LoadGLSubsectors(FileReader &lump)
|
||||||
for (i=0; i<numsubsectors; i++)
|
for (i=0; i<numsubsectors; i++)
|
||||||
{
|
{
|
||||||
subsectors[i].numlines = LittleLong(data[i].numsegs );
|
subsectors[i].numlines = LittleLong(data[i].numsegs );
|
||||||
subsectors[i].firstline = &Level->segs[LittleLong(data[i].firstseg)];
|
|
||||||
|
|
||||||
if (subsectors[i].numlines == 0)
|
if (subsectors[i].numlines == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned firstseg = LittleLong(data[i].firstseg);
|
||||||
|
if (firstseg >= numsegs)
|
||||||
|
return false;
|
||||||
|
subsectors[i].firstline = &Level->segs[firstseg];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,7 +825,7 @@ bool MapLoader::LoadGLNodes(MapData * map)
|
||||||
const int idcheck1b = MAKE_ID('X','G','L','N');
|
const int idcheck1b = MAKE_ID('X','G','L','N');
|
||||||
const int idcheck2b = MAKE_ID('X','G','L','2');
|
const int idcheck2b = MAKE_ID('X','G','L','2');
|
||||||
const int idcheck3b = MAKE_ID('X','G','L','3');
|
const int idcheck3b = MAKE_ID('X','G','L','3');
|
||||||
int id;
|
int id = 0;
|
||||||
|
|
||||||
auto &file = map->Reader(ML_GLZNODES);
|
auto &file = map->Reader(ML_GLZNODES);
|
||||||
file.Read (&id, 4);
|
file.Read (&id, 4);
|
||||||
|
|
Loading…
Reference in a new issue