Change defusing for lazy bundles
With lazy bundle, exceptions thrown by deserialization of custom items moved from being thrown in initializeFromParcelLocked() (when the bundle is first touched) to being thrown in getValueAt() (whenever the item is retrieved), which means they were escaping the defuse logic that caught those exceptions. So, now also catching these exceptions in getValueAt(), however, here we can be much less drastic, instead of erasing the bundle, we can simply remove the bad element. This also means we don't need to log wtf in initializeFromParcelLocked() if sShouldDefuse = true but the bundle is not marked as defusable, since touching the bundle doesn't carry the same consequences as before go/lazy-bundle. So, I moved that log to unparcel(itemwise = true), ie. whenever the entire bundle is deserialized on purpose. Now, 2 types of defusing can happen: 1. If the (custom) item we're retrieving caused the exception, we'll remove the item and return null. 2. If the exception was raised during partial deserialization, that is, during the read of the map and its basic types (while skipping custom types), the map will be left empty. I believe only manually written parcels would cause this type of exception and if an exception is raised here it will also be raised in the final destination too, afaict. Because of this, we can now touch app-provided bundles without fear of clobbering the data on its way to the final destination. Following conversation on previous CL, narrowed exception raised in case of unknown type to be BadParcelableException. Test: atest -d android.os.cts.ParcelTest android.os.cts.BundleTest android.os.BundleTest android.os.ParcelTest Bug: 195622897 Change-Id: I4746140f63482a9ea475aac25897a447737393e4
Loading
Please register or sign in to comment