Final round of Mapster32 hardening. Going over the limits should now always produce an error message instead of corrupting the data. Also fixes crash in defs.c (thanks for the crashlog, LeoD).

git-svn-id: https://svn.eduke32.com/eduke32@1808 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-02-27 19:13:44 +00:00
parent 7f2bf98179
commit 619d3c8c9e
3 changed files with 203 additions and 281 deletions

View file

@ -1780,12 +1780,17 @@ static void copy_some_wall_members(int16_t dst, int16_t src)
} }
// helpers for often needed ops: // helpers for often needed ops:
static void copyloop1(int16_t *danumwalls, int32_t *m) static int32_t copyloop1(int16_t *danumwalls, int32_t *m)
{ {
if (*danumwalls >= MAXWALLS + M32_FIXME_WALLS)
return 1;
Bmemcpy(&wall[*danumwalls], &wall[*m], sizeof(walltype)); Bmemcpy(&wall[*danumwalls], &wall[*m], sizeof(walltype));
wall[*danumwalls].point2 = *danumwalls+1; wall[*danumwalls].point2 = *danumwalls+1;
(*danumwalls)++; (*danumwalls)++;
*m = wall[*m].point2; *m = wall[*m].point2;
return 0;
} }
static void updatesprite1(int16_t j) static void updatesprite1(int16_t j)
@ -1811,7 +1816,7 @@ void overheadeditor(void)
int32_t tempint, tempint1, tempint2, doubvel; int32_t tempint, tempint1, tempint2, doubvel;
int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3, x4, y4; int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3, x4, y4;
int32_t highlightx1, highlighty1, highlightx2, highlighty2, xvect, yvect; int32_t highlightx1, highlighty1, highlightx2, highlighty2, xvect, yvect;
int16_t pag, suckwall=0, sucksect, split=0, bad, goodtogo; int16_t pag, suckwall=0, sucksect, split=0, bad;
int16_t splitsect=0, joinsector[2]; int16_t splitsect=0, joinsector[2];
int16_t splitstartwall=0, loopnum; int16_t splitstartwall=0, loopnum;
int32_t mousx, mousy, bstatus; int32_t mousx, mousy, bstatus;
@ -3585,7 +3590,8 @@ end_point_dragging:
{ {
if (newnumwalls >= MAXWALLS + M32_FIXME_WALLS) if (newnumwalls >= MAXWALLS + M32_FIXME_WALLS)
{ {
printmessage16("Joining sectors failed: not enough space beyond wall[]"); message("Joining sectors failed: not enough space beyond wall[]");
joinsector[0] = -1;
newnumwalls = -1; newnumwalls = -1;
for (i=0; i<numwalls; i++) for (i=0; i<numwalls; i++)
@ -3815,7 +3821,7 @@ end_join_sectors:
if (tempint2 != 0) if (tempint2 != 0)
{ {
int32_t ps = 2; // pointsize int32_t ps = 2, goodtogo; // pointsize
centerx = ((x1+x2) + scale(y1-y2,tempint1,tempint2))>>1; centerx = ((x1+x2) + scale(y1-y2,tempint1,tempint2))>>1;
centery = ((y1+y2) + scale(x2-x1,tempint1,tempint2))>>1; centery = ((y1+y2) + scale(x2-x1,tempint1,tempint2))>>1;
@ -3893,38 +3899,7 @@ end_join_sectors:
} }
} }
goodtogo = 1; // Checking limits... if (bad > 0) //Space
if (bad > 0)
{
if (newnumwalls < numwalls) // starting wall drawing
{
}
else
{
//if not back to first point
if (firstx != mousxplc || firsty != mousyplc) //nextpoint
{
}
//if not split and back to first point
if ((split == 0) && (firstx == mousxplc) && (firsty == mousyplc) && (newnumwalls >= numwalls+3))
{
if (suckwall == -1) //if no connections to other sectors
{ /* No problem... */ }
else
{
if (newnumwalls > MAXWALLS)
{
goodtogo = 0;
printmessage16("Closing wall drawing would exceed wall limit.");
}
}
}
// else if (split==1) {} // handled there
}
}
if (bad > 0 && goodtogo) //Space
{ {
if (newnumwalls < numwalls) // starting wall drawing if (newnumwalls < numwalls) // starting wall drawing
{ {
@ -4054,32 +4029,39 @@ end_join_sectors:
else else
{ {
printmessage16("You can't draw new lines over red lines."); printmessage16("You can't draw new lines over red lines.");
goto end_space_handling;
} }
} }
} }
////////// newnumwalls is at most MAXWALLS here //////////
//if not split and back to first point //if not split and back to first point
if ((split == 0) && (firstx == mousxplc) && (firsty == mousyplc) && (newnumwalls >= numwalls+3)) if (!split && newnumwalls >= numwalls+3
&& firstx==mousxplc && firsty==mousyplc)
{ {
// newnumwalls is at most MAXWALLS here
wall[newnumwalls-1].point2 = numwalls; wall[newnumwalls-1].point2 = numwalls;
if (suckwall == -1) //if no connections to other sectors if (suckwall == -1) //if no connections to other sectors
{ {
k = -1; k = -1;
for (i=0; i<numsectors; i++) for (i=0; i<numsectors; i++)
{
if (inside(firstx,firsty,i) == 1) if (inside(firstx,firsty,i) == 1)
{ {
// if all points inside that one sector i,
// will add an inner loop
for (j=numwalls+1; j<newnumwalls; j++) for (j=numwalls+1; j<newnumwalls; j++)
{ {
if (inside(wall[j].x, wall[j].y, i) == 0) if (inside(wall[j].x, wall[j].y, i) == 0)
continue; goto check_next_sector;
} }
k = i; k = i;
break; break;
} }
check_next_sector: ;
}
if (k == -1) //if not inside another sector either if (k == -1) //if not inside another sector either
{ {
@ -4105,6 +4087,8 @@ end_join_sectors:
headspritesect[numsectors] = -1; headspritesect[numsectors] = -1;
numsectors++; numsectors++;
printmessage16("Created new sector %d", numsectors-1);
} }
else //else add loop to sector else //else add loop to sector
{ {
@ -4143,40 +4127,32 @@ end_join_sectors:
} }
setfirstwall(k, suckwall+j); // restore old first wall setfirstwall(k, suckwall+j); // restore old first wall
printmessage16("Added inner loop to sector %d", k);
} }
} }
else // if connected to at least one other sector else // if connected to at least one other sector
{ {
sectortype *newsec;
const sectortype *oldsec;
//add new sector with connections //add new sector with connections
if (clockdir(numwalls) == 1) if (clockdir(numwalls) == 1)
flipwalls(numwalls,newnumwalls); flipwalls(numwalls,newnumwalls);
newsec = &sector[numsectors];
sucksect = sectorofwall(suckwall); sucksect = sectorofwall(suckwall);
oldsec = &sector[sucksect];
Bmemset(newsec, 0, sizeof(sectortype)); if (numsectors != sucksect)
newsec->extra = -1; Bmemcpy(&sector[numsectors], &sector[sucksect], sizeof(sectortype));
newsec->wallptr = numwalls; sector[numsectors].wallptr = numwalls;
newsec->wallnum = newnumwalls-numwalls; sector[numsectors].wallnum = newnumwalls-numwalls;
newsec->ceilingstat = oldsec->ceilingstat; sector[numsectors].extra = -1;
newsec->floorstat = oldsec->floorstat; sector[numsectors].lotag = sector[numsectors].hitag = 0;
newsec->ceilingxpanning = oldsec->ceilingxpanning;
newsec->floorxpanning = oldsec->floorxpanning; sector[numsectors].ceilingstat &= ~2;
newsec->ceilingshade = oldsec->ceilingshade; sector[numsectors].floorstat &= ~2;
newsec->floorshade = oldsec->floorshade; sector[numsectors].ceilingheinum = sector[numsectors].floorheinum = 0;
newsec->ceilingz = oldsec->ceilingz; sector[numsectors].ceilingpal = sector[numsectors].floorpal = 0;
newsec->floorz = oldsec->floorz;
newsec->ceilingpicnum = oldsec->ceilingpicnum;
newsec->floorpicnum = oldsec->floorpicnum;
// newsec->ceilingheinum = oldsec->ceilingheinum;
// newsec->floorheinum = oldsec->floorheinum;
for (i=numwalls; i<newnumwalls; i++) for (i=numwalls; i<newnumwalls; i++)
{ {
@ -4186,17 +4162,22 @@ end_join_sectors:
headspritesect[numsectors] = -1; headspritesect[numsectors] = -1;
numsectors++; numsectors++;
printmessage16("Created new sector %d based on sector %d", numsectors-1, sucksect);
} }
numwalls = newnumwalls; numwalls = newnumwalls;
newnumwalls = -1; newnumwalls = -1;
asksave = 1; asksave = 1;
goto end_space_handling;
} }
////////// split sector //////////
else if (split == 1) else if (split == 1)
{ {
int16_t danumwalls, splitendwall, secondstartwall; int16_t danumwalls, splitendwall, doSectorSplit;
int16_t secondstartwall=-1; // used only with splitting
//split sector
startwall = sector[splitsect].wallptr; startwall = sector[splitsect].wallptr;
endwall = startwall + sector[splitsect].wallnum - 1; endwall = startwall + sector[splitsect].wallnum - 1;
@ -4206,9 +4187,7 @@ end_join_sectors:
if (wall[k].x != wall[newnumwalls-1].x || wall[k].y != wall[newnumwalls-1].y) if (wall[k].x != wall[newnumwalls-1].x || wall[k].y != wall[newnumwalls-1].y)
continue; continue;
bad = 0; doSectorSplit = (loopnumofsector(splitsect,splitstartwall) == loopnumofsector(splitsect,k));
if (loopnumofsector(splitsect,splitstartwall) != loopnumofsector(splitsect,k))
bad = 1;
if (numwalls+2*(newnumwalls-numwalls-1) > MAXWALLS) if (numwalls+2*(newnumwalls-numwalls-1) > MAXWALLS)
{ {
@ -4218,11 +4197,7 @@ end_join_sectors:
break; break;
} }
if (bad == 0) ////////// common code for splitting/loop joining //////////
{
//SPLIT IT!
//Split splitsect given: startwall,
// new points: numwalls to newnumwalls-2
splitendwall = k; splitendwall = k;
newnumwalls--; //first fix up the new walls newnumwalls--; //first fix up the new walls
@ -4237,32 +4212,47 @@ end_join_sectors:
danumwalls = newnumwalls; //where to add more walls danumwalls = newnumwalls; //where to add more walls
m = splitendwall; //copy rest of loop next m = splitendwall; //copy rest of loop next
if (doSectorSplit)
{
while (m != splitstartwall) while (m != splitstartwall)
copyloop1(&danumwalls, &m); if (copyloop1(&danumwalls, &m)) goto split_not_enough_walls;
wall[danumwalls-1].point2 = numwalls; wall[danumwalls-1].point2 = numwalls;
//Add other loops for 1st sector //Add other loops for 1st sector
loopnum = loopnumofsector(splitsect,splitstartwall); i = loopnum = loopnumofsector(splitsect,splitstartwall);
i = loopnum;
for (j=startwall; j<=endwall; j++) for (j=startwall; j<=endwall; j++)
{ {
k = loopnumofsector(splitsect,j); k = loopnumofsector(splitsect,j);
if ((k != i) && (k != loopnum)) if (k == i)
{ continue;
if (k == loopnum)
continue;
i = k; i = k;
if (loopinside(wall[j].x,wall[j].y,numwalls) == 1)
{ if (loopinside(wall[j].x,wall[j].y, numwalls) != 1)
continue;
m = j; //copy loop m = j; //copy loop
k = danumwalls; k = danumwalls;
do do
copyloop1(&danumwalls, &m); if (copyloop1(&danumwalls, &m)) goto split_not_enough_walls;
while (m != j); while (m != j);
wall[danumwalls-1].point2 = k; wall[danumwalls-1].point2 = k;
} }
}
}
secondstartwall = danumwalls; secondstartwall = danumwalls;
}
else
{
do
if (copyloop1(&danumwalls, &m)) goto split_not_enough_walls;
while (m != splitendwall);
}
//copy split points for other sector backwards //copy split points for other sector backwards
for (j=newnumwalls; j>numwalls; j--) for (j=newnumwalls; j>numwalls; j--)
{ {
@ -4274,29 +4264,46 @@ end_join_sectors:
} }
m = splitstartwall; //copy rest of loop next m = splitstartwall; //copy rest of loop next
if (doSectorSplit)
{
while (m != splitendwall) while (m != splitendwall)
copyloop1(&danumwalls, &m); if (copyloop1(&danumwalls, &m)) goto split_not_enough_walls;
wall[danumwalls-1].point2 = secondstartwall; wall[danumwalls-1].point2 = secondstartwall;
}
else
{
do
if (copyloop1(&danumwalls, &m)) goto split_not_enough_walls;
while (m != splitstartwall);
wall[danumwalls-1].point2 = numwalls;
}
//Add other loops for 2nd sector //Add other loops for 2nd sector
loopnum = loopnumofsector(splitsect,splitstartwall); i = loopnum = loopnumofsector(splitsect,splitstartwall);
i = loopnum;
for (j=startwall; j<=endwall; j++) for (j=startwall; j<=endwall; j++)
{ {
k = loopnumofsector(splitsect, j); k = loopnumofsector(splitsect, j);
if ((k != i) && (k != loopnum)) if (k==i)
{ continue;
if (doSectorSplit && k==loopnum)
continue;
if (!doSectorSplit && (k == loopnumofsector(splitsect,splitstartwall) || k == loopnumofsector(splitsect,splitendwall)))
continue;
i = k; i = k;
if (loopinside(wall[j].x,wall[j].y,secondstartwall) == 1)
{ if (doSectorSplit && (loopinside(wall[j].x,wall[j].y, secondstartwall) != 1))
continue;
m = j; k = danumwalls; //copy loop m = j; k = danumwalls; //copy loop
do do
copyloop1(&danumwalls, &m); if (copyloop1(&danumwalls, &m)) goto split_not_enough_walls;
while (m != j); while (m != j);
wall[danumwalls-1].point2 = k; wall[danumwalls-1].point2 = k;
} }
}
}
//fix all next pointers on old sector line //fix all next pointers on old sector line
for (j=numwalls; j<danumwalls; j++) for (j=numwalls; j<danumwalls; j++)
@ -4304,12 +4311,16 @@ end_join_sectors:
if (wall[j].nextwall >= 0) if (wall[j].nextwall >= 0)
{ {
NEXTWALL(j).nextwall = j; NEXTWALL(j).nextwall = j;
if (j < secondstartwall)
if (!doSectorSplit || j < secondstartwall)
NEXTWALL(j).nextsector = numsectors; NEXTWALL(j).nextsector = numsectors;
else else
NEXTWALL(j).nextsector = numsectors+1; NEXTWALL(j).nextsector = numsectors+1;
} }
} }
if (doSectorSplit)
{
//set all next pointers on split //set all next pointers on split
for (j=numwalls; j<newnumwalls; j++) for (j=numwalls; j<newnumwalls; j++)
{ {
@ -4319,20 +4330,29 @@ end_join_sectors:
wall[m].nextwall = j; wall[m].nextwall = j;
wall[m].nextsector = numsectors; wall[m].nextsector = numsectors;
} }
//copy sector attributes & fix wall pointers //copy sector attributes & fix wall pointers
Bmemcpy(&sector[numsectors], &sector[splitsect], sizeof(sectortype)); Bmemcpy(&sector[numsectors], &sector[splitsect], sizeof(sectortype));
Bmemcpy(&sector[numsectors+1], &sector[splitsect], sizeof(sectortype));
sector[numsectors].wallptr = numwalls; sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = secondstartwall-numwalls; sector[numsectors].wallnum = secondstartwall-numwalls;
Bmemcpy(&sector[numsectors+1], &sector[splitsect], sizeof(sectortype));
sector[numsectors+1].wallptr = secondstartwall; sector[numsectors+1].wallptr = secondstartwall;
sector[numsectors+1].wallnum = danumwalls-secondstartwall; sector[numsectors+1].wallnum = danumwalls-secondstartwall;
}
else
{
//copy sector attributes & fix wall pointers
Bmemcpy(&sector[numsectors], &sector[splitsect], sizeof(sectortype));
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = danumwalls-numwalls;
}
//fix sprites //fix sprites
j = headspritesect[splitsect]; j = headspritesect[splitsect];
while (j != -1) while (j != -1)
{ {
k = nextspritesect[j]; k = nextspritesect[j];
if (loopinside(sprite[j].x,sprite[j].y,numwalls) == 1) if (!doSectorSplit || loopinside(sprite[j].x,sprite[j].y,numwalls) == 1)
changespritesect(j,numsectors); changespritesect(j,numsectors);
//else if (loopinside(sprite[j].x,sprite[j].y,secondstartwall) == 1) //else if (loopinside(sprite[j].x,sprite[j].y,secondstartwall) == 1)
else //Make sure no sprites get left out & deleted! else //Make sure no sprites get left out & deleted!
@ -4340,30 +4360,27 @@ end_join_sectors:
j = k; j = k;
} }
numsectors+=2; numsectors += 1 + doSectorSplit;
//Back of number of walls of new sector for later k = danumwalls-numwalls; //Back of number of walls of new sector for later
k = danumwalls-numwalls; numwalls = danumwalls;
//clear out old sector's next pointers for clean deletesector //clear out old sector's next pointers for clean deletesector
numwalls = danumwalls;
for (j=startwall; j<=endwall; j++) for (j=startwall; j<=endwall; j++)
{ wall[j].nextwall = wall[j].nextsector = -1;
wall[j].nextwall = -1;
wall[j].nextsector = -1;
}
deletesector(splitsect); deletesector(splitsect);
//Check pointers //Check pointers
for (j=numwalls-k; j<numwalls; j++) for (j=numwalls-k; j<numwalls; j++)
{ {
if (wall[j].nextwall >= 0) if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector); checksectorpointer(wall[j].nextwall, wall[j].nextsector);
checksectorpointer(j, sectorofwall(j)); checksectorpointer(j, sectorofwall(j));
} }
//k now safe to use as temp //k now safe to use as temp
#if 0
if (doSectorSplit)
for (m=numsectors-2; m<numsectors; m++) for (m=numsectors-2; m<numsectors; m++)
{ {
j = headspritesect[m]; j = headspritesect[m];
@ -4374,110 +4391,14 @@ end_join_sectors:
j = k; j = k;
} }
} }
#endif
printmessage16(doSectorSplit ? "Sector split." : "Loops joined.");
printmessage16("Sector split."); if (0)
}
else
{ {
//Sector split - actually loop joining split_not_enough_walls:
message("%s failed: not enough space beyond wall[]",
splitendwall = k; doSectorSplit ? "Splitting sectors" : "Joining loops");
newnumwalls--; //first fix up the new walls
for (i=numwalls; i<newnumwalls; i++)
{
copy_some_wall_members(i, startwall);
wall[i].nextwall = -1;
wall[i].nextsector = -1;
wall[i].point2 = i+1;
}
danumwalls = newnumwalls; //where to add more walls
m = splitendwall; //copy rest of loop next
do
copyloop1(&danumwalls, &m);
while (m != splitendwall);
//copy split points for other sector backwards
for (j=newnumwalls; j>numwalls; j--)
{
Bmemcpy(&wall[danumwalls],&wall[j],sizeof(walltype));
wall[danumwalls].nextwall = -1;
wall[danumwalls].nextsector = -1;
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
}
m = splitstartwall; //copy rest of loop next
do
copyloop1(&danumwalls, &m);
while (m != splitstartwall);
wall[danumwalls-1].point2 = numwalls;
//Add other loops to sector
loopnum = loopnumofsector(splitsect,splitstartwall);
i = loopnum;
for (j=startwall; j<=endwall; j++)
{
k = loopnumofsector(splitsect, j);
if ((k != i) && (k != loopnumofsector(splitsect,splitstartwall)) && (k != loopnumofsector(splitsect,splitendwall)))
{
i = k;
m = j; k = danumwalls; //copy loop
do
copyloop1(&danumwalls, &m);
while (m != j);
wall[danumwalls-1].point2 = k;
}
}
//fix all next pointers on old sector line
for (j=numwalls; j<danumwalls; j++)
{
if (wall[j].nextwall >= 0)
{
NEXTWALL(j).nextwall = j;
NEXTWALL(j).nextsector = numsectors;
}
}
//copy sector attributes & fix wall pointers
Bmemcpy(&sector[numsectors],&sector[splitsect],sizeof(sectortype));
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = danumwalls-numwalls;
//fix sprites
j = headspritesect[splitsect];
while (j != -1)
{
k = nextspritesect[j];
changespritesect(j,numsectors);
j = k;
}
numsectors++;
//Back of number of walls of new sector for later
k = danumwalls-numwalls;
//clear out old sector's next pointers for clean deletesector
numwalls = danumwalls;
for (j=startwall; j<=endwall; j++)
{
wall[j].nextwall = -1;
wall[j].nextsector = -1;
}
deletesector(splitsect);
//Check pointers
for (j=numwalls-k; j<numwalls; j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer(j, numsectors-1);
}
printmessage16("Loops joined.");
} }
newnumwalls = -1; newnumwalls = -1;
@ -6729,6 +6650,7 @@ static void copysector(int16_t soursector, int16_t destsector, int16_t deststart
break; break;
m += sector[highlightsector[i]].wallnum; m += sector[highlightsector[i]].wallnum;
} }
if (i==highlightsectorcnt) if (i==highlightsectorcnt)
{ {
message("internal error in copysector(): i==highlightsectorcnt"); message("internal error in copysector(): i==highlightsectorcnt");

View file

@ -467,7 +467,7 @@ static int32_t defsparser(scriptfile *script)
char *texturetokptr = script->ltextptr, *textureend, *fn = NULL, *tfn = NULL, *ftd = NULL; char *texturetokptr = script->ltextptr, *textureend, *fn = NULL, *tfn = NULL, *ftd = NULL;
int32_t tile=-1, token, i; int32_t tile=-1, token, i;
int32_t alphacut = 255; int32_t alphacut = 255;
int32_t xoffset = 0, yoffset = 0; int32_t xoffset = 0, yoffset = 0, goodtogo=0;
static const tokenlist tilefromtexturetokens[] = static const tokenlist tilefromtexturetokens[] =
{ {
@ -526,6 +526,7 @@ static int32_t defsparser(scriptfile *script)
} }
else Bfree(tfn); else Bfree(tfn);
pathsearchmode = i; pathsearchmode = i;
goodtogo = 1;
} }
if ((unsigned)tile >= (unsigned)MAXTILES) if ((unsigned)tile >= (unsigned)MAXTILES)
@ -535,6 +536,7 @@ static int32_t defsparser(scriptfile *script)
break; break;
} }
if (goodtogo)
{ {
int32_t xsiz, ysiz, j; int32_t xsiz, ysiz, j;
int32_t *picptr = NULL; int32_t *picptr = NULL;

View file

@ -6703,7 +6703,6 @@ static void Keys2d(void)
static int32_t omx = 0, omy = 0; static int32_t omx = 0, omy = 0;
/* /*
static int32_t opointhighlight, olinehighlight, ocursectornum; static int32_t opointhighlight, olinehighlight, ocursectornum;
if (pointhighlight == opointhighlight && linehighlight == olinehighlight && tcursectornum == ocursectornum) if (pointhighlight == opointhighlight && linehighlight == olinehighlight && tcursectornum == ocursectornum)
*/ */
if (omx == mousxplc && omy == mousyplc) if (omx == mousxplc && omy == mousyplc)
@ -6723,7 +6722,6 @@ static void Keys2d(void)
ocursectornum = tcursectornum; ocursectornum = tcursectornum;
*/ */
if (totalclock < lastpm16time + 120*2) if (totalclock < lastpm16time + 120*2)
_printmessage16("%s", lastpm16buf); _printmessage16("%s", lastpm16buf);
else if (counter >= 2 && totalclock >= 120*6) else if (counter >= 2 && totalclock >= 120*6)