<commit_before>//
//  SecItem.swift
//  Valet
//
//  Created by <NAME> and <NAME> on 9/16/17.
//  Copyright © 2017 Square, Inc.
//
//
//  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 Foundation


internal func execute<ReturnType>(in lock: NSLock, block: () -> ReturnType) -> ReturnType {
    lock.lock()
    defer {
        lock.unlock()
    }
    return block()
}


internal final class SecItem {
    
    // MARK: Internal Enum
    
    internal enum DataResult<SuccessType, FailureType> {
        case success(SuccessType)
        case error(FailureType)
    }
    
    internal enum Result<FailureType> {
        case success
        case error(FailureType)
    }
    
    // MARK: Internal Class Properties
    
    internal static var sharedAccessGroupPrefix: String? {
        let query = [
            kSecClass : kSecClassGenericPassword,
            kSecAttrAccount : "SharedAccessGroupAlwaysAccessiblePrefixPlaceholder",
            kSecReturnAttributes : true,
            kSecAttrAccessible : Accessibility.alwaysThisDeviceOnly.secAccessibilityAttribute
            ] as CFDictionary
        
        secItemLock.lock()
        defer {
            secItemLock.unlock()
        }
        
        var result: AnyObject? = nil
        var status = SecItemCopyMatching(query, &result)
        
        if status == errSecItemNotFound {
            status = SecItemAdd(query, &result)
        }
        
        guard status == errSecSuccess else {
            ErrorHandler.assertionFailure("Could not find shared access group prefix.")
            return nil
        }
        
        let queryResult = result as! [CFString : AnyHashable]
        guard let accessGroup = queryResult[kSecAttrAccessGroup] as? String else {
            ErrorHandler.assertionFailure("Could not find shared access group prefix.")
            return nil
        }
        
        let components = accessGroup.components(separatedBy: ".")
        let bundleSeedIdentifier = components.first
        
        return Identifier(nonEmpty: bundleSeedIdentifier)?.description
    }
    
    // MARK: Internal Class Methods
    
    internal static func copy<DesiredType>(matching query: [String : AnyHashable]) -> DataResult<DesiredType, OSStatus> {
        guard query.count > 0 else {
            ErrorHandler.assertionFailure("Must provide a query with at least one item")
            return .error(errSecParam)<commit_msg>Avoid force casting when finding the shared access group prefix to prevent crashing when the keychain is in a bad state<commit_after>//
//  SecItem.swift
//  Valet
//
//  Created by <NAME> and <NAME> on 9/16/17.
//  Copyright © 2017 Square, Inc.
//
//
//  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 Foundation


internal func execute<ReturnType>(in lock: NSLock, block: () -> ReturnType) -> ReturnType {
    lock.lock()
    defer {
        lock.unlock()
    }
    return block()
}


internal final class SecItem {
    
    // MARK: Internal Enum
    
    internal enum DataResult<SuccessType, FailureType> {
        case success(SuccessType)
        case error(FailureType)
    }
    
    internal enum Result<FailureType> {
        case success
        case error(FailureType)
    }
    
    // MARK: Internal Class Properties
    
    internal static var sharedAccessGroupPrefix: String? {
        let query = [
            kSecClass : kSecClassGenericPassword,
            kSecAttrAccount : "SharedAccessGroupAlwaysAccessiblePrefixPlaceholder",
            kSecReturnAttributes : true,
            kSecAttrAccessible : Accessibility.alwaysThisDeviceOnly.secAccessibilityAttribute
            ] as CFDictionary
        
        secItemLock.lock()
        defer {
            secItemLock.unlock()
        }
        
        var result: AnyObject? = nil
        var status = SecItemCopyMatching(query, &result)
        
        if status == errSecItemNotFound {
            status = SecItemAdd(query, &result)
        }
        
        guard status == errSecSuccess, let queryResult = result as? [CFString : AnyHashable], let accessGroup = queryResult[kSecAttrAccessGroup] as? String else {
            ErrorHandler.assertionFailure("Could not find shared access group prefix.")
            return nil
        }
        
        let components = accessGroup.components(separatedBy: ".")
        let bundleSeedIdentifier = components.first
        
        return Identifier(nonEmpty: bundleSeedIdentifier)?.description
    }
    
    // MARK: Internal Class Methods
    
    internal static func copy<DesiredType>(matching query: [String : AnyHashable]) -> DataResult<DesiredType, OSStatus> {
        guard query.count > 0 else {
            ErrorHandler.assertionFailure("Must provide a query with at least one item")
            return .error(errSecParam)
{'fraction_non_alphanumeric': 0.0807698917339749, 'fraction_numerical': 0.004811823337343186, 'mean_word_length': 2.3467510063254746, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3922630', 'n_tokens_mistral': 1526, 'n_tokens_neox': 1479, 'n_words': 488}