microsoft / microsoft/AdaptiveCards

[Rendering] iOS App crash

Open
#7,748 3 comments 0 reactions 1 assignee View on GitHub

@jwoo-msft is already working on this.

Since Aug 8, 2022.

Area-Renderers Bug
Dominant language
C#
Stars
2k
Forks
595
Avg merge
1d 19h
Merged PRs (30d)
1

Description

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++;
        }
    });
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.