From 28fbe0e4244744eab0b46d6af3736c151d9258f6 Mon Sep 17 00:00:00 2001 From: Einar Omang Date: Tue, 3 Sep 2024 09:29:14 +0200 Subject: [PATCH] Fix race condition in #2536 This fixes a race condition in BsonMapper, caused by a fix to a different issue in #2493. It seems like the current approach of checking the dictionary twice is deliberate. That said, I don't believe reading from a dictionary that may be in the process of being updated is actually safe to begin with. --- LiteDB/Client/Mapper/BsonMapper.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/LiteDB/Client/Mapper/BsonMapper.cs b/LiteDB/Client/Mapper/BsonMapper.cs index c613e7bc3..c13e60327 100644 --- a/LiteDB/Client/Mapper/BsonMapper.cs +++ b/LiteDB/Client/Mapper/BsonMapper.cs @@ -235,16 +235,14 @@ internal EntityMapper GetEntityMapper(Type type) { //TODO: needs check if Type if BsonDocument? Returns empty EntityMapper? - if (!_entities.TryGetValue(type, out EntityMapper mapper)) + lock (_entities) { - lock (_entities) + if (!_entities.TryGetValue(type, out EntityMapper mapper)) { - if (!_entities.TryGetValue(type, out mapper)) - return this.BuildAddEntityMapper(type); + return this.BuildAddEntityMapper(type); } + return mapper; } - - return mapper; } /// @@ -396,7 +394,7 @@ protected virtual CreateObject GetTypeCtor(EntityMapper mapper) for (i = 0; i < pars.Length; i++) { ParameterInfo par = pars[i]; - MemberMapper mi = null; + MemberMapper mi = null; foreach (MemberMapper member in mapper.Members) { if (member.MemberName.ToLower() == par.Name.ToLower() && member.DataType == par.ParameterType) @@ -405,10 +403,10 @@ protected virtual CreateObject GetTypeCtor(EntityMapper mapper) break; } } - if (mi == null) {break;} + if (mi == null) { break; } paramMap[i] = new KeyValuePair(mi.FieldName, mi.DataType); } - if (i < pars.Length) { continue;} + if (i < pars.Length) { continue; } CreateObject toAdd = (BsonDocument value) => Activator.CreateInstance(type, paramMap.Select(x => this.Deserialize(x.Value, value[x.Key])).ToArray());