ServiceStack / Issues

Issue Tracker for the commercial versions of ServiceStack
11 stars 8 forks source link

Improper handling of RabbitMQ payloads using ReadOnlyMemory<T> #806

Closed andrevasj closed 2 months ago

andrevasj commented 2 months ago

Describe the issue

According to RabbitMQ documentation, payload must be deserialized before delivery handler method returns. https://www.rabbitmq.com/client-libraries/dotnet-api-guide#consuming-memory-safety

However RabbitMqBasicConsumer.HandleBasicDeliver places payload as part of the BasicGetResult to the SharedQueue. This payload later is accessed in RabbitMQWorker.StartSubscription method and randomly returns corrupted data from ReadonlyMemory, because memory is already deallocated.

Reproduction

  1. Publish some messages to the specific queue (since the memory deallocation is random, publish more than 1K messages to reproduce).
  2. Handle messages using ServiceStack handler mechanism.

Expected behavior

Random exception occurs during deserialization. ReadonlyMemory payload is already overwritten:

Received exception in Worker: mq:MessageXXX.inq
System.Runtime.Serialization.SerializationException: Type definitions should start with a '{', expecting serialized type 'WeeklyReportRecipientsBatch', got string starting with: ��y)�f�42�Vm3^v���?6��j��[�Z�Iޞ�0�AZg���{�v
   at ServiceStack.Text.Common.DeserializeTypeRefJson.StringToType(ReadOnlySpan`1 strType, TypeConfig typeConfig, EmptyCtorDelegate ctorFn, KeyValuePair`2[] typeAccessors) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs:line 28
   at ServiceStack.Text.Common.DeserializeType`1.StringToTypeContext.DeserializeJson(ReadOnlySpan`1 value) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.Text/src/ServiceStack.Text/Common/DeserializeType.cs:line 58
   at ServiceStack.Text.Json.JsonReader`1.Parse(ReadOnlySpan`1 value) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.Text/src/ServiceStack.Text/Json/JsonReader.Generic.cs:line 111
   at ServiceStack.Text.Json.JsonReader`1.Parse(String value) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.Text/src/ServiceStack.Text/Json/JsonReader.Generic.cs:line 84
   at ServiceStack.Text.JsonSerializer.DeserializeFromString[T](String value) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.Text/src/ServiceStack.Text/JsonSerializer.cs:line 46
   at ServiceStack.StringExtensions.FromJson[T](String json) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack.Text/src/ServiceStack.Text/StringExtensions.cs:line 570
   at ServiceStack.RabbitMq.RabbitMqExtensions.ToMessage[T](BasicGetResult msgResult) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.RabbitMq/RabbitMqExtensions.cs:line 223
   at ServiceStack.RabbitMq.RabbitMqQueueClient.CreateMessage[T](Object mqResponse) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.RabbitMq/RabbitMqQueueClient.cs:line 76
   at ServiceStack.Messaging.MessageHandler`1.ProcessMessage(IMessageQueueClient mqClient, Object mqResponse) in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack/Messaging/MessageHandler.cs:line 118
   at ServiceStack.RabbitMq.RabbitMqWorker.StartSubscription() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.RabbitMq/RabbitMqWorker.cs:line 221
   at ServiceStack.RabbitMq.RabbitMqWorker.Run() in /home/runner/work/ServiceStack/ServiceStack/ServiceStack/src/ServiceStack.RabbitMq/RabbitMqWorker.cs:line 113

System Info

Windows 2012
.NET 8.0.5
ServiceStack 8.2.2

Additional context

No response

Validations

mythz commented 2 months ago

It should be resolved from this commit, this change is available from v8.3.1+ that's now available in our Pre Release packages.