Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-11330] Incorrect String range after bridging #3983

Open
swift-ci opened this issue Aug 19, 2019 · 4 comments
Open

[SR-11330] Incorrect String range after bridging #3983

swift-ci opened this issue Aug 19, 2019 · 4 comments

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-11330
Radar None
Original Reporter wiruzx (JIRA User)
Type Bug
Environment

Swift 5.0.1

Additional Detail from JIRA
Votes 0
Component/s Foundation, Standard Library
Labels Bug
Assignee None
Priority Medium

md5: ece32cfe96d1ab6bf46997a365bb2677

relates to:

  • SR-10080 Unexpected behaviour with String/Range bridged from NSString/NSRange

Issue Description:

If you have a string bridged to objc and back to swift, range will be wrong:

let string = "You’ll be happy one day."

let range = string.range(of: "day")!

let nsString = NSMutableString()
nsString.append(string)

let bridgedBack = nsString.copy() as! String
let nsRange = NSRange(range, in: bridgedBack)

// Crash here because of out of bounds
print(nsString.substring(with: nsRange)) // Location of NSRange is 22, but should be 20

Crash will not happen, however, if I didn't create mutable string, but just bridged Swift String to NSString, so:

let string = "You’ll be happy one day."

let range = string.range(of: "day")!

let nsString = string as NSString

let bridgedBack = nsString as String
let nsRange = NSRange(range, in: bridgedBack)

// No crash, everything as expected
print(nsString.substring(with: nsRange))

As a workaround, you could add bridgedBack + "" to make it work

let string = "You’ll be happy one day."

let range = string.range(of: "day")!

let nsString = NSMutableString()
nsString.append(string)

let bridgedBack = nsString.copy() as! String
let nsRange = NSRange(range, in: bridgedBack + "")

// No crash, everything as expected
print(nsString.substring(with: nsRange))
@theblixguy
Copy link

cc @milseman

@belkadan
Copy link

I believe this is correct behavior; unlike NSRange, a Range<String.Index> in one String cannot be used with another String. But @milseman can confirm/deny.

@milseman
Copy link
Mannequin

milseman mannequin commented Aug 22, 2019

Yes, specifically one is a range into a lazily-bridged NSString with a different underlying representation while the other is a native Swift String.

@swift-ci
Copy link
Contributor Author

Comment by Victor Shamanov (JIRA)

@milseman Thanks!
Is it documented anywhere by any chance? I'd like to read more about it.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants