txt2stix 1.2.3__tar.gz → 1.2.5__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 (264) hide show
  1. {txt2stix-1.2.3 → txt2stix-1.2.5}/PKG-INFO +1 -1
  2. {txt2stix-1.2.3 → txt2stix-1.2.5}/pyproject.toml +1 -1
  3. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_bundler.py +14 -0
  4. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_main.py +100 -5
  5. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/bundler.py +3 -0
  6. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/txt2stix.py +2 -0
  7. {txt2stix-1.2.3 → txt2stix-1.2.5}/.env.example +0 -0
  8. {txt2stix-1.2.3 → txt2stix-1.2.5}/.env.markdown +0 -0
  9. {txt2stix-1.2.3 → txt2stix-1.2.5}/.github/workflows/create-release.yml +0 -0
  10. {txt2stix-1.2.3 → txt2stix-1.2.5}/.github/workflows/run-tests.yml +0 -0
  11. {txt2stix-1.2.3 → txt2stix-1.2.5}/.gitignore +0 -0
  12. {txt2stix-1.2.3 → txt2stix-1.2.5}/LICENSE +0 -0
  13. {txt2stix-1.2.3 → txt2stix-1.2.5}/README.md +0 -0
  14. {txt2stix-1.2.3 → txt2stix-1.2.5}/docs/README.md +0 -0
  15. {txt2stix-1.2.3 → txt2stix-1.2.5}/docs/stix-mapping.md +0 -0
  16. {txt2stix-1.2.3 → txt2stix-1.2.5}/docs/txt2stix.png +0 -0
  17. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/__init__.py +0 -0
  18. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/extractions/ai/config.yaml +0 -0
  19. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/extractions/lookup/config.yaml +0 -0
  20. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/extractions/pattern/config.yaml +0 -0
  21. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/helpers/mimetype_filename_extension_list.csv +0 -0
  22. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/helpers/stix_relationship_types.txt +0 -0
  23. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/helpers/tlds.txt +0 -0
  24. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/helpers/windows_registry_key_prefix.txt +0 -0
  25. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/_README.md +0 -0
  26. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/_generate_lookups.py +0 -0
  27. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/attack_pattern.txt +0 -0
  28. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/campaign.txt +0 -0
  29. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/country_iso3166_alpha2.txt +0 -0
  30. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/course_of_action.txt +0 -0
  31. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/disarm_id_v1_6.txt +0 -0
  32. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/disarm_name_v1_6.txt +0 -0
  33. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/extensions.txt +0 -0
  34. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/identity.txt +0 -0
  35. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/infrastructure.txt +0 -0
  36. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/intrusion_set.txt +0 -0
  37. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/malware.txt +0 -0
  38. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_atlas_id_v4_9_0.txt +0 -0
  39. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_atlas_name_v4_9_0.txt +0 -0
  40. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_enterprise_aliases_v18_0.txt +0 -0
  41. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_enterprise_id_v18_0.txt +0 -0
  42. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_enterprise_name_v18_0.txt +0 -0
  43. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_ics_aliases_v18_0.txt +0 -0
  44. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_ics_id_v18_0.txt +0 -0
  45. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_ics_name_v18_0.txt +0 -0
  46. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_mobile_aliases_v18_0.txt +0 -0
  47. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_mobile_id_v18_0.txt +0 -0
  48. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_attack_mobile_name_v18_0.txt +0 -0
  49. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_capec_id_v3_9.txt +0 -0
  50. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_capec_name_v3_9.txt +0 -0
  51. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_cwe_id_v4_18.txt +0 -0
  52. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/mitre_cwe_name_v4_18.txt +0 -0
  53. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/sector_aliases_v1_0.txt +0 -0
  54. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/threat_actor.txt +0 -0
  55. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/tld.txt +0 -0
  56. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/lookups/tool.txt +0 -0
  57. {txt2stix-1.2.3 → txt2stix-1.2.5}/includes/tests/test_cases.yaml +0 -0
  58. {txt2stix-1.2.3 → txt2stix-1.2.5}/requirements.txt +0 -0
  59. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/README.md +0 -0
  60. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/ai_country.txt +0 -0
  61. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/ai_mitre_attack_enterprise.txt +0 -0
  62. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/ai_mitre_attack_ics.txt +0 -0
  63. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/ai_mitre_attack_mobile.txt +0 -0
  64. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/ai_mitre_capec.txt +0 -0
  65. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/ai_mitre_cwe.txt +0 -0
  66. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/all_cases.txt +0 -0
  67. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_autonomous_system_number.txt +0 -0
  68. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_all.txt +0 -0
  69. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_amex.txt +0 -0
  70. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_diners.txt +0 -0
  71. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_discover.txt +0 -0
  72. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_jcb.txt +0 -0
  73. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_mastercard.txt +0 -0
  74. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_union_pay.txt +0 -0
  75. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_bank_card_visa.txt +0 -0
  76. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_country_alpha2.txt +0 -0
  77. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cpe_uri.txt +0 -0
  78. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cryptocurrency_btc_transaction.txt +0 -0
  79. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cryptocurrency_btc_wallet.txt +0 -0
  80. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cryptocurrency_eth_transaction.txt +0 -0
  81. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cryptocurrency_eth_wallet.txt +0 -0
  82. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cryptocurrency_xmr_transaction.txt +0 -0
  83. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cryptocurrency_xmr_wallet.txt +0 -0
  84. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_cve_id.txt +0 -0
  85. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_directory_unix.txt +0 -0
  86. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_directory_unix_file.txt +0 -0
  87. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_directory_windows.txt +0 -0
  88. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_directory_windows_with_file.txt +0 -0
  89. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_disarm.txt +0 -0
  90. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_disarm_name.txt +0 -0
  91. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_domain_name_only.txt +0 -0
  92. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_domain_name_subdomain.txt +0 -0
  93. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_email_address.txt +0 -0
  94. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_file_hash_md5.txt +0 -0
  95. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_file_hash_sha_1.txt +0 -0
  96. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_file_hash_sha_224.txt +0 -0
  97. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_file_hash_sha_256.txt +0 -0
  98. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_file_hash_sha_384.txt +0 -0
  99. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_file_hash_sha_512.txt +0 -0
  100. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_file_name.txt +0 -0
  101. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_host_name.txt +0 -0
  102. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_host_name_file.txt +0 -0
  103. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_host_name_path.txt +0 -0
  104. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_host_name_subdomain.txt +0 -0
  105. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_host_name_url.txt +0 -0
  106. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_iban_number.txt +0 -0
  107. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_ipv4_address_cidr.txt +0 -0
  108. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_ipv4_address_only.txt +0 -0
  109. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_ipv4_address_port.txt +0 -0
  110. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_ipv6_address_cidr.txt +0 -0
  111. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_ipv6_address_only.txt +0 -0
  112. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_ipv6_address_port.txt +0 -0
  113. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mac_address.txt +0 -0
  114. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_atlas.txt +0 -0
  115. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_atlas_name.txt +0 -0
  116. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_enterprise.txt +0 -0
  117. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_enterprise_aliases.txt +0 -0
  118. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_enterprise_name.txt +0 -0
  119. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_ics.txt +0 -0
  120. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_ics_aliases.txt +0 -0
  121. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_ics_name.txt +0 -0
  122. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_mobile.txt +0 -0
  123. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_mobile_aliases.txt +0 -0
  124. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_attack_mobile_name.txt +0 -0
  125. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_capec.txt +0 -0
  126. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_capec_name.txt +0 -0
  127. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_cwe.txt +0 -0
  128. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_mitre_cwe_name.txt +0 -0
  129. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_phone_number.txt +0 -0
  130. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_sector_aliases.txt +0 -0
  131. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_url.txt +0 -0
  132. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_url_file.txt +0 -0
  133. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_url_path.txt +0 -0
  134. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_user_agent.txt +0 -0
  135. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/generic_windows_registry_key.txt +0 -0
  136. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_attack_pattern.txt +0 -0
  137. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_campaign.txt +0 -0
  138. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_course_of_action.txt +0 -0
  139. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_identity.txt +0 -0
  140. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_infrastructure.txt +0 -0
  141. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_intrusion_set.txt +0 -0
  142. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_malware.txt +0 -0
  143. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_threat_actor.txt +0 -0
  144. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/extraction_types/lookup_tool.txt +0 -0
  145. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/ai_index_position.txt +0 -0
  146. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/attack_flow_demo.txt +0 -0
  147. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/attack_navigator_demo.txt +0 -0
  148. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/bad_vulmatch_lookups.txt +0 -0
  149. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/basic_relationship.txt +0 -0
  150. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/char_length_too_long.txt +0 -0
  151. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/descriptive_for_ai_relationships_1.txt +0 -0
  152. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/disarm_demo.txt +0 -0
  153. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/embedded_img_ignore.txt +0 -0
  154. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/embedded_link_ignore.txt +0 -0
  155. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/ip1.txt +0 -0
  156. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/ip2.txt +0 -0
  157. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/known_whitelist_match.txt +0 -0
  158. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/mitre_attack_enterprise_ai_demo.txt +0 -0
  159. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/mitre_attack_enterprise_lookup_demo.txt +0 -0
  160. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/mixed_extractions.txt +0 -0
  161. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/not_security_content.txt +0 -0
  162. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/test_ai_hash_error_with_stix2_lib.txt +0 -0
  163. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/test_aliases.txt +0 -0
  164. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/test_extraction_boundary.txt +0 -0
  165. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/manually_generated_reports/test_extraction_escapes.txt +0 -0
  166. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/APT28-Center-of-Storm-2017.txt +0 -0
  167. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/Bitdefender-Labs-Report-X-creat6958-en-EN.txt +0 -0
  168. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/FireEyeAPT39.txt +0 -0
  169. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/France_CERT_APT31_Pakdoor_TLPWHITE.txt +0 -0
  170. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/Group-IB_Ransomware_Uncovered_whitepaper_eng.txt +0 -0
  171. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/JOINT_CSA_HUNTING_RU_INTEL_SNAKE_MALWARE_20230509.txt +0 -0
  172. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/TA22-0126-QAKBOT-analysis-TLP-GREEN.txt +0 -0
  173. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/dinners_card.txt +0 -0
  174. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/mandiant-apt1.txt +0 -0
  175. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/data/real_intel_reports/mykings_report_final.txt +0 -0
  176. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/manual-tests/cases-ai-relationships.md +0 -0
  177. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/manual-tests/cases-extraction-type-ai.md +0 -0
  178. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/manual-tests/cases-extraction-type-lookup.md +0 -0
  179. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/manual-tests/cases-extraction-type-pattern.md +0 -0
  180. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/manual-tests/cases-standard-tests.md +0 -0
  181. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/scripts/generate_simple_extraction_test_cases_txt_files.py +0 -0
  182. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/__init__.py +0 -0
  183. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_attack_flow.py +0 -0
  184. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_extractors.py +0 -0
  185. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_indicator.py +0 -0
  186. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_lookups.py +0 -0
  187. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_retriever.py +0 -0
  188. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_run_txt2stix.py +0 -0
  189. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/test_utils.py +0 -0
  190. {txt2stix-1.2.3 → txt2stix-1.2.5}/tests/src/utils.py +0 -0
  191. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/__init__.py +0 -0
  192. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/__init__.py +0 -0
  193. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/anthropic.py +0 -0
  194. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/base.py +0 -0
  195. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/deepseek.py +0 -0
  196. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/gemini.py +0 -0
  197. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/openai.py +0 -0
  198. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/openrouter.py +0 -0
  199. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/prompts.py +0 -0
  200. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/ai_extractor/utils.py +0 -0
  201. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/attack_flow.py +0 -0
  202. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/common.py +0 -0
  203. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/credential_checker.py +0 -0
  204. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/extractions.py +0 -0
  205. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/indicator.py +0 -0
  206. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/lookups.py +0 -0
  207. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/__init__.py +0 -0
  208. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/__init__.py +0 -0
  209. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/base_extractor.py +0 -0
  210. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/README.md +0 -0
  211. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/__init__.py +0 -0
  212. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/amex_card_extractor.py +0 -0
  213. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/diners_card_extractor.py +0 -0
  214. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/discover_card_extractor.py +0 -0
  215. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/jcb_card_extractor.py +0 -0
  216. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/master_card_extractor.py +0 -0
  217. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/union_card_extractor.py +0 -0
  218. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/card/visa_card_extractor.py +0 -0
  219. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/crypto/__init__.py +0 -0
  220. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/crypto/btc_extractor.py +0 -0
  221. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/directory/__init__.py +0 -0
  222. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/directory/unix_directory_extractor.py +0 -0
  223. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/directory/unix_file_path_extractor.py +0 -0
  224. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/directory/windows_directory_path_extractor.py +0 -0
  225. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/directory/windows_file_path_extractor.py +0 -0
  226. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/domain/__init__.py +0 -0
  227. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/domain/domain_extractor.py +0 -0
  228. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/domain/hostname_extractor.py +0 -0
  229. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/domain/sub_domain_extractor.py +0 -0
  230. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/__init__.py +0 -0
  231. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/md5_extractor.py +0 -0
  232. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/sha1_extractor.py +0 -0
  233. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/sha224_extractor.py +0 -0
  234. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/sha2_256_exactor.py +0 -0
  235. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/sha2_512_exactor.py +0 -0
  236. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/sha3_256_exactor.py +0 -0
  237. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/hashes/sha3_512_exactor.py +0 -0
  238. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/helper.py +0 -0
  239. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/ip/__init__.py +0 -0
  240. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/ip/ipv4_cidr_extractor.py +0 -0
  241. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/ip/ipv4_extractor.py +0 -0
  242. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/ip/ipv4_port_extractor.py +0 -0
  243. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/ip/ipv6_cidr_extractor.py +0 -0
  244. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/ip/ipv6_extractor.py +0 -0
  245. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/ip/ipv6_port_extractor.py +0 -0
  246. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/__init__.py +0 -0
  247. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/asn_extractor.py +0 -0
  248. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/cpe_extractor.py +0 -0
  249. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/cve_extractor.py +0 -0
  250. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/email_extractor.py +0 -0
  251. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/filename_extractor.py +0 -0
  252. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/iban_extractor.py +0 -0
  253. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/mac_address_extractor.py +0 -0
  254. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/phonenumber_extractor.py +0 -0
  255. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/user_agent_extractor.py +0 -0
  256. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/others/windows_registry_key_extractor.py +0 -0
  257. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/url/__init__.py +0 -0
  258. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/url/url_extractor.py +0 -0
  259. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/url/url_file_extractor.py +0 -0
  260. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/pattern/extractors/url/url_path_extractor.py +0 -0
  261. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/retriever.py +0 -0
  262. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/stix.py +0 -0
  263. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix/utils.py +0 -0
  264. {txt2stix-1.2.3 → txt2stix-1.2.5}/txt2stix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: txt2stix
