Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[swift] Fix edge case for heap based messages using a redacted description field #2772

Merged
merged 1 commit into from
Jan 9, 2024

Conversation

dnkoutso
Copy link
Collaborator

@dnkoutso dnkoutso commented Jan 3, 2024

This is a rather obscure edge case but we hit it nonetheless.

A message stored on the heap with a field named description that is also marked as redacted will fail Swift compilation.

Tests are using generated code that is not committed but here what it looks like:
// Code generated by Wire protocol buffer compiler, do not edit.
// Source: RedactedLargeMessage in redacted.proto
import Foundation
import Wire

@dynamicMemberLookup
public struct RedactedLargeMessage {

    @CopyOnWrite
    private var storage: Storage
    /**
     * Access the underlying storage
     */
    public subscript<Property>(dynamicMember keyPath: WritableKeyPath<Storage, Property>) -> Property {
        get {
            storage[keyPath: keyPath]
        }
        set {
            storage[keyPath: keyPath] = newValue
        }
    }
    public var a: String? {
        get {
            storage.a
        }
        set {
            storage.a = newValue
        }
    }
    public var b: String? {
        get {
            storage.b
        }
        set {
            storage.b = newValue
        }
    }
    public var c: String? {
        get {
            storage.c
        }
        set {
            storage.c = newValue
        }
    }
    public var d: String? {
        get {
            storage.d
        }
        set {
            storage.d = newValue
        }
    }
    public var e: String? {
        get {
            storage.e
        }
        set {
            storage.e = newValue
        }
    }
    public var f: String? {
        get {
            storage.f
        }
        set {
            storage.f = newValue
        }
    }
    public var g: String? {
        get {
            storage.g
        }
        set {
            storage.g = newValue
        }
    }
    public var h: String? {
        get {
            storage.h
        }
        set {
            storage.h = newValue
        }
    }
    public var i: String? {
        get {
            storage.i
        }
        set {
            storage.i = newValue
        }
    }
    public var j: String? {
        get {
            storage.j
        }
        set {
            storage.j = newValue
        }
    }
    public var k: String? {
        get {
            storage.k
        }
        set {
            storage.k = newValue
        }
    }
    public var l: String? {
        get {
            storage.l
        }
        set {
            storage.l = newValue
        }
    }
    public var m: String? {
        get {
            storage.m
        }
        set {
            storage.m = newValue
        }
    }
    public var n: String? {
        get {
            storage.n
        }
        set {
            storage.n = newValue
        }
    }
    public var o: String? {
        get {
            storage.o
        }
        set {
            storage.o = newValue
        }
    }
    public var p: String? {
        get {
            storage.p
        }
        set {
            storage.p = newValue
        }
    }
    public var q: String? {
        get {
            storage.q
        }
        set {
            storage.q = newValue
        }
    }
    public var r: String? {
        get {
            storage.r
        }
        set {
            storage.r = newValue
        }
    }
    public var s: String? {
        get {
            storage.s
        }
        set {
            storage.s = newValue
        }
    }
    public var t: String? {
        get {
            storage.t
        }
        set {
            storage.t = newValue
        }
    }
    public var u: String? {
        get {
            storage.u
        }
        set {
            storage.u = newValue
        }
    }
    public var v: String? {
        get {
            storage.v
        }
        set {
            storage.v = newValue
        }
    }
    public var w: String? {
        get {
            storage.w
        }
        set {
            storage.w = newValue
        }
    }
    public var x: String? {
        get {
            storage.x
        }
        set {
            storage.x = newValue
        }
    }
    public var y: String? {
        get {
            storage.y
        }
        set {
            storage.y = newValue
        }
    }
    public var z: String? {
        get {
            storage.z
        }
        set {
            storage.z = newValue
        }
    }
    /**
     * A large message with a redacted description causes a Swift compiler error.
     */
    public var description_: String? {
        get {
            storage.description_
        }
        set {
            storage.description_ = newValue
        }
    }
    public var unknownFields: Foundation.Data {
        get {
            storage.unknownFields
        }
        set {
            storage.unknownFields = newValue
        }
    }

    public init(configure: (inout Self.Storage) -> Swift.Void = { _ in }) {
        self.storage = Storage(
                configure: configure
                )
    }

}

#if !WIRE_REMOVE_EQUATABLE
extension RedactedLargeMessage : Equatable {
}
#endif

#if !WIRE_REMOVE_HASHABLE
extension RedactedLargeMessage : Hashable {
}
#endif

extension RedactedLargeMessage : Sendable {
}

extension RedactedLargeMessage : ProtoDefaultedValue {

    public static var defaultedValue: RedactedLargeMessage {
        RedactedLargeMessage()
    }
}

#if !WIRE_REMOVE_REDACTABLE
extension RedactedLargeMessage : Redactable {

    public enum RedactedKeys : String, RedactedKey {

        case a
        case description

    }

    public var description: String {
        return storage.description
    }
}
#endif

extension RedactedLargeMessage : Proto2Codable {

    public init(from protoReader: ProtoReader) throws {
        self.storage = try Storage(from: protoReader)
    }

    public func encode(to protoWriter: ProtoWriter) throws {
        try storage.encode(to: protoWriter)
    }

}

#if !WIRE_REMOVE_CODABLE
extension RedactedLargeMessage : Codable {

    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        self.storage = try container.decode(Storage.self)
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(storage)
    }

}
#endif

/**
 * Subtypes within RedactedLargeMessage
 */
extension RedactedLargeMessage {

    public struct RedactedLargeOneOf {

        public var action: RedactedLargeMessage.RedactedLargeOneOf.Action?
        public var unknownFields: Foundation.Data = .init()

        public init(configure: (inout Self) -> Swift.Void = { _ in }) {
            configure(&self)
        }

    }

}

#if !WIRE_REMOVE_EQUATABLE
extension RedactedLargeMessage.RedactedLargeOneOf : Equatable {
}
#endif

#if !WIRE_REMOVE_HASHABLE
extension RedactedLargeMessage.RedactedLargeOneOf : Hashable {
}
#endif

extension RedactedLargeMessage.RedactedLargeOneOf : Sendable {
}

extension RedactedLargeMessage.RedactedLargeOneOf : ProtoDefaultedValue {

    public static var defaultedValue: RedactedLargeMessage.RedactedLargeOneOf {
        RedactedLargeMessage.RedactedLargeOneOf()
    }
}

extension RedactedLargeMessage.RedactedLargeOneOf : ProtoMessage {

    public static func protoMessageTypeURL() -> String {
        return "type.googleapis.com/RedactedLargeMessage.RedactedLargeOneOf"
    }

}

extension RedactedLargeMessage.RedactedLargeOneOf : Proto2Codable {

    public init(from protoReader: ProtoReader) throws {
        var action: RedactedLargeMessage.RedactedLargeOneOf.Action? = nil

        let token = try protoReader.beginMessage()
        while let tag = try protoReader.nextTag(token: token) {
            switch tag {
            case 1: action = .value1(try protoReader.decode(String.self))
            case 2: action = .value2(try protoReader.decode(String.self))
            case 3: action = .value3(try protoReader.decode(String.self))
            case 4: action = .value4(try protoReader.decode(String.self))
            case 5: action = .value5(try protoReader.decode(String.self))
            case 6: action = .value6(try protoReader.decode(String.self))
            case 7: action = .value7(try protoReader.decode(String.self))
            case 8: action = .value8(try protoReader.decode(String.self))
            case 9: action = .value9(try protoReader.decode(String.self))
            case 10: action = .value10(try protoReader.decode(String.self))
            case 11: action = .value11(try protoReader.decode(String.self))
            case 12: action = .value12(try protoReader.decode(String.self))
            case 13: action = .value13(try protoReader.decode(String.self))
            case 14: action = .value14(try protoReader.decode(String.self))
            case 15: action = .value15(try protoReader.decode(String.self))
            case 16: action = .value16(try protoReader.decode(String.self))
            case 17: action = .description_(try protoReader.decode(String.self))
            default: try protoReader.readUnknownField(tag: tag)
            }
        }
        self.unknownFields = try protoReader.endMessage(token: token)

        self.action = action
    }

