diff --git a/src/Libraries/CoreNodes/Data.cs b/src/Libraries/CoreNodes/Data.cs
index 01639990cfc..88dc093528c 100644
--- a/src/Libraries/CoreNodes/Data.cs
+++ b/src/Libraries/CoreNodes/Data.cs
@@ -13,6 +13,8 @@
using Dynamo.Events;
using Dynamo.Logging;
using Dynamo.Session;
+using System.Globalization;
+using System.Text;
namespace DSCore
{
@@ -188,8 +190,9 @@ private static object DynamoJObjectToNative(JObject jObject)
/// A JSON string where primitive types (e.g. double, int, boolean), Lists, and Dictionary's will be turned into the associated JSON type.
public static string StringifyJSON([ArbitraryDimensionArrayImport] object values)
{
- return JsonConvert.SerializeObject(values,
- new JsonConverter[]
+ var settings = new JsonSerializerSettings()
+ {
+ Converters = new JsonConverter[]
{
new DictConverter(),
new DesignScriptGeometryConverter(),
@@ -198,9 +201,66 @@ public static string StringifyJSON([ArbitraryDimensionArrayImport] object values
#if _WINDOWS
new PNGImageConverter(),
#endif
- });
+ }
+ };
+
+ StringBuilder sb = new StringBuilder(256);
+ using (var writer = new StringWriter(sb, CultureInfo.InvariantCulture))
+ {
+ using (var jsonWriter = new MaxDepthJsonTextWriter(writer))
+ {
+ JsonSerializer.Create(settings).Serialize(jsonWriter, values);
+ }
+ return writer.ToString();
+ }
}
+ ///
+ /// Subclass of JsonTextWriter that limits a maximum supported object depth to prevent circular reference crashes when serializing arbitrary .NET objects types.
+ ///
+ private class MaxDepthJsonTextWriter : JsonTextWriter
+ {
+ private readonly int maxDepth = 15;
+ private int depth = 0;
+
+ public MaxDepthJsonTextWriter(TextWriter writer) : base(writer) { }
+
+ public override void WriteStartArray()
+ {
+ base.WriteStartArray();
+ depth++;
+ CheckDepth();
+ }
+
+ public override void WriteEndArray()
+ {
+ base.WriteEndArray();
+ depth--;
+ CheckDepth();
+ }
+
+ public override void WriteStartObject()
+ {
+ base.WriteStartObject();
+ depth++;
+ CheckDepth();
+ }
+
+ public override void WriteEndObject()
+ {
+ base.WriteEndObject();
+ depth--;
+ CheckDepth();
+ }
+
+ private void CheckDepth()
+ {
+ if (depth > maxDepth)
+ {
+ throw new JsonSerializationException(string.Format("Depth {0} Exceeds MaxDepth {1} at path \"{2}\"", depth, maxDepth, Path));
+ }
+ }
+ }
#region Converters
///