         var other = [String]()
         while position < endIndex {
             let size = Int(try UInt8(data: data, position: &position))
-            guard size > 0 else { break }
-            var attr = String(bytes: data[position..<position+size], encoding: .utf8)!.characters.split(separator: "=", maxSplits: 1, omittingEmptySubsequences: false).map { String($0) }
+            let labelStart = position
+            guard size > 0 else {
+                break
+            }
+            guard data.formIndex(&position, offsetBy: size, limitedBy: data.endIndex) else {
+                throw DecodeError.invalidLabelSize
+            }
+            guard let label = String(bytes: data[labelStart..<position], encoding: .utf8) else {
+                throw DecodeError.unicodeDecodingError
+            }
+            let attr = label.characters.split(separator: "=", maxSplits: 1, omittingEmptySubsequences: false).map { String($0) }
             if attr.count == 2 {
                 attrs[attr[0]] = attr[1]
             } else {
                 other.append(attr[0])
             }
-            position += size
         }
         self.attributes = attrs
         self.values = other

extension HostRecord: ResourceRecord {
    init(unpack data: Data, position: inout Data.Index, common: RecordCommonFields) throws {
        (name, _, unique, internetClass, ttl) = common
        let size = Int(try unpack(data, &position) as UInt16)
        ip = IPType(networkBytes: Data(data[position..<position+size]))!
        position += size
    }

    public func pack(onto buffer: inout Data, labels: inout Labels) throws {

extension Record: ResourceRecord {
    init(unpack data: Data, position: inout Data.Index, common: RecordCommonFields) throws {
        (name, type, unique, internetClass, ttl) = common
        let size = Int(try UInt16(data: data, position: &position))
        let dataStart = position
        guard data.formIndex(&position, offsetBy: size, limitedBy: data.endIndex) else {
            throw DecodeError.invalidDataSize
        }
        self.data = Data(data[dataStart..<position])
    }

    public func pack(onto buffer: inout Data, labels: inout Labels) throws {
