Skip to content

Conversation

@pushpender-singh-ap
Copy link
Owner

Harden native unarchive implementations on both platforms. Enforce app-sandbox output paths, perform atomic final swaps, and ensure bridge-safe result construction on the main thread. Adds cancellation and relative-path metadata, updates TypeScript spec and docs.


Key changes

  • iOS (ios/Unarchive.mm, ios/Unarchive.h)

    • Added isOutputPathInSandbox: and early rejection with UNARCHIVE_INVALID_PATH.
    • Extract to a temporary directory and atomically replace the final output using replaceItemAtURL:withItemAtURL: (with appropriate fallback/cleanup).
    • Build/resolve the final result on the main thread and copy immutable data before dispatch.
    • Cooperative cancellation (cancelUnarchive) and improved debug diagnostics.
    • ZIP-SLIP validation and canonicalization checks.
  • Android (android/src/main/java/com/unarchive/UnarchiveModule.kt)

    • Enforce isPathAllowed() (app-scoped paths only).
    • Atomic move with rename-backup fallback (atomicMoveOrFallback).
    • Single FileOutputStream per entry and stream-safe extraction.
    • Job-tracked cancellation and isActive checks.
    • Collect POJOs on background thread; convert to WritableNativeArray/WritableNativeMap on Dispatchers.Main.
  • TypeScript / JS

    • src/NativeUnarchive.ts / src/index.tsx:
      • Added cancelUnarchive() and CancelResult.
      • Added relativePath to FileInfo.
  • Docs / Release

    • Updated README.md with sandbox/path/security guidance and new API docs.
    • Added CHANGELOG.md.
    • Example app updated to reflect sandbox path selection, cancellation UI, sharing/export features.

Files worth reviewing

  • ios/Unarchive.mm
  • ios/Unarchive.h
  • android/src/main/java/com/unarchive/UnarchiveModule.kt
  • src/NativeUnarchive.ts
  • src/index.tsx
  • README.md
  • CHANGELOG.md
  • example/src/App.tsx

Migration notes / Breaking changes

  • Output paths must be within app sandbox:
    • iOS: Documents, Caches, or tmp directories only (use DocumentDirectoryPath, CachesDirectoryPath, or TemporaryDirectoryPath).
    • Android: context.filesDir, context.cacheDir, or context.getExternalFilesDir(null) (use DocumentDirectoryPath or app-specific external files path).
  • Concurrency: Only one extraction at a time per module instance. Concurrent attempts receive UNARCHIVE_BUSY.
  • Error handling: Use error.code for programmatic handling (new, granular error codes).

@pushpender-singh-ap pushpender-singh-ap self-assigned this Oct 5, 2025
@pushpender-singh-ap pushpender-singh-ap added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request labels Oct 5, 2025
@pushpender-singh-ap pushpender-singh-ap merged commit 8f61438 into main Oct 5, 2025
4 of 5 checks passed
@pushpender-singh-ap pushpender-singh-ap deleted the fix/sandbox-atomic-mainthread branch October 5, 2025 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant