// Detect a zip archive.
// Author: Jason Hood <jadoxa@yahoo.com.au>

includeScript("archive");
sName="Zip";

function detect_Zip(bFile,bShowOptions)
{
    var nOffset=0;
    if(bFile)
    {
        // Don't know what this is, but I happened to have a file that started
        // with it.
        if(File.compare("'PK00'"))
        {
            nOffset=4;
        }
        if(Binary.compare("'PK'0708",nOffset))
        {
            sOptions="extended";
            bDetected=1;
            return;
        }
    }
    else
    {
        if(File.compareOverlay("'PK'0304"))
        {
            nOffset=File.getOverlayOffset();
        }
        else
        {
            var nSize=File.getSize();
            if(nSize<64)
            {
                return;
            }
            nSize-=11;
            nOffset=nSize;
            if(!File.compare("'PK'0506'",nOffset))
            {
                if(nSize<4096)
                {
                    nOffset=0;
                }
                else
                {
                    nOffset-=4096;
                    nSize=4096;
                }
                nOffset=File.findSignature(nOffset,nSize,"'PK'0506");
                if(nOffset==-1)
                {
                    return;
                }
                var nBase=File.readDword(nOffset+16);
                nOffset-=File.readDword(nOffset+12);
                if(!File.compare("'PK'0102",nOffset))
                {
                    return;
                }
                nOffset+=File.readDword(nOffset+0x2a)-nBase;
            }
        }
    }

    if(File.compare("'PK'0304",nOffset))
    {
        bDetected=1;

        if(File.findString(nOffset,0x40,"META-INF/MANIFEST.MF")!=-1)
        {
            sOptions=sOptions.append("JAR"); // Java archive
        }

        if(File.findString(nOffset,0x40,"classes.dex")!=-1)
        {
            sOptions=sOptions.append("APK"); // Android application package file
        }

        var nVer=0;
        if(!bShowOptions)
        {
            // Just take the first file and assume it carries through.
            if(File.readByte(nOffset+6)&1)
            {
                sOptions="encrypted";
            }
            nVer=File.readByte(nOffset+4);
        }
        else
        {
            var bEncrypted=0;
            do
            {
                var v=File.readByte(nOffset+4);
                if(v>nVer)
                {
                    nVer=v;
                }
                if(!bEncrypted&&(File.readByte(nOffset+6)&1))
                {
                    bEncrypted=1;
                }
                var nPacked=File.readDword(nOffset+0x12);
                var nName=File.readWord(nOffset+0x1A);
                Archive.add(File.readDword(nOffset+0x16),nPacked,
                            nPacked==0&&File.readByte(nOffset+0x1E+nName-1)==0x2F);
                nOffset+=0x1E+nName+File.readWord(nOffset+0x1C)+nPacked;
            } while(File.compare("'PK'0304",nOffset));
            if(bEncrypted)
            {
                sOptions="encrypted";
            }
            sOptions=sOptions.append(Archive.contents());
        }
        sVersion=(nVer/10).toFixed(1);
    }
}
