فهرست منبع

Avoid NullReferenceException when accessing CustomOptions

(Note: the test is from #6826, but the implementation is effectively reverting to an earlier one.)
Jon Skeet 6 سال پیش
والد
کامیت
4dd95d2b6b

+ 16 - 0
csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs

@@ -31,6 +31,7 @@
 #endregion
 
 using Google.Protobuf.Reflection;
+using Google.Protobuf.TestProtos;
 using Google.Protobuf.WellKnownTypes;
 using NUnit.Framework;
 using System.IO;
@@ -202,6 +203,21 @@ namespace Google.Protobuf.Test.Reflection
             AssertOption(new Aggregate { S = "FieldAnnotation" }, fieldOptions.TryGetMessage, AggregateFieldOpt);
         }
 
+        [Test]
+        public void NoOptions()
+        {
+            var fileDescriptor = UnittestProto3Reflection.Descriptor;
+            var messageDescriptor = TestAllTypes.Descriptor;
+            Assert.NotNull(fileDescriptor.CustomOptions);
+            Assert.NotNull(messageDescriptor.CustomOptions);
+            Assert.NotNull(messageDescriptor.Fields[1].CustomOptions);
+            Assert.NotNull(fileDescriptor.Services[0].CustomOptions);
+            Assert.NotNull(fileDescriptor.Services[0].Methods[0].CustomOptions);
+            Assert.NotNull(fileDescriptor.EnumTypes[0].CustomOptions);
+            Assert.NotNull(fileDescriptor.EnumTypes[0].Values[0].CustomOptions);
+            Assert.NotNull(TestAllTypes.Descriptor.Oneofs[0].CustomOptions);
+        }
+
         private void AssertOption<T>(T expected, OptionFetcher<T> fetcher, CustomOptionNumber field)
         {
             T actual;

+ 2 - 2
csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs

@@ -129,8 +129,8 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this enum.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => Proto.Options.CustomOptions;
-
+        public CustomOptions CustomOptions =>  Proto.Options?.CustomOptions ?? CustomOptions.Empty;
+        
         /* // uncomment this in the full proto2 support PR
         /// <summary>
         /// Gets a single value enum option for this descriptor

+ 1 - 1
csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs

@@ -74,7 +74,7 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this enum value.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => Proto.Options.CustomOptions;
+        public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
 
         /* // uncomment this in the full proto2 support PR
         /// <summary>

+ 1 - 1
csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs

@@ -278,7 +278,7 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this field.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => Proto.Options.CustomOptions;
+        public CustomOptions CustomOptions =>  Proto.Options?.CustomOptions ?? CustomOptions.Empty;
 
         /* // uncomment this in the full proto2 support PR
         /// <summary>

+ 1 - 1
csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs

@@ -510,7 +510,7 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this file.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => Proto.Options.CustomOptions;
+        public CustomOptions CustomOptions =>  Proto.Options?.CustomOptions ?? CustomOptions.Empty;
 
         /* // uncomment this in the full proto2 support PR
         /// <summary>

+ 1 - 1
csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs

@@ -247,7 +247,7 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this message.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => Proto.Options.CustomOptions;
+        public CustomOptions CustomOptions =>  Proto.Options?.CustomOptions ?? CustomOptions.Empty;
 
         /* // uncomment this in the full proto2 support PR
         /// <summary>

+ 1 - 1
csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs

@@ -74,7 +74,7 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this method.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => Proto.Options.CustomOptions;
+        public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
 
         /* // uncomment this in the full proto2 support PR
         /// <summary>

+ 1 - 1
csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs

@@ -106,7 +106,7 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this oneof.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => proto.Options.CustomOptions;
+        public CustomOptions CustomOptions => proto.Options?.CustomOptions ?? CustomOptions.Empty;
 
         /* // uncomment this in the full proto2 support PR
         /// <summary>

+ 1 - 1
csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs

@@ -95,7 +95,7 @@ namespace Google.Protobuf.Reflection
         /// The (possibly empty) set of custom options for this service.
         /// </summary>
         //[Obsolete("CustomOptions are obsolete. Use GetOption")]
-        public CustomOptions CustomOptions => Proto.Options.CustomOptions;
+        public CustomOptions CustomOptions => Proto.Options?.CustomOptions ?? CustomOptions.Empty;
 
         /* // uncomment this in the full proto2 support PR
         /// <summary>