Skip to content

Commit 39b909c

Browse files
committed
Merge branch 'main' into readdle-main
# Conflicts: # Sources/FoundationNetworking/URLProtectionSpace.swift # Sources/FoundationNetworking/URLSession/HTTP/HTTPMessage.swift # Sources/FoundationNetworking/URLSession/Message.swift # Sources/FoundationNetworking/URLSession/URLSessionTask.swift # Tests/Foundation/Tests/TestURLProtectionSpace.swift
2 parents 1ded37f + b1ed91d commit 39b909c

File tree

9 files changed

+162
-30
lines changed

9 files changed

+162
-30
lines changed

Sources/Foundation/Decimal.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ extension Decimal : Hashable, Comparable {
161161

162162
// The low 64 bits of the integer part. (Used by uint64Value and int64Value.)
163163
private var _unsignedInt64Value: UInt64 {
164-
if _exponent < -20 || _exponent > 20 {
164+
// Quick check if number if has too many zeros before decimal point or too many trailing zeros after decimal point.
165+
// Log10 (2^64) ~ 19, log10 (2^128) ~ 38
166+
if _exponent < -38 || _exponent > 20 {
165167
return 0
166168
}
167169
if _length == 0 || isZero || magnitude < (0 as Decimal) {

Sources/Foundation/NSPathUtilities.swift

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -760,17 +760,34 @@ internal func _NSCreateTemporaryFile(_ filePath: String) throws -> (Int32, Strin
760760
// Don't close h, fd is transferred ownership
761761
let fd = _open_osfhandle(intptr_t(bitPattern: h), 0)
762762
#else
763-
let maxLength = Int(PATH_MAX) + 1
764-
var buf = [Int8](repeating: 0, count: maxLength)
765-
let _ = template._nsObject.getFileSystemRepresentation(&buf, maxLength: maxLength)
766-
guard let name = mktemp(&buf) else {
767-
throw _NSErrorWithErrno(errno, reading: false, path: filePath)
763+
var filename = template.utf8CString
764+
765+
let result = filename.withUnsafeMutableBufferPointer { (ptr: inout UnsafeMutableBufferPointer<CChar>) -> (Int32, String)? in
766+
// filename is updated with the temp file name on success.
767+
let fd = mkstemp(ptr.baseAddress!)
768+
if fd == -1 {
769+
return nil
770+
} else {
771+
guard let fname = String(utf8String: ptr.baseAddress!) else {
772+
// Couldnt convert buffer back to filename.
773+
close(fd)
774+
errno = ENOENT
775+
return nil
776+
}
777+
return (fd, fname)
778+
}
779+
}
780+
781+
guard let (fd, pathResult) = result else {
782+
throw _NSErrorWithErrno(errno, reading: false, path: template)
768783
}
769-
let fd = open(name, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
770-
if fd == -1 {
771-
throw _NSErrorWithErrno(errno, reading: false, path: filePath)
784+
785+
// Set the file mode to match macOS
786+
guard fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) != -1 else {
787+
let _errno = errno
788+
close(fd)
789+
throw _NSErrorWithErrno(_errno, reading: false, path: pathResult)
772790
}
773-
let pathResult = FileManager.default.string(withFileSystemRepresentation: buf, length: Int(strlen(buf)))
774791
#endif
775792
return (fd, pathResult)
776793
}

Sources/Foundation/Process.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -944,11 +944,17 @@ open class Process: NSObject {
944944
try _throwIfPosixError(_CFPosixSpawnFileActionsAddClose(fileActions, fd))
945945
}
946946

947-
#if canImport(Darwin)
947+
#if canImport(Darwin)
948948
var spawnAttrs: posix_spawnattr_t? = nil
949949
try _throwIfPosixError(posix_spawnattr_init(&spawnAttrs))
950+
try _throwIfPosixError(posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_SETPGROUP)))
950951
try _throwIfPosixError(posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_CLOEXEC_DEFAULT)))
951-
#else
952+
#else
953+
var spawnAttrs: posix_spawnattr_t = posix_spawnattr_t()
954+
try _throwIfPosixError(posix_spawnattr_init(&spawnAttrs))
955+
try _throwIfPosixError(posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_SETPGROUP)))
956+
957+
// POSIX_SPAWN_CLOEXEC_DEFAULT is an Apple extension so emulate it.
952958
for fd in 3 ... findMaximumOpenFD() {
953959
guard adddup2[fd] == nil &&
954960
!addclose.contains(fd) &&
@@ -957,7 +963,7 @@ open class Process: NSObject {
957963
}
958964
try _throwIfPosixError(_CFPosixSpawnFileActionsAddClose(fileActions, fd))
959965
}
960-
#endif
966+
#endif
961967

