!fVdZddlZddlZddlZddlZddlZddlZddlZddl Zddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlmZmZmZdZdZGddeZGdd eZGd d eZd eed eefdZded efdZd eeded eefdZ dZ!d eeded eefdZ"d eed e#e$eee%ffdZ&ejNGddZ(GddZ)GddejTZ+y)z(Store, load, and handle problem reports.N) GeneratorIterableIteratorss(/c,eZdZdZdedeffd ZxZS)MalformedProblemReportzRaised when a problem report violates the crash report format. This exception might be raised when the keys of the report are not ASCII. messageargsc.t|d|dg|y)NzMalformed problem report: z$. Is this a proper .crash text file?)super__init__)selfrr __class__s 0/usr/lib/python3/dist-packages/problem_report.pyr zMalformedProblemReport.__init__,s+ ( 22 3  )__name__ __module__ __qualname____doc__strobjectr __classcell__rs@rrr&s    F  rrceZdZdZy)_SizeLimitExceededz>Raised internally to signal a value that is too big to encode.N)rrrrrrrr4sHrrcJeZdZdZdeeddfdZdeefdZdeefdZy) _EntryParserzIterator over entries in RFC822 formatted files. This iterator reads ahead one line to determine the boundaries between the entries. Each returned entry is a line-based iterator. iteratorreturnNc.||_d|_d|_y)NT)r next_line entry_read)r rs rr z_EntryParser.__init__?s  '+rc#K|jsJ|jd|_|jD]'}|jdr|||_d|_yd|_yw)z$Iterate over all lines of one entry.N T)r!r startswithr")r lines rentry_iteratorz_EntryParser.entry_iteratorDsa~~~nnMM Dt$ !%   sA"A$c|js|jD]}|jst|j|_d|_|jS)NF)r"r'r!nextr)r _s r__next__z_EntryParser.__next__QsQ((*  ~~!$--0DN""$$r) rrrrrbytesr r'r+rrrrr8s> %T  %(5/%rrentryrc#K|D]} tj|y#tj$r}t t |dd}~wwxYwwN)base64 b64decodebinasciiErrorrr)r-r&errors r_base64_decoderr5[sQ? ?""4( (?~~ ?(U4$ > ?s$A#AAA  AAr&c|d}d}|dzr |||dzz }|dzr||dk7r|dz }||dk7r|dz }|dzr||dk7r|dz }||dk7r|dz }|dzr|dz }||d S) z0Strip gzip header from line and return the rest. rNr)r&flagsoffsets r_strip_gzip_headerr@cs GE F qy$v,"" qy6la aKF6la!  rz6la aKF6la!  qy!  =r first_linec#K|j}|t|}|D]M}|dkDrd|jdr|dd|t|dz z }6|dd|t|dz z }Oyw)Nr r:r=)striplenendswith)r-rAr&lengths r _text_decoderrIws    D J YF$ A:K == q*  c$i!m #Fqr(N c$i!m #F$sA3A5cn ddl}|jS#t$r}td|ddd}~wwxYw)Nrz$Failed to import zstandard library: z#. Please install python3-zstandard.) zstandard ImportError RuntimeErrorZstdDecompressor)rKr4s r_get_zstandard_decompressorrOsP  % % '' 25':1 2  s 4/4 first_blockc#Ktj}|j||D]}|j|ywr/)rO decompressobj decompress)r-rP decompressorblocks r_zstandard_decoderrVsH.0>>@L  ! !+ ..-%%e,,-sAA crt|} |jdd\}} |j d}|jd k(}|r t|}n t||}|||fS#t$r!td|j dddwxYw#t $r}tt |dd}~wwxYw) zParse the given entry and return key and value. Return the key and a line iterator over the value. Also return a boolean if the entry is base64 encoded (i.e. is a binary value). :r:zLine backslashreplace)errorsz? does not contain a colon for separating the key from the valueNASCIIsbase64) r)split ValueErrorrdecodeUnicodeDecodeErrorrrEr5rI)r-rA key_in_bytesfirst_line_valuekeyr4base64_encodedvalue_iterators r _parse_entryres eJ+5+;+;D!+D(';!!'*&++-:N(/&u.>?  ..% $J%%-?%@C& '    ;$SZ0d:;s"A&B&*B B6B11B6cPeZdZUdZeed<deddfdZdZdee fdZ de fdZ y) CompressedFilezRepresents a ProblemReport value which points to a compressed file. The file is expected to be compressed with gzip or zstandard. filenamerNcH||_t|jd|_y)Nrb)rhopen_compressed_file)r rhs rr zCompressedFile.__init__s  $T]]D 9rcRt|dr|jjyy)Nrl)hasattrrlcloser s r__del__zCompressedFile.__del__s$ 4+ ,  ! ! ' ' ) -rc#RK |jjd}|sy|#w)z?Iterate over the compressed content of the file in 1 MB chunks.N)rlread)r rUs riter_compressedzCompressedFile.iter_compresseds/))..w7EK s%'cbtj|jtjdS)z?Check if the compressed file is readable by the effective user.T) effective_ids)osaccessrhR_OKrps r is_readablezCompressedFile.is_readablesyytDDr) rrrrr__annotations__r rqrr,ruboolr{rrrrgrgsD M::: *%ETErrgc eZdZdZ ddedzdedzdedzddfdZdeddfdZdefd Z defd Z e d e ede efd Z defd Zdej ddfdZdefdZdeefdZy)CompressedValuezRepresent a ProblemReport value which is gzip or zstandard compressed. By default, compressed values are in gzip format. Earlier versions of problem_report used zlib format (without gzip header). Nvaluenamecompressed_valuercH||_||_|r|j|yy)zAInitialize an empty CompressedValue object with an optional name.N)rr set_value)r rrrs rr zCompressedValue.__init__s'!1  NN5 ! rctj}tj|jd|d5}|j |ddd|j |_y#1swYxYw)zSet uncompressed value.wbrmodefileobjmtimeN)ioBytesIOgzipGzipFilerwritegetvaluer)r routgzs rrzCompressedValue.set_valuesSjjl ]]4994A F " HHUO  #   s A((A1cH|jJt|jS)z=Return size of the compressed (but not base64 encoded) value.)rrFrps rget_compressed_sizez#CompressedValue.get_compressed_sizes%$$0004(())rc4|jdzdzdzS)aReturn the size needed on disk to store the compressed value. The compressed value will be base64 encoded when written to disk which adds an overhead of 1/3 plus up to 2 bytes of padding. Additional spaces and newlines are ignored in this calculation. r=r7r9)rrps rget_on_disk_sizez CompressedValue.get_on_disk_sizes"))+a/A5::rr-c#Kt|d}|y|jtrt||Ed{y|jtrAt j t j }|jt|n't j }|j||D]}|j||jy7w)z5Decode the given compressed value (iterator version).N) r)r%ZSTANDARD_MAGIC_NUMBERrVGZIP_HEADER_STARTzlibrR MAX_WBITSrSr@flush)r-rUrTs rdecode_compressed_streamz(CompressedValue.decode_compressed_streamsUD! =    2 3)%7 7 7    - .--t~~o>L))*??4#8#89 9t4455rfilecN|jsJ|jjtr:t}|j t j |j|y|jjtretjt j |j5} |jd}|sn|j|& dddy|jtj|jy#1swY8xYw)z5Write uncompressed value into given file-like object.N)rrs)rr%rrO copy_streamrrrrrrtrrrS)r rrTrrUs rrzCompressedValue.writes$$$$  + +,B C68L  $ $RZZ0E0E%F M   + +,= >rzz$2G2G'HI RGGG,E JJu%      4??4#8#89:  s :)DD$c|jsJ|jjtr/tt j d|jdddSt |jS)z$Return length of uncompressed value.v}}T4+@+@+EFqIJ J4>>#$$rc>|jjS)z.Behaves like splitlines() for a normal string.)r splitlinesrps rrzCompressedValue.splitlines<s~~**,,r)NNN)rrrrr,rr rrrr staticmethodrrrtypingBinaryIOrrlistrrrrrrs#)- "t| "Dj " $, "  "/u//*S* ;#;##HUO##* 65 6;&//;d;*%%-DK-rrc FeZdZdZd,dededzddffd ZdeeddfdZ d-d eje jzd e e jd zd eedzddfd Zd eje jzdeeezdeddfdZdeefdZdedzfdZde fdZedeezde fdZedeezdeezfdZ d.deedzdeeeeezezezffdZd/d e jde ddfdZde deeeeeffdZ d e jdeddfdZ!ed e jdedeeddfd Z"dede#eddffd!Z$d e jdeddfd"Z%d/d#ed$e ddfd%Z& d0d&Z'd'ed(ee(zezezezddfd)Z)deefd*Z*ed e+ddfd+Z,xZ-S)1 ProblemReportz1Class to store, load, and handle problem reports.N problem_typedaterct|tj}t| ||dt |_y)zInitialize a fresh problem report. problem_type can be 'Crash', 'Packaging', 'KernelCrash' or 'KernelOops'. date is the desired date/time string; if None (default), the current local time is used. N) ProblemTypeDate)timeasctimer r setold_keys)r rrrs rr zProblemReport.__init__Ds2 <<<>D tDE#&% rtagsc|j}|j|}djt||d<y)z/Add tags to the report. Duplicates are dropped. TagsN)get_tagsunionjoinsorted)r r current_tagsnew_tagss radd_tagszProblemReport.add_tagsRs4}} %%d+xxx 01V rrbinary compressed key_filterc|j||jj|r t|}nd}t |D]}t |\}}}|||vr|r|durd|j|<n|dk(r*t |dj||j|<nn|jdjt j||j|<n-|jdj||j|<||j|t|dk(snt|jj|_ y)aInitialize problem report from a file-like object. If binary is False, binary data is not loaded; the dictionary key is created, but its value will be an empty string. If it is True, it is transparently uncompressed and available as dictionary byte array values. If binary is 'compressed', the compressed value is retained, and the dictionary value will be a CompressedValue object. This is useful if the compressed value is still useful (to avoid recompression if the file needs to be written back). file needs to be opened in binary mode. If key_filter is given, only those keys will be loaded. Files are in RFC822 format, but with case sensitive keys. NFrr)rrr)_assert_bin_modedataclearrrrerr _try_unicoderremoverFkeysr) r rrrremaining_keysr-rbrrcs rloadzProblemReport.loadXs6, d#   _N!N!$' E,8,? )C>)c.GU?%)DIIcN|+%4 388H3E&DIIcN&*%6%6!I!I(!ST&DIIcN "&!2!2388H3E!F #)%%c*~&!+/ 2DIINN,- rbin_keys directoryc|j|t|tr|g}t|}i}t |D]}t |\}}} ||vr| ||<|j || s0tjj||} t| d5} tj|D]} | j|  ddd|rtddj|dd|j!vr5|j#Dcgc] \}}|dus |}}}t%|dy#1swYsxYw#t$r} td| | d} ~ wwxYwcc}}w) zExtract only given binary elements from the problem report. Binary elements like kernel crash dumps can be very big. This method extracts directly files without loading the report into memory. rNzunable to open z Cannot find z, z in reportFz has no binary content)r isinstancerrrrerrxpathrrkrrrOSErrorKeyErrorvaluesitemsr])r rrr missing_keys b64_blockr-rbrrckey_pathrrUr4itemelementrs r extract_keyszProblemReport.extract_keyss d# h $ zHH~  !$' GE,8,? )C>,&+IcN    $!ww||Is3H G(D))S!0!I!I(!S) %()) G$ \$))L*A)B*MN N I$$& &/8/@UmdGGuDTTUEUw&<=> > ')) Gz:;F G Vs< E,D9E E%#E%9E >E E"EE"cXd|vr tSt|djdS)zReturn the set of tags.rr)rr\rps rrzProblemReport.get_tagss+  5L4<%%c*++rc.tjtj} tjtjdt t j t j|dtjtj|S#t$r'Ytjtj|ywxYw#tjtj|wxYw#tj$rYywxYw)zhGet timestamp (seconds since epoch) from Date field. Return None if it is not present. CrN) locale getlocaleLC_TIME setlocalerrmktimestrptimerr3)r orig_ctimes r get_timestampzProblemReport.get_timestamps %%fnn5   =  54;;t}}T&\'BCD  <   <   <||  sBAB"=$C>" C+C,$C>CC&C;;C>>DDc&d|jvS)z~Check if the report has any keys which were not loaded. This could happen when using binary=False in load(). N)rrps rhas_removed_fieldsz ProblemReport.has_removed_fieldss t{{}$$rstringctt|tr(|D]#}|dks t|jr#yy)z0Check if the given strings contains binary data. TF)rr,chrisspace)rcs r is_binaryzProblemReport.is_binarys9 fe $ r6#a&.."2 rrct|tr#|j|s |jdS|S#t$r|cYSwxYw)z*Try to convert bytearray value to Unicode.UTF-8)rr,rr^r_)clsrs rrzProblemReport._try_unicodesJ eU #CMM%,@ ||G,, &   s6 AArc#RK|r/tt|jt|z}nt|j}dD]*}||vs|j||j d|,|D]%}|j dr||}||||f'yw)aIterate over all non-internal items sorted. The most interesting fields will be returned first. The remaining items will be returned in alphabetical order. Keys starting with an underscore are considered internal and are skipped. Also values that are None will be skipped. If keys is provided, only those keys will be iterated over. ) Traceback StackTraceTitlerPackageExecutablePathrr*N)rrrrinsertr%)r rrbrs r sorted_itemszProblemReport.sorted_itemss #diik*SY67D$))+&D $Cd{ C  As# $ !C~~c"IE}tCy.  !s AB'AB'only_newc|j||j|\}}|D]}|j|||D]}|j||y)aWrite information into the given file-like object. If only_new is True, only keys which have been added since the last load() are written (i. e. those returned by new_keys()). If a value is a string, it is written directly. Otherwise it must be a tuple of the form (file, encode=True, limit=None, fail_on_empty=False). The first argument can be a file name or a file-like object, which will be read and its content will become the value of this key. 'encode' specifies whether the contents will be gzip compressed and base64-encoded (this defaults to True). If limit is set to a positive integer, the file is not attached if it's larger than the given limit, and the entire key will be removed. If fail_on_empty is True, reading zero bytes will cause an OSError. file needs to be opened in binary mode. Files are written in RFC822 format. N)r_get_sorted_keys_write_ascii_item)_write_binary_item_compressed_and_encoded)r rrasckeysbinkeysks rrzProblemReport.writesi( d#00: ,A  " "4 + , DA  : :4 C Drc8g}g}|jjD]}|r||jvr|j|}t|dr5|j |r|j |R|j |dt |ttfs%t|dk\r|ds|j ||j ||jd|vr#|jd|jdd|j||fS)zySort keys into ASCII non-ASCII/binary attachment ones, so that the base64 ones appear last in the report findr=r:rr) rrrrnrappendrrgrrFsortrr)r rrrrvs rrzProblemReport._get_sorted_keys/s! "AA. ! Aq&!>>!$NN1%NN1%q>?"CDFaK!q!q!# "&   G # NN= ) NN1m , rrbc|j|}t|dst|dk\r |d|d}nd}t|dk\xr|d}t|ddr|dj}n(t |dd5}|j}ddd|rt|dk(rt d|z|t||kDr|j|=yt |tr|jd }|j|jd d |vr3|jd |j|jd d n"|jd|j||jd y#1swYxYw)Nr r7r=r9rrtrjdid not get any data for field rr[rCs:  s: ) rrnrFrtrkrrrencoderreplace)r rrbr limit fail_on_emptyfs rrzProblemReport._write_ascii_itemOsX IIcNq&!1v{qt/!FaK0AaDMqtV$aDIIK!A$%!A!Q1?#EFF SVe^IIcN a !A 3::g&' A: JJw  JJqyy/ 0 JJu  JJqM 5-!!s >E??Fchunkscf|j} |j|djd|D]7}|jd|jtj|9|jdy#t $r$|j ||j|wxYw)zCWrite out binary chunks as a base64-encoded RFC822 multiline field.z: base64r[rrCN)tellrrr0 b64encode Exceptionseektruncate)rrbrreset_positionchunks r!_write_binary_item_base64_encodedz/ProblemReport._write_binary_item_base64_encodedvs   JJ#h'..w7 8 4 6" 6++E23 4 JJu   IIn % MM. )  s A0B-B0c #K|j|}t|tr|jEd{yt|tr|j J|j yt dz|jdzdz}|tjd}tjdtjtj tjd}d}t|dr>|t|z }tj||}|j!|}|r |nd}t|d k\r |d |d }t|dd r|d} nt#|dd } | j%d } |t| z }tj| |}|||kDr|j|=t'd| r|j!| }|r|nnpt|dd s| j)t|dk\r'|d r"|dk(rt+d|dt-|d|j/} | t1j2d|dzz } | t1j2d|dzz } | y7Jw)aGenerator taking the value out of self.data and outputing it in compressed chunks of binary data. Throws a _SizeLimitExceeded exception if the value exceeds its specified size limit, in which case it will also remove the value from self.data entirely. Nsrrrr r7r=rtrjrsz,Binary data bigger than the limit ({limit}b)r9rz from rl)rrrgrurrrrrcrc32 compressobjDEFLATEDr DEF_MEM_LEVELrnrFcompressrkrtrrorrrrpack) r rbr gzip_headercrcbcsizeoutblockrrrUs r_generate_compressed_chunksz)ProblemReport._generate_compressed_chunkssu # e^ ,,,. . .  e_ -))5 55(( (  - .jj! "   jjo   aASASUV W 5& ! CJ D**UC(C{{5)HE5zQ58#7auQx(!Hq4(wE "jj,$e| IIcN0J!{{51H& 58V, 5zQ5819!9#fSq]OT   T3#344 T4*#455 E /s3JI?I Jch |j|||j|y#t$rYywxYw)z?Write the binary keys with gzip compression and base64 encodingN)rr-r)r rrbs rrz7ProblemReport._write_binary_item_compressed_and_encodeds;   2 2c4;;C@ "   s "% 11 reportfile keep_timesctj|} t|d5}tj|d|j |ddd|r,tj ||j |jftj||jy#1swYXxYw#|r,tj ||j |jftj||jwxYw)aAdd this report's data to an already existing report file. The file will be temporarily chmod'ed to 000 to prevent frontends from picking up a hal-updated report file. If keep_times is True, then the file's atime and mtime restored after updating. abrN) rxstatrkchmodrutimest_atimest_mtimest_mode)r r/r0streports radd_to_existingzProblemReport.add_to_existingsWWZ  -j$' #6Q' 6" #bkk2;;%?@ HHZ ,  # #bkk2;;%?@ HHZ ,s# B.(B" B."B+'B..AC>c~ |j|t|jj}d}g}d|vr#|j d|j dd|r6d} |D]/} | |vs|j | |j | | | dz } 1|D]} |r| |vr |j| } d} t | tr| j} nt| dsd} t| ddr| d}nt| dd}| jd r|j} notj}tj | d |d 5} |jd }|r|j#|nn' ddd|j%} |j'n;|j)| r*| jd r| } nt| | j} | rt*j,j.j1d d}| jd r|j3dd| n|j3dd| d z|j5| t*j6j9||j;|t=| }t | t>r| jAdd} t | tBsJt=| jE}|dkr%|dk(r | jG} || dz| zdzz }w|dkrK||krF|| dzz }| jds| dz } || jIjKdddzz }t*j,jLjO| d}|j3dd| dz|j;|t*j,jLjO|d}|j3dd|j d|t*j,jPjS}|r*|jUD]\} } |j3| | |D]}|jW||j#|jYj[d|j#dy#1swY5xYw)aWrite MIME/Multipart RFC 2822 formatted data into file. file must be a file-like object, not a path. It needs to be opened in binary mode. If a value is a string or a CompressedValue, it is written directly. Otherwise it must be a tuple containing the source file and an optional boolean value (in that order); the first argument can be a file name or a file-like object, which will be read and its content will become the value of this key. The file will be gzip compressed, unless the key already ends in .gz. attach_treshold specifies the maximum number of lines for a value to be included into the first inline text part. All bigger values (as well as all non-ASCII ones) will become an attachment, as well as text values bigger than 1 kB. Extra MIME preamble headers can be specified, too, as a dictionary. skip_keys is a set/list specifying keys which are filtered out and not written to the destination file. priority_fields is a set/list specifying the order in which keys should appear in the destination file. rrr:Nr rtrjz.gzrrrs applicationzx-gzipzContent-Disposition attachment)rhrriz:  z: z )_charsetz.txtinlinerC).rrrrrrrrrrnrkrGrtrrrrrrroremailmimebaseMIMEBase add_header set_payloadencoders encode_base64r rFr,r^rrrstriprErtextMIMEText multipart MIMEMultipartrattach as_stringr)r rattach_treshold extra_headers skip_keyspriority_fieldsrrL attachmentscounterpriority_fieldrr  attach_valuerrrrUattr+linesmsgas r write_mimezProblemReport.write_mimes=F d#diinn&' D KK & KK= ) G"1 !!T)KK/KK8qLG  ! M ,AQ)^ ! AL!_- 11 Q'! 1Q4(!AQqT4(A::e$#$668L**,CqtSJ&b"$%FF7OE$ " % # !& &$'<<>L "::e$#$L#21a#8#I#ILjjoo..}hG::e$NN#8,QRNSNN-|a%i# -,,S1""3'1va')4A!!S)))ALLN+4AJ&D::d+T AGGI--dE:TAAD **//221w2GCNN-|a&j# &&s+[M ,`jjoo&&tg&> ,h71c"jj""002 %++- %1q!$ % A JJqM  3==?))'23 5K&&s )R22R< rr ct|dsJ|jddjddjddjstd|dt |t t fszt|dsnt |trOt|dk(s#t|d k\r3t|d kr%|dd vrt|d dst|d d std|d|jj||S)Nisalnum.r=-r*zkey 'zT' contains invalid characters (only numbers, letters, '.', '_', and '-' are allowed)r:r=r9>FTrrtzvalue for key z7 must be a string, CompressedValue, or a file reference) rnrr`r]rrgrtuplerF TypeErrorr __setitem__)r rr s rrezProblemReport.__setitem__s q)$$$yyb!))#r2::3CKKMsJK  q>?; <q)$1e$FaKA! A! ! 8MQqT9-1v1F $'(  yy$$Q**rcbt|jj|jz S)zReturn newly added keys. Return the set of keys which have been added to the report since it was constructed or loaded. )rrrrrps rnew_keyszProblemReport.new_keyss# 499>>#$t}}44rc*t|drJdy)z0Assert that given file object is in binary mode.encodingz"file stream must be in binary modeN)rn)rs rrzProblemReport._assert_bin_modes4,R.RR,,r)CrashN)TNr/)F)NNN).rrrrrr rrrrrrr}Literalrrrrrrrrr,r classmethodrrrcrrrrrrrrr-rr;r^rgrergrrrrs@rrrAs; (S (#* (PT (2Xc]2t27;+/ 6.mmfoo-6.v~~l336.SMD( 6.  6.p(?mmfoo-(?3-#%(? (?  (?T,#c(, sTz$%D%%#+$,0#!SMD(#! %eo5;eCDE F#!JD&//DTDdD<  %S 498L2M @%foo%C%D%Noo$'19%  MsMydAR7SM^ OO *-   -#-4-D-( Rh++//ACG%O+ +<5#c(5SvS$SSrr),rr0r2 collections dataclassesemail.encodersrCemail.mime.baseemail.mime.multipartemail.mime.textrrrrxrrrrcollections.abcrrrrrr]rrMrrr,r5r@rIrOrVrcrr}re dataclassrgrUserDictrrrrrwsX. 99$,  Z  II %8 %F?8E??x?Uu( $% $e $ $ (-huo-E-huo-//E#x2L,M/< EEE