modelaudit 0.2.31__tar.gz → 0.2.32__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (591) hide show
  1. modelaudit-0.2.32/.release-please-manifest.json +3 -0
  2. {modelaudit-0.2.31 → modelaudit-0.2.32}/CHANGELOG.md +20 -0
  3. {modelaudit-0.2.31 → modelaudit-0.2.32}/PKG-INFO +1 -1
  4. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/coreml_scanner.py +54 -65
  5. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/oci_layer_scanner.py +35 -14
  6. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/openvino_scanner.py +78 -2
  7. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/pmml_scanner.py +3 -1
  8. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/tensorrt_scanner.py +2 -2
  9. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/file/detection.py +5 -0
  10. {modelaudit-0.2.31 → modelaudit-0.2.32}/pyproject.toml +1 -1
  11. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_coreml_scanner.py +53 -0
  12. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_oci_layer_scanner.py +27 -0
  13. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_openvino_scanner.py +56 -3
  14. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_pmml_scanner.py +99 -0
  15. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_tensorrt_scanner.py +14 -1
  16. {modelaudit-0.2.31 → modelaudit-0.2.32}/uv.lock +666 -654
  17. modelaudit-0.2.31/.release-please-manifest.json +0 -3
  18. {modelaudit-0.2.31 → modelaudit-0.2.32}/.dockerignore +0 -0
  19. {modelaudit-0.2.31 → modelaudit-0.2.32}/.editorconfig +0 -0
  20. {modelaudit-0.2.31 → modelaudit-0.2.32}/.gitattributes +0 -0
  21. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/CODEOWNERS +0 -0
  22. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  23. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  24. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  25. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/markdown-link-check-config.json +0 -0
  26. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/README.md +0 -0
  27. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/codeql.yml +0 -0
  28. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/docker-image-test.yml +0 -0
  29. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/docker-publish.yml +0 -0
  30. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/docs-check.yml +0 -0
  31. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/nightly.yml +0 -0
  32. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/perf.yml +0 -0
  33. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/release-please.yml +0 -0
  34. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/test.yml +0 -0
  35. {modelaudit-0.2.31 → modelaudit-0.2.32}/.github/workflows/validate-pr-title.yml +0 -0
  36. {modelaudit-0.2.31 → modelaudit-0.2.32}/.gitignore +0 -0
  37. {modelaudit-0.2.31 → modelaudit-0.2.32}/.mailmap +0 -0
  38. {modelaudit-0.2.31 → modelaudit-0.2.32}/.modelaudit.toml.example +0 -0
  39. {modelaudit-0.2.31 → modelaudit-0.2.32}/.prettierignore +0 -0
  40. {modelaudit-0.2.31 → modelaudit-0.2.32}/AGENTS.md +0 -0
  41. {modelaudit-0.2.31 → modelaudit-0.2.32}/CLAUDE.md +0 -0
  42. {modelaudit-0.2.31 → modelaudit-0.2.32}/CODE_OF_CONDUCT.md +0 -0
  43. {modelaudit-0.2.31 → modelaudit-0.2.32}/CONTRIBUTING.md +0 -0
  44. {modelaudit-0.2.31 → modelaudit-0.2.32}/Dockerfile +0 -0
  45. {modelaudit-0.2.31 → modelaudit-0.2.32}/Dockerfile.full +0 -0
  46. {modelaudit-0.2.31 → modelaudit-0.2.32}/Dockerfile.tensorflow +0 -0
  47. {modelaudit-0.2.31 → modelaudit-0.2.32}/LICENSE +0 -0
  48. {modelaudit-0.2.31 → modelaudit-0.2.32}/MAINTAINERS.md +0 -0
  49. {modelaudit-0.2.31 → modelaudit-0.2.32}/MANIFEST.in +0 -0
  50. {modelaudit-0.2.31 → modelaudit-0.2.32}/README.md +0 -0
  51. {modelaudit-0.2.31 → modelaudit-0.2.32}/RULES.md +0 -0
  52. {modelaudit-0.2.31 → modelaudit-0.2.32}/SECURITY.md +0 -0
  53. {modelaudit-0.2.31 → modelaudit-0.2.32}/SUPPORT.md +0 -0
  54. {modelaudit-0.2.31 → modelaudit-0.2.32}/THIRD_PARTY_NOTICES.md +0 -0
  55. {modelaudit-0.2.31 → modelaudit-0.2.32}/codecov.yml +0 -0
  56. {modelaudit-0.2.31 → modelaudit-0.2.32}/docker-compose.yml +0 -0
  57. {modelaudit-0.2.31 → modelaudit-0.2.32}/docker-entrypoint.sh +0 -0
  58. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/agents/architecture.md +0 -0
  59. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/agents/dependencies.md +0 -0
  60. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/agents/new-scanner-quickstart.md +0 -0
  61. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/agents/release-process.md +0 -0
  62. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/cve-gap-pr-plan-2026-03-20.md +0 -0
  63. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/cve-process.md +0 -0
  64. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/dependency-policy.md +0 -0
  65. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/format-gap-plans/coreml-mlmodel.md +0 -0
  66. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/format-gap-plans/mxnet-models.md +0 -0
  67. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/format-gap-plans/tensorflow-metagraph.md +0 -0
  68. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/format-gap-plans/torchserve-mar.md +0 -0
  69. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/maintainers/triage-playbook.md +0 -0
  70. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/security/threat-model.md +0 -0
  71. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/user/compatibility-matrix.md +0 -0
  72. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/user/metadata-extraction.md +0 -0
  73. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/user/offline-air-gapped.md +0 -0
  74. {modelaudit-0.2.31 → modelaudit-0.2.32}/docs/user/security-model.md +0 -0
  75. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/__init__.py +0 -0
  76. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/__main__.py +0 -0
  77. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/__init__.py +0 -0
  78. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/anomaly_detector.py +0 -0
  79. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/enhanced_pattern_detector.py +0 -0
  80. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/entropy_analyzer.py +0 -0
  81. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/framework_patterns.py +0 -0
  82. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/integrated_analyzer.py +0 -0
  83. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/ml_context_analyzer.py +0 -0
  84. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/opcode_sequence_analyzer.py +0 -0
  85. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/semantic_analyzer.py +0 -0
  86. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/analysis/unified_context.py +0 -0
  87. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/auth/__init__.py +0 -0
  88. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/auth/client.py +0 -0
  89. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/auth/config.py +0 -0
  90. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/__init__.py +0 -0
  91. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/adaptive_cache_keys.py +0 -0
  92. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/batch_operations.py +0 -0
  93. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/cache_manager.py +0 -0
  94. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/cache_policy.py +0 -0
  95. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/optimized_config.py +0 -0
  96. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/scan_results_cache.py +0 -0
  97. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cache/trusted_config_store.py +0 -0
  98. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/cli.py +0 -0
  99. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/__init__.py +0 -0
  100. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/constants.py +0 -0
  101. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/data/spdx_licenses.json +0 -0
  102. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/explanations.py +0 -0
  103. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/generated_keras_layers.py +0 -0
  104. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/local_config.py +0 -0
  105. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/name_blacklist.py +0 -0
  106. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/config/rule_config.py +0 -0
  107. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/core.py +0 -0
  108. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/detectors/__init__.py +0 -0
  109. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/detectors/cve_patterns.py +0 -0
  110. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/detectors/jit_script.py +0 -0
  111. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/detectors/network_comm.py +0 -0
  112. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/detectors/secrets.py +0 -0
  113. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/detectors/suspicious_symbols.py +0 -0
  114. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/integrations/__init__.py +0 -0
  115. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/integrations/jfrog.py +0 -0
  116. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/integrations/license_checker.py +0 -0
  117. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/integrations/mlflow.py +0 -0
  118. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/integrations/sarif_formatter.py +0 -0
  119. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/integrations/sbom_generator.py +0 -0
  120. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/metadata_extractor.py +0 -0
  121. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/models.py +0 -0
  122. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/progress/__init__.py +0 -0
  123. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/progress/base.py +0 -0
  124. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/progress/console.py +0 -0
  125. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/progress/file.py +0 -0
  126. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/progress/hooks.py +0 -0
  127. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/progress/multi_phase.py +0 -0
  128. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/LICENSE +0 -0
  129. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/NOTICE +0 -0
  130. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/__init__.py +0 -0
  131. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/py.typed +0 -0
  132. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/__init__.py +0 -0
  133. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/__init__.py +0 -0
  134. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/__init__.py +0 -0
  135. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/allocation_description_pb2.py +0 -0
  136. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/api_def_pb2.py +0 -0
  137. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/attr_value_pb2.py +0 -0
  138. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/cost_graph_pb2.py +0 -0
  139. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/cpp_shape_inference_pb2.py +0 -0
  140. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/dataset_metadata_pb2.py +0 -0
  141. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/dataset_options_pb2.py +0 -0
  142. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/dataset_pb2.py +0 -0
  143. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/device_attributes_pb2.py +0 -0
  144. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/full_type_pb2.py +0 -0
  145. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/function_pb2.py +0 -0
  146. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/graph_debug_info_pb2.py +0 -0
  147. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/graph_pb2.py +0 -0
  148. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/graph_transfer_info_pb2.py +0 -0
  149. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/kernel_def_pb2.py +0 -0
  150. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/log_memory_pb2.py +0 -0
  151. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/model_pb2.py +0 -0
  152. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/node_def_pb2.py +0 -0
  153. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/op_def_pb2.py +0 -0
  154. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/optimized_function_graph_pb2.py +0 -0
  155. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/reader_base_pb2.py +0 -0
  156. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/resource_handle_pb2.py +0 -0
  157. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/step_stats_pb2.py +0 -0
  158. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/tensor_description_pb2.py +0 -0
  159. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/tensor_pb2.py +0 -0
  160. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/tensor_shape_pb2.py +0 -0
  161. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/tensor_slice_pb2.py +0 -0
  162. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/types_pb2.py +0 -0
  163. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/variable_pb2.py +0 -0
  164. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/framework/versions_pb2.py +0 -0
  165. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/__init__.py +0 -0
  166. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/cluster_pb2.py +0 -0
  167. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/composite_tensor_variant_pb2.py +0 -0
  168. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/control_flow_pb2.py +0 -0
  169. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/core_platform_payloads_pb2.py +0 -0
  170. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/critical_section_pb2.py +0 -0
  171. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/data_service_pb2.py +0 -0
  172. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/debug_event_pb2.py +0 -0
  173. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/debug_pb2.py +0 -0
  174. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/device_filters_pb2.py +0 -0
  175. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/device_properties_pb2.py +0 -0
  176. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/fingerprint_pb2.py +0 -0
  177. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/meta_graph_pb2.py +0 -0
  178. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/named_tensor_pb2.py +0 -0
  179. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/remote_tensor_handle_pb2.py +0 -0
  180. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/rewriter_config_pb2.py +0 -0
  181. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/saved_model_pb2.py +0 -0
  182. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/saved_object_graph_pb2.py +0 -0
  183. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/saver_pb2.py +0 -0
  184. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/service_config_pb2.py +0 -0
  185. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/snapshot_pb2.py +0 -0
  186. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/struct_pb2.py +0 -0
  187. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/tensor_bundle_pb2.py +0 -0
  188. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/trackable_object_graph_pb2.py +0 -0
  189. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/transport_options_pb2.py +0 -0
  190. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/protos/tensorflow/core/protobuf/verifier_config_pb2.py +0 -0
  191. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/py.typed +0 -0
  192. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/rules.py +0 -0
  193. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/__init__.py +0 -0
  194. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/base.py +0 -0
  195. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/catboost_scanner.py +0 -0
  196. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/cntk_scanner.py +0 -0
  197. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/compressed_scanner.py +0 -0
  198. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/executorch_scanner.py +0 -0
  199. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/flax_msgpack_scanner.py +0 -0
  200. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/gguf_scanner.py +0 -0
  201. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/jax_checkpoint_scanner.py +0 -0
  202. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/jinja2_template_scanner.py +0 -0
  203. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/joblib_scanner.py +0 -0
  204. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/keras_h5_scanner.py +0 -0
  205. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/keras_utils.py +0 -0
  206. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/keras_zip_scanner.py +0 -0
  207. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/lightgbm_scanner.py +0 -0
  208. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/llamafile_scanner.py +0 -0
  209. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/manifest_scanner.py +0 -0
  210. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/metadata_scanner.py +0 -0
  211. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/mxnet_scanner.py +0 -0
  212. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/nemo_scanner.py +0 -0
  213. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/numpy_scanner.py +0 -0
  214. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/onnx_scanner.py +0 -0
  215. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/paddle_scanner.py +0 -0
  216. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/pickle_scanner.py +0 -0
  217. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/pytorch_binary_scanner.py +0 -0
  218. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/pytorch_zip_scanner.py +0 -0
  219. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/r_serialized_scanner.py +0 -0
  220. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/rknn_scanner.py +0 -0
  221. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/rule_mapper.py +0 -0
  222. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/safetensors_scanner.py +0 -0
  223. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/sevenzip_scanner.py +0 -0
  224. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/skops_scanner.py +0 -0
  225. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/tar_scanner.py +0 -0
  226. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/text_scanner.py +0 -0
  227. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/tf_metagraph_scanner.py +0 -0
  228. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/tf_savedmodel_scanner.py +0 -0
  229. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/tflite_scanner.py +0 -0
  230. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/torch7_scanner.py +0 -0
  231. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/torchserve_mar_scanner.py +0 -0
  232. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/weight_distribution_scanner.py +0 -0
  233. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/xgboost_scanner.py +0 -0
  234. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/scanners/zip_scanner.py +0 -0
  235. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/telemetry.py +0 -0
  236. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/__init__.py +0 -0
  237. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/auto_defaults.py +0 -0
  238. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/file/__init__.py +0 -0
  239. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/file/filtering.py +0 -0
  240. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/file/handlers.py +0 -0
  241. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/file/large_file_handler.py +0 -0
  242. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/file/streaming.py +0 -0
  243. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/__init__.py +0 -0
  244. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/assets.py +0 -0
  245. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/auto_defaults.py +0 -0
  246. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/cache_decorator.py +0 -0
  247. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/code_validation.py +0 -0
  248. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/disk_space.py +0 -0
  249. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/file_hash.py +0 -0
  250. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/file_iterator.py +0 -0
  251. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/interrupt_handler.py +0 -0
  252. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/ml_context.py +0 -0
  253. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/result_conversion.py +0 -0
  254. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/retry.py +0 -0
  255. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/secure_hasher.py +0 -0
  256. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/helpers/types.py +0 -0
  257. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/lfs.py +0 -0
  258. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/model_extensions.py +0 -0
  259. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/sources/__init__.py +0 -0
  260. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/sources/cloud_storage.py +0 -0
  261. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/sources/dvc.py +0 -0
  262. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/sources/huggingface.py +0 -0
  263. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/sources/jfrog.py +0 -0
  264. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/sources/pytorch_hub.py +0 -0
  265. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/utils/tensorflow_compat.py +0 -0
  266. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/whitelists/__init__.py +0 -0
  267. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/whitelists/huggingface_organizations.py +0 -0
  268. {modelaudit-0.2.31 → modelaudit-0.2.32}/modelaudit/whitelists/huggingface_popular.py +0 -0
  269. {modelaudit-0.2.31 → modelaudit-0.2.32}/package-lock.json +0 -0
  270. {modelaudit-0.2.31 → modelaudit-0.2.32}/package.json +0 -0
  271. {modelaudit-0.2.31 → modelaudit-0.2.32}/pyproject.toml.example +0 -0
  272. {modelaudit-0.2.31 → modelaudit-0.2.32}/release-please-config.json +0 -0
  273. {modelaudit-0.2.31 → modelaudit-0.2.32}/renovate.json +0 -0
  274. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/README.md +0 -0
  275. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/benchmark_report.py +0 -0
  276. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/check_circular_imports.py +0 -0
  277. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/compile_tensorflow_protos.sh +0 -0
  278. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/fetch_hf_org_models.py +0 -0
  279. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/fetch_hf_top_models.py +0 -0
  280. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/generate_keras_layer_inventory.py +0 -0
  281. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/jax_flax_scanning_demo.py +0 -0
  282. {modelaudit-0.2.31 → modelaudit-0.2.32}/scripts/minimal_circular_check.py +0 -0
  283. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/__init__.py +0 -0
  284. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_analysis_modules.py +0 -0
  285. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_anomaly_detector.py +0 -0
  286. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_enhanced_pattern_detector.py +0 -0
  287. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_entropy_analyzer.py +0 -0
  288. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_framework_patterns.py +0 -0
  289. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_ml_context_analyzer.py +0 -0
  290. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_opcode_sequence_analyzer.py +0 -0
  291. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/analysis/test_unified_context.py +0 -0
  292. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit1_basic_torch_bypass.pkl +0 -0
  293. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit2_advanced_torch_bypass.pkl +0 -0
  294. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit3_sophisticated_hybrid.pkl +0 -0
  295. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit4_supply_chain_attack.pkl +0 -0
  296. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit5_ultra_high_confidence.pkl +0 -0
  297. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit6_ordereddict_bypass.pkl +0 -0
  298. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit7_nested_collections.pkl +0 -0
  299. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit9_manual_construction.pkl +0 -0
  300. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/exploits/exploit_ultimate_50pct.pkl +0 -0
  301. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_7z_test_assets.py +0 -0
  302. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_advanced_pickle_tests.py +0 -0
  303. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_evil_pickle.py +0 -0
  304. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_jinja2_test_assets.py +0 -0
  305. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_nested_pickle_assets.py +0 -0
  306. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_os_alias_tests.py +0 -0
  307. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_safe_nested_assets.py +0 -0
  308. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_safetensors_assets.py +0 -0
  309. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/generators/generate_security_assets.py +0 -0
  310. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/pickles/bypass_pocs/gen_bypass_v4.py +0 -0
  311. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/pickles/memo_attack.pkl +0 -0
  312. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/pickles/multiple_stream_attack.pkl +0 -0
  313. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/pickles/nt_alias_attack.pkl +0 -0
  314. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/pickles/posix_alias_attack.pkl +0 -0
  315. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/pickles/stack_global_attack.pkl +0 -0
  316. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/archives/path_traversal.zip +0 -0
  317. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/archives/safe_model.zip +0 -0
  318. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign/chatml_format.json +0 -0
  319. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign/complex_legitimate.json +0 -0
  320. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign/conditional_system.json +0 -0
  321. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign/huggingface_llama.json +0 -0
  322. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign/simple_roles.json +0 -0
  323. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign/special_tokens.json +0 -0
  324. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign_conditional_format.json +0 -0
  325. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign_huggingface_chat.json +0 -0
  326. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign_simple_template.json +0 -0
  327. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/benign_template.j2 +0 -0
  328. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/edge_cases/empty_template.json +0 -0
  329. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/edge_cases/malformed_template.json +0 -0
  330. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/edge_cases/multiple_templates.json +0 -0
  331. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/edge_cases/no_template.json +0 -0
  332. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/edge_cases/oversized_template.json +0 -0
  333. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/attr_bypass.json +0 -0
  334. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/combined_attack.json +0 -0
  335. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/config_exploit.json +0 -0
  336. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/cve_2024_34359_original.json +0 -0
  337. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/direct_eval.json +0 -0
  338. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/env_extraction.json +0 -0
  339. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/file_access.json +0 -0
  340. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/hex_bypass.json +0 -0
  341. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/loop_discovery.json +0 -0
  342. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/network_exfil.json +0 -0
  343. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/request_exploit.json +0 -0
  344. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious/subprocess_injection.json +0 -0
  345. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious_cve_2024_34359.json +0 -0
  346. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious_env_vars.json +0 -0
  347. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious_file_read.json +0 -0
  348. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious_loop_exploit.json +0 -0
  349. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious_obfuscated.json +0 -0
  350. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/malicious_subprocess.template +0 -0
  351. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/obfuscated/base64_payload.json +0 -0
  352. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/obfuscated/char_construction.json +0 -0
  353. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/obfuscated/format_bypass.json +0 -0
  354. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/obfuscated/getattr_bypass.json +0 -0
  355. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/standalone/benign_chat.j2 +0 -0
  356. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/standalone/malicious_standalone.jinja +0 -0
  357. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/standalone/suspicious_benign.template +0 -0
  358. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/tokenizer_config.json +0 -0
  359. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/yaml/malicious_config.yaml +0 -0
  360. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/jinja2/yaml/model_config.yaml +0 -0
  361. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/basic_lambda_layer.h5 +0 -0
  362. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/custom_layer_attack.h5 +0 -0
  363. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/keras_zip_format.keras +0 -0
  364. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/lambda_exfiltration.h5 +0 -0
  365. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/lambda_with_imports.h5 +0 -0
  366. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/loss_injection.h5 +0 -0
  367. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/malicious_lambda.h5 +0 -0
  368. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/metric_injection.h5 +0 -0
  369. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/keras/safe_model.h5 +0 -0
  370. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/manifests/safe_config.json +0 -0
  371. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/manifests/suspicious_config.json +0 -0
  372. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/decode_exec_chain.pkl +0 -0
  373. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/dill_func.pkl +0 -0
  374. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/malicious_model_realistic.pkl +0 -0
  375. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/malicious_system_call.pkl +0 -0
  376. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/nested_pickle_base64.pkl +0 -0
  377. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/nested_pickle_hex.pkl +0 -0
  378. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/nested_pickle_multistage.pkl +0 -0
  379. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/nested_pickle_raw.pkl +0 -0
  380. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/safe_data.pkl +0 -0
  381. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/safe_large_model.pkl +0 -0
  382. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/safe_model_with_binary.pkl +0 -0
  383. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/safe_model_with_encoding.pkl +0 -0
  384. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/safe_model_with_tokens.pkl +0 -0
  385. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/safe_nested_structure.pkl +0 -0
  386. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pickles/simple_nested.pkl +0 -0
  387. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pipeline.skops +0 -0
  388. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pytorch/malicious_eval.pt +0 -0
  389. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/pytorch/safe_model.pt +0 -0
  390. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/safetensors/malicious_import.safetensors +0 -0
  391. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/safetensors/multiple_patterns.safetensors +0 -0
  392. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/safetensors/obfuscated_metadata.safetensors +0 -0
  393. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/safetensors/safe_model.safetensors +0 -0
  394. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/safetensors/script_injection.safetensors +0 -0
  395. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/safetensors/shell_commands.safetensors +0 -0
  396. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/safetensors/suspicious_url.safetensors +0 -0
  397. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/tensorflow/malicious_pyfunc/saved_model.pb +0 -0
  398. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/samples/tensorflow/safe_savedmodel/saved_model.pb +0 -0
  399. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/agpl_component/agpl_model.pkl +0 -0
  400. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/agpl_component/neural_network.py +0 -0
  401. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mit_model/config.json +0 -0
  402. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mit_model/model.py +0 -0
  403. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mit_model/model_weights.pkl +0 -0
  404. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mixed_licenses/LICENSE +0 -0
  405. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mixed_licenses/apache_component.py +0 -0
  406. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mixed_licenses/dataset_cc_nc.json +0 -0
  407. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mixed_licenses/gpl_utility.py +0 -0
  408. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/mixed_licenses/mixed_model.pkl +0 -0
  409. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/unlicensed_dataset/embeddings.npy +0 -0
  410. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/unlicensed_dataset/features.csv +0 -0
  411. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/license_scenarios/unlicensed_dataset/training_data.json +0 -0
  412. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/security_scenarios/mixed_malicious_model/config.json +0 -0
  413. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/assets/scenarios/security_scenarios/mixed_malicious_model/model.pkl +0 -0
  414. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/benchmarks/test_scan_benchmarks.py +0 -0
  415. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/cache/__init__.py +0 -0
  416. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/cache/test_cache_correctness.py +0 -0
  417. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/cache/test_optimized_config.py +0 -0
  418. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/cli_output.py +0 -0
  419. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/config/__init__.py +0 -0
  420. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/config/test_name_blacklist.py +0 -0
  421. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/conftest.py +0 -0
  422. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/demo_license_functionality.py +0 -0
  423. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_builtin_detection.py +0 -0
  424. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_compile_eval_variants.py +0 -0
  425. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_cve_detection.py +0 -0
  426. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_jit_script_detector.py +0 -0
  427. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_network_comm_detector.py +0 -0
  428. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_runpy_detection.py +0 -0
  429. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_secrets_detector.py +0 -0
  430. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/detectors/test_suspicious_symbols.py +0 -0
  431. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/helpers/__init__.py +0 -0
  432. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/helpers/file_creators.py +0 -0
  433. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/helpers/frameworks.py +0 -0
  434. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_jfrog.py +0 -0
  435. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_jfrog_integration.py +0 -0
  436. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_license_checker.py +0 -0
  437. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_license_integration.py +0 -0
  438. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_mlflow_integration.py +0 -0
  439. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_sarif_formatter.py +0 -0
  440. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_sbom_license_integration.py +0 -0
  441. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/integrations/test_sbom_url_fixes.py +0 -0
  442. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/progress/__init__.py +0 -0
  443. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/progress/test_base.py +0 -0
  444. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_base_scanner.py +0 -0
  445. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_catboost_scanner.py +0 -0
  446. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_cntk_scanner.py +0 -0
  447. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_compressed_scanner.py +0 -0
  448. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_executorch_scanner.py +0 -0
  449. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_flax_msgpack_scanner.py +0 -0
  450. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_gguf_scanner.py +0 -0
  451. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_jax_checkpoint_scanner.py +0 -0
  452. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_jinja2_template_scanner.py +0 -0
  453. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_joblib_scanner.py +0 -0
  454. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_joblib_scanner_codecs.py +0 -0
  455. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_keras_h5_scanner.py +0 -0
  456. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_keras_zip_scanner.py +0 -0
  457. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_lightgbm_scanner.py +0 -0
  458. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_llamafile_scanner.py +0 -0
  459. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_manifest_scanner.py +0 -0
  460. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_metadata_scanner.py +0 -0
  461. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_mxnet_scanner.py +0 -0
  462. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_nemo_scanner.py +0 -0
  463. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_numpy_scanner.py +0 -0
  464. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_onnx_dependency_handling.py +0 -0
  465. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_onnx_scanner.py +0 -0
  466. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_paddle_scanner.py +0 -0
  467. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_pickle_scanner.py +0 -0
  468. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_pytorch_binary_scanner.py +0 -0
  469. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_pytorch_zip_scanner.py +0 -0
  470. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_r_serialized_scanner.py +0 -0
  471. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_rknn_scanner.py +0 -0
  472. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_rule_code_registry_consistency.py +0 -0
  473. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_rule_mapper.py +0 -0
  474. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_safetensors_scanner.py +0 -0
  475. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_scanner_registry.py +0 -0
  476. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_sevenzip_scanner.py +0 -0
  477. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_skops_content_analysis.py +0 -0
  478. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_skops_scanner.py +0 -0
  479. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_tar_scanner.py +0 -0
  480. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_tf_metagraph_scanner.py +0 -0
  481. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_tf_savedmodel_scanner.py +0 -0
  482. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_tflite_scanner.py +0 -0
  483. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_torch7_scanner.py +0 -0
  484. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_torchserve_mar_scanner.py +0 -0
  485. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_weight_distribution_scanner.py +0 -0
  486. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_xgboost_scanner.py +0 -0
  487. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/scanners/test_zip_scanner.py +0 -0
  488. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_asset_inventory_integration.py +0 -0
  489. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_asset_list.py +0 -0
  490. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_auth_config.py +0 -0
  491. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_basic.py +0 -0
  492. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_benchmark_report.py +0 -0
  493. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_bug1_confidence_exploit.py +0 -0
  494. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cache_cli.py +0 -0
  495. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cache_optimizations.py +0 -0
  496. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_checks_recording.py +0 -0
  497. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cli.py +0 -0
  498. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cli_cache_dir.py +0 -0
  499. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cli_default_command.py +0 -0
  500. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cli_file_filtering.py +0 -0
  501. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cli_license_integration.py +0 -0
  502. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cli_logging_handlers.py +0 -0
  503. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cli_output.py +0 -0
  504. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cloud_url_detection.py +0 -0
  505. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_core.py +0 -0
  506. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_core_asset_extraction.py +0 -0
  507. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_cve_2025_10155_bin_pickle.py +0 -0
  508. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_debug_command.py +0 -0
  509. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_dill_joblib_enhanced.py +0 -0
  510. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_directory_file_filtering.py +0 -0
  511. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_double_interrupt.py +0 -0
  512. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_exit_codes.py +0 -0
  513. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_false_positive_fixes.py +0 -0
  514. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_file_hash.py +0 -0
  515. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_gguf_sbom_integration.py +0 -0
  516. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_graceful_degradation.py +0 -0
  517. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_header_discrepancy.py +0 -0
  518. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_huggingface_extensions.py +0 -0
  519. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_huggingface_symlinks.py +0 -0
  520. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_importlib_detection.py +0 -0
  521. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_integration.py +0 -0
  522. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_jax_flax_integration.py +0 -0
  523. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_jit_script_integration.py +0 -0
  524. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_lazy_loading.py +0 -0
  525. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_lazy_loading_integration.py +0 -0
  526. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_manifest_name_policy.py +0 -0
  527. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_metadata_extractor.py +0 -0
  528. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_models.py +0 -0
  529. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_nested_pickle_integration.py +0 -0
  530. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_network_comm_integration.py +0 -0
  531. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_os_alias_detection.py +0 -0
  532. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_os_subprocess_detection.py +0 -0
  533. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_path_traversal.py +0 -0
  534. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_performance_benchmarks.py +0 -0
  535. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_pickle_context_filtering.py +0 -0
  536. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_progress.py +0 -0
  537. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_pydantic_models.py +0 -0
  538. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_python_version_warning.py +0 -0
  539. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_pytorch_zip_detection.py +0 -0
  540. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_real_world_dill_joblib.py +0 -0
  541. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_regression_corpus.py +0 -0
  542. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_regular_scan_hash.py +0 -0
  543. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_rules.py +0 -0
  544. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_safetensors_optimization.py +0 -0
  545. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_secure_hasher.py +0 -0
  546. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_security_asset_integration.py +0 -0
  547. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_security_enhancements.py +0 -0
  548. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_shebang_context.py +0 -0
  549. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_simple_jinja2.py +0 -0
  550. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_sklearn_joblib_false_positive.py +0 -0
  551. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_streaming_scan.py +0 -0
  552. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_telemetry.py +0 -0
  553. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_telemetry_decoupling.py +0 -0
  554. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_tensorflow_lambda_detection.py +0 -0
  555. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_timeout_configuration.py +0 -0
  556. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_utils.py +0 -0
  557. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_weak_hash_detection.py +0 -0
  558. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_webbrowser_detection.py +0 -0
  559. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_why_explanations.py +0 -0
  560. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/test_xdist_status.py +0 -0
  561. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/__init__.py +0 -0
  562. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/__init__.py +0 -0
  563. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_advanced_file_handler.py +0 -0
  564. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_advanced_size_limits.py +0 -0
  565. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_file_filter.py +0 -0
  566. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_file_type_validation_integration.py +0 -0
  567. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_filetype.py +0 -0
  568. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_integration_file_type_demo.py +0 -0
  569. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_large_file_handler.py +0 -0
  570. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_streaming_analysis.py +0 -0
  571. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/file/test_streaming_preview.py +0 -0
  572. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_asset_from_scan_result.py +0 -0
  573. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_auto_defaults.py +0 -0
  574. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_code_validation.py +0 -0
  575. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_disk_space.py +0 -0
  576. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_file_iterator.py +0 -0
  577. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_interrupt_handling.py +0 -0
  578. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_ml_context_false_positives.py +0 -0
  579. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_py_compile_improvements.py +0 -0
  580. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/helpers/test_secure_hasher.py +0 -0
  581. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/sources/test_cloud_storage.py +0 -0
  582. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/sources/test_dvc_integration.py +0 -0
  583. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/sources/test_huggingface.py +0 -0
  584. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/sources/test_pytorch_hub.py +0 -0
  585. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/test_lfs.py +0 -0
  586. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/utils/test_result_conversion.py +0 -0
  587. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/whitelists/__init__.py +0 -0
  588. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/whitelists/test_combined.py +0 -0
  589. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/whitelists/test_huggingface_popular.py +0 -0
  590. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/whitelists/test_organizations.py +0 -0
  591. {modelaudit-0.2.31 → modelaudit-0.2.32}/tests/xdist_status.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.32"
