codeaudit 1.9.2__tar.gz → 1.9.3__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 (277) hide show
  1. {codeaudit-1.9.2 → codeaudit-1.9.3}/CHANGELOG.md +16 -0
  2. {codeaudit-1.9.2 → codeaudit-1.9.3}/PKG-INFO +3 -2
  3. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/codeauditcommands.md +1 -1
  4. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/ca_api_example_scanning.ipynb +1 -1
  5. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/codeauditchecks.html +2 -2
  6. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/demoscan.json +2 -2
  7. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/makeitbetter.md +13 -1
  8. {codeaudit-1.9.2 → codeaudit-1.9.3}/pyproject.toml +5 -4
  9. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/__about__.py +1 -1
  10. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/altairplots.py +7 -29
  11. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/api_interfaces.py +29 -11
  12. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/api_reporting.py +23 -7
  13. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/data/sastchecks.csv +1 -1
  14. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/dashboardapp.py +137 -36
  15. codeaudit-1.9.3/src/dashboard/pyodide/dashboardapp_192.html +299 -0
  16. codeaudit-1.9.3/src/dashboard/pyodide/dashboardapp_fixedTMPfor_v1.9.0.js +91 -0
  17. codeaudit-1.9.3/src/dashboard/pyodide/deployed/dashboardapp_192.html +299 -0
  18. codeaudit-1.9.3/src/dashboard/pyodide/deployed/dashboardapp_fixedTMPfor_v1.9.0.js +91 -0
  19. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/unit_tests/test_count_weaknesses.py +12 -0
  20. codeaudit-1.9.3/tests/unit_tests/test_get_weakness_counts.py +495 -0
  21. codeaudit-1.9.3/tests/validationfiles/zip_example.json +144 -0
  22. {codeaudit-1.9.2 → codeaudit-1.9.3}/.github/workflows/python-test.yml +0 -0
  23. {codeaudit-1.9.2 → codeaudit-1.9.3}/.github/workflows/sast_validation.yml +0 -0
  24. {codeaudit-1.9.2 → codeaudit-1.9.3}/.gitignore +0 -0
  25. {codeaudit-1.9.2 → codeaudit-1.9.3}/CONTRIBUTE.md +0 -0
  26. {codeaudit-1.9.2 → codeaudit-1.9.3}/LICENSE.txt +0 -0
  27. {codeaudit-1.9.2 → codeaudit-1.9.3}/README.md +0 -0
  28. {codeaudit-1.9.2 → codeaudit-1.9.3}/SECURITY.md +0 -0
  29. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/.gitignore +0 -0
  30. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/class_index.html +0 -0
  31. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/coverage_html_cb_dd2e7eb5.js +0 -0
  32. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/favicon_32_cb_c827f16f.png +0 -0
  33. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/function_index.html +0 -0
  34. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/index.html +0 -0
  35. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/keybd_closed_cb_900cfef5.png +0 -0
  36. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/status.json +0 -0
  37. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/style_cb_9ff733b0.css +0 -0
  38. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8___about___py.html +0 -0
  39. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8___init___py.html +0 -0
  40. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_altairplots_py.html +0 -0
  41. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_api_helpers_py.html +0 -0
  42. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_api_interfaces_py.html +0 -0
  43. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_api_reporting_py.html +0 -0
  44. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_checkmodules_py.html +0 -0
  45. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_codeaudit_dashboard_py.html +0 -0
  46. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_codeaudit_py.html +0 -0
  47. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_complexitycheck_py.html +0 -0
  48. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_dashboard_reports_py.html +0 -0
  49. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_filehelpfunctions_py.html +0 -0
  50. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_htmlhelpfunctions_py.html +0 -0
  51. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_issuevalidations_py.html +0 -0
  52. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_privacy_lint_py.html +0 -0
  53. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_pypi_package_scan_py.html +0 -0
  54. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_reporting_py.html +0 -0
  55. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_security_checks_py.html +0 -0
  56. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_suppression_py.html +0 -0
  57. {codeaudit-1.9.2 → codeaudit-1.9.3}/cov_html/z_15dab3f49bf85fa8_totals_py.html +0 -0
  58. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/CLIcommands.ipynb +0 -0
  59. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/CONTRIBUTE.md +0 -0
  60. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/_config.yml +0 -0
  61. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/_static/nocxstyle.css +0 -0
  62. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/_toc.yml +0 -0
  63. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/about.md +0 -0
  64. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/apidocs/api_intro.md +0 -0
  65. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/apidocs/codeaudit.rst +0 -0
  66. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/apidocs/modules.rst +0 -0
  67. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/architecture.md +0 -0
  68. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/changelog.md +0 -0
  69. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/assert_check.md +0 -0
  70. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/base64_check.md +0 -0
  71. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/binding_check.md +0 -0
  72. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/builtinfunctions_check.md +0 -0
  73. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/chmod_check.md +0 -0
  74. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/directorycreation_check.md +0 -0
  75. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/dynamicimport_check.md +0 -0
  76. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/exception_check.md +0 -0
  77. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/ftp_check.md +0 -0
  78. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/hash_check.md +0 -0
  79. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/httpserver_check.md +0 -0
  80. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/input_check.md +0 -0
  81. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/loggingconf_check.md +0 -0
  82. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/marshal_check.md +0 -0
  83. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/mktemp_check.md +0 -0
  84. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/multiprocessing_check.md +0 -0
  85. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/pickle_check.md +0 -0
  86. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/random_check.md +0 -0
  87. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/shelve_check.md +0 -0
  88. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/shutil_check.md +0 -0
  89. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/subprocess_check.md +0 -0
  90. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/syscalls_check.md +0 -0
  91. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/systemcalls_check.md +0 -0
  92. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/tarfile_extract_check.md +0 -0
  93. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/xml_check.md +0 -0
  94. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checks/zipfile_check.md +0 -0
  95. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/checksinformation.md +0 -0
  96. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/cimode.md +0 -0
  97. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/codeauditchecks.md +0 -0
  98. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/codeauditoverview.md +0 -0
  99. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/complexitycheck.md +0 -0
  100. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/data_egress_implementation.md +0 -0
  101. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/data_exfiltration_detection.md +0 -0
  102. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/ca_api_example_basic.ipynb +0 -0
  103. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/ca_api_example_checks.ipynb +0 -0
  104. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/ca_api_example_json.ipynb +0 -0
  105. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/ca_api_example_overview.ipynb +0 -0
  106. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/ca_checks.ipynb +0 -0
  107. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/demofile.py +0 -0
  108. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/directoryscan.html +0 -0
  109. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/example_risk_heatmap.ipynb +0 -0
  110. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/example_weakness_perfile_view.ipynb +0 -0
  111. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/filescan.html +0 -0
  112. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/modulescan.html +0 -0
  113. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/examples/overview.html +0 -0
  114. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/features.md +0 -0
  115. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/filescan.md +0 -0
  116. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/filescan.png +0 -0
  117. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/handling_errors.md +0 -0
  118. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/help.md +0 -0
  119. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/howtoscan.md +0 -0
  120. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/OO.png +0 -0
  121. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/ROI_logo.png +0 -0
  122. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/YourLogoHere.png +0 -0
  123. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/ai_use.png +0 -0
  124. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/architecture_overview.png +0 -0
  125. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/codeauditlogo.png +0 -0
  126. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/filescan_screenshot_16012026.png +0 -0
  127. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/modulescan_screenshot_16012026.png +0 -0
  128. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/nocxbanner.png +0 -0
  129. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/overview_linkaudit.png +0 -0
  130. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/images/overview_screenshot_16012026.png +0 -0
  131. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/implementedvalidations.md +0 -0
  132. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/installation.md +0 -0
  133. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/intro.md +0 -0
  134. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/issues.md +0 -0
  135. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/license.md +0 -0
  136. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/markingissues.md +0 -0
  137. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/modulescan.md +0 -0
  138. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/overviewplot.png +0 -0
  139. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/pca_overview.png +0 -0
  140. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/project_philosophy.md +0 -0
  141. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/sponsors.md +0 -0
  142. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/userguide.md +0 -0
  143. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/warnings.md +0 -0
  144. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/whatissast.md +0 -0
  145. {codeaudit-1.9.2 → codeaudit-1.9.3}/docs/whysast.md +0 -0
  146. {codeaudit-1.9.2 → codeaudit-1.9.3}/filescan.png +0 -0
  147. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/__init__.py +0 -0
  148. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/api_helpers.py +0 -0
  149. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/checkmodules.py +0 -0
  150. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/ci_workflowscan.py +0 -0
  151. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/complexitycheck.py +0 -0
  152. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/corecli.py +0 -0
  153. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/dashboard_reports.py +0 -0
  154. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/data/secretslist.txt +0 -0
  155. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/filehelpfunctions.py +0 -0
  156. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/htmlhelpfunctions.py +0 -0
  157. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/issuevalidations.py +0 -0
  158. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/privacy_lint.py +0 -0
  159. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/pypi_package_scan.py +0 -0
  160. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/reporting.py +0 -0
  161. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/security_checks.py +0 -0
  162. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/simple.css +0 -0
  163. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/suppression.py +0 -0
  164. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/codeaudit/totals.py +0 -0
  165. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/__init__.py +0 -0
  166. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/module_load_validation.html +0 -0
  167. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/module_load_validation2.html +0 -0
  168. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_171.html +0 -0
  169. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_171.js +0 -0
  170. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_190.html +0 -0
  171. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_190.js +0 -0
  172. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_191.html +0 -0
  173. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_191.js +0 -0
  174. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_version162.html +0 -0
  175. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_version162.js +0 -0
  176. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_version166.html +0 -0
  177. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/dashboardapp_version166.js +0 -0
  178. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/deployed/dashboardapp_171.html +0 -0
  179. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/deployed/dashboardapp_171.js +0 -0
  180. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/deployed/dashboardapp_180.html +0 -0
  181. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/pyodide/deployed/dashboardapp_180.js +0 -0
  182. /codeaudit-1.9.2/src/dashboard/pyodide/deployed/dashboardapp.html → /codeaudit-1.9.3/src/dashboard/pyodide/deployed/dashboardapp_191.html +0 -0
  183. /codeaudit-1.9.2/src/dashboard/pyodide/deployed/dashboardapp.js → /codeaudit-1.9.3/src/dashboard/pyodide/deployed/dashboardapp_191.js +0 -0
  184. {codeaudit-1.9.2 → codeaudit-1.9.3}/src/dashboard/requirements.txt +0 -0
  185. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/__init__.py +0 -0
  186. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/count_lines_file1.py +0 -0
  187. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/spytestdir/clean.py +0 -0
  188. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/spytestdir/elastic.py +0 -0
  189. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/spytestdir/example1.py +0 -0
  190. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/spytestdir/klyne.py +0 -0
  191. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/spytestdir/mixed.py +0 -0
  192. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/spytestdir/telemetry.py +0 -0
  193. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/spytestdir/telemetryfile2.py +0 -0
  194. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/suppression/sastsuppression_0.py +0 -0
  195. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/suppression/sastsuppression_1.py +0 -0
  196. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/suppression/sastsuppression_2.py +0 -0
  197. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_apicalls.py +0 -0
  198. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_apicalls2.py +0 -0
  199. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_base64.py +0 -0
  200. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_basicpatterns.py +0 -0
  201. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_chmod.py +0 -0
  202. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_constructspart2.py +0 -0
  203. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_correctexceptionuse.py +0 -0
  204. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_count_commentlines.py +0 -0
  205. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_directorycreation.py +0 -0
  206. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_directorycreation2.py +0 -0
  207. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_dynamic_import.py +0 -0
  208. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_edgecases.py +0 -0
  209. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_filescan_api.py +0 -0
  210. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_ftp.py +0 -0
  211. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_hashstrenght.py +0 -0
  212. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_importlib_util.py +0 -0
  213. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_modulecheck.py +0 -0
  214. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_obfuscatingbuiltins.py +0 -0
  215. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_oschecks.py +0 -0
  216. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_pylintreport.py +0 -0
  217. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_pypiscan.py +0 -0
  218. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_random.py +0 -0
  219. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_secretfinding.py +0 -0
  220. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_standardlibconstructs.py +0 -0
  221. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_subprocess.py +0 -0
  222. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_suppression.py +0 -0
  223. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_suppressionlogic.py +0 -0
  224. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_totalscheck.py +0 -0
  225. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_valid_python.py +0 -0
  226. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_wasmsafe_funtions.py +0 -0
  227. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/test_zstd.py +0 -0
  228. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/unit_tests/__init__.py +0 -0
  229. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/unit_tests/test_clean_import_list.py +0 -0
  230. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/unit_tests/test_collectsourcefiles.py +0 -0
  231. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/unit_tests/test_filehelpfunctions.py +0 -0
  232. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/unit_tests/test_readinsourcefile.py +0 -0
  233. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/allshit.py +0 -0
  234. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/apivalidations.py +0 -0
  235. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/assert.py +0 -0
  236. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/base64.py +0 -0
  237. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/chmod_things.py +0 -0
  238. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/codeaudit_scan.json +0 -0
  239. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/complexitycheck.py +0 -0
  240. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/correctcounts.py +0 -0
  241. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/danger_imports.py +0 -0
  242. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/directorycreation.py +0 -0
  243. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/directorycreation2.py +0 -0
  244. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/dunderexec_with_parsing_error.py +0 -0
  245. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/eval.py +0 -0
  246. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/eval2.py +0 -0
  247. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/exception.py +0 -0
  248. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/file3.py +0 -0
  249. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/file_with_warnings.py +0 -0
  250. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/ftp.py +0 -0
  251. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/gzip.py +0 -0
  252. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/hashcheck.py +0 -0
  253. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/httpserver.py +0 -0
  254. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/incorrect_python_file.py +0 -0
  255. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/inputstatement.py +0 -0
  256. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/linkaudit-0.9.9.tar.gz +0 -0
  257. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/malware.py +0 -0
  258. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/malwareAI.py +0 -0
  259. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/marshal.py +0 -0
  260. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/modulecheck.py +0 -0
  261. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/multiprocessing.py +0 -0
  262. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/obfuscating.py +0 -0
  263. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/oschecks.py +0 -0
  264. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/pickle.py +0 -0
  265. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/python2_file_willnotwork.py +0 -0
  266. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/random.py +0 -0
  267. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/shelve.py +0 -0
  268. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/shutil.py +0 -0
  269. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/subprocess.py +0 -0
  270. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/syslibrary.py +0 -0
  271. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/tarfilevalidation.py +0 -0
  272. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/tempcheck.py +0 -0
  273. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/validation1.py +0 -0
  274. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/validation2.py +0 -0
  275. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/xml.py +0 -0
  276. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/zipfile.py +0 -0
  277. {codeaudit-1.9.2 → codeaudit-1.9.3}/tests/validationfiles/zstd.py +0 -0
