According to our top researchers, it is a proven fact that it is better to show an error in chat instead of outright crashing the game

Don't crash the game if a .cw map has a bogus uuid length
This commit is contained in:
UnknownShadow200 2020-08-21 12:07:07 +10:00
parent a174821b28
commit 8a64e278e8
4 changed files with 14 additions and 8 deletions

View File

@ -47,7 +47,7 @@ enum ERRORS_ALL {
DAT_ERR_JCLASS_TYPE, DAT_ERR_JCLASS_FIELDS, DAT_ERR_JCLASS_ANNOTATION,
DAT_ERR_JOBJECT_TYPE, DAT_ERR_JARRAY_TYPE, DAT_ERR_JARRAY_CONTENT,
/* CW map decoding errors */
NBT_ERR_UNKNOWN, CW_ERR_ROOT_TAG, CW_ERR_STRING_LEN,
NBT_ERR_UNKNOWN, CW_ERR_ROOT_TAG, CW_ERR_STRING_LEN, CW_ERR_UUID_LEN,
/* OpenAL initing errors */
AL_ERR_INIT_DEVICE, AL_ERR_INIT_CONTEXT,
/* Inflate errors */

View File

@ -259,7 +259,7 @@ cc_result Fcm_Load(struct Stream* stream) {
/* header[25] (4) date modified */
/* header[29] (4) date created */
Mem_Copy(&World.Uuid, &header[33], sizeof(World.Uuid));
Mem_Copy(&World.Uuid, &header[33], WORLD_UUID_LEN);
/* header[49] (26) layer index */
count = (int)Stream_GetU32_LE(&header[75]);
@ -304,6 +304,7 @@ struct NbtTag {
struct { String text; char buffer[NBT_STRING_SIZE]; } str;
} value;
char _nameBuffer[NBT_STRING_SIZE];
cc_result err;
};
static cc_uint8 NbtTag_U8(struct NbtTag* tag) {
@ -432,10 +433,11 @@ static cc_result Nbt_ReadTag(cc_uint8 typeId, cc_bool readTagName, struct Stream
}
if (res) return res;
tag.err = 0;
callback(&tag);
/* NOTE: callback must set DataBig to NULL, if doesn't want it to be freed */
if (!NbtTag_IsSmall(&tag)) Mem_Free(tag.value.big);
return 0;
return tag.err;
}
#define IsTag(tag, tagName) (String_CaselessEqualsConst(&tag->name, tagName))
@ -500,8 +502,11 @@ static void Cw_Callback_1(struct NbtTag* tag) {
if (IsTag(tag, "Z")) { World.Length = NbtTag_U16(tag); return; }
if (IsTag(tag, "UUID")) {
if (tag->dataSize != sizeof(World.Uuid)) Logger_Abort("Map UUID must be 16 bytes");
Mem_Copy(World.Uuid, tag->value.small, sizeof(World.Uuid));
if (tag->dataSize != WORLD_UUID_LEN) {
tag->err = CW_ERR_UUID_LEN;
} else {
Mem_Copy(World.Uuid, tag->value.small, WORLD_UUID_LEN);
}
return;
}
@ -1091,7 +1096,7 @@ cc_result Cw_Save(struct Stream* stream) {
Mem_Copy(tmp, cw_begin, sizeof(cw_begin));
{
Mem_Copy(&tmp[43], World.Uuid, sizeof(World.Uuid));
Mem_Copy(&tmp[43], World.Uuid, WORLD_UUID_LEN);
Stream_SetU16_BE(&tmp[63], World.Width);
Stream_SetU16_BE(&tmp[69], World.Height);
Stream_SetU16_BE(&tmp[75], World.Length);

View File

@ -25,7 +25,7 @@ static void GenerateNewUuid(void) {
Random_Next(&rnd, Game_Username.buffer[i] + 3);
}
for (i = 0; i < 16; i++) {
for (i = 0; i < WORLD_UUID_LEN; i++) {
World.Uuid[i] = Random_Next(&rnd, 256);
}

View File

@ -12,6 +12,7 @@ struct AABB;
#define World_Unpack(idx, x, y, z) x = idx % World.Width; z = (idx / World.Width) % World.Length; y = (idx / World.Width) / World.Length;
/* Packs an x,y,z into a single index */
#define World_Pack(x, y, z) (((y) * World.Length + (z)) * World.Width + (x))
#define WORLD_UUID_LEN 16
CC_VAR extern struct _WorldData {
/* The blocks in the world. */
@ -32,7 +33,7 @@ CC_VAR extern struct _WorldData {
/* Adds one Y coordinate to a packed index. */
int OneY;
/* Unique identifier for this world. */
cc_uint8 Uuid[16];
cc_uint8 Uuid[WORLD_UUID_LEN];
#ifdef EXTENDED_BLOCKS
/* Masks access to World.Blocks/World.Blocks2 */