diff --git a/eng/Packages.Data.props b/eng/Packages.Data.props index 14a0ddd29df5..096c5a1da738 100644 --- a/eng/Packages.Data.props +++ b/eng/Packages.Data.props @@ -89,7 +89,7 @@ - + diff --git a/sdk/communication/Azure.Communication.JobRouter/README.md b/sdk/communication/Azure.Communication.JobRouter/README.md index 2df44db09d5e..b1ff7f828661 100644 --- a/sdk/communication/Azure.Communication.JobRouter/README.md +++ b/sdk/communication/Azure.Communication.JobRouter/README.md @@ -157,10 +157,10 @@ foreach (EventGridEvent egEvent in egEvents) switch (egEvent.EventType) { case "Microsoft.Communication.WorkerOfferIssued": - AcsRouterWorkerOfferIssuedEventData deserializedEventData = + AcsRouterWorkerOfferIssuedEventData? deserializedEventData = egEvent.Data.ToObjectFromJson(); - Console.Write(deserializedEventData.OfferId); // Offer Id - offerId = deserializedEventData.OfferId; + Console.Write(deserializedEventData?.OfferId); // Offer Id + offerId = deserializedEventData?.OfferId ?? string.Empty; break; // Handle any other custom event type default: diff --git a/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorld.md b/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorld.md index 40010a5e6d48..a74fdf0ab7a0 100644 --- a/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorld.md +++ b/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorld.md @@ -102,10 +102,10 @@ foreach (EventGridEvent egEvent in egEvents) switch (egEvent.EventType) { case "Microsoft.Communication.WorkerOfferIssued": - AcsRouterWorkerOfferIssuedEventData deserializedEventData = + AcsRouterWorkerOfferIssuedEventData? deserializedEventData = egEvent.Data.ToObjectFromJson(); - Console.Write(deserializedEventData.OfferId); // Offer Id - offerId = deserializedEventData.OfferId; + Console.Write(deserializedEventData?.OfferId); // Offer Id + offerId = deserializedEventData?.OfferId ?? string.Empty; break; // Handle any other custom event type default: diff --git a/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorldAsync.md b/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorldAsync.md index 83d0e7b53d95..97f624200b45 100644 --- a/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorldAsync.md +++ b/sdk/communication/Azure.Communication.JobRouter/samples/Sample1_HelloWorldAsync.md @@ -102,10 +102,10 @@ foreach (EventGridEvent egEvent in egEvents) switch (egEvent.EventType) { case "Microsoft.Communication.WorkerOfferIssued": - AcsRouterWorkerOfferIssuedEventData deserializedEventData = + AcsRouterWorkerOfferIssuedEventData? deserializedEventData = egEvent.Data.ToObjectFromJson(); - Console.Write(deserializedEventData.OfferId); // Offer Id - offerId = deserializedEventData.OfferId; + Console.Write(deserializedEventData?.OfferId); // Offer Id + offerId = deserializedEventData?.OfferId ?? string.Empty; break; // Handle any other custom event type default: diff --git a/sdk/communication/Azure.Communication.JobRouter/tests/Samples/JobRouterChangeNotification.cs b/sdk/communication/Azure.Communication.JobRouter/tests/Samples/JobRouterChangeNotification.cs index 5b253e1b20c9..231084942dcd 100644 --- a/sdk/communication/Azure.Communication.JobRouter/tests/Samples/JobRouterChangeNotification.cs +++ b/sdk/communication/Azure.Communication.JobRouter/tests/Samples/JobRouterChangeNotification.cs @@ -62,10 +62,10 @@ public void ReceivedChangeNotification() switch (egEvent.EventType) { case "Microsoft.Communication.WorkerOfferIssued": - AcsRouterWorkerOfferIssuedEventData deserializedEventData = + AcsRouterWorkerOfferIssuedEventData? deserializedEventData = egEvent.Data.ToObjectFromJson(); - Console.Write(deserializedEventData.OfferId); // Offer Id - offerId = deserializedEventData.OfferId; + Console.Write(deserializedEventData?.OfferId); // Offer Id + offerId = deserializedEventData?.OfferId ?? string.Empty; break; // Handle any other custom event type default: diff --git a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs index 51737c53c1db..1061bfa856d4 100644 --- a/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs +++ b/sdk/core/Azure.Core/api/Azure.Core.net6.0.cs @@ -22,6 +22,7 @@ public static partial class AzureCoreExtensions [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming.")] public static dynamic ToDynamicFromJson(this System.BinaryData utf8Json, Azure.Core.Serialization.JsonPropertyNames propertyNameFormat, string dateTimeFormat = "o") { throw null; } public static System.Threading.Tasks.ValueTask ToObjectAsync(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming.")] public static object? ToObjectFromJson(this System.BinaryData data) { throw null; } public static T? ToObject(this System.BinaryData data, Azure.Core.Serialization.ObjectSerializer serializer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } @@ -1189,6 +1190,7 @@ protected ObjectSerializer() { } } namespace Azure.Messaging { + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming.")] public partial class CloudEvent { public CloudEvent(string source, string type, System.BinaryData? data, string? dataContentType, Azure.Messaging.CloudEventDataFormat dataFormat = Azure.Messaging.CloudEventDataFormat.Binary) { } diff --git a/sdk/core/Azure.Core/src/Messaging/CloudEvent.cs b/sdk/core/Azure.Core/src/Messaging/CloudEvent.cs index 138b7b8f9b77..984c640d3163 100644 --- a/sdk/core/Azure.Core/src/Messaging/CloudEvent.cs +++ b/sdk/core/Azure.Core/src/Messaging/CloudEvent.cs @@ -3,14 +3,18 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; using Azure.Core; +using Azure.Core.Serialization; namespace Azure.Messaging { /// Represents a CloudEvent conforming to the 1.0 schema. This type has built-in serialization using System.Text.Json. [JsonConverter(typeof(CloudEventConverter))] + [RequiresUnreferencedCode(DynamicData.SerializationRequiresUnreferencedCode)] + [RequiresDynamicCode(DynamicData.SerializationRequiresUnreferencedCode)] public class CloudEvent { /// Initializes a new instance of the class. diff --git a/sdk/core/Azure.Core/src/Messaging/CloudEventConverter.cs b/sdk/core/Azure.Core/src/Messaging/CloudEventConverter.cs index 8cdaf16df452..b606baca362f 100644 --- a/sdk/core/Azure.Core/src/Messaging/CloudEventConverter.cs +++ b/sdk/core/Azure.Core/src/Messaging/CloudEventConverter.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; using Azure.Core; +using Azure.Core.Serialization; namespace Azure.Messaging { @@ -13,6 +15,8 @@ namespace Azure.Messaging /// A custom converter that attributes the type. /// This allows System.Text.Json to serialize and deserialize CloudEvents by default. /// + [RequiresUnreferencedCode(DynamicData.SerializationRequiresUnreferencedCode)] + [RequiresDynamicCode(DynamicData.SerializationRequiresUnreferencedCode)] internal class CloudEventConverter : JsonConverter { /// diff --git a/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs b/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs index 6a5ef7ee97b1..430ba42b2fcf 100644 --- a/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs +++ b/sdk/core/Azure.Core/src/Serialization/AzureCoreExtensions.cs @@ -54,6 +54,8 @@ public static class AzureCoreExtensions /// Otherwise, it returns either an object[] or Dictionary<string, object>. /// Each value in the key value pair or list will also be converted into a primitive or another complex type recursively. /// + [RequiresUnreferencedCode(DynamicData.SerializationRequiresUnreferencedCode)] + [RequiresDynamicCode(DynamicData.SerializationRequiresUnreferencedCode)] public static object? ToObjectFromJson(this BinaryData data) { JsonElement element = data.ToObjectFromJson(); diff --git a/sdk/core/Azure.Core/tests/compatibility/ExpectedAotWarnings.txt b/sdk/core/Azure.Core/tests/compatibility/ExpectedAotWarnings.txt index 263a624ce51e..7de79d8f192f 100644 --- a/sdk/core/Azure.Core/tests/compatibility/ExpectedAotWarnings.txt +++ b/sdk/core/Azure.Core/tests/compatibility/ExpectedAotWarnings.txt @@ -10,7 +10,7 @@ ILC : AOT analysis warning IL3050: Azure\.Core\.Json\.MutableJsonDocument: Using .*Azure\.Core.src.DynamicData.DynamicData\.ObjectEnumerator\.cs\(\d*\): Trim analysis warning IL2026: Azure\.Core\.Serialization\.DynamicData\.ObjectEnumerator\.Current\.get: Using member 'Azure\.Core\.Serialization\.DynamicData\.DynamicData\(MutableJsonElement,DynamicDataOptions\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. This class utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming .*Azure\.Core.src.DynamicData.DynamicData\.ObjectEnumerator\.cs\(\d*\): AOT analysis warning IL3050: Azure\.Core\.Serialization\.DynamicData\.ObjectEnumerator\.Current\.get: Using member 'Azure\.Core\.Serialization\.DynamicData\.DynamicData\(MutableJsonElement,DynamicDataOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. This class utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming .*Azure\.Core.src.DynamicData.DynamicDataProperty\.cs\(\d*\): Trim analysis warning IL2026: Azure\.Core\.Serialization\.DynamicDataProperty\.System\.Dynamic\.IDynamicMetaObjectProvider\.GetMetaObject\(Expression\): Using member 'Azure\.Core\.Serialization\.DynamicDataProperty\.MetaObject\.MetaObject\(Expression,IDynamicMetaObjectProvider\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code -ILC : Trim analysis warning IL2026: System\.BinaryData\.BinaryData\(Object,JsonSerializerOptions,Type\): Using member 'System\.Text\.Json\.JsonSerializer\.SerializeToUtf8Bytes\(Object,Type,JsonSerializerOptions\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. JSON serialization and deserialization might require types that cannot be statically analyzed\. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved +ILC : Trim analysis warning IL2026: Azure\.Messaging\.CloudEvent: Using member 'Azure\.Messaging\.CloudEventConverter\.CloudEventConverter\(\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming +ILC : AOT analysis warning IL3050: Azure\.Messaging\.CloudEvent: Using member 'Azure\.Messaging\.CloudEventConverter\.CloudEventConverter\(\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. This utilizes reflection-based JSON serialization and deserialization which is not compatible with trimming ILC : AOT analysis warning IL3050: System\.BinaryData\.BinaryData\(Object,JsonSerializerOptions,Type\): Using member 'System\.Text\.Json\.JsonSerializer\.SerializeToUtf8Bytes\(Object,Type,JsonSerializerOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation\. Use System\.Text\.Json source generation for native AOT applications -ILC : Trim analysis warning IL2026: System\.BinaryData\.ToObjectFromJson\(JsonSerializerOptions\): Using member 'System\.Text\.Json\.JsonSerializer\.Deserialize\(ReadOnlySpan`1,Type,JsonSerializerOptions\)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code\. JSON serialization and deserialization might require types that cannot be statically analyzed\. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved -ILC : AOT analysis warning IL3050: System\.BinaryData\.ToObjectFromJson\(JsonSerializerOptions\): Using member 'System\.Text\.Json\.JsonSerializer\.Deserialize\(ReadOnlySpan`1,Type,JsonSerializerOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation\. Use System\.Text\.Json source generation for native AOT applications +ILC : AOT analysis warning IL3050: System\.BinaryData\.ToObjectFromJson\(JsonSerializerOptions\): Using member 'System\.Text\.Json\.JsonSerializer\.Deserialize\(ReadOnlySpan`1,JsonSerializerOptions\)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling\. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation\. Use System\.Text\.Json source generation for native AOT applications \ No newline at end of file diff --git a/sdk/core/System.ClientModel/tests/Pipeline/HttpClientPipelineTransportTests.cs b/sdk/core/System.ClientModel/tests/Pipeline/HttpClientPipelineTransportTests.cs index 845569806a28..5197efcd1309 100644 --- a/sdk/core/System.ClientModel/tests/Pipeline/HttpClientPipelineTransportTests.cs +++ b/sdk/core/System.ClientModel/tests/Pipeline/HttpClientPipelineTransportTests.cs @@ -353,7 +353,7 @@ public async Task UnbufferedResponseContentStreamContainsResponseContent() Assert.AreEqual("Mock content", BinaryData.FromStream(message.Response!.ContentStream!).ToString()); // The second time it's read the stream's Position is at the end - Assert.AreEqual(string.Empty, BinaryData.FromStream(message.Response!.ContentStream!).ToString()); + Assert.AreEqual(0, BinaryData.FromStream(message.Response!.ContentStream!).ToArray().Length); } [Test] @@ -372,7 +372,7 @@ public async Task UnbufferedResponseContentStreamEmptyIfNoResponseContent() await transport.ProcessSyncOrAsync(message, IsAsync); - Assert.AreEqual(string.Empty, BinaryData.FromStream(message.Response!.ContentStream!).ToString()); + Assert.AreEqual(0, BinaryData.FromStream(message.Response!.ContentStream!).ToArray().Length); } [Test] diff --git a/sdk/openai/tools/TestFramework/src/Mocks/MockPage.cs b/sdk/openai/tools/TestFramework/src/Mocks/MockPage.cs index 830bbe9aa0c4..9d9ff8cbf0e3 100644 --- a/sdk/openai/tools/TestFramework/src/Mocks/MockPage.cs +++ b/sdk/openai/tools/TestFramework/src/Mocks/MockPage.cs @@ -31,7 +31,12 @@ public static MockPage FromClientResult(ClientResult result) { PipelineResponse response = result.GetRawResponse(); response.BufferContent(); - return response.Content.ToObjectFromJson>(); + MockPage mockPage = response.Content.ToObjectFromJson>() ?? new MockPage + { + Values = [], + Next = 0 + }; + return mockPage; } /// diff --git a/sdk/openai/tools/TestFramework/src/Mocks/MockRestServiceClient.cs b/sdk/openai/tools/TestFramework/src/Mocks/MockRestServiceClient.cs index 74d2e40ad8ed..53cc2c177c9c 100644 --- a/sdk/openai/tools/TestFramework/src/Mocks/MockRestServiceClient.cs +++ b/sdk/openai/tools/TestFramework/src/Mocks/MockRestServiceClient.cs @@ -88,8 +88,10 @@ public virtual ClientResult Add(string id, TData data, CancellationToken token = .ConfigureAwait(false); var response = result.GetRawResponse(); + var entry = response.Content.ToObjectFromJson.Entry>(); + var entryData = entry == null ? default : entry.data; return ClientResult.FromOptionalValue( - response.Content.ToObjectFromJson.Entry>().data, + entryData, response); } catch (ClientResultException ex) @@ -118,8 +120,10 @@ public virtual ClientResult Add(string id, TData data, CancellationToken token = { ClientResult result = SendSyncOrAsync(false, HttpMethod.Get, id, default, token).GetAwaiter().GetResult(); var response = result.GetRawResponse(); + var entry = response.Content.ToObjectFromJson.Entry>(); + var entryData = entry == null ? default : entry.data; return ClientResult.FromOptionalValue( - response.Content.ToObjectFromJson.Entry>().data, + entryData, response); } catch (ClientResultException ex) @@ -263,7 +267,7 @@ protected async ValueTask SendSyncOrAsync(bool isAsync, HttpMethod if (message.Response.Content?.ToMemory().Length > 0) { var error = message.Response.Content.ToObjectFromJson.Error>(); - throw new ClientResultException($"Error {error.error}: {error.message}", message.Response); + throw new ClientResultException($"Error {error?.error}: {error?.message}", message.Response); } throw new ClientResultException(message.Response); diff --git a/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md b/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md index 675ea34416d7..cd311ed5818d 100644 --- a/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md +++ b/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md @@ -1,5 +1,10 @@ # Release History +## 12.22.2 (2024-10-10) + +### Other Changes +- Upgraded `System.Text.Json` package dependency to 6.0.10 for security fix. + ## 12.22.1 (2024-09-25) ### Other Changes diff --git a/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj b/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj index 6f260523b68b..a951bd197de7 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj +++ b/sdk/storage/Azure.Storage.Blobs/src/Azure.Storage.Blobs.csproj @@ -4,7 +4,7 @@ Microsoft Azure.Storage.Blobs client library - 12.22.1 + 12.22.2 12.22.0 BlobSDK;$(DefineConstants) diff --git a/sdk/storage/Azure.Storage.Queues/src/Models/QueueMessage.cs b/sdk/storage/Azure.Storage.Queues/src/Models/QueueMessage.cs index 5a242cfecf95..fbc6078c3597 100644 --- a/sdk/storage/Azure.Storage.Queues/src/Models/QueueMessage.cs +++ b/sdk/storage/Azure.Storage.Queues/src/Models/QueueMessage.cs @@ -35,7 +35,17 @@ internal QueueMessage(string messageText) [EditorBrowsable(EditorBrowsableState.Never)] public string MessageText { - get => Body?.ToString(); + get + { + try + { + return Body?.ToString(); + } + catch (ArgumentNullException) // workaround for: https://github.com/dotnet/runtime/issues/68262 which was fixed in 8.0.0, can remove this after upgrade + { + return string.Empty; + } + } internal set => Body = value == null ? null : new BinaryData(value); } diff --git a/sdk/storage/Azure.Storage.Queues/src/QueueMessageCodec.cs b/sdk/storage/Azure.Storage.Queues/src/QueueMessageCodec.cs index 70792e7c289d..3810fca25ab2 100644 --- a/sdk/storage/Azure.Storage.Queues/src/QueueMessageCodec.cs +++ b/sdk/storage/Azure.Storage.Queues/src/QueueMessageCodec.cs @@ -17,7 +17,14 @@ public static string EncodeMessageBody(BinaryData binaryData, QueueMessageEncodi switch (messageEncoding) { case QueueMessageEncoding.None: - return binaryData.ToString(); + try + { + return binaryData.ToString(); + } + catch (ArgumentNullException) // workaround for: https://github.com/dotnet/runtime/issues/68262 which was fixed in 8.0.0, can remove this after upgrade + { + return string.Empty; + } case QueueMessageEncoding.Base64: if (MemoryMarshal.TryGetArray(binaryData.ToMemory(), out var segment)) {