Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdc4e429

Browse files
Improve C# handling of Any JSON serialization/deserialization
An Any without a type URL is now serialized to JSON as an empty object.A JSON object without a type URL is now deserialized as an empty Any.A JSON object with an invalid type URL now throws InvalidProtocolBufferException.PiperOrigin-RevId: 753147779
1 parentf5bc2a3 commitdc4e429

File tree

5 files changed

+38
-4
lines changed

5 files changed

+38
-4
lines changed

‎conformance/failure_list_csharp.txt‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,4 @@ Recommended.Editions_Proto3.ValueRejectInfNumberValue.JsonOutput
3333
Recommended.Editions_Proto3.ValueRejectNanNumberValue.JsonOutput
3434
Required.Editions_Proto2.ProtobufInput.UnknownOrdering.ProtobufOutput
3535
Required.Editions_Proto3.ProtobufInput.UnknownOrdering.ProtobufOutput
36-
Required.*.JsonInput.AnyWithNoType.* # Failed to parse input or produce output.
37-
Required.*.JsonInput.AnyWktRepresentationWithEmptyTypeAndValue # Should have failed to parse, but didn't.
38-
Required.*.JsonInput.AnyWktRepresentationWithBadType # Should have failed to parse, but didn't.
3936

‎csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,13 @@ public void AnyUnknownType()
591591
Assert.Throws<InvalidOperationException>(()=>JsonFormatter.Default.Format(any));
592592
}
593593

594+
[Test]
595+
publicvoidAnyEmpty()
596+
{
597+
varany=newAny();
598+
AssertJson("{ }",JsonFormatter.Default.Format(any));
599+
}
600+
594601
[Test]
595602
[TestCase(typeof(BoolValue),true,"true")]
596603
[TestCase(typeof(Int32Value),32,"32")]

‎csharp/src/Google.Protobuf.Test/JsonParserTest.cs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,17 @@ public void Any_UnknownType()
840840
[Test]
841841
publicvoidAny_NoTypeUrl()
842842
{
843+
// Currently if we're missing the type URL (@type) we return an empty Any message
844+
// regardless of other fields. In the future we could potentially fail if there's no
845+
// type URL but other fields are present.
843846
stringjson="{\"foo\":\"bar\" }";
847+
Assert.AreEqual(newAny(),Any.Parser.ParseJson(json));
848+
}
849+
850+
[Test]
851+
publicvoidAny_BadTypeUrl()
852+
{
853+
stringjson="{\"@type\":\"no-slash\" }";
844854
Assert.Throws<InvalidProtocolBufferException>(()=>Any.Parser.ParseJson(json));
845855
}
846856

‎csharp/src/Google.Protobuf/JsonFormatter.cs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,13 @@ private void WriteAny(TextWriter writer, IMessage value, int indentationLevel) {
471471

472472
stringtypeUrl=
473473
(string)value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
474+
// If no type URL has been specified, just return an empty JSON object.
475+
if(typeUrl==""){
476+
WriteBracketOpen(writer,ObjectOpenBracket);
477+
WriteBracketClose(writer,ObjectCloseBracket,false,indentationLevel);
478+
return;
479+
}
480+
474481
ByteStringdata=
475482
(ByteString)value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
476483
stringtypeName=Any.GetTypeName(typeUrl);

‎csharp/src/Google.Protobuf/JsonParser.cs‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,13 @@ private void MergeAny(IMessage message, JsonTokenizer tokenizer)
516516
tokens.Add(token);
517517
token=tokenizer.Next();
518518

519+
// If we get to the end of the object and haven't seen a type URL, just return.
520+
// (The message will be empty at this point.)
521+
// We could potentially make this more conservative, failing if there are
522+
// other properties but no type URL.
519523
if(tokenizer.ObjectDepth<typeUrlObjectDepth)
520524
{
521-
thrownewInvalidProtocolBufferException("Any message with no @type");
525+
return;
522526
}
523527
}
524528

@@ -530,6 +534,15 @@ private void MergeAny(IMessage message, JsonTokenizer tokenizer)
530534
}
531535
stringtypeUrl=token.StringValue;
532536
stringtypeName=Any.GetTypeName(typeUrl);
537+
// If we don't find a slash, GetTypeName returns an empty string. An empty string can
538+
// never be a valid type name (whether that was through @type="", @type="blah" or
539+
// @type="blah/") so we fail. This is InvalidProtocolBufferException rather than
540+
// the InvalidOperationException used below, as it's the data that's invalid rather than
541+
// the context in which we're parsing it.
542+
if(typeName=="")
543+
{
544+
thrownewInvalidProtocolBufferException("Invalid Any.@type value");
545+
}
533546

534547
MessageDescriptordescriptor=settings.TypeRegistry.Find(typeName);
535548
if(descriptor==null)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp