重叠访问“结果”,但修改需要独占访问;考虑复制到xcode 10中的局部变量

时间:2018-06-07 07:39:38

标签: ios swift

open static func PBKDF2(_ password: String, salt: Data,
                                 prf: PRFAlg, rounds: UInt32) throws -> Data {

            var result = Data(count:prf.cc.digestLength)
            let passwData = password.data(using: String.Encoding.utf8)!
            let status = result.withUnsafeMutableBytes {
                (passwDataBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
                return CCKeyDerivationPBKDF!(PBKDFAlgorithm.pbkdf2.rawValue,
                                             (passwData as NSData).bytes, passwData.count,
                                             (salt as NSData).bytes, salt.count,
                                             prf.rawValue, rounds,
                                             passwDataBytes, result.count)
            }
            guard status == noErr else { throw CCError(status) }

            return result
        }

result.withUnsafeMutableBytes在Xcode 10中给出错误,在Xcode 9中它是一个警告。

1 个答案:

答案 0 :(得分:16)

这是SE-0176 Enforce Exclusive Access to Memory的结果,它是在Swift 4中实现的 并且在Swift 4.2中更严格。

解决方案是将计数分配给单独的变量:

let count = result.count
let status = result.withUnsafeMutableBytes {
    (passwDataBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
        return CCKeyDerivationPBKDF(..., count)
}

或捕获捕获列表中的计数:

let status = result.withUnsafeMutableBytes { [ count = result.count ]
    (passwDataBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
        return CCKeyDerivationPBKDF(..., count)
}

另请参阅Swift论坛中的Overlapping access warning in withUnsafeMutableBytes

  

hamishknight

     

withUnsafeMutableBytes(_ :)是Data上的一种变异方法,因此它需要在调用期间对数据进行写访问。通过访问闭包中的data.count,您将开始一个与当前写访问冲突的新数据读取。

     

Joe_Groff

     

您还可以在闭包的捕获列表中捕获数据副本或其计数:...

     

在独占访问开始之前,对闭包形成时的值进行评估,并按值捕获结果,避免重叠访问。

this comment in 相应的拉取请求:

  

这里适当的解决方法是复制闭包外部的缓冲区计数,并将其传递给inet_ntop()。