Skip to content

Commit

Permalink
Maximum allowed nesting level for Encoding/Decoding set to 100.
Browse files Browse the repository at this point in the history
  • Loading branch information
Softing committed Feb 3, 2017
1 parent 418f3b3 commit 0ba43e8
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 31 deletions.
31 changes: 30 additions & 1 deletion Stack/Core/Types/Encoders/BinaryDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public BinaryDecoder(byte[] buffer, int start, int count, ServiceMessageContext
m_istrm = new MemoryStream(buffer, start, count, false);
m_reader = new BinaryReader(m_istrm);
m_context = context;
m_nestingLevel = 0;
}

/// <summary>
Expand All @@ -57,6 +58,7 @@ public BinaryDecoder(Stream stream, ServiceMessageContext context)
m_istrm = stream;
m_reader = new BinaryReader(m_istrm);
m_context = context;
m_nestingLevel = 0;
}
#endregion

Expand Down Expand Up @@ -543,11 +545,22 @@ public StatusCode ReadStatusCode(string fieldName)
/// </summary>
public DiagnosticInfo ReadDiagnosticInfo(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++;

// read the encoding byte.
byte encodingByte = m_reader.ReadByte();

DiagnosticInfo value = new DiagnosticInfo();

// read the fields of the diagnostic info structure.
if ((encodingByte & (byte)DiagnosticInfoEncodingBits.SymbolicId) != 0)
{
Expand Down Expand Up @@ -584,6 +597,8 @@ public DiagnosticInfo ReadDiagnosticInfo(string fieldName)
value.InnerDiagnosticInfo = ReadDiagnosticInfo(null);
}

m_nestingLevel--;

return value;
}

Expand Down Expand Up @@ -1269,8 +1284,21 @@ public IEncodeable ReadEncodeable(string fieldName, System.Type systemType)
Utils.Format("Cannot decode type '{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++;

encodeable.Decode(this);

m_nestingLevel--;

return encodeable;
}

Expand Down Expand Up @@ -2083,6 +2111,7 @@ private ExtensionObject ReadExtensionObject()
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
}
}
30 changes: 30 additions & 0 deletions Stack/Core/Types/Encoders/BinaryEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public BinaryEncoder(ServiceMessageContext context)
m_ostrm = new MemoryStream();
m_writer = new BinaryWriter(m_ostrm);
m_context = context;
m_nestingLevel = 0;
}

/// <summary>
Expand All @@ -49,6 +50,7 @@ public BinaryEncoder(byte[] buffer, int start, int count, ServiceMessageContext
m_ostrm = new MemoryStream(buffer, start, count);
m_writer = new BinaryWriter(m_ostrm);
m_context = context;
m_nestingLevel = 0;
}

/// <summary>
Expand All @@ -61,6 +63,7 @@ public BinaryEncoder(Stream stream, ServiceMessageContext context)
m_ostrm = stream;
m_writer = new BinaryWriter(m_ostrm);
m_context = context;
m_nestingLevel = 0;
}
#endregion

Expand Down Expand Up @@ -596,6 +599,17 @@ public void WriteStatusCode(string fieldName, StatusCode value)
/// </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++;

// check for null.
if (value == null)
{
Expand Down Expand Up @@ -679,6 +693,8 @@ public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
{
WriteDiagnosticInfo(null, value.InnerDiagnosticInfo);
}

m_nestingLevel--;
}

/// <summary>
Expand Down Expand Up @@ -1110,18 +1126,31 @@ public void WriteExtensionObject(string fieldName, ExtensionObject value)
/// </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)
{
if (systemType == null) throw new ArgumentNullException("systemType");
value = Activator.CreateInstance(systemType) as IEncodeable;
}

m_nestingLevel++;

// encode the object.
if (value != null)
{
value.Encode(this);
}

m_nestingLevel--;
}

/// <summary>
Expand Down Expand Up @@ -1826,6 +1855,7 @@ private void WriteNodeIdBody(byte encoding, object identifier, ushort namespaceI
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
}

Expand Down
40 changes: 35 additions & 5 deletions Stack/Core/Types/Encoders/XmlDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ public XmlDecoder(ServiceMessageContext context)
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>
Expand All @@ -48,6 +49,7 @@ public XmlDecoder(XmlElement element, ServiceMessageContext context)
Initialize();
m_reader = new XmlNodeReader(element);
m_context = context;
m_nestingLevel = 0;
#endif
}

Expand All @@ -60,6 +62,7 @@ public XmlDecoder(System.Type systemType, XmlReader reader, ServiceMessageContex

m_reader = reader;
m_context = context;
m_nestingLevel = 0;

string ns = null;
string name = null;
Expand Down Expand Up @@ -1207,6 +1210,17 @@ public DiagnosticInfo ReadDiagnosticInfo(string fieldName)
/// </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))
Expand Down Expand Up @@ -1242,6 +1256,8 @@ public DiagnosticInfo ReadDiagnosticInfo()
EndField("InnerDiagnosticInfo");
}

m_nestingLevel--;

return value;
}

Expand Down Expand Up @@ -1460,12 +1476,23 @@ public IEncodeable ReadEncodeable(
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);

PushNamespace(xmlName.Namespace);
value.Decode(this);
PushNamespace(xmlName.Namespace);
value.Decode(this);
PopNamespace();

// skip to end of encodeable object.
Expand All @@ -1486,7 +1513,9 @@ public IEncodeable ReadEncodeable(

EndField(fieldName);
}


m_nestingLevel--;

return value;
}

Expand Down Expand Up @@ -2763,6 +2792,7 @@ private bool MoveToElement(string elementName)
private ServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
#endregion
}
}
Loading

0 comments on commit 0ba43e8

Please sign in to comment.