    public func encode(to protoWriter: ProtoWriter) throws {
        if let action = self.action {
            try action.encode(to: protoWriter)
        }
        try protoWriter.writeUnknownFields(unknownFields)
    }

}

#if !WIRE_REMOVE_CODABLE
extension RedactedLargeMessage.RedactedLargeOneOf : Codable {

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: StringLiteralCodingKeys.self)
        if let value1 = try container.decodeIfPresent(String.self, forKey: "value1") {
            self.action = .value1(value1)
        } else if let value2 = try container.decodeIfPresent(String.self, forKey: "value2") {
            self.action = .value2(value2)
        } else if let value3 = try container.decodeIfPresent(String.self, forKey: "value3") {
            self.action = .value3(value3)
        } else if let value4 = try container.decodeIfPresent(String.self, forKey: "value4") {
            self.action = .value4(value4)
        } else if let value5 = try container.decodeIfPresent(String.self, forKey: "value5") {
            self.action = .value5(value5)
        } else if let value6 = try container.decodeIfPresent(String.self, forKey: "value6") {
            self.action = .value6(value6)
        } else if let value7 = try container.decodeIfPresent(String.self, forKey: "value7") {
            self.action = .value7(value7)
        } else if let value8 = try container.decodeIfPresent(String.self, forKey: "value8") {
            self.action = .value8(value8)
        } else if let value9 = try container.decodeIfPresent(String.self, forKey: "value9") {
            self.action = .value9(value9)
        } else if let value10 = try container.decodeIfPresent(String.self, forKey: "value10") {
            self.action = .value10(value10)
        } else if let value11 = try container.decodeIfPresent(String.self, forKey: "value11") {
            self.action = .value11(value11)
        } else if let value12 = try container.decodeIfPresent(String.self, forKey: "value12") {
            self.action = .value12(value12)
        } else if let value13 = try container.decodeIfPresent(String.self, forKey: "value13") {
            self.action = .value13(value13)
        } else if let value14 = try container.decodeIfPresent(String.self, forKey: "value14") {
            self.action = .value14(value14)
        } else if let value15 = try container.decodeIfPresent(String.self, forKey: "value15") {
            self.action = .value15(value15)
        } else if let value16 = try container.decodeIfPresent(String.self, forKey: "value16") {
            self.action = .value16(value16)
        } else if let description_ = try container.decodeIfPresent(String.self, forKey: "description") {
            self.action = .description_(description_)
        } else {
            self.action = nil
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: StringLiteralCodingKeys.self)

        switch self.action {
        case .value1(let value1): try container.encode(value1, forKey: "value1")
        case .value2(let value2): try container.encode(value2, forKey: "value2")
        case .value3(let value3): try container.encode(value3, forKey: "value3")
        case .value4(let value4): try container.encode(value4, forKey: "value4")
        case .value5(let value5): try container.encode(value5, forKey: "value5")
        case .value6(let value6): try container.encode(value6, forKey: "value6")
        case .value7(let value7): try container.encode(value7, forKey: "value7")
        case .value8(let value8): try container.encode(value8, forKey: "value8")
        case .value9(let value9): try container.encode(value9, forKey: "value9")
        case .value10(let value10): try container.encode(value10, forKey: "value10")
        case .value11(let value11): try container.encode(value11, forKey: "value11")
        case .value12(let value12): try container.encode(value12, forKey: "value12")
        case .value13(let value13): try container.encode(value13, forKey: "value13")
        case .value14(let value14): try container.encode(value14, forKey: "value14")
        case .value15(let value15): try container.encode(value15, forKey: "value15")
        case .value16(let value16): try container.encode(value16, forKey: "value16")
        case .description_(let description_): try container.encode(description_, forKey: "description")
        case Optional.none: break
        }
    }

}
#endif

