From b75c788dddd7668f654af8b022850492d2ddc12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Helge=20He=C3=9F?= Date: Thu, 12 Dec 2024 18:01:19 +0100 Subject: [PATCH] Make base64 decoder tolerant Add padding if necessary, Foundation is picky about those. Also fix the recursion in base64url. --- Sources/MacroCore/Buffer/BufferStrings.swift | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Sources/MacroCore/Buffer/BufferStrings.swift b/Sources/MacroCore/Buffer/BufferStrings.swift index d3b07d6..3706703 100644 --- a/Sources/MacroCore/Buffer/BufferStrings.swift +++ b/Sources/MacroCore/Buffer/BufferStrings.swift @@ -151,10 +151,23 @@ public extension Buffer { return buffer case "base64": - guard let data = Data(base64Encoded: String(string)) else { - throw DataDecodingError.failedToDecodeBase64 + let s = String(string) + if let data = Data(base64Encoded: s) { return Buffer(data) } + + // https://stackoverflow.com/questions/4080988/why-does-base64-encoding + switch s.count % 4 { + case 0: // should have decoded above + throw DataDecodingError.failedToDecodeBase64 + case 1: // invalid base64 + throw DataDecodingError.failedToDecodeBase64 + case 2: + if let data = Data(base64Encoded: s + "==") { return Buffer(data) } + case 3: + if let data = Data(base64Encoded: s + "=") { return Buffer(data) } + default: + assertionFailure("Invalid % operation.") } - return Buffer(data) + throw DataDecodingError.failedToDecodeBase64 case "base64url": return try Self.from(String(string.map { @@ -163,7 +176,7 @@ public extension Buffer { case "_" : return "/" default : return $0 } - }), encoding) + }), "base64") default: return try from(string, .encodingWithName(encoding))