Skip to content

Commit 4c63b3e

Browse files
authored
Merge pull request #1615 from spevans/pr_ubuntu18_fixes_42
[4.2] Ubuntu18.04 fixes for TestURLSession
2 parents c1c3683 + a657b2e commit 4c63b3e

File tree

16 files changed

+450
-132
lines changed

16 files changed

+450
-132
lines changed

DarwinCompatibilityTests.xcodeproj/project.pbxproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
B907F36F20BB188800013CBE /* NSString-ISO-8859-1-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B907F36E20BB188800013CBE /* NSString-ISO-8859-1-data.txt */; };
11+
B917D32420B0DB9700728EE0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B917D32320B0DB9700728EE0 /* Foundation.framework */; };
12+
B917D32620B0DE2000728EE0 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = B917D32520B0DE2000728EE0 /* main.swift */; };
1013
B95788861F6FB9470003EB01 /* TestNSNumberBridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B95788851F6FB9470003EB01 /* TestNSNumberBridging.swift */; };
1114
B9C89ED21F6BF67C00087AF4 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B9C89ED11F6BF67C00087AF4 /* XCTest.framework */; };
1215
B9C89F361F6BF89C00087AF4 /* TestScanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9C89EE61F6BF88F00087AF4 /* TestScanner.swift */; };
@@ -123,6 +126,10 @@
123126
/* End PBXCopyFilesBuildPhase section */
124127