/**
 * Subtypes within RedactedLargeMessage.RedactedLargeOneOf
 */
extension RedactedLargeMessage.RedactedLargeOneOf {

    public enum Action {

        case value1(String)
        case value2(String)
        case value3(String)
        case value4(String)
        case value5(String)
        case value6(String)
        case value7(String)
        case value8(String)
        case value9(String)
        case value10(String)
        case value11(String)
        case value12(String)
        case value13(String)
        case value14(String)
        case value15(String)
        case value16(String)
        /**
         * A large message with a redacted description causes a Swift compiler error.
         */
        case description_(String)

        fileprivate func encode(to protoWriter: ProtoWriter) throws {
            switch self {
            case .value1(let value1): try protoWriter.encode(tag: 1, value: value1)
            case .value2(let value2): try protoWriter.encode(tag: 2, value: value2)
            case .value3(let value3): try protoWriter.encode(tag: 3, value: value3)
            case .value4(let value4): try protoWriter.encode(tag: 4, value: value4)
            case .value5(let value5): try protoWriter.encode(tag: 5, value: value5)
            case .value6(let value6): try protoWriter.encode(tag: 6, value: value6)
            case .value7(let value7): try protoWriter.encode(tag: 7, value: value7)
            case .value8(let value8): try protoWriter.encode(tag: 8, value: value8)
            case .value9(let value9): try protoWriter.encode(tag: 9, value: value9)
            case .value10(let value10): try protoWriter.encode(tag: 10, value: value10)
            case .value11(let value11): try protoWriter.encode(tag: 11, value: value11)
            case .value12(let value12): try protoWriter.encode(tag: 12, value: value12)
            case .value13(let value13): try protoWriter.encode(tag: 13, value: value13)
            case .value14(let value14): try protoWriter.encode(tag: 14, value: value14)
            case .value15(let value15): try protoWriter.encode(tag: 15, value: value15)
            case .value16(let value16): try protoWriter.encode(tag: 16, value: value16)
            case .description_(let description_): try protoWriter.encode(tag: 17, value: description_)
            }
        }

    }

}

#if !WIRE_REMOVE_EQUATABLE
extension RedactedLargeMessage.RedactedLargeOneOf.Action : Equatable {
}
#endif

#if !WIRE_REMOVE_HASHABLE
extension RedactedLargeMessage.RedactedLargeOneOf.Action : Hashable {
}
#endif

extension RedactedLargeMessage.RedactedLargeOneOf.Action : Sendable {
}

#if !WIRE_REMOVE_REDACTABLE
extension RedactedLargeMessage.RedactedLargeOneOf.Action : Redactable {

    public enum RedactedKeys : String, RedactedKey {

        case description

    }

}
#endif

extension RedactedLargeMessage {

    /**
     * Underlying storage for RedactedLargeMessage
     */
    public struct Storage {

        @ProtoDefaulted
        public var a: String?
        @ProtoDefaulted
        public var b: String?
        @ProtoDefaulted
        public var c: String?
        @ProtoDefaulted
        public var d: String?
        @ProtoDefaulted
        public var e: String?
        @ProtoDefaulted
        public var f: String?
        @ProtoDefaulted
        public var g: String?
        @ProtoDefaulted
        public var h: String?
        @ProtoDefaulted
        public var i: String?
        @ProtoDefaulted
        public var j: String?
        @ProtoDefaulted
        public var k: String?
        @ProtoDefaulted
        public var l: String?
        @ProtoDefaulted
        public var m: String?
        @ProtoDefaulted
        public var n: String?
        @ProtoDefaulted
        public var o: String?
        @ProtoDefaulted
        public var p: String?
        @ProtoDefaulted
        public var q: String?
        @ProtoDefaulted
        public var r: String?
        @ProtoDefaulted
        public var s: String?
        @ProtoDefaulted
        public var t: String?
        @ProtoDefaulted
        public var u: String?
        @ProtoDefaulted
        public var v: String?
        @ProtoDefaulted
        public var w: String?
        @ProtoDefaulted
        public var x: String?
        @ProtoDefaulted
        public var y: String?
        @ProtoDefaulted
        public var z: String?
        @ProtoDefaulted
        public var description_: String?
        public var unknownFields: Foundation.Data = .init()

