mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-18 22:51:50 +00:00
C-CON: Correct handling of size-zero gamearrays: Prevent a crash upon loading a savegame containing them, and allow resizearray to zero.
git-svn-id: https://svn.eduke32.com/eduke32@5355 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
efe58c71f9
commit
1e40b689b2
3 changed files with 32 additions and 14 deletions
|
@ -4579,9 +4579,13 @@ finish_qsprintf:
|
||||||
|
|
||||||
int32_t numelts = kfilelength(fil) / sizeof(int32_t);
|
int32_t numelts = kfilelength(fil) / sizeof(int32_t);
|
||||||
|
|
||||||
// NOTE: LunaCON is stricter: if the file has no
|
if (numelts == 0)
|
||||||
// elements, resize the array to size zero.
|
{
|
||||||
if (numelts > 0)
|
Baligned_free(aGameArrays[j].plValues);
|
||||||
|
aGameArrays[j].plValues = NULL;
|
||||||
|
aGameArrays[j].size = numelts;
|
||||||
|
}
|
||||||
|
else if (numelts > 0)
|
||||||
{
|
{
|
||||||
int32_t numbytes = numelts * sizeof(int32_t);
|
int32_t numbytes = numelts * sizeof(int32_t);
|
||||||
#ifdef BITNESS64
|
#ifdef BITNESS64
|
||||||
|
@ -4644,18 +4648,20 @@ finish_qsprintf:
|
||||||
const int32_t newSize = Gv_GetVarX(*insptr++);
|
const int32_t newSize = Gv_GetVarX(*insptr++);
|
||||||
const int32_t oldSize = aGameArrays[tw].size;
|
const int32_t oldSize = aGameArrays[tw].size;
|
||||||
|
|
||||||
if (newSize > 0 && newSize != oldSize)
|
if (newSize >= 0 && newSize != oldSize)
|
||||||
{
|
{
|
||||||
// OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n",
|
// OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n",
|
||||||
// aGameArrays[j].szLabel, aGameArrays[j].size, newSize);
|
// aGameArrays[j].szLabel, aGameArrays[j].size, newSize);
|
||||||
intptr_t *const tmpar = (intptr_t *)Xmalloc(GAR_ELTSZ * oldSize);
|
intptr_t *const tmpar = oldSize != 0 ? (intptr_t *)Xmalloc(GAR_ELTSZ * oldSize) : NULL;
|
||||||
memcpy(tmpar, aGameArrays[tw].plValues, GAR_ELTSZ * oldSize);
|
if (oldSize != 0)
|
||||||
|
memcpy(tmpar, aGameArrays[tw].plValues, GAR_ELTSZ * oldSize);
|
||||||
|
|
||||||
Baligned_free(aGameArrays[tw].plValues);
|
Baligned_free(aGameArrays[tw].plValues);
|
||||||
aGameArrays[tw].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, GAR_ELTSZ * newSize);
|
aGameArrays[tw].plValues = newSize != 0 ? (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, GAR_ELTSZ * newSize) : NULL;
|
||||||
aGameArrays[tw].size = newSize;
|
aGameArrays[tw].size = newSize;
|
||||||
|
|
||||||
memcpy(aGameArrays[tw].plValues, tmpar, GAR_ELTSZ * min(oldSize, newSize));
|
if (oldSize != 0)
|
||||||
|
memcpy(aGameArrays[tw].plValues, tmpar, GAR_ELTSZ * min(oldSize, newSize));
|
||||||
if (newSize > oldSize)
|
if (newSize > oldSize)
|
||||||
memset(&aGameArrays[tw].plValues[oldSize], 0, GAR_ELTSZ * (newSize - oldSize));
|
memset(&aGameArrays[tw].plValues[oldSize], 0, GAR_ELTSZ * (newSize - oldSize));
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,14 @@ int32_t Gv_ReadSave(int32_t fil, int32_t newbehav)
|
||||||
goto corrupt;
|
goto corrupt;
|
||||||
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
|
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
|
||||||
|
|
||||||
aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, aGameArrays[i].size * GAR_ELTSZ);
|
intptr_t const asize = aGameArrays[i].size;
|
||||||
if (kdfread(aGameArrays[i].plValues, GAR_ELTSZ * aGameArrays[i].size, 1, fil) < 1) goto corrupt;
|
if (asize != 0)
|
||||||
|
{
|
||||||
|
aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, asize * GAR_ELTSZ);
|
||||||
|
if (kdfread(aGameArrays[i].plValues, GAR_ELTSZ * aGameArrays[i].size, 1, fil) < 1) goto corrupt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
aGameArrays[i].plValues = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
|
// Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
|
||||||
|
@ -466,8 +472,13 @@ int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32
|
||||||
if (!(dwFlags & GAMEARRAY_TYPE_MASK))
|
if (!(dwFlags & GAMEARRAY_TYPE_MASK))
|
||||||
{
|
{
|
||||||
Baligned_free(aGameArrays[i].plValues);
|
Baligned_free(aGameArrays[i].plValues);
|
||||||
aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, asize * GAR_ELTSZ);
|
if (asize != 0)
|
||||||
Bmemset(aGameArrays[i].plValues, 0, asize * GAR_ELTSZ);
|
{
|
||||||
|
aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, asize * GAR_ELTSZ);
|
||||||
|
Bmemset(aGameArrays[i].plValues, 0, asize * GAR_ELTSZ);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
aGameArrays[i].plValues = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
aGameArrays[i].plValues=(intptr_t *)arrayptr;
|
aGameArrays[i].plValues=(intptr_t *)arrayptr;
|
||||||
|
|
|
@ -1215,9 +1215,10 @@ static void sv_makevarspec()
|
||||||
if (aGameArrays[i].dwFlags & GAMEARRAY_READONLY)
|
if (aGameArrays[i].dwFlags & GAMEARRAY_READONLY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
intptr_t * const plValues = aGameArrays[i].plValues;
|
||||||
svgm_vars[j].flags = 0;
|
svgm_vars[j].flags = 0;
|
||||||
svgm_vars[j].ptr = aGameArrays[i].plValues;
|
svgm_vars[j].ptr = plValues;
|
||||||
svgm_vars[j].size = sizeof(aGameArrays[0].plValues[0]);
|
svgm_vars[j].size = plValues == NULL ? 0 : sizeof(aGameArrays[0].plValues[0]);
|
||||||
svgm_vars[j].cnt = aGameArrays[i].size; // assumed constant throughout demo, i.e. no RESIZEARRAY
|
svgm_vars[j].cnt = aGameArrays[i].size; // assumed constant throughout demo, i.e. no RESIZEARRAY
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue