fix: read local file headers properly #27

This commit is contained in:
REAndroid 2023-04-24 23:19:47 +02:00
parent 6a6ccea50e
commit 87528e3cef
2 changed files with 27 additions and 26 deletions

View File

@ -39,6 +39,11 @@ public class FileChannelInputStream extends InputStream {
this.bufferLength = len; this.bufferLength = len;
this.pos = len; this.pos = len;
} }
public FileChannel getFileChannel() {
return fileChannel;
}
@Override @Override
public int read(byte[] bytes) throws IOException { public int read(byte[] bytes) throws IOException {
return read(bytes, 0, bytes.length); return read(bytes, 0, bytes.length);
@ -96,4 +101,8 @@ public class FileChannelInputStream extends InputStream {
public int read() throws IOException { public int read() throws IOException {
throw new IOException("Why one byte?"); throw new IOException("Why one byte?");
} }
@Override
public void reset(){
total = 0;
}
} }

View File

@ -17,11 +17,12 @@ package com.reandroid.archive2.model;
import com.reandroid.archive2.block.*; import com.reandroid.archive2.block.*;
import com.reandroid.archive2.block.ApkSignatureBlock; import com.reandroid.archive2.block.ApkSignatureBlock;
import com.reandroid.archive2.io.FileChannelInputStream;
import com.reandroid.archive2.io.ZipInput; import com.reandroid.archive2.io.ZipInput;
import com.reandroid.arsc.io.BlockReader; import com.reandroid.arsc.io.BlockReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.nio.channels.FileChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -29,7 +30,6 @@ public class LocalFileDirectory {
private final CentralFileDirectory centralFileDirectory; private final CentralFileDirectory centralFileDirectory;
private final List<LocalFileHeader> headerList; private final List<LocalFileHeader> headerList;
private ApkSignatureBlock apkSignatureBlock; private ApkSignatureBlock apkSignatureBlock;
private long mTotalDataLength;
public LocalFileDirectory(CentralFileDirectory centralFileDirectory){ public LocalFileDirectory(CentralFileDirectory centralFileDirectory){
this.centralFileDirectory = centralFileDirectory; this.centralFileDirectory = centralFileDirectory;
this.headerList = new ArrayList<>(); this.headerList = new ArrayList<>();
@ -43,27 +43,23 @@ public class LocalFileDirectory {
visitApkSigBlock(zipInput); visitApkSigBlock(zipInput);
} }
private void visitLocalFile(ZipInput zipInput) throws IOException { private void visitLocalFile(ZipInput zipInput) throws IOException {
EndRecord endRecord = getCentralFileDirectory().getEndRecord();
InputStream inputStream = zipInput.getInputStream(0, endRecord.getOffsetOfCentralDirectory());
visitLocalFile(inputStream);
inputStream.close();
}
private void visitLocalFile(InputStream inputStream) throws IOException {
List<LocalFileHeader> headerList = this.getHeaderList(); List<LocalFileHeader> headerList = this.getHeaderList();
long offset = 0; long offset;
int read; int read;
CentralFileDirectory centralFileDirectory = getCentralFileDirectory();
LocalFileHeader lfh = new LocalFileHeader();
read = lfh.readBytes(inputStream);
int index = 0; int index = 0;
while (lfh.isValidSignature()){ CentralFileDirectory centralFileDirectory = getCentralFileDirectory();
offset += read; long length = zipInput.getLength();
lfh.setIndex(index); FileChannelInputStream inputStream= (FileChannelInputStream) zipInput.getInputStream(0, length);
CentralEntryHeader ceh = centralFileDirectory.get(lfh); FileChannel fileChannel = inputStream.getFileChannel();
lfh.mergeZeroValues(ceh); for(CentralEntryHeader ceh: centralFileDirectory.getHeaderList()){
offset = ceh.getLocalRelativeOffset();
fileChannel.position(offset);
LocalFileHeader lfh = new LocalFileHeader();
lfh.readBytes(inputStream);
offset = offset + lfh.countBytes();
lfh.setFileOffset(offset); lfh.setFileOffset(offset);
ceh.setFileOffset(offset); ceh.setFileOffset(offset);
offset += inputStream.skip(lfh.getDataSize()); offset = inputStream.skip(lfh.getDataSize());
DataDescriptor dataDescriptor = null; DataDescriptor dataDescriptor = null;
if(lfh.hasDataDescriptor()){ if(lfh.hasDataDescriptor()){
dataDescriptor = new DataDescriptor(); dataDescriptor = new DataDescriptor();
@ -72,14 +68,13 @@ public class LocalFileDirectory {
offset += read; offset += read;
} }
} }
index++;
lfh.setIndex(index);
lfh.setDataDescriptor(dataDescriptor); lfh.setDataDescriptor(dataDescriptor);
headerList.add(lfh); headerList.add(lfh);
index++; length = length - offset;
inputStream.reset();
lfh = new LocalFileHeader();
read = lfh.readBytes(inputStream);
} }
mTotalDataLength = offset;
} }
private void visitApkSigBlock(ZipInput zipInput) throws IOException{ private void visitApkSigBlock(ZipInput zipInput) throws IOException{
CentralFileDirectory cfd = getCentralFileDirectory(); CentralFileDirectory cfd = getCentralFileDirectory();
@ -103,7 +98,4 @@ public class LocalFileDirectory {
public List<LocalFileHeader> getHeaderList() { public List<LocalFileHeader> getHeaderList() {
return headerList; return headerList;
} }
public long getTotalDataLength() {
return mTotalDataLength;
}
} }