3
- Version: 1.2.3
3
+ Version: 1.2.5
4
4
  Summary: txt2stix is a Python script that is designed to identify and extract IoCs and TTPs from text files, identify the relationships between them, convert them to STIX 2.1 objects, and output as a STIX 2.1 bundle.
5
5
  Project-URL: Homepage, https://github.com/muchdogesec/txt2stix
6
6
  Project-URL: Issues, https://github.com/muchdogesec/txt2stix/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "txt2stix"
7
- version = "1.2.3"
7
+ version = "1.2.5"
8
8
  authors = [{ name = "dogesec" }]
9
9
  maintainers = [{ name = "dogesec" }]
10
10
  description = "txt2stix is a Python script that is designed to identify and extract IoCs and TTPs from text files, identify the relationships between them, convert them to STIX 2.1 objects, and output as a STIX 2.1 bundle."
@@ -114,6 +114,20 @@ def test_add_indicator(bundler):
114
114
  assert bundler.id_map[extracted_dict["id"]] == mocked_related_refs
115
115
 
116
116
 
117
+ def test_add_indicator_rejects_empty_values(bundler):
118
+ """Test that add_indicator raises MinorException for None or empty extracted values."""
119
+ extracted_dict_empty = {
120
+ "id": "ex-1",
121
+ "type": "test_type",
122
+ "value": ""
123
+ }
124
+ mocked_extractor = MagicMock()
125
+ bundler.all_extractors = dict(test_type=mocked_extractor)
126
+
127
+ with pytest.raises(MinorException, match="extracted value is empty"):
128
+ bundler.add_indicator(extracted_dict_empty, add_standard_relationship=False)
129
+
130
+
117
131
  def test_add_indicator_sets_id_map():
