Skip to content

Default to strict file-type registration (fixes #477)#479

Open
andiwand wants to merge 1 commit into
mainfrom
fix/strict-catch-default-477
Open

Default to strict file-type registration (fixes #477)#479
andiwand wants to merge 1 commit into
mainfrom
fix/strict-catch-default-477

Conversation

@andiwand

@andiwand andiwand commented Jul 8, 2026

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Problem

The app registered a true catch-all VIEW intent-filter (content/file scheme with no MIME/extension constraint, plus */*). As a result the OS offered OpenDocument Reader for completely unrelated content — including vCard/contact URIs, as reported in #477.

Root cause

A narrower STRICT_CATCH activity-alias (specific document MIME types + extension patterns) and a landing-screen toggle to switch between them already existed. The real issue was that CATCH_ALL was the default, and the old code force-enabled it on every launch — so narrowing was never a blocker, it just wasn't the default.

Changes

  • Manifest: CATCH_ALLandroid:enabled="false", STRICT_CATCHandroid:enabled="true", so fresh installs are strict from the very first launch (even a cold VIEW-intent launch).
  • MainActivity: the alias choice is now driven by a SharedPreferences flag instead of unreliable component state. New installs and existing users who never touched the switch default to strict; an explicit toggle is remembered. Users who genuinely want catch-all can still opt in via the landing-screen switch.
  • Landing-screen string: reworded for the inverted default (opt in to all-file-types, rather than opt out).

MIME/extension list renewal

Audited the STRICT_CATCH list against what the app actually opens (CoreLoader.isSupported, RawLoader whitelist/blacklist, PDF via pdf2htmlEX) and updated it.

Document types (CoreLoader) — fixed gaps:

  • Added ODF graphics MIME types (…opendocument.graphics / …graphics-template) — the .odg extension patterns were already registered but the MIME type was missing, so .odg content URIs didn't match.
  • Added xlsx (…spreadsheetml.sheet) MIME type + .xlsx extension patterns — supported by CoreLoader with OOXML enabled (the default), previously unreachable in strict mode except via application/octet-stream.
  • pptx intentionally left out — the core still has it disabled (TODO in CoreLoader).

Raw types (RawLoader) — kept openable by default:

  • Registered text/plain, text/csv, image/* and application/zip, plus .txt / .csv / .zip extension patterns, so plain text, images, CSV and zip still offer the app by default.
  • text/plain is used deliberately instead of text/* — a text/* wildcard would re-match text/vcard and reintroduce the exact contacts bug from App registers itself as being able to open signal links from contacts app #477. (RawLoader also blacklists text/vcard, so the app never wanted them anyway.)

Behavior change note

Existing users who relied on the catch-all default now only get offered for the types above by default. They can re-enable all-file-types with the landing-screen switch. This is the intended fix for #477.

Testing

  • ./gradlew :app:compileProDebugJavaWithJavac — passes
  • ./gradlew :app:processProDebugMainManifest — manifest merges cleanly

The app registered a true catch-all VIEW intent-filter (content/file
scheme with no MIME/extension constraint plus */*), so the OS offered
OpenDocument Reader for unrelated content like vCard/contact URIs
(issue #477).

A narrower STRICT_CATCH activity-alias and a landing-screen toggle
already existed, but CATCH_ALL was the default and the old code
force-enabled it on every launch. This makes STRICT_CATCH the default:

- Manifest: CATCH_ALL android:enabled=false, STRICT_CATCH
  android:enabled=true, so fresh installs are strict from first launch.
- MainActivity: drive the alias choice from a SharedPreferences flag
  instead of component state. New installs and existing users who never
  used the switch default to strict; an explicit toggle is remembered.
  Users who want the old behavior can still opt in via the switch.
- Update the landing-screen help text for the inverted default.

Renew the STRICT_CATCH type list to match what the app actually opens:
- CoreLoader: add ODF graphics MIME types (the .odg extension patterns
  were already registered) and xlsx (spreadsheetml.sheet) MIME type and
  .xlsx extension patterns. pptx stays out since the core disables it.
- RawLoader: keep text, images, csv and zip openable by default by
  registering text/plain, text/csv, image/* and application/zip plus
  .txt/.csv/.zip extension patterns. text/plain is used deliberately
  instead of text/* so text/vcard contacts are not matched again (#477).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XXRLLpHb7kGTr6tic2H9LZ
@andiwand andiwand force-pushed the fix/strict-catch-default-477 branch from 492b1c5 to 27ac474 Compare July 8, 2026 20:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 492b1c5c6e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".


<activity-alias
android:name="at.tomtasche.reader.ui.activity.MainActivity.CATCH_ALL"
android:enabled="false"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve file-URI extension matching in strict mode

Disabling CATCH_ALL removes the only default filter that matches an ACTION_VIEW intent carrying a bare file:///.../name.odt URI with no MIME type: the strict extension filters below all require an authority via android:host="*", while normal file:/// URIs have no host. Legacy file managers that send supported documents this way will stop showing the app unless users opt into all-file-types, even though strict mode is supposed to cover document extensions.

Useful? React with 👍 / 👎.

</activity-alias>
<activity-alias
android:name="at.tomtasche.reader.ui.activity.MainActivity.STRICT_CATCH"
android:enabled="true"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep strict mode from matching generic binary MIME

Enabling STRICT_CATCH by default also enables its MIME-only application/octet-stream entry. Android treats a type-only filter as matching content:/file: URIs with that MIME type, so any provider that reports a generic binary type for an unrelated file will still offer OpenDocument Reader with the catch-all switch off. Constrain octet-stream handling to the extension-based filters or remove it from strict mode so the new default is actually document-only.

Useful? React with 👍 / 👎.

@andiwand

andiwand commented Jul 8, 2026

Copy link
Copy Markdown
Member Author

🤖 Generated with Claude Code

@codex - Both suggestions are valid observations, but they're deliberate tradeoffs rather than regressions, so leaving strict mode as-is:

P2 – application/octet-stream in strict mode: kept intentionally. Many file providers report application/octet-stream for .odt/.ods files they don't recognize; dropping it would stop the app being offered for those documents, and the extension-based filters can't reliably backfill (they require a URI authority — see below). It was already present in the old catch-all, and it does not reintroduce #477 — that bug was text/vcard, which strict mode no longer matches.

P2 – hostless file:///…​.odt matching: only affects legacy file managers that send file:// URIs (no host) with a null MIME type. Modern Android (API 24+) pushes content:// URIs, which always carry a MIME type and match the strict filters, and discourages file:// exposure. The old CATCH_ALL also gated its scheme filters on host="*", so this path was already fragile. Low practical risk, so not worth the extra filter surface here.

Net: #477 (vCard/contacts catch-all) is fixed, and the strict default stays document-oriented while still covering the common provider cases.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant