From ac461ca2d12cec49ddcfb932df6dc1119dff4616 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 25 Jul 2018 17:13:43 -0600 Subject: [PATCH] Fixup parser: Robust to servers various "empty" types For base64Encoded data, sometimes the server sends "null" sometimes the server sends an empty string. --- Signal/src/Jobs/MessageFetcherJob.swift | 2 +- Signal/test/SSKTests/ParamParserTest.swift | 31 ++++++++++++++++++++- SignalServiceKit/src/Util/ParamParser.swift | 10 ++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/Signal/src/Jobs/MessageFetcherJob.swift b/Signal/src/Jobs/MessageFetcherJob.swift index ceca5d806..8db9af128 100644 --- a/Signal/src/Jobs/MessageFetcherJob.swift +++ b/Signal/src/Jobs/MessageFetcherJob.swift @@ -131,7 +131,7 @@ public class MessageFetcherJob: NSObject { let timestamp: UInt64 = try params.required(key: "timestamp") let source: String = try params.required(key: "source") let sourceDevice: UInt32 = try params.required(key: "sourceDevice") - let legacyMessage = try params.optionalBase64EncodedData(key: "message") + let legacyMessage: Data? = try params.optionalBase64EncodedData(key: "message") let content: Data? = try params.optionalBase64EncodedData(key: "content") return SSKEnvelope(timestamp: UInt64(timestamp), source: source, sourceDevice: sourceDevice, type: type, content: content, legacyMessage: legacyMessage) diff --git a/Signal/test/SSKTests/ParamParserTest.swift b/Signal/test/SSKTests/ParamParserTest.swift index 34e93a0c2..d4f9f506b 100644 --- a/Signal/test/SSKTests/ParamParserTest.swift +++ b/Signal/test/SSKTests/ParamParserTest.swift @@ -71,7 +71,9 @@ class ParamParserTest: XCTestCase { }()) } - func testBase64Data() { + // MARK: Base64EncodedData + + func testBase64Data_Valid() { let originalString = "asdf" let utf8Data: Data = originalString.data(using: .utf8)! let base64EncodedString = utf8Data.base64EncodedString() @@ -86,4 +88,31 @@ class ParamParserTest: XCTestCase { let roundTripString = String(data: data, encoding: .utf8) XCTAssertEqual(originalString, roundTripString) } + + func testBase64Data_EmptyString() { + let dict: [String: Any] = ["some_data": ""] + let parser = ParamParser(dictionary: dict) + + XCTAssertThrowsError(try parser.requiredBase64EncodedData(key: "some_data")) + XCTAssertEqual(nil, try parser.optionalBase64EncodedData(key: "some_data")) + } + + func testBase64Data_NSNull() { + let dict: [String: Any] = ["some_data": NSNull()] + let parser = ParamParser(dictionary: dict) + + XCTAssertThrowsError(try parser.requiredBase64EncodedData(key: "some_data")) + XCTAssertEqual(nil, try parser.optionalBase64EncodedData(key: "some_data")) + } + + func testBase64Data_Invalid() { + // invalid base64 data + let base64EncodedString = "YXNkZg" + + let dict: [String: Any] = ["some_data": base64EncodedString] + let parser = ParamParser(dictionary: dict) + + XCTAssertThrowsError(try parser.requiredBase64EncodedData(key: "some_data")) + XCTAssertThrowsError(try parser.optionalBase64EncodedData(key: "some_data")) + } } diff --git a/SignalServiceKit/src/Util/ParamParser.swift b/SignalServiceKit/src/Util/ParamParser.swift index e8501e85f..9fea969f7 100644 --- a/SignalServiceKit/src/Util/ParamParser.swift +++ b/SignalServiceKit/src/Util/ParamParser.swift @@ -64,6 +64,10 @@ public class ParamParser { return nil } + guard !(someValue is NSNull) else { + return nil + } + guard let typedValue = someValue as? T else { throw invalid(key: key) } @@ -85,7 +89,7 @@ public class ParamParser { } public func optional(key: Key) throws -> T? where T: FixedWidthInteger { - guard let someValue = dictionary[key] else { + guard let someValue: Any = try optional(key: key) else { return nil } @@ -121,6 +125,10 @@ public class ParamParser { throw ParseError.invalidFormat(key) } + guard data.count > 0 else { + return nil + } + return data } }