        public init(configure: (inout Self) -> Swift.Void = { _ in }) {
            configure(&self)
        }

    }

}

#if !WIRE_REMOVE_EQUATABLE
extension RedactedLargeMessage.Storage : Equatable {
}
#endif

#if !WIRE_REMOVE_HASHABLE
extension RedactedLargeMessage.Storage : Hashable {
}
#endif

extension RedactedLargeMessage.Storage : Sendable {
}

#if !WIRE_REMOVE_REDACTABLE
extension RedactedLargeMessage.Storage : Redactable {

    public typealias RedactedKeys = RedactedLargeMessage.RedactedKeys

}
#endif

extension RedactedLargeMessage.Storage : ProtoMessage {

    public static func protoMessageTypeURL() -> String {
        return "type.googleapis.com/RedactedLargeMessage"
    }

}

extension RedactedLargeMessage.Storage : Proto2Codable {

    public init(from protoReader: ProtoReader) throws {
        var a: String? = nil
        var b: String? = nil
        var c: String? = nil
        var d: String? = nil
        var e: String? = nil
        var f: String? = nil
        var g: String? = nil
        var h: String? = nil
        var i: String? = nil
        var j: String? = nil
        var k: String? = nil
        var l: String? = nil
        var m: String? = nil
        var n: String? = nil
        var o: String? = nil
        var p: String? = nil
        var q: String? = nil
        var r: String? = nil
        var s: String? = nil
        var t: String? = nil
        var u: String? = nil
        var v: String? = nil
        var w: String? = nil
        var x: String? = nil
        var y: String? = nil
        var z: String? = nil
        var description_: String? = nil

        let token = try protoReader.beginMessage()
        while let tag = try protoReader.nextTag(token: token) {
            switch tag {
            case 1: a = try protoReader.decode(String.self)
            case 2: b = try protoReader.decode(String.self)
            case 3: c = try protoReader.decode(String.self)
            case 4: d = try protoReader.decode(String.self)
            case 5: e = try protoReader.decode(String.self)
            case 6: f = try protoReader.decode(String.self)
            case 7: g = try protoReader.decode(String.self)
            case 8: h = try protoReader.decode(String.self)
            case 9: i = try protoReader.decode(String.self)
            case 10: j = try protoReader.decode(String.self)
            case 11: k = try protoReader.decode(String.self)
            case 12: l = try protoReader.decode(String.self)
            case 13: m = try protoReader.decode(String.self)
            case 14: n = try protoReader.decode(String.self)
            case 15: o = try protoReader.decode(String.self)
            case 16: p = try protoReader.decode(String.self)
            case 17: q = try protoReader.decode(String.self)
            case 18: r = try protoReader.decode(String.self)
            case 19: s = try protoReader.decode(String.self)
            case 20: t = try protoReader.decode(String.self)
            case 21: u = try protoReader.decode(String.self)
            case 22: v = try protoReader.decode(String.self)
            case 23: w = try protoReader.decode(String.self)
            case 24: x = try protoReader.decode(String.self)
            case 25: y = try protoReader.decode(String.self)
            case 26: z = try protoReader.decode(String.self)
            case 27: description_ = try protoReader.decode(String.self)
            default: try protoReader.readUnknownField(tag: tag)
            }
        }
        self.unknownFields = try protoReader.endMessage(token: token)

        self._a.wrappedValue = a
        self._b.wrappedValue = b
        self._c.wrappedValue = c
        self._d.wrappedValue = d
        self._e.wrappedValue = e
        self._f.wrappedValue = f
        self._g.wrappedValue = g
        self._h.wrappedValue = h
        self._i.wrappedValue = i
        self._j.wrappedValue = j
        self._k.wrappedValue = k
        self._l.wrappedValue = l
        self._m.wrappedValue = m
        self._n.wrappedValue = n
        self._o.wrappedValue = o
        self._p.wrappedValue = p
        self._q.wrappedValue = q
        self._r.wrappedValue = r
        self._s.wrappedValue = s
        self._t.wrappedValue = t
        self._u.wrappedValue = u
        self._v.wrappedValue = v
        self._w.wrappedValue = w
        self._x.wrappedValue = x
        self._y.wrappedValue = y
        self._z.wrappedValue = z
        self._description_.wrappedValue = description_
    }

