Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix out of range enum casts in deSerialize functions #14090

Merged
merged 6 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3019,6 +3019,9 @@ void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *ca
CASE_SET(HUD_STAT_TEXT2, text2, sdata);

CASE_SET(HUD_STAT_STYLE, style, data);

case HudElementStat_END:
break;
}

#undef CASE_SET
Expand Down
3 changes: 2 additions & 1 deletion src/hud.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ enum HudElementType {
HUD_ELEM_MINIMAP = 7
};

enum HudElementStat {
enum HudElementStat : u8 {
HUD_STAT_POS = 0,
HUD_STAT_NAME,
HUD_STAT_SCALE,
Expand All @@ -85,6 +85,7 @@ enum HudElementStat {
HUD_STAT_Z_INDEX,
HUD_STAT_TEXT2,
HUD_STAT_STYLE,
HudElementStat_END // Dummy for validity check
};

enum HudCompassDir {
Expand Down
6 changes: 5 additions & 1 deletion src/itemdef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ void ItemDefinition::deSerialize(std::istream &is, u16 protocol_version)
if (version < 6)
throw SerializationError("unsupported ItemDefinition version");

type = (enum ItemType)readU8(is);
type = static_cast<ItemType>(readU8(is));
if (type >= ItemType_END) {
type = ITEM_NONE;
}

name = deSerializeString16(is);
description = deSerializeString16(is);
inventory_image = deSerializeString16(is);
Expand Down
3 changes: 2 additions & 1 deletion src/itemdef.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ struct ItemStack;
Base item definition
*/

enum ItemType
enum ItemType : u8
{
ITEM_NONE,
ITEM_NODE,
ITEM_CRAFT,
ITEM_TOOL,
ItemType_END // Dummy for validity check
};

struct ItemDefinition
Expand Down
6 changes: 6 additions & 0 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,8 @@ void ServerMap::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
floodable_node = n0.getContent();
liquid_kind = CONTENT_AIR;
break;
case LiquidType_END:
break;
}

/*
Expand Down Expand Up @@ -696,6 +698,8 @@ void ServerMap::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
flowing_down = true;
}
break;
case LiquidType_END:
break;
}
}

Expand Down Expand Up @@ -848,6 +852,8 @@ void ServerMap::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
for (u16 i = 0; i < num_flows; i++)
m_transforming_liquid.push_back(flows[i].p);
break;
case LiquidType_END:
break;
}
}
//infostream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
Expand Down
7 changes: 6 additions & 1 deletion src/network/clientpackethandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1229,8 +1229,13 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)

*pkt >> server_id >> stat;

// Do nothing if stat is not known
if (stat >= HudElementStat_END) {
return;
}

// Keep in sync with:server.cpp -> SendHUDChange
switch ((HudElementStat)stat) {
switch (static_cast<HudElementStat>(stat)) {
case HUD_STAT_POS:
case HUD_STAT_SCALE:
case HUD_STAT_ALIGN:
Expand Down
129 changes: 74 additions & 55 deletions src/nodedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,57 +126,62 @@ void NodeBox::deSerialize(std::istream &is)

reset();

type = (enum NodeBoxType)readU8(is);

if(type == NODEBOX_FIXED || type == NODEBOX_LEVELED)
{
u16 fixed_count = readU16(is);
while(fixed_count--)
{
aabb3f box;
box.MinEdge = readV3F32(is);
box.MaxEdge = readV3F32(is);
fixed.push_back(box);
type = static_cast<NodeBoxType>(readU8(is));
switch (type) {
case NODEBOX_REGULAR:
break;
case NODEBOX_FIXED:
case NODEBOX_LEVELED: {
u16 fixed_count = readU16(is);
while(fixed_count--) {
aabb3f box;
box.MinEdge = readV3F32(is);
box.MaxEdge = readV3F32(is);
fixed.push_back(box);
}
break;
}
}
else if(type == NODEBOX_WALLMOUNTED)
{
wall_top.MinEdge = readV3F32(is);
wall_top.MaxEdge = readV3F32(is);
wall_bottom.MinEdge = readV3F32(is);
wall_bottom.MaxEdge = readV3F32(is);
wall_side.MinEdge = readV3F32(is);
wall_side.MaxEdge = readV3F32(is);
}
else if (type == NODEBOX_CONNECTED)
{
case NODEBOX_WALLMOUNTED:
wall_top.MinEdge = readV3F32(is);
wall_top.MaxEdge = readV3F32(is);
wall_bottom.MinEdge = readV3F32(is);
wall_bottom.MaxEdge = readV3F32(is);
wall_side.MinEdge = readV3F32(is);
wall_side.MaxEdge = readV3F32(is);
break;
case NODEBOX_CONNECTED: {
#define READBOXES(box) { \
count = readU16(is); \
(box).reserve(count); \
while (count--) { \
v3f min = readV3F32(is); \
v3f max = readV3F32(is); \
(box).emplace_back(min, max); }; }

u16 count;

auto &c = getConnected();

READBOXES(fixed);
READBOXES(c.connect_top);
READBOXES(c.connect_bottom);
READBOXES(c.connect_front);
READBOXES(c.connect_left);
READBOXES(c.connect_back);
READBOXES(c.connect_right);
READBOXES(c.disconnected_top);
READBOXES(c.disconnected_bottom);
READBOXES(c.disconnected_front);
READBOXES(c.disconnected_left);
READBOXES(c.disconnected_back);
READBOXES(c.disconnected_right);
READBOXES(c.disconnected);
READBOXES(c.disconnected_sides);
count = readU16(is); \
(box).reserve(count); \
while (count--) { \
v3f min = readV3F32(is); \
v3f max = readV3F32(is); \
(box).emplace_back(min, max); }; }

u16 count;

auto &c = getConnected();

READBOXES(fixed);
READBOXES(c.connect_top);
READBOXES(c.connect_bottom);
READBOXES(c.connect_front);
READBOXES(c.connect_left);
READBOXES(c.connect_back);
READBOXES(c.connect_right);
READBOXES(c.disconnected_top);
READBOXES(c.disconnected_bottom);
READBOXES(c.disconnected_front);
READBOXES(c.disconnected_left);
READBOXES(c.disconnected_back);
READBOXES(c.disconnected_right);
READBOXES(c.disconnected);
READBOXES(c.disconnected_sides);
break;
}
default:
type = NODEBOX_REGULAR;
break;
}
}

Expand Down Expand Up @@ -266,9 +271,11 @@ void TileDef::deSerialize(std::istream &is, NodeDrawType drawtype, u16 protocol_
color.setBlue(readU8(is));
}
scale = has_scale ? readU8(is) : 0;
if (has_align_style)
if (has_align_style) {
align_style = static_cast<AlignStyle>(readU8(is));
else
if (align_style >= AlignStyle_END)
align_style = ALIGN_STYLE_NODE;
} else
align_style = ALIGN_STYLE_NODE;
cx384 marked this conversation as resolved.
Show resolved Hide resolved
}

Expand Down Expand Up @@ -559,11 +566,19 @@ void ContentFeatures::deSerialize(std::istream &is, u16 protocol_version)
int value = readS16(is);
groups[name] = value;
}
param_type = (enum ContentParamType) readU8(is);
param_type_2 = (enum ContentParamType2) readU8(is);

param_type = static_cast<ContentParamType>(readU8(is));
if (param_type >= ContentParamType_END)
param_type = CPT_NONE;

param_type_2 = static_cast<ContentParamType2>(readU8(is));
if (param_type_2 >= ContentParamType2_END)
param_type_2 = CPT2_NONE;

// visual
drawtype = (enum NodeDrawType) readU8(is);
drawtype = static_cast<NodeDrawType>(readU8(is));
if (drawtype >= NodeDrawType_END)
drawtype = NDT_NORMAL;
mesh = deSerializeString16(is);
visual_scale = readF32(is);
if (readU8(is) != 6)
Expand Down Expand Up @@ -609,7 +624,9 @@ void ContentFeatures::deSerialize(std::istream &is, u16 protocol_version)
damage_per_second = readU32(is);

// liquid
liquid_type = (enum LiquidType) readU8(is);
liquid_type = static_cast<LiquidType>(readU8(is));
if (liquid_type >= LiquidType_END)
liquid_type = LIQUID_NONE;
liquid_move_physics = liquid_type != LIQUID_NONE;
liquid_alternative_flowing = deSerializeString16(is);
liquid_alternative_source = deSerializeString16(is);
Expand Down Expand Up @@ -646,6 +663,8 @@ void ContentFeatures::deSerialize(std::istream &is, u16 protocol_version)
if (is.eof())
throw SerializationError("");
alpha = static_cast<enum AlphaMode>(tmp);
if (alpha >= AlphaMode_END)
throw SerializationError("unsupported AlphaMode");
cx384 marked this conversation as resolved.
Show resolved Hide resolved
if (alpha == ALPHAMODE_LEGACY_COMPAT)
alpha = ALPHAMODE_OPAQUE;

Expand Down
18 changes: 13 additions & 5 deletions src/nodedef.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ class NodeResolver;
class TestSchematic;
#endif

enum ContentParamType
enum ContentParamType : u8
{
CPT_NONE,
CPT_LIGHT,
ContentParamType_END // Dummy for validity check
};

enum ContentParamType2
enum ContentParamType2 : u8
{
CPT2_NONE,
// Need 8-bit param2
Expand Down Expand Up @@ -82,16 +83,19 @@ enum ContentParamType2
CPT2_4DIR,
// 6 bits of palette index, then 4dir
CPT2_COLORED_4DIR,
// Dummy for validity check
ContentParamType2_END
};

enum LiquidType
enum LiquidType : u8
{
LIQUID_NONE,
LIQUID_FLOWING,
LIQUID_SOURCE,
LiquidType_END // Dummy for validity check
};

enum NodeBoxType
enum NodeBoxType : u8
{
NODEBOX_REGULAR, // Regular block; allows buildable_to
NODEBOX_FIXED, // Static separately defined box(es)
Expand Down Expand Up @@ -189,7 +193,7 @@ class TextureSettings {
void readSettings();
};

enum NodeDrawType
enum NodeDrawType : u8
{
// A basic solid block
NDT_NORMAL,
Expand Down Expand Up @@ -233,6 +237,8 @@ enum NodeDrawType
NDT_MESH,
// Combined plantlike-on-solid
NDT_PLANTLIKE_ROOTED,
// Dummy for validity check
NodeDrawType_END
};

// Mesh options for NDT_PLANTLIKE with CPT2_MESHOPTIONS
Expand All @@ -252,13 +258,15 @@ enum AlignStyle : u8 {
ALIGN_STYLE_NODE,
ALIGN_STYLE_WORLD,
ALIGN_STYLE_USER_DEFINED,
AlignStyle_END // Dummy for validity check
};

enum AlphaMode : u8 {
ALPHAMODE_BLEND,
ALPHAMODE_CLIP,
ALPHAMODE_OPAQUE,
ALPHAMODE_LEGACY_COMPAT, /* only sent by old servers, equals OPAQUE */
AlphaMode_END // Dummy for validity check
};


Expand Down
4 changes: 4 additions & 0 deletions src/particles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ T TweenedParameter<T>::blend(float fac) const
fac *= myrand_range(0.7f, 1.0f);
}
}
case TweenStyle::TweenStyle_END:
break;
}
if (fac>1.f)
fac = 1.f;
Expand All @@ -110,6 +112,8 @@ template<typename T>
void TweenedParameter<T>::deSerialize(std::istream &is)
{
style = static_cast<TweenStyle>(readU8(is));
if (style >= TweenStyle::TweenStyle_END)
style = TweenStyle::fwd;
reps = readU16(is);
beginning = readF32(is);
start.deSerialize(is);
Expand Down
3 changes: 2 additions & 1 deletion src/particles.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ namespace ParticleParamTypes
}

// Animation styles (fwd is normal, linear interpolation)
enum class TweenStyle : u8 { fwd, rev, pulse, flicker };
// TweenStyle_END is a dummy value for validity check
enum class TweenStyle : u8 { fwd, rev, pulse, flicker, TweenStyle_END};

// "Tweened" pretty much means "animated" in this context
template <typename T>
Expand Down
5 changes: 4 additions & 1 deletion src/script/common/c_content.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2100,7 +2100,7 @@ bool read_hud_change(lua_State *L, HudElementStat &stat, HudElement *elem, void
return false;
}

stat = (HudElementStat)statint;
stat = static_cast<HudElementStat>(statint);
}

switch (stat) {
Expand Down Expand Up @@ -2162,6 +2162,9 @@ bool read_hud_change(lua_State *L, HudElementStat &stat, HudElement *elem, void
elem->style = luaL_checknumber(L, 4);
*value = &elem->style;
break;
case HudElementStat_END:
return false;
break;
}

return true;
Expand Down