@@ -1,5 +1,21 @@
1
1
  # Change Log
2
2
 
3
+ ## Version 1.9.3:
4
+
5
+ **Changed**
6
+
7
+ * Updated functions `weaknesses_overview` and `total_weaknesses`.
8
+
9
+ **Fixed**
10
+
11
+ * Fixed issue in API function `get_weakness_counts` and included extra tests.
12
+ * Corrected severity for the `input` function.
13
+
14
+ **Documentation**
15
+ * Validated and documented correct working and compatibility for Python 3.15.
16
+
17
+
18
+
3
19
  ## Version 1.9.2:
4
20
 
5
21
  * Fixed issue for API scan
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: codeaudit
3
- Version: 1.9.2
3
+ Version: 1.9.3
4
4
  Summary: A modern Python security source code analyzer (SAST) based on distrust.
5
5
  Project-URL: Homepage, https://codeaudit.nocomplexity.com
6
6
  Project-URL: Documentation, https://github.com/nocomplexity/codeaudit#readme
@@ -18,6 +18,7 @@ Classifier: Programming Language :: Python
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Programming Language :: Python :: 3.15
21
22
  Classifier: Topic :: Security
22
23
  Classifier: Topic :: Software Development :: Quality Assurance
23
24
  Requires-Python: >=3.12