    public func encode(to protoWriter: ProtoWriter) throws {
        try protoWriter.encode(tag: 1, value: self.a)
        try protoWriter.encode(tag: 2, value: self.b)
        try protoWriter.encode(tag: 3, value: self.c)
        try protoWriter.encode(tag: 4, value: self.d)
        try protoWriter.encode(tag: 5, value: self.e)
        try protoWriter.encode(tag: 6, value: self.f)
        try protoWriter.encode(tag: 7, value: self.g)
        try protoWriter.encode(tag: 8, value: self.h)
        try protoWriter.encode(tag: 9, value: self.i)
        try protoWriter.encode(tag: 10, value: self.j)
        try protoWriter.encode(tag: 11, value: self.k)
        try protoWriter.encode(tag: 12, value: self.l)
        try protoWriter.encode(tag: 13, value: self.m)
        try protoWriter.encode(tag: 14, value: self.n)
        try protoWriter.encode(tag: 15, value: self.o)
        try protoWriter.encode(tag: 16, value: self.p)
        try protoWriter.encode(tag: 17, value: self.q)
        try protoWriter.encode(tag: 18, value: self.r)
        try protoWriter.encode(tag: 19, value: self.s)
        try protoWriter.encode(tag: 20, value: self.t)
        try protoWriter.encode(tag: 21, value: self.u)
        try protoWriter.encode(tag: 22, value: self.v)
        try protoWriter.encode(tag: 23, value: self.w)
        try protoWriter.encode(tag: 24, value: self.x)
        try protoWriter.encode(tag: 25, value: self.y)
        try protoWriter.encode(tag: 26, value: self.z)
        try protoWriter.encode(tag: 27, value: self.description_)
        try protoWriter.writeUnknownFields(unknownFields)
    }

}

