Quellcode durchsuchen

Handle writing out json when the value is empty/zero bytes and no type.

Thomas Van Lenten vor 4 Jahren
Ursprung
Commit
aeb96554f3

+ 1 - 0
FuzzTesting/FailCases/clusterfuzz-testcase-minimized-FuzzJSON_release-4929034878844928

@@ -0,0 +1 @@
+   {"wktAny":	{}}	

+ 12 - 0
Sources/SwiftProtobuf/AnyMessageStorage.swift

@@ -410,6 +410,18 @@ extension AnyMessageStorage {
   func encodedJSONString(options: JSONEncodingOptions) throws -> String {
     switch state {
     case .binary(let valueData):
+      // Follow the C++ protostream_objectsource.cc's
+      // ProtoStreamObjectSource::RenderAny() special casing of an empty value.
+      guard !valueData.isEmpty else {
+        if _typeURL.isEmpty {
+          return "{}"
+        }
+        var jsonEncoder = JSONEncoder()
+        jsonEncoder.startField(name: "@type")
+        jsonEncoder.putStringValue(value: _typeURL)
+        jsonEncoder.endObject()
+        return jsonEncoder.stringResult
+      }
       // Transcode by decoding the binary data to a message object
       // and then recode back into JSON.
       guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) else {

+ 5 - 0
Tests/SwiftProtobufTests/Test_FuzzTests.swift

@@ -96,6 +96,11 @@ class Test_FuzzTests: XCTestCase {
 
     // FailCases/JSON-Any
     assertJSONFails(" {\"wktAny\":{\"ny\":{")
+
+    // FuzzTesting/FailCases/clusterfuzz-testcase-minimized-FuzzJSON_release-4929034878844928
+    // This actually fails when the fuzzer was trying to write it back out again.
+    let msg = try! Fuzz_Testing_Message(jsonString: "   {\"wktAny\":  {}}  ")
+    XCTAssertEqual(try! msg.jsonString(), "{\"wktAny\":{}}")
   }
 
   func test_TextFormat() {