aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/compactbinaryvalidation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/compactbinaryvalidation.cpp')
-rw-r--r--src/zencore/compactbinaryvalidation.cpp96
1 files changed, 76 insertions, 20 deletions
diff --git a/src/zencore/compactbinaryvalidation.cpp b/src/zencore/compactbinaryvalidation.cpp
index 462978f63..d7292f405 100644
--- a/src/zencore/compactbinaryvalidation.cpp
+++ b/src/zencore/compactbinaryvalidation.cpp
@@ -4,7 +4,7 @@
#include <zencore/compactbinarypackage.h>
#include <zencore/endian.h>
-#include <zencore/memory.h>
+#include <zencore/memoryview.h>
#include <zencore/string.h>
#include <zencore/testing.h>
@@ -86,23 +86,24 @@ ValidateCbFieldType(MemoryView& View, CbValidateMode Mode, CbValidateError& Erro
static uint64_t
ValidateCbUInt(MemoryView& View, CbValidateMode Mode, CbValidateError& Error)
{
- if (View.GetSize() > 0 && View.GetSize() >= MeasureVarUInt(View.GetData()))
+ size_t ViewSize = View.GetSize();
+ if (ViewSize > 0)
{
- uint32_t ValueByteCount;
- const uint64_t Value = ReadVarUInt(View.GetData(), ValueByteCount);
- if (EnumHasAnyFlags(Mode, CbValidateMode::Format) && ValueByteCount > MeasureVarUInt(Value))
+ uint32_t ValueByteCount = MeasureVarUInt(View.GetData());
+ if (ViewSize >= ValueByteCount)
{
- AddError(Error, CbValidateError::InvalidInteger);
+ const uint64_t Value = ReadMeasuredVarUInt(View.GetData(), ValueByteCount);
+ if (EnumHasAnyFlags(Mode, CbValidateMode::Format) && ValueByteCount != MeasureVarUInt(Value))
+ {
+ AddError(Error, CbValidateError::InvalidInteger);
+ }
+ View += ValueByteCount;
+ return Value;
}
- View += ValueByteCount;
- return Value;
- }
- else
- {
- AddError(Error, CbValidateError::OutOfBounds);
- View.Reset();
- return 0;
}
+ AddError(Error, CbValidateError::OutOfBounds);
+ View.Reset();
+ return 0;
}
/**
@@ -134,6 +135,37 @@ ValidateCbFloat64(MemoryView& View, CbValidateMode Mode, CbValidateError& Error)
}
/**
+ * Validate and read a fixed-size value from the view.
+ *
+ * Modifies the view to start at the end of the value, and adds error flags if applicable.
+ */
+static MemoryView
+ValidateCbFixedValue(MemoryView& View, CbValidateMode Mode, CbValidateError& Error, uint64_t Size)
+{
+ ZEN_UNUSED(Mode);
+
+ const MemoryView Value = View.Left(Size);
+ View += Size;
+ if (Value.GetSize() < Size)
+ {
+ AddError(Error, CbValidateError::OutOfBounds);
+ }
+ return Value;
+};
+
+/**
+ * Validate and read a value from the view where the view begins with the value size.
+ *
+ * Modifies the view to start at the end of the value, and adds error flags if applicable.
+ */
+static MemoryView
+ValidateCbDynamicValue(MemoryView& View, CbValidateMode Mode, CbValidateError& Error)
+{
+ const uint64_t ValueSize = ValidateCbUInt(View, Mode, Error);
+ return ValidateCbFixedValue(View, Mode, Error, ValueSize);
+}
+
+/**
* Validate and read a string from the view.
*
* Modifies the view to start at the end of the string, and adds error flags if applicable.
@@ -377,8 +409,20 @@ ValidateCbField(MemoryView& View, CbValidateMode Mode, CbValidateError& Error, c
ValidateFixedPayload(12);
break;
case CbFieldType::CustomById:
+ {
+ MemoryView Value = ValidateCbDynamicValue(View, Mode, Error);
+ ValidateCbUInt(Value, Mode, Error);
+ }
+ break;
case CbFieldType::CustomByName:
- ZEN_NOT_IMPLEMENTED(); // TODO: FIX!
+ {
+ MemoryView Value = ValidateCbDynamicValue(View, Mode, Error);
+ const std::string_view TypeName = ValidateCbString(Value, Mode, Error);
+ if (TypeName.empty() && !EnumHasAnyFlags(Error, CbValidateError::OutOfBounds))
+ {
+ AddError(Error, CbValidateError::InvalidType);
+ }
+ }
break;
}
@@ -544,10 +588,17 @@ ValidateCompactBinary(MemoryView View, CbValidateMode Mode, CbFieldType Type)
CbValidateError Error = CbValidateError::None;
if (EnumHasAnyFlags(Mode, CbValidateMode::All))
{
- ValidateCbField(View, Mode, Error, Type);
- if (!View.IsEmpty() && EnumHasAnyFlags(Mode, CbValidateMode::Padding))
+ if (View.IsEmpty())
{
- AddError(Error, CbValidateError::Padding);
+ AddError(Error, CbValidateError::OutOfBounds);
+ }
+ else
+ {
+ ValidateCbField(View, Mode, Error, Type);
+ if (!View.IsEmpty() && EnumHasAnyFlags(Mode, CbValidateMode::Padding))
+ {
+ AddError(Error, CbValidateError::Padding);
+ }
}
}
return Error;
@@ -654,10 +705,11 @@ ToString(const CbValidateError Error)
ExtendableStringBuilder<128> Out;
- auto AppendFlag = [&, IsFirst = false](std::string_view FlagString) {
+ auto AppendFlag = [&, IsFirst = true](std::string_view FlagString) mutable {
if (!IsFirst)
Out.Append('|');
Out.Append(FlagString);
+ IsFirst = false;
};
#define _ENUM_CASE(V) \
@@ -686,7 +738,11 @@ ToString(const CbValidateError Error)
#undef _ENUM_CASE
- return "Error";
+ if (Out.Size() == 0)
+ {
+ return "Error";
+ }
+ return Out.ToString();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////