Skip to content
This repository has been archived by the owner on Jul 11, 2024. It is now read-only.

Crash in String+ListItemFormatter.swift #29

Closed
liamnichols opened this issue Apr 17, 2019 · 3 comments
Closed

Crash in String+ListItemFormatter.swift #29

liamnichols opened this issue Apr 17, 2019 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@liamnichols
Copy link
Owner

Our crash reports don't log the exact locale being used when formatting strings however I do know that it was in an Arabic speaking region but not completely sure if language is playing a part to this.

Crashed: com.apple.main-thread
0  ListItemFormatter              0x10371fe14 closure #1 in String.init(format:locale:ranges:arguments:) (String+ListItemFormatter.swift:76)
1  ListItemFormatter              0x103720f1c partial apply for closure #1 in String.init(format:locale:ranges:arguments:) (<compiler-generated>)
2  ListItemFormatter              0x103720f4c partial apply for thunk for @callee_guaranteed (@guaranteed NSTextCheckingResult?, @unowned NSMatchingFlags, @unowned UnsafeMutablePointer<ObjCBool>) -> () (<compiler-generated>)
3  ListItemFormatter              0x10371fe68 thunk for @escaping @callee_guaranteed (@guaranteed NSTextCheckingResult?, @unowned NSMatchingFlags, @unowned UnsafeMutablePointer<ObjCBool>) -> () (<compiler-generated>)
4  Foundation                     0x18252bd24 -[NSRegularExpression(NSMatching) enumerateMatchesInString:options:range:usingBlock:] + 1380
5  ListItemFormatter              0x103720e00 specialized String.init(format:locale:ranges:arguments:) (String+ListItemFormatter.swift:49)
6  ListItemFormatter              0x10371c324 ListPatternBuilder.listByUsingStartMiddleAndEndFormat(between:) (ListPatternBuilder.swift)
7  ListItemFormatter              0x10371bde4 ListPatternBuilder.build(from:) (ListPatternBuilder.swift:57)
8  ListItemFormatter              0x10371af30 ListItemFormatter.attributedString(for:withDefaultAttributes:) (ListItemFormatter.swift:190)
9  ListItemFormatter              0x10371b568 @objc ListItemFormatter.attributedString(for:withDefaultAttributes:) (<compiler-generated>)
10 ListItemFormatter              0x10371ac30 ListItemFormatter.string(for:) (ListItemFormatter.swift:179)
11 ListItemFormatter              0x10371ad0c @objc ListItemFormatter.string(for:) (<compiler-generated>)
12 Global                         0x102b253b8 InboxItem.sendersText(with:) (InboxItem+Localization.swift:43)
13 Global                         0x102b25ce4 InboxItem.messageToDisplay(for:with:) (InboxItem+Localization.swift:106)
14 Global                         0x102b2683c InboxItem.attributedMessageToDisplay(for:with:) (InboxItem+Localization.swift:137)
15 Global                         0x102ccfadc InboxCollectionViewCell.configureWithInboxItem(_:session:formatter:) (InboxCollectionViewCell.swift:163)
16 Global                         0x102453d14 specialized InboxViewController.collectionView(_:layout:sizeForItemAt:) (InboxViewController.swift:209)
17 Global                         0x102450830 @objc InboxViewController.collectionView(_:layout:sizeForItemAt:) (<compiler-generated>)
18 UIKit                          0x18b8f5ee4 -[UICollectionViewFlowLayout _getSizingInfosWithExistingSizingDictionary:] + 2972
19 UIKit                          0x18b8f5008 -[UICollectionViewFlowLayout _fetchItemsInfoForRect:] + 144
20 UIKit                          0x18b8f4f5c -[UICollectionViewFlowLayout prepareLayout] + 224
21 UIKit                          0x18b8f4e3c -[UICollectionViewData _prepareToLoadData] + 160
22 UIKit                          0x18b8f4484 -[UICollectionViewData validateLayoutInRect:] + 104
23 UIKit                          0x18b8f36b4 -[UICollectionView layoutSubviews] + 248
24 UIKit                          0x18b7c26f4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1420
25 QuartzCore                     0x185d37e54 -[CALayer layoutSublayers] + 184
26 QuartzCore                     0x185d3bfe4 CA::Layer::layout_if_needed(CA::Transaction*) + 324
27 QuartzCore                     0x185ca86c8 CA::Context::commit_transaction(CA::Transaction*) + 320
28 QuartzCore                     0x185cd01b0 CA::Transaction::commit() + 580
29 QuartzCore                     0x185cd1030 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 92
30 CoreFoundation                 0x181b56910 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
31 CoreFoundation                 0x181b54238 __CFRunLoopDoObservers + 412
32 CoreFoundation                 0x181b54884 __CFRunLoopRun + 1436
33 CoreFoundation                 0x181a74da8 CFRunLoopRunSpecific + 552
34 GraphicsServices               0x183a5a020 GSEventRunModal + 100
35 UIKit                          0x18ba94758 UIApplicationMain + 236
36 Global                         0x1022fde50 main (main.swift:19)
37 libdyld.dylib                  0x181505fc0 start + 4

This part of the code in theory was working fine since there is test coverage but I guess the first place to start is by adding some more robust tests to see if the issue can be reproduced.

@liamnichols liamnichols added the bug Something isn't working label Apr 17, 2019
@liamnichols
Copy link
Owner Author

I've finally managed to reproduce this with the following data:

let json = #"["roro(همسات المستقبل)","َمنار منار، Alwahabi Alwahabi، و10 آخرين"]"#
let data = try XCTUnwrap(json.data(using: .utf8))
let array = try JSONDecoder().decode([String].self, from: data)

var ranges: [Range<String.Index>] = []
let output = String(format: "{0}، {1}", ranges: &ranges, array.first!, array.last!) // crashes

I think its partially related to deserialising via JSONDecoder (NSJSONSerialization) since the strings are actually bridged from NSString and have some kind of different memory layout that messes with the ranges

@liamnichols
Copy link
Owner Author

Ok so the bottom line is that this issue crops up when there is a combining character in one of the strings.. If a lone combining character was placed at the start of a string then it can combine with whatever string it is joined with causing the range calculation to be off which then results in a crash 😕

I'll try and simplify the replication steps

@liamnichols
Copy link
Owner Author

Fixed in 0.1.0

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant