Skip to content

Commit

Permalink
tar: Do not use String(format:) in octal6/11
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
euanh committed Jan 6, 2025
1 parent 2de7109 commit 07cbd91
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions Sources/Tar/tar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,25 @@ extension [UInt8] {
func octal6(_ value: Int) -> String {
precondition(value >= 0)
precondition(value < 0o777777)
return String(format: "%06o", value)
# String(format: "%06o", value) cannot be used because of a race in Foundation
# which causes it to return an empty string from time to time when running the tests
# in parallel using swift-testing:
let str = String(value, radix: 8)
return String(repeating: "0", count: 6 - str.count).appending(str)
}

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

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

0 comments on commit 07cbd91

Please sign in to comment.