mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #68423 from glessard/se0405-take2
[se-0405] rename `String.init(validatingUTF8:)`
This commit is contained in:
@@ -16,7 +16,7 @@ public enum SwiftRuntime {
|
||||
private static func _metadataKind<T>(of value: T) -> UnsafePointer<CChar>
|
||||
|
||||
public static func metadataKind<T>(of value: T) -> String {
|
||||
return String(validatingUTF8: _metadataKind(of: value))!
|
||||
return String(validatingCString: _metadataKind(of: value))!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -850,7 +850,7 @@ func _printDebuggingAdvice(_ fullTestName: String) {
|
||||
#else
|
||||
let interpreter = getenv("SWIFT_INTERPRETER")
|
||||
if interpreter != nil {
|
||||
if let interpreterCmd = String(validatingUTF8: interpreter!) {
|
||||
if let interpreterCmd = String(validatingCString: interpreter!) {
|
||||
invocation.insert(interpreterCmd, at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ public func spawnChild(_ args: [String])
|
||||
childArgs.insert(CommandLine.arguments[0], at: 0)
|
||||
let interpreter = getenv("SWIFT_INTERPRETER")
|
||||
if interpreter != nil {
|
||||
if let invocation = String(validatingUTF8: interpreter!) {
|
||||
if let invocation = String(validatingCString: interpreter!) {
|
||||
childArgs.insert(invocation, at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ internal func getAddressInfoForImage(atIndex i: UInt32) ->
|
||||
debugLog("BEGIN \(#function)"); defer { debugLog("END \(#function)") }
|
||||
let header = unsafeBitCast(_dyld_get_image_header(i),
|
||||
to: UnsafePointer<MachHeader>.self)
|
||||
let name = String(validatingUTF8: _dyld_get_image_name(i)!)!
|
||||
let name = String(validatingCString: _dyld_get_image_name(i)!)!
|
||||
var size: UInt = 0
|
||||
let address = getsegmentdata(header, "__TEXT", &size)
|
||||
return (name, address, size)
|
||||
@@ -111,7 +111,7 @@ internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? {
|
||||
let capture = getSectionInfo("__swift5_capture", header)
|
||||
let typeref = getSectionInfo("__swift5_typeref", header)
|
||||
let reflstr = getSectionInfo("__swift5_reflstr", header)
|
||||
return ReflectionInfo(imageName: String(validatingUTF8: imageName)!,
|
||||
return ReflectionInfo(imageName: String(validatingCString: imageName)!,
|
||||
fieldmd: fieldmd,
|
||||
assocty: assocty,
|
||||
builtin: builtin,
|
||||
@@ -160,7 +160,7 @@ internal func getReflectionInfoForImage(atIndex i: UInt32) -> ReflectionInfo? {
|
||||
return _getMetadataSection(UInt(i)).map { rawPointer in
|
||||
let name = _getMetadataSectionName(rawPointer)
|
||||
let metadataSection = rawPointer.bindMemory(to: MetadataSections.self, capacity: 1).pointee
|
||||
return ReflectionInfo(imageName: String(validatingUTF8: name)!,
|
||||
return ReflectionInfo(imageName: String(validatingCString: name)!,
|
||||
fieldmd: Section(range: metadataSection.swift5_fieldmd),
|
||||
assocty: Section(range: metadataSection.swift5_assocty),
|
||||
builtin: Section(range: metadataSection.swift5_builtin),
|
||||
@@ -302,7 +302,7 @@ internal func sendReflectionInfos() {
|
||||
internal func printErrnoAndExit() {
|
||||
debugLog("BEGIN \(#function)"); defer { debugLog("END \(#function)") }
|
||||
let errorCString = strerror(errno)!
|
||||
let message = String(validatingUTF8: errorCString)! + "\n"
|
||||
let message = String(validatingCString: errorCString)! + "\n"
|
||||
let bytes = Array(message.utf8)
|
||||
fwrite(bytes, 1, bytes.count, stderr)
|
||||
fflush(stderr)
|
||||
|
||||
@@ -435,7 +435,7 @@ public struct Backtrace: CustomStringConvertible, Sendable {
|
||||
_dyld_process_info_for_each_segment(dyldInfo, machHeaderAddress) {
|
||||
address, size, name in
|
||||
|
||||
if let name = String(validatingUTF8: name!), name == "__TEXT" {
|
||||
if let name = String(validatingCString: name!), name == "__TEXT" {
|
||||
endOfText = address + size
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,40 @@ extension String {
|
||||
self = ""
|
||||
}
|
||||
|
||||
/// Creates a new string by copying and validating the null-terminated UTF-8
|
||||
/// data referenced by the given pointer.
|
||||
///
|
||||
/// This initializer does not try to repair ill-formed UTF-8 code unit
|
||||
/// sequences. If any are found, the result of the initializer is `nil`.
|
||||
///
|
||||
/// The following example calls this initializer with pointers to the
|
||||
/// contents of two different `CChar` arrays---the first with well-formed
|
||||
/// UTF-8 code unit sequences and the second with an ill-formed sequence at
|
||||
/// the end.
|
||||
///
|
||||
/// let validUTF8: [CChar] = [67, 97, 102, -61, -87, 0]
|
||||
/// validUTF8.withUnsafeBufferPointer { ptr in
|
||||
/// let s = String(validatingCString: ptr.baseAddress!)
|
||||
/// print(s)
|
||||
/// }
|
||||
/// // Prints "Optional("Café")"
|
||||
///
|
||||
/// let invalidUTF8: [CChar] = [67, 97, 102, -61, 0]
|
||||
/// invalidUTF8.withUnsafeBufferPointer { ptr in
|
||||
/// let s = String(validatingCString: ptr.baseAddress!)
|
||||
/// print(s)
|
||||
/// }
|
||||
/// // Prints "nil"
|
||||
///
|
||||
/// - Parameter nullTerminatedUTF8:
|
||||
/// A pointer to a null-terminated UTF-8 code sequence.
|
||||
@inlinable
|
||||
@_alwaysEmitIntoClient
|
||||
public init?(validatingCString nullTerminatedUTF8: UnsafePointer<CChar>) {
|
||||
// FIXME: https://github.com/apple/swift/issues/68433 (rdar://115296219)
|
||||
self.init(validatingUTF8: nullTerminatedUTF8)
|
||||
}
|
||||
|
||||
/// Creates a new string by copying and validating the null-terminated UTF-8
|
||||
/// data referenced by the given pointer.
|
||||
///
|
||||
@@ -149,7 +183,11 @@ extension String {
|
||||
/// }
|
||||
/// // Prints "nil"
|
||||
///
|
||||
/// Note: This initializer is deprecated. Use
|
||||
/// `String.init?(validatingCString:)` instead.
|
||||
///
|
||||
/// - Parameter cString: A pointer to a null-terminated UTF-8 code sequence.
|
||||
@available(swift, deprecated: 6, renamed: "String.init(validatingCString:)")
|
||||
public init?(validatingUTF8 cString: UnsafePointer<CChar>) {
|
||||
let len = UTF8._nullCodeUnitOffset(in: cString)
|
||||
guard let str = cString.withMemoryRebound(to: UInt8.self, capacity: len, {
|
||||
@@ -162,37 +200,57 @@ extension String {
|
||||
|
||||
@inlinable
|
||||
@_alwaysEmitIntoClient
|
||||
public init?(validatingUTF8 cString: [CChar]) {
|
||||
guard let length = cString.firstIndex(of: 0) else {
|
||||
public init?(validatingCString nullTerminatedUTF8: [CChar]) {
|
||||
guard let length = nullTerminatedUTF8.firstIndex(of: 0) else {
|
||||
_preconditionFailure(
|
||||
"input of String.init(validatingUTF8:) must be null-terminated"
|
||||
"input of String.init(validatingCString:) must be null-terminated"
|
||||
)
|
||||
}
|
||||
guard let string = cString.prefix(length).withUnsafeBufferPointer({
|
||||
let string = nullTerminatedUTF8.prefix(length).withUnsafeBufferPointer {
|
||||
$0.withMemoryRebound(to: UInt8.self, String._tryFromUTF8(_:))
|
||||
})
|
||||
else { return nil }
|
||||
|
||||
}
|
||||
guard let string else { return nil }
|
||||
self = string
|
||||
}
|
||||
|
||||
@inlinable
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, deprecated, renamed: "String.init(validatingCString:)")
|
||||
public init?(validatingUTF8 cString: [CChar]) {
|
||||
self.init(validatingCString: cString)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, deprecated, message: "Use a copy of the String argument")
|
||||
public init?(validatingCString nullTerminatedUTF8: String) {
|
||||
self = nullTerminatedUTF8.withCString(String.init(cString:))
|
||||
}
|
||||
|
||||
@inlinable
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, deprecated, message: "Use a copy of the String argument")
|
||||
public init?(validatingUTF8 cString: String) {
|
||||
self = cString.withCString(String.init(cString:))
|
||||
self.init(validatingCString: cString)
|
||||
}
|
||||
|
||||
@inlinable
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, deprecated, message: "Use String(_ scalar: Unicode.Scalar)")
|
||||
public init?(validatingCString nullTerminatedUTF8: inout CChar) {
|
||||
guard nullTerminatedUTF8 == 0 else {
|
||||
_preconditionFailure(
|
||||
"input of String.init(validatingUTF8:) must be null-terminated"
|
||||
)
|
||||
}
|
||||
self = ""
|
||||
}
|
||||
|
||||
@inlinable
|
||||
@_alwaysEmitIntoClient
|
||||
@available(*, deprecated, message: "Use String(_ scalar: Unicode.Scalar)")
|
||||
public init?(validatingUTF8 cString: inout CChar) {
|
||||
guard cString == 0 else {
|
||||
_preconditionFailure(
|
||||
"input of String.init(validatingUTF8:) must be null-terminated"
|
||||
)
|
||||
}
|
||||
self = ""
|
||||
self.init(validatingCString: &cString)
|
||||
}
|
||||
|
||||
/// Creates a new string by copying the null-terminated data referenced by
|
||||
|
||||
@@ -196,7 +196,7 @@ public class AnyKeyPath: Hashable, _AppendKeyPath {
|
||||
}
|
||||
guard let ptr = _kvcKeyPathStringPtr else { return nil }
|
||||
|
||||
return String(validatingUTF8: ptr)
|
||||
return String(validatingCString: ptr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -355,7 +355,7 @@ internal func _adHocPrint_unlocked<T, TargetStream: TextOutputStream>(
|
||||
target.write(")")
|
||||
case .enum:
|
||||
if let cString = _getEnumCaseName(value),
|
||||
let caseName = String(validatingUTF8: cString) {
|
||||
let caseName = String(validatingCString: cString) {
|
||||
// Write the qualified type name in debugPrint.
|
||||
if isDebugPrint {
|
||||
printTypeName(mirror.subjectType)
|
||||
@@ -390,7 +390,7 @@ internal func _adHocPrint_unlocked<T, TargetStream: TextOutputStream>(
|
||||
} else {
|
||||
// Fall back to the type or an opaque summary of the kind
|
||||
if let cString = _opaqueSummary(mirror.subjectType),
|
||||
let opaqueSummary = String(validatingUTF8: cString) {
|
||||
let opaqueSummary = String(validatingCString: cString) {
|
||||
target.write(opaqueSummary)
|
||||
} else {
|
||||
target.write(_typeName(mirror.subjectType, qualified: true))
|
||||
@@ -532,7 +532,7 @@ internal func _dumpPrint_unlocked<T, TargetStream: TextOutputStream>(
|
||||
case .`enum`:
|
||||
target.write(_typeName(mirror.subjectType, qualified: true))
|
||||
if let cString = _getEnumCaseName(value),
|
||||
let caseName = String(validatingUTF8: cString) {
|
||||
let caseName = String(validatingCString: cString) {
|
||||
target.write(".")
|
||||
target.write(caseName)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ internal func getChild<T>(of value: T, type: Any.Type, index: Int) -> (label: St
|
||||
|
||||
let value = _getChild(of: value, type: type, index: index, outName: &nameC, outFreeFunc: &freeFunc)
|
||||
|
||||
let name = nameC.flatMap({ String(validatingUTF8: $0) })
|
||||
let name = nameC.flatMap({ String(validatingCString: $0) })
|
||||
freeFunc?(nameC)
|
||||
return (name, value)
|
||||
}
|
||||
|
||||
@@ -107,20 +107,20 @@ func expectEqualCString(_ lhs: UnsafePointer<UInt8>,
|
||||
}
|
||||
}
|
||||
|
||||
CStringTests.test("String.init(validatingUTF8:)") {
|
||||
CStringTests.test("String.init(validatingCString:)") {
|
||||
do {
|
||||
let (s, dealloc) = getASCIIUTF8()
|
||||
expectEqual("ab", String(validatingUTF8: bindAsCChar(s)))
|
||||
expectEqual("ab", String(validatingCString: bindAsCChar(s)))
|
||||
dealloc()
|
||||
}
|
||||
do {
|
||||
let (s, dealloc) = getNonASCIIUTF8()
|
||||
expectEqual("аб", String(validatingUTF8: bindAsCChar(s)))
|
||||
expectEqual("аб", String(validatingCString: bindAsCChar(s)))
|
||||
dealloc()
|
||||
}
|
||||
do {
|
||||
let (s, dealloc) = getIllFormedUTF8String1()
|
||||
expectNil(String(validatingUTF8: bindAsCChar(s)))
|
||||
expectNil(String(validatingCString: bindAsCChar(s)))
|
||||
dealloc()
|
||||
}
|
||||
}
|
||||
@@ -324,14 +324,14 @@ CStringTests.test("String.cString.with.inout.CChar.conversion") {
|
||||
expectUnreachable()
|
||||
}
|
||||
|
||||
CStringTests.test("String.validatingUTF8.with.Array.input") {
|
||||
CStringTests.test("String.validatingCString.with.Array.input") {
|
||||
guard #available(SwiftStdlib 5.7, *) else { return }
|
||||
do {
|
||||
let (u8p, dealloc) = getASCIIUTF8()
|
||||
defer { dealloc() }
|
||||
let buffer = UnsafeBufferPointer(start: u8p, count: getUTF8Length(u8p)+1)
|
||||
let str = buffer.withMemoryRebound(to: CChar.self) {
|
||||
String(validatingUTF8: Array($0))
|
||||
String(validatingCString: Array($0))
|
||||
}
|
||||
expectNotNil(str)
|
||||
str?.withCString {
|
||||
@@ -344,41 +344,41 @@ CStringTests.test("String.validatingUTF8.with.Array.input") {
|
||||
// no need to test every case; that is covered in other tests
|
||||
expectCrashLater(
|
||||
// Workaround for https://github.com/apple/swift/issues/58362 (rdar://91365967)
|
||||
// withMessage: "input of String.init(validatingUTF8:) must be null-terminated"
|
||||
// withMessage: "input of String.init(validatingCString:) must be null-terminated"
|
||||
)
|
||||
_ = String(validatingUTF8: [])
|
||||
_ = String(validatingCString: [])
|
||||
expectUnreachable()
|
||||
}
|
||||
|
||||
CStringTests.test("String.validatingUTF8.with.String.input") {
|
||||
CStringTests.test("String.validatingCString.with.String.input") {
|
||||
guard #available(SwiftStdlib 5.7, *) else { return }
|
||||
let (u8p, dealloc) = getASCIIUTF8()
|
||||
defer { dealloc() }
|
||||
var str = String(validatingUTF8: "ab")
|
||||
var str = String(validatingCString: "ab")
|
||||
expectNotNil(str)
|
||||
str?.withCString {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: getUTF8Length(u8p)+1) {
|
||||
expectEqualCString(u8p, $0)
|
||||
}
|
||||
}
|
||||
str = String(validatingUTF8: "")
|
||||
str = String(validatingCString: "")
|
||||
expectNotNil(str)
|
||||
expectEqual(str?.isEmpty, true)
|
||||
}
|
||||
|
||||
CStringTests.test("String.validatingUTF8.with.inout.conversion") {
|
||||
CStringTests.test("String.validatingCString.with.inout.conversion") {
|
||||
guard #available(SwiftStdlib 5.7, *) else { return }
|
||||
var c = CChar.zero
|
||||
var str = String(validatingUTF8: &c)
|
||||
var str = String(validatingCString: &c)
|
||||
expectNotNil(str)
|
||||
expectEqual(str?.isEmpty, true)
|
||||
c = 100
|
||||
guard enableCrashTests else { return }
|
||||
expectCrashLater(
|
||||
// Workaround for https://github.com/apple/swift/issues/58362 (rdar://91365967)
|
||||
// withMessage: "input of String.init(validatingUTF8:) must be null-terminated"
|
||||
// withMessage: "input of String.init(validatingCString:) must be null-terminated"
|
||||
)
|
||||
str = String(validatingUTF8: &c)
|
||||
str = String(validatingCString: &c)
|
||||
expectUnreachable()
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ func checkStringOverloadCompilationDiagnostics() {
|
||||
|
||||
_ = String(cString: "string") // expected-warning {{'init(cString:)' is deprecated: Use a copy of the String argument}}
|
||||
|
||||
_ = String(validatingUTF8: "string") // expected-warning {{init(validatingUTF8:)' is deprecated: Use a copy of the String argument}}
|
||||
_ = String(validatingCString: "string") // expected-warning {{init(validatingCString:)' is deprecated: Use a copy of the String argument}}
|
||||
|
||||
_ = String.decodeCString("string", as: Unicode.UTF8.self) // expected-warning {{'decodeCString(_:as:repairingInvalidCodeUnits:)' is deprecated: Use a copy of the String argument}}
|
||||
|
||||
@@ -23,7 +23,7 @@ func checkInoutConversionOverloadCompilationDiagnostics() {
|
||||
|
||||
_ = String(cString: &c) // expected-warning {{'init(cString:)' is deprecated: Use String(_ scalar: Unicode.Scalar)}}
|
||||
|
||||
_ = String(validatingUTF8: &c) // expected-warning {{init(validatingUTF8:)' is deprecated: Use String(_ scalar: Unicode.Scalar)}}
|
||||
_ = String(validatingCString: &c) // expected-warning {{init(validatingCString:)' is deprecated: Use String(_ scalar: Unicode.Scalar)}}
|
||||
|
||||
var u = Unicode.UTF8.CodeUnit.zero
|
||||
|
||||
|
||||
Reference in New Issue
Block a user