ReviewOS

craft-native/craft

fix(android): finish native validation of kept private images (#414 follow-up)

#417
Closed glennmichael123 opened this 7 days ago ·
7 days ago

Split from #414

The iOS portion of #414 is implemented and simulator-verified. At the requester’s direction, Android completion is tracked independently here rather than holding the iOS issue open.

Current implementation

Android already has the kept-image loader on main in 1e866bb. This is not a request to implement it again. MainActivityNative.kt.template checks CraftNativeMedia.local(this, uri) before the public image cache/network, while retaining the existing image-source scheme policy.

Commit 2107ffe strengthens keptPrivateImageLoadsOfflineWithoutEnteringPublicCache in NativeNavigationTest.kt: an explicit protocol node is updated through updateNode, and assertions verify that the same mounted ImageView handles source replacement.

Remaining verification

Earlier API 34 and API 35 runs failed at "kept bytes must not allow arbitrary file URLs" after successfully displaying the kept image. The fixture retained an ImageView reference across full-document renders; a stale reference was suspected but has NOT been established as the root cause. The revised fixture must pass native instrumentation before Android is considered complete. Source-contract tests alone are not sufficient.

The latest main Mobile E2E run was still pending when this issue was filed: https://github.com/craft-native/craft/actions/runs/40326490959

Acceptance

  • Run the kept-private-image instrumentation regression on Android API 34 and 35; investigate and fix any failure rather than relaxing assertions.
  • A kept image keyed by an HTTPS .invalid address loads offline into the mounted ImageView with the expected pixels.
  • Private bytes do not enter the public image cache.
  • Arbitrary file URLs remain rejected and clear the previous image.
  • Source mutations retain the mounted view; late decode results cannot replace a newer source.
  • A corrupt kept copy reports an error without silently fetching a network replacement.
  • Publish the Android package containing the verified implementation and name the actual published version in the closing comment.

As checked on 26 October 2026, the published @craft-native/android version is still 0.0.358 and does not contain this fix. The application should keep the response with craft.media.keep(url, { headers }) and use the original HTTPS URL as the image source, not a picker/download filesystem path.

6 days ago

Shipped and verified in @craft-native/android 0.0.369.

The exact release commit 447523f passed Mobile E2E: https://github.com/craft-native/craft/actions/runs/40491395933 . I downloaded its API 34 and API 35 instrumentation artifacts rather than relying on the workflow badge. Each XML report contains 84 tests with zero failures/errors/skips and explicitly records keptPrivateImageLoadsOfflineWithoutEnteringPublicCache passing (API 34: 4.31s; API 35: 3.624s).

That test exercises the mounted protocol ImageView: offline HTTPS .invalid kept bytes and expected red pixels, no public cache insertion, arbitrary file URL rejection and clearing, in-place source mutation, rejection of late decode completion, and an error for corrupt kept bytes without a network fallback. The fixture isolates its protocol document from Home runtime updates; it does not relax these assertions.

The downloaded npm 0.0.369 MainActivityNative.kt.template SHA-256-matches the tested tag source (9651850a447770218fc95857d40280b5cdc8074de9a50ee24d46876b1dcc8959). Release publication succeeded: https://github.com/craft-native/craft/actions/runs/40491396336 . Applications can keep an authenticated response with craft.media.keep(url, { headers }) and render the original HTTPS URL; arbitrary filesystem paths remain unsupported.

Sign in to comment on this issue.