[GH-ISSUE #1470] [Bug] inspect-artifact rejects a valid APK whose entries differ only in case #499

Closed
opened 2026-10-15 18:25:37 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @CassieFox23 on GitHub (Oct 10, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1470

TL;DR: inspect-artifact rejects a valid release APK because two of its files differ only in case. So project-android-application-graph can't run on that APK. Shrunk release APKs often have such pairs.

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

The APK is Coffee 2.27 from F-Droid (com.github.muellerma.coffee, Apache-2.0). Its SHA-256 matches F-Droid's signed index.

rea inspect-artifact coffee.apk --format json

It exits 1 with artifact_operation_failed, reason path:

Artifact path collision: res/2f.xml differs only in case from res/2F.xml

Both entries really exist, at 724 and 1,916 bytes. The APK has 39 such pairs among 840 entries. Release builds shrink resource names like this. Zip names are case-sensitive, and Android installs the APK fine.

Adding --integrity-policy record-and-continue gives the same failure.

Reproduction

  1. Download com.github.muellerma.coffee_47.apk from https://f-droid.org/repo/.
  2. Run rea inspect-artifact <apk> --format json.
  3. unzip -l <apk> | grep -i 'res/2f.xml' lists both entries.

Expected behavior

The APK's inventory loads, so project-android-application-graph can use it. Two ideas:

  • Keep both entries, since zip names are case-sensitive.
  • Or record the pairs as a limitation and continue.

The check makes sense when files get extracted onto a case-insensitive disk. An APK inventory may not need it.

Impact and scope

The other five Android commands work on this APK. That covers package, class search, class, method and references. Only the graph is blocked, because its input comes from inspect-artifact.

The check lives in ArtifactPathRegistry in src/artifacts/ArtifactPaths.ts. It folds every path part to lower case. Main at 4e3d3354 still has it.

Interface

CLI.

Earliest failure stage

Artifact or evidence registration

Not run

Edit: #1480 fixed this. Three of these items ran, in the #1480 check. Still not run: macOS or Windows. Also, the 39 "pairs" above are 39 groups with 79 names. One group is a triple.

  • Other shrunk release APKs. I expect the same failure, but I only tested this one. Five more F-Droid apps hit it before #1480.
  • The MCP surface, and open_binary as another route. MCP failed the same way before #1480 and works after it.
  • The graph command on an APK without case pairs. It ran on WordleSolver (GPL-3.0-only), before and after the fix.
  • macOS or Windows. Their default disks ignore case, so the risk there differs.

Edit: The sources for WordleSolver do not agree on its licence. F-Droid says GPL-3.0-only, the repo's LICENSE file says Apache-2.0, and the source headers say GPL-3.0-or-later.

Test setup
  • Box: Nobara 44 (Fedora 44 base), Linux 7.2.9
  • CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads
  • RAM: 32 GB DDR4-3600
  • Node: 22.23.1 and 26.11.1, same result
  • REA: 6.3.0 (released package); main 4e3d3354 source read only
  • Android: JADX via REA_JADX_MCP_JAR, on Temurin JDK 21 (GPL-2.0 with Classpath Exception)

🤖 Generated with Claude Code (Opus 5.5) 🦊

Originally created by @CassieFox23 on GitHub (Oct 10, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1470 **TL;DR:** `inspect-artifact` rejects a valid release APK because two of its files differ only in case. So `project-android-application-graph` can't run on that APK. Shrunk release APKs often have such pairs. ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior The APK is [Coffee 2.27](https://f-droid.org/packages/com.github.muellerma.coffee/) from F-Droid (`com.github.muellerma.coffee`, [Apache-2.0](https://github.com/mueller-ma/Coffee/blob/main/LICENSE)). Its SHA-256 matches F-Droid's signed index. ``` rea inspect-artifact coffee.apk --format json ``` It exits 1 with `artifact_operation_failed`, reason `path`: ``` Artifact path collision: res/2f.xml differs only in case from res/2F.xml ``` Both entries really exist, at 724 and 1,916 bytes. The APK has 39 such pairs among 840 entries. Release builds shrink resource names like this. Zip names are case-sensitive, and Android installs the APK fine. Adding `--integrity-policy record-and-continue` gives the same failure. ### Reproduction 1. Download [`com.github.muellerma.coffee_47.apk`](https://f-droid.org/repo/com.github.muellerma.coffee_47.apk) from [https://f-droid.org/repo/](https://f-droid.org/repo/). 2. Run `rea inspect-artifact <apk> --format json`. 3. `unzip -l <apk> | grep -i 'res/2f.xml'` lists both entries. ### Expected behavior The APK's inventory loads, so `project-android-application-graph` can use it. Two ideas: - Keep both entries, since zip names are case-sensitive. - Or record the pairs as a limitation and continue. The check makes sense when files get extracted onto a case-insensitive disk. An APK inventory may not need it. ### Impact and scope The other five Android commands work on this APK. That covers package, class search, class, method and references. Only the graph is blocked, because its input comes from `inspect-artifact`. The check lives in `ArtifactPathRegistry` in `src/artifacts/ArtifactPaths.ts`. It folds every path part to lower case. Main at `4e3d3354` still has it. ### Interface CLI. ### Earliest failure stage Artifact or evidence registration ### Not run Edit: #1480 fixed this. Three of these items ran, in [the #1480 check](https://github.com/morluto/rea/pull/1480#issuecomment-6095273878). Still not run: macOS or Windows. Also, the 39 "pairs" above are 39 groups with 79 names. One group is a triple. - ~~Other shrunk release APKs. I expect the same failure, but I only tested this one.~~ Five more F-Droid apps hit it before #1480. - ~~The MCP surface, and `open_binary` as another route.~~ MCP failed the same way before #1480 and works after it. - ~~The graph command on an APK without case pairs.~~ It ran on [WordleSolver](https://f-droid.org/packages/org.billthefarmer.solver/) ([GPL-3.0-only](https://gitlab.com/fdroid/fdroiddata/-/blob/93455203833a2fe27d499d6f7870319a23712004/metadata/org.billthefarmer.solver.yml#L4)), before and after the fix. - macOS or Windows. Their default disks ignore case, so the risk there differs. Edit: The sources for WordleSolver do not agree on its licence. F-Droid says `GPL-3.0-only`, the repo's [LICENSE](https://github.com/billthefarmer/wordlesolver/blob/59180002e66c3befaebdbbf0a41073baf9f0cef4/LICENSE) file says `Apache-2.0`, and the [source headers](https://github.com/billthefarmer/wordlesolver/blob/59180002e66c3befaebdbbf0a41073baf9f0cef4/src/main/java/org/billthefarmer/solver/Main.java#L8-L10) say `GPL-3.0-or-later`. <details> <summary>Test setup</summary> - Box: Nobara 44 (Fedora 44 base), Linux 7.2.9 - CPU: AMD Ryzen 9 5900X, 12 cores / 24 threads - RAM: 32 GB DDR4-3600 - Node: 22.23.1 and 26.11.1, same result - REA: 6.3.0 (released package); main `4e3d3354` source read only - Android: JADX via `REA_JADX_MCP_JAR`, on [Temurin JDK 21](https://adoptium.net/) ([GPL-2.0 with Classpath Exception](https://github.com/adoptium/jdk21u/blob/master/LICENSE)) </details> 🤖 Generated with Claude Code (Opus 5.5) 🦊
bsakaguchi 2026-10-15 18:25:37 +00:00
Author
Owner

@CassieFox23 commented on GitHub (Oct 10, 2026):

TL;DR: Fixed by #1480. Coffee 2.27 now loads, and the Android graph runs on it. The full check is in the #1480 comment: here.

Check on Coffee 2.27 (Apache-2.0) 7296f2b5b 1f0775684
inspect-artifact exit 1, path collision exit 0
project-android-application-graph no input to give it exit 0

Five more F-Droid apps with case pairs failed on 7296f2b5b. All five load on 1f0775684. One fix to my count above: Coffee has 39 groups with 79 names, not 39 pairs. One group is a triple.

Not run

  • Extraction to a disk that ignores case. Mounting one here needs root.
  • macOS or Windows.

Thanks, morluto, for the quick fix.

Test setup
  • Box: Nobara 44 (Fedora 44 base), Linux 7.2.9
  • Node: 22.23.1, 24.18.0, 26.11.1
  • Head / base: 1f0775684 / 7296f2b5b

🤖 Generated with Claude Code (Opus 5.5) 🦊

<!-- gh-comment-id:6095274647 --> @CassieFox23 commented on GitHub (Oct 10, 2026): **TL;DR:** Fixed by #1480. Coffee 2.27 now loads, and the Android graph runs on it. The full check is in the #1480 comment: [here](https://github.com/morluto/rea/pull/1480#issuecomment-6095273878). | Check on [Coffee 2.27](https://f-droid.org/packages/com.github.muellerma.coffee/) ([Apache-2.0](https://github.com/mueller-ma/Coffee/blob/main/LICENSE)) | `7296f2b5b` | `1f0775684` | |---|---|---| | `inspect-artifact` | exit 1, path collision | exit 0 | | `project-android-application-graph` | no input to give it | exit 0 | Five more F-Droid apps with case pairs failed on `7296f2b5b`. All five load on `1f0775684`. One fix to my count above: Coffee has 39 groups with 79 names, not 39 pairs. One group is a triple. ### Not run - Extraction to a disk that ignores case. Mounting one here needs root. - macOS or Windows. Thanks, morluto, for the quick fix. <details> <summary>Test setup</summary> - Box: Nobara 44 (Fedora 44 base), Linux 7.2.9 - Node: 22.23.1, 24.18.0, 26.11.1 - Head / base: `1f0775684` / `7296f2b5b` </details> 🤖 Generated with Claude Code (Opus 5.5) 🦊
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#499
No description provided.