<?xml version="1.0" encoding="utf-8"?>
<Peach version="1.0" author="Jason Kratzer">
  <Include ns="default" src="file:defaults.xml"/>
  
  <DataModel name="ZipFileFormat">
    <!--  A.  Local file header -->
    <Block name="LocalFileHeader" maxOccurs="1024">
      <String name="lfh_Signature" valueType="hex" value="504b0304" token="true" mutable="false"/>
      <Number name="lfh_Ver" size="16" endian="little" signed="false"/>
      <Flags name="lfh_BitFlag" size="16" endian="little" signed="false">
        <Flag name="lfh_bf_Encrypted" size="1" position="0"/>
        <Flag name="lfh_bf_CompMethod1" size="1" position="1"/>
        <Flag name="lfh_bf_CompMethod2" size="1" position="2"/>
        <Flag name="lfh_bf_Zeroed" size="1" position="3"/>
        <Flag name="lfh_bf_Deflate" size="1" position="4"/>
        <Flag name="lfh_bf_Patched" size="1" position="5"/>
        <Flag name="lfh_bf_Strong" size="1" position="6"/>
        <Flag name="lfh_bf_Unused1" size="1" position="7"/>
        <Flag name="lfh_bf_Unused2" size="1" position="8"/>
        <Flag name="lfh_bf_Unused3" size="1" position="9"/>
        <Flag name="lfh_bf_Unused4" size="1" position="10"/>
        <Flag name="lfh_bf_Efs" size="1" position="11"/>
        <Flag name="lfh_bf_Reserved1" size="1" position="12"/>
        <Flag name="lfh_bf_Enc_CD" size="1" position="13"/>
        <Flag name="lfh_bf_Reserved2" size="1" position="14"/>
        <Flag name="lfh_bf_Reserved3" size="1" position="15"/>
      </Flags>
      <Number name="lfh_CompMethod" size="16" endian="little" signed="false"/>
      <Number name="lfh_LastModTime" size="16" endian="little" signed="false"/>
      <Number name="lfh_LastModDate" size="16" endian="little" signed="false"/>
      <Number name="lfh_CRC32" size="32" endian="little" signed="false"/>  
      <Number name="lfh_CompSize" size="32" endian="little" signed="false">
        <Relation type="size" of="lfh_CompSizeData"/>
      </Number>
      <Number name="lfh_DecompSize" size="32" endian="little" signed="false"/>
      <Number name="lfh_FileNameLen" size="16" endian="little" signed="false">
        <Relation type="size" of="lfh_FileName"/>
      </Number>
      <Number name="lfh_ExtraFldLen" size="16" endian="little" signed="false">
        <Relation type="size" of="lfh_FldName"/>
      </Number>
      <String name="lfh_FileName"/>
      <String name="lfh_FldName"/>
    <!--  B.  File data -->
      <Block name="lfh_Data">
        <Block name="lfh_DataHasSize">
          <Relation type="when" when="int(self.find('lfh_CompSize').defaultValue) != 0"/>
          <Blob name="lfh_CompSizeData" mutable="false"/>
        </Block>
        <Block name="lfh_DataNoSize">
          <Relation type="when" when="int(self.find('lfh_CompSize').defaultValue) == 0"/>
          <Blob name="lfh_CompNoSizeData" mutable="false"/>
        </Block>
      </Block>
    <!--  C.  Data descriptor -->
      <Block name="DataDescriptor">
	    <Relation type="when" when="int(self.find('lfh_BitFlag.lfh_bf_Zeroed').defaultValue) == 1"/>
        <String name="dd_Sig" valueType="hex" value="504b0708" token="true" mutable="false"/>
        <Number name="dd_CRC32" size="32" endian="little" signed="false"/>
		<Choice name="dd_chooser">
		  <Block name="dd_64">
            <Number name="dd_CompSize64" size="64" endian="little" signed="false"/>
            <Number name="dd_DecompSize64" size="64" endian="little" signed="false" constraint="'4b50' not in hex(value)"/>
          </Block>
		  <Block name="dd_32">
            <Number name="dd_CompSize32" size="32" endian="little" signed="false"/>
            <Number name="dd_DecompSize32" size="32" endian="little" signed="false"/>
          </Block>
        </Choice>
      </Block>
    </Block>

    <!-- E.  Archive Extra Data Record: -->
    <Block name="ArchiveExtraDataRecord" minOccurs="0" maxOccurs="1">
      <String name="aedr_Sig" valueType="hex" value="504b0608" token="true" mutable="false"/>
      <Number name="aedr_ExtFldLen" size="32" endian="little" signed="false"/>
      <Blob name="aedr_ExtFld"/> <!-- Look into adding more definition -->
    </Block>

    <!-- F.  Central directory structure: -->
    <Block name="CentralDirectoryStructure" minOccurs="0" maxOccurs="1">
      <Block name="FileHeader" maxOccurs="1024">
        <String name="cfh_Signature" valueType="hex" value="504b0102" token="true" mutable="false"/>
        <Number name="cfh_Ver" size="16" endian="little" signed="false"/>
        <Number name="cfh_VerReq" size="16" endian="little" signed="false"/>
        <Flags name="cfh_BitFlag" size="16" endian="little" signed="false">
          <Flag name="cfh_bf_Encrypted" size="1" position="0"/>
          <Flag name="cfh_bf_CompMethod1" size="1" position="1"/>
          <Flag name="cfh_bf_CompMethod2" size="1" position="2"/>
          <Flag name="cfh_bf_Zeroed" size="1" position="3"/>
          <Flag name="cfh_bf_Deflate" size="1" position="4"/>
          <Flag name="cfh_bf_Patched" size="1" position="5"/>
          <Flag name="cfh_bf_Strong" size="1" position="6"/>
          <Flag name="cfh_bf_Unused1" size="1" position="7"/>
          <Flag name="cfh_bf_Unused2" size="1" position="8"/>
          <Flag name="cfh_bf_Unused3" size="1" position="9"/>
          <Flag name="cfh_bf_Unused4" size="1" position="10"/>
          <Flag name="cfh_bf_EFS" size="1" position="11"/>
          <Flag name="cfh_bf_Reserved1" size="1" position="12"/>
          <Flag name="cfh_bf_Enc_Cd" size="1" position="13"/>
          <Flag name="cfh_bf_Reserved2" size="1" position="14"/>
          <Flag name="cfh_bf_Reserved3" size="1" position="15"/>
        </Flags>
        <Number name="cfh_CompMethod" size="16" endian="little" signed="false"/>
        <Number name="cfh_LastModTime" size="16" endian="little" signed="false"/>
        <Number name="cfh_LastModDate" size="16" endian="little" signed="false"/>
        <Number name="cfh_CRC32" size="32" endian="little" signed="false" mutable="false"/>
        <Number name="cfh_CompSize" size="32" endian="little" signed="false"/>
        <Number name="cfh_DecompSize" size="32" endian="little" signed="false"/>
        <Number name="cfh_FileNameLen" size="16" endian="little" signed="false">
          <Relation type="size" of="cfh_FileName"/>
        </Number>
        <Number name="cfh_ExtraFldLen" size="16" endian="little" signed="false">
          <Relation type="size" of="cfh_FldName"/>
        </Number>
        <Number name="cfh_FileCommLen" size="16" endian="little" signed="false">
          <Relation type="size" of="cfh_FileComment"/>
        </Number>
        <Number name="cfh_DiskNumStart" size="16" endian="little" signed="false"/>
        <Number name="cfh_IntFileAttrib" size="16" endian="little" signed="false"/>
        <Number name="cfh_ExtFileAttrib" size="32" endian="little" signed="false"/>
        <Number name="cfh_RelOffsetLFH" size="32" endian="little" signed="false"/>
        <String name="cfh_FileName">
	      <Fixup class="checksums.ExpressionFixup">
            <Param name="ref" value="lfh_FileName" />
            <Param name="expression" value="data" />
          </Fixup>
        </String> 
        <String name="cfh_FldName"/>
        <String name="cfh_FileComment"/>
      </Block>
      <Block name="CDSDigitalSignature" minOccurs="0" maxOccurs="1">
        <String name="cdsds_Signature" valueType="hex" value="504b0505" token="true" mutable="false"/>          
        <Number name="cdsds_DataSize" size="16" endian="little" signed="false">
          <Relation type="size" of="cdsds_Data"/>
        </Number>
        <Blob name="cdsds_Data" mutable="false"/>
      </Block>
    </Block>

    <!--  G.  Zip64 end of central directory record -->
    <Block name="Zip64EndOfCentralDirectoryRecord" minOccurs="0" maxOccurs="1">
      <String name="z64eocd_Signature" valueType="hex" value="504b0606" token="true" mutable="false"/>
      <Number name="z64eocd_SizeOfRecord" size="64" endian="little" signed="false">
        <Relation type="size" of="CentralDirectoryRecord"/>
      </Number>
      <Block name="CentralDirectoryRecord">
        <Number name="z64eocd_VerMadeBy" size="16" endian="little" signed="false"/>
        <Number name="z64eocd_VerNeeded" size="16" endian="little" signed="false"/>
        <Number name="z64eocd_ThisDiskNum" size="32" endian="little" signed="false"/>
        <Number name="z64eocd_SofCDDiskNum" size="32" endian="little" signed="false"/>
        <Number name="z64eocd_CDOnDisk" size="64" endian="little" signed="false"/>
        <Number name="z64eocd_TotNumEntries" size="64" endian="little" signed="false"/>
        <Number name="z64eocd_SizeOfCenDir" size="64" endian="little" signed="false"/>
        <Number name="z64eocd_OffsetToCenDir" size="64" endian="little" signed="false"/>
        <Block name="z64eocd_Z64ExtensDS" minOccurs="0" maxOccurs="1">
          <Number name="z64eocd_ExtensDs_Header" size="16" endian="little" signed="false"/>
          <Number name="z64eocd_ExtensDs_Size" size="32" endian="little" signed="false">
            <Relation type="size" of="z64eocd_ExtensDs_Data"/>
          </Number>
          <Blob name="z64eocd_ExtensDs_Data"/>
        </Block>
      </Block>
    </Block>
    
    <!-- H.  Zip64 end of central directory locator -->
    <Block name="Zip64EndOfCentralDirectoryLocator" minOccurs="0" maxOccurs="1">
      <String name="eocdl_Signature" valueType="hex" value="504b0607" token="true" mutable="false"/>
      <Number name="eocdl_NumOfDisk" size="32" endian="little" signed="false"/>
      <Number name="eocdl_RelOffsetofZ64" size="64" endian="little" signed="false"/>
      <Number name="eocdl_TotNumDisk" size="32" endian="little" signed="false"/>
    </Block>
    
    <!--  I.  End of central directory record: -->
    <Block name="EndOfCentralDirectoryRecord">
      <String name="eocd_Signature" valueType="hex" value="504b0506" token="true" mutable="false"/>
      <Number name="eocd_NumOfDisk" size="16" endian="little" signed="false"/>
      <Number name="eocd_NumOfDiskWCD" size="16" endian="little" signed="false"/>
      <Number name="eocd_TotNumEntriesOD" size="16" endian="little" signed="false"/>
      <Number name="eocd_TotNumEntriesICD" size="16" endian="little" signed="false"/>
      <Number name="eocd_SizeOfCenDir" size="32" endian="little" signed="false">
        <Relation type="size" of="CentralDirectoryStructure" isOutputOnly="true"/>
      </Number>
      <Number name="eocd_OffsetToCenDir" size="32" endian="little" signed="false">
	    <Relation type="size" of="LocalFileHeader" isOutputOnly="true"/>
      </Number>
      <Block name="ZipFileCommentBlock" minOccur="0" maxOccur="1">
        <Number name="eocd_CommLen" size="16" endian="little" signed="false">
          <Relation type="size" of="eocd_Comment"/>
        </Number>
        <Blob name="eocd_Comment"/>
      </Block>
    </Block>
    
  </DataModel>
  
  <DataModel name="Param">
    <String name="Value" isStatic="true"/>
  </DataModel>

  <StateModel name="TheState" initialState="Initial">
    <State name="Initial">
      <Action type="output">
        <DataModel ref="ZipFileFormat"/>
        <Data name="data" fileName="C:\peachfuzz\minset\test.zip"/>
      </Action>
      <Action type="close"/>
      <Action type="call" method="ScoobySnacks"/>
        </State>
  </StateModel>

  <Agent name="LocalAgent">
    <Monitor class="debugger.WindowsDebugEngine">
      <Param name="CommandLine" value="C:\Program Files\GlobalSCAPE\CuteZIP\CuteZip.exe -x fuzzed.zip C:\temp"/>
      <Param name="StartOnCall" value="ScoobySnacks"/>
    </Monitor>
    <Monitor class="process.PageHeap">
      <Param name="Executable" value="CuteZip.exe"/>
    </Monitor>
  </Agent>
        
  <Test name="TheTest">
    <Strategy class="rand.RandomMutationStrategy" switchCount="1500" maxFieldsToMutate="7"/>
    <Agent ref="LocalAgent"/>
    <StateModel ref="TheState"/>
    <!--<Publisher class="file.FileWriterLauncherGui">
      <Param name="fileName" value="fuzzed.zip"/>
      <Param name="windowName" value="jZip"/>
      <Param name="debugger" value="true"/>
    </Publisher>-->
    <Publisher class="file.FileWriterLauncher">
      <Param name="fileName" value="fuzzed.zip" />
      <Param name="debugger" value="true"/>
    </Publisher>
  </Test>

  <Run name="DefaultRun">
    <Test ref="TheTest"/>
    <Logger class="logger.Filesystem">
       <Param name="path" value="Z:\logs.zip.cutezip"/>
    </Logger>
  </Run>

</Peach>