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

[expo-in-app-purchases] Add defensive null checks and missing iOS SKErrorCode values #11773

Merged
merged 3 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public Context getContext() {
*/
@Override
public void onPurchasesUpdated(BillingResult result, List<Purchase> purchases) {
if (result.getResponseCode() == BillingResponseCode.OK) {
if (result.getResponseCode() == BillingResponseCode.OK && purchases != null) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
}
Expand Down Expand Up @@ -263,11 +263,11 @@ public void run() {
PurchasesResult purchasesResult = mBillingClient.queryPurchases(SkuType.INAPP);

// If there are subscriptions supported, we add subscription rows as well
if (areSubscriptionsSupported()) {
if (purchasesResult != null && areSubscriptionsSupported()) {
PurchasesResult subscriptionResult
= mBillingClient.queryPurchases(SkuType.SUBS);

if (subscriptionResult.getResponseCode() == BillingResponseCode.OK) {
if (subscriptionResult != null && subscriptionResult.getResponseCode() == BillingResponseCode.OK) {
purchasesResult.getPurchasesList().addAll(
subscriptionResult.getPurchasesList());
}
Expand Down Expand Up @@ -441,7 +441,7 @@ private static Bundle purchaseHistoryToBundle(PurchaseHistoryRecord purchaseReco
*/
private void onQueryPurchasesFinished(PurchasesResult result, final Promise promise) {
// Have we been disposed of in the meantime? If so, or bad result code, then quit
if (mBillingClient == null || result.getResponseCode() != BillingResponseCode.OK) {
if (mBillingClient == null || result == null || result.getResponseCode() != BillingResponseCode.OK) {
promise.reject("E_QUERY_FAILED", "Billing client was null or query was unsuccessful");
return;
}
Expand Down Expand Up @@ -481,7 +481,7 @@ public void onSkuDetailsResponse(BillingResult inAppResult,
mBillingClient.querySkuDetailsAsync(subs.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> subscriptionDetails) {
if (skuDetails != null) {
if (skuDetails != null && subscriptionDetails != null) {
skuDetails.addAll(subscriptionDetails);
}
listener.onSkuDetailsResponse(billingResult, skuDetails);
Expand All @@ -501,9 +501,11 @@ public void queryPurchasableItems(List<String> itemList, final Promise promise)
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
ArrayList<Bundle> results = new ArrayList<>();
for (SkuDetails skuDetails : skuDetailsList) {
mSkuDetailsMap.put(skuDetails.getSku(), skuDetails);
results.add(skuToBundle(skuDetails));
if (skuDetailsList != null) {
for (SkuDetails skuDetails : skuDetailsList) {
mSkuDetailsMap.put(skuDetails.getSku(), skuDetails);
results.add(skuToBundle(skuDetails));
}
danmaas marked this conversation as resolved.
Show resolved Hide resolved
}
Bundle response = formatResponse(billingResult, results);
promise.resolve(response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ - (void)handleQuery:(SKProductsResponse *)response {
NSMutableArray *result = [NSMutableArray array];

for (SKProduct *validProduct in response.products) {
if(!validProduct.localizedDescription) { continue; } // skip product with nil values - this can happen if it is in review "rejected" state
danmaas marked this conversation as resolved.
Show resolved Hide resolved
NSDictionary *productData = [self getProductData:validProduct];
[result addObject:productData];
}
Expand All @@ -167,6 +168,7 @@ -(void)handlePurchase:(SKProductsResponse *)response {
}

for (SKProduct *validProduct in response.products) {
if(!validProduct.localizedDescription) { continue; } // skip product with nil values - this can happen if it is in review "rejected" state
danmaas marked this conversation as resolved.
Show resolved Hide resolved
[self purchase:validProduct];
}
}
Expand Down Expand Up @@ -422,12 +424,14 @@ - (int)errorCodeNativeToJS:(SKErrorCode)errorCode
case SKErrorPaymentInvalid:
case SKErrorPaymentNotAllowed:
case SKErrorPaymentCancelled:
case SKErrorOverlayCancelled:
return 1;
case SKErrorStoreProductNotAvailable:
return 6;
case SKErrorCloudServiceRevoked:
case SKErrorCloudServicePermissionDenied:
case SKErrorCloudServiceNetworkConnectionFailed:
case SKErrorOverlayTimeout:
danmaas marked this conversation as resolved.
Show resolved Hide resolved
return 10;
case SKErrorPrivacyAcknowledgementRequired:
return 11;
Expand All @@ -436,8 +440,11 @@ - (int)errorCodeNativeToJS:(SKErrorCode)errorCode
case SKErrorInvalidSignature:
case SKErrorInvalidOfferPrice:
case SKErrorInvalidOfferIdentifier:
case SKErrorOverlayInvalidConfiguration:
case SKErrorIneligibleForOffer:
return 13;
case SKErrorMissingOfferParams:
case SKErrorUnsupportedPlatform:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know what triggers this? Is it e.g. Catalyst code on macOS for an app that supports IAPs only on iOS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't know what triggers SKErrorUnsupportedPlatform. The Apple docs are empty (https://developer.apple.com/documentation/storekit/skerrorcode/skerrorunsupportedplatform).

I will reassign this to 0 (UNKNOWN) for now. (I've also commented the magic numbers to show which IAPErrorCode enum value they correspond to).

return 14;
default:
return 0;
Expand Down