jpsim / SourceKitten

An adorable little framework and command line tool for interacting with SourceKit.
MIT License
2.31k stars 226 forks source link

Crash on unicode characters used after string interpolation #444

Open ilyapuchka opened 7 years ago

ilyapuchka commented 7 years ago

sourcekitten structure returns wrong key.length when unicode characters are used after string interpolation. Here is an example:

sourcekitten structure --text 'class Foo { var blah: String { switch { default: return "\(true) π" }}}'

It will always give 26 for length of case statement:

"key.kind" : "source.lang.swift.stmt.case",
"key.offset" : 40,
"key.length" : 26

At the same time when unicode character comes before string interpolation length is completely different.

sourcekitten structure --text 'class Foo { var blah: String { switch { default: return "π \(true)" }}}'

"key.kind" : "source.lang.swift.stmt.case",
"key.offset" : 40,
"key.length" : 32

but again adding whitespaces after string interpolation does not change the length, which will probably lead to crash again.

Crash happens when trying to extract string for such statement from the source:

frame #7: 0x000000010e443ac0 SourceKittenFramework`NSString.CacheContainer.location(byteOffset=91, self=0x00007fabf73072d0) at String+SourceKitten.swift:129

Reference https://github.com/krzysztofzablocki/Sourcery/issues/432

norio-nomura commented 7 years ago

The length of source.lang.swift.stmt.case including string interpolation seems to be wrong even if it does not contain unicode characters.

$ sourcekitten structure --text 'switch { default: return "\(true)" }'
…
          "key.kind" : "source.lang.swift.stmt.case",
          "key.length" : 27,  // should be 25
          "key.namelength" : 0,
          "key.nameoffset" : 0,
          "key.offset" : 9
…

string interpolation followed by unicode:

$ sourcekitten structure --text 'switch { default: return "\(true) π" }'
…
          "key.kind" : "source.lang.swift.stmt.case",
          "key.length" : 26, // should be 28
          "key.namelength" : 0,
          "key.nameoffset" : 0,
          "key.offset" : 9
…

unicode before string interpolation:

$ sourcekitten structure --text 'switch { default: return "π \(true)" }'
…
          "key.kind" : "source.lang.swift.stmt.case",
          "key.length" : 30, // should be 28
          "key.namelength" : 0,
          "key.nameoffset" : 0,
          "key.offset" : 9
…

This issue should be filed to bugs.swift.org.

ilyapuchka commented 7 years ago

https://bugs.swift.org/browse/SR-6443