118
132
  extractor = MagicMock()
119
133
  extractor.stix_mapping = "domain-name"
@@ -30,8 +30,10 @@ from txt2stix.txt2stix import (
30
30
  processing_phase,
31
31
  run_extractors,
32
32
  extract_relationships,
33
+ validate_token_count,
33
34
  )
34
- from txt2stix.common import FatalException
35
+ from txt2stix.common import FatalException, MinorException
36
+ from txt2stix.bundler import txt2stixBundler
35
37
  import argparse
36
38
 
37
39
 
@@ -419,7 +421,9 @@ def test_processing_phase_applies_extracts_and_relationships():
419
421
  preprocessed_text = "SOME TEXT"
420
422
  # prepare data object similar to Txt2StixData
421
423
  data = SimpleNamespace()
422
- data.extractions = {'lookup': ['l1'], 'pattern': ['p1']}
424
+ mock1 = {"name": "observable1", "error": "some error"}
425
+ mock2 = {"name": "observable2", "error": "some error"}
426
+ data.extractions = {'lookup': [mock1], 'pattern': [mock2]}
423
427
  data.relationships = {'relationships': ['r1']}
424
428
  data.content_check = None
425
429
 
@@ -428,6 +432,97 @@ def test_processing_phase_applies_extracts_and_relationships():
428
432
 
