fix: avoid assumptions about res dir#4067
Merged
IgorEisberg merged 3 commits intomainfrom Jan 14, 2026
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes issues where Apktool made incorrect assumptions about resource directory locations during decoding. Previously, directories named res, R, or r were assumed to contain only file resources, which caused problems when these directories appeared in JARs without a resources.arsc file (like framework.jar).
Changes:
- Removed hardcoded assumptions about resource directory names (
RESOURCES_DIRNAMES) - Modified behavior to trust only
resources.arscas the source of truth for file resources - Refactored
Directoryinterface to use varargs for improved utility - Updated test expectations to reflect new behavior where unrecognized resource directories go to
unknownfolder
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| brut.j.dir/src/main/java/brut/directory/Directory.java | Changed method signatures to use varargs instead of explicit arrays |
| brut.j.dir/src/main/java/brut/directory/AbstractDirectory.java | Implemented varargs methods by reordering single and multi-argument implementations |
| brut.apktool/apktool-lib/src/test/java/brut/androlib/AndResGuardTest.java | Updated test to expect r folder contents in unknown directory when decoding without resources |
| brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/data/StyledString.java | Removed unused import |
| brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java | Simplified logic by removing special-case handling and always mapping input to output filenames |
| brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/ApkInfo.java | Removed RESOURCES_DIRNAMES constant and its usage in STANDARD_FILENAMES_PATTERN |
| brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java | Removed copying of RESOURCES_DIRNAMES directories in raw resource mode |
| brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkBuilder.java | Refactored build logic with improved file freshness checking and consolidated resource building methods |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
iBotPeaches
approved these changes
Jan 14, 2026
iBotPeaches
added a commit
to iBotPeaches/apktool.org
that referenced
this pull request
Jan 14, 2026
EduardoA3677
pushed a commit
to EduardoA3677/Apktool
that referenced
this pull request
Feb 4, 2026
* Initial plan * fix: tighten span tag parsing (iBotPeaches#4061) * fix: avoid assumptions about res dir (iBotPeaches#4067) * refactor: nested dex + replace --only-main-classes with -a/--all-src (iBotPeaches#4069) * refactor: source and tests (iBotPeaches#4071) * chore: promote -a/--all-src to a common option (iBotPeaches#4072) * build(deps): bump com.android.tools:r8 from 8.13.17 to 8.13.19 (iBotPeaches#4064) Bumps com.android.tools:r8 from 8.13.17 to 8.13.19. --- updated-dependencies: - dependency-name: com.android.tools:r8 dependency-version: 8.13.19 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * minor: TextUtils hotfix (iBotPeaches#4079) * refactor: new BinaryXmlResourceParser, ResXmlSerializer and more (iBotPeaches#4077) * build: migrate to modern maven publish (iBotPeaches#4073) * build: migrate to modern maven publish * build: move to v0.36 * build: use v33 for Java 11 min * build: skip maven on unsupported Java versions * chore: configure codeql manually * build: defer maven publishing till jdk11 * chore: move publising to own file * build(deps): bump gradle/actions from 5.0.0 to 5.0.1 (iBotPeaches#4080) Bumps [gradle/actions](https://github.com/gradle/actions) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/gradle/actions/releases) - [Commits](gradle/actions@v5...v5.0.1) --- updated-dependencies: - dependency-name: gradle/actions dependency-version: 5.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: ensure proper locale in ResPrimitive (iBotPeaches#4084) Signed-off-by: Salvo Giangreco <giangrecosalvo9@gmail.com> * feat: support for API 36.1 (Baklava) (iBotPeaches#4082) * feat: staged aliases support (iBotPeaches#4085) * fix: framework parse performed twice (iBotPeaches#4086) * fix: framework parse performed twice * fix up dynamic references with calling pkgId * Fix merge conflict markers in SmaliDecoder.java * Fix compilation errors in SmaliDecoder and AaptInvoker --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Salvo Giangreco <giangrecosalvo9@gmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Igor Eisberg <8811086+IgorEisberg@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Connor Tumbleson <iBotPeaches@users.noreply.github.com> Co-authored-by: Salvo Giangreco <giangrecosalvo9@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes: #3507
Fixes: #3615
Fixes: #3810
Background:
When building,
resfolder is the only recognized folder for resources. That is unambiguous.That isn't true when decoding. While
assetsandlibare reserved names by the system, there is no requirement that file resources are all underresin an APK - they can be anywhere (even inassetsandlib) and obfuscators exploit it.The only arbiter of what is a file resource and what isn't is
resources.arsc.We already handle filtering file resources under
assetsandlib(only possible by an obfuscator) when decoding with resources, but we were still assuming thatres/R/rwere guaranteed to contain file resources only. This caused misc files inresfolder to be dropped when they appeared in JARs likeframework.jar, which doesn't have aresources.arsc, and thus no file resources either.Solution:
Make no assumptions about the location of file resources at all. Paths of file resources can only be determined when decoding with resources by trusting
resources.arsc. Anything that wasn't referenced inresources.arscis inherently unknown and goes to theunknownfolder to be repacked as-is.Note:
When decoding without resources,
resources.arscis not parsed and no file resource paths are established, thus all "potential resources folders" (res,R,ror whatever) end up inunknownand will be repacked as-is.The advantage: We no longer need to explicitly hardcode "potential resources folders" in Apktool. We trust
resources.arsconly.Extra:
Tweaked the appropriate test for this change.
Tweaked
Directoryto use varargs instead of explicit array for more utility.Cleaned an unused import and some old code that isn't used anymore.
Tested on a full ROM rebuild. No diffs except
framework.jarthat is now decoded properly.