MpjB tdZdZddlZddlZddlmZddlZejjejjejjejje Z e ejvrejjde [ ddlmZej"ddk\reZdZdZd ZGd d ej.ZGd d ej2ZGddeZGddej2ZegdZegdZGddej@Z!Gdde!Z"Gdde!Z#Gdde!Z$Gddej@Z%Gdde%Z&d Z'e(d!k(r2ejRejTejVd"deeyy)#zQ Parse xls up to some point Read storages, (sub-)streams, records from xls file z0.54N)unpack) record_basec6d} t|}|jD]'}t|ts||j yy ||j y#t $rt jddY5wxYw#||j wwxYw)a  determine whether a given file is an excel ole file returns True if given file is an ole file and contains a Workbook stream todo: could further check that workbook stream starts with a globals substream. See also: oleid.OleID.check_excel NTz/Ignoring exception in is_xls, assume is not xls)exc_infoF)XlsFile iter_streams isinstanceWorkbookStreamclose Exceptionloggingdebug)filenamexls_filestreams a/mnt/ssd/data/Dropbox/adrian/scripts/msg_venv/lib/python3.12/site-packages/oletools/xls_parser.pyis_xlsrQsH 8$++- F&.1   NN      NN   % G# %%   NN  s4.AAA B B=B?BBBct|||dzdk(}|r!|dz|z}||dz|jd|fSt||dz|S)z= read a unicode string from a XLUnicodeStringNoCch structure rascii)orddecoderead_unicode_2byte)data start_idxn_charslow_bytes_onlyend_idxs r read_unicoder jsc$y156!;Na-')IaK(//8'AA!$ ! W==c||dzz}|dkrdtdd|zz||D}nfdt||dD}dj||fS)z: read a unicode string with characters encoded by 2 bytes c32K|]}t|yw)N)unichr).0vals r z%read_unicode_2byte..zsHCF3KHs<Hc 3ZK|]"}ttd||dzd$yw).}s7B 6$Xhqj(AB1EFBs(+)rrangejoin)rrrrunicharss` rrrvsn'A+%G}H3W,d9W.EFHB$))Wa$@B 88H w &&r!c eZdZdZedZy)rz1 An xls file has most streams made up of records c$|dk(rtStS)z helper for iter_streams Workbook)r XlsStream)cls stream_names rstream_class_for_namezXlsFile.stream_class_for_names * $! !r!N)__name__ __module__ __qualname____doc__ classmethodr9r!rrrs;r!rc&eZdZdZdZedZy)r6z- most streams in xls file consist of records c\td|jjd\}}||dfS)| read first few bytes of record to determine size and type returns (type, size, other) where other is None ?(4''r!ctdfS)T determine a class for given record type returns (clz, force_read) F) XlsRecordr7rGs rrecord_class_for_typezXlsStream.record_class_for_types %r!N)r:r;r<r=rIr>rNr?r!rr6r6s7(  r!r6c eZdZdZedZy)r z+ Stream in excel file that holds most info c|tjk(rtdfS|tjk(rtdfS|tjk(rtdfStdfSrKTF) XlsRecordBofTYPE XlsRecordEofXlsRecordSupBookrLrMs rrNz$WorkbookStream.record_class_for_types[ |(( (% % ** *& & ).. .#T) )e# #r!N)r:r;r<r=r>rNr?r!rr r s5 $ $r!r c.eZdZdZdZdZdZedZy) XlsbStreamz@ binary stream of an xlsb file, usually have a record structure ct|jjd}||jzrGt|jjd}||jz||jzdzz}n|}d}d}t dD]T}t|jjd}|||jz|zz }|dz }||jzdk(sTn||dfS)rBrrrDN)rrrE HIGH_BIT_MASK LOW7_BIT_MASKr0)rFr(val2rGrHshift_s rrIzXlsbStream.read_record_heads $++""1%& ## #t{{''*+Dd000 2 22q8:HHq Adkk&&q)*C t111e; ;H QJEd(((Q.   4''r!cH|tjk(rtdfStdfSrQ)XlsbBeginSupBookrS XlsbRecordrMs rrNz XlsbStream.record_class_for_types) ',, ,#T) )u$ $r!N) r:r;r<r=r\r]rIr>rNr?r!rrWrWs(JMM(0%%r!rW)()BuiltInFnGroupCount)icBookExt)iCodeName)BCodePage)icDat)ij DataLabExt)ikDataLabExtContents)DBCell) DbOrParmQry)i DBQueryExt)ivDConn)# ExternName) ExternSheet)ExtSST)i ExtString)igFeatHdr)[ FileSharing)iFormat)1Font)i GUIDTypeLib)iHLink) InterfaceHdr) InterfaceEnd)i Index)Lbl)Mms)]Obj)i' ObjectLink)i  OleDbConn) OleObjectSize)iRichTextStream)ibSheetExt)iShrFmla)i  SxViewExt)iX SxViewLink)iWebPub)zXF (formatting))i}zXFExt (formatting))iStyle)iStyleExt))iL BrtEndSupBook)i BrtSupAddin)ic BrtSupBookSrc)iJBrtSupNameBits)iHBrtSupNameBool)iK BrtSupNameEnd)iE BrtSupNameErr)iIBrtSupNameFmla)iG BrtSupNameNil)iD BrtSupNameNum)iF BrtSupNameSt)iABrtSupNameStart)iCBrtSupNameValueEnd)iBBrtSupNameValueStart)if BrtSupSame)ie BrtSupSelf)ig BrtSupTabsceZdZdZdZdZy)rLz1 basic building block of data in workbook stream i c~ t|jS#t$rdj|jcYSwxYw); simplification for subclasses to create their own __str__ zXlsRecord type {0})FREQUENT_RECORDStypeKeyErrorformatrFs r _type_strzXlsRecord._type_str.s: :#DII. . :'..tyy9 9 : $<<Nr:r;r<r=MAX_SIZErr?r!rrLrL(s;H:r!rLc8eZdZdZdZdZegdZdZdZ y)rRz) record found at beginning of substreams i ))workbook)rzdialog/worksheet) chart)@macrocn|jd|_ytd|jddd|_y)Nr-r#rDr)rdoctyperrFr`s rfinish_constructingz XlsRecordBof.finish_constructing>s3 99 DL dDIIaN3A6 r!cdj|j|jvr|j|jSdS)NzBOF Record ({0} substream)unknown)rrDOCTYPESrs rrzXlsRecordBof._type_strEsA+22+/<<4==+HDMM$,, '  r!N) r:r;r<r=rSSIZEdictrrrr?r!rrRrR6s(3 D D78H7r!rRceZdZdZdZdZdZy)rTz# record found at end of substreams rcy)Nz EOF Recordr?rs rrzXlsRecordEof._type_strPsr!N)r:r;r<r=rSrrr?r!rrTrTKs- D Dr!rTc<eZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z y ) rUz The SupBook record specifies a supporting link "... The collection of records specifies the contents of an external workbook, DDE data source, or OLE data source." (MS-XLS, paragraph 2.4.271) irzself-referencingzaddin-referencingunusedz same-sheetzole/dde data sourcezexternal workbookcd|_d|_d|_|j|_|j y|j dkr$tdj|j td|j dd\|_|_d|jcxkrdkr-nn*t|j d|j\|_}n d\|_}|jdk(r|j|_y|jd k(r!|jd k(r|j|_y|jd k(r|j|_y|jd k(r|j|_y|jdk(r|jr|j|_y|jdkDr|jr|j |_yyy) z>Finish constructing this record; called at end of constructor.NrDz+not enough data (size is {0} but need >= 4)rCrrw)r/rDiri: )ctabcch virt_pathLINK_TYPE_UNKNOWNsupport_link_typersize ValueErrorrrr LINK_TYPE_SELFLINK_TYPE_ADDINLINK_TYPE_UNUSEDLINK_TYPE_SAMESHEETLINK_TYPE_OLE_DDELINK_TYPE_EXTERNALrs rrz$XlsRecordSupBook.finish_constructingess !%!7!7 99   99q=J$fTYY/1 1$UDIIbqM: 48 txx 4  ,TYY488 D DNA & DNA 88u %)%8%8D " YY# $((f"4%)%9%9D " ^^y (%)%:%:D " ^^y (%)%=%=D " YY# $..%)%;%;D " YY]t~~%)%<%.>!,!9!9; !..0 FL   "     #    "     #s(B?AB A%%A((A==B__main__r),r= __version__sysos.pathosstructrrpathnormpathdirnameabspath__file__ PARENT_DIRinsertoletoolsr version_infochrr&rr r OleRecordFilerOleRecordStreamr6r rWrrr OleRecordBaserLrRrTrUrcrbrr:exittestargvr?r!rr sL " WW  bggoobggooGGOOH/ !  SXXHHOOAz" A! F2 > ' k'' ++ ($Y$&'%,,'%^))X* : )) :9*96Ey6Er ;** ; 7Cz7C~  ( z CHH [  chhqrlG^ DEr!