429
433
  processing_phase(bundler, preprocessed_text, data, ai_create_attack_flow=False, ai_create_attack_navigator_layer=False)
430
434
 
431
- bundler.process_observables.assert_any_call(['l1'])
432
- bundler.process_observables.assert_any_call(['p1'])
433
- bundler.process_relationships.assert_called_once_with(['r1'])
435
+ bundler.process_observables.assert_any_call([mock1])
436
+ bundler.process_observables.assert_any_call([mock2])
437
+ assert "error" not in mock2 # ensure no error field removal in this test
438
+ assert "error" not in mock1 # ensure no error field removal in this test
439
+ bundler.process_relationships.assert_called_once_with(['r1'])
440
+
441
+
442
+ def test_run_extractors():
443
+ """Test run_extractors returns dict with id fields and handles AI extractor failures."""
444
+ text_content = "SAMPLE TEXT"
445
+ extractors_map = {
446
+ 'lookup': {'lookup1': MagicMock()},
447
+ 'pattern': {'pattern1': MagicMock()},
448
+ 'ai': {'ai1': MagicMock()}
449
+ }
450
+
451
+ mock_ai_extractor1 = MagicMock()
452
+ mock_ai_extractor1.extractor_name = "ai_extractor_1"
453
+ mock_ai_extractor1.extract_objects.return_value = [{'type': 'ipv4', 'value': '1.1.1.1'}]
454
+
455
+ mock_ai_extractor2 = MagicMock()
456
+ mock_ai_extractor2.extractor_name = "ai_extractor_2"
457
+ mock_ai_extractor2.extract_objects.side_effect = Exception("AI extraction failed")
458
+
459
+ with patch('txt2stix.txt2stix.lookups.extract_all') as mock_lookup, \
460
+ patch('txt2stix.txt2stix.pattern.extract_all') as mock_pattern:
461
+
462
+ mock_lookup.return_value = [{'type': 'domain', 'value': 'example.com'}]
463
+ mock_pattern.return_value = [{'type': 'url', 'value': 'http://test.com'}]
464
+
465
+ result = run_extractors(extractors_map, text_content, ai_extractors=[mock_ai_extractor1, mock_ai_extractor2])
466
+
467
+ # Verify lookup and pattern were called
468
+ assert 'lookup' in result
469
+ assert 'pattern' in result
470
+ assert 'ai-ai_extractor_1' in result
471
+
472
+ # Verify all extracts have 'id' field
473
+ all_extracts = []
474
+ for extracts in result.values():
475
+ all_extracts.extend(extracts)
476
+
477
+ for i, extract in enumerate(all_extracts):
478
+ assert 'id' in extract
479
+ assert extract['id'].startswith('ex-')
480
+
481
+ # Verify AI extractor 2 failure was handled (should not be in results)
482
+ assert 'ai-ai_extractor_2' not in result
483
+
484
+
485
+ def test_extract_relationships():
486
+ """Test extract_relationships calls AI session and handles exceptions."""
487
+ text = "TEXT_CONTENT"
488
+ all_extracts = {"lookup": [{'id': 'ex-0'}, {'id': 'ex-1'}], "ai": [{'id': 'ex-2'}, {'id': 'ex-3'}]}
489
+ mock_ai_session = MagicMock()
490
+ mock_ai_session.extract_relationships.return_value.model_dump.return_value = {
491
+ "relationships": [{'source': 'ex-0', 'target': 'ex-2'}]
492
+ }
493
+
494
+ relationships = extract_relationships(text, all_extracts, mock_ai_session)
495
+
496
+ # Verify extract_relationships was called with flattened list
497
+ called_args = mock_ai_session.extract_relationships.call_args
498
+ assert len(called_args[0][1]) == 4 # flattened list of 4 extracts
499
+ assert called_args[0][2] == RELATIONSHIP_TYPES
500
+
501
+ mock_ai_session.extract_relationships.return_value.model_dump.assert_called()
502
+ assert relationships == {"relationships": [{'source': 'ex-0', 'target': 'ex-2'}]}
503
+
504
+ # Test exception handling - should return None
505
+ mock_ai_session.extract_relationships.side_effect = Exception("AI failed")
506
+ assert extract_relationships(text, all_extracts, mock_ai_session) is None
507
+
508
+
509
+ def test_validate_token_count():
510
+ """Test validate_token_count raises FatalException when limit exceeded."""
511
+
512
+ # Test case 1: Should not raise when under limit
513
+ mock_extractor1 = MagicMock()
514
+ mock_extractor1.extractor_name = "test_extractor_under_limit"
515
+ mock_extractor1.count_tokens.return_value = 500
516
+
517
+ # Use different input text to avoid lru_cache collision
518
+ validate_token_count(1000, "test input 1", [mock_extractor1])
519
+
520
+ # Test case 2: Should raise when over limit
521
+ mock_extractor2 = MagicMock()
522
+ mock_extractor2.extractor_name = "test_extractor_over_limit"
523
+ mock_extractor2.count_tokens.return_value = 1500
524
+
525
+ with pytest.raises(FatalException, match="exceeds INPUT_TOKEN_LIMIT"):
526
+ # Use different input text to avoid lru_cache collision
527
+ validate_token_count(1000, "test input 2", [mock_extractor2])
528
+
@@ -307,6 +307,9 @@ class txt2stixBundler:
307
307
  extracted_value = extracted_dict["value"]
308
308
  extracted_id = extracted_dict["id"]
309
309
 
310
+ if extracted_value is None or extracted_value == "":
311
+ raise MinorException(f"extracted value is empty")
312
+
310
313
  indicator = self.new_indicator(extractor, stix_mapping, extracted_value)
311
314
  # set id so it doesn''t need to be created in build_observables
312
315
  if extracted_dict.get("indexes"):
@@ -556,6 +556,8 @@ def processing_phase(
556
556
  ai_content_check_provider=None,
557
557
  ):
558
558
  """Process extracted `data` into the given `bundler` without invoking LLMs."""
559
+ for d in itertools.chain([], *(data.extractions or {}).values()):
560
+ d.pop("error", None)
559
561
  try:
560
562
  if data.content_check:
561
563
  cc = data.content_check
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes