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:
hendricks266 2015-09-24 06:31:55 +00:00
parent efe58c71f9
commit 1e40b689b2
3 changed files with 32 additions and 14 deletions

View file

@ -4579,9 +4579,13 @@ finish_qsprintf:
int32_t numelts = kfilelength(fil) / sizeof(int32_t);
// NOTE: LunaCON is stricter: if the file has no
// elements, resize the array to size zero.
if (numelts > 0)
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);
#ifdef BITNESS64
@ -4644,18 +4648,20 @@ finish_qsprintf:
const int32_t newSize = Gv_GetVarX(*insptr++);
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",
// aGameArrays[j].szLabel, aGameArrays[j].size, newSize);
intptr_t *const tmpar = (intptr_t *)Xmalloc(GAR_ELTSZ * oldSize);
memcpy(tmpar, aGameArrays[tw].plValues, GAR_ELTSZ * oldSize);
intptr_t *const tmpar = oldSize != 0 ? (intptr_t *)Xmalloc(GAR_ELTSZ * oldSize) : NULL;
if (oldSize != 0)
memcpy(tmpar, aGameArrays[tw].plValues, GAR_ELTSZ * oldSize);
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;
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)
memset(&aGameArrays[tw].plValues[oldSize], 0, GAR_ELTSZ * (newSize - oldSize));
}

View file

@ -189,8 +189,14 @@ int32_t Gv_ReadSave(int32_t fil, int32_t newbehav)
goto corrupt;
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, aGameArrays[i].size * GAR_ELTSZ);
if (kdfread(aGameArrays[i].plValues, GAR_ELTSZ * aGameArrays[i].size, 1, fil) < 1) goto corrupt;
intptr_t const asize = aGameArrays[i].size;
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__);
@ -466,8 +472,13 @@ int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32
if (!(dwFlags & GAMEARRAY_TYPE_MASK))
{
Baligned_free(aGameArrays[i].plValues);
aGameArrays[i].plValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, asize * GAR_ELTSZ);
Bmemset(aGameArrays[i].plValues, 0, asize * GAR_ELTSZ);
if (asize != 0)
{
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
aGameArrays[i].plValues=(intptr_t *)arrayptr;

View file

@ -1215,9 +1215,10 @@ static void sv_makevarspec()
if (aGameArrays[i].dwFlags & GAMEARRAY_READONLY)
continue;
intptr_t * const plValues = aGameArrays[i].plValues;
svgm_vars[j].flags = 0;
svgm_vars[j].ptr = aGameArrays[i].plValues;
svgm_vars[j].size = sizeof(aGameArrays[0].plValues[0]);
svgm_vars[j].ptr = plValues;
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
j++;
}