962968
let fileManager = FileManager()
963969
let previousDirectoryPath = fileManager.currentDirectoryPath
@@ -972,16 +978,10 @@ open class Process: NSObject {
972978

973979
// Launch
974980
var pid = pid_t()
975-
#if os(macOS)
976981
guard _CFPosixSpawn(&pid, launchPath, fileActions, &spawnAttrs, argv, envp) == 0 else {
977982
throw _NSErrorWithErrno(errno, reading: true, path: launchPath)
978983
}
979-
#else
980-
guard _CFPosixSpawn(&pid, launchPath, fileActions, nil, argv, envp) == 0 else {
981-
throw _NSErrorWithErrno(errno, reading: true, path: launchPath)
982-
}
983-
#endif
984-
984+
posix_spawnattr_destroy(&spawnAttrs)
985985

986986
// Close the write end of the input and output pipes.
987987
if let pipe = standardInput as? Pipe {

Sources/FoundationNetworking/URLSession/HTTP/HTTPMessage.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ private extension _HTTPURLProtocol._HTTPMessage._Challenge._AuthParameter {
305305
private static func parameterValue(from valueView: inout String.UnicodeScalarView.SubSequence) -> String? {
306306
// Trim BWS
307307
valueView = valueView.trimSPHTPrefix ?? valueView
308-
if valueView.first == _Delimiters.Dquote {
308+
if valueView.first == _Delimiters.DoubleQuote {
309309
// quoted-string
310310
if let valueRange = valueView.rangeOfQuotedStringPrefix {
311311
let value = valueView[valueRange].dequotedString()
@@ -506,7 +506,7 @@ private extension String.UnicodeScalarView.SubSequence {
506506
}
507507
var idx = startIndex
508508
// Expect and consume dquote
509-
guard self[idx] == _Delimiters.Dquote else {
509+
guard self[idx] == _Delimiters.DoubleQuote else {
510510
return nil
511511
}
512512
idx = self.index(after: idx)
@@ -520,7 +520,7 @@ private extension String.UnicodeScalarView.SubSequence {
520520
return nil
521521
}
522522
isQuotedPair = false
523-
} else if currentScalar == _Delimiters.Dquote {
523+
} else if currentScalar == _Delimiters.DoubleQuote {
524524
break
525525
} else {
526526
guard currentScalar.isQdtext else {
@@ -530,7 +530,7 @@ private extension String.UnicodeScalarView.SubSequence {
530530
idx = self.index(after: idx)
531531
}
532532
// Expect stop on dquote
533-
guard idx < endIndex, self[idx] == _Delimiters.Dquote else {
533+
guard idx < endIndex, self[idx] == _Delimiters.DoubleQuote else {
534534
return nil
535535
}
536536
return startIndex..<self.index(after: idx)
@@ -546,7 +546,7 @@ private extension String.UnicodeScalarView.SubSequence {
546546
resultView.reserveCapacity(self.count)
547547
var idx = startIndex
548548
// Expect and consume dquote
549-
guard self[idx] == _Delimiters.Dquote else {
549+
guard self[idx] == _Delimiters.DoubleQuote else {
550550
return nil
551551
}
552552
idx = self.index(after: idx)
@@ -561,7 +561,7 @@ private extension String.UnicodeScalarView.SubSequence {
561561
}
562562
isQuotedPair = false
563563
resultView.append(currentScalar)
564-
} else if currentScalar == _Delimiters.Dquote {
564+
} else if currentScalar == _Delimiters.DoubleQuote {
565565
break
566566
} else {
567567
guard currentScalar.isQdtext else {
@@ -572,7 +572,7 @@ private extension String.UnicodeScalarView.SubSequence {
572572
idx = self.index(after: idx)
573573
}
574574
// Expect stop on dquote
575-
guard idx < endIndex, self[idx] == _Delimiters.Dquote else {
575+
guard idx < endIndex, self[idx] == _Delimiters.DoubleQuote else {
576576
return nil
577577
}
578578
return String(resultView)

Sources/FoundationNetworking/URLSession/Message.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ struct _Delimiters {
113113
static let Colon = UnicodeScalar(0x3a)
114114
static let Backslash = UnicodeScalar(0x5c)!
115115
static let Comma = UnicodeScalar(0x2c)!
116-
static let Dquote = UnicodeScalar(0x22)!
116+
static let DoubleQuote = UnicodeScalar(0x22)!
117117
static let Equals = UnicodeScalar(0x3d)!
118118
/// *Separators* according to RFC 2616
119119
static let Separators = NSCharacterSet(charactersIn: "()<>@,;:\\\"/[]?={} \t")

Sources/FoundationNetworking/URLSession/URLSessionTask.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,8 +1071,7 @@ extension URLSessionTask {
10711071
static func authHandler(for authScheme: String) -> _AuthHandler? {
10721072
let handlers: [String : _AuthHandler] = [
10731073
NSURLAuthenticationMethodHTTPBasic : basicAuth,
1074-
NSURLAuthenticationMethodHTTPDigest: digestAuth,
1075-
NSURLAuthenticationMethodNTLM : ntlmAuth,
1074+
NSURLAuthenticationMethodHTTPDigest: digestAuth
10761075
]
10771076
return handlers[authScheme]
10781077
}

Tests/Foundation/Tests/TestDecimal.swift

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,83 @@ class TestDecimal: XCTestCase {
12801280
}
12811281
}
12821282

1283+
func test_intValue() {
1284+
// SR-7236
1285+
XCTAssertEqual(NSDecimalNumber(value: -1).intValue, -1)
1286+
XCTAssertEqual(NSDecimalNumber(value: 0).intValue, 0)
1287+
XCTAssertEqual(NSDecimalNumber(value: 1).intValue, 1)
1288+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal.nan).intValue, 0)
1289+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(1e50)).intValue, 0)
1290+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(1e-50)).intValue, 0)
1291+
1292+
XCTAssertEqual(NSDecimalNumber(value: UInt64.max).uint64Value, UInt64.max)
1293+
XCTAssertEqual(NSDecimalNumber(value: UInt64.max).adding(1).uint64Value, 0)
1294+
XCTAssertEqual(NSDecimalNumber(value: Int64.max).int64Value, Int64.max)
1295+
XCTAssertEqual(NSDecimalNumber(value: Int64.max).adding(1).int64Value, Int64.min)
1296+
XCTAssertEqual(NSDecimalNumber(value: Int64.max).adding(1).uint64Value, UInt64(Int64.max) + 1)
1297+
XCTAssertEqual(NSDecimalNumber(value: Int64.min).int64Value, Int64.min)
1298+
1299+
XCTAssertEqual(NSDecimalNumber(value: 10).dividing(by: 3).intValue, 3)
1300+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Double.pi)).intValue, 3)
1301+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int.max)).intValue, Int.max)
1302+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int32.max)).int32Value, Int32.max)
1303+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int64.max)).int64Value, Int64.max)
1304+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int.min)).intValue, Int.min)
1305+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int32.min)).int32Value, Int32.min)
1306+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int64.min)).int64Value, Int64.min)
1307+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(UInt.max)).uintValue, UInt.max)
1308+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(UInt32.max)).uint32Value, UInt32.max)
1309+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(UInt64.max)).uint64Value, UInt64.max)
1310+
1311+
1312+
// SR-2980
1313+
let sr2980Tests = [
1314+
("250.229953885078403", 250),
1315+
("103.8097165991902834008097165991902834", 103),
1316+
("31.541176470588235294", 31),
1317+
("12345.12345678901234", 12345),
1318+
("12345.123456789012345", 12345),
1319+
]
1320+
1321+
for (string, value) in sr2980Tests {
1322+
let decimalValue = NSDecimalNumber(string: string)
1323+
XCTAssertEqual(decimalValue.intValue, value)
1324+
XCTAssertEqual(decimalValue.int8Value, Int8(truncatingIfNeeded: value))
1325+
XCTAssertEqual(decimalValue.int16Value, Int16(value))
1326+
XCTAssertEqual(decimalValue.int32Value, Int32(value))
1327+
XCTAssertEqual(decimalValue.int64Value, Int64(value))
1328+
XCTAssertEqual(decimalValue.uintValue, UInt(value))
1329+
XCTAssertEqual(decimalValue.uint8Value, UInt8(truncatingIfNeeded: value))
1330+
XCTAssertEqual(decimalValue.uint16Value, UInt16(value))
1331+
XCTAssertEqual(decimalValue.uint32Value, UInt32(value))
1332+
XCTAssertEqual(decimalValue.uint64Value, UInt64(value))
1333+
}
1334+
1335+
// Large mantissas, negative exponent
1336+
let maxMantissa = (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max)
1337+
1338+
let tests = [
1339+
(-34, 0, "34028.2366920938463463374607431768211455", 34028),
1340+
(-35, 0, "3402.82366920938463463374607431768211455", 3402),
1341+
(-36, 0, "340.282366920938463463374607431768211455", 340),
1342+
(-37, 0, "34.0282366920938463463374607431768211455", 34),
1343+
(-38, 0, "3.40282366920938463463374607431768211455", 3),
1344+
(-39, 0, "0.340282366920938463463374607431768211455", 0),
1345+
(-34, 1, "-34028.2366920938463463374607431768211455", -34028),
1346+
(-35, 1, "-3402.82366920938463463374607431768211455", -3402),
1347+
(-36, 1, "-340.282366920938463463374607431768211455", -340),
1348+
(-37, 1, "-34.0282366920938463463374607431768211455", -34),
1349+
(-38, 1, "-3.40282366920938463463374607431768211455", -3),
1350+
(-39, 1, "-0.340282366920938463463374607431768211455", 0),
1351+
]
1352+
1353+
for (exponent, isNegative, description, intValue) in tests {
1354+
let d = Decimal(_exponent: Int32(exponent), _length: 8, _isNegative: UInt32(isNegative), _isCompact: 1, _reserved: 0, _mantissa: maxMantissa)
1355+
XCTAssertEqual(d.description, description)
1356+
XCTAssertEqual(NSDecimalNumber(decimal:d).intValue, intValue)
1357+
}
1358+
}
1359+
12831360
static var allTests : [(String, (TestDecimal) -> () throws -> Void)] {
12841361
return [
12851362
("test_NSDecimalNumberInit", test_NSDecimalNumberInit),
@@ -1310,6 +1387,7 @@ class TestDecimal: XCTestCase {
13101387
("test_multiplyingByPowerOf10", test_multiplyingByPowerOf10),
13111388
("test_initExactly", test_initExactly),
13121389
("test_NSNumberEquality", test_NSNumberEquality),
1390+
("test_intValue", test_intValue),
13131391
]
13141392
}
13151393
}