3
+ }
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.32](https://github.com/promptfoo/modelaudit/compare/v0.2.31...v0.2.32) (2026-04-05)
9
+
10
+ ### Bug Fixes
11
+
12
+ - detect punctuated TensorRT tmp paths ([#867](https://github.com/promptfoo/modelaudit/issues/867)) ([9607530](https://github.com/promptfoo/modelaudit/commit/96075302de2d71b228be97e49698d6a1ad6b35bf))
13
+ - fail closed on OpenVINO DOCTYPE parse errors ([#864](https://github.com/promptfoo/modelaudit/issues/864)) ([f5b19c4](https://github.com/promptfoo/modelaudit/commit/f5b19c48c7eab876e29f1f474c555b902fa9b6ce))
14
+ - ignore OCI metadata URLs during layer discovery ([#866](https://github.com/promptfoo/modelaudit/issues/866)) ([0b24e3f](https://github.com/promptfoo/modelaudit/commit/0b24e3f7a0e013541bce100b64f1d69558bd807d))
15
+ - reduce PMML subprocess extension false positives ([#869](https://github.com/promptfoo/modelaudit/issues/869)) ([5e6f79d](https://github.com/promptfoo/modelaudit/commit/5e6f79dc134267202b5a4b841a8946af865ebd15))
16
+ - tolerate bounded CoreML custom block truncation ([#868](https://github.com/promptfoo/modelaudit/issues/868)) ([34df06d](https://github.com/promptfoo/modelaudit/commit/34df06dd2c12b69815a2a15f1273085856bebf64))
17
+
18
+ ## [Unreleased]
19
+
20
+ ### Bug Fixes
21
+
22
+ - avoid CoreML nested parse failures on bounded-read truncation
23
+ - detect punctuation-delimited TensorRT `/tmp` plugin paths
24
+ - avoid PMML `<Extension>` false positives for benign `subprocess` prose while preserving `subprocess.getoutput()`, `subprocess.getstatusoutput()`, and `importlib.import_module("subprocess")` detections
25
+
8
26
  ## [0.2.31](https://github.com/promptfoo/modelaudit/compare/v0.2.30...v0.2.31) (2026-04-04)
9
27
 
10
28
  ### Bug Fixes
@@ -163,6 +181,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
163
181
  - **security:** detect protocol 0/1 pickle streams whose dangerous opcode appears after large trivial padding or after a non-trivial probe-boundary prelude, reject all-trivial no-`STOP` probe prefixes, and preserve rule codes across cached scan-result round trips
164
182
  - **license:** bound binary header scans and reuse compiled patterns to avoid full-file regex passes on large model archives
165
183
  - **security:** stop iterating malformed TFLite models after excessive subgraph counts are detected
184
+ - **openvino:** route forbidden-DOCTYPE IR XML into the OpenVINO scanner, fail closed on XML parse errors, and suppress warning-level format-validation noise for benign `.xml` models with no distinctive magic bytes
166
185
  - **security:** fail closed on conflicting duplicate or alias Keras root members so benign trailing `config.json` entries cannot hide malicious earlier configs, while accepting byte-identical duplicates without warning noise
167
186
  - **security:** detect PyTorch binary code and blacklist patterns that straddle chunk boundaries, avoid duplicate overlap reports, and return `success=False` when CRITICAL findings are present
168
187
  - **security:** scan every duplicate PyTorch ZIP member by physical archive entry and report conflicting duplicate names at INFO severity so benign trailing `data.pkl` entries cannot shadow malicious earlier payloads without making benign-but-conflicting duplicates warning-fail by themselves
@@ -180,6 +199,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
180
199
  - preserve disguised model files during directory prefiltering without promoting document ZIPs
181
200
  - fail closed on duplicate 7z entries, nested critical findings, probe-limit truncation, and malformed 7z safety-limit configs
182
201
  - **oci:** fail closed on nested findings and partial layer traversal, content-sniff misnamed layer members, normalize cosmetic layer-ref suffix changes, and reject oversized members before temp extraction
202
+ - **oci:** ignore non-layer metadata strings ending in `.tar.gz` when collecting manifest layer refs so benign URLs do not become false missing-layer failures
183
203
  - recurse into nested 7z members even when their filenames use misleading extensions
184
204
  - fail closed on extreme-size files when a scanner lacks bounded large-file analysis
185
205
  - harden scan-cache invalidation and skip caching operational scan failures
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modelaudit
3
- Version: 0.2.31
3
+ Version: 0.2.32
4
4
  Summary: Static scanning library for detecting malicious code, backdoors, and other security risks in ML model files
5
5
  Project-URL: Repository, https://github.com/promptfoo/modelaudit
6
6
  Project-URL: Homepage, https://github.com/promptfoo/modelaudit
@@ -198,6 +198,7 @@ class CoreMLScanner(BaseScanner):
198
198
  MAX_USER_METADATA_ENTRIES: ClassVar[int] = 512
199
199
  MAX_RECURSIVE_MESSAGE_DEPTH: ClassVar[int] = 16
200
200
  MAX_RECURSIVE_PROTOBUF_DEPTH: ClassVar[int] = 64
201
+ _allow_truncated_field_parse = False
201
202
 
202
203
  # CoreML model oneof fields from Model.proto
203
204
  MODEL_TYPE_FIELDS: ClassVar[frozenset[int]] = frozenset(
@@ -339,6 +340,7 @@ class CoreMLScanner(BaseScanner):
339
340
  result = self._create_result()
340
341
  self.current_file_path = path
341
342
  file_size = self.get_file_size(path)
343
+ self._allow_truncated_field_parse = file_size > self.MAX_PARSE_BYTES
342
344
  result.metadata["file_size"] = file_size
343
345
 
344
346
  # Add file integrity check for compliance.
@@ -362,6 +364,7 @@ class CoreMLScanner(BaseScanner):
362
364
  return result
363
365
 
364
366
  if file_size > self.MAX_PARSE_BYTES:
367
+ result.metadata["coreml_bounded_read_truncated"] = True
365
368
  result.add_check(
366
369
  name="CoreML Bounded Parse Window",
367
370
  passed=True,
@@ -438,9 +441,11 @@ class CoreMLScanner(BaseScanner):
438
441
  model_path=model_path,
439
442
  )
440
443
 
441
- traversal_truncated = bool(result.metadata.get("coreml_traversal_truncated"))
444
+ scan_truncated = bool(
445
+ result.metadata.get("coreml_bounded_read_truncated") or result.metadata.get("coreml_traversal_truncated")
446
+ )
442
447
 
443
- if metadata_findings == 0 and not traversal_truncated:
448
+ if metadata_findings == 0 and not scan_truncated:
444
449
  result.add_check(
445
450
  name="CoreML Metadata Security Check",
446
451
  passed=True,
@@ -448,7 +453,7 @@ class CoreMLScanner(BaseScanner):
448
453
  location=path,
449
454
  )
450
455
 
451
- if custom_findings == 0 and not traversal_truncated:
456
+ if custom_findings == 0 and not scan_truncated:
452
457
  result.add_check(
453
458
  name="CoreML Custom Code Path Check",
454
459
  passed=True,
@@ -456,7 +461,7 @@ class CoreMLScanner(BaseScanner):
456
461
  location=path,
457
462
  )
458
463
 
459
- if linked_path_findings == 0 and not traversal_truncated:
464
+ if linked_path_findings == 0 and not scan_truncated:
460
465
  result.add_check(
461
466
  name="CoreML Linked Model Path Check",
462
467
  passed=True,
@@ -609,6 +614,22 @@ class CoreMLScanner(BaseScanner):
609
614
  "has_custom_model": has_custom_model,
610
615
  }
611
616
 
617
+ def _parse_field_message(
618
+ self,
619
+ field: _ProtoField,
620
+ *,
621
+ max_fields: int,
622
+ ) -> tuple[list[_ProtoField], str | None]:
623
+ payload = field.value
624
+ if not isinstance(payload, bytes):
625
+ return [], None
626
+
627
+ return _parse_message(
628
+ payload,
629
+ max_fields=max_fields,
630
+ allow_truncated=self._allow_truncated_field_parse and field.truncated,
631
+ )
632
+
612
633
  def _analyze_description(
613
634
  self,
614
635
  top_fields: list[_ProtoField],
@@ -623,11 +644,10 @@ class CoreMLScanner(BaseScanner):
623
644
  if not description_messages:
624
645
  return findings
625
646
 
626
- description_payload = description_messages[0].value
627
- if not isinstance(description_payload, bytes):
628
- return findings
629
-
630
- desc_fields, desc_error = _parse_message(description_payload, max_fields=self.MAX_NESTED_FIELDS)
647
+ desc_fields, desc_error = self._parse_field_message(
648
+ description_messages[0],
649
+ max_fields=self.MAX_NESTED_FIELDS,
650
+ )
631
651
  if desc_error:
632
652
  result.add_check(
633
653
  name="CoreML Description Parse",
@@ -643,11 +663,10 @@ class CoreMLScanner(BaseScanner):
643
663
  if not metadata_messages:
644
664
  return findings
645
665
 
646
- metadata_payload = metadata_messages[0].value
647
- if not isinstance(metadata_payload, bytes):
648
- return findings
649
-
650
- metadata_fields, metadata_error = _parse_message(metadata_payload, max_fields=self.MAX_NESTED_FIELDS)
666
+ metadata_fields, metadata_error = self._parse_field_message(
667
+ metadata_messages[0],
668
+ max_fields=self.MAX_NESTED_FIELDS,
669
+ )
651
670
  if metadata_error:
652
671
  result.add_check(
653
672
  name="CoreML Metadata Parse",
@@ -694,11 +713,7 @@ class CoreMLScanner(BaseScanner):
694
713
  user_defined: dict[str, str] = {}
695
714
  user_defined_fields = _len_fields(metadata_fields, 100)[: self.MAX_USER_METADATA_ENTRIES]
696
715
  for index, entry_field in enumerate(user_defined_fields):
697
- entry_payload = entry_field.value
698
- if not isinstance(entry_payload, bytes):
699
- continue
700
-
701
- entry_fields, entry_error = _parse_message(entry_payload, max_fields=32)
716
+ entry_fields, entry_error = self._parse_field_message(entry_field, max_fields=32)
702
717
  if entry_error:
703
718
  result.add_check(
704
719
  name="CoreML User Metadata Entry Parse",
@@ -862,12 +877,9 @@ class CoreMLScanner(BaseScanner):
862
877
  for model_field in top_fields:
863
878
  if model_field.field_number not in self.NEURAL_NETWORK_FIELDS or model_field.wire_type != 2:
864
879
  continue
865
- payload = model_field.value
866
- if not isinstance(payload, bytes):
867
- continue
868
-
869
- network_fields, network_error = _parse_message(
870
- payload, max_fields=self.MAX_NESTED_FIELDS, allow_truncated=False
880
+ network_fields, network_error = self._parse_field_message(
881
+ model_field,
882
+ max_fields=self.MAX_NESTED_FIELDS,
871
883
  )
872
884
  if network_error:
873
885
  result.add_check(
@@ -886,12 +898,10 @@ class CoreMLScanner(BaseScanner):
886
898
 
887
899
  layer_fields = _len_fields(network_fields, 1)
888
900
  for layer_index, layer_field in enumerate(layer_fields):
889
- layer_payload = layer_field.value
890
- if not isinstance(layer_payload, bytes):
891
- continue
892
901
  layer_count += 1
893
- parsed_layer, layer_error = _parse_message(
894
- layer_payload, max_fields=self.MAX_NESTED_FIELDS, allow_truncated=False
902
+ parsed_layer, layer_error = self._parse_field_message(
903
+ layer_field,
904
+ max_fields=self.MAX_NESTED_FIELDS,
895
905
  )
896
906
  if layer_error:
897
907
  result.add_check(
@@ -917,14 +927,10 @@ class CoreMLScanner(BaseScanner):
917
927
 
918
928
  custom_fields = _len_fields(parsed_layer, 500)
919
929
  for custom_field in custom_fields:
920
- custom_payload = custom_field.value
921
- if not isinstance(custom_payload, bytes):
922
- continue
923
930
  custom_layer_count += 1
924
- parsed_custom, custom_error = _parse_message(
925
- custom_payload,
931
+ parsed_custom, custom_error = self._parse_field_message(
932
+ custom_field,
926
933
  max_fields=self.MAX_NESTED_FIELDS,
927
- allow_truncated=False,
928
934
  )
929
935
  if custom_error:
930
936
  result.add_check(
@@ -979,12 +985,9 @@ class CoreMLScanner(BaseScanner):
979
985
 
980
986
  custom_model_fields = _len_fields(top_fields, self.CUSTOM_MODEL_FIELD)
981
987
  for custom_model_field in custom_model_fields:
982
- payload = custom_model_field.value
983
- if not isinstance(payload, bytes):
984
- continue
985
-
986
- custom_model, custom_model_error = _parse_message(
987
- payload, max_fields=self.MAX_NESTED_FIELDS, allow_truncated=False
988
+ custom_model, custom_model_error = self._parse_field_message(
989
+ custom_model_field,
990
+ max_fields=self.MAX_NESTED_FIELDS,
988
991
  )
989
992
  if custom_model_error:
990
993
  result.add_check(
@@ -1053,11 +1056,7 @@ class CoreMLScanner(BaseScanner):
1053
1056
 
1054
1057
  parameter_entries = _len_fields(message_fields, 30)
1055
1058
  for entry_index, parameter_entry in enumerate(parameter_entries):
1056
- entry_payload = parameter_entry.value
1057
- if not isinstance(entry_payload, bytes):
1058
- continue
1059
-
1060
- entry_fields, entry_error = _parse_message(entry_payload, max_fields=32, allow_truncated=False)
1059
+ entry_fields, entry_error = self._parse_field_message(parameter_entry, max_fields=32)
1061
1060
  if entry_error:
1062
1061
  result.add_check(
1063
1062
  name="CoreML Custom Parameter Entry Parse",
@@ -1079,12 +1078,11 @@ class CoreMLScanner(BaseScanner):
1079
1078
  continue
1080
1079
 
1081
1080
  raw_key = key_fields[0].value
1082
- raw_value = value_fields[0].value
1083
- if not isinstance(raw_key, bytes) or not isinstance(raw_value, bytes):
1081
+ if not isinstance(raw_key, bytes):
1084
1082
  continue
1085
1083
 
1086
1084
  param_key = _decode_string(raw_key, max_length=256)
1087
- value_message_fields, value_error = _parse_message(raw_value, max_fields=32, allow_truncated=False)
1085
+ value_message_fields, value_error = self._parse_field_message(value_fields[0], max_fields=32)
1088
1086
  if value_error:
1089
1087
  result.add_check(
1090
1088
  name="CoreML Custom Parameter Value Parse",
@@ -1151,11 +1149,7 @@ class CoreMLScanner(BaseScanner):
1151
1149
 
1152
1150
  base_dir = Path(path).resolve().parent
1153
1151
  for linked_model_field in linked_model_fields:
1154
- payload = linked_model_field.value
1155
- if not isinstance(payload, bytes):
1156
- continue
1157
-
1158
- linked_model_message, parse_error = _parse_message(payload, max_fields=64, allow_truncated=False)
1152
+ linked_model_message, parse_error = self._parse_field_message(linked_model_field, max_fields=64)
1159
1153
  if parse_error:
1160
1154
  result.add_check(
1161
1155
  name="CoreML Linked Model Parse",
@@ -1173,11 +1167,10 @@ class CoreMLScanner(BaseScanner):
1173
1167
 
1174
1168
  linked_model_file_fields = _len_fields(linked_model_message, 1)
1175
1169
  for linked_model_file_field in linked_model_file_fields:
1176
- file_payload = linked_model_file_field.value
1177
- if not isinstance(file_payload, bytes):
1178
- continue
1179
-
1180
- linked_model_file, file_error = _parse_message(file_payload, max_fields=64, allow_truncated=False)
1170
+ linked_model_file, file_error = self._parse_field_message(
1171
+ linked_model_file_field,
1172
+ max_fields=64,
1173
+ )
1181
1174
  if file_error:
1182
1175
  result.add_check(
1183
1176
  name="CoreML Linked Model File Parse",
@@ -1225,11 +1218,7 @@ class CoreMLScanner(BaseScanner):
1225
1218
  if not parameter_fields:
1226
1219
  return None
1227
1220
 
1228
- payload = parameter_fields[0].value
1229
- if not isinstance(payload, bytes):
1230
- return None
1231
-
1232
- parsed_parameter, parse_error = _parse_message(payload, max_fields=16, allow_truncated=False)
1221
+ parsed_parameter, parse_error = self._parse_field_message(parameter_fields[0], max_fields=16)
1233
1222
  if parse_error:
1234
1223
  return None
1235
1224
 
@@ -110,6 +110,40 @@ class OciLayerScanner(BaseScanner):
110
110
  """Trim manifest layer refs so cosmetic suffix whitespace cannot hide .tar.gz layers."""
111
111
  return layer_ref.strip().rstrip(" .")
112
112
 
113
+ @classmethod
114
+ def _collect_layer_paths(cls, manifest_data: Any) -> list[str]:
115
+ """Collect layer refs from manifest layer fields without treating arbitrary strings as layers."""
116
+ layer_paths: list[str] = []
117
+
118
+ def _append_layer_ref(value: Any) -> None:
119
+ if isinstance(value, str) and cls._normalize_layer_ref(value).lower().endswith(cls._LAYER_ARCHIVE_SUFFIX):
120
+ layer_paths.append(value)
121
+
122
+ def _collect_layer_value(value: Any) -> None:
123
+ if isinstance(value, str):
124
+ _append_layer_ref(value)
125
+ elif isinstance(value, list):
126
+ for item in value:
127
+ _collect_layer_value(item)
128
+ elif isinstance(value, dict):
129
+ for key, item in value.items():
130
+ if str(key).lower() in {"layers", "urls"}:
131
+ _collect_layer_value(item)
132
+
133
+ def _walk_manifest(obj: Any) -> None:
134
+ if isinstance(obj, dict):
135
+ for key, value in obj.items():
136
+ if str(key).lower() == "layers":
137
+ _collect_layer_value(value)
138
+ elif isinstance(value, (dict, list)):
139
+ _walk_manifest(value)
140
+ elif isinstance(obj, list):
141
+ for item in obj:
142
+ _walk_manifest(item)
143
+
144
+ _walk_manifest(manifest_data)
145
+ return layer_paths
146
+
113
147
  @staticmethod
114
148
  def _rewrite_embedded_location(
115
149
  location: str | None,
@@ -233,20 +267,7 @@ class OciLayerScanner(BaseScanner):
233
267
  result.finish(success=False)
234
268
  return result
235
269
 
236
- # Find layer paths ending with .tar.gz
237
- layer_paths: list[str] = []
238
-
239
- def _search(obj: Any) -> None:
240
- if isinstance(obj, dict):
241
- for v in obj.values():
242
- _search(v)
243
- elif isinstance(obj, list):
244
- for item in obj:
245
- _search(item)
246
- elif isinstance(obj, str) and self._normalize_layer_ref(obj).lower().endswith(self._LAYER_ARCHIVE_SUFFIX):
247
- layer_paths.append(obj)
248
-
249
- _search(manifest_data)
270
+ layer_paths = self._collect_layer_paths(manifest_data)
250
271
 
251
272
  manifest_dir = os.path.dirname(path)
252
273
  scan_complete = True
@@ -40,6 +40,77 @@ def _local_tag_name(tag: str) -> str:
40
40
  return tag.rsplit("}", 1)[-1].lower()
41
41
 
42
42
 
43
+ def _skip_doctype_declaration(xml_prefix: bytes, start_offset: int) -> int | None:
44
+ """Skip a DOCTYPE declaration without expanding entities."""
45
+ index = start_offset + len(b"<!DOCTYPE")
46
+ bracket_depth = 0
47
+ quote_char: int | None = None
48
+
49
+ while index < len(xml_prefix):
50
+ byte = xml_prefix[index]
51
+ if quote_char is not None:
52
+ if byte == quote_char:
53
+ quote_char = None
54
+ elif byte in {ord("'"), ord('"')}:
55
+ quote_char = byte
56
+ elif byte == ord("["):
57
+ bracket_depth += 1
58
+ elif byte == ord("]") and bracket_depth > 0:
59
+ bracket_depth -= 1
60
+ elif byte == ord(">") and bracket_depth == 0:
61
+ return index + 1
62
+ index += 1
63
+
64
+ return None
65
+
66
+
67
+ def _looks_like_openvino_xml_prefix(xml_prefix: bytes) -> bool:
68
+ """Sniff the first root element without relying on entity-expanding XML parsing."""
69
+ index = 3 if xml_prefix.startswith(b"\xef\xbb\xbf") else 0
70
+ prefix_length = len(xml_prefix)
71
+
72
+ while index < prefix_length:
73
+ while index < prefix_length and chr(xml_prefix[index]).isspace():
74
+ index += 1
75
+
76
+ if xml_prefix.startswith(b"<?", index):
77
+ end_offset = xml_prefix.find(b"?>", index + 2)
78
+ if end_offset == -1:
79
+ return False
80
+ index = end_offset + 2
81
+ continue
82
+
83
+ if xml_prefix.startswith(b"<!--", index):
84
+ end_offset = xml_prefix.find(b"-->", index + 4)
85
+ if end_offset == -1:
86
+ return False
87
+ index = end_offset + 3
88
+ continue
89
+
90
+ if xml_prefix[index : index + len(b"<!DOCTYPE")].upper() == b"<!DOCTYPE":
91
+ next_index = _skip_doctype_declaration(xml_prefix, index)
92
+ if next_index is None:
93
+ return False
94
+ index = next_index
95
+ continue
96
+
97
+ break
98
+
99
+ if index >= prefix_length or xml_prefix[index : index + 1] != b"<":
100
+ return False
101
+ if xml_prefix[index + 1 : index + 2] in {b"/", b"!", b"?"}:
102
+ return False
103
+
104
+ tag_end = index + 1
105
+ while tag_end < prefix_length and xml_prefix[tag_end : tag_end + 1] not in b" \t\r\n\f/>":
106
+ tag_end += 1
107
+ if tag_end == index + 1:
108
+ return False
109
+
110
+ root_tag = xml_prefix[index + 1 : tag_end].decode("utf-8", "ignore")
111
+ return _local_tag_name(root_tag) in _OPENVINO_ROOT_TAGS
112
+
113
+
43
114
  def _iter_element_attributes(layer: Any) -> Iterator[tuple[str, str, str]]:
44
115
  """Yield normalized attributes from a layer and its nested config nodes."""
45
116
  for element in layer.iter():
@@ -68,8 +139,11 @@ class OpenVinoScanner(BaseScanner):
68
139
  try:
69
140
  with open(path, "rb") as xml_file:
70
141
  xml_prefix = xml_file.read(cls.CAN_HANDLE_MAX_PARSE_BYTES)
71
- for _event, element in DefusedET.iterparse(BytesIO(xml_prefix), events=("start",)):
72
- return _local_tag_name(str(element.tag)) in _OPENVINO_ROOT_TAGS
142
+ try:
143
+ for _event, element in DefusedET.iterparse(BytesIO(xml_prefix), events=("start",)):
144
+ return _local_tag_name(str(element.tag)) in _OPENVINO_ROOT_TAGS
145
+ except Exception:
146
+ return _looks_like_openvino_xml_prefix(xml_prefix)
73
147
  except Exception:
74
148
  return False
75
149
 
@@ -105,6 +179,8 @@ class OpenVinoScanner(BaseScanner):
105
179
  tree = DefusedET.parse(path)
106
180
  root = tree.getroot()
107
181
  except Exception as e: # pragma: no cover - parse errors
182
+ result.metadata["operational_error"] = True
183
+ result.metadata["operational_error_reason"] = "openvino_xml_parse_failed"
108
184
  result.add_check(
109
185
  name="OpenVINO XML Parse",
110
186
  passed=False,
@@ -27,7 +27,9 @@ SUSPICIOUS_PATTERNS = [
27
27
  r"exec\s*\(",
28
28
  r"eval\s*\(",
29
29
  r"import\s+os",
30
- r"subprocess",
30
+ r"\b(?:importlib\s*\.\s*)?import_module\s*\(\s*['\"]subprocess['\"]\s*\)",
31
+ r"\b(?:from\s+subprocess\s+import|import\s+subprocess)\b",
32
+ r"\bsubprocess\s*\.\s*(?:popen|run|call|check_call|check_output|getoutput|getstatusoutput)\s*\(",
31
33
  r"__import__",
32
34
  r"system\s*\(",
33
35
  ]
@@ -11,11 +11,11 @@ from .base import BaseScanner, IssueSeverity, ScanResult
11
11
 
12
12
  SUSPICIOUS_PATTERN_RULES: tuple[tuple[str, re.Pattern[str]], ...] = (
13
13
  ("../", re.compile(r"(?<![A-Za-z0-9_.-])(?:\.\./|\.\.\\)", re.IGNORECASE)),
14
- ("/tmp/", re.compile(r"(?:^|[\s'\"=:])(?:/tmp/|(?:[A-Za-z]:)?\\tmp\\)", re.IGNORECASE)),
14
+ ("/tmp/", re.compile(r"(?<![A-Za-z0-9_.-])(?:/tmp/|(?:[A-Za-z]:)?\\tmp\\)", re.IGNORECASE)),
15
15
  (
16
16
  ".so",
17
17
  re.compile(
18
- r"(?<![A-Za-z0-9_.-])(?:[A-Za-z0-9_+.-]+)?\.so(?:\.[A-Za-z0-9_+.-]+)?(?![A-Za-z0-9_.-])",
18
+ r"(?<![A-Za-z0-9_.-])(?:[A-Za-z0-9_+.-]+)?\.so(?:\.[0-9]+(?:\.[0-9]+)*)?(?![A-Za-z0-9_.-])",
19
19
  re.IGNORECASE,
20
20
  ),
21
21
  ),
@@ -1382,6 +1382,11 @@ def validate_file_type(path: str) -> bool:
1382
1382
  if ext_format == "pmml" and header_format == "pmml":
1383
1383
  return True
1384
1384
 
1385
+ # OpenVINO IR XML can be identified structurally by the dedicated scanner
1386
+ # even when bounded magic-byte detection returns unknown for normal XML.
1387
+ if ext_format == "openvino":
1388
+ return header_format in {"openvino", "unknown"}
1389
+
1385
1390
  if ext_format == "torchserve_mar":
1386
1391
  return header_format == "torchserve_mar"
1387
1392
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "modelaudit"
7
- version = "0.2.31"
7
+ version = "0.2.32"
8
8
  description = "Static scanning library for detecting malicious code, backdoors, and other security risks in ML model files"
9
9
  authors = [
10
10
  { name = "Ian Webster", email = "ian@promptfoo.dev" },
@@ -539,6 +539,30 @@ def test_coreml_scanner_recursion_limit_succeeds_just_below_limit(tmp_path: Path
539
539
  )
540
540
 
541
541
 
542
+ def test_coreml_scanner_oversized_truncated_benign_layers_do_not_fail_closed(tmp_path: Path) -> None:
543
+ oversized_layer = _build_layer("safe_layer_" + "A" * (CoreMLScanner.MAX_PARSE_BYTES + 2048))
544
+ model_path = _write_model(
545
+ tmp_path / "oversized_truncated_benign.mlmodel",
546
+ _build_model(
547
+ description=_build_description(metadata=_build_metadata()),
548
+ neural_network=_build_neural_network(layers=[oversized_layer]),
549
+ ),
550
+ )
551
+
552
+ result = CoreMLScanner().scan(str(model_path))
553
+
554
+ assert result.success is True
555
+ assert result.metadata.get("coreml_bounded_read_truncated") is True
556
+ assert not any(
557
+ issue.severity == IssueSeverity.CRITICAL and "Unable to parse CoreML neural network block" in issue.message
558
+ for issue in result.issues
559
+ )
560
+ assert any(
561
+ check.name == "CoreML Bounded Parse Window" and check.status.value == "passed" for check in result.checks
562
+ )
563
+ assert not any(check.name == "CoreML Custom Code Path Check" for check in result.checks)
564
+
565
+
542
566
  def test_coreml_scanner_malformed_custom_model_fails_closed(tmp_path: Path) -> None:
543
567
  model_path = _write_model(
544
568
  tmp_path / "malformed_custom_model.mlmodel",
@@ -581,6 +605,35 @@ def test_coreml_scanner_truncated_linked_model_file_fails_closed(tmp_path: Path)
581
605
  )
582
606
 
583
607
 
608
+ def test_coreml_scanner_truncated_nested_linked_model_fails_closed_without_bounded_read(tmp_path: Path) -> None:
609
+ malformed_nested_model = (
610
+ _field_varint(1, 8)
611
+ + _field_bytes(2, _build_description(metadata=_build_metadata()))
612
+ + _encode_varint((556 << 3) | 2)
613
+ + _encode_varint(8)
614
+ + b"\x0a\x05abc"
615
+ )
616
+ model_path = _write_model(
617
+ tmp_path / "nested_malformed_linked_model.mlmodel",
618
+ _build_model(
619
+ description=_build_description(metadata=_build_metadata()),
620
+ pipeline_wrapper=_build_pipeline_wrapper(malformed_nested_model),
621
+ ),
622
+ )
623
+
624
+ result = CoreMLScanner().scan(str(model_path))
625
+
626
+ assert result.success is False
627
+ assert result.metadata.get("coreml_bounded_read_truncated") is not True
628
+ assert any(
629
+ issue.severity == IssueSeverity.CRITICAL
630
+ and "Unable to parse CoreML linked-model block" in issue.message
631
+ and "][1:0][556]" in issue.details.get("field_path", "")
632
+ and issue.details.get("parse_error") == "truncated length-delimited field 1"
633
+ for issue in result.issues
634
+ )
635
+
636
+
584
637
  def test_coreml_scanner_corrupt_protobuf_handling(tmp_path: Path) -> None:
585
638
  corrupt_path = tmp_path / "corrupt.mlmodel"
586
639
  # Truncated length-delimited field
@@ -294,6 +294,33 @@ class TestOciLayerScanner:
294
294
 
295
295
  assert result.success is True
296
296
 
297
+ def test_scan_manifest_ignores_non_layer_tar_gz_metadata_strings(self, tmp_path: Path) -> None:
298
+ """Metadata URLs ending in .tar.gz should not be treated as required local layer files."""
299
+ safe_file = tmp_path / "safe.txt"
300
+ safe_file.write_text("Safe content")
301
+
302
+ layer_path = tmp_path / "layer.tar.gz"
303
+ with tarfile.open(layer_path, "w:gz") as tar:
304
+ tar.add(safe_file, arcname="safe.txt")
305
+
306
+ manifest = {
307
+ "layers": ["layer.tar.gz"],
308
+ "homepage": "https://cdn.example.com/not-a-local-layer.tar.gz",
309
+ "metadata": {
310
+ "release_notes": "https://cdn.example.com/docs.tar.gz",
311
+ "labels": ["stable", "https://cdn.example.com/archive.tar.gz"],
312
+ },
313
+ }
314
+ manifest_path = tmp_path / "metadata-url.manifest"
315
+ manifest_path.write_text(json.dumps(manifest))
316
+
317
+ result = OciLayerScanner().scan(str(manifest_path))
318
+
319
+ assert result.success is True
320
+ assert not any("not-a-local-layer.tar.gz" in issue.message for issue in result.issues)
321
+ assert not any("docs.tar.gz" in issue.message for issue in result.issues)
322
+ assert not any("archive.tar.gz" in issue.message for issue in result.issues)
323
+
297
324
  def test_scan_layer_with_non_scannable_files(self, tmp_path):
298
325
  """Test scanning layer containing files that don't match any scanner."""
299
326
  # Create a random binary file