Merge pull request #197 from AlinMoldovean/master

Merged changes from UA-.NET
This commit is contained in:
Erich Barnstedt
2017-07-14 10:15:12 +02:00
committed by GitHub
10 changed files with 1045 additions and 738 deletions
@@ -642,6 +642,12 @@ namespace Opc.Ua.Client
// create a placeholder for the node if it does not already exist.
if (!m_nodes.Exists(reference.NodeId))
{
// transform absolute identifiers.
if (reference.NodeId != null && reference.NodeId.IsAbsolute)
{
reference.NodeId = ExpandedNodeId.ToNodeId(reference.NodeId, NamespaceUris);
}
Node target = new Node(reference);
m_nodes.Attach(target);
}
@@ -128,36 +128,36 @@ namespace Opc.Ua.Server
/// </summary>
/// <param name="session">The session to use.</param>
/// <returns>
/// A copy of the system context that references the new operation context.
/// A copy of the system context that references the new session.
/// </returns>
public ServerSystemContext Copy(Session session)
{
ServerSystemContext copy = (ServerSystemContext)MemberwiseClone();
OperationContext = null;
copy.OperationContext = null;
if (session != null)
{
SessionId = session.Id;
UserIdentity = session.Identity;
PreferredLocales = session.PreferredLocales;
copy.SessionId = session.Id;
copy.UserIdentity = session.Identity;
copy.PreferredLocales = session.PreferredLocales;
}
else
{
SessionId = null;
UserIdentity = null;
PreferredLocales = null;
copy.SessionId = null;
copy.UserIdentity = null;
copy.PreferredLocales = null;
}
return copy;
}
/// <summary>
/// Creates a copy of the context that can be used with the specified session.
/// Creates a copy of the context that can be used with the specified server context.
/// </summary>
/// <param name="context">The session to use.</param>
/// <param name="context">The server context to use.</param>
/// <returns>
/// A copy of the system context that references the new operation context.
/// A copy of the system context that references the new server context.
/// </returns>
public ServerSystemContext Copy(ServerSystemContext context)
{
@@ -165,14 +165,14 @@ namespace Opc.Ua.Server
if (context != null)
{
OperationContext = context.OperationContext;
SessionId = context.SessionId;
UserIdentity = context.UserIdentity;
PreferredLocales = context.PreferredLocales;
NamespaceUris = context.NamespaceUris;
ServerUris = context.ServerUris;
TypeTable = context.TypeTable;
EncodeableFactory = context.EncodeableFactory;
copy.OperationContext = context.OperationContext;
copy.SessionId = context.SessionId;
copy.UserIdentity = context.UserIdentity;
copy.PreferredLocales = context.PreferredLocales;
copy.NamespaceUris = context.NamespaceUris;
copy.ServerUris = context.ServerUris;
copy.TypeTable = context.TypeTable;
copy.EncodeableFactory = context.EncodeableFactory;
}
return copy;
@@ -335,8 +335,11 @@ namespace Opc.Ua.Server
public void Delete(OperationContext context)
{
// delete the diagnostics.
ServerSystemContext systemContext = m_server.DefaultSystemContext.Copy(m_session);
m_server.DiagnosticsNodeManager.DeleteSubscriptionDiagnostics(systemContext, m_diagnosticsId);
if (m_diagnosticsId != null && !m_diagnosticsId.IsNullNodeId)
{
ServerSystemContext systemContext = m_server.DefaultSystemContext.Copy(m_session);
m_server.DiagnosticsNodeManager.DeleteSubscriptionDiagnostics(systemContext, m_diagnosticsId);
}
lock (m_lock)
{
File diff suppressed because it is too large Load Diff
+196 -145
View File
@@ -33,6 +33,7 @@ namespace Opc.Ua
m_ostrm = new MemoryStream();
m_writer = new BinaryWriter(m_ostrm);
m_context = context;
m_nestingLevel = 0;
}
/// <summary>
@@ -45,6 +46,7 @@ namespace Opc.Ua
m_ostrm = new MemoryStream(buffer, start, count);
m_writer = new BinaryWriter(m_ostrm);
m_context = context;
m_nestingLevel = 0;
}
/// <summary>
@@ -57,6 +59,7 @@ namespace Opc.Ua
m_ostrm = stream;
m_writer = new BinaryWriter(m_ostrm);
m_context = context;
m_nestingLevel = 0;
}
#endregion
@@ -644,6 +647,15 @@ namespace Opc.Ua
/// </summary>
public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
// check for null.
if (value == null)
{
@@ -651,6 +663,8 @@ namespace Opc.Ua
return;
}
m_nestingLevel++;
// calculate the encoding.
byte encoding = 0;
@@ -727,6 +741,8 @@ namespace Opc.Ua
{
WriteDiagnosticInfo(null, value.InnerDiagnosticInfo);
}
m_nestingLevel--;
}
/// <summary>
@@ -792,160 +808,24 @@ namespace Opc.Ua
}
/// <summary>
/// Writes an Variant array to the stream.
/// Writes an Variant to the stream.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
public void WriteVariant(string fieldName, Variant value)
{
// check for null.
if (value.Value == null || value.TypeInfo == null || value.TypeInfo.BuiltInType == BuiltInType.Null)
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
WriteByte(null, 0);
return;
}
// encode enums as int32.
byte encodingByte = (byte)value.TypeInfo.BuiltInType;
if (value.TypeInfo.BuiltInType == BuiltInType.Enumeration)
{
encodingByte = (byte)BuiltInType.Int32;
}
object valueToEncode = value.Value;
if (value.TypeInfo.ValueRank < 0)
{
WriteByte(null, encodingByte);
switch (value.TypeInfo.BuiltInType)
{
case BuiltInType.Boolean: { WriteBoolean(null, (bool)valueToEncode); return; }
case BuiltInType.SByte: { WriteSByte(null, (sbyte)valueToEncode); return; }
case BuiltInType.Byte: { WriteByte(null, (byte)valueToEncode); return; }
case BuiltInType.Int16: { WriteInt16(null, (short)valueToEncode); return; }
case BuiltInType.UInt16: { WriteUInt16(null, (ushort)valueToEncode); return; }
case BuiltInType.Int32: { WriteInt32(null, (int)valueToEncode); return; }
case BuiltInType.UInt32: { WriteUInt32(null, (uint)valueToEncode); return; }
case BuiltInType.Int64: { WriteInt64(null, (long)valueToEncode); return; }
case BuiltInType.UInt64: { WriteUInt64(null, (ulong)valueToEncode); return; }
case BuiltInType.Float: { WriteFloat(null, (float)valueToEncode); return; }
case BuiltInType.Double: { WriteDouble(null, (double)valueToEncode); return; }
case BuiltInType.String: { WriteString(null, (string)valueToEncode); return; }
case BuiltInType.DateTime: { WriteDateTime(null, (DateTime)valueToEncode); return; }
case BuiltInType.Guid: { WriteGuid(null, (Uuid)valueToEncode); return; }
case BuiltInType.ByteString: { WriteByteString(null, (byte[])valueToEncode); return; }
case BuiltInType.XmlElement: { WriteXmlElement(null, (XmlElement)valueToEncode); return; }
case BuiltInType.NodeId: { WriteNodeId(null, (NodeId)valueToEncode); return; }
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeId(null, (ExpandedNodeId)valueToEncode); return; }
case BuiltInType.StatusCode: { WriteStatusCode(null, (StatusCode)valueToEncode); return; }
case BuiltInType.QualifiedName: { WriteQualifiedName(null, (QualifiedName)valueToEncode); return; }
case BuiltInType.LocalizedText: { WriteLocalizedText(null, (LocalizedText)valueToEncode); return; }
case BuiltInType.ExtensionObject: { WriteExtensionObject(null, (ExtensionObject)valueToEncode); return; }
case BuiltInType.DataValue: { WriteDataValue(null, (DataValue)valueToEncode); return; }
case BuiltInType.Enumeration: { WriteInt32(null, (int)valueToEncode); return; }
}
throw ServiceResultException.Create(
StatusCodes.BadEncodingError,
"Unexpected type encountered while encoding a Variant: {0}",
value.TypeInfo.BuiltInType);
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
if (value.TypeInfo.ValueRank >= 0)
{
Matrix matrix = null;
m_nestingLevel++;
encodingByte |= (byte)VariantArrayEncodingBits.Array;
WriteVariantValue(fieldName, value);
if (value.TypeInfo.ValueRank > 1)
{
encodingByte |= (byte)VariantArrayEncodingBits.ArrayDimensions;
matrix = (Matrix)valueToEncode;
valueToEncode = matrix.Elements;
}
WriteByte(null, encodingByte);
switch (value.TypeInfo.BuiltInType)
{
case BuiltInType.Boolean: { WriteBooleanArray(null, (bool[])valueToEncode); break; }
case BuiltInType.SByte: { WriteSByteArray(null, (sbyte[])valueToEncode); break; }
case BuiltInType.Byte: { WriteByteArray(null, (byte[])valueToEncode); break; }
case BuiltInType.Int16: { WriteInt16Array(null, (short[])valueToEncode); break; }
case BuiltInType.UInt16: { WriteUInt16Array(null, (ushort[])valueToEncode); break; }
case BuiltInType.Int32: { WriteInt32Array(null, (int[])valueToEncode); break; }
case BuiltInType.UInt32: { WriteUInt32Array(null, (uint[])valueToEncode); break; }
case BuiltInType.Int64: { WriteInt64Array(null, (long[])valueToEncode); break; }
case BuiltInType.UInt64: { WriteUInt64Array(null, (ulong[])valueToEncode); break; }
case BuiltInType.Float: { WriteFloatArray(null, (float[])valueToEncode); break; }
case BuiltInType.Double: { WriteDoubleArray(null, (double[])valueToEncode); break; }
case BuiltInType.String: { WriteStringArray(null, (string[])valueToEncode); break; }
case BuiltInType.DateTime: { WriteDateTimeArray(null, (DateTime[])valueToEncode); break; }
case BuiltInType.Guid: { WriteGuidArray(null, (Uuid[])valueToEncode); break; }
case BuiltInType.ByteString: { WriteByteStringArray(null, (byte[][])valueToEncode); break; }
case BuiltInType.XmlElement: { WriteXmlElementArray(null, (XmlElement[])valueToEncode); break; }
case BuiltInType.NodeId: { WriteNodeIdArray(null, (NodeId[])valueToEncode); break; }
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeIdArray(null, (ExpandedNodeId[])valueToEncode); break; }
case BuiltInType.StatusCode: { WriteStatusCodeArray(null, (StatusCode[])valueToEncode); break; }
case BuiltInType.QualifiedName: { WriteQualifiedNameArray(null, (QualifiedName[])valueToEncode); break; }
case BuiltInType.LocalizedText: { WriteLocalizedTextArray(null, (LocalizedText[])valueToEncode); break; }
case BuiltInType.ExtensionObject: { WriteExtensionObjectArray(null, (ExtensionObject[])valueToEncode); break; }
case BuiltInType.DataValue: { WriteDataValueArray(null, (DataValue[])valueToEncode); break; }
case BuiltInType.Enumeration:
{
Enum[] enums = valueToEncode as Enum[];
int[] ints = new int[enums.Length];
for (int ii = 0; ii < enums.Length; ii++)
{
ints[ii] = (int)(object)enums[ii];
}
WriteInt32Array(null, ints);
return;
}
case BuiltInType.Variant:
{
Variant[] variants = valueToEncode as Variant[];
if (variants != null)
{
WriteVariantArray(null, variants);
break;
}
object[] objects = valueToEncode as object[];
if (objects != null)
{
WriteObjectArray(null, objects);
break;
}
throw ServiceResultException.Create(
StatusCodes.BadEncodingError,
"Unexpected type encountered while encoding a Matrix: {0}",
valueToEncode.GetType());
}
default:
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingError,
"Unexpected type encountered while encoding a Variant: {0}",
value.TypeInfo.BuiltInType);
}
}
// write the dimensions.
if (value.TypeInfo.ValueRank > 1)
{
WriteInt32Array(null, (int[])matrix.Dimensions);
}
}
m_nestingLevel--;
}
/// <summary>
@@ -1158,6 +1038,15 @@ namespace Opc.Ua
/// </summary>
public void WriteEncodeable(string fieldName, IEncodeable value, System.Type systemType)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
// create a default object if a null object specified.
if (value == null)
{
@@ -1165,11 +1054,15 @@ namespace Opc.Ua
value = Activator.CreateInstance(systemType) as IEncodeable;
}
m_nestingLevel++;
// encode the object.
if (value != null)
{
value.Encode(this);
}
m_nestingLevel--;
}
/// <summary>
@@ -1866,6 +1759,163 @@ namespace Opc.Ua
}
}
}
/// <summary>
/// Writes an Variant to the stream.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
private void WriteVariantValue(string fieldName, Variant value)
{
// check for null.
if (value.Value == null || value.TypeInfo == null || value.TypeInfo.BuiltInType == BuiltInType.Null)
{
WriteByte(null, 0);
return;
}
// encode enums as int32.
byte encodingByte = (byte)value.TypeInfo.BuiltInType;
if (value.TypeInfo.BuiltInType == BuiltInType.Enumeration)
{
encodingByte = (byte)BuiltInType.Int32;
}
object valueToEncode = value.Value;
if (value.TypeInfo.ValueRank < 0)
{
WriteByte(null, encodingByte);
switch (value.TypeInfo.BuiltInType)
{
case BuiltInType.Boolean: { WriteBoolean(null, (bool)valueToEncode); return; }
case BuiltInType.SByte: { WriteSByte(null, (sbyte)valueToEncode); return; }
case BuiltInType.Byte: { WriteByte(null, (byte)valueToEncode); return; }
case BuiltInType.Int16: { WriteInt16(null, (short)valueToEncode); return; }
case BuiltInType.UInt16: { WriteUInt16(null, (ushort)valueToEncode); return; }
case BuiltInType.Int32: { WriteInt32(null, (int)valueToEncode); return; }
case BuiltInType.UInt32: { WriteUInt32(null, (uint)valueToEncode); return; }
case BuiltInType.Int64: { WriteInt64(null, (long)valueToEncode); return; }
case BuiltInType.UInt64: { WriteUInt64(null, (ulong)valueToEncode); return; }
case BuiltInType.Float: { WriteFloat(null, (float)valueToEncode); return; }
case BuiltInType.Double: { WriteDouble(null, (double)valueToEncode); return; }
case BuiltInType.String: { WriteString(null, (string)valueToEncode); return; }
case BuiltInType.DateTime: { WriteDateTime(null, (DateTime)valueToEncode); return; }
case BuiltInType.Guid: { WriteGuid(null, (Uuid)valueToEncode); return; }
case BuiltInType.ByteString: { WriteByteString(null, (byte[])valueToEncode); return; }
case BuiltInType.XmlElement: { WriteXmlElement(null, (XmlElement)valueToEncode); return; }
case BuiltInType.NodeId: { WriteNodeId(null, (NodeId)valueToEncode); return; }
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeId(null, (ExpandedNodeId)valueToEncode); return; }
case BuiltInType.StatusCode: { WriteStatusCode(null, (StatusCode)valueToEncode); return; }
case BuiltInType.QualifiedName: { WriteQualifiedName(null, (QualifiedName)valueToEncode); return; }
case BuiltInType.LocalizedText: { WriteLocalizedText(null, (LocalizedText)valueToEncode); return; }
case BuiltInType.ExtensionObject: { WriteExtensionObject(null, (ExtensionObject)valueToEncode); return; }
case BuiltInType.DataValue: { WriteDataValue(null, (DataValue)valueToEncode); return; }
case BuiltInType.Enumeration: { WriteInt32(null, (int)valueToEncode); return; }
}
throw ServiceResultException.Create(
StatusCodes.BadEncodingError,
"Unexpected type encountered while encoding a Variant: {0}",
value.TypeInfo.BuiltInType);
}
if (value.TypeInfo.ValueRank >= 0)
{
Matrix matrix = null;
encodingByte |= (byte)VariantArrayEncodingBits.Array;
if (value.TypeInfo.ValueRank > 1)
{
encodingByte |= (byte)VariantArrayEncodingBits.ArrayDimensions;
matrix = (Matrix)valueToEncode;
valueToEncode = matrix.Elements;
}
WriteByte(null, encodingByte);
switch (value.TypeInfo.BuiltInType)
{
case BuiltInType.Boolean: { WriteBooleanArray(null, (bool[])valueToEncode); break; }
case BuiltInType.SByte: { WriteSByteArray(null, (sbyte[])valueToEncode); break; }
case BuiltInType.Byte: { WriteByteArray(null, (byte[])valueToEncode); break; }
case BuiltInType.Int16: { WriteInt16Array(null, (short[])valueToEncode); break; }
case BuiltInType.UInt16: { WriteUInt16Array(null, (ushort[])valueToEncode); break; }
case BuiltInType.Int32: { WriteInt32Array(null, (int[])valueToEncode); break; }
case BuiltInType.UInt32: { WriteUInt32Array(null, (uint[])valueToEncode); break; }
case BuiltInType.Int64: { WriteInt64Array(null, (long[])valueToEncode); break; }
case BuiltInType.UInt64: { WriteUInt64Array(null, (ulong[])valueToEncode); break; }
case BuiltInType.Float: { WriteFloatArray(null, (float[])valueToEncode); break; }
case BuiltInType.Double: { WriteDoubleArray(null, (double[])valueToEncode); break; }
case BuiltInType.String: { WriteStringArray(null, (string[])valueToEncode); break; }
case BuiltInType.DateTime: { WriteDateTimeArray(null, (DateTime[])valueToEncode); break; }
case BuiltInType.Guid: { WriteGuidArray(null, (Uuid[])valueToEncode); break; }
case BuiltInType.ByteString: { WriteByteStringArray(null, (byte[][])valueToEncode); break; }
case BuiltInType.XmlElement: { WriteXmlElementArray(null, (XmlElement[])valueToEncode); break; }
case BuiltInType.NodeId: { WriteNodeIdArray(null, (NodeId[])valueToEncode); break; }
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeIdArray(null, (ExpandedNodeId[])valueToEncode); break; }
case BuiltInType.StatusCode: { WriteStatusCodeArray(null, (StatusCode[])valueToEncode); break; }
case BuiltInType.QualifiedName: { WriteQualifiedNameArray(null, (QualifiedName[])valueToEncode); break; }
case BuiltInType.LocalizedText: { WriteLocalizedTextArray(null, (LocalizedText[])valueToEncode); break; }
case BuiltInType.ExtensionObject: { WriteExtensionObjectArray(null, (ExtensionObject[])valueToEncode); break; }
case BuiltInType.DataValue: { WriteDataValueArray(null, (DataValue[])valueToEncode); break; }
case BuiltInType.Enumeration:
{
Enum[] enums = valueToEncode as Enum[];
int[] ints = new int[enums.Length];
for (int ii = 0; ii < enums.Length; ii++)
{
ints[ii] = (int)(object)enums[ii];
}
WriteInt32Array(null, ints);
return;
}
case BuiltInType.Variant:
{
Variant[] variants = valueToEncode as Variant[];
if (variants != null)
{
WriteVariantArray(null, variants);
break;
}
object[] objects = valueToEncode as object[];
if (objects != null)
{
WriteObjectArray(null, objects);
break;
}
throw ServiceResultException.Create(
StatusCodes.BadEncodingError,
"Unexpected type encountered while encoding a Matrix: {0}",
valueToEncode.GetType());
}
default:
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingError,
"Unexpected type encountered while encoding a Variant: {0}",
value.TypeInfo.BuiltInType);
}
}
// write the dimensions.
if (value.TypeInfo.ValueRank > 1)
{
WriteInt32Array(null, (int[])matrix.Dimensions);
}
}
}
#endregion
#region Private Fields
@@ -1874,6 +1924,7 @@ namespace Opc.Ua
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
}
@@ -32,6 +32,7 @@ namespace Opc.Ua
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
#region Constructors
@@ -40,8 +41,8 @@ namespace Opc.Ua
if (context == null) throw new ArgumentNullException("context");
Initialize();
m_context = context;
m_nestingLevel = 0;
m_reader = new JsonTextReader(new StringReader(json));
m_root = ReadObject();
m_stack = new Stack<object>();
@@ -53,6 +54,7 @@ namespace Opc.Ua
Initialize();
m_context = context;
m_nestingLevel = 0;
m_reader = reader;
m_root = ReadObject();
m_stack = new Stack<object>();
@@ -942,6 +944,16 @@ namespace Opc.Ua
try
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
m_stack.Push(value);
DiagnosticInfo di = new DiagnosticInfo();
@@ -985,6 +997,7 @@ namespace Opc.Ua
}
finally
{
m_nestingLevel--;
m_stack.Pop();
}
}
@@ -1150,6 +1163,16 @@ namespace Opc.Ua
try
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
m_stack.Push(value);
BuiltInType type = (BuiltInType)ReadByte("Type");
@@ -1180,6 +1203,7 @@ namespace Opc.Ua
}
finally
{
m_nestingLevel--;
m_stack.Pop();
}
}
@@ -1357,6 +1381,17 @@ namespace Opc.Ua
throw new ServiceResultException(StatusCodes.BadDecodingError, Utils.Format("Type does not support IEncodeable interface: '{0}'", systemType.FullName));
}
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
try
{
m_stack.Push(token);
@@ -1368,6 +1403,8 @@ namespace Opc.Ua
m_stack.Pop();
}
m_nestingLevel--;
return value;
}
@@ -32,6 +32,7 @@ namespace Opc.Ua
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
public bool UseReversibleEncoding { get; private set; }
@@ -45,6 +46,7 @@ namespace Opc.Ua
Initialize();
m_context = context;
m_nestingLevel = 0;
m_writer = writer;
UseReversibleEncoding = useReversibleEncoding;
@@ -729,6 +731,17 @@ namespace Opc.Ua
/// </summary>
public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
if (value == null)
{
WriteSimpleField(fieldName, null, false);
@@ -773,6 +786,8 @@ namespace Opc.Ua
}
PopStructure();
m_nestingLevel--;
}
/// <summary>
@@ -837,10 +852,21 @@ namespace Opc.Ua
}
/// <summary>
/// Writes an Variant array to the stream.
/// Writes an Variant to the stream.
/// </summary>
public void WriteVariant(string fieldName, Variant value)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
if (Variant.Null == value)
{
WriteSimpleField(fieldName, null, false);
@@ -881,6 +907,8 @@ namespace Opc.Ua
PopStructure();
}
m_nestingLevel--;
}
/// <summary>
@@ -987,6 +1015,17 @@ namespace Opc.Ua
/// </summary>
public void WriteEncodeable(string fieldName, IEncodeable value, System.Type systemType)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
if (value == null)
{
WriteSimpleField(fieldName, null, false);
@@ -1001,6 +1040,8 @@ namespace Opc.Ua
}
PopStructure();
m_nestingLevel--;
}
/// <summary>
+52 -9
View File
@@ -33,8 +33,9 @@ namespace Opc.Ua
if (context == null) throw new ArgumentNullException("context");
Initialize();
m_context = context;
}
m_nestingLevel = 0;
}
/// <summary>
/// Initializes the object with an XML element to parse.
/// </summary>
@@ -44,6 +45,7 @@ namespace Opc.Ua
Initialize();
m_reader = XmlReader.Create(new StringReader(element.OuterXml));
m_context = context;
m_nestingLevel = 0;
}
/// <summary>
@@ -55,6 +57,7 @@ namespace Opc.Ua
m_reader = reader;
m_context = context;
m_nestingLevel = 0;
string ns = null;
string name = null;
@@ -82,11 +85,11 @@ namespace Opc.Ua
PushNamespace(ns);
BeginField(name, false);
}
/// <summary>
/// Sets private members to default values.
/// </summary>
}
/// <summary>
/// Sets private members to default values.
/// </summary>
private void Initialize()
{
m_reader = null;
@@ -1190,6 +1193,17 @@ namespace Opc.Ua
/// </summary>
public DiagnosticInfo ReadDiagnosticInfo()
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
DiagnosticInfo value = new DiagnosticInfo();
if (BeginField("SymbolicId", true))
@@ -1225,6 +1239,8 @@ namespace Opc.Ua
EndField("InnerDiagnosticInfo");
}
m_nestingLevel--;
return value;
}
@@ -1321,6 +1337,17 @@ namespace Opc.Ua
/// </summary>
public Variant ReadVariant(string fieldName)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
Variant value = new Variant();
if (BeginField(fieldName, true))
@@ -1348,6 +1375,8 @@ namespace Opc.Ua
EndField(fieldName);
}
m_nestingLevel--;
return value;
}
@@ -1443,6 +1472,17 @@ namespace Opc.Ua
Utils.Format("Type does not support IEncodeable interface: '{0}'", systemType.FullName));
}
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
if (BeginField(fieldName, true))
{
XmlQualifiedName xmlName = EncodeableFactory.GetXmlName(systemType);
@@ -1466,10 +1506,12 @@ namespace Opc.Ua
m_reader.Skip();
m_reader.MoveToContent();
}
EndField(fieldName);
}
m_nestingLevel--;
return value;
}
@@ -2742,6 +2784,7 @@ namespace Opc.Ua
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
}
}
+51 -9
View File
@@ -35,6 +35,7 @@ namespace Opc.Ua
m_destination = new StringBuilder();
m_context = context;
m_nestingLevel = 0;
XmlWriterSettings settings = new XmlWriterSettings();
settings.CheckCharacters = false;
@@ -72,6 +73,7 @@ namespace Opc.Ua
Initialize(root.Name, root.Namespace);
m_context = context;
m_nestingLevel = 0;
}
/// <summary>
@@ -612,10 +614,21 @@ namespace Opc.Ua
/// </summary>
public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
if (BeginField(fieldName, value == null, true))
{
PushNamespace(Namespaces.OpcUaXsd);
if (value != null)
{
WriteInt32("SymbolicId", value.SymbolicId);
@@ -628,9 +641,11 @@ namespace Opc.Ua
}
PopNamespace();
EndField(fieldName);
}
m_nestingLevel--;
}
/// <summary>
@@ -687,18 +702,31 @@ namespace Opc.Ua
/// </summary>
public void WriteVariant(string fieldName, Variant value)
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
if (BeginField(fieldName, false, false))
{
PushNamespace(Namespaces.OpcUaXsd);
m_writer.WriteStartElement("Value", Namespaces.OpcUaXsd);
WriteVariantContents(value.Value, value.TypeInfo);
m_writer.WriteStartElement("Value", Namespaces.OpcUaXsd);
WriteVariantContents(value.Value, value.TypeInfo);
m_writer.WriteEndElement();
PopNamespace();
EndField(fieldName);
}
m_nestingLevel--;
}
/// <summary>
@@ -804,7 +832,18 @@ namespace Opc.Ua
/// Writes an encodeable object to the stream.
/// </summary>
public void WriteEncodeable(string fieldName, IEncodeable value, System.Type systemType)
{
{
// check the nesting level for avoiding a stack overflow.
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(
StatusCodes.BadEncodingLimitsExceeded,
"Maximum nesting level of {0} was exceeded",
m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
if (BeginField(fieldName, value == null, true))
{
if (value != null)
@@ -814,7 +853,9 @@ namespace Opc.Ua
EndField(fieldName);
}
}
m_nestingLevel--;
}
/// <summary>
/// Writes an enumerated value array to the stream.
@@ -1959,6 +2000,7 @@ namespace Opc.Ua
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
}
}
@@ -31,24 +31,26 @@ namespace Opc.Ua
/// </summary>
public ServiceMessageContext()
{
m_maxStringLength = UInt16.MaxValue;
m_maxByteStringLength = UInt16.MaxValue*16;
m_maxArrayLength = UInt16.MaxValue;
m_maxMessageSize = UInt16.MaxValue*32;
m_namespaceUris = new NamespaceTable();
m_serverUris = new StringTable();
m_factory = EncodeableFactory.GlobalFactory;
m_maxStringLength = UInt16.MaxValue;
m_maxByteStringLength = UInt16.MaxValue*16;
m_maxArrayLength = UInt16.MaxValue;
m_maxMessageSize = UInt16.MaxValue*32;
m_namespaceUris = new NamespaceTable();
m_serverUris = new StringTable();
m_factory = EncodeableFactory.GlobalFactory;
m_maxEncodingNestingLevels = 200;
}
private ServiceMessageContext(bool shared) : this()
{
m_maxStringLength = UInt16.MaxValue;
m_maxByteStringLength = UInt16.MaxValue*16;
m_maxArrayLength = UInt16.MaxValue;
m_maxMessageSize = UInt16.MaxValue*32;
m_namespaceUris = new NamespaceTable(shared);
m_serverUris = new StringTable(shared);
m_factory = EncodeableFactory.GlobalFactory;
m_maxStringLength = UInt16.MaxValue;
m_maxByteStringLength = UInt16.MaxValue*16;
m_maxArrayLength = UInt16.MaxValue;
m_maxMessageSize = UInt16.MaxValue*32;
m_namespaceUris = new NamespaceTable(shared);
m_serverUris = new StringTable(shared);
m_factory = EncodeableFactory.GlobalFactory;
m_maxEncodingNestingLevels = 200;
}
#endregion
@@ -123,6 +125,14 @@ namespace Opc.Ua
set { lock (m_lock) { m_maxMessageSize = value; } }
}
/// <summary>
/// The maximum nesting level accepted while encoding or decoding objects.
/// </summary>
public uint MaxEncodingNestingLevels
{
get { lock (m_lock) { return m_maxEncodingNestingLevels; } }
}
/// <summary>
/// The table of namespaces used by the server.
/// </summary>
@@ -205,6 +215,7 @@ namespace Opc.Ua
private int m_maxByteStringLength;
private int m_maxArrayLength;
private int m_maxMessageSize;
private uint m_maxEncodingNestingLevels;
private NamespaceTable m_namespaceUris;
private StringTable m_serverUris;
private EncodeableFactory m_factory;