ReviewOS

craft-native/craft

fix(ios): openURL, setBadge and setFlashlight never settle on a malformed argument in Swift

#221
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Three Swift dispatcher cases answer only when their argument casts, and have no else:

case "openURL":
    if let urlString = body["url"] as? String, let url = URL(string: urlString) {
        UIApplication.shared.open(url)
        resolveCallback(callbackId, result: true)
    }
case "setBadge":
    if let count = body["count"] as? Int {
        setBadgeCount(count, callbackId: callbackId)
    }
case "setFlashlight":
    if let enabled = body["enabled"] as? Bool {
        setFlashlight(enabled: enabled, callbackId: callbackId)
    }

All three page methods post a callbackId and return a promise. So craft.openURL(undefined), craft.openURL('not a url'), craft.setBadge('3') and craft.setFlashlight('on') never settle on the Swift path.

Where it bites

Zig serves all three first (bridge_mobile_system.zig, bridge_mobile_display.zig, bridge_mobile_misc.zig), so this path runs:

  • in apps built without the Zig runtime;
  • in a Zig build when the payload cannot be serialized (CraftZigRuntime.offer returns false for an invalid JSON object and Swift answers instead).

Fix

Reject with INVALID_ARGUMENT in each else, using the same code share uses for nothing to share.

ios_conformance_test.zig could also catch the class. Among the checks added for #207 is one that a case the page waits on can resolve. The next step is a check that no if let inside such a case ends without an else that answers. The scan is harder to make exact, so start with a recorded list of the three cases above that may only shrink.

Found while fixing #207.

9 days ago

The Siri pair has the same shape, found while fixing #211: case "registerSiriShortcut" and case "removeSiriShortcut" are if let … as? String with no else, so a missing or mistyped shortcutAction or phrase never settles on the Swift path. Zig refuses both with MissingData or InvalidParameter (bridge_mobile_siri.zig, readFields). Worth fixing in the same change.

Sign in to comment on this issue.