Skip to content

Commit

Permalink
Prevent concurrent use of YAML serializer / deserializer
Browse files Browse the repository at this point in the history
YamlDotNet ISerializer and IDeserializer are not thread-safe
  • Loading branch information
alxmitch committed Apr 3, 2024
1 parent d523291 commit 09f8f20
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions src/KubernetesClient/KubernetesYaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace k8s
/// </summary>
public static class KubernetesYaml
{
private static readonly object DeserializerLockObject = new object();
private static readonly object SerializerLockObject = new object();

private static DeserializerBuilder CommonDeserializerBuilder =>
new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
Expand Down Expand Up @@ -156,8 +159,11 @@ public static List<object> LoadAllFromString(string content, IDictionary<string,
parser.Consume<StreamStart>();
while (parser.Accept<DocumentStart>(out _))
{
var dict = GetDeserializer(strict).Deserialize<Dictionary<object, object>>(parser);
types.Add(mergedTypeMap[dict["apiVersion"] + "/" + dict["kind"]]);
lock (DeserializerLockObject)
{
var dict = GetDeserializer(strict).Deserialize<Dictionary<object, object>>(parser);
types.Add(mergedTypeMap[dict["apiVersion"] + "/" + dict["kind"]]);
}
}

parser = new MergingParser(new Parser(new StringReader(content)));
Expand All @@ -167,8 +173,11 @@ public static List<object> LoadAllFromString(string content, IDictionary<string,
while (parser.Accept<DocumentStart>(out _))
{
var objType = types[ix++];
var obj = GetDeserializer(strict).Deserialize(parser, objType);
results.Add(obj);
lock (DeserializerLockObject)
{
var obj = GetDeserializer(strict).Deserialize(parser, objType);
results.Add(obj);
}
}

return results;
Expand Down Expand Up @@ -204,13 +213,19 @@ public static string SaveToString<T>(T value)
public static TValue Deserialize<TValue>(string yaml, bool strict = false)
{
using var reader = new StringReader(yaml);
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
lock (DeserializerLockObject)
{
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
}
}

public static TValue Deserialize<TValue>(Stream yaml, bool strict = false)
{
using var reader = new StreamReader(yaml);
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
lock (DeserializerLockObject)
{
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
}
}

public static string SerializeAll(IEnumerable<object> values)
Expand All @@ -231,7 +246,11 @@ public static string SerializeAll(IEnumerable<object> values)
if (value != null)
{
emitter.Emit(new DocumentStart());
Serializer.SerializeValue(emitter, value, value.GetType());
lock (SerializerLockObject)
{
Serializer.SerializeValue(emitter, value, value.GetType());
}

emitter.Emit(new DocumentEnd(true));
}
}
Expand All @@ -252,7 +271,10 @@ public static string Serialize(object value)

emitter.Emit(new StreamStart());
emitter.Emit(new DocumentStart());
Serializer.SerializeValue(emitter, value, value.GetType());
lock (SerializerLockObject)
{
Serializer.SerializeValue(emitter, value, value.GetType());
}

return stringBuilder.ToString();
}
Expand Down

0 comments on commit 09f8f20

Please sign in to comment.