Skip to content

Commit 7a65720

Browse files
committed
tar: Do not use String(format:) in octal6/11
String(format:) sometimes returns an empty string even if the number being formatted can be represented in an octal string of the requested length. This may be a thread-safety problem and has only been seen when running the tests. swiftlang/swift-corelibs-foundation#5152 This commit changes octal6/11 to use String(value, radix:) and handle padding directly. This has not failed during hundreds of test runs. Benchmarking the old and new implementations of octal6() shows that the new version also is about twice as fast as the old one and makes no allocations, whereas the old version made 7 allocations.
1 parent 2de7109 commit 7a65720

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

Sources/Tar/tar.swift

+11-3
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,24 @@ extension [UInt8] {
7272
func octal6(_ value: Int) -> String {
7373
precondition(value >= 0)
7474
precondition(value < 0o777777)
75-
return String(format: "%06o", value)
75+
// String(format: "%06o", value) cannot be used because of a race in Foundation
76+
// which causes it to return an empty string from time to time when running the tests
77+
// in parallel using swift-testing: https://github.com/swiftlang/swift-corelibs-foundation/issues/5152
78+
let str = String(value, radix: 8)
79+
return String(repeating: "0", count: 6 - str.count).appending(str)
7680
}
7781

78-
/// Serializes an integer to a 11 character octal representation.
82+
/// Serializes an integer to an 11 character octal representation.
7983
/// - Parameter value: The integer to serialize.
8084
/// - Returns: The serialized form of `value`.
8185
func octal11(_ value: Int) -> String {
8286
precondition(value >= 0)
8387
precondition(value < 0o777_7777_7777)
84-
return String(format: "%011o", value)
88+
// String(format: "%011o", value) cannot be used because of a race in Foundation
89+
// which causes it to return an empty string from time to time when running the tests
90+
// in parallel using swift-testing: https://github.com/swiftlang/swift-corelibs-foundation/issues/5152
91+
let str = String(value, radix: 8)
92+
return String(repeating: "0", count: 11 - str.count).appending(str)
8593
}
8694

8795
// These ranges define the offsets of the standard fields in a Tar header.

0 commit comments

Comments
 (0)