fix: close open files (#75)

This commit is contained in:
dan1st 2022-08-07 00:16:23 +02:00 committed by GitHub
parent 09f6ab4155
commit 123ad54c15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -49,70 +49,74 @@ class Patcher(private val options: PatcherOptions) {
init { init {
val extInputFile = ExtFile(options.inputFile) val extInputFile = ExtFile(options.inputFile)
val outDir = File(options.resourceCacheDirectory) try {
if (outDir.exists()) { val outDir = File(options.resourceCacheDirectory)
logger.info("Deleting existing resource cache directory") if (outDir.exists()) {
outDir.deleteRecursively() logger.info("Deleting existing resource cache directory")
} outDir.deleteRecursively()
outDir.mkdirs() }
outDir.mkdirs()
val androlib = Androlib(BuildOptions().also { it.setBuildOptions(options) }) val androlib = Androlib(BuildOptions().also { it.setBuildOptions(options) })
val resourceTable = androlib.getResTable(extInputFile, true) val resourceTable = androlib.getResTable(extInputFile, true)
val packageMetadata = PackageMetadata() val packageMetadata = PackageMetadata()
if (options.patchResources) { if (options.patchResources) {
logger.info("Decoding resources") logger.info("Decoding resources")
// decode resources to cache directory // decode resources to cache directory
androlib.decodeManifestWithResources(extInputFile, outDir, resourceTable) androlib.decodeManifestWithResources(extInputFile, outDir, resourceTable)
androlib.decodeResourcesFull(extInputFile, outDir, resourceTable) androlib.decodeResourcesFull(extInputFile, outDir, resourceTable)
// read additional metadata from the resource table // read additional metadata from the resource table
packageMetadata.metaInfo.usesFramework = UsesFramework().also { framework -> packageMetadata.metaInfo.usesFramework = UsesFramework().also { framework ->
framework.ids = resourceTable.listFramePackages().map { it.id }.sorted() framework.ids = resourceTable.listFramePackages().map { it.id }.sorted()
}
packageMetadata.metaInfo.doNotCompress = buildList {
androlib.recordUncompressedFiles(extInputFile, this)
}
} else {
logger.info("Only decoding AndroidManifest.xml because resource patching is disabled")
// create decoder for the resource table
val decoder = ResAttrDecoder()
decoder.currentPackage = ResPackage(resourceTable, 0, null)
// create xml parser with the decoder
val axmlParser = AXmlResourceParser()
axmlParser.attrDecoder = decoder
// parse package information with the decoder and parser which will set required values in the resource table
// instead of decodeManifest another more low level solution can be created to make it faster/better
XmlPullStreamDecoder(
axmlParser, AndrolibResources().resXmlSerializer
).decodeManifest(
extInputFile.directory.getFileInput("AndroidManifest.xml"), nullOutputStream
)
} }
packageMetadata.metaInfo.doNotCompress = buildList { packageMetadata.packageName = resourceTable.currentResPackage.name
androlib.recordUncompressedFiles(extInputFile, this) packageMetadata.packageVersion = resourceTable.versionInfo.versionName
} packageMetadata.metaInfo.versionInfo = resourceTable.versionInfo
packageMetadata.metaInfo.sdkInfo = resourceTable.sdkInfo
} else { logger.info("Reading dex files")
logger.info("Only decoding AndroidManifest.xml because resource patching is disabled")
// create decoder for the resource table // read dex files
val decoder = ResAttrDecoder() val dexFile = MultiDexIO.readDexFile(true, options.inputFile, NAMER, null, null)
decoder.currentPackage = ResPackage(resourceTable, 0, null) // get the opcodes
opcodes = dexFile.opcodes
// create xml parser with the decoder // finally create patcher data
val axmlParser = AXmlResourceParser() data = PatcherData(
axmlParser.attrDecoder = decoder dexFile.classes.toMutableList(), options.resourceCacheDirectory, packageMetadata
// parse package information with the decoder and parser which will set required values in the resource table
// instead of decodeManifest another more low level solution can be created to make it faster/better
XmlPullStreamDecoder(
axmlParser, AndrolibResources().resXmlSerializer
).decodeManifest(
extInputFile.directory.getFileInput("AndroidManifest.xml"), nullOutputStream
) )
} finally {
extInputFile.close()
} }
packageMetadata.packageName = resourceTable.currentResPackage.name
packageMetadata.packageVersion = resourceTable.versionInfo.versionName
packageMetadata.metaInfo.versionInfo = resourceTable.versionInfo
packageMetadata.metaInfo.sdkInfo = resourceTable.sdkInfo
logger.info("Reading dex files")
// read dex files
val dexFile = MultiDexIO.readDexFile(true, options.inputFile, NAMER, null, null)
// get the opcodes
opcodes = dexFile.opcodes
// finally create patcher data
data = PatcherData(
dexFile.classes.toMutableList(), options.resourceCacheDirectory, packageMetadata
)
} }
/** /**
@ -165,43 +169,46 @@ class Patcher(private val options: PatcherOptions) {
if (options.patchResources) { if (options.patchResources) {
val cacheDirectory = ExtFile(options.resourceCacheDirectory) val cacheDirectory = ExtFile(options.resourceCacheDirectory)
try {
val androlibResources = AndrolibResources().also { resources ->
resources.buildOptions = BuildOptions().also { buildOptions ->
buildOptions.setBuildOptions(options)
buildOptions.isFramework = metaInfo.isFrameworkApk
buildOptions.resourcesAreCompressed = metaInfo.compressionType
buildOptions.doNotCompress = metaInfo.doNotCompress
}
val androlibResources = AndrolibResources().also { resources -> resources.setSdkInfo(metaInfo.sdkInfo)
resources.buildOptions = BuildOptions().also { buildOptions -> resources.setVersionInfo(metaInfo.versionInfo)
buildOptions.setBuildOptions(options) resources.setSharedLibrary(metaInfo.sharedLibrary)
buildOptions.isFramework = metaInfo.isFrameworkApk resources.setSparseResources(metaInfo.sparseResources)
buildOptions.resourcesAreCompressed = metaInfo.compressionType
buildOptions.doNotCompress = metaInfo.doNotCompress
} }
resources.setSdkInfo(metaInfo.sdkInfo) val manifestFile = cacheDirectory.resolve("AndroidManifest.xml")
resources.setVersionInfo(metaInfo.versionInfo)
resources.setSharedLibrary(metaInfo.sharedLibrary)
resources.setSparseResources(metaInfo.sparseResources)
}
val manifestFile = cacheDirectory.resolve("AndroidManifest.xml") ResXmlPatcher.fixingPublicAttrsInProviderAttributes(manifestFile)
ResXmlPatcher.fixingPublicAttrsInProviderAttributes(manifestFile) val aaptFile = cacheDirectory.resolve("aapt_temp_file")
val aaptFile = cacheDirectory.resolve("aapt_temp_file") // delete if it exists
Files.deleteIfExists(aaptFile.toPath())
// delete if it exists val resDirectory = cacheDirectory.resolve("res")
Files.deleteIfExists(aaptFile.toPath()) val includedFiles = metaInfo.usesFramework.ids.map { id ->
androlibResources.getFrameworkApk(
id, metaInfo.usesFramework.tag
)
}.toTypedArray()
val resDirectory = cacheDirectory.resolve("res") logger.info("Compiling resources")
val includedFiles = metaInfo.usesFramework.ids.map { id -> androlibResources.aaptPackage(
androlibResources.getFrameworkApk( aaptFile, manifestFile, resDirectory, null, null, includedFiles
id, metaInfo.usesFramework.tag
) )
}.toTypedArray()
logger.info("Compiling resources") resourceFile = aaptFile
androlibResources.aaptPackage( } finally {
aaptFile, manifestFile, resDirectory, null, null, includedFiles cacheDirectory.close()
) }
resourceFile = aaptFile
} }
logger.trace("Creating new dex file") logger.trace("Creating new dex file")