@@ -1,6 +1,6 @@
1
1
  % THIS FILE IS GENERATED! - Use CLIcommands.ipynb to make it better!
2
2
  # Commands Overview
3
- Python Code Audit commands for: version: 1.9.2
3
+ Python Code Audit commands for: version: 1.9.3
4
4
  ```
5
5
  ----------------------------------------------------
6
6
  _ __ _
@@ -197,7 +197,7 @@
197
197
  "name": "python",
198
198
  "nbconvert_exporter": "python",
199
199
  "pygments_lexer": "ipython3",
200
- "version": "3.14.7"
200
+ "version": "3.14.8"
201
201
  }
202
202
  },
203
203
  "nbformat": 4,
@@ -422,7 +422,7 @@ footer {
422
422
  <tr>
423
423
  <td>Input Function</td>
424
424
  <td>input</td>
425
- <td>Low</td>
425
+ <td>High</td>
426
426
  <td>User input must be strictly sanitized and validated to prevent injection vulnerabilities.</td>
427
427
  </tr>
428
428
  <tr>
@@ -774,4 +774,4 @@ footer {
774
774
  <td>Vulnerable to path traversal attacks if used with untrusted archives.</td>
775
775
  </tr>
776
776
  </tbody>
777
- </table><br><p>Number of implemented security validations:<b>89</b></p><p>Version of codeaudit: <b>1.9.2</b><p>Because Python and cybersecurity are constantly changing, issue reports <b>SHOULD</b> specify the codeaudit version used.</p><p><b>Disclaimer:</b> <i>This SAST tool <a href="https://github.com/nocomplexity/codeaudit" target="_blank"><b>Python Code Audit</b></a> provides a powerful, automatic security analysis for Python source code. However, it's not a substitute for human review in combination with business knowledge. Undetected vulnerabilities may still exist.</i></p><p>This Python security report was created on: <b>2026-10-09 19:31</b> with <a href="https://github.com/nocomplexity/codeaudit" target="_blank"><b>Python Code Audit</b></a> version <b>1.9.2</b></p><hr><footer><div class="footer-links">Check the <a href="https://nocomplexity.com/documents/codeaudit/intro.html" target="_blank">documentation</a> for help on found issues.<br>Codeaudit is made with <span class="heart">&#10084;</span> by cyber security professionals who advocate for <a href="https://nocomplexity.com/simplify-security/" target="_blank">open simple security solutions</a>.<br><a href="https://nocomplexity.com/documents/codeaudit/CONTRIBUTE.html" target="_blank">Join the community</a> and contribute to make this tool better!</div></footer></div></body></html>
777
+ </table><br><p>Number of implemented security validations:<b>89</b></p><p>Version of codeaudit: <b>1.9.3</b><p>Because Python and cybersecurity are constantly changing, issue reports <b>SHOULD</b> specify the codeaudit version used.</p><p><b>Disclaimer:</b> <i>This SAST tool <a href="https://github.com/nocomplexity/codeaudit" target="_blank"><b>Python Code Audit</b></a> provides a powerful, automatic security analysis for Python source code. However, it's not a substitute for human review in combination with business knowledge. Undetected vulnerabilities may still exist.</i></p><p>This Python security report was created on: <b>2026-10-30 18:27</b> with <a href="https://github.com/nocomplexity/codeaudit" target="_blank"><b>Python Code Audit</b></a> version <b>1.9.3</b></p><hr><footer><div class="footer-links">Check the <a href="https://nocomplexity.com/documents/codeaudit/intro.html" target="_blank">documentation</a> for help on found issues.<br>Codeaudit is made with <span class="heart">&#10084;</span> by cyber security professionals who advocate for <a href="https://nocomplexity.com/simplify-security/" target="_blank">open simple security solutions</a>.<br><a href="https://nocomplexity.com/documents/codeaudit/CONTRIBUTE.html" target="_blank">Join the community</a> and contribute to make this tool better!</div></footer></div></body></html>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "Python_Code_Audit",
3
- "version": "1.9.2",
4
- "generated_on": "2026-10-09 19:31",
3
+ "version": "1.9.3",
4
+ "generated_on": "2026-10-30 18:27",
5
5
  "file_security_info": {
6
6
  "0": {
7
7
  "FileName": "demofile.py",
@@ -38,6 +38,16 @@ To lower the barrier for new contributors, I'd make the tone more welcoming, red
38
38
 
39
39
  Welcome! This guide will help you set up a local development environment for Python Code Audit and start contributing to the project.
40
40
 
41
+ ### 0. Create and activate an new environment
42
+
43
+ I prefer using [`conda`](https://nocomplexity.com/documents/pythonbook/environments.html#environments) but use what you want.
44
+
45
+ Set up a new environment:
46
+ ```bash
47
+ conda create --name codeaudit_dev python=3.15
48
+ ```
49
+
50
+
41
51
  ### 1. Clone the repository
42
52
 
43
53
  We recommend working in a dedicated virtual environment to avoid conflicts with other Python projects.
@@ -48,14 +58,16 @@ The Python Code Audit source code is hosted on GitHub.
48
58
  ```bash
