mirror of
https://github.com/revanced/revanced-cli.git
synced 2024-12-11 20:57:49 +01:00
revert: feat: remove extra zipalign step
This reverts commit c8e793efab
.
This commit is contained in:
parent
d96eb847d7
commit
c3d8fecad0
12
src/main/kotlin/app/revanced/cli/aligning/Aligning.kt
Normal file
12
src/main/kotlin/app/revanced/cli/aligning/Aligning.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package app.revanced.cli.aligning
|
||||||
|
|
||||||
|
import app.revanced.cli.command.MainCommand.logger
|
||||||
|
import app.revanced.utils.signing.align.ZipAligner
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object Aligning {
|
||||||
|
fun align(inputFile: File, outputFile: File) {
|
||||||
|
logger.info("Aligning ${inputFile.name} to ${outputFile.name}")
|
||||||
|
ZipAligner.align(inputFile, outputFile)
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package app.revanced.cli.command
|
package app.revanced.cli.command
|
||||||
|
|
||||||
|
import app.revanced.cli.aligning.Aligning
|
||||||
import app.revanced.cli.logging.impl.DefaultCliLogger
|
import app.revanced.cli.logging.impl.DefaultCliLogger
|
||||||
import app.revanced.cli.patcher.Patcher
|
import app.revanced.cli.patcher.Patcher
|
||||||
import app.revanced.cli.patcher.logging.impl.PatcherLogger
|
import app.revanced.cli.patcher.logging.impl.PatcherLogger
|
||||||
@ -160,11 +161,15 @@ internal object MainCommand : Runnable {
|
|||||||
|
|
||||||
val cacheDirectory = File(pArgs.cacheDirectory)
|
val cacheDirectory = File(pArgs.cacheDirectory)
|
||||||
|
|
||||||
|
// align the file
|
||||||
|
val alignedFile = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk")
|
||||||
|
Aligning.align(patchedFile, alignedFile)
|
||||||
|
|
||||||
// sign the file
|
// sign the file
|
||||||
val finalFile = if (!pArgs.mount) {
|
val finalFile = if (!pArgs.mount) {
|
||||||
val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk")
|
val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk")
|
||||||
Signing.sign(
|
Signing.sign(
|
||||||
patchedFile,
|
alignedFile,
|
||||||
signedOutput,
|
signedOutput,
|
||||||
SigningOptions(
|
SigningOptions(
|
||||||
pArgs.cn,
|
pArgs.cn,
|
||||||
@ -177,7 +182,7 @@ internal object MainCommand : Runnable {
|
|||||||
|
|
||||||
signedOutput
|
signedOutput
|
||||||
} else
|
} else
|
||||||
patchedFile
|
alignedFile
|
||||||
|
|
||||||
// finally copy to the specified output file
|
// finally copy to the specified output file
|
||||||
logger.info("Copying ${finalFile.name} to ${outputFile.name}")
|
logger.info("Copying ${finalFile.name} to ${outputFile.name}")
|
||||||
|
@ -2,12 +2,10 @@ package app.revanced.cli.patcher
|
|||||||
|
|
||||||
import app.revanced.cli.command.MainCommand.args
|
import app.revanced.cli.command.MainCommand.args
|
||||||
import app.revanced.cli.command.MainCommand.logger
|
import app.revanced.cli.command.MainCommand.logger
|
||||||
|
import app.revanced.utils.filesystem.ZipFileSystemUtils
|
||||||
import app.revanced.utils.patcher.addPatchesFiltered
|
import app.revanced.utils.patcher.addPatchesFiltered
|
||||||
import app.revanced.utils.patcher.applyPatchesVerbose
|
import app.revanced.utils.patcher.applyPatchesVerbose
|
||||||
import app.revanced.utils.patcher.mergeFiles
|
import app.revanced.utils.patcher.mergeFiles
|
||||||
import app.revanced.utils.signing.align.ZipAligner
|
|
||||||
import app.revanced.utils.signing.align.zip.ZipFile
|
|
||||||
import app.revanced.utils.signing.align.zip.structures.ZipEntry
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
@ -25,22 +23,26 @@ internal object Patcher {
|
|||||||
|
|
||||||
// write output file
|
// write output file
|
||||||
if (output.exists()) Files.delete(output.toPath())
|
if (output.exists()) Files.delete(output.toPath())
|
||||||
|
inputFile.copyTo(output)
|
||||||
|
|
||||||
val result = patcher.save()
|
val result = patcher.save()
|
||||||
ZipFile(output).use { outputFile ->
|
ZipFileSystemUtils(output).use { outputFileSystem ->
|
||||||
// replace all dex files
|
// replace all dex files
|
||||||
result.dexFiles.forEach {
|
result.dexFiles.forEach {
|
||||||
logger.info("Writing dex file ${it.name}")
|
logger.info("Writing dex file ${it.name}")
|
||||||
outputFile.addEntryCompressData(ZipEntry.createWithName(it.name), it.dexFileInputStream.readAllBytes())
|
outputFileSystem.write(it.name, it.dexFileInputStream.readAllBytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.disableResourcePatching) {
|
if (!args.disableResourcePatching) {
|
||||||
logger.info("Writing resources...")
|
logger.info("Writing resources...")
|
||||||
|
|
||||||
outputFile.copyEntriesFromFileAligned(ZipFile(result.resourceFile!!), ZipAligner::getEntryAlignment)
|
ZipFileSystemUtils(result.resourceFile!!).use { resourceFileSystem ->
|
||||||
|
val resourceFiles = resourceFileSystem.getFile(File.separator)
|
||||||
|
outputFileSystem.writePathRecursively(resourceFiles)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outputFile.copyEntriesFromFileAligned(ZipFile(inputFile), ZipAligner::getEntryAlignment)
|
result.doNotCompress?.let { outputFileSystem.uncompress(*it.toTypedArray()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package app.revanced.utils.filesystem
|
||||||
|
|
||||||
|
import java.io.Closeable
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.FileSystems
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
|
||||||
|
internal class ZipFileSystemUtils(
|
||||||
|
file: File
|
||||||
|
) : Closeable {
|
||||||
|
private var zipFileSystem = FileSystems.newFileSystem(file.toPath(), mapOf("noCompression" to true))
|
||||||
|
|
||||||
|
private fun Path.deleteRecursively() {
|
||||||
|
if (!Files.exists(this)) {
|
||||||
|
throw IllegalStateException("File exists in real folder but not in zip file system")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Files.isDirectory(this)) {
|
||||||
|
Files.list(this).forEach { path ->
|
||||||
|
path.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.delete(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun getFile(path: String) = zipFileSystem.getPath(path)
|
||||||
|
|
||||||
|
internal fun writePathRecursively(path: Path) {
|
||||||
|
Files.list(path).use { fileStream ->
|
||||||
|
fileStream.forEach { filePath ->
|
||||||
|
val fileSystemPath = filePath.getRelativePath(path)
|
||||||
|
fileSystemPath.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.walk(path).use { fileStream ->
|
||||||
|
// don't include build directory
|
||||||
|
// by skipping the root node.
|
||||||
|
fileStream.skip(1).forEach { filePath ->
|
||||||
|
val relativePath = filePath.getRelativePath(path)
|
||||||
|
|
||||||
|
if (Files.isDirectory(filePath)) {
|
||||||
|
Files.createDirectory(relativePath)
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.copy(filePath, relativePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun write(path: String, content: ByteArray) = Files.write(zipFileSystem.getPath(path), content)
|
||||||
|
|
||||||
|
private fun Path.getRelativePath(path: Path): Path = zipFileSystem.getPath(path.relativize(this).toString())
|
||||||
|
|
||||||
|
// TODO: figure out why the file system is uncompressed by default and how to fix it
|
||||||
|
internal fun uncompress(vararg paths: String) =
|
||||||
|
paths.forEach { Files.setAttribute(zipFileSystem.getPath(it), "zip:method", ZipEntry.STORED) }
|
||||||
|
|
||||||
|
override fun close() = zipFileSystem.close()
|
||||||
|
}
|
@ -1,11 +1,28 @@
|
|||||||
package app.revanced.utils.signing.align
|
package app.revanced.utils.signing.align
|
||||||
|
|
||||||
import app.revanced.utils.signing.align.zip.structures.ZipEntry
|
import app.revanced.utils.signing.align.zip.ZipFile
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
internal object ZipAligner {
|
internal object ZipAligner {
|
||||||
private const val DEFAULT_ALIGNMENT = 4
|
private const val DEFAULT_ALIGNMENT = 4
|
||||||
private const val LIBRARY_ALIGNMENT = 4096
|
private const val LIBRARY_ALIGNMENT = 4096
|
||||||
|
|
||||||
fun getEntryAlignment(entry: ZipEntry): Int? =
|
fun align(input: File, output: File) {
|
||||||
if (entry.compression.toUInt() != 0u) null else if (entry.fileName.endsWith(".so")) LIBRARY_ALIGNMENT else DEFAULT_ALIGNMENT
|
val inputZip = ZipFile(input)
|
||||||
|
val outputZip = ZipFile(output)
|
||||||
|
|
||||||
|
for (entry in inputZip.entries) {
|
||||||
|
val data = inputZip.getDataForEntry(entry)
|
||||||
|
|
||||||
|
if (entry.compression == 0.toUShort()) {
|
||||||
|
val alignment = if (entry.fileName.endsWith(".so")) LIBRARY_ALIGNMENT else DEFAULT_ALIGNMENT
|
||||||
|
|
||||||
|
outputZip.addEntryAligned(entry, data, alignment)
|
||||||
|
} else {
|
||||||
|
outputZip.addEntry(entry, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputZip.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,15 @@ package app.revanced.utils.signing.align.zip
|
|||||||
|
|
||||||
import app.revanced.utils.signing.align.zip.structures.ZipEndRecord
|
import app.revanced.utils.signing.align.zip.structures.ZipEndRecord
|
||||||
import app.revanced.utils.signing.align.zip.structures.ZipEntry
|
import app.revanced.utils.signing.align.zip.structures.ZipEntry
|
||||||
import java.io.Closeable
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.RandomAccessFile
|
import java.io.RandomAccessFile
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.channels.FileChannel
|
import java.nio.channels.FileChannel
|
||||||
import java.util.zip.CRC32
|
|
||||||
import java.util.zip.Deflater
|
|
||||||
|
|
||||||
class ZipFile(val file: File) : Closeable {
|
class ZipFile(val file: File) {
|
||||||
var entries: MutableList<ZipEntry> = mutableListOf()
|
var entries: MutableList<ZipEntry> = mutableListOf()
|
||||||
|
|
||||||
private val filePointer: RandomAccessFile = RandomAccessFile(file, "rw")
|
private val filePointer: RandomAccessFile = RandomAccessFile(file, "rw")
|
||||||
private var CDNeedsRewrite = false
|
|
||||||
|
|
||||||
private val compressionLevel = 5
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
//if file isn't empty try to load entries
|
//if file isn't empty try to load entries
|
||||||
@ -59,24 +53,23 @@ class ZipFile(val file: File) : Closeable {
|
|||||||
|
|
||||||
return buildList(numberOfEntries) {
|
return buildList(numberOfEntries) {
|
||||||
for (i in 1..numberOfEntries) {
|
for (i in 1..numberOfEntries) {
|
||||||
add(
|
add(ZipEntry.fromCDE(filePointer).also
|
||||||
ZipEntry.fromCDE(filePointer).also
|
{
|
||||||
{
|
//for some reason the local extra field can be different from the central one
|
||||||
//for some reason the local extra field can be different from the central one
|
it.readLocalExtra(
|
||||||
it.readLocalExtra(
|
filePointer.channel.map(
|
||||||
filePointer.channel.map(
|
FileChannel.MapMode.READ_ONLY,
|
||||||
FileChannel.MapMode.READ_ONLY,
|
it.localHeaderOffset.toLong() + 28,
|
||||||
it.localHeaderOffset.toLong() + 28,
|
2
|
||||||
2
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
})
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeCD() {
|
private fun writeCDE() {
|
||||||
val CDStart = filePointer.channel.position().toUInt()
|
val CDEStart = filePointer.channel.position().toUInt()
|
||||||
|
|
||||||
entries.forEach {
|
entries.forEach {
|
||||||
filePointer.channel.write(it.toCDE())
|
filePointer.channel.write(it.toCDE())
|
||||||
@ -89,17 +82,15 @@ class ZipFile(val file: File) : Closeable {
|
|||||||
0u,
|
0u,
|
||||||
entriesCount,
|
entriesCount,
|
||||||
entriesCount,
|
entriesCount,
|
||||||
filePointer.channel.position().toUInt() - CDStart,
|
filePointer.channel.position().toUInt() - CDEStart,
|
||||||
CDStart,
|
CDEStart,
|
||||||
""
|
""
|
||||||
)
|
)
|
||||||
|
|
||||||
filePointer.channel.write(endRecord.toECD())
|
filePointer.channel.write(endRecord.toECD())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addEntry(entry: ZipEntry, data: ByteBuffer) {
|
fun addEntry(entry: ZipEntry, data: ByteBuffer) {
|
||||||
CDNeedsRewrite = true
|
|
||||||
|
|
||||||
entry.localHeaderOffset = filePointer.channel.position().toUInt()
|
entry.localHeaderOffset = filePointer.channel.position().toUInt()
|
||||||
|
|
||||||
filePointer.channel.write(entry.toLFH())
|
filePointer.channel.write(entry.toLFH())
|
||||||
@ -108,45 +99,17 @@ class ZipFile(val file: File) : Closeable {
|
|||||||
entries.add(entry)
|
entries.add(entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addEntryCompressData(entry: ZipEntry, data: ByteArray) {
|
fun addEntryAligned(entry: ZipEntry, data: ByteBuffer, alignment: Int) {
|
||||||
val compressor = Deflater(compressionLevel, true)
|
//calculate where data would end up
|
||||||
compressor.setInput(data)
|
val dataOffset = filePointer.filePointer + entry.LFHSize
|
||||||
compressor.finish()
|
|
||||||
|
|
||||||
val uncompressedSize = data.size
|
val mod = dataOffset % alignment
|
||||||
val compressedData =
|
|
||||||
ByteArray(uncompressedSize) //i'm guessing compression won't make the data bigger
|
|
||||||
|
|
||||||
val compressedDataLength = compressor.deflate(compressedData)
|
//wrong alignment
|
||||||
val compressedBuffer =
|
if (mod != 0L) {
|
||||||
ByteBuffer.wrap(compressedData.take(compressedDataLength).toByteArray())
|
//add padding at end of extra field
|
||||||
|
entry.localExtraField =
|
||||||
compressor.end()
|
entry.localExtraField.copyOf((entry.localExtraField.size + (alignment - mod)).toInt())
|
||||||
|
|
||||||
val crc = CRC32()
|
|
||||||
crc.update(data)
|
|
||||||
|
|
||||||
entry.compression = 8u //deflate compression
|
|
||||||
entry.uncompressedSize = uncompressedSize.toUInt()
|
|
||||||
entry.compressedSize = compressedDataLength.toUInt()
|
|
||||||
entry.crc32 = crc.value.toUInt()
|
|
||||||
|
|
||||||
addEntry(entry, compressedBuffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addEntryCopyData(entry: ZipEntry, data: ByteBuffer, alignment: Int? = null) {
|
|
||||||
alignment?.let { alignment ->
|
|
||||||
//calculate where data would end up
|
|
||||||
val dataOffset = filePointer.filePointer + entry.LFHSize
|
|
||||||
|
|
||||||
val mod = dataOffset % alignment
|
|
||||||
|
|
||||||
//wrong alignment
|
|
||||||
if (mod != 0L) {
|
|
||||||
//add padding at end of extra field
|
|
||||||
entry.localExtraField =
|
|
||||||
entry.localExtraField.copyOf((entry.localExtraField.size + (alignment - mod)).toInt())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addEntry(entry, data)
|
addEntry(entry, data)
|
||||||
@ -160,17 +123,8 @@ class ZipFile(val file: File) : Closeable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun copyEntriesFromFileAligned(file: ZipFile, entryAlignment: (entry: ZipEntry) -> Int?) {
|
fun finish() {
|
||||||
for (entry in file.entries) {
|
writeCDE()
|
||||||
if (entries.any { it.fileName == entry.fileName }) continue //don't add duplicates
|
|
||||||
|
|
||||||
val data = file.getDataForEntry(entry)
|
|
||||||
addEntryCopyData(entry, data, entryAlignment(entry))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun close() {
|
|
||||||
if (CDNeedsRewrite) writeCD()
|
|
||||||
filePointer.close()
|
filePointer.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,7 @@ data class ZipEndRecord(
|
|||||||
fun toECD(): ByteBuffer {
|
fun toECD(): ByteBuffer {
|
||||||
val commentBytes = fileComment.toByteArray(Charsets.UTF_8)
|
val commentBytes = fileComment.toByteArray(Charsets.UTF_8)
|
||||||
|
|
||||||
val buffer = ByteBuffer.allocate(ECD_HEADER_SIZE + commentBytes.size)
|
val buffer = ByteBuffer.allocate(ECD_HEADER_SIZE + commentBytes.size).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
||||||
.also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
|
||||||
|
|
||||||
buffer.putUInt(ECD_SIGNATURE)
|
buffer.putUInt(ECD_SIGNATURE)
|
||||||
buffer.putUShort(diskNumber)
|
buffer.putUShort(diskNumber)
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package app.revanced.utils.signing.align.zip.structures
|
package app.revanced.utils.signing.align.zip.structures
|
||||||
|
|
||||||
import app.revanced.utils.signing.align.zip.*
|
import app.revanced.utils.signing.align.zip.getUShort
|
||||||
|
import app.revanced.utils.signing.align.zip.putUInt
|
||||||
|
import app.revanced.utils.signing.align.zip.putUShort
|
||||||
|
import app.revanced.utils.signing.align.zip.readUIntLE
|
||||||
|
import app.revanced.utils.signing.align.zip.readUShortLE
|
||||||
import java.io.DataInput
|
import java.io.DataInput
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.nio.ByteOrder
|
import java.nio.ByteOrder
|
||||||
@ -9,12 +13,12 @@ data class ZipEntry(
|
|||||||
val version: UShort,
|
val version: UShort,
|
||||||
val versionNeeded: UShort,
|
val versionNeeded: UShort,
|
||||||
val flags: UShort,
|
val flags: UShort,
|
||||||
var compression: UShort,
|
val compression: UShort,
|
||||||
val modificationTime: UShort,
|
val modificationTime: UShort,
|
||||||
val modificationDate: UShort,
|
val modificationDate: UShort,
|
||||||
var crc32: UInt,
|
val crc32: UInt,
|
||||||
var compressedSize: UInt,
|
val compressedSize: UInt,
|
||||||
var uncompressedSize: UInt,
|
val uncompressedSize: UInt,
|
||||||
val diskNumber: UShort,
|
val diskNumber: UShort,
|
||||||
val internalAttributes: UShort,
|
val internalAttributes: UShort,
|
||||||
val externalAttributes: UInt,
|
val externalAttributes: UInt,
|
||||||
@ -22,7 +26,7 @@ data class ZipEntry(
|
|||||||
val fileName: String,
|
val fileName: String,
|
||||||
val extraField: ByteArray,
|
val extraField: ByteArray,
|
||||||
val fileComment: String,
|
val fileComment: String,
|
||||||
var localExtraField: ByteArray = ByteArray(0), //separate for alignment
|
var localExtraField: ByteArray = ByteArray(0), //seperate for alignment
|
||||||
) {
|
) {
|
||||||
val LFHSize: Int
|
val LFHSize: Int
|
||||||
get() = LFH_HEADER_SIZE + fileName.toByteArray(Charsets.UTF_8).size + localExtraField.size
|
get() = LFH_HEADER_SIZE + fileName.toByteArray(Charsets.UTF_8).size + localExtraField.size
|
||||||
@ -37,27 +41,6 @@ data class ZipEntry(
|
|||||||
const val LFH_HEADER_SIZE = 30
|
const val LFH_HEADER_SIZE = 30
|
||||||
const val LFH_SIGNATURE = 0x04034b50u
|
const val LFH_SIGNATURE = 0x04034b50u
|
||||||
|
|
||||||
fun createWithName(fileName: String): ZipEntry {
|
|
||||||
return ZipEntry(
|
|
||||||
0x1403u, //made by unix, version 20
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
0x0821u, //seems to be static time google uses, no idea
|
|
||||||
0x0221u, //same as above
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
0u,
|
|
||||||
fileName,
|
|
||||||
ByteArray(0),
|
|
||||||
""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fromCDE(input: DataInput): ZipEntry {
|
fun fromCDE(input: DataInput): ZipEntry {
|
||||||
val signature = input.readUIntLE()
|
val signature = input.readUIntLE()
|
||||||
|
|
||||||
@ -84,8 +67,7 @@ data class ZipEntry(
|
|||||||
val externalAttributes = input.readUIntLE()
|
val externalAttributes = input.readUIntLE()
|
||||||
val localHeaderOffset = input.readUIntLE()
|
val localHeaderOffset = input.readUIntLE()
|
||||||
|
|
||||||
val variableFieldsLength =
|
val variableFieldsLength = fileNameLength.toInt() + extraFieldLength.toInt() + fileCommentLength.toInt()
|
||||||
fileNameLength.toInt() + extraFieldLength.toInt() + fileCommentLength.toInt()
|
|
||||||
|
|
||||||
if (variableFieldsLength > 0) {
|
if (variableFieldsLength > 0) {
|
||||||
val fileNameBytes = ByteArray(fileNameLength.toInt())
|
val fileNameBytes = ByteArray(fileNameLength.toInt())
|
||||||
@ -99,8 +81,7 @@ data class ZipEntry(
|
|||||||
fileComment = fileCommentBytes.toString(Charsets.UTF_8)
|
fileComment = fileCommentBytes.toString(Charsets.UTF_8)
|
||||||
}
|
}
|
||||||
|
|
||||||
flags = (flags and 0b1000u.inv()
|
flags = (flags and 0b1000u.inv().toUShort()) //disable data descriptor flag as they are not used
|
||||||
.toUShort()) //disable data descriptor flag as they are not used
|
|
||||||
|
|
||||||
return ZipEntry(
|
return ZipEntry(
|
||||||
version,
|
version,
|
||||||
@ -157,9 +138,8 @@ data class ZipEntry(
|
|||||||
val nameBytes = fileName.toByteArray(Charsets.UTF_8)
|
val nameBytes = fileName.toByteArray(Charsets.UTF_8)
|
||||||
val commentBytes = fileComment.toByteArray(Charsets.UTF_8)
|
val commentBytes = fileComment.toByteArray(Charsets.UTF_8)
|
||||||
|
|
||||||
val buffer =
|
val buffer = ByteBuffer.allocate(CDE_HEADER_SIZE + nameBytes.size + extraField.size + commentBytes.size)
|
||||||
ByteBuffer.allocate(CDE_HEADER_SIZE + nameBytes.size + extraField.size + commentBytes.size)
|
.also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
||||||
.also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
|
||||||
|
|
||||||
buffer.putUInt(CDE_SIGNATURE)
|
buffer.putUInt(CDE_SIGNATURE)
|
||||||
buffer.putUShort(version)
|
buffer.putUShort(version)
|
||||||
|
Loading…
Reference in New Issue
Block a user