125128
/* Begin PBXFileReference section */
129+
B907F36E20BB188800013CBE /* NSString-ISO-8859-1-data.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = "NSString-ISO-8859-1-data.txt"; path = "TestFoundation/Resources/NSString-ISO-8859-1-data.txt"; sourceTree = "<group>"; };
130+
B917D31C20B0DB8B00728EE0 /* xdgTestHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = xdgTestHelper; sourceTree = BUILT_PRODUCTS_DIR; };
131+
B917D32320B0DB9700728EE0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
132+
B917D32520B0DE2000728EE0 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = main.swift; path = TestFoundation/xdgTestHelper/main.swift; sourceTree = "<group>"; };
126133
B95788851F6FB9470003EB01 /* TestNSNumberBridging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = TestNSNumberBridging.swift; path = TestFoundation/TestNSNumberBridging.swift; sourceTree = "<group>"; };
127134
B9C89EC11F6BF47D00087AF4 /* DarwinCompatibilityTests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = DarwinCompatibilityTests; sourceTree = BUILT_PRODUCTS_DIR; };
128135
B9C89ED11F6BF67C00087AF4 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
@@ -269,6 +276,7 @@
269276
B9C89FAA1F6DCAE700087AF4 /* NSString-UTF16-LE-data.txt */,
270277
B9C89FB01F6DCAE900087AF4 /* NSString-UTF32-BE-data.txt */,
271278
B9C89FA51F6DCAE500087AF4 /* NSString-UTF32-LE-data.txt */,
279+
B907F36E20BB188800013CBE /* NSString-ISO-8859-1-data.txt */,
272280
B9C89FAE1F6DCAE800087AF4 /* NSStringTestData.txt */,
273281
B9C89FB21F6DCAE900087AF4 /* NSURLTestData.plist */,
274282
B9C89FB61F6DCAEA00087AF4 /* NSXMLDocumentTestData.xml */,
@@ -467,6 +475,7 @@
467475
isa = PBXResourcesBuildPhase;
468476
buildActionMask = 2147483647;
469477
files = (
478+
B907F36F20BB188800013CBE /* NSString-ISO-8859-1-data.txt in Resources */,
470479
B9C89FBA1F6DCAEB00087AF4 /* NSString-UTF32-LE-data.txt in Resources */,
471480
B9C89FBB1F6DCAEB00087AF4 /* NSKeyedUnarchiver-EdgeInsetsTest.plist in Resources */,
472481
B9C89FBC1F6DCAEB00087AF4 /* NSKeyedUnarchiver-ConcreteValueTest.plist in Resources */,

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@
330330
9F0DD3571ECD783500F68030 /* SwiftFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B5D885D1BBC938800234F36 /* SwiftFoundation.framework */; };
331331
A058C2021E529CF100B07AA1 /* TestMassFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A058C2011E529CF100B07AA1 /* TestMassFormatter.swift */; };
332332
AE35A1861CBAC85E0042DB84 /* SwiftFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = AE35A1851CBAC85E0042DB84 /* SwiftFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
333+
B907F36B20BB07A700013CBE /* NSString-ISO-8859-1-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B907F36A20BB07A700013CBE /* NSString-ISO-8859-1-data.txt */; };
333334
B90C57BB1EEEEA5A005208AE /* TestFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525AECEB1BF2C96400D15BB0 /* TestFileManager.swift */; };
334335
B90C57BC1EEEEA5A005208AE /* TestThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E5835F31C20C9B500C81317 /* TestThread.swift */; };
335336
B910957A1EEF237800A71930 /* NSString-UTF16-LE-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B91095781EEF237800A71930 /* NSString-UTF16-LE-data.txt */; };
@@ -814,6 +815,7 @@
814815
A5A34B551C18C85D00FD972B /* TestByteCountFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestByteCountFormatter.swift; sourceTree = "<group>"; };
815816
AE35A1851CBAC85E0042DB84 /* SwiftFoundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftFoundation.h; sourceTree = "<group>"; };
816817
B167A6641ED7303F0040B09A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
818+
B907F36A20BB07A700013CBE /* NSString-ISO-8859-1-data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "NSString-ISO-8859-1-data.txt"; sourceTree = "<group>"; };
817819
B91095781EEF237800A71930 /* NSString-UTF16-LE-data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "NSString-UTF16-LE-data.txt"; sourceTree = "<group>"; };
818820
B91095791EEF237800A71930 /* NSString-UTF16-BE-data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "NSString-UTF16-BE-data.txt"; sourceTree = "<group>"; };
819821
B933A79C1F3055F600FE6846 /* NSString-UTF32-BE-data.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "NSString-UTF32-BE-data.txt"; sourceTree = "<group>"; };
@@ -1460,6 +1462,7 @@
14601462
B91095791EEF237800A71930 /* NSString-UTF16-BE-data.txt */,
14611463
B933A79C1F3055F600FE6846 /* NSString-UTF32-BE-data.txt */,
14621464
B933A79D1F3055F600FE6846 /* NSString-UTF32-LE-data.txt */,
1465+
B907F36A20BB07A700013CBE /* NSString-ISO-8859-1-data.txt */,
14631466
528776181BF27D9500CB0090 /* Test.plist */,
14641467
EA66F63B1BF1619600136161 /* NSURLTestData.plist */,
14651468
E1A3726E1C31EBFB0023AF4D /* NSXMLDocumentTestData.xml */,
@@ -2153,6 +2156,7 @@
21532156
D3E8D6D51C36AC0C00295652 /* NSKeyedUnarchiver-RectTest.plist in Resources */,
21542157
D3A597F81C3415CC00295652 /* NSKeyedUnarchiver-URLTest.plist in Resources */,
21552158
D3E8D6D31C36982700295652 /* NSKeyedUnarchiver-EdgeInsetsTest.plist in Resources */,
2159+
B907F36B20BB07A700013CBE /* NSString-ISO-8859-1-data.txt in Resources */,
21562160
D370696E1C394FBF00295652 /* NSKeyedUnarchiver-RangeTest.plist in Resources */,
21572161
D3A597F71C3415CC00295652 /* NSKeyedUnarchiver-ArrayTest.plist in Resources */,
21582162
CE19A88C1C23AA2300B4CB6A /* NSStringTestData.txt in Resources */,

Foundation/HTTPCookie.swift

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -266,54 +266,55 @@ open class HTTPCookie : NSObject {
266266
}
267267
_version = version
268268