Tests/Foundation/Tests/TestProcess.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,37 @@ class TestProcess : XCTestCase {
806806
}
807807
}
808808

809+
#if !os(Windows)
810+
func test_processGroup() throws {
811+
// The process group of the child process should be different to the parent's.
812+
let process = Process()
813+
814+
process.executableURL = xdgTestHelperURL()
815+
process.arguments = ["--pgrp"]
816+
let pipe = Pipe()
817+
process.standardOutput = pipe
818+
process.standardError = nil
819+
820+
try process.run()
821+
process.waitUntilExit()
822+
XCTAssertEqual(process.terminationStatus, 0)
823+
824+
let data = pipe.fileHandleForReading.availableData
825+
guard let string = String(data: data, encoding: .ascii) else {
826+
XCTFail("Could not read stdout")
827+
return
828+
}
829+
830+
let parts = string.trimmingCharacters(in: .newlines).components(separatedBy: ": ")
831+
guard parts.count == 2, parts[0] == "pgrp", let childPgrp = Int(parts[1]) else {
832+
XCTFail("Could not pgrp fron stdout")
833+
return
834+
}
835+
let parentPgrp = Int(getpgrp())
836+
XCTAssertNotEqual(parentPgrp, childPgrp, "Child process group \(parentPgrp) should not equal parent process group \(childPgrp)")
837+
}
838+
#endif
839+
809840
static var allTests: [(String, (TestProcess) -> () throws -> Void)] {
810841
var tests = [
811842
("test_exit0" , test_exit0),
@@ -843,6 +874,7 @@ class TestProcess : XCTestCase {
843874
("test_interrupt", test_interrupt),
844875
("test_suspend_resume", test_suspend_resume),
845876
("test_fileDescriptorsAreNotInherited", test_fileDescriptorsAreNotInherited),
877+
("test_processGroup", test_processGroup),
846878
]
847879
#endif
848880
return tests

Tests/Tools/XDGTestHelper/main.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ case "--signal-test":
274274

275275
case "--print-open-file-descriptors":
276276
printOpenFileDescriptors()
277+
278+
case "--pgrp":
279+
print("pgrp: \(getpgrp())")
280+
277281
#endif
278282

279283
default:

0 commit comments

Comments
 (0)