-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Labels
bugSomething isn't workingSomething isn't working
Milestone
Description
Severity: 🔴 Critical
File: Sources/BushelUtilities/Extensions/Date+RFC2822.swift:43
PR: #126
Issue
The shared static DateFormatter can cause race conditions when date(from:) is called concurrently from multiple threads. DateFormatter has internal mutable state that is not thread-safe, which is particularly problematic for HTTP header parsing where concurrent requests are common.
Current Code
extension Date {
private static let rfc2822Formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}()
public init?(rfc2822String: String) {
guard let date = Self.rfc2822Formatter.date(from: rfc2822String) else {
return nil
}
self = date
}
}Recommended Solutions
Option 1: Create a new formatter instance per call (simplest)
extension Date {
private static func makeRFC2822Formatter() -> DateFormatter {
let formatter = DateFormatter()
formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}
public init?(rfc2822String: String) {
guard let date = Self.makeRFC2822Formatter().date(from: rfc2822String) else {
return nil
}
self = date
}
}Option 2: Use a lock for thread-safe access (better performance)
extension Date {
private static let formatterLock = NSLock()
private static let rfc2822Formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}()
public init?(rfc2822String: String) {
formatterLock.lock()
defer { formatterLock.unlock() }
guard let date = Self.rfc2822Formatter.date(from: rfc2822String) else {
return nil
}
self = date
}
}Impact
This is a critical issue that can cause:
- Race conditions in production
- Unpredictable parsing failures
- Data corruption
- Crashes in concurrent scenarios
Source: CodeRabbit AI review of PR #126
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working