
    Si                       S SK Jr  S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SK	r	S SK
JrJr  S SKrS SKrS SKrS SKJrJrJrJrJrJrJr  S SKJrJrJrJrJrJrJrJ r   S SK!J"r"J#r#  \(       a  S SK$J%r%   " S S	\RL                  5      r'\RP                  " S
S0S
S0/5       " S S\'5      5       r)\RP                  " S
S0S
S0/5       " S S\'5      5       r*\RP                  " S
S0S
S0/5       " S S\RL                  5      5       r+\RP                  " S
S0S
S0/5       " S S\RL                  5      5       r, " S S\'5      r-\R\                  " \R^                  S:g  SS9 " S S\-5      5       r0 " S S\+5      r1 " S S\,5      r2 " S  S!\RL                  5      r3S2S" jr4\R\                  " \R^                  S:H  S#S9 " S$ S%\'5      5       r5\R\                  " \R^                  S:H  S#S9 " S& S'\'5      5       r6\R\                  " \R^                  S:H  S(S9 " S) S*\'5      5       r7 " S+ S,\'5      r8 " S- S.\RL                  5      r9 " S/ S0\'5      r:\;S1:X  a  \Rx                  " 5         gg)3    )annotationsN)TYPE_CHECKINGAny)
ModelProto	NodeProtoTensorProtocheckerhelperparsershape_inference)_ALLOWED_EXTERNAL_DATA_KEYSExternalDataInfo convert_model_from_external_dataconvert_model_to_external_dataload_external_data_for_modelload_external_data_for_tensorsave_external_dataset_external_data)
from_arrayto_array)Sequencec                  |    \ rS rSr% SrSrS\S'   SS jrSS jrSS jr	 S       SS	 jjr
SSS
 jjrSS jrSrg)TestLoadExternalDataBase-   zyBase class for testing external data related behaviors.

Subclasses should be parameterized with a serialization format.
protobufstrserialization_formatc                   [         R                  " 5       U l        U R                  R                  U l        [
        R                  " S5      R                  SS5      R                  [
        R                  5      S-   U l
        [
        R                  " S5      R                  SS5      R                  [
        R                  5      S-   U l        U R                  5       U l        g N         i      )tempfileTemporaryDirectory_temp_dir_objnametemp_dirnparangereshapeastypefloat32initializer_valueattribute_valuecreate_test_modelmodel_filenameselfs    [/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/onnx/test/test_external_data.pysetUpTestLoadExternalDataBase.setUp5   s    %88:!//44!#1!5!5a!;!B!B2::!NQT!T!yy|33Aq9@@LsR"446    c                8    U R                   R                  5         g Nr&   cleanupr2   s    r4   tearDown!TestLoadExternalDataBase.tearDown<       ""$r7   c                    [         R                  R                  U R                  [	        [
        R                  " 5       5      S-   5      $ Nz.onnxospathjoinr(   r   uuiduuid4r2   s    r4   get_temp_model_filename0TestLoadExternalDataBase.get_temp_model_filename?   +    ww||DMM3tzz|+<w+FGGr7   c                   [        [        R                  " U5      5      nX$l        U=(       d    U S3n[	        XES9  [        [        R                  R                  U R                  U5      S5       nUR                  UR                  5        S S S 5        UR                  S5        [        R                  R                  Ul        U$ ! , (       d  f       N@= f)N.binlocationwbraw_data)r   r)   arrayr'   r   openrB   rC   rD   r(   writerO   
ClearFieldonnxr   EXTERNALdata_location)r3   valuetensor_namerM   tensortensor_filename	data_files          r4   create_external_data_tensor4TestLoadExternalDataBase.create_external_data_tensorB   s     BHHUO,!":T&:&;"'',,t}}o>EOOFOO, F*%#//88	 FEs   1C
Cc           	     6   [         R                  R                  S/ S/U R                  U R                  S5      S9nU R                  U R
                  SU5      /n[        R                  " S[         R                  R                  U R
                  R                  5      /n[        R                  " U/SU/ US9n[        R                  " U5      n[        R                  R                  U R                  S5      n[         R                   " XgU R"                  5        U$ )	NConstantvaluesr/   inputsoutputsrW   input_value
test_graphrb   rc   initializer
model.onnx)rT   r
   	make_noder\   r/   r.   make_tensor_value_infor   FLOATshape
make_graph
make_modelrB   rC   rD   r(   
save_modelr   )r3   rM   constant_nodeinitializersrb   graphmodelr1   s           r4   r0   *TestLoadExternalDataBase.create_test_modelP   s   --J22$$!	 . 
 ,,&&
 ))t//55t7M7M7S7S
 !!O$
 !!%(dmm\Bt/H/HIr7   c                    U R                   S:w  a  U R                  S5        [        R                  " U R                  5        g )Nr   zDcheck_model supports protobuf only as binary when provided as a path)r   skipTestr	   check_modelr1   r2   s    r4   test_check_model)TestLoadExternalDataBase.test_check_modelv   s5    $$
2MMV 	D//0r7   )r&   r/   r.   r1   r(   NreturnNone)r{   r    rW   z	list[Any]rX   r   rM   r   r{   r   )rM   r   r{   r   )__name__
__module____qualname____firstlineno____doc__r   __annotations__r5   r<   rG   r\   r0   rx   __static_attributes__ r7   r4   r   r   -   s[    
 !+#*7%H CE-0<?	$L1r7   r   r   r   	textprotoc                  2    \ rS rSrSS jrSS jrSS jrSrg)TestLoadExternalData~   c                   [         R                  " U R                  U R                  5      nUR                  R
                  S   n[        R                  R                  [        U5      U R                  5        UR                  R                  S   R                  S   R                  n[        R                  R                  [        U5      U R                  5        g Nr   rT   
load_modelr1   r   rr   rg   r)   testingassert_allcloser   r.   node	attributetr/   r3   rs   initializer_tensorattribute_tensors       r4   test_load_external_data,TestLoadExternalData.test_load_external_data   s     3 3T5N5NO"[[44Q7


""8,>#?AWAWX ;;++A.88;==


""8,<#=t?S?STr7   c                   [         R                  " U R                  U R                  SS9n[	        XR
                  5        UR                  R                  S   n[        R                  R                  [        U5      U R                  5        UR                  R                  S   R                  S   R                  n[        R                  R                  [        U5      U R                   5        g )NFload_external_datar   )rT   r   r1   r   r   r(   rr   rg   r)   r   r   r   r.   r   r   r   r/   r   s       r4   !test_load_external_data_for_model6TestLoadExternalData.test_load_external_data_for_model   s    !:!:u
 	%UMM:"[[44Q7


""8,>#?AWAWX ;;++A.88;==


""8,<#=t?S?STr7   c                   [         R                  " U R                  U R                  5      n[        R
                  R                  U R                  S5      n[        R                  " U5        [        R
                  R                  US5      n[         R                  " XU R                  5        [         R                  " X0R                  5      nUR                  R                  S   n[        R                  R                  [        U5      U R                   5        UR                  R"                  S   R$                  S   R&                  n[        R                  R                  [        U5      U R(                  5        g N	save_copyrh   r   rT   r   r1   r   rB   rC   rD   r(   mkdirro   rr   rg   r)   r   r   r   r.   r   r   r   r/   r3   rs   r(   new_model_filename	new_modelr   r   s          r4   test_save_external_data,TestLoadExternalData.test_save_external_data        3 3T5N5NO77<<{;
WW\\(LA43L3LMOO$68Q8QR	&__88;


""8,>#?AWAWX$??//2<<Q?AA


""8,<#=t?S?STr7   r   Nrz   )r   r   r   r   r   r   r   r   r   r7   r4   r   r   ~   s    U	UUr7   r   c                      \ rS rSr    S	S jrS
S jrS
S jr\R                  R                  \	R                  " S5      5          SS j5       rSrg)TestLoadExternalDataSingleFile   c           	     z   Sn/ n[        [        R                  R                  U R                  U5      S5       nU H  u  pV[        [        R                  " U5      5      nUR                  5       nUS-  S:w  a%  UR                  SSUS-  -
  -  5        US-   US-  -
  nUR                  UR                  5        [        UUUUR                  5       U-
  S9  Xgl        UR                  S5        [        R                  R                   Ul        UR%                  U5        M     S S S 5        U$ ! , (       d  f       U$ = f)Ntensors.binab   r       rM   offsetlengthrO   )rQ   rB   rC   rD   r(   r   r)   rP   tellrR   rO   r   r'   rS   rT   r   rU   rV   append)	r3   tensors_datarZ   tensorsr[   rW   rX   rY   r   s	            r4   create_external_data_tensors;TestLoadExternalDataSingleFile.create_external_data_tensors   s    ("'',,t}}o>E&2"#BHHUO4")D=A%OOETFTM-A$BC#d]Vd]:F0!,!$>>+f4	 *!!*-'+'7'7'@'@$v&# '3 F( ) FE( s   C(D++
D:c                   [         R                  " U R                  U R                  5      nUR                  R
                  S   n[        R                  R                  [        U5      U R                  5        UR                  R                  S   R                  S   R                  n[        R                  R                  [        U5      U R                  5        g r   r   r   s       r4   #test_load_external_single_file_dataBTestLoadExternalDataSingleFile.test_load_external_single_file_data   s     3 3T5N5NO"[[44Q7


""8,>#?AWAWX ;;++A.88;==


""8,<#=t?S?STr7   c                   [         R                  " U R                  U R                  5      n[        R
                  R                  U R                  S5      n[        R                  " U5        [        R
                  R                  US5      n[         R                  " XU R                  5        [         R                  " X0R                  5      nUR                  R                  S   n[        R                  R                  [        U5      U R                   5        UR                  R"                  S   R$                  S   R&                  n[        R                  R                  [        U5      U R(                  5        g r   r   r   s          r4   #test_save_external_single_file_dataBTestLoadExternalDataSingleFile.test_save_external_single_file_data   r   r7   )TFc                N   [         R                  " U R                  U R                  5      n[        R
                  R                  U R                  S5      n[        R                  " U5        [        R
                  R                  U R                  S5      n[        R                  " U5        U(       a!  [        R
                  R                  US5      nOSn[        R
                  R                  U R                  S5      n[        R                  " U5        [        R
                  R                  US5      nS	S jnU" UUS9  U R                  [         R                  R                  5         [         R                  " X'U R                  5        S S S 5        g ! , (       d  f       g = f)
Nr   invalid_external_datar   z$../invalid_external_data/tensors.binexternal_datarh   c                    U R                   R                   H&  nUR                  S5      (       d  M  [        X!5        M(     g )NrO   )rr   rg   HasFieldr   )rs   rM   rY   s      r4   'convert_model_to_external_data_no_checkڅTestLoadExternalDataSingleFile.test_save_external_invalid_single_file_data_and_check.<locals>.convert_model_to_external_data_no_check   s-    ++11??:..%f7 2r7   rL   )rs   r   rM   r   )rT   r   r1   r   rB   rC   rD   r(   r   assertRaisesr	   ValidationErrorro   )	r3   use_absolute_pathrs   	model_dirtraversal_external_data_dir traversal_external_data_locationexternal_data_dirnew_model_filepathr   s	            r4   5test_save_external_invalid_single_file_data_and_checkTTestLoadExternalDataSingleFile.test_save_external_invalid_single_file_data_and_check   s     3 3T5N5NOGGLL<	
&(ggllMM2'
# 	,-/1ww||+]0, 0V,GGLLH
"#WW\\)\B	8
 	05	

 t||;;<OOEt7P7PQ =<<s   +"F
F$r   Nr   zlist[tuple[list[Any], Any]]r{   zlist[TensorProto]rz   )r   boolr{   r|   )r   r   r   r   r   r   r   parameterizedexpand	itertoolsproductr   r   r   r7   r4   r   r      sm    7	8UU   ''	

#R!%#R	#R
#Rr7   r   c                     \ rS rSr% SrS\S'   SS jrS r    SS jrSS jr	\
R                  " \S:g  S	5      SS
 j5       rSS jrSS jrSS jr  SS jr  SS jr  SS jr  SS jrSS jr  SS jrSS jrSS jrSS jrSrg) TestSaveAllTensorsAsExternalDatai  r   r   r   c                   [         R                  " 5       U l        U R                  R                  U l        [
        R                  " S5      R                  SS5      R                  [
        R                  5      S-   U l
        [
        R                  " S5      R                  SS5      R                  [
        R                  5      S-   U l        U R                  5       U l        g r   )r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   create_test_model_protors   r2   s    r4   r5   &TestSaveAllTensorsAsExternalData.setUp  s    %88:!//44!#1!5!5a!;!B!B2::!NQT!T!yy|33Aq9@@LsR113
r7   c                    [         R                  R                  U R                  [	        [
        R                  " 5       5      S-   5      $ r@   rA   r2   s    r4   rG   8TestSaveAllTensorsAsExternalData.get_temp_model_filename  rI   r7   c                    / nU H;  u  p4[        [        R                  " U5      5      nXEl        UR	                  U5        M=     U$ r9   )r   r)   rP   r'   r   )r3   r   r   rW   rX   rY   s         r4   create_data_tensors4TestSaveAllTensorsAsExternalData.create_data_tensors!  s@     ".E0F%KNN6" #/
 r7   c                   U R                  U R                  S4U R                  S4/5      n[        R                  R                  S/ S/US   S9n[        R                  " S[        R                  R                  U R                  R                  5      /n[        R                  " U/SU/ US   /S	9n[        R                  " U5      $ )
Nr/   rd   r_   r`   r   ra   re      rf   )r   r/   r.   rT   r
   ri   rj   r   rk   rl   rm   rn   )r3   r   rp   rb   rr   s        r4   r   8TestSaveAllTensorsAsExternalData.create_test_model_proto,  s    **%%'89''7
 --rH:WQZ . 

 ))t//55t7M7M7S7S
 !!O 
   ''r7   :check_model supports protobuf only when provided as a pathc                D    [         R                  " U R                  5        g r9   r	   rw   rs   r2   s    r4   rx   1TestSaveAllTensorsAsExternalData.test_check_modelG      
 	DJJ'r7   c                T   U R                  5       n[        U R                  SS9  [        R                  " U R                  XR
                  5        [        R                  " XR
                  5      nUR                  R                  S   nU R                  UR                  S5      5        g )N   size_thresholdr   rV   )rG   r   rs   rT   ro   r   r   rr   rg   assertFalser   r3   model_file_pathrs   r   s       r4   7test_convert_model_to_external_data_with_size_thresholdXTestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_with_size_thresholdN  sy    668&tzz$G

O5N5NO1J1JK"[[44Q7+44_EFr7   c                   U R                  5       n[        U R                  SS9  [        R                  " U R                  XR
                  5        [        R                  " XR
                  5      nUR                  R                  S   nU R                  UR                  S5      5        [        R                  R                  [        U5      U R                  5        g )Nr   r   rV   )rG   r   rs   rT   ro   r   r   rr   rg   
assertTruer   r)   r   r   r   r.   r   s       r4   :test_convert_model_to_external_data_without_size_threshold[TestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_without_size_thresholdX  s    668&tzz!D

O5N5NO1J1JK"[[44Q7*33ODE


""8,>#?AWAWXr7   c                   U R                  5       n[        [        R                  " 5       5      n[	        U R
                  SSUS9  [        R                  " U R
                  XR                  5        U R                  [        R                  R                  [        R                  R                  U R                  U5      5      5        [        R                  " XR                  5      n[!        U5        U R                  5       n[        R                  " X1U R                  5        [        R                  " XR                  5      nUR"                  R$                  S   nU R'                  [)        UR*                  5      5        U R-                  UR.                  [0        R2                  5        [4        R6                  R9                  [;        U5      U R<                  5        UR"                  R>                  S   R@                  S   RB                  nU R'                  [)        UR*                  5      5        U R-                  UR.                  [0        R2                  5        [4        R6                  R9                  [;        U5      U RD                  5        g )Nr   T)r   all_tensors_to_one_filerM   )#rG   r   rE   rF   r   rs   rT   ro   r   r   rB   rC   isfilerD   r(   r   r   rr   rg   r   lenr   assertEqualrV   r   DEFAULTr)   r   r   r   r.   r   r   r   r/   )r3   r   external_data_filers   r   r   s         r4   ?test_convert_model_to_external_data_from_one_file_with_location`TestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_from_one_file_with_locationb  s   668 .&JJ$('		
 	

O5N5NOrww||DMMCU'VWX1J1JK 	)/6680I0IJ1J1JK"[[44Q7/==>?+99;;N;NO


""8,>#?AWAWX ;;++A.88;==-;;<=)779L9LM


""8,<#=t?S?STr7   c                   U R                  5       n[        U R                  SSS9  [        R                  " U R                  XR
                  5        U R                  [        R                  R                  U5      5        U R                  [        R                  R                  [        R                  R                  U R                  U5      5      5        g )Nr   T)r   r   rG   r   rs   rT   ro   r   r   rB   rC   r   rD   r(   r3   r   s     r4   Rtest_convert_model_to_external_data_from_one_file_without_location_uses_model_namesTestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_from_one_file_without_location_uses_model_name  s     668&JJq$	
 	

O5N5NO78rww||DMM?'STUr7   c                Z   U R                  5       n[        U R                  SSSS9  [        R                  " U R                  XR
                  5        U R                  [        R                  R                  U5      5        U R                  [        R                  R                  [        R                  R                  U R                  S5      5      5        U R                  [        R                  R                  [        R                  R                  U R                  S5      5      5        g )Nr   Fr   r   convert_attributerd   r/   )rG   r   rs   rT   ro   r   r   rB   rC   r   rD   r(   r   r  s     r4   Itest_convert_model_to_external_data_one_file_per_tensor_without_attributejTestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_one_file_per_tensor_without_attribute  s     668&JJ$)#		
 	

O5N5NO78rww||DMM='QRST]]DU(VWXr7   c                Z   U R                  5       n[        U R                  SSSS9  [        R                  " U R                  XR
                  5        U R                  [        R                  R                  U5      5        U R                  [        R                  R                  [        R                  R                  U R                  S5      5      5        U R                  [        R                  R                  [        R                  R                  U R                  S5      5      5        g )Nr   FTr  rd   r/   r  r  s     r4   Ftest_convert_model_to_external_data_one_file_per_tensor_with_attributegTestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_one_file_per_tensor_with_attribute  s     668&JJ$)"		
 	

O5N5NO78rww||DMM='QRSrww||DMMCT'UVWr7   c                P   U R                  5       n[        U R                  SSSS9  [        R                  " U R                  XR
                  5        U R                  [        R                  R                  [        R                  R                  U R                  S5      5      5        U R                  [        R                  R                  [        R                  R                  U R                  S5      5      5        [        R                  " XR
                  5      nUR                  R                  S   nU R                  UR!                  S5      5        UR                  R"                  S   R$                  S   R&                  nU R                  UR!                  S5      5        g )Nr   F)r   r  r   rd   r/   rV   )rG   r   rs   rT   ro   r   r   rB   rC   r   rD   r(   r   r   rr   rg   r   r   r   r   r3   r   rs   r   r   s        r4   Etest_convert_model_to_external_data_does_not_convert_attribute_valuesfTestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_does_not_convert_attribute_values  s     668&JJ#$)		
 	

O5N5NOrww||DMM='QRST]]DU(VWX1J1JK"[[44Q7*33ODE ;;++A.88;==)22?CDr7   c                   U R                  5       n[        U R                  SSS9  [        R                  " U R                  XR
                  5        [        R                  " XR
                  5      nUR                  R                  S   n[        R                  R                  [        U5      U R                  5        U R                  UR                  S5      5        UR                  R                   S   R"                  S   R$                  n[        R                  R                  [        U5      U R&                  5        U R                  UR                  S5      5        g )Nr   Tr   r  rV   )rG   r   rs   rT   ro   r   r   rr   rg   r)   r   r   r   r.   r   r   r   r   r   r/   r  s        r4   =test_convert_model_to_external_data_converts_attribute_values^TestSaveAllTensorsAsExternalData.test_convert_model_to_external_data_converts_attribute_values  s    668&JJqD	
 	

O5N5NO1J1JK"[[44Q7


""8,>#?AWAWX*33ODE ;;++A.88;==


""8,<#=t?S?ST(11/BCr7   c                (   U R                  5       n[        R                  " U R                  UU R                  SS9  U R                  [        R                  R                  U5      5        [        R                  " XR                  5      nUR                  R                  S   nU R                  UR                  S5      5        UR                  R                  S   R                  S   R                   nU R                  UR                  S5      5        g )NF)save_as_external_datar   rV   )rG   rT   ro   rs   r   r   rB   rC   r   r   rr   rg   r   r   r   r   r   r  s        r4   Etest_save_model_does_not_convert_to_external_data_and_saves_the_modelfTestSaveAllTensorsAsExternalData.test_save_model_does_not_convert_to_external_data_and_saves_the_model  s     668JJ%%"'		
 	781J1JK"[[44Q7+44_EF ;;++A.88;==)22?CDr7   c                   U R                  5       n[        R                  " U R                  UU R                  SSS SSS9  [        R
                  " XR                  5      nUR                  R                  S   nU R                  UR                  S5      5        [        R                  R                  [        U5      U R                  5        UR                  R                  S   R                   S   R"                  nU R%                  UR                  S5      5        [        R                  R                  [        U5      U R&                  5        g )NTr   Fr  r   rM   r   r  rV   rG   rT   ro   rs   r   r   rr   rg   r   r   r)   r   r   r   r.   r   r   r   r   r/   r  s        r4   0test_save_model_does_convert_and_saves_the_modelQTestSaveAllTensorsAsExternalData.test_save_model_does_convert_and_saves_the_model  s   668JJ%%"&$(#		
 1J1JK"[[44Q7*33ODE


""8,>#?AWAWX ;;++A.88;==)22?CD


""8,<#=t?S?STr7   c           
     $   U R                  5       n[        R                  " U R                  UU R                  SS SSS9  [        R
                  " XR                  SS9n[        R                  " UUU R                  SS SSS9  [        R
                  " XR                  5      nUR                  R                  S   nU R                  UR                  S5      5        [        R                  R                  [        U5      U R                  5        UR                  R                  S   R                   S   R"                  nU R%                  UR                  S5      5        [        R                  R                  [        U5      U R&                  5        g )NTr   F)r  rM   r   r  r   rV   r  r  s        r4   -test_save_model_without_loading_external_dataNTestSaveAllTensorsAsExternalData.test_save_model_without_loading_external_data  sB   668JJ%%"&#	
 665
 	%%"&#	
 1J1JK"[[44Q7*33ODE


""8,>#?AWAWX ;;++A.88;==)22?CD


""8,<#=t?S?STr7   c                   U R                  5       nU R                  R                  R                  S   R                  n[
        R                  " U R                  UU R                  SSS9  U R                  [        R                  R                  U5      5        [
        R                  " XR                  SS9nUR                  R                  S   nSUl        [        X@R                  5        U R                  UR                  U5        g )Nr   T)r  r   Fr   s   dummpy_raw_data)rG   rs   rr   rg   rO   rT   ro   r   r   rB   rC   r   r   r   r(   r   )r3   r   original_raw_datars   r   s        r4   6test_save_model_with_existing_raw_data_should_overrideWTestSaveAllTensorsAsExternalData.test_save_model_with_existing_raw_data_should_override&  s    668 JJ,,88;DDJJ%%"&	
 	78665
 #[[44Q7&8#%&8--H+446GHr7   )r&   r/   r.   rs   r(   Nrz   r   r{   r   )r   r   r   r   r   r   r5   rG   r   r   unittestskipIfrx   r   r   r   r  r  r  r  r  r  r  r  r#  r   r   r7   r4   r   r     s     !+#*4H	7			(6 __
*D(	(GYU>V	VY	Y"X	X"E	E.D$E	E&U.!UFIr7   r   c                      \ rS rSr% SrS\S'   SS jr\S 5       rSS jr	SS jr
\R                  " \S:g  S	5      SS
 j5       rSS jrSS jrSS jrSrg)TestExternalDataToArrayi<  r   r   r   c                   [         R                  " 5       U l        U R                  R                  U l        [
        R                  R                  U R                  S5      U l        [        R                  R                  SSS5      R                  [        R                  5      U l        SU l        U R!                  5       U l        g )Nrh   
   <   d   )   i,  )r$   r%   r&   r'   r(   rB   rC   rD   _model_file_pathr)   randomrandr,   r-   
large_data
small_datar0   rs   r2   s    r4   r5   TestExternalDataToArray.setUpE  s    %88:!//44%'WW\\$--%N))..R5<<RZZH$++-
r7   c                    U R                   $ r9   )r/  r2   s    r4   r   'TestExternalDataToArray.model_file_pathM  s    $$$r7   c                8    U R                   R                  5         g r9   r:   r2   s    r4   r<    TestExternalDataToArray.tearDownQ  r>   r7   c                   [         R                  " S[        R                  U R                  R
                  5      n[         R                  " S[        R                  U R                  R
                  [        R                  R                  U R                  5      SS9n[        R                  " U R                  [        R                  5      n[         R                  " S[        R                  UR
                  [        R                  R                  U5      SS9n[         R                  " S[        R                  U R                  5      n[        R                   R                  SSS/S/S9n[        R                   R                  S	S/S/[        R                  S
9n[         R                   " Xg/SU/U/X$/S9n[         R"                  " USS9$ )NXT)r'   	data_typedimsvalsrawShapeCReshapeY)rb   rc   Cast)rb   rc   toz
test-model)rg   zonnx-example)producer_name)r
   rj   r   rk   r2  rl   make_tensorrT   numpy_helpertobytes_little_endianr)   rP   r3  int64INT64ri   rm   rn   )	r3   r:  
input_init
shape_data
shape_initr@  r+   cast	graph_defs	            r4   r0   )TestExternalDataToArray.create_test_modelT  su   ))#{/@/@$//BWBWX''!''&&""88I

 XXdoorxx8
''!''!!""88D

 ))#{/@/@$//R++''>E ( 

 {{$$C53%K4E4E % 
 %%OCC#0
	   .IIr7   r   c                D    [         R                  " U R                  5        g r9   r   r2   s    r4   rx   (TestExternalDataToArray.test_check_modelz  r   r7   c           	     "   [         R                  " U R                  U R                  U R                  SSSS9  [         R
                  " U R                  U R                  SS9nU R                  [        R                  [        R                  USS9  g )NTFr   r  r   r   r   )strict_mode)
rT   ro   rs   r   r   loadr   r   InferenceErrorinfer_shapes)r3   model_without_external_datas     r4   .test_reshape_inference_with_external_data_failFTestExternalDataToArray.test_reshape_inference_with_external_data_fail  s    JJ  %%"&$)	
 '+ii  $";";PU'
# 	**(('	 	 	
r7   c           	     r   [         R                  " U R                  U R                  U R                  SSSS9  [         R
                  " U R                  U R                  SS9n[        UR                  R                  S   U R                  5      n[        R                  R                  X R                  5        g )NTFr   rT  r   )rT   ro   rs   r   r   rV  r   rr   rg   r(   r)   r   r   r2  )r3   rs   loaded_large_datas      r4    test_to_array_with_external_data8TestExternalDataToArray.test_to_array_with_external_data  s    JJ  %%"&$)	
 		  $";";PU
 %U[[%<%<Q%?O


""#4ooFr7   c                "   [         R                  " U R                  U R                  U R                  SSS SSS9  [         R
                  " U R                  U R                  SS9nUR                  R                  S   nU R                  UR                  S5      5        [        R                  R                  [        X R                  5      U R                  5        UR                  R                  S   nU R                  UR                  S5      (       + 5        [        R                  R                  [        U5      U R                   5        [         R                  " UU R                  U R                  SSS SSS9  [         R
                  " U R                  U R                  SS9nUR                  R                  S   nU R                  UR                  S5      5        [        R                  R                  [        X R                  5      U R                  5        UR                  R                  S   nU R                  UR                  S5      5        [        R                  R                  [        X0R                  5      U R                   5        g )	NTFr   r  r   r   rV   r   )rT   ro   rs   r   r   rV  rr   rg   r   r   r)   r   r   r   r(   r2  r3  )r3   model_without_loading_externallarge_input_tensorsmall_shape_tensors       r4   1test_save_model_with_external_data_multiple_timesITestExternalDataToArray.test_save_model_with_external_data_multiple_times  s    	JJ  %%"&$)"		
 *.  $";";PU*
& <AAMMaP*33ODE


""'7	
 <AAMMaP.77HHI


""8,>#?Q 	*  %%"&$)"		
 *.  $";";PU*
& <AAMMaP*33ODE


""'7	
 <AAMMaP*33ODE


""'7	
r7   )r/  r&   r2  rs   r3  r(   Nrz   r%  )r   r   r   r   r   r   r5   propertyr   r<   r0   r&  r'  rx   rZ  r^  rd  r   r   r7   r4   r)  r)  <  sl     !+#*. % %%$JL __
*D(	(
,G"5
r7   r)  c                  T    \ rS rSrSr S	       S
S jjrSS jrSS jrSS jrSr	g)3TestNotAllowToLoadExternalDataOutsideModelDirectoryi  xEssential test to check that onnx (validate) C++ code will not allow to load external_data outside the model
directory.
c                    [        [        R                  " U5      5      nX$l        U=(       d    U S3n[	        XES9  UR                  S5        [        R                  R                  Ul	        U$ )NrK   rL   rO   )
r   r)   rP   r'   r   rS   rT   r   rU   rV   )r3   rW   rX   rM   rY   rZ   s         r4   r\   OTestNotAllowToLoadExternalDataOutsideModelDirectory.create_external_data_tensor  s[     BHHUO,!":T&:&;*%#//88r7   c                    U R                  S5      U l        U R                  [        R                  R
                  5         [        R                  " U R                  5        SSS5        g! , (       d  f       g= f)MWe only test the model validation as onnxruntime uses this to load the model.z../../file.binNr0   r1   r   rT   r	   r   rw   r2   s    r4   rx   DTestNotAllowToLoadExternalDataOutsideModelDirectory.test_check_model  sN    "445EFt||;;< 3 34 =<<    !A**
A8c                    U R                  S5      U l        U R                  [        R                  R
                  5         [        R                  " U R                  5        SSS5        g! , (       d  f       g= f)More relative path test.z../test/../file.binNrn  r2   s    r4   test_check_model_relativeMTestNotAllowToLoadExternalDataOutsideModelDirectory.test_check_model_relative  sN    "445JKt||;;< 3 34 =<<rp  c                    U R                  S5      U l        U R                  [        R                  R
                  5         [        R                  " U R                  5        SSS5        g! , (       d  f       g= f)JONNX checker disallows using absolute path as location in external tensor.z
//file.binNrn  r2   s    r4   test_check_model_absoluteMTestNotAllowToLoadExternalDataOutsideModelDirectory.test_check_model_absolute  sM    "44\Bt||;;< 3 34 =<<rp  r1   Nr}   r   rz   )
r   r   r   r   r   r\   rx   rs  rw  r   r   r7   r4   rh  rh    sB    
 CE-0<?	555r7   rh  ntzSkip Windows test)reasonc                  6    \ rS rSrSrSS jrSS jrSS jrSrg)	<TestNotAllowToLoadExternalDataOutsideModelDirectoryOnWindowsi  ri  c                    U R                  S5      U l        U R                  [        R                  R
                  5         [        R                  " U R                  5        SSS5        g! , (       d  f       g= f)rm  z..\..\file.binNrn  r2   s    r4   rx   MTestNotAllowToLoadExternalDataOutsideModelDirectoryOnWindows.test_check_model  sN    "445GHt||;;< 3 34 =<<rp  c                    U R                  S5      U l        U R                  [        R                  R
                  5         [        R                  " U R                  5        SSS5        g! , (       d  f       g= f)rr  z..\test\..\file.binNrn  r2   s    r4   rs  VTestNotAllowToLoadExternalDataOutsideModelDirectoryOnWindows.test_check_model_relative  sN    "445MNt||;;< 3 34 =<<rp  c                    U R                  S5      U l        U R                  [        R                  R
                  5         [        R                  " U R                  5        SSS5        g! , (       d  f       g= f)rv  zC:/file.binNrn  r2   s    r4   rw  VTestNotAllowToLoadExternalDataOutsideModelDirectoryOnWindows.test_check_model_absolute  sM    "44]Ct||;;< 3 34 =<<rp  ry  Nrz   )	r   r   r   r   r   rx   rs  rw  r   r   r7   r4   r}  r}    s    555r7   r}  c                  ,   ^  \ rS rSrSU 4S jjrSrU =r$ )(TestSaveAllTensorsAsExternalDataWithPathi   c                H   > [         R                  " [        TU ]  5       5      $ r9   )pathlibPathsuperrG   )r3   	__class__s    r4   rG   @TestSaveAllTensorsAsExternalDataWithPath.get_temp_model_filename!  s    ||EG;=>>r7   r   r{   zpathlib.Path)r   r   r   r   rG   r   __classcell__)r  s   @r4   r  r     s    ? ?r7   r  c                  (    \ rS rSr\SS j5       rSrg)TestExternalDataToArrayWithPathi%  c                B    [         R                  " U R                  5      $ r9   )r  r  r/  r2   s    r4   r   /TestExternalDataToArrayWithPath.model_file_path&  s    ||D1122r7   r   Nr  )r   r   r   r   rf  r   r   r   r7   r4   r  r  %  s    3 3r7   r  c                  Z    \ rS rSrSS jrSS jrSS jrSS jrSS jrSS jr	SS jr
S	rg
)TestFunctionsAndSubGraphsi+  c                6   [         R                  " 5       U l        U R                  R                  n[        R
                  R                  US5      U l        [        R                  " S5      R                  [        R                  5      n[        US5      U l        g )Nrh   r   rY   )r$   r%   r&   r'   rB   rC   rD   r/  r)   r*   r,   r-   r   _tensor)r3   r(   rP   s      r4   r5   TestFunctionsAndSubGraphs.setUp,  se    %88:%%**%'WW\\(L%I		$&&rzz2!%2r7   c                8    U R                   R                  5         g r9   r:   r2   s    r4   r<   "TestFunctionsAndSubGraphs.tearDown3  r>   r7   c                X    U R                  UR                  [        R                  5        g r9   )r   rV   r   r   r3   rY   s     r4   _check_is_internal,TestFunctionsAndSubGraphs._check_is_internal6  s    --{/B/BCr7   c                X    U R                  UR                  [        R                  5        g r9   )r   rV   r   rU   r  s     r4   _check_is_external,TestFunctionsAndSubGraphs._check_is_external9  s    --{/C/CDr7   c                T   U Hd  nU R                  UR                  S5        UR                  S   R                  nUR	                  U R
                  5        U R                  U5        Mf     [        USSS9  U H-  nUR                  S   R                  nU R                  U5        M/     g)ai  Check that the tensors in the model are externalized.

The tensors in the specified sequence of Constant nodes are set to self._tensor,
an internal tensor. The model is then converted to external data format.
The tensors are then checked to ensure that they are externalized.

Arguments:
    model: The model to check.
    nodes: A sequence of Constant nodes.

r_   r   Tr  N)	r   op_typer   r   CopyFromr  r  r   r  )r3   rs   nodesr   rY   s        r4   _check TestFunctionsAndSubGraphs._check<  s     DT\\:6^^A&((FOODLL)##F+	  	'uQRVWD^^A&((F##F+ r7   c                    Sn[         R                  " U5      nU R                  X"R                  S   R                  S   /5        g )Na|  
           <ir_version: 7,  opset_import: ["": 15, "local": 1]>
           agraph (float[N] X) => (float[N] Y)
            {
              Y = local.add(X)
            }

            <opset_import: ["" : 15],  domain: "local">
            add (float[N] X) => (float[N] Y) {
              C = Constant <value = float[1] {1.0}> ()
              Y = Add (X, C)
           }
        r   )r   parse_modelr  	functionsr   )r3   
model_textrs   s      r4   test_function'TestFunctionsAndSubGraphs.test_functionT  s>    
 "":.EOOA.33A678r7   c                    Sn[         R                  " U5      nUR                  R                  S   nUR                   Vs/ s H  oDR
                  R                  S   PM     nnU R                  X%5        g s  snf )Na2  
           <ir_version: 7,  opset_import: ["": 15, "local": 1]>
           agraph (bool flag, float[N] X) => (float[N] Y)
            {
              Y = if (flag) <
                then_branch = g1 () => (float[N] Y_then) {
                    B = Constant <value = float[1] {0.0}> ()
                    Y_then = Add (X, C)
                },
                else_branch = g2 () => (float[N] Y_else) {
                    C = Constant <value = float[1] {1.0}> ()
                    Y_else = Add (X, C)
                }
              >
            }
        r   )r   r  rr   r   r   gr  )r3   r  rs   if_nodeattrconstant_nodess         r4   test_subgraph'TestFunctionsAndSubGraphs.test_subgraphe  sg    
  "":.++""1%5<5F5FG5FT&&++a.5FGE* Hs    "A6)r/  r&   r  Nrz   )rY   r   r{   r|   )rs   r   r  zSequence[NodeProto]r{   r|   )r   r   r   r   r5   r<   r  r  r  r  r  r   r   r7   r4   r  r  +  s'    3%DE,09"+r7   r  c                     [         R                  " S5      n [        R                  " S[        R                  S9nU R
                  R                  R                  [        USS95        X4$ )zPCreate a simple model with a large initializer suitable for external data tests.z
        <ir_version: 7, opset_import: ["": 17]>
        agraph (float[100, 100] input) => (float[100, 100] output) {
            output = Identity(input)
        }
        )r-  r-  dtypeweightr'   )	r   r  r)   onesr-   rr   rg   r   r   )rs   rP   s     r4   _make_external_data_test_modelr  |  sT    	E GGJbjj1E	KK"":e(#CD<r7   z/Symlinks require elevated privileges on Windowsc                  "    \ rS rSrSrSS jrSrg)%TestSaveExternalDataSymlinkProtectioni  zSTest that save_external_data rejects symlinks to prevent arbitrary file overwrites.c           
        [         R                  R                  U R                  S5      n[	        US5       nUR                  S5        SSS5        [        5       u  p4[         R                  R                  U R                  S5      nSn[        R                  " UUSSUSS	9  [         R                  R                  U R                  U5      n[         R                  " U5        [         R                  " X5        [        R                  " US
S9nUR                  5       UR                  R                  S   l        U R!                  ["        R$                  5         [        R                  " UUSSUSS	9  SSS5        [	        U5       nU R'                  UR)                  5       S5        SSS5        g! , (       d  f       GNm= f! , (       d  f       NU= f! , (       d  f       g= f)z4Saving external data must refuse to follow symlinks.zsensitive.txtwSENSITIVE DATANrh   data.binTr   r  r   rM   r   Fr   r   )rB   rC   rD   r(   rQ   rR   r  rT   ro   removesymlinkrV  tobytesrr   rg   rO   r   r	   r   r   read)	r3   sensitive_filefrs   rP   
model_pathext_dataext_data_pathloaded_models	            r4    test_save_rejects_symlink_targetFTestSaveExternalDataSymlinkProtection.test_save_rejects_symlink_target  s^   dmm_E.#&!GG$% ' 67WW\\$-->
"&$(	
 T]]H=
		- 


>1yyF5:]]_&&q)2w667OO&*(,!# 8 .!QQVVX'78 "!E '&. 87 "!s#   F/G!G/
F>
G
G r   Nrz   )r   r   r   r   r   r  r   r   r7   r4   r  r    s     ^&9r7   r  c                  6    \ rS rSrSrSS jrSS jrSS jrSrg)	%TestLoadExternalDataSymlinkProtectioni  zQTest that loading external data rejects symlinks to prevent arbitrary file reads.c           	        [        5       u  p[        R                  R                  U R                  S5      nSn[
        R                  " UUSSUSS9  [        R                  R                  U R                  S5      n[        US5       nUR                  S5        S	S	S	5        [        R                  R                  U R                  U5      n[        R                  " U5        [        R                  " XW5        U R                  [        R                  5         [
        R                  " U5        S	S	S	5        g	! , (       d  f       N= f! , (       d  f       g	= f)
zLLoading a model whose external data is a symlink must raise ValidationError.rh   r  Tr   r  
target.txtr  r  N)r  rB   rC   rD   r(   rT   ro   rQ   rR   r  r  r   r	   r   rV  )r3   rs   _r  r  target_filer  r  s           r4   'test_load_rejects_symlink_external_dataMTestLoadExternalDataSymlinkProtection.test_load_rejects_symlink_external_data  s    13WW\\$-->
"&$(	
 ggll4==,?+s#qGG$% $ T]]H=
		- 


;. w667IIj! 87 $# 87s   D7E7
E
Ec           	        [        5       u  p[        R                  R                  U R                  S5      nSn[
        R                  " UUSSUSS9  [        R                  R                  U R                  S5      n[        US5       nUR                  S5        S	S	S	5        [        R                  R                  U R                  U5      n[        R                  " U5        [        R                  " XW5        [
        R                  " US
S9nU R                  [        R                  5         [        XR                  5        S	S	S	5        g	! , (       d  f       N= f! , (       d  f       g	= f)zAload_external_data_for_model must reject symlinked external data.rh   r  Tr   r  r  r  r  NFr   )r  rB   rC   rD   r(   rT   ro   rQ   rR   r  r  rV  r   r	   r   r   )	r3   rs   r  r  r  r  r  r  r  s	            r4   1test_load_external_data_for_model_rejects_symlinkWTestLoadExternalDataSymlinkProtection.test_load_external_data_for_model_rejects_symlink  s    13WW\\$-->
"&$(	
 ggll4==,?+s#qGG$% $ T]]H=
		- 


;. yyFw667(}}E 87 $# 87s   E,E
E
E*c           	        [         R                  R                  U R                  S5      n[         R                  " U5        [         R                  R                  US5      n[        US5       nUR                  S5        SSS5        [         R                  R                  U R                  S5      n[         R                  " U5        [         R                  R                  US5      n[         R                  " U5        [        5       u  pg[         R                  R                  US5      n[        R                  " UUS	S	S
SS9  [        R                  " U5        [         R                  " X5        [        R                  " USS9n	U R                  [        R                   5         [#        X5        SSS5        g! , (       d  f       GN?= f! , (       d  f       g= f)zIA symlink in the parent directory must be caught by realpath containment.	sensitivez
secret.binrN   sx  SENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATASENSITIVE DATANr   subdirrh   Tzsubdir/secret.binr   r  Fr   )rB   rC   rD   r(   makedirsrQ   rR   r  rT   ro   shutilrmtreer  rV  r   r	   r   r   )
r3   sensitive_dirsecret_filer  r   subdir_pathrs   r  r  r  s
             r4   *test_load_rejects_parent_directory_symlinkPTestLoadExternalDataSymlinkProtection.test_load_rejects_parent_directory_symlink  s@    T]]K@
M"ggll=,?+t$GG+, % GGLL<	
Iggll9h7
K  23WW\\)\:
"&$((	
 	k"


=. yyFw667(A 877 %$6 87s   -F7"G	7
G	
Gr   Nrz   )	r   r   r   r   r   r  r  r  r   r   r7   r4   r  r    s     \"6F8"Br7   r  z'Hardlinks behave differently on Windowsc                  "    \ rS rSrSrSS jrSrg)&TestLoadExternalDataHardlinkProtectioni  zFTest that loading external data rejects files with multiple hardlinks.c           	        [        5       u  p[        R                  R                  U R                  S5      nSn[
        R                  " UUSSUSS9  [        R                  R                  U R                  U5      n[        R                  R                  U R                  S5      n[        R                  " XV5        U R                  [        R                  5         [
        R                  " U5        SSS5        g! , (       d  f       g= f)zVLoading a model whose external data has multiple hardlinks must raise ValidationError.rh   r  Tr   r  zhardlink_data.binN)r  rB   rC   rD   r(   rT   ro   linkr   r	   r   rV  )r3   rs   r  r  r  r  hardlink_paths          r4   *test_load_rejects_hardlinked_external_dataQTestLoadExternalDataHardlinkProtection.test_load_rejects_hardlinked_external_data   s    13WW\\$-->
"&$(	
 T]]H=T]]4GH
- w667IIj! 877s   C;;
D	r   Nrz   )r   r   r   r   r   r  r   r   r7   r4   r  r    s
    P"r7   r  c                  "    \ rS rSrSrSS jrSrg)*TestSaveExternalDataAbsolutePathValidationi9  z4Test that save_external_data rejects absolute paths.c                   [         R                  " S[         R                  S9n[        USS9n[	        USS9  U R                  [        R                  5         [        X R                  5        SSS5        g! , (       d  f       g= f)z;Absolute paths must be rejected as external data locations.)r-  r  r  r  z/etc/passwdrL   N)
r)   r  r-   r   r   r   r	   r   r   r(   )r3   rP   rY   s      r4   test_save_rejects_absolute_pathJTestSaveExternalDataAbsolutePathValidation.test_save_rejects_absolute_path<  sX    bjj1E1&=9w667v}}5 877s   A66
Br   Nrz   )r   r   r   r   r   r  r   r   r7   r4   r  r  9  s
    >6r7   r  c                      \ rS rSrSr\ S     SS jj5       rSS jrSS jrSS jr	SS jr
SS jrSS	 jrSS
 jrSS jrSS jrSS jrSrg)TestExternalDataInfoSecurityiE  a  Tests for ExternalDataInfo hardening against attribute injection and bounds.

Covers all attack vectors from the security advisory: unknown key injection,
dunder attribute injection, negative offset/length bypass, and validates
that legitimate keys still work correctly.
c                0   [        5       nXl        [         R                  Ul        UR                  R                  S/5        [         R                  Ul        U R                  5        H+  u  p4UR                  R                  5       nX5l        XEl        M-     U$ )z@Create a TensorProto with given external_data key-value entries.   )r   r'   rk   r;  r<  extendrU   rV   itemsr   addkeyrW   )entriesrX   rY   r  rW   entrys         r4   _make_tensor_with_external_data<TestExternalDataInfoSecurity._make_tensor_with_external_dataM  sw     !&,,A3*33!--/JC((,,.EIK * r7   c                   U R                  SSSSS.5      n[        U5      nU R                  UR                  S5        U R                  UR                  S5        U R                  UR                  [        5        U R                  UR                  S5        U R                  UR                  [        5        U R                  UR                  S5        g)	zCAll valid external_data keys must be accepted and correctly parsed.weights.bin161024zsha256:abc123)rM   r   r   checksum   r   N)	r  r   r   rM   r   assertIsInstanceintr   r  r3   rY   infos      r4   !test_valid_external_data_accepted>TestExternalDataInfoSecurity.test_valid_external_data_accepted^  s    55) +	
  '6b)dkk3/d+dkk3/8r7   c                ~   U R                  SSS.5      n[        R                  " SS9 n[        R                  " S5        [	        U5      nSSS5        U R                  [        WS5      S	5        U R                  UR                  S5        U R                  [        S
 W 5       5      S5        g! , (       d  f       Ni= f)zJUnknown external_data keys must not be set as object attributes (CWE-915).r  
evil_value)rM   malicious_attrTrecordalwaysNr	  z;Unknown key 'malicious_attr' should not become an attributec              3  R   #    U  H  nS [        UR                  5      ;   v   M     g7f)r	  Nr   message.0r  s     r4   	<genexpr>ITestExternalDataInfoSecurity.test_unknown_key_rejected.<locals>.<genexpr>  s     CFq C		N2F   %'z3Expected warning about unknown key 'malicious_attr')r  warningscatch_warningssimplefilterr   r   hasattrr   rM   r   any)r3   rY   caughtr  s       r4   test_unknown_key_rejected6TestExternalDataInfoSecurity.test_unknown_key_rejectedp  s    55&,G
 $$D1V!!(+#F+D 2 	D*+I	

 	6CFCCA	
 21s   "B..
B<c                   U R                  SS05      nUR                  R                  5       nSUl        SUl        [
        n[        R                  " SS9 n[        R                  " S5        [        U5      nSSS5        U R                  WU5        U R                  [        U5      R                  S	5        U R                  UR                  S5        U R                  [        S
 W 5       5      S5        g! , (       d  f       N= f)zDunder keys like '__class__' must not be injected via external_data (CWE-915).

Without the whitelist, setattr(self, '__class__', ...) would corrupt
the object type, enabling type confusion attacks.
rM   r  r  zbuiltins.dictTr
  r  Nr   c              3  R   #    U  H  nS [        UR                  5      ;   v   M     g7f)r  Nr  r  s     r4   r  HTestExternalDataInfoSecurity.test_dunder_key_rejected.<locals>.<genexpr>  s     >v!s199~-vr  z-Expected warning about dunder key '__class__')r  r   r  r  rW   r   r  r  r  r  r   typer   rM   r   r  )r3   rY   dunder_entryoriginal_classr  r  s         r4   test_dunder_key_rejected5TestExternalDataInfoSecurity.test_dunder_key_rejected  s     55z=6QR++//1&,)$$D1V!!(+#F+D 2 	dN3d,,.@A6>v>>;	
 21s   "C66
Dc                   U R                  SSS.5      nU R                  [        5       n[        U5        SSS5        U R	                  S[        WR                  5      R                  5       5        g! , (       d  f       NB= f)zBNegative offset must raise ValueError to prevent seek(-1) attacks.r  z-1rM   r   Nnon-negativer  r   
ValueErrorr   assertInr   	exceptionlowerr3   rY   ctxs      r4   test_negative_offset_rejected:TestExternalDataInfoSecurity.test_negative_offset_rejected  sb    55&$7
 z*cV$ +nc#--&8&>&>&@A +*   A22
B c                   U R                  SSS.5      nU R                  [        5       n[        U5        SSS5        U R	                  S[        WR                  5      R                  5       5        g! , (       d  f       NB= f)zCNegative length must raise ValueError to prevent underflow attacks.r  z-100rM   r   Nr'  r(  r-  s      r4   test_negative_length_rejected:TestExternalDataInfoSecurity.test_negative_length_rejected  sb    55&&9
 z*cV$ +nc#--&8&>&>&@A +*r1  c                    U R                  SSSS.5      n[        U5      nU R                  UR                  S5        U R                  UR                  S5        U R                  UR
                  S5        g)zNZero values for offset/length should be accepted (edge case for bounds check).r  0r   r   N)r  r   r   rM   r   r   r  s      r4   $test_zero_offset_and_length_acceptedATestExternalDataInfoSecurity.test_zero_offset_and_length_accepted  sd    55&#E
  '6a(a(r7   c                   U R                  SSSSS.5      n[        R                  " SS9 n[        R                  " S5        [	        U5      nS	S	S	5        U R                  [        WS
5      5        U R                  [        US5      5        U R                  UR                  S5        W Vs/ s HA  nS[        UR                  5      R                  5       ;   d  M,  [        UR                  5      PMC     nnU R                  [        U5      SS5        U R                  S
US   5        U R                  SUS   5        U R                  SUS   5        g	! , (       d  f       GN= fs  snf )z>Multiple unknown keys in a single tensor must all be rejected.r  abc)rM   evil_oneevil_two__dict__Tr
  r  Nr>  r?  zunknown external data keyr   z.Expected 1 aggregated warning for unknown keysr   r@  )r  r  r  r  r   r   r  r   rM   r   r  r,  r   r*  )r3   rY   r  r  r  unknown_key_warningss         r4   'test_multiple_unknown_keys_all_rejectedDTestExternalDataInfoSecurity.test_multiple_unknown_keys_all_rejected  sA   55)	
 $$D1V!!(+#F+D 2 	z23z236  
*c!))n.B.B.DD C		N 	  

 	$%<	
 	j"6q"9:j"6q"9:j"6q"9:' 21 
s   "E++E#E#
E c                z    U R                  [        [        5        U R                  [        [        1 Sk5      5        g)z>The whitelist must be a frozenset to prevent runtime mutation.>   r   r   basepathr  rM   N)r  r   	frozensetr   r2   s    r4   $test_allowed_keys_constant_is_frozenATestExternalDataInfoSecurity.test_allowed_keys_constant_is_frozen  s-    99E'NO	
r7   c                    U R                  SSS.5      nU R                  [        5         [        U5        SSS5        g! , (       d  f       g= f)zFNon-numeric offset string must raise ValueError from int() conversion.r  abcr&  Nr  r   r)  r   r  s     r4   test_non_numeric_offset_raises;TestExternalDataInfoSecurity.test_non_numeric_offset_raises  s>    55&%8
 z*V$ +**	   ?
Ac                    U R                  SSS.5      nU R                  [        5         [        U5        SSS5        g! , (       d  f       g= f)zFNon-numeric length string must raise ValueError from int() conversion.r  not_a_numberr3  NrK  r  s     r4   test_non_numeric_length_raises;TestExternalDataInfoSecurity.test_non_numeric_length_raises  s>    55&.A
 z*V$ +**rN  r   N)test_tensor)r  zdict[str, str]rX   r   r{   r   rz   )r   r   r   r   r   staticmethodr  r  r  r#  r/  r4  r8  rB  rG  rL  rQ  r   r   r7   r4   r  r  E  sn      ) 
  9$
*
4BB	);>
%%r7   r  c                  6    \ rS rSrSrSS jrSS jrSS jrSrg)	&TestLoadExternalDataFileSizeValidationi  zQTests for defense-in-depth file-size validation in load_external_data_for_tensor.c                N   [         R                  " S[         R                  S9n[        USS9n[	        USS9  [
        R                  R                  U R                  S5      n[        US5       nUR                  UR                  5        SSS5        [
        R                  R                  U5      n[	        USUS	-   S
9  UR                  S5        U R                  [        S5         [!        X R                  5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f)z.Offset beyond file size must raise ValueError.r  r  r  r  r  rL   rN   Nr-  r&  rO   zoffset.*exceeds file sizer)   r  r-   r   r   rB   rC   rD   r(   rQ   rR   rO   getsizerS   assertRaisesRegexr)  r   r3   rP   rY   	data_pathr  	file_sizes         r4   $test_offset_exceeds_file_size_raisesKTestLoadExternalDataFileSizeValidation.test_offset_exceeds_file_size_raises  s    BJJ/E1&:6GGLL
;	)T"aGGFOO$ # GGOOI.	&:i#oN*%##J0KL)&--@ ML #" ML   .D&D
D
D$c                N   [         R                  " S[         R                  S9n[        USS9n[	        USS9  [
        R                  R                  U R                  S5      n[        US5       nUR                  UR                  5        SSS5        [
        R                  R                  U5      n[	        USUS	-  S
9  UR                  S5        U R                  [        S5         [!        X R                  5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f)z;Length that overflows available data must raise ValueError.rX  r  r  r  r  rL   rN   Ni  r3  rO   zlength.*exceeds available datarY  r\  s         r4   )test_length_exceeds_available_data_raisesPTestLoadExternalDataFileSizeValidation.test_length_exceeds_available_data_raises	  s    BJJ/E1&:6GGLL
;	)T"aGGFOO$ # GGOOI.	&:i$>NO*%##J0PQ)&--@ RQ #" RQra  c                   [         R                  " / SQ[         R                  S9n[        USS9nUR                  n[
        R                  R                  U R                  S5      n[        US5       nUR                  U5        SSS5        [        USS[        U5      S	9  UR                  S
5        [        X R                  5        U R                  UR                  U5        g! , (       d  f       Nf= f)z;Valid offset+length within file size should load correctly.)g      ?g       @g      @g      @r  r  r  r  rN   Nr   r   rO   )r)   rP   r-   r   rO   rB   rC   rD   r(   rQ   rR   r   r   rS   r   r   )r3   rP   rY   r>  r]  r  s         r4   +test_valid_offset_and_length_load_correctlyRTestLoadExternalDataFileSizeValidation.test_valid_offset_and_length_load_correctly  s    -RZZ@E1ooGGLL
;	)T"aGGCL # 	&:aCQ*%%fmm<#. #"s   2C$$
C2r   Nrz   )	r   r   r   r   r   r_  rc  rf  r   r   r7   r4   rV  rV    s    [A$A$/r7   rV  __main__)r{   ztuple[ModelProto, np.ndarray])=
__future__r   r   rB   r  r  r$   r&  rE   r  typingr   r   numpyr)   r   rT   r   r   r   r	   r
   r   r   onnx.external_data_helperr   r   r   r   r   r   r   r   onnx.numpy_helperr   r   collections.abcr   TestCaser   parameterized_classr   r   r   r)  rh  r'  r'   r}  r  r  r  r  r  r  r  r  r  rV  r   mainr   r7   r4   <module>rr     s   #  	       %     	 	 	 3(N1x00 N1b ""	,	-!U3 !U!UH ""	,	-]R%= ]R]R@ ""	,	-eIx'8'8 eIeIP	 ""	,	-[
h// [
[
|"5:R "5J 
D)<=575 >54?/O ?
3&= 3N+ 1 1 N+b 
GGtOM)9,D )9)9X 
GGtOM\B,D \B\B~ 
D)RS"-E " T"8	61I 	6l%8#4#4 l%^5/-E 5/p zMMO r7   