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-12060] Optimiser Error on String w/ Emoji #54496

Open
swift-ci opened this issue Jan 21, 2020 · 3 comments
Open

[SR-12060] Optimiser Error on String w/ Emoji #54496

swift-ci opened this issue Jan 21, 2020 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-12060
Radar rdar://problem/58997065
Original Reporter helge (JIRA User)
Type Bug

Attachment: Download

Environment

Xcode 11C504, macOS 10.14.6

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 8592f0a66efbd5b78be89cbe4cb92931

Issue Description:

Sorry in advance for the bad bug report :-/ When compiling my project (well, a set of static libs within a larger app), w/ `-Owholemodule` or `-O` (opt for speed), it produces an out of bounds exception. Just switching to `-O0` makes it work, `-Osize` also works.

It only crashes on larger input WITH an embedded Emoji, ~300 chars (presumably when `NSBigMutableString` starts getting used). Small input w/ Emoji seems fine, large input w/o Emoji seems fine.

*** -[NSBigMutableString characterAtIndex:]: Index 309 out of bounds; string length 309

Here is the relevant code:

public extension NSAttributedString {
  func generateFormattedString() -> String {
    let fontManager = NSFontManager.shared
    let s = self // makes it easier to move elsewhere (its a ref type anyways)
    var markDown    = ""
    markDown.reserveCapacity(s.length)
    
    let fullRange = NSMakeRange(0, s.length)
    let plain     = s.string
    
    s.enumerateAttributes(in: fullRange, options: []) {
      attributes, nsRange, stop in
      
      guard nsRange.location >= 0 && nsRange.length > 0 else {
        assertionFailure("unexpected empty range: \(nsRange) \(plain)")
        return
      }
      guard let range = Range(nsRange, in: plain) else {
        assertionFailure("unexpected: \(nsRange) \(plain)")
        return
      }
      let sub = plain[range] // <=== this crashes w/ the OOB

Note that both ranges are validated and it is what NSAttributedString gives me as input, no own tweaking.
Maybe something w/ promoting the `plain` into the closure? Or something within the `Range` conversion?

@swift-ci
Copy link
Collaborator Author

Comment by Helge Heß (JIRA)

Rewritten to use NSString, makes it work.

    let plain     = string as NSString
...
      let sub = plain.substring(with: nsRange)

@beccadax
Copy link
Contributor

@swift-ci create

@eeckstein
Copy link
Member

helge (JIRA User) Is it possible that you attach a small self-contained swift file, including the input string, which reproduces the problem?

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

3 participants