Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NSDecimal addition generates large number on iOS 18 #930

Open
kbot opened this issue Sep 19, 2024 · 2 comments
Open

NSDecimal addition generates large number on iOS 18 #930

kbot opened this issue Sep 19, 2024 · 2 comments

Comments

@kbot
Copy link

kbot commented Sep 19, 2024

Our production application (linked with iOS 17) has been seeing reports by users updating to iOS 18 that previously valid decimal account balances are now huge numbers.

Our code for calculating the balance:

NSDecimal totalBalanceDec = {0};
    NSArray* arrBalances = (NSArray*)JSON_NULL_SAFE([responseDict objectForKey:@"balances"]);
    NSString* currencyType;
    for (NSDictionary* balance in arrBalances) {
        currencyType = JSON_NULL_SAFE([balance objectForKey:key]);
        if (currencyType && [currencyType isEqualToString:value]) {
            if ([balance objectForKey:@"value"]) {
                NSDecimal decCopy;
                NSDecimalCopy(&decCopy, &totalBalanceDec);
                NSDecimal dec2 = [[balance objectForKey:@"value"] decimalValue];
                NSDecimalAdd(&totalBalanceDec, &decCopy, &dec2, NSRoundPlain);
            }
        }
    }
    return [NSDecimalNumber decimalNumberWithDecimal:totalBalanceDec];

Sample balances response data from our backend:

balances =     (
                {
            balanceType = CREDIT;
            createdDate = 1633544314000;
            creditType = INCENTIVIZED;
            currencyType = USD;
            id = ff8081817c55441b017c56d41d5811f7;
            lastModifiedDate = 1633544314000;
            value = 0;
        },
                {
            balanceType = CREDIT;
            createdDate = 1634856010000;
            creditType = PAID;
            currencyType = USD;
            id = ff8081817ca48459017ca502ffba0288;
            lastModifiedDate = 1726768624000;
            value = "75.2";
        },
                {
            balanceType = CREDIT;
            createdDate = 1637278758000;
            creditType = EARNED;
            currencyType = USD;
            id = ff8081817d00a009017d356b33ae7c58;
            lastModifiedDate = 1725407407000;
            value = "2.22";
        }
    )

Previous to ios 18 this would have produced 77.42 but after updating to iOS 18 it looks like this:
Screenshot 2024-09-19 at 12 23 59 PM

@itingliu
Copy link
Contributor

itingliu commented Oct 2, 2024

I'm not able to when I run it with an SDK containing the ToT swift-foundation. Here's my test case

        NSString *jsonString = @"[\
        {\
            \"balanceType\" : \"CREDIT\",\
            \"createdDate\" : 1633544314000,\
            \"creditType\" : \"INCENTIVIZED\",\
            \"currencyType\" : \"USD\",\
            \"id\" : \"ff8081817c55441b017c56d41d5811f7\",\
            \"lastModifiedDate\" : 1633544314000,\
            \"value\" : 0,\
        },\
        {\
            \"balanceType\" : \"CREDIT\",\
            \"createdDate\" : 1634856010000,\
            \"creditType\" : \"PAID\",\
            \"currencyType\" : \"USD\",\
            \"id\" : \"ff8081817ca48459017ca502ffba0288\",\
            \"lastModifiedDate\" : 1726768624000,\
            \"value\" : \"75.2\",\
        },\
                {\
            \"balanceType\" : \"CREDIT\",\
            \"createdDate\" : 1637278758000,\
            \"creditType\" : \"EARNED\",\
            \"currencyType\" : \"USD\",\
            \"id\" : \"ff8081817d00a009017d356b33ae7c58\",\
            \"lastModifiedDate\" : 1725407407000,\
            \"value\" : \"2.22\",\
        }]";

        NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
        NSError *e;
        NSArray *arrBalances = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&e];
        assert(!e);
        NSDecimal totalBalanceDec = {0};
        for (NSDictionary* balance in arrBalances) {
            NSString* currencyType = [balance objectForKey:@"currencyType"];
            if (currencyType && [currencyType isEqualToString:@"USD"]) {
                if ([balance objectForKey:@"value"]) {
                    NSDecimal decCopy;
                    NSDecimalCopy(&decCopy, &totalBalanceDec);
                    NSDecimal dec2 = [[balance objectForKey:@"value"] decimalValue];
                    NSDecimalAdd(&totalBalanceDec, &decCopy, &dec2, NSRoundPlain);
                }
            }
        }
        NSDecimalNumber *num =  [NSDecimalNumber decimalNumberWithDecimal:totalBalanceDec];
        NSLog(@"num = %f", num.doubleValue); // 77.42

It's possible that it only reproduces for apps linked against 17.0 running on iOS 18 though. If you already have that dev environment setup handy, can you help us verify if that's indeed the case, and would the issue be resolved if you recompile the app?

@kbot
Copy link
Author

kbot commented Oct 7, 2024

We do not have an environment to debug on devices with iOS 18 at the moment, but I can confirm that our production app only experienced this issue for users running iOS 18.

Our immediate workaround was to remove this single dependency on NSDecimal, which resolved the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants