From 5454ef892d3031452038bf6c1af2129ca5d09773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20B=C3=A1lint=20Misius?= Date: Sat, 7 Dec 2024 00:09:33 +0100 Subject: [PATCH] Fix crashes when giving !set invalid property values This fixes two kinds of crashes: the one where the value passed is not possible to convert at all to the type of value expected (e.g. expect unsigned integer, get point), and also when it is possible, because the difference is only in signedness (e.g. expect unsigned integer, get signed integer). Both cases crash since 8552aafbceb7, where the handling of the former case got removed and accidentally never got added back, and the handling of the latter changed from converting everything to strings and working from there to converting directly between floats and numbers, disregarding signedness. --- src/lua/CommandInterface.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/lua/CommandInterface.cpp b/src/lua/CommandInterface.cpp index 81bc08014..ee9b2f085 100644 --- a/src/lua/CommandInterface.cpp +++ b/src/lua/CommandInterface.cpp @@ -361,6 +361,7 @@ AnyType CommandInterface::tptS_set(std::deque * words) } auto &propInfo = Particle::GetProperties()[*prop]; + // assume that value can be anything if (value.GetType() == TypeNumber && propInfo.Type == StructProperty::Float) { value = FloatType(NumberType(value).Value()); @@ -369,27 +370,38 @@ AnyType CommandInterface::tptS_set(std::deque * words) { value = NumberType(FloatType(value).Value()); } + // value can still be almost anything, but if it was NumberType or FloatType, + // at least it now matches the float-ness, if not the signedness, of prop AccessProperty changeProperty; try { switch (value.GetType()) { case TypeNumber: + // get a number (an int) => take an int changeProperty.propertyIndex = *prop; changeProperty.propertyValue = NumberType(value).Value(); + if (propInfo.Type == StructProperty::UInteger) + { + // actually want an unsigned int => convert the int taken to one + changeProperty.propertyValue = static_cast(std::get(changeProperty.propertyValue)); + } break; case TypeFloat: + // get a float => take a float changeProperty.propertyIndex = *prop; changeProperty.propertyValue = FloatType(value).Value(); break; case TypeString: + // AccessProperty::Parse returns the appropriate variant changeProperty = AccessProperty::Parse(*prop, StringType(value).Value()); break; default: - break; + // get something else => bail + throw GeneralException("Invalid property value"); } } catch (const AccessProperty::ParseError &ex)