49
59
  git clone https://github.com/nocomplexity/codeaudit
50
60
  cd codeaudit
61
+ pip install -e .
51
62
  ```
52
63
 
64
+
53
65
  ### 2. Install development dependencies
54
66
 
55
67
  Install `pytest`, which is used for running the test suite:
56
68
 
57
69
  ```bash
58
- pip install pytest
70
+ pip install -U pytest
59
71
  ```
60
72
 
61
73
  ### 3. Install Hatch
@@ -25,6 +25,7 @@ classifiers = [
25
25
  "Programming Language :: Python :: 3.12",
26
26
  "Programming Language :: Python :: 3.13",
27
27
  "Programming Language :: Python :: 3.14",
28
+ "Programming Language :: Python :: 3.15",
28
29
  ]
29
30
 
30
31
  [project.optional-dependencies]
@@ -57,14 +58,14 @@ extra-dependencies = [
57
58
  check = "mypy --install-types --non-interactive {args:src/codeaudit tests}"
58
59
 
59
60
  [[tool.hatch.envs.hatch-test.matrix]]
60
- python = ["3.14", "3.13", "3.12"]
61
+ python = ["3.15", "3.14", "3.13", "3.12"]
61
62
 
62
63
  [tool.hatch.envs.hatch-test]
63
64
  randomize = true
64
65
  dependencies = ["pytest", "pytest-cov", "coverage"]
65
66
 
66
67
  [tool.black]
67
- target-version = ["py311", "py312", "py313", "py314"]
68
+ target-version = ["py312", "py313", "py314","py315"]
68
69
  extend-exclude ='(python2_file_willnotwork|dunderexec_with_parsing_error).py|validationfiles|suppression|spytestdir'
69
70
 
70
71
  [tool.coverage.run]
@@ -78,8 +79,8 @@ show_missing = true
78
79
  dependencies = ["black", "pylint"]
79
80
 
80
81
  [tool.hatch.envs.hatch-static-analysis.scripts]
81
- format-check = "black --target-version py313 --check src tests"
82
- format-fix = "black --target-version py313 src tests"
82
+ format-check = "black --target-version py314 --check src tests"
83
+ format-fix = "black --target-version py314 src tests"
83
84
  lint-check = "pylint src tests"
84
85
 
85
86
  [tool.pytest]
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Maikel Mardjan
2
2
  #
3
3
  # SPDX-License-Identifier: GPL-3.0-or-later
4
- __version__ = "1.9.2"
4
+ __version__ = "1.9.3"
@@ -18,7 +18,8 @@ import pandas as pd
18
18
 
19
19
  from collections import Counter
20
20
  from pathlib import Path
21
-
21
+ from codeaudit.api_interfaces import get_weakness_counts
22
+ from codeaudit.api_reporting import total_weaknesses
22
23
 
23
24
  def module_count_barchart(scanresult):
24
25
  """Create a bar chart showing module counts by category.
@@ -689,20 +690,8 @@ def weaknesses_overview(scanresult):
689
690
  .mark_text()
690
691
  .encode(text="msg:N")
691
692
  )
692
-
693
- # --- Count every 'validation' across all files ---
694
- counter = Counter()
695
- for file_info in file_security_info.values():
696
- if not isinstance(file_info, dict):
697
- continue
698
- sast_result = file_info.get("sast_result")
699
- if not isinstance(sast_result, dict):
700
- continue
701
- for finding in sast_result.values():
702
- if isinstance(finding, dict):
703
- validation = finding.get("validation")
704
- if validation and isinstance(validation, str):
705
- counter[validation] += 1
693
+ # --- Count every validation across all files ---
694
+ counter = Counter(get_weakness_counts(scanresult))
706
695
 
707
696
  if not counter:
708
697
  return (
@@ -875,7 +864,7 @@ def sast_files_overview(scanresult):
875
864
  "base_name": base_name,
876
865
  "parent_folder": parent_folder,
877
866
  "full_path": str(filepath),
878
- "issues": len(sast_result),
867
+ "issues": total_weaknesses(scanresult),
879
868
  "complexity": file_info.get("Complexity_Score", 0),
880
869
  }
881
870
  )
@@ -977,19 +966,8 @@ def weaknesses_radial_overview(scanresult):
977
966
  )
978
967
 
979
968
  # --- Count every 'validation' across all files ---
980
- counter = Counter()
981
- for file_info in file_security_info.values():
982
- if not isinstance(file_info, dict):
983
- continue
984
- sast_result = file_info.get("sast_result")
985
- if not isinstance(sast_result, dict):
986
- continue
987
- for finding in sast_result.values():
988
- if isinstance(finding, dict):
989
- validation = finding.get("validation")
990
- if validation and isinstance(validation, str):
991
- counter[validation] += 1
992
-
969
+ counter = Counter(get_weakness_counts(scanresult))
970
+
993
971
  if not counter:
994
972
  return (
995
973
  alt.Chart(
@@ -315,38 +315,56 @@ def read_input_file(filename, safe_directory="data_folder"):
315
315
 
316
316
  def get_weakness_counts(input_file, nosec=False):
317
317
  """
318
- Analyze a Python file or package and count occurrences of code weaknesses.
318
+ Count SAST weaknesses.
319
+
320
+ Accepts either:
321
+ - A scan result dictionary.
322
+ - A file/package path that will be scanned.
319
323
  """
320
- # Assuming filescan is imported from codeaudit.api_interfaces
321
- scan_result = filescan(input_file, nosec)
324
+
325
+ # Accept an existing scan result or scan a file/package
326
+ if isinstance(input_file, dict):
327
+ scan_result = input_file
328
+ else:
329
+ scan_result = filescan(input_file, nosec)
322
330
 
323
331
  if not isinstance(scan_result, dict):
324
- raise ValueError("filescan() did not return a valid result dictionary")
332
+ raise ValueError("Invalid scan result")
325
333
 
326
334
  if "Error" in scan_result:
327
335
  raise ValueError(scan_result["Error"])
328
336
 
329
337
  file_security_info = scan_result.get("file_security_info")
338
+
330
339
  if not isinstance(file_security_info, dict):
331
340
  return {}
332
341
 
333
342
  counter = Counter()
334
343
 
335
344
  for file_info in file_security_info.values():
345
+
336
346
  if not isinstance(file_info, dict):
337
347
  continue
338
348
 
339
349
  sast_result = file_info.get("sast_result", {})
350
+
340
351
  if not isinstance(sast_result, dict):
341
352
  continue
342
353
 
343
- # Based on your data: sast_result keys are line numbers (e.g., 171)
344
- # and values are dicts containing the 'validation' type.
345
- for issue_details in sast_result.values():
346
- if isinstance(issue_details, dict):
347
- # We use the 'validation' field to identify the type of weakness
348
- weakness_type = issue_details.get("validation", "Unknown")
349
- counter[weakness_type] += 1
354
+ for finding in sast_result.values():
355
+
356
+ # Support individual findings and lists of findings
357
+ findings = finding if isinstance(finding, list) else [finding]
358
+
359
+ for issue in findings:
360
+
361
+ if not isinstance(issue, dict):
362
+ continue
363
+
364
+ weakness_type = issue.get("validation", "Unknown")
365
+
366
+ if isinstance(weakness_type, str) and weakness_type:
367
+ counter[weakness_type] += 1
350
368
 
351
369
  return dict(counter)
352
370
 
@@ -19,17 +19,33 @@ So all results are returned as Pandas Dataframe. This makes things easier for fu
19
19
 
20
20
  """
21
21
 
22
-
23
22
  def total_weaknesses(scan_result):
24
- """Returns the total weaknesses found
25
- input: scan_result (dict): Scan output containing "file_security_info" with
26
- per-file SAST findings. Each finding should include a "validation" field.
23
+ """Count all individual weaknesses in a scan result.
24
+
25
+ Walks through each file's SAST findings and adds up every
26
+ individual weakness found.
27
+
28
+ Args:
29
+ scan_result (dict): Scan output with a "file_security_info" key
30
+ mapping file names to their per-file results. Each file's
31
+ "sast_result" maps check names to either a single finding
32
+ or a list of findings.
27
33
 
28
- """
34
+ Returns:
35
+ int: Total number of individual weaknesses across all files.
36
+ """
29
37
  total = 0
30
38
 
31
- for file_info in scan_result.get("file_security_info", {}).values():
39
+ file_security_info = scan_result.get("file_security_info", {})
40
+
41
+ for file_info in file_security_info.values():
32
42
  sast_result = file_info.get("sast_result", {})
33
- total += len(sast_result)
43
+
44
+ for finding in sast_result.values():
45
+ if isinstance(finding, list):
46
+ total += len(finding)
47
+ else:
48
+ total += 1
34
49
 
35
50
  return total
51
+
@@ -9,7 +9,7 @@ Directory Creation,os.mknod,Low,Direct file system calls require careful input v
9
9
  Directory Creation,os.makedev,Low,Direct file system calls require careful input validation to prevent vulnerabilities.
10
10
  OS Forking,os.fork,Low,"On macOS use of this function is unsafe when mixed with using higher-level system APIs, and that includes using urllib.request."
11
11
  Dangerous Built-in: eval,eval,High,This function can execute arbitrary code. Never safe with untrusted input.
12
- Input Function,input,Low,User input must be strictly sanitized and validated to prevent injection vulnerabilities.
12
+ Input Function,input,High,User input must be strictly sanitized and validated to prevent injection vulnerabilities.
13
13
  Overly Broad Exception Handling,pass,Low,Using `pass` in an `except` block can silently ignore critical security exceptions.
14
14
  Overly Broad Exception Handling,continue,Low,Skipping over exceptions can mask critical errors and security risks.
15
15
  Dangerous Built-in: exec,exec,High,This function can execute arbitrary code and should be used only with validated constructs.
@@ -88,42 +88,60 @@ async def get_pypi_download_info_wasm(package_name):
88
88
 
89
89
 
90
90
  async def get_package_source_wasm(url):
91
- import gzip
92
- import tarfile
91
+ import os
93
92
  import tempfile
94
- import zlib
95
-
96
93
  from pyodide.http import pyfetch
97
94
 
95
+ tmpdir_obj = None
98
96
  try:
99
97
  response = await pyfetch(url)
100
98
  if not response.ok:
101
99
  return None
102
100
 
103
- content = await response.bytes()
104
- content_encoding = response.headers.get("Content-Encoding")
105
-
106
- if content_encoding == "gzip":
107
- content = gzip.decompress(content)
108
- elif content_encoding == "deflate":
109
- content = zlib.decompress(content, -zlib.MAX_WBITS)
110
-
111
101
  tmpdir_obj = tempfile.TemporaryDirectory(prefix="codeaudit_")
112
102
  temp_dir = tmpdir_obj.name
103
+ extract_dir = os.path.join(temp_dir, "extracted")
104
+ os.makedirs(extract_dir, exist_ok=True) #nosec
105
+
106
+ # Recommended Pyodide way – works reliably in MEMFS
107
+ await response.unpack_archive(extract_dir=extract_dir, format="gztar")
108
+
109
+ # Locate the actual package root (same logic as before)
110
+ entries = os.listdir(extract_dir)
111
+ directories = [
112
+ os.path.join(extract_dir, entry)
113
+ for entry in entries
114
+ if os.path.isdir(os.path.join(extract_dir, entry))
115
+ ]
116
+ files = [
117
+ entry
118
+ for entry in entries
119
+ if os.path.isfile(os.path.join(extract_dir, entry))
120
+ ]
121
+
122
+ if len(directories) == 1 and not files:
123
+ source_dir = directories[0]
124
+ else:
125
+ source_dir = extract_dir
126
+
127
+ # Verify that the extracted source contains Python files
128
+ has_python_files = any(
129
+ filename.endswith(".py")
130
+ for root, _, filenames in os.walk(source_dir)
131
+ for filename in filenames
132
+ )
133
+
134
+ if not has_python_files:
135
+ print(f"WASM extraction found no .py files under {source_dir}")
136
+ tmpdir_obj.cleanup()
137
+ return None
113
138
 
114
- tar_path = f"{temp_dir}/package.tar.gz"
115
- with open(tar_path, "wb") as f:
116
- f.write(content)
117
-
118
- with tarfile.open(tar_path, "r:gz") as tar:
119
- tar.extractall(
120
- path=temp_dir, filter="data"
121
- ) # nosec Possible risks are mitigated and this happens in the WASM context.
122
-
123
- return temp_dir, tmpdir_obj
139
+ return source_dir, tmpdir_obj
124
140
 
125
141
  except Exception as e:
126
- print(f"WASM fetch error: {e}")
142
+ print(f"WASM fetch/extraction error: {e}")
143
+ if tmpdir_obj is not None:
144
+ tmpdir_obj.cleanup()
127
145
  return None
128
146
 
129
147
 
@@ -175,12 +193,28 @@ async def filescan_wasm(input_path, nosec=False):
175
193
  try:
176
194
  scan_output = _codeaudit_directory_scan_wasm(src_dir, nosec_flag=nosec)
177
195
  output |= scan_output
178
- # correct statistics for imported modules and modules count
179
- correct_imported_modules = package_imports(output)
180
- output["module_overview"]["imported_modules"] = correct_imported_modules
181
- output["statistics_overview"]["External Modules"] = len(
182
- correct_imported_modules
196
+ # Normalize optional sections before updating them.
197
+ # The WASM scanner may omit these sections for some packages.
198
+ module_overview = output.setdefault(
199
+ "module_overview",
200
+ {"core_modules": [], "imported_modules": []},
183
201
  )
202
+ if not isinstance(module_overview, dict):
203
+ module_overview = {
204
+ "core_modules": [],
205
+ "imported_modules": [],
206
+ }
207
+ output["module_overview"] = module_overview
208
+
209
+ # package_imports() can return None when module data is absent.
210
+ correct_imported_modules = package_imports(output) or []
211
+ module_overview["imported_modules"] = correct_imported_modules
212
+
213
+ statistics_overview = output.setdefault("statistics_overview", {})
214
+ if not isinstance(statistics_overview, dict):
215
+ statistics_overview = {}
216
+ output["statistics_overview"] = statistics_overview
217
+ statistics_overview["External Modules"] = len(correct_imported_modules)
184
218
  finally:
185
219
  if tmp_handle:
186
220
  tmp_handle.cleanup()
@@ -190,6 +224,68 @@ async def filescan_wasm(input_path, nosec=False):
190
224
  return {"Error": "Package not found on PyPI.org."}
191
225
 
192
226
 
227
+ # async def filescan_wasm(input_path, nosec=False):
228
+ # """
229
+ # WASM-compatible PyPI-only version of filescan function.
230
+ # Matches the behaviour of the original implementation for PyPI scans.
231
+
232
+ # PYPI PACKAGE ONLY (for now)
233
+ # """
234
+ # ca_version_info = version()
235
+ # now = datetime.datetime.now()
236
+ # timestamp_str = now.strftime("%Y-%m-%d %H:%M")
237
+ # output = ca_version_info | {"generated_on": timestamp_str}
238
+ # pypi_data = await get_pypi_download_info_wasm(input_path)
239
+
240
+ # if pypi_data:
241
+ # package_name = input_path
242
+ # url = pypi_data.get("download_url")
243
+ # release = pypi_data.get("release")
244
+
245
+ # if url is not None:
246
+ # # WASM-safe
247
+ # if IS_PYODIDE:
248
+ # decoded_res = await get_package_source_wasm(url)
249
+ # else:
250
+ # source_res = get_package_source(url)
251
+
252
+ # if inspect.isawaitable(source_res):
253
+ # decoded_res = await source_res
254
+ # else:
255
+ # decoded_res = source_res
256
+ # # Validation
257
+ # if decoded_res is None:
258
+ # return {
259
+ # "Error": f"Could not download or extract package from {url}. "
260
+ # f"This may be due to browser restrictions."
261
+ # }
262
+
263
+ # src_dir, tmp_handle = decoded_res
264
+
265
+ # # Match original structure EXACTLY
266
+ # output |= {
267
+ # "package_name": package_name,
268
+ # "package_release": release,
269
+ # }
270
+
271
+ # try:
272
+ # scan_output = _codeaudit_directory_scan_wasm(src_dir, nosec_flag=nosec)
273
+ # output |= scan_output
274
+ # # correct statistics for imported modules and modules count
275
+ # correct_imported_modules = package_imports(output)
276
+ # output["module_overview"]["imported_modules"] = correct_imported_modules
277
+ # output["statistics_overview"]["External Modules"] = len(
278
+ # correct_imported_modules
279
+ # )
280
+ # finally:
281
+ # if tmp_handle:
282
+ # tmp_handle.cleanup()
283
+
284
+ # return output
285
+ # # ---------------------------------------------------------
286
+ # return {"Error": "Package not found on PyPI.org."}
287
+
288
+
193
289
  # - END of specific HELPERS to do CA things -#
194
290
 
195
291
 
@@ -213,13 +309,18 @@ loading = pn.indicators.LoadingSpinner(
213
309
  value=False, size=60, color="primary", bgcolor="light", name="Scanning..."
214
310
  )
215
311
 
312
+ placeholder = pn.pane.Markdown(
313
+ "*Run a scan to populate this tab.*",
314
+ sizing_mode="stretch_width",
315
+ )
316
+
317
+ overview_content = pn.Column(placeholder)
318
+ modules_content = pn.Column(placeholder)
319
+ complexity_content = pn.Column(placeholder)
320
+ weaknesses_content = pn.Column(placeholder)
321
+ weaknesses_files_content = pn.Column(placeholder)
322
+ weaknesses_details_content = pn.Column(placeholder)
216
323
 
217
- overview_content = pn.Column()
218
- modules_content = pn.Column()
219
- complexity_content = pn.Column()
220
- weaknesses_content = pn.Column()
221
- weaknesses_files_content = pn.Column()
222
- weaknesses_details_content = pn.Column()
223
324
 
224
325
  tabs = pn.Tabs(
225
326
  ("Package Overview", overview_content),
@@ -259,7 +360,7 @@ async def run_scan(event):
259
360
 
260
361
  try:
261
362
  # ✅ Allow UI to update (spinner renders)
262
- await asyncio.sleep(0.1)
363
+ await asyncio.sleep(0.5)
263
364
 
264
365
  # ✅ WASM-safe: no threads, no nested event loops
265
366
  result = await filescan_wasm(package_name, respect_marker)
@@ -310,7 +411,7 @@ async def run_scan(event):
310
411
  ]
311
412
 
312
413
  except Exception as e:
313
- status.object = f"❌ Error: {str(e)}"
414
+ status.object = f"❌ Exception(!): {str(e)}"
314
415
 
315
416
  finally:
316
417
  # --- Reset UI state ---