AdaptiveCards icon indicating copy to clipboard operation
AdaptiveCards copied to clipboard

[Rendering] iOS App crash

Open yanweida99 opened this issue 3 years ago • 2 comments

Target Platforms

iOS

SDK Version

commit: 7a28ac233f2253c398ebaa71b30e1a2839295b40

Application Name

Our app with AdaptiveCards SDK

Problem Description

The app crash using AdaptiveCards SDK. The reproducibility of this crash is extremely low. I have raised a same issue before, but there is no way to reproduce it. Now I can improve the reproducibility by simulating the code. Please see the Sample Code. Requires a lower performance device (iPhone 7) to run and it is more easy to reproduce.

Thread 0 name:  com.apple.main-thread
--
Thread 0 Crashed:
0   libobjc.A.dylib                         0x1dc3f2f40 objc_msgSend + 32
1   CoreFoundation                          0x1c367ab30 -[__NSDictionaryM objectForKey:] + 184
2   AdaptiveCards                           0x109553220 -[ACRTextBlockRenderer render:rootView:inputs:baseCardElement:hostConfig:] + 600
3   AdaptiveCards                           0x1094f1fd8 +[ACRRenderer render:rootView:inputs:withCardElems:andHostConfig:] + 612
4   AdaptiveCards                           0x10956cbd0 -[ACRColumnRenderer render:rootView:inputs:baseCardElement:hostConfig:] + 924
5   AdaptiveCards                           0x1094a2c50 -[ACRColumnSetRenderer render:rootView:inputs:baseCardElement:hostConfig:] + 2348
6   AdaptiveCards                           0x1094f1fd8 +[ACRRenderer render:rootView:inputs:withCardElems:andHostConfig:] + 612
7   AdaptiveCards                           0x1094f1600 +[ACRRenderer renderWithAdaptiveCards:inputs:context:containingView:hostconfig:] + 996
8   AdaptiveCards                           0x1095465c0 -[ACRView render] + 312
9   AdaptiveCards                           0x109546384 -[ACRView init:hostconfig:widthConstraint:delegate:] + 708
10  AdaptiveCards                           0x1094f0f18 +[ACRRenderer render:config:widthConstraint:delegate:] + 140
11  XXX                                    0x10066b05c ItemAdaptiveCardView.renderView() + 323 (ItemAdaptiveCardView.swift:297)

Screenshots

Crash recording: https://user-images.githubusercontent.com/26455374/183379810-e9c066df-b55c-4bce-934d-3a4b2a4ca65b.MP4

Crash screenshots: Test

Card JSON

{
    "type": "AdaptiveCard",
    "version": "1.3",
    "fallbackText": "",
    "body": [
        {
            "type": "TextBlock",
            "size": "Medium",
            "weight": "Bolder",
            "text": "Publish Adaptive Card Schema"
        }
    ]
}

Sample Code Language

Objective-C++

Sample Code

Modify the code of the file(ACRTextBlockRenderer.mm) as follows:

- (UIView *)render:(UIView<ACRIContentHoldingView> *)viewGroup
           rootView:(ACRView *)rootView
             inputs:(NSMutableArray *)inputs
    baseCardElement:(ACOBaseCardElement *)acoElem
         hostConfig:(ACOHostConfig *)acoConfig;
{
    std::shared_ptr<HostConfig> config = [acoConfig getHostConfig];
    std::shared_ptr<BaseCardElement> elem = [acoElem element];
    std::shared_ptr<TextBlock> txtBlck = std::dynamic_pointer_cast<TextBlock>(elem);

    if (txtBlck->GetText().empty()) {
        return nil;
    }

    ACRUILabel *lab = [[ACRUILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
    lab.backgroundColor = [UIColor clearColor];

    lab.style = [viewGroup style];
    NSMutableAttributedString *content = nil;
    if (rootView) {
        NSMutableDictionary *textMap = [rootView getTextMap];
        NSNumber *number = [NSNumber numberWithUnsignedLongLong:(unsigned long long)txtBlck.get()];
        NSString *key = [number stringValue];
        NSDictionary *data = nil;
        NSData *htmlData = nil;
        NSDictionary *options = nil;
        NSDictionary *descriptor = nil;
        NSString *text = nil;
    
        int i = 0;
        while (i<1000) {
            NSLog(@"Test::objectForKey");
            [textMap objectForKey:key];
            [textMap objectForKey:key];
            [textMap objectForKey:key];
            [textMap objectForKey:key];
            if (![textMap objectForKey:key] || rootView.context.isFirstRowAsHeaders) {
                RichTextElementProperties textProp;
                TexStylesToRichTextElementProperties(txtBlck, [acoConfig getHostConfig]->GetTextStyles().columnHeader, textProp);
                buildIntermediateResultForText(rootView, acoConfig, textProp, key);
            }
            if (![textMap objectForKey:key] || rootView.context.isFirstRowAsHeaders) {
                RichTextElementProperties textProp;
                TexStylesToRichTextElementProperties(txtBlck, [acoConfig getHostConfig]->GetTextStyles().columnHeader, textProp);
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                    buildIntermediateResultForText(rootView, acoConfig, textProp, key);
                    buildIntermediateResultForText(rootView, acoConfig, textProp, key);
                    buildIntermediateResultForText(rootView, acoConfig, textProp, key);
                });
            }
            i++;
        }

        data = textMap[key];
        htmlData = data[@"html"];
        options = data[@"options"];
        descriptor = data[@"descriptor"];
        text = data[@"nonhtml"];
        ……
}

Modify the code of the file(ACRView.mm) as follows:

- (void)enqueueIntermediateTextProcessingResult:(NSDictionary *)data
                                      elementId:(NSString *)elementId
{
    dispatch_sync(_serial_text_queue, ^{
        int i=0;
        while (i<1000) {
            NSLog(@"Test::Change");
            self->_textMap[elementId] = data;
            [self->_textMap removeAllObjects];
            self->_textMap[elementId] = data;
            [self->_textMap removeAllObjects];
            self->_textMap[elementId] = data;
            [self->_textMap removeAllObjects];
            self->_textMap[elementId] = data;
            [self->_textMap removeAllObjects];
            self->_textMap[elementId] = data;
            [self->_textMap removeAllObjects];
            self->_textMap[elementId] = data;
            [self->_textMap removeAllObjects];
            self->_textMap[elementId] = data;
            i++;
        }
    });
}

yanweida99 avatar Aug 08 '22 09:08 yanweida99

@yanweida99 -- Thanks for this detailed report!

@jwoo-msft - care to take a look?

paulcam206 avatar Aug 08 '22 20:08 paulcam206

thanks @yanweida99. I remember you and this issue. I will take a look at it at my next cycle.

Thanks!

jwoo-msft avatar Aug 09 '22 23:08 jwoo-msft

Hi @jwoo-msft , May I know any updates about this bug?

yihuds avatar Dec 08 '22 08:12 yihuds