handle unknown chunk type instead of throw

This commit is contained in:
REAndroid 2022-12-30 09:16:12 -05:00
parent 4b6dc12622
commit dd380be38f
5 changed files with 67 additions and 11 deletions

View File

@ -35,6 +35,9 @@ public abstract class BaseChunk extends ExpandableBlockContainer {
protected void addToHeader(Block block){ protected void addToHeader(Block block){
mHeaderBlock.addChild(block); mHeaderBlock.addChild(block);
} }
void setHeaderLoaded(HeaderBlock.HeaderLoaded headerLoaded){
mHeaderBlock.setHeaderLoaded(headerLoaded);
}
public HeaderBlock getHeaderBlock(){ public HeaderBlock getHeaderBlock(){
return mHeaderBlock; return mHeaderBlock;
} }
@ -50,16 +53,21 @@ public abstract class BaseChunk extends ExpandableBlockContainer {
@Override @Override
public void onReadBytes(BlockReader reader) throws IOException { public void onReadBytes(BlockReader reader) throws IOException {
HeaderBlock headerBlock=reader.readHeaderBlock(); HeaderBlock headerBlock=reader.readHeaderBlock();
ChunkType chunkType = headerBlock.getChunkType(); checkInvalidChunk(headerBlock);
if(chunkType==null || chunkType==ChunkType.NULL){ BlockReader chunkReader = reader.create(
throw new IOException("Invalid chunk: "+headerBlock); reader.getPosition(),
} headerBlock.getChunkSize());
BlockReader chunkReader=reader.create(reader.getPosition(), headerBlock.getChunkSize());
super.onReadBytes(chunkReader); super.onReadBytes(chunkReader);
reader.offset(headerBlock.getChunkSize()); reader.offset(headerBlock.getChunkSize());
chunkReader.close(); chunkReader.close();
onChunkLoaded(); onChunkLoaded();
} }
void checkInvalidChunk(HeaderBlock headerBlock) throws IOException {
ChunkType chunkType = headerBlock.getChunkType();
if(chunkType==null || chunkType==ChunkType.NULL){
throw new IOException("Invalid chunk: "+headerBlock);
}
}
@Override @Override
public String toString(){ public String toString(){
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();

View File

@ -115,6 +115,9 @@ package com.reandroid.lib.arsc.chunk;
addChild(mPackageLastBlocks); addChild(mPackageLastBlocks);
} }
public BlockList<UnknownChunk> getUnknownChunkList(){
return mPackageLastBlocks.getUnknownChunkList();
}
public StagedAliasEntry searchByStagedResId(int stagedResId){ public StagedAliasEntry searchByStagedResId(int stagedResId){
for(StagedAlias stagedAlias:getStagedAliasList().getChildes()){ for(StagedAlias stagedAlias:getStagedAliasList().getChildes()){

View File

@ -29,22 +29,30 @@ public class PackageLastBlocks extends FixedBlockContainer {
private final BlockList<StagedAlias> mStagedAliasList; private final BlockList<StagedAlias> mStagedAliasList;
private final BlockList<Overlayable> mOverlayableList; private final BlockList<Overlayable> mOverlayableList;
private final BlockList<OverlayablePolicy> mOverlayablePolicyList; private final BlockList<OverlayablePolicy> mOverlayablePolicyList;
private final BlockList<UnknownChunk> mUnknownChunkList;
public PackageLastBlocks(SpecTypePairArray specTypePairArray, public PackageLastBlocks(SpecTypePairArray specTypePairArray,
LibraryBlock libraryBlock, LibraryBlock libraryBlock,
BlockList<StagedAlias> stagedAliasList, BlockList<StagedAlias> stagedAliasList,
BlockList<Overlayable> overlayableList, BlockList<Overlayable> overlayableList,
BlockList<OverlayablePolicy> overlayablePolicyList){ BlockList<OverlayablePolicy> overlayablePolicyList){
super(5); super(6);
this.mSpecTypePairArray=specTypePairArray; this.mSpecTypePairArray=specTypePairArray;
this.mLibraryBlock=libraryBlock; this.mLibraryBlock=libraryBlock;
this.mStagedAliasList=stagedAliasList; this.mStagedAliasList=stagedAliasList;
this.mOverlayableList=overlayableList; this.mOverlayableList=overlayableList;
this.mOverlayablePolicyList=overlayablePolicyList; this.mOverlayablePolicyList=overlayablePolicyList;
this.mUnknownChunkList = new BlockList<>();
addChild(0, mSpecTypePairArray); addChild(0, mSpecTypePairArray);
addChild(1, mLibraryBlock); addChild(1, mLibraryBlock);
addChild(2, mStagedAliasList); addChild(2, mStagedAliasList);
addChild(3, mOverlayableList); addChild(3, mOverlayableList);
addChild(4, mOverlayablePolicyList); addChild(4, mOverlayablePolicyList);
addChild(5, mUnknownChunkList);
}
public BlockList<UnknownChunk> getUnknownChunkList(){
return mUnknownChunkList;
} }
@Override @Override
@ -72,7 +80,7 @@ public class PackageLastBlocks extends FixedBlockContainer {
}else if(chunkType==ChunkType.STAGED_ALIAS){ }else if(chunkType==ChunkType.STAGED_ALIAS){
readStagedAlias(reader); readStagedAlias(reader);
}else { }else {
readUnexpectedBlock(reader, headerBlock); readUnknownChunk(reader);
} }
return pos!=reader.getPosition(); return pos!=reader.getPosition();
} }
@ -100,7 +108,9 @@ public class PackageLastBlocks extends FixedBlockContainer {
overlayablePolicy.readBytes(reader); overlayablePolicy.readBytes(reader);
mOverlayablePolicyList.add(overlayablePolicy); mOverlayablePolicyList.add(overlayablePolicy);
} }
private void readUnexpectedBlock(BlockReader reader, HeaderBlock headerBlock) throws IOException{ private void readUnknownChunk(BlockReader reader) throws IOException{
throw new IOException(reader.getActualPosition()+", Unexpected block: "+headerBlock.toString()); UnknownChunk unknownChunk = new UnknownChunk();
unknownChunk.readBytes(reader);
mUnknownChunkList.add(unknownChunk);
} }
} }

View File

@ -18,13 +18,18 @@ package com.reandroid.lib.arsc.header;
import com.reandroid.lib.arsc.chunk.ChunkType; import com.reandroid.lib.arsc.chunk.ChunkType;
import com.reandroid.lib.arsc.base.Block; import com.reandroid.lib.arsc.base.Block;
import com.reandroid.lib.arsc.container.ExpandableBlockContainer; import com.reandroid.lib.arsc.container.ExpandableBlockContainer;
import com.reandroid.lib.arsc.io.BlockLoad;
import com.reandroid.lib.arsc.io.BlockReader;
import com.reandroid.lib.arsc.item.IntegerItem; import com.reandroid.lib.arsc.item.IntegerItem;
import com.reandroid.lib.arsc.item.ShortItem; import com.reandroid.lib.arsc.item.ShortItem;
public class HeaderBlock extends ExpandableBlockContainer { import java.io.IOException;
public class HeaderBlock extends ExpandableBlockContainer implements BlockLoad {
private final ShortItem mType; private final ShortItem mType;
private final ShortItem mHeaderSize; private final ShortItem mHeaderSize;
private final IntegerItem mChunkSize; private final IntegerItem mChunkSize;
private HeaderLoaded mHeaderLoaded;
public HeaderBlock(short type){ public HeaderBlock(short type){
super(3); super(3);
this.mType=new ShortItem(type); this.mType=new ShortItem(type);
@ -33,6 +38,12 @@ public class HeaderBlock extends ExpandableBlockContainer {
addChild(mType); addChild(mType);
addChild(mHeaderSize); addChild(mHeaderSize);
addChild(mChunkSize); addChild(mChunkSize);
this.mType.setBlockLoad(this);
this.mHeaderSize.setBlockLoad(this);
this.mChunkSize.setBlockLoad(this);
}
public void setHeaderLoaded(HeaderLoaded headerLoaded){
this.mHeaderLoaded=headerLoaded;
} }
public ChunkType getChunkType(){ public ChunkType getChunkType(){
return ChunkType.get(mType.get()); return ChunkType.get(mType.get());
@ -54,7 +65,7 @@ public class HeaderBlock extends ExpandableBlockContainer {
} }
public int getHeaderSize(){ public int getHeaderSize(){
return (0xffff & mHeaderSize.get()); return mHeaderSize.unsignedInt();
} }
public void setHeaderSize(short headerSize){ public void setHeaderSize(short headerSize){
mHeaderSize.set(headerSize); mHeaderSize.set(headerSize);
@ -82,6 +93,21 @@ public class HeaderBlock extends ExpandableBlockContainer {
int count=parent.countBytes(); int count=parent.countBytes();
setChunkSize(count); setChunkSize(count);
} }
@Override
public void onBlockLoaded(BlockReader reader, Block sender) throws IOException {
HeaderLoaded headerLoaded = mHeaderLoaded;
if(headerLoaded==null){
return;
}
if(sender==this.mType){
headerLoaded.onChunkTypeLoaded(mType.get());
}else if(sender==this.mHeaderSize){
headerLoaded.onHeaderSizeLoaded(mHeaderSize.unsignedInt());
}else if(sender==this.mChunkSize){
headerLoaded.onChunkSizeLoaded(mHeaderSize.unsignedInt(),
mChunkSize.get());
}
}
@Override @Override
protected void onRefreshed() { protected void onRefreshed() {
@ -110,4 +136,10 @@ public class HeaderBlock extends ExpandableBlockContainer {
builder.append("}"); builder.append("}");
return builder.toString(); return builder.toString();
} }
public interface HeaderLoaded{
void onChunkTypeLoaded(short type);
void onHeaderSizeLoaded(int headerSize);
void onChunkSizeLoaded(int headerSize, int chunkSize);
}
} }

View File

@ -37,6 +37,9 @@ public class ShortItem extends BlockItem {
public short get(){ public short get(){
return mCache; return mCache;
} }
public int unsignedInt(){
return 0xffff & get();
}
@Override @Override
protected void onBytesChanged() { protected void onBytesChanged() {
// To save cpu usage, better to calculate once only when bytes changed // To save cpu usage, better to calculate once only when bytes changed