269-
if let portString = properties[.port] as? String, _version == 1 {
270-
_portList = portString.split(separator: ",")
269+
if let portString = properties[.port] as? String {
270+
let portList = portString.split(separator: ",")
271271
.compactMap { Int(String($0)) }
272272
.map { NSNumber(value: $0) }
273+
if version == 1 {
274+
_portList = portList
275+
} else {
276+
// Version 0 only stores a single port number
277+
_portList = portList.count > 0 ? [portList[0]] : nil
278+
}
273279
} else {
274280
_portList = nil
275281
}
276282

277-
// TODO: factor into a utility function
278-
if version == 0 {
283+
var expDate: Date? = nil
284+
// Maximum-Age is prefered over expires-Date but only version 1 cookies use Maximum-Age
285+
if let maximumAge = properties[.maximumAge] as? String,
286+
let secondsFromNow = Int(maximumAge) {
287+
if version == 1 {
288+
expDate = Date(timeIntervalSinceNow: Double(secondsFromNow))
289+
}
290+
} else {
279291
let expiresProperty = properties[.expires]
280292
if let date = expiresProperty as? Date {
281-
_expiresDate = date
293+
expDate = date
282294
} else if let dateString = expiresProperty as? String {
283295
let formatter = DateFormatter()
284296
formatter.locale = Locale(identifier: "en_US_POSIX")
285297
formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss O" // per RFC 6265 '<rfc1123-date, defined in [RFC2616], Section 3.3.1>'
286298
let timeZone = TimeZone(abbreviation: "GMT")
287299
formatter.timeZone = timeZone
288-
_expiresDate = formatter.date(from: dateString)
289-
} else {
290-
_expiresDate = nil
300+
expDate = formatter.date(from: dateString)
291301
}
292-
} else if
293-
let maximumAge = properties[.maximumAge] as? String,
294-
let secondsFromNow = Int(maximumAge), _version == 1 {
295-
_expiresDate = Date(timeIntervalSinceNow: Double(secondsFromNow))
296-
} else {
297-
_expiresDate = nil
298302
}
303+
_expiresDate = expDate
299304

300305
if let discardString = properties[.discard] as? String {
301306
_sessionOnly = discardString == "TRUE"
302307
} else {
303308
_sessionOnly = properties[.maximumAge] == nil && version >= 1
304309
}
305-
if version == 0 {
306-
_comment = nil
307-
_commentURL = nil
310+
311+
_comment = properties[.comment] as? String
312+
if let commentURL = properties[.commentURL] as? URL {
313+
_commentURL = commentURL
314+
} else if let commentURL = properties[.commentURL] as? String {
315+
_commentURL = URL(string: commentURL)
308316
} else {
309-
_comment = properties[.comment] as? String
310-
if let commentURL = properties[.commentURL] as? URL {
311-
_commentURL = commentURL
312-
} else if let commentURL = properties[.commentURL] as? String {
313-
_commentURL = URL(string: commentURL)
314-
} else {
315-
_commentURL = nil
316-
}
317+
_commentURL = nil
317318
}
318319
_HTTPOnly = false
319320

@@ -363,7 +364,11 @@ open class HTTPCookie : NSObject {
363364
cookieString.removeLast()
364365
cookieString.removeLast()
365366
}
366-
return ["Cookie": cookieString]
367+
if cookieString == "" {
368+
return [:]
369+
} else {
370+
return ["Cookie": cookieString]
371+
}
367372
}
368373

369374
/// Return an array of cookies parsed from the specified response header fields and URL.
@@ -418,9 +423,9 @@ open class HTTPCookie : NSObject {
418423
properties[canonicalize(name)] = value
419424
}
420425

421-
//if domain wasn't provided use the URL
426+
// If domain wasn't provided, extract it from the URL
422427
if properties[.domain] == nil {
423-
properties[.domain] = url.absoluteString
428+
properties[.domain] = url.host
424429
}
425430

426431
//the default Path is "/"

Foundation/NSData.swift

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -185,41 +185,58 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
185185
/// Initializes a data object with the data from the location specified by a given URL.
186186
public init(contentsOf url: URL, options readOptionsMask: ReadingOptions = []) throws {
187187
super.init()
188-
try _contentsOf(url: url, options: readOptionsMask)
188+
let (data, _) = try NSData.contentsOf(url: url, options: readOptionsMask)
189+
_init(bytes: UnsafeMutableRawPointer(mutating: data.bytes), length: data.length, copy: true)
189190
}
190191

191192
/// Initializes a data object with the data from the location specified by a given URL.
192193
public init?(contentsOf url: URL) {
193194
super.init()
194195
do {
195-
try _contentsOf(url: url)
196+
let (data, _) = try NSData.contentsOf(url: url)
197+
_init(bytes: UnsafeMutableRawPointer(mutating: data.bytes), length: data.length, copy: true)
196198
} catch {
197199
return nil
198200
}
199201
}
200202

201-
/// Initializes a data object with the data from the location specified by a given URL.
202-
private func _contentsOf(url: URL, options readOptionsMask: ReadingOptions = []) throws {
203+
internal static func contentsOf(url: URL, options readOptionsMask: ReadingOptions = []) throws -> (NSData, URLResponse?) {
204+
let readResult: NSData
205+
var urlResponse: URLResponse?
206+
203207
if url.isFileURL {
204-
let readResult = try NSData.readBytesFromFileWithExtendedAttributes(url.path, options: readOptionsMask)
205-
_init(bytes: readResult.bytes, length: readResult.length, copy: false, deallocator: readResult.deallocator)
208+
let data = try NSData.readBytesFromFileWithExtendedAttributes(url.path, options: readOptionsMask)
209+
readResult = NSData(bytesNoCopy: data.bytes, length: data.length, deallocator: data.deallocator)
206210
} else {
207211
let session = URLSession(configuration: URLSessionConfiguration.default)
208212
let cond = NSCondition()
213+
cond.lock()
214+
209215
var resError: Error?
210216
var resData: Data?
217+
var taskFinished = false
211218
let task = session.dataTask(with: url, completionHandler: { data, response, error in
219+
cond.lock()
212220
resData = data
221+
urlResponse = response
213222
resError = error
214-
cond.broadcast()
223+
taskFinished = true
224+
cond.signal()
225+
cond.unlock()
215226
})
227+
216228
task.resume()
217-
cond.wait()
229+
while taskFinished == false {
230+
cond.wait()
231+
}
232+
cond.unlock()
233+
218234
guard let data = resData else {
219235
throw resError!
220236
}
221-
_init(bytes: UnsafeMutableRawPointer(mutating: data._nsObject.bytes), length: data.count, copy: true)
237+
readResult = NSData(bytes: UnsafeMutableRawPointer(mutating: data._nsObject.bytes), length: data.count)
222238
}
239+
return (readResult, urlResponse)
223240
}
224241

225242
/// Initializes a data object with the given Base64 encoded string.

Foundation/NSString.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@ open class NSString : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSC
294294
}
295295

296296
internal func _fastCStringContents(_ nullTerminated: Bool) -> UnsafePointer<Int8>? {
297+
guard !nullTerminated else {
298+
// There is no way to fastly and safely retrieve a pointer to a null-terminated string from a String of Swift.
299+
return nil
300+
}
297301
if type(of: self) == NSString.self || type(of: self) == NSMutableString.self {
298302
if _storage._guts._isContiguousASCII {
299303
return unsafeBitCast(_storage._guts.startASCII, to: UnsafePointer<Int8>.self)
@@ -1254,12 +1258,14 @@ extension NSString {
12541258
public convenience init(contentsOfFile path: String, encoding enc: UInt) throws {
12551259
try self.init(contentsOf: URL(fileURLWithPath: path), encoding: enc)
12561260
}
1257-
1261+
12581262
public convenience init(contentsOf url: URL, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {
1259-
let readResult = try NSData(contentsOf: url, options:[])
1263+
let (readResult, urlResponse) = try NSData.contentsOf(url: url)
12601264

12611265
let encoding: UInt
12621266
let offset: Int
1267+
// Look for a BOM (Byte Order Marker) to try and determine the text Encoding, this also skips
1268+
// over the bytes. This takes precedence over the textEncoding in the http header
12631269
let bytePtr = readResult.bytes.bindMemory(to: UInt8.self, capacity:readResult.length)
12641270
if readResult.length >= 4 && bytePtr[0] == 0xFF && bytePtr[1] == 0xFE && bytePtr[2] == 0x00 && bytePtr[3] == 0x00 {
12651271
encoding = String.Encoding.utf32LittleEndian.rawValue
@@ -1277,14 +1283,15 @@ extension NSString {
12771283
encoding = String.Encoding.utf32BigEndian.rawValue
12781284
offset = 4
12791285
}
1280-
else {
1286+
else if let charSet = urlResponse?.textEncodingName, let textEncoding = String.Encoding(charSet: charSet) {
1287+
encoding = textEncoding.rawValue
1288+
offset = 0
1289+
} else {
12811290
//Need to work on more conditions. This should be the default
12821291
encoding = String.Encoding.utf8.rawValue
12831292
offset = 0
12841293
}
12851294

1286-
enc?.pointee = encoding
1287-
12881295
// Since the encoding being passed includes the byte order the BOM wont be checked or skipped, so pass offset to
12891296
// manually skip the BOM header.
12901297
guard let cf = CFStringCreateWithBytes(kCFAllocatorDefault, bytePtr + offset, readResult.length - offset,
@@ -1301,6 +1308,7 @@ extension NSString {
13011308
"NSDebugDescription" : "Unable to bridge CFString to String."
13021309
])
13031310
}
1311+
enc?.pointee = encoding
13041312
}
13051313

13061314
public convenience init(contentsOfFile path: String, usedEncoding enc: UnsafeMutablePointer<UInt>?) throws {

Foundation/Process.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,8 @@ open class Process: NSObject {
484484

485485
self.processIdentifier = pid
486486

487-
self.processLaunchedCondition.unlock()
488487
self.processLaunchedCondition.broadcast()
488+
self.processLaunchedCondition.unlock()
489489
}
490490

491491
open func interrupt() { NSUnimplemented() } // Not always possible. Sends SIGINT.

Foundation/StringEncodings.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,39 @@ extension String {
2727
public static let utf32 = Encoding(rawValue: 0x8c000100)
2828
public static let utf32BigEndian = Encoding(rawValue: 0x98000100)
2929
public static let utf32LittleEndian = Encoding(rawValue: 0x9c000100)
30+
31+
// Map selected IANA character set names to encodings, see
32+
// https://www.iana.org/assignments/character-sets/character-sets.xhtml
33+
internal init?(charSet: String) {
34+
let encoding: Encoding?
35+
36+
switch charSet.lowercased() {
37+
case "us-ascii": encoding = .ascii
38+
case "utf-8": encoding = .utf8
39+
case "utf-16": encoding = .utf16
40+
case "utf-16be": encoding = .utf16BigEndian
41+
case "utf-16le": encoding = .utf16LittleEndian
42+
case "utf-32": encoding = .utf32
43+
case "utf-32be": encoding = .utf32BigEndian
44+
case "utf-32le": encoding = .utf32LittleEndian
45+
case "iso-8859-1": encoding = .isoLatin1
46+
case "iso-8859-2": encoding = .isoLatin2
47+
case "iso-2022-jp": encoding = .iso2022JP
48+
case "windows-1250": encoding = .windowsCP1250
49+
case "windows-1251": encoding = .windowsCP1251
50+
case "windows-1252": encoding = .windowsCP1252
51+
case "windows-1253": encoding = .windowsCP1253
52+
case "windows-1254": encoding = .windowsCP1254
53+
case "shift_jis": encoding = .shiftJIS
54+
case "euc-jp": encoding = .japaneseEUC
55+
case "macintosh": encoding = .macOSRoman
56+
default: encoding = nil
57+
}
58+
guard let value = encoding?.rawValue else {
59+
return nil
60+
}
61+
rawValue = value
62+
}
3063
}
3164

3265
public typealias EncodingConversionOptions = NSString.EncodingConversionOptions
@@ -50,6 +83,7 @@ extension String.Encoding : CustomStringConvertible {
5083
}
5184
}
5285

86+
5387
@available(*, unavailable, renamed: "String.Encoding")
5488
public typealias NSStringEncoding = UInt
5589

0 commit comments

Comments
 (0)