#if !WIRE_REMOVE_CODABLE
extension RedactedLargeMessage.Storage : Codable {

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: StringLiteralCodingKeys.self)
        self._a.wrappedValue = try container.decodeIfPresent(String.self, forKey: "a")
        self._b.wrappedValue = try container.decodeIfPresent(String.self, forKey: "b")
        self._c.wrappedValue = try container.decodeIfPresent(String.self, forKey: "c")
        self._d.wrappedValue = try container.decodeIfPresent(String.self, forKey: "d")
        self._e.wrappedValue = try container.decodeIfPresent(String.self, forKey: "e")
        self._f.wrappedValue = try container.decodeIfPresent(String.self, forKey: "f")
        self._g.wrappedValue = try container.decodeIfPresent(String.self, forKey: "g")
        self._h.wrappedValue = try container.decodeIfPresent(String.self, forKey: "h")
        self._i.wrappedValue = try container.decodeIfPresent(String.self, forKey: "i")
        self._j.wrappedValue = try container.decodeIfPresent(String.self, forKey: "j")
        self._k.wrappedValue = try container.decodeIfPresent(String.self, forKey: "k")
        self._l.wrappedValue = try container.decodeIfPresent(String.self, forKey: "l")
        self._m.wrappedValue = try container.decodeIfPresent(String.self, forKey: "m")
        self._n.wrappedValue = try container.decodeIfPresent(String.self, forKey: "n")
        self._o.wrappedValue = try container.decodeIfPresent(String.self, forKey: "o")
        self._p.wrappedValue = try container.decodeIfPresent(String.self, forKey: "p")
        self._q.wrappedValue = try container.decodeIfPresent(String.self, forKey: "q")
        self._r.wrappedValue = try container.decodeIfPresent(String.self, forKey: "r")
        self._s.wrappedValue = try container.decodeIfPresent(String.self, forKey: "s")
        self._t.wrappedValue = try container.decodeIfPresent(String.self, forKey: "t")
        self._u.wrappedValue = try container.decodeIfPresent(String.self, forKey: "u")
        self._v.wrappedValue = try container.decodeIfPresent(String.self, forKey: "v")
        self._w.wrappedValue = try container.decodeIfPresent(String.self, forKey: "w")
        self._x.wrappedValue = try container.decodeIfPresent(String.self, forKey: "x")
        self._y.wrappedValue = try container.decodeIfPresent(String.self, forKey: "y")
        self._z.wrappedValue = try container.decodeIfPresent(String.self, forKey: "z")
        self._description_.wrappedValue = try container.decodeIfPresent(String.self, forKey: "description")
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: StringLiteralCodingKeys.self)

        try container.encodeIfPresent(self.a, forKey: "a")
        try container.encodeIfPresent(self.b, forKey: "b")
        try container.encodeIfPresent(self.c, forKey: "c")
        try container.encodeIfPresent(self.d, forKey: "d")
        try container.encodeIfPresent(self.e, forKey: "e")
        try container.encodeIfPresent(self.f, forKey: "f")
        try container.encodeIfPresent(self.g, forKey: "g")
        try container.encodeIfPresent(self.h, forKey: "h")
        try container.encodeIfPresent(self.i, forKey: "i")
        try container.encodeIfPresent(self.j, forKey: "j")
        try container.encodeIfPresent(self.k, forKey: "k")
        try container.encodeIfPresent(self.l, forKey: "l")
        try container.encodeIfPresent(self.m, forKey: "m")
        try container.encodeIfPresent(self.n, forKey: "n")
        try container.encodeIfPresent(self.o, forKey: "o")
        try container.encodeIfPresent(self.p, forKey: "p")
        try container.encodeIfPresent(self.q, forKey: "q")
        try container.encodeIfPresent(self.r, forKey: "r")
        try container.encodeIfPresent(self.s, forKey: "s")
        try container.encodeIfPresent(self.t, forKey: "t")
        try container.encodeIfPresent(self.u, forKey: "u")
        try container.encodeIfPresent(self.v, forKey: "v")
        try container.encodeIfPresent(self.w, forKey: "w")
        try container.encodeIfPresent(self.x, forKey: "x")
        try container.encodeIfPresent(self.y, forKey: "y")
        try container.encodeIfPresent(self.z, forKey: "z")
        try container.encodeIfPresent(self.description_, forKey: "description")
    }

}
#endif

@dnkoutso dnkoutso requested a review from lickel January 3, 2024 17:11
@dnkoutso dnkoutso changed the title Fix edge case for heap based messages using a redacted description field [swift] Fix edge case for heap based messages using a redacted description field Jan 3, 2024
@dnkoutso dnkoutso force-pushed the description_bug branch 2 times, most recently from 5919388 to a4afa43 Compare January 4, 2024 08:18

func testLargeMessageRedactedUnsafeNameField() {
let redacted = RedactedLargeMessage {
$0.description_ = "foo"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add Codable tests around description_, which should use the JSON key of "description"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@dnkoutso dnkoutso merged commit a7a68dc into master Jan 9, 2024
7 checks passed
@dnkoutso dnkoutso deleted the description_bug branch January 9, 2024 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants