MobileOrg / mobileorg

MobileOrg iPhone App
http://mobileorg.github.io
GNU General Public License v2.0
556 stars 69 forks source link

Pressing sync button crashes application when some .org files use emoji 🎯 #220

Closed serhiip closed 4 years ago

serhiip commented 6 years ago

After the crash, I am able to launch the application again and use it just fine. The application still crashes again on subsequent synchronizations

image-1

dive commented 4 years ago

I found the problem, and it is within captureComponentsMatchedBy function that we use to extract information from the index.org and other org files.

The problem is that Swift uses UTF8 strings representation by default, but Objective C API still requires UTF16. It fails to calculate a proper length in this case because NSRange assumes that we are operating on NSString by default (yeah, an annoying API design in Swift, check #SR-10710, #SR-11330, etc.). This function definition is amazing as to me:

func matches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> [NSTextCheckingResult]

You have to pass Swift String mixed with NSRange, and it assumes that you get indexes on the same Swift String later but on the .utf16 representation.

Should be easy to fix and cover with tests. Assign to myself.

Trimmed crash stacktrace

``` Process: MobileOrg [57244] Path: /Users/USER/Library/Developer/CoreSimulator/Devices/C1DD3041-665D-4501-8950-07BEE9BBD998/data/Containers/Bundle/Application/B2A99344-6764-4D92-8FA7-1E6EF1678719/MobileOrg.app/MobileOrg Identifier: MobileOrg Version: 1.7.5 (32) Code Type: X86-64 (Native) Parent Process: launchd_sim [57019] Responsible: SimulatorTrampoline [1350] User ID: 501 Date/Time: 2019-10-16 20:31:28.460 +0100 OS Version: Mac OS X 10.15 (19A583) Report Version: 12 Anonymous UUID: ACACA966-5E0B-C7DE-9754-6EE32C8AC16D Sleep/Wake UUID: 3AD30C9C-7475-4C74-84B7-341411C226F9 Time Awake Since Boot: 220000 seconds Time Since Wake: 1400 seconds System Integrity Protection: enabled Crashed Thread: 0 Dispatch queue: com.apple.main-thread Exception Type: EXC_BAD_INSTRUCTION (SIGILL) Exception Codes: 0x0000000000000001, 0x0000000000000000 Exception Note: EXC_CORPSE_NOTIFY Termination Signal: Illegal instruction: 4 Termination Reason: Namespace SIGNAL, Code 0x4 Terminating Process: exc handler [57244] Application Specific Information: Fatal error: String index is out of bounds CoreSimulator 681.5.4 - Device: iPhone 8 (C1DD3041-665D-4501-8950-07BEE9BBD998) - Runtime: iOS 13.1 (17A844) - DeviceType: iPhone 8 Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libswiftCore.dylib 0x00000001021e219f specialized _fatalErrorMessage(_:_:file:line:flags:) + 463 1 libswiftCore.dylib 0x00000001021e9852 specialized String.index(after:) + 290 2 libswiftCore.dylib 0x000000010213749e String.index(_:offsetBy:) + 62 3 com.mobileorg.mobileorg-LocalDev 0x0000000100239d89 NSString.captureComponentsMatchedBy(regex:) + 2185 4 com.mobileorg.mobileorg-LocalDev 0x000000010023a63e @objc NSString.captureComponentsMatchedBy(regex:) + 94 5 com.mobileorg.mobileorg-LocalDev 0x00000001001eb2b3 -[Node linkFile] + 67 (Node.m:331) 6 com.mobileorg.mobileorg-LocalDev 0x00000001001eb5b9 -[Node collectLinks:] + 105 (Node.m:363) 7 com.mobileorg.mobileorg-LocalDev 0x00000001001eb9c9 -[Node collectLinks:] + 1145 8 com.mobileorg.mobileorg-LocalDev 0x00000001001f737a -[SyncManager findAndFetchLinksForNode:] + 106 (SyncManager.m:506) 9 com.mobileorg.mobileorg-LocalDev 0x00000001001f7b03 -[SyncManager doneProcessingOrgFile] + 307 10 com.mobileorg.mobileorg-LocalDev 0x000000010020105c -[OrgFileParser parse:] + 11836 (OrgFileParser.m:506) 11 com.mobileorg.mobileorg-LocalDev 0x00000001001f79be -[SyncManager processOrgFile:withLocalFile:] + 286 (SyncManager.m:599) 12 com.mobileorg.mobileorg-LocalDev 0x00000001001f8c85 -[SyncManager transferComplete:] + 933 (SyncManager.m:759) 13 com.mobileorg.mobileorg-LocalDev 0x0000000100243712 partial apply + 34 14 com.mobileorg.mobileorg-LocalDev 0x0000000100240d4c thunk for @escaping @callee_guaranteed (@unowned TransferContext?) -> () + 12 15 com.mobileorg.mobileorg-LocalDev 0x000000010023fee4 CloudTransferManager.requestFinished(_:) + 932 (CloudTransferManager.swift:153) 16 com.mobileorg.mobileorg-LocalDev 0x00000001002405e5 closure #1 in CloudTransferManager.processRequest(_:) + 917 (CloudTransferManager.swift:139) 17 com.mobileorg.mobileorg-LocalDev 0x00000001002425cd closure #2 in closure #1 in CloudTransferManager.downloadFile(from:to:completionHandler:) + 125 (CloudTransferManager.swift:199) 18 com.mobileorg.mobileorg-LocalDev 0x000000010021ffdd thunk for @escaping @callee_guaranteed () -> () + 45 19 libdispatch.dylib 0x00007fff516ac810 _dispatch_call_block_and_release + 12 20 libdispatch.dylib 0x00007fff516ad781 _dispatch_client_callout + 8 21 libdispatch.dylib 0x00007fff516b9caa _dispatch_main_queue_callback_4CF + 1212 22 com.apple.CoreFoundation 0x00007fff23b0ce49 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 23 com.apple.CoreFoundation 0x00007fff23b07aa9 __CFRunLoopRun + 2329 24 com.apple.CoreFoundation 0x00007fff23b06e66 CFRunLoopRunSpecific + 438 25 com.apple.GeoServices 0x00007fff38346bb0 GSEventRunModal + 65 26 com.apple.UIKitCore 0x00007fff47578dd0 UIApplicationMain + 1621 27 com.mobileorg.mobileorg-LocalDev 0x00000001001e88de main + 94 (main.m:30) 28 libdyld.dylib 0x00007fff516ecd29 start + 1 ... ```