summaryrefslogtreecommitdiff
path: root/csharp/src
diff options
context:
space:
mode:
authorJon Skeet <jonskeet@google.com>2016-01-15 12:02:07 +0000
committerJon Skeet <jonskeet@google.com>2016-01-15 12:02:07 +0000
commitf437b67f600545f432863457a39870cb74675d34 (patch)
tree608f813163899f678c04726117f36a006199b332 /csharp/src
parent022a9b267561a3fccfcfaa7023779b969692bf74 (diff)
downloadprotobuf-javalite-f437b67f600545f432863457a39870cb74675d34.tar.gz
Extra strictness for FieldMask conversion
Diffstat (limited to 'csharp/src')
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs10
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonParserTest.cs8
-rw-r--r--csharp/src/Google.Protobuf/JsonFormatter.cs27
-rw-r--r--csharp/src/Google.Protobuf/JsonParser.cs8
4 files changed, 51 insertions, 2 deletions
diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
index 09308556..98b00f46 100644
--- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -418,6 +418,16 @@ namespace Google.Protobuf
}
[Test]
+ [TestCase("foo__bar")]
+ [TestCase("foo_3_ar")]
+ [TestCase("fooBar")]
+ public void FieldMaskInvalid(string input)
+ {
+ var mask = new FieldMask { Paths = { input } };
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(mask));
+ }
+
+ [Test]
public void FieldMaskStandalone()
{
var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } };
diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
index aa090d12..e8666b36 100644
--- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
@@ -779,6 +779,14 @@ namespace Google.Protobuf
}
[Test]
+ [TestCase("foo_bar")]
+ public void FieldMask_Invalid(string jsonValue)
+ {
+ string json = WrapInQuotes(jsonValue);
+ Assert.Throws<InvalidProtocolBufferException>(() => FieldMask.Parser.ParseJson(json));
+ }
+
+ [Test]
public void Any_RegularMessage()
{
var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 563b834e..573ca766 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -224,6 +224,31 @@ namespace Google.Protobuf
return !first;
}
+ /// <summary>
+ /// Camel-case converter with added strictness for field mask formatting.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception>
+ private static string ToCamelCaseForFieldMask(string input)
+ {
+ for (int i = 0; i < input.Length; i++)
+ {
+ char c = input[i];
+ if (c >= 'A' && c <= 'Z')
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
+ }
+ if (c == '_' && i < input.Length - 1)
+ {
+ char next = input[i + 1];
+ if (next < 'a' || next > 'z')
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
+ }
+ }
+ }
+ return ToCamelCase(input);
+ }
+
// Converted from src/google/protobuf/util/internal/utility.cc ToCamelCase
// TODO: Use the new field in FieldDescriptor.
internal static string ToCamelCase(string input)
@@ -525,7 +550,7 @@ namespace Google.Protobuf
private void WriteFieldMask(StringBuilder builder, IMessage value)
{
IList paths = (IList) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
- WriteString(builder, string.Join(",", paths.Cast<string>().Select(ToCamelCase)));
+ WriteString(builder, string.Join(",", paths.Cast<string>().Select(ToCamelCaseForFieldMask)));
}
private void WriteAny(StringBuilder builder, IMessage value)
diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs
index db601c57..9e5d8711 100644
--- a/csharp/src/Google.Protobuf/JsonParser.cs
+++ b/csharp/src/Google.Protobuf/JsonParser.cs
@@ -894,6 +894,8 @@ namespace Google.Protobuf
private static string ToSnakeCase(string text)
{
var builder = new StringBuilder(text.Length * 2);
+ // Note: this is probably unnecessary now, but currently retained to be as close as possible to the
+ // C++, whilst still throwing an exception on underscores.
bool wasNotUnderscore = false; // Initialize to false for case 1 (below)
bool wasNotCap = false;
@@ -927,7 +929,11 @@ namespace Google.Protobuf
else
{
builder.Append(c);
- wasNotUnderscore = c != '_';
+ if (c == '_')
+ {
+ throw new InvalidProtocolBufferException($"Invalid field mask: {text}");
+ }
+ wasNotUnderscore = true;
wasNotCap = true;
}
}