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

Allow decoding of extension objects for legacy devices which do not set the length #2869

Open
wants to merge 1 commit into
base: develop/main374
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 37 additions & 33 deletions Stack/Opc.Ua.Core/Types/Encoders/BinaryDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ public Int32Collection ReadInt32Array(string fieldName)

for (int ii = 0; ii < length; ii++)
{
values.Add(ReadInt32(null));
values.Add(SafeReadInt32());
}

return values;
Expand Down Expand Up @@ -945,7 +945,7 @@ public Int64Collection ReadInt64Array(string fieldName)

for (int ii = 0; ii < length; ii++)
{
values.Add(ReadInt64(null));
values.Add(SafeReadInt64());
}

return values;
Expand All @@ -967,7 +967,7 @@ public UInt64Collection ReadUInt64Array(string fieldName)

for (int ii = 0; ii < length; ii++)
{
values.Add(ReadUInt64(null));
values.Add(SafeReadUInt64());
}

return values;
Expand All @@ -989,7 +989,7 @@ public FloatCollection ReadFloatArray(string fieldName)

for (int ii = 0; ii < length; ii++)
{
values.Add(ReadFloat(null));
values.Add(SafeReadFloat());
}

return values;
Expand All @@ -1011,7 +1011,7 @@ public DoubleCollection ReadDoubleArray(string fieldName)

for (int ii = 0; ii < length; ii++)
{
values.Add(ReadDouble(null));
values.Add(SafeReadDouble());
}

return values;
Expand Down Expand Up @@ -1547,22 +1547,22 @@ private DiagnosticInfo ReadDiagnosticInfo(string fieldName, int depth)
// read the fields of the diagnostic info structure.
if ((encodingByte & (byte)DiagnosticInfoEncodingBits.SymbolicId) != 0)
{
value.SymbolicId = ReadInt32(null);
value.SymbolicId = SafeReadInt32();
}

if ((encodingByte & (byte)DiagnosticInfoEncodingBits.NamespaceUri) != 0)
{
value.NamespaceUri = ReadInt32(null);
value.NamespaceUri = SafeReadInt32();
}

if ((encodingByte & (byte)DiagnosticInfoEncodingBits.Locale) != 0)
{
value.Locale = ReadInt32(null);
value.Locale = SafeReadInt32();
}

if ((encodingByte & (byte)DiagnosticInfoEncodingBits.LocalizedText) != 0)
{
value.LocalizedText = ReadInt32(null);
value.LocalizedText = SafeReadInt32();
}

if ((encodingByte & (byte)DiagnosticInfoEncodingBits.AdditionalInfo) != 0)
Expand Down Expand Up @@ -1617,7 +1617,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadBoolean(null);
values[ii] = SafeReadBoolean();
}

array = values;
Expand Down Expand Up @@ -1656,7 +1656,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadInt16(null);
values[ii] = SafeReadInt16();
}

array = values;
Expand All @@ -1669,7 +1669,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadUInt16(null);
values[ii] = SafeReadUInt16();
}

array = values;
Expand All @@ -1683,7 +1683,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadInt32(null);
values[ii] = SafeReadInt32();
}
array = values;
break;
Expand All @@ -1708,7 +1708,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadInt64(null);
values[ii] = SafeReadInt64();
}

array = values;
Expand All @@ -1721,7 +1721,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadUInt64(null);
values[ii] = SafeReadUInt64();
}

array = values;
Expand All @@ -1734,7 +1734,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadFloat(null);
values[ii] = SafeReadFloat();
}

array = values;
Expand All @@ -1747,7 +1747,7 @@ private Array ReadArrayElements(int length, BuiltInType builtInType)

for (int ii = 0; ii < values.Length; ii++)
{
values[ii] = ReadDouble(null);
values[ii] = SafeReadDouble();
}

array = values;
Expand Down Expand Up @@ -2096,15 +2096,16 @@ private ExtensionObject ReadExtensionObject()
return extension;
}

// get the length.
int length = ReadInt32(null);
// Get the length.
// Allow a length of -1 to support legacy devices that don't fill the length correctly
int length = SafeReadInt32();

// save the current position.
int start = Position;

// create instance of type.
IEncodeable encodeable = null;
if (systemType != null && length >= 0)
if (systemType != null && length >= -1)
{
encodeable = Activator.CreateInstance(systemType) as IEncodeable;

Expand Down Expand Up @@ -2132,7 +2133,7 @@ private ExtensionObject ReadExtensionObject()

// verify the decoder did not exceed the length of the encodeable object
int used = Position - start;
if (length != used)
if (length >= 0 && length != used)
{
errorMessage = "Length mismatch";
exception = null;
Expand Down Expand Up @@ -2211,11 +2212,14 @@ private ExtensionObject ReadExtensionObject()
}

// any unread data indicates a decoding error.
long unused = length - (Position - start);
if (unused > 0)
if (length >= 0)
{
throw ServiceResultException.Create(StatusCodes.BadDecodingError,
"Cannot skip {0} bytes of unknown extension object body with type '{1}'.", unused, extension.TypeId);
long unused = length - (Position - start);
if (unused > 0)
{
throw ServiceResultException.Create(StatusCodes.BadDecodingError,
"Cannot skip {0} bytes of unknown extension object body with type '{1}'.", unused, extension.TypeId);
}
}

if (encodeable != null)
Expand Down Expand Up @@ -2307,7 +2311,7 @@ private Variant ReadVariantValue(string fieldName)

case BuiltInType.Boolean:
{
value.Set(ReadBoolean(null));
value.Set(SafeReadBoolean());
break;
}

Expand All @@ -2325,20 +2329,20 @@ private Variant ReadVariantValue(string fieldName)

case BuiltInType.Int16:
{
value.Set(ReadInt16(null));
value.Set(SafeReadInt16());
break;
}

case BuiltInType.UInt16:
{
value.Set(ReadUInt16(null));
value.Set(SafeReadUInt16());
break;
}

case BuiltInType.Int32:
case BuiltInType.Enumeration:
{
value.Set(ReadInt32(null));
value.Set(SafeReadInt32());
break;
}

Expand All @@ -2350,25 +2354,25 @@ private Variant ReadVariantValue(string fieldName)

case BuiltInType.Int64:
{
value.Set(ReadInt64(null));
value.Set(SafeReadInt64());
break;
}

case BuiltInType.UInt64:
{
value.Set(ReadUInt64(null));
value.Set(SafeReadUInt64());
break;
}

case BuiltInType.Float:
{
value.Set(ReadFloat(null));
value.Set(SafeReadFloat());
break;
}

case BuiltInType.Double:
{
value.Set(ReadDouble(null));
value.Set(SafeReadDouble());
break;
}

Expand Down
Loading