Skip to content

Commit 7dad2f3

Browse files
authored
Prevent concurrent use of YAML serializer / deserializer (#1544)
YamlDotNet ISerializer and IDeserializer are not thread-safe
1 parent d523291 commit 7dad2f3

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

src/KubernetesClient/KubernetesYaml.cs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ namespace k8s
1212
/// </summary>
1313
public static class KubernetesYaml
1414
{
15+
private static readonly object DeserializerLockObject = new object();
16+
private static readonly object SerializerLockObject = new object();
17+
1518
private static DeserializerBuilder CommonDeserializerBuilder =>
1619
new DeserializerBuilder()
1720
.WithNamingConvention(CamelCaseNamingConvention.Instance)
@@ -156,8 +159,11 @@ public static List<object> LoadAllFromString(string content, IDictionary<string,
156159
parser.Consume<StreamStart>();
157160
while (parser.Accept<DocumentStart>(out _))
158161
{
159-
var dict = GetDeserializer(strict).Deserialize<Dictionary<object, object>>(parser);
160-
types.Add(mergedTypeMap[dict["apiVersion"] + "/" + dict["kind"]]);
162+
lock (DeserializerLockObject)
163+
{
164+
var dict = GetDeserializer(strict).Deserialize<Dictionary<object, object>>(parser);
165+
types.Add(mergedTypeMap[dict["apiVersion"] + "/" + dict["kind"]]);
166+
}
161167
}
162168

163169
parser = new MergingParser(new Parser(new StringReader(content)));
@@ -167,8 +173,11 @@ public static List<object> LoadAllFromString(string content, IDictionary<string,
167173
while (parser.Accept<DocumentStart>(out _))
168174
{
169175
var objType = types[ix++];
170-
var obj = GetDeserializer(strict).Deserialize(parser, objType);
171-
results.Add(obj);
176+
lock (DeserializerLockObject)
177+
{
178+
var obj = GetDeserializer(strict).Deserialize(parser, objType);
179+
results.Add(obj);
180+
}
172181
}
173182

174183
return results;
@@ -204,13 +213,19 @@ public static string SaveToString<T>(T value)
204213
public static TValue Deserialize<TValue>(string yaml, bool strict = false)
205214
{
206215
using var reader = new StringReader(yaml);
207-
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
216+
lock (DeserializerLockObject)
217+
{
218+
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
219+
}
208220
}
209221

210222
public static TValue Deserialize<TValue>(Stream yaml, bool strict = false)
211223
{
212224
using var reader = new StreamReader(yaml);
213-
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
225+
lock (DeserializerLockObject)
226+
{
227+
return GetDeserializer(strict).Deserialize<TValue>(new MergingParser(new Parser(reader)));
228+
}
214229
}
215230

216231
public static string SerializeAll(IEnumerable<object> values)
@@ -231,7 +246,11 @@ public static string SerializeAll(IEnumerable<object> values)
231246
if (value != null)
232247
{
233248
emitter.Emit(new DocumentStart());
234-
Serializer.SerializeValue(emitter, value, value.GetType());
249+
lock (SerializerLockObject)
250+
{
251+
Serializer.SerializeValue(emitter, value, value.GetType());
252+
}
253+
235254
emitter.Emit(new DocumentEnd(true));
236255
}
237256
}
@@ -252,7 +271,10 @@ public static string Serialize(object value)
252271

253272
emitter.Emit(new StreamStart());
254273
emitter.Emit(new DocumentStart());
255-
Serializer.SerializeValue(emitter, value, value.GetType());
274+
lock (SerializerLockObject)
275+
{
276+
Serializer.SerializeValue(emitter, value, value.GetType());
277+
}
256278

257279
return stringBuilder.ToString();
258280
}

0 commit comments

Comments
 (0)