From 234855ff2258c7dba037b27150dc109014f7c462 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Sun, 5 Jul 2020 18:12:33 -0400 Subject: [PATCH 1/2] Fix crash in BinaryDataDecoder when decoding values from misaligned memory. The crash error was "load from misaligned raw pointer". --- .../BinaryDataCoders/BinaryDataDecoder.swift | 9 +++-- .../MisalignedDecoderTests.swift | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 Tests/BinaryCodableTests/MisalignedDecoderTests.swift diff --git a/Sources/BinaryCodable/BinaryDataCoders/BinaryDataDecoder.swift b/Sources/BinaryCodable/BinaryDataCoders/BinaryDataDecoder.swift index 2926054..344f706 100644 --- a/Sources/BinaryCodable/BinaryDataCoders/BinaryDataDecoder.swift +++ b/Sources/BinaryCodable/BinaryDataCoders/BinaryDataDecoder.swift @@ -124,10 +124,13 @@ private class BinaryDataDecodingContainer: BinaryDecodingContainer { throw BinaryDecodingError.dataCorrupted(.init(debugDescription: "Not enough data to create a a type of \(type). Needed: \(byteWidth). Received: \(bytes.count).")) } - let value = bytes.withUnsafeBytes { ptr -> T in - return ptr.load(as: T.self) + return bytes.withUnsafeBytes { ptr in + var value: T = 0 + withUnsafeMutableBytes(of: &value) { valuePtr in + valuePtr.copyMemory(from: UnsafeRawBufferPointer(rebasing: ptr[0.. String { diff --git a/Tests/BinaryCodableTests/MisalignedDecoderTests.swift b/Tests/BinaryCodableTests/MisalignedDecoderTests.swift new file mode 100644 index 0000000..2eacad0 --- /dev/null +++ b/Tests/BinaryCodableTests/MisalignedDecoderTests.swift @@ -0,0 +1,40 @@ +// Copyright 2020-present the BinaryCodable authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import BinaryCodable +import XCTest + +private struct MisalignedPacket: BinaryDecodable { + let twoByteInt: UInt16 + init(from decoder: BinaryDecoder) throws { + var container = decoder.container(maxLength: nil) + let _ = try container.decode(length: 1) + self.twoByteInt = try container.decode(UInt16.self) + } +} + +final class MisalignedDecoderTests: XCTestCase { + + func testEmpty() throws { + // Given + let packetData: [UInt8] = [0, 3, 0] + let decoder = BinaryDataDecoder() + + // When + let packet = try decoder.decode(MisalignedPacket.self, from: packetData) + + // Then + XCTAssertEqual(packet.twoByteInt, 3) + } +} From f3ca249670df9e1c959f5364bc97914987d73ac7 Mon Sep 17 00:00:00 2001 From: Jeff Verkoeyen Date: Sun, 5 Jul 2020 18:37:38 -0400 Subject: [PATCH 2/2] Lint. --- Tests/BinaryCodableTests/MisalignedDecoderTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/BinaryCodableTests/MisalignedDecoderTests.swift b/Tests/BinaryCodableTests/MisalignedDecoderTests.swift index 2eacad0..5f300f6 100644 --- a/Tests/BinaryCodableTests/MisalignedDecoderTests.swift +++ b/Tests/BinaryCodableTests/MisalignedDecoderTests.swift @@ -19,7 +19,7 @@ private struct MisalignedPacket: BinaryDecodable { let twoByteInt: UInt16 init(from decoder: BinaryDecoder) throws { var container = decoder.container(maxLength: nil) - let _ = try container.decode(length: 1) + _ = try container.decode(length: 1) self.twoByteInt = try container.decode(UInt16.self) } }