Catch all bundletool exceptions when matching device APKs#92
Catch all bundletool exceptions when matching device APKs#92thomasbuilds wants to merge 1 commit into
Conversation
|
Hmm. If the DeviceSpec is invalid, I'm wondering if we should treat that as an invalid request instead of an incompatible device. We already have some protovalidate rules on our Buf-packaged version of bundletool's protobuf definitions. We could add to those (or the app store API protos) and get further validation basically for free, but I haven't mapped out all of the possible exceptions bundletool could throw through ApkMatcher and why, so that approach might not have accurate semantics. Overall I'm thinking:
What do you think? Also FYI, the directory server is being subsumed by Parcelo, so changes to it fit better there since that's where active development is happening. This change is fine here, but I'll eventually copy it over to Parcelo anyway. |
|
Yeah, I think an invalid spec should be I'd lean toward validation over a catch because the exception type doesn't reliably tell those two apart. Running a few specs through ApkMatcher, the same unrecognized ABI comes back as an On completeness, the For the implementation I think you're right that protovalidate is the way to go for the ABI case. The existing DeviceSpec rules and validateDeviceSpec only check that the lists are non-empty and sdk/density are positive, so we'd add something like restricting |
GetAppDownloadInfo and GetAppUpdateInfo pass a fully client-controlled device spec to bundletool's ApkMatcher. protovalidate only checks that supported_abis is non-empty, not that its entries name real ABIs, so an unrecognized ABI reaches the matcher. bundletool then reports it inconsistently: an IncompatibleDeviceException for split APKs (or silently ignores it when an ABI the app ships a split for precedes it in the list) and an InvalidCommandException for multi-ABI ones. Mapping by exception type would give the same malformed spec different status codes depending on the app. Validate supported_abis against bundletool's known ABI names before matching and reject unrecognized ones with INVALID_ARGUMENT, so a malformed spec is treated as a bad request rather than an incompatible device. Separately, some matchers reject the spec without raising a BundleToolException: DeviceTierApkMatcher and CountrySetApkMatcher call Guava's checkArgument when the spec's device_tier / country_set doesn't match the bundle's declared values, and OpenGlFeatureMatcher throws a NumberFormatException decoding the spec's reqGlEsVersion device feature. The tier and country set values are bundle-relative, so protovalidate can't cover them. Widen getMatchingApkPaths's catch from IncompatibleDeviceException to BundleToolException and IllegalArgumentException so such specs yield an empty match (FAILED_PRECONDITION) instead of escaping uncaught.
|
For the time being I've implemented the supported_abis check in code rather than as a protovalidate rule, since the rules live in android-bundle / appstore-api |
GetAppDownloadInfo and GetAppUpdateInfo pass a fully client-controlled device spec to bundletool's ApkMatcher. Only the spec's presence is validated (the appstore-api DeviceAttributes.spec field is required, but its contents are not), so arbitrary device specs reach bundletool.
getMatchingApkPaths only caught IncompatibleDeviceException, but bundletool rejects specs it cannot interpret with other sibling BundleToolException subtypes. For example, an app whose bundle has multi-ABI variant targeting causes MultiAbiMatcher to throw an InvalidCommandException for an unrecognized ABI in the device spec. Those escaped uncaught instead of being treated as an incompatible device.
Catch the common BundleToolException base instead so any device spec bundletool cannot match or interpret yields an empty match set.