From 3690eac8b2b1ecec31ac54adde3851d32e5be813 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 25 Mar 2026 13:59:30 +0100 Subject: [PATCH 01/13] wip Signed-off-by: Jan Kowalleck --- .../d_with_additional_site/.gitignore | 2 ++ .../d_with_additional_site/README.md | 4 ++++ .../.editorconfig | 11 ----------- .../.gitattributes | 2 -- .../README.md | 6 ------ .../my_licenses/richtext.rtf | Bin 210 -> 0 bytes .../my_licenses/utf-16be_withBOM.txt | Bin 94 -> 0 bytes .../my_licenses/utf-16le_withBOM.txt | Bin 86 -> 0 bytes .../my_licenses/utf-8_noBOM.txt | 4 ---- .../my_licenses/utf-8_withBOM.txt | 4 ---- .../pyproject.toml | 16 ---------------- tests/_data/infiles/environment/local/init.py | 1 + 12 files changed, 7 insertions(+), 43 deletions(-) create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/richtext.rtf delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16be_withBOM.txt delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16le_withBOM.txt delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-8_noBOM.txt delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-8_withBOM.txt delete mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/pyproject.toml diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore new file mode 100644 index 000000000..a4d2bdf61 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore @@ -0,0 +1,2 @@ +# in these cases we need to keep the dists, for showcasing purposes +!/dist/ diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md new file mode 100644 index 000000000..93a53cc1e --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md @@ -0,0 +1,4 @@ +build via +```shell +python -m build +``` diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig deleted file mode 100644 index a860ebadf..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# EditorConfig is awesome: https://editorconfig.org - -[my_licenses/utf-8*] -charset = utf-8 - -[my_licenses/utf-16le*] -charset = utf-16le - -[my_licenses/utf-16be*] -charset = utf-16be - diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes deleted file mode 100644 index e2462c370..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -Licenses/* binary -Licenses/*.txt binary diff=txt diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md deleted file mode 100644 index 94e9b731d..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# PEP 639 - regression 868 - -see - -PEP-630 expects license gfiles to be UTF8 encoded text. -some license files may not be text, some may not be UTF8 encoded, but still be added as license files. diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/richtext.rtf b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/richtext.rtf deleted file mode 100644 index 2e6251f1d073d5884a176bc89e8f3f582f773b9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210 zcmW-bF$=;l5QUu!{STQPFZD1@OOonP`rmC`J{}Jq- za^PrkAJs$biyI9JVFx=rLxnSaguibIO+}+cRTeau*ibSWfRfjzhZj(yI2m1)lEFFyRulEn;-74N5%jE diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16be_withBOM.txt b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16be_withBOM.txt deleted file mode 100644 index b030bead0d064ea06a4729e30f0d4c2b6129c4af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94 zcmezOpP_^ygCUclm_dOd4M^uOqykwWJ}(0oLn%-;jX{^ekim>02`rP!kjIeBkk60; c$^z Y4pa%!ufX8M;LqR-6tTU*e2 None: join(localpackages_dir, 'a', 'dist', 'package_a-23.42-py3-none-any.whl'), join(localpackages_dir, 'b', 'dist', 'package-b-23.42.tar.gz'), join(localpackages_dir, 'c'), + join(localpackages_dir, 'd_with_additional_site'), ) From 175f9f22be0138d46b09ced204a80252686ff873 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 25 Mar 2026 14:56:45 +0100 Subject: [PATCH 02/13] wip Signed-off-by: Jan Kowalleck --- .../d_with_additional_site/README.md | 5 ++++- ...ith_additional_site-0.0.1-py3-none-any.whl | Bin 0 -> 3364 bytes .../additional_site.pth | 1 + .../additional_site_loaded.py | 5 +++++ .../METADATA | 5 +++++ .../RECORD | 3 +++ .../WHEEL | 5 +++++ .../top_level.txt | 3 +++ .../module_d.py | 21 ++++++++++++++++++ tests/_data/infiles/environment/local/init.py | 2 +- 10 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/d_with_additional_site-0.0.1-py3-none-any.whl create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site.pth create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site_loaded.py create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/METADATA create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md index 93a53cc1e..2f5040dff 100644 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md @@ -1,4 +1,7 @@ build via ```shell -python -m build +rm -rf dist +mkdir dist +cd src +zip -r ../dist/d_with_additional_site-0.0.1-py3-none-any.whl d_with_additional_site-0.0.1-py3-none-any ``` diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/d_with_additional_site-0.0.1-py3-none-any.whl b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/d_with_additional_site-0.0.1-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..05e76bffcf4971b49a4eb2a0cce0750bc76b5fd1 GIT binary patch literal 3364 zcmWIWW@h1H0D+5nl`&ujl+a?3VMvKD&n(G^PfSV4EXmBzOU#Kc&MZmQHPAEAGt@1p zG}g__&r8)!%&XK74dG;9=DdA4^8*lk;9oLcQCBY%q_?-Dp5ew6`zxzn39^p1#*-K&KdL8Z zmjZeHKS*$j_AVR%AMEG>zx% z``1slY}l|_ktN+)Tg9h4mHbJrZ-(W@lD!Hih4g>!`&3tT@YqbdWW&{pTfddmBcegN05z%uN%Aqi zM4^|GSzMxT5>Zi0S6{YVtD!_op+u{plx?Zlv^24$Vz1dkrlmCaY}jmiZ8J0k zAVmi#1k`<=bwvYx55i%z2!U`9S63f=-Ve`6P0i5_OD!q}7FAXXhI$5E?x}gHMTsT( zMOF&MsU@WaCHeU|#R?i0MxX*rlPf4czeLxwST~@wC^aWD$x5N5s5F%;Br)Ae0l9GF zLMkjkS!ZWNg`zIdn+`x6P7ALFxjOp?xq$r&%0M8DR;0obDlkP}xrm-xuL4u(0TD== zZGFXnlvI;|MP1F45AQZIGBE66Vqh>O$@RJUDWy57@hPyvtpj`EmO9BXf3bl;>-(Rg z{!cD>aYnw~Se@j&$~D@NrR1`lti%DK8*6gCetx$W(ApZMH_i6&?Dw|S-FqgAP0iul z^X-tu3$EiUGqx`J!20~8X;kjE*}C&m98U#xI!;Y_AmwzSyJ`B?O^4-;!m?W5|1-aH zmiJ!Nr+4)m4lQ9XNou;p*Q`42#|+>1tY7(p7G8+G@3oNYkVfq0o=Df4X%(@mU#@b# z6T5TY-}uvVJC5xP=i?v8{4cQRdHkZA_1g7ic3ZZ)RabQNEw`|KD_QaLY2?-vU7o+P zOA=RK=UkLN&naf+CQ;=rjVpKy&%T^lZgR;p^nF6wm}|eaLqt z@S{Z4`?F`xPblh}c*=5f&kJscrTGrqmOF)QN{C-2=iJUiSV^+(^VgDK!B*ce3K9wkyG|*XC$`?o!LBa>Kibf8fGGH-+&oa~`flnop zv(PGRpc_FIHrAknxDm4sM!0cFqb0B=3.8 diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD new file mode 100644 index 000000000..c99fc035b --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD @@ -0,0 +1,3 @@ +module_d.py,, +additional_site.pth,, +additional_site_loaded.py,, diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL new file mode 100644 index 000000000..14a883f29 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (82.0.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt new file mode 100644 index 000000000..38b154031 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt @@ -0,0 +1,3 @@ +module_d +additional_site_loaded.py +additional_site.pth diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py new file mode 100644 index 000000000..8283b82a6 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py @@ -0,0 +1,21 @@ +# This file is part of CycloneDX Python +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + + +""" +module D +""" diff --git a/tests/_data/infiles/environment/local/init.py b/tests/_data/infiles/environment/local/init.py index ff137f4f5..0b5e4978b 100644 --- a/tests/_data/infiles/environment/local/init.py +++ b/tests/_data/infiles/environment/local/init.py @@ -54,7 +54,7 @@ def main() -> None: join(localpackages_dir, 'a', 'dist', 'package_a-23.42-py3-none-any.whl'), join(localpackages_dir, 'b', 'dist', 'package-b-23.42.tar.gz'), join(localpackages_dir, 'c'), - join(localpackages_dir, 'd_with_additional_site'), + join(localpackages_dir, 'd_with_additional_site', 'dist', 'd_with_additional_site-0.0.1-py3-none-any.whl'), ) From e1e2c3b5990f509c992c7c455d78122ccfdc6ef5 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Wed, 25 Mar 2026 14:57:02 +0100 Subject: [PATCH 03/13] wip Signed-off-by: Jan Kowalleck --- .../dist/package-a-23.42.tar.gz | Bin 0 -> 1418 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/package-a-23.42.tar.gz diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/package-a-23.42.tar.gz b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/package-a-23.42.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..62bf1071aa04bbe8fba7e80e177f58e094aeb004 GIT binary patch literal 1418 zcmV;51$Fu#iwFocVDn`H|8QYrYhh<)EnzJ(GcGhTE_7jX0PURpPun;c$NAZR#iQ`c zCebu;^TIeWT@Sjg+SZ~LZZ}PcnZ!+f%iAR`r8?dJes&t5z+l?Ja@+cRC6p$9aBSDl z^RZ($X4`E4dce+KaTfAoaL?@b)2iu`nqjVn{L4QMgy9ak`?Oq8|x{$4T%&9 z-?e?)a-41NS;ur;%c1Tz*+BjD%31JoF7S3XR z!pwZp6#s2Xsph}yxwh}qj`Dwpx)k}}gf^j`w1+TD6#+m_)l6RX3U#PcwxFK=12rvp zq795X$$0t;*@Q(lgM=+0%_Pk9gnueZn24AIKM!~=L8K65NgfN91{~%>POID0nV2ez z_jMN8sbtEUDf?WVO;+uINwTSIwWd<$JMH#-J~vraSTif4cKyVmY`^L6^#$WDbi>Q%4{O%tl%n_P?WL| zr!#r2u`Wud>bz>8nv11ibjQ#i8}M6q+#heLJl^#WUk#5A;azt$>JAS3y)g_&us0m+ z_YeESfjWBu-NAc!-5>040as0>Zo|*>LYH3^Qs`#np>DG==hq4_$(98wa~_C^2voh& zXr`acMA;cHQdJ$ud69@xf0?B!UZ`@3MIt1V)sA1jsI}{2giRaVu8*|0aa%|2Y3c{v-d9|H%J4_&**VjrMwDQ=ZEQ@c*9m zf9hH{`0sZ-eE#2vF86zom6acoFY+S$lLyk2SrU_b28HDQ4)eL>kmo!Nc^WKEVv&9- z@3NCweiHLD9{=~AheG}%|B?Tw2k`%M@%mBuuTHP?pW3eDBmbKax;pY7`H%cZ{v-eI z;Qxc?VPE9GeUtwdrMUmU5nass(dCi<$baO&=WHYY*O~vpmtaOE~O;aoHmba#rvAS68dvVUUoQK_PNkU%kHmZ;*>6|6TZ7ullQF zZL_);!1xDX6GSTYM)E9WarMIiR&6tf{(if+-0iNC2%E`iR+K8A567gq*g{bMJW<`h z+C*Rw@Y+MX;jALb7{iv~3E=tLht86Q~t1O=HdbVjP z`=#}%sw7Xts?wJ>W|el5aLInued{K^{|(>&hVOqv{@47kf}0skqDS`sd*}a-ck}%} ze#b-pH^P4&MJM_(&oPlKI$6FBU>B;BkV%bli(n)`p-?Ck3WY+UP$(1%g+ifFC=?2X YLZMJ76bgkxp}tG~3(ex2B>;E;03~<(LjV8( literal 0 HcmV?d00001 From 895a015ff259e860722a8312be7a26bfc3caab32 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 12:18:55 +0200 Subject: [PATCH 04/13] wip Signed-off-by: Jan Kowalleck --- .../c/dist/package-c-23.42.tar.gz | Bin 1454 -> 0 bytes .../c/dist/package_c-23.42-py3-none-any.whl | Bin 1613 -> 0 bytes .../d_with_additional_site/.gitignore | 2 - .../d_with_additional_site/README.md | 7 --- ...ith_additional_site-0.0.1-py3-none-any.whl | Bin 3364 -> 0 bytes .../dist/package-a-23.42.tar.gz | Bin 1418 -> 0 bytes .../additional_site.pth | 1 - .../additional_site_loaded.py | 5 -- .../METADATA | 5 -- .../RECORD | 3 - .../WHEEL | 5 -- .../top_level.txt | 3 - .../d_with_malicious_pth/.gitignore | 5 ++ .../d_with_malicious_pth/MANIFEST.in | 1 + .../d_with_malicious_pth/README.md | 22 +++++++ ..._with_malicious_pth-0.0.1-py3-none-any.whl | Bin 0 -> 2600 bytes .../d_with_malicious_pth/pyproject.toml | 13 ++++ .../src/module_d/__init__.py} | 2 +- .../src/module_d/pown.pth | 1 + .../broken-with-malicious-pth/init.py | 59 ++++++++++++++++++ .../broken-with-malicious-pth/pyproject.toml | 5 ++ tests/_data/infiles/environment/local/init.py | 1 - tests/integration/test_cli_environment.py | 13 ++++ 23 files changed, 120 insertions(+), 33 deletions(-) delete mode 100644 tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz delete mode 100644 tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/d_with_additional_site-0.0.1-py3-none-any.whl delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/package-a-23.42.tar.gz delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site.pth delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site_loaded.py delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/METADATA delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL delete mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/.gitignore create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/MANIFEST.in create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/README.md create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/dist/d_with_malicious_pth-0.0.1-py3-none-any.whl create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/pyproject.toml rename tests/_data/infiles/_helpers/local_pckages/{d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py => d_with_malicious_pth/src/module_d/__init__.py} (98%) create mode 100644 tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/src/module_d/pown.pth create mode 100644 tests/_data/infiles/environment/broken-with-malicious-pth/init.py create mode 100644 tests/_data/infiles/environment/broken-with-malicious-pth/pyproject.toml diff --git a/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz b/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz deleted file mode 100644 index 5a7057aaaf40792aeaac8f13941caaa826e2c584..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1454 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 diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore deleted file mode 100644 index a4d2bdf61..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# in these cases we need to keep the dists, for showcasing purposes -!/dist/ diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md deleted file mode 100644 index 2f5040dff..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/README.md +++ /dev/null @@ -1,7 +0,0 @@ -build via -```shell -rm -rf dist -mkdir dist -cd src -zip -r ../dist/d_with_additional_site-0.0.1-py3-none-any.whl d_with_additional_site-0.0.1-py3-none-any -``` diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/d_with_additional_site-0.0.1-py3-none-any.whl b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/dist/d_with_additional_site-0.0.1-py3-none-any.whl deleted file mode 100644 index 05e76bffcf4971b49a4eb2a0cce0750bc76b5fd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3364 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 YLZMJ76bgkxp}tG~3(ex2B>;E;03~<(LjV8( diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site.pth b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site.pth deleted file mode 100644 index 9b7a29313..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site.pth +++ /dev/null @@ -1 +0,0 @@ -import additional_site_loaded diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site_loaded.py b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site_loaded.py deleted file mode 100644 index f635f31f9..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/additional_site_loaded.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -this code is intended to be aut-executed by `additional_site.pth` -""" -import sys -print('!! malicious autoloaded code !!', file=sys.stderr) diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/METADATA b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/METADATA deleted file mode 100644 index 20ecf6cf9..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/METADATA +++ /dev/null @@ -1,5 +0,0 @@ -Metadata-Version: 2.4 -Name: d_with_additional_site -Version: 0.0.1 -Summary: some package with additional site -Requires-Python: >=3.8 diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD deleted file mode 100644 index c99fc035b..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/RECORD +++ /dev/null @@ -1,3 +0,0 @@ -module_d.py,, -additional_site.pth,, -additional_site_loaded.py,, diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL deleted file mode 100644 index 14a883f29..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: setuptools (82.0.1) -Root-Is-Purelib: true -Tag: py3-none-any - diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt b/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt deleted file mode 100644 index 38b154031..000000000 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/d_with_additional_site-0.0.1.dist-info/top_level.txt +++ /dev/null @@ -1,3 +0,0 @@ -module_d -additional_site_loaded.py -additional_site.pth diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/.gitignore b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/.gitignore new file mode 100644 index 000000000..14efe0a91 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/.gitignore @@ -0,0 +1,5 @@ +# in these cases we need to keep the dists, since this is the manipulated one +/build/ +/**.egg-info.egg-info + +!/dist/ diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/MANIFEST.in b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/MANIFEST.in new file mode 100644 index 000000000..e7e887c29 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/MANIFEST.in @@ -0,0 +1 @@ +include src/module_d/pown.pth diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/README.md b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/README.md new file mode 100644 index 000000000..e9bef2e0a --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/README.md @@ -0,0 +1,22 @@ +create a package that installs a malicious `.pth` file. + +build via +```shell +rm -rf dist build src/d_with_malicious_pth.egg-info.egg-info +python -m build --wheel + +cd dist +rm -rf manip_build +unzip d_with_malicious_pth-0.0.1-py3-none-any.whl -d manip_build +rm d_with_malicious_pth-0.0.1-py3-none-any.whl + +cd manip_build +mv module_d/pown.pth . +echo pown.pth >> d_with_malicious_pth-0.0.1.dist-info/top_level.txt +sed -i 's#module_d/pown.pth#pown.pth#g' d_with_malicious_pth-0.0.1.dist-info/RECORD + +zip ../d_with_malicious_pth-0.0.1-py3-none-any.whl -r . +cd .. +rm -rf manip_build +cd .. +``` diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/dist/d_with_malicious_pth-0.0.1-py3-none-any.whl b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/dist/d_with_malicious_pth-0.0.1-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..ef820946532b77142f7c9b3d50f92a3b356252a8 GIT binary patch literal 2600 zcmWIWW@h1H00FM}x)?A6N^mmBFy!W^l;)(yr|5@C$r zL;%nT5uhdxhG!v$QAe(P{k)Npfng651A_>%5%KYvd6^~g@p=W7VAC8_yV5}z&9u}> zj`@oX1X|z!6!m{{$%`}c?Z)aP&sDC`jw~gY-F=ywSd;vD7|U6hiAXH zt?u44QEX}s=bmqeEM9Ou4A~NO@gwW=lcrI*+h*&|OL06E)af`i<$;vbh3=;5TQ?n+ zHww#YegDt=&RO1jQJ>z`Z#cAsy(FpW5?{0Gv>!8k-?M(@3tD&~_P*Cbu0tBJn|mT% zYo=Ais(!i3`A+Q4eShOm%k4O}Gn|iq9P_`xqUZ68Zq{qpm)ULE?p9sVbtrhw+;2R4 z{(M>!wMne)AK#@7S6{PSH1=0q=X0}5@Rq}swjIyDoUxXAxnx!OhFwLA4UT9n-E!{4 z>j(QuWn)ey)FFd0f@wvckE=!EGw8GmaeB=$|yB zyr1Jy_@BNap)@FSz-K85I54Q;;e!`cvY| zGfOh!a}#qilQZ*6i{lGQGIR~}4D<~3QZkE6bTjkP@(HFcgz-m?$^I4srZo^YBG&kl z{DSzL)UwnZy^@L&cuHQRgOQS9$(^epzdTP5=u$33+UE4Hi*?dE<9UVGTUYDcne&^23@#Zz{N#PccWaPGr~Y}JlO5-M z&z$r*cSc{gPhaEYgQnHS7l7~ym)_a4zB;S61ZkW*?;EP&;d9Q<$3L_nkl|%W!|M=+ zmpop&I%jpfbg%KQ&^gI4Ga)^DP5MDr21J~Jyru5*tScJmB@osk)?48ouC6}#{1l#% znwp~>t2VFXGKnp{Eo`6arZ z#kv8dMX5QNNmdFaMWv}+A&Kc$3I&zMx_S9|sk(`Im0U=%0xGn+0$eRjfF;fgAl4?< z`9ZGE{y{GA#DJw(>pgdNmy-j-v5&Rao7@)aoNLnPxA0QQefDty&*2r4@;iTBUbgui z)4l)i*Lq%iD3eyq5!fuz;`IAb#zdWzr_0aJT3K|y^f}8Cza=*=y}C7JjpMzB4>v7$ z{#5C+c^ACVwn&>HO;=KCVd~NJ{!TH5n|vji8;xsc&h1etITk9vx-dW1e21Np^o*6y zbG7}ZOo?P;Kf)EEF0r(uL}XvIjX;9}m*k=z_p`lcVvR5G=wA5e&-e4-2ZJ5^wp}!= zQHc6hwYX}-9*?LZ2TwWPqF)^=Pw$_o`h%}i=W>ai)1>1ZcN;q%&ozAc{qilT#oguc zW$CVWR<8JxasAU&FPEsoRX=18cyJfqdmfRX{M(^jF{I<};f(0A?bkH^+<#uz#C`QB z%X-z{hKZV2PfH)=eR$=)%>6qR`wkXvwnt=_Rep6bzEQUXLV#&%5)g9$BLu;JUw-_E~z+H)@5=AR0bxc6|QQ^b}h zIN)TEfU*S`{yKt~utES>DzQT9JTxaljKfvqL5u??MTRYn&dA20)PF#evDAI|9IA@q zP$yvRN@UTB&l89+K`mI3J+Y8jtI&#BeD*>D53@)`*t?`r9@xGh%8Q5s7HB1w!WB7G zF^fBdm0KFW5o;y1@WW>x#EY2a6S9370OT}rnE(I) literal 0 HcmV?d00001 diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/pyproject.toml b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/pyproject.toml new file mode 100644 index 000000000..4bb002f35 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/pyproject.toml @@ -0,0 +1,13 @@ +[project] +name = "d_with_malicious_pth" +version = "0.0.1" +description = "some package D with malicious pth" +authors = [] +requires-python = ">=3.8" + +[tool.setuptools.packages.find] +where = ["src"] + +[build-system] +requires = ["setuptools>=68.0", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/src/module_d/__init__.py similarity index 98% rename from tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py rename to tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/src/module_d/__init__.py index 8283b82a6..78821cf21 100644 --- a/tests/_data/infiles/_helpers/local_pckages/d_with_additional_site/src/d_with_additional_site-0.0.1-py3-none-any/module_d.py +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/src/module_d/__init__.py @@ -17,5 +17,5 @@ """ -module D +module C """ diff --git a/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/src/module_d/pown.pth b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/src/module_d/pown.pth new file mode 100644 index 000000000..3355714f4 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/d_with_malicious_pth/src/module_d/pown.pth @@ -0,0 +1 @@ +import sys; print('!! YOU GOT POWNED !!',file=sys.stderr); print('!! YOU GOT POWNED !!',file=sys.stdout); raise Exception('!! YOU GOT POWNED !!') diff --git a/tests/_data/infiles/environment/broken-with-malicious-pth/init.py b/tests/_data/infiles/environment/broken-with-malicious-pth/init.py new file mode 100644 index 000000000..cf796d9b6 --- /dev/null +++ b/tests/_data/infiles/environment/broken-with-malicious-pth/init.py @@ -0,0 +1,59 @@ +# This file is part of CycloneDX Python +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) OWASP Foundation. All Rights Reserved. + +""" +initialize this testbed. +""" + +from os import name as os_name +from os.path import abspath, dirname, join +from subprocess import check_call # nosec:B404 +from sys import executable, stderr +from venv import EnvBuilder + +__all__ = ['main'] + +this_dir = dirname(__file__) +env_dir = join(this_dir, '.venv') + +localpackages_dir = abspath(join(dirname(__file__), '..', '..', '_helpers', 'local_pckages')) + + +def pip_install(*args: str) -> None: + # pip is not API, but a CLI -- call it like that! + call = (executable, '-m', 'pip', + '--python', env_dir, + 'install', '--require-virtualenv', '--no-input', '--progress-bar=off', '--no-color', + *args) + print('+ ', *call, file=stderr) + check_call(call, cwd=this_dir, shell=False) # nosec:B603 + + +def main() -> None: + EnvBuilder( + system_site_packages=False, + symlinks=os_name != 'nt', + with_pip=False, + ).create(env_dir) + + pip_install( + join(localpackages_dir, 'd_with_malicious_pth', 'dist', 'd_with_malicious_pth-0.0.1-py3-none-any.whl'), + ) + + +if __name__ == '__main__': + main() diff --git a/tests/_data/infiles/environment/broken-with-malicious-pth/pyproject.toml b/tests/_data/infiles/environment/broken-with-malicious-pth/pyproject.toml new file mode 100644 index 000000000..c00bb6dca --- /dev/null +++ b/tests/_data/infiles/environment/broken-with-malicious-pth/pyproject.toml @@ -0,0 +1,5 @@ +[project] +# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata +name = "with_malicious_pth" +version = "0.1.0" +description = "packages with malicious pth" diff --git a/tests/_data/infiles/environment/local/init.py b/tests/_data/infiles/environment/local/init.py index 0b5e4978b..062b9e663 100644 --- a/tests/_data/infiles/environment/local/init.py +++ b/tests/_data/infiles/environment/local/init.py @@ -54,7 +54,6 @@ def main() -> None: join(localpackages_dir, 'a', 'dist', 'package_a-23.42-py3-none-any.whl'), join(localpackages_dir, 'b', 'dist', 'package-b-23.42.tar.gz'), join(localpackages_dir, 'c'), - join(localpackages_dir, 'd_with_additional_site', 'dist', 'd_with_additional_site-0.0.1-py3-none-any.whl'), ) diff --git a/tests/integration/test_cli_environment.py b/tests/integration/test_cli_environment.py index 1459943b4..50b192468 100644 --- a/tests/integration/test_cli_environment.py +++ b/tests/integration/test_cli_environment.py @@ -35,6 +35,7 @@ test_data = tuple( (f'{basename(projectdir)}-{sv.name}-{of.name}', projectdir, sv, of) for projectdir in map(dirname, initfiles) + if not basename(projectdir).startswith('broken-') for of, sv in SUPPORTED_OF_SV ) @@ -116,6 +117,18 @@ def test_with_pyproject_not_found(self) -> None: self.assertNotEqual(0, res, err) self.assertIn('Could not open pyproject file: something-that-must-not-exist.testing', err) + def test_with_sites_detection_fails(self) -> None: + projectdir = join(INFILES_DIRECTORY, 'environment', 'broken-with-malicious-pth') + res, out, err = run_cli( + 'environment', + '-vvv', + '-o=-', + '--pyproject', join(projectdir, 'pyproject.toml'), + join(projectdir, '.venv') + ) + self.assertNotEqual(0, res, err) + self.assertIn('FOOOOO', err) + def test_with_current_python(self) -> None: sv = SchemaVersion.V1_6 of = random.choice((OutputFormat.XML, OutputFormat.JSON)) # nosec B311 From 55122f96ae006e581c4baf6c5c246c1178c12516 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 12:24:40 +0200 Subject: [PATCH 05/13] wip Signed-off-by: Jan Kowalleck --- .../local_pckages/c/dist/package-c-23.42.tar.gz | Bin 0 -> 1454 bytes .../c/dist/package_c-23.42-py3-none-any.whl | Bin 0 -> 1613 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz create mode 100644 tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl diff --git a/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz b/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5a7057aaaf40792aeaac8f13941caaa826e2c584 GIT binary patch literal 1454 zcmV;f1yTARiwFo{A@pSe|8QYrYhh<)En_V*GcGhTE_7jX0PS3DZ`(Ey_GkWzgYu;X zVp)g(gw_4J)zodP@vZc~)pFF;Y&pi}b*=NJ?Z_<4 zaBQXjmT5F=;8dyq<1m>&B=@EA|0#5||7icw{-gab?f=QE7xn(&`Ec9%@7ngg_P^5kZbMmj4MVRlh0`p#Vu4C8D}tAd z#hhkrCHhaR%R8;BjMyJDp0T`svJg|%_h&~<{Q!;HcgX*i`zil7k^d{m0x7=~1w4{&(-^f5UDS{BOJRujwlOw+-a~N^m*jVE|X0k`Es~Jb!$ssIfF@;~zbkI(;y2gad={J+EeA0@#oWEZ}kE~?^x)3U6!|8F}|&a^Gt zLH@4-dn^3Vp`m$Y($q$yepeXE(Mj+RLZ9^HQtm1D#)IcRhSBq zwi}K4e6G`?vwD(E8sSnfZ@lhzdjqehHXw>BXK~2#9J1w>KmeBupsDPSPcLOJLpp~f z13Jl=EE9?9?>ysz$CG`?%dH66O2BiG@ynUGHCU_O$!Fdaki$h|&^jLUJq>>8czthQ zw(+)q`f_-73U523QD<=4?|Ev6q&plO_fPx7flNJz&fp!q>JN_hfytqgw_(?5rur{C z$<;8jK#iHl*sTtXlVykUl=*zjefeDRWTtjzCdn1cV);0bvMl1cdYQTGULacudBg=3 zMb0M=r5B^;ogDvGFLUbsfW@NRiMiS4ky2gx#xg#c3V7l_h2h(dcLL87*<{hU4xKQB zkt)w&#B!Ehsiz=B(=@U)I?yc=Xp?tt{fFm2|K0iz&wp_Jx3T^!({cgGCX+gk$4O%= z`u}z3|Bl_V@cbYBf3*Kq`~S-RqyLZgf5ZMiIwauh&;MP=MgPAN;Q2rLf5`vH|H%Ky z|M&2}H#{44d!8zY475J;=t%4@no2Q-5c^&_xo3i;IxQAM^XF?23i|e&!*N|B?TZ{}GSi|IgX$t@6K2-sXSH zR2Ss`3V^DP{Ez&P{Ez&P{C^MsKiUubBLACr`Csb4jr?B)R$f1HkCg@3xHc`#;xmoFe|qXyW&OmEe8(y3a{WBL+vHt!IQruFAN7nOn>b zjRY+BGoFev_xAa}M#=zuS@b6eb}f|5C$Rt;`~`c!W1#}clbD7;ix6|@EyLVp9-%Wa zO|o3pe}7K0)k%K&Wuk1fILp_FzYYs1LK7;AysrkTP>|F8JJFgLnCo@`nFAO8N|z5D-vS{C~M)$l)?OfJ+m&p8ov zagzpr{RQ_sHOC!W4*kwQ$Q5q9AUHhZv7v$_Vmt5vg9f5ol(wV3Y|yY@xD^GARGOWZAc+%U*E zCnaZdZobp@TCcM9EfzT}75|>NZhs=9^H=i5sTI$)L-cKyT5+eYc9Y<~8Zl{}x$ygp zo162l6)gLm;Qk-*2d#?ryap_ zo)=d6@Ud=^*{yR|{kV$v(khoZ`yQoFdUsu+(`((r@Av%vFr5tU3GtmN>N1}ptC+dS zc4|zqX7S6k0N#a$`6*j_n&;&l&x=|nyvHjh>fH@(`}u#&Lrj*3+q|#OpElVyXyUgd z|8I#u{qr=F)ulJziLrTisyb!)j*4T81yA3!ak{hZ#PWU4etmClo45+JBubPllS<*= zz4Hfm06YdS0b_9EO!IHEfid?9h?Ri2ATc>RF&!9%x<r!>X1hv`MUhET^bI~Mu!iK%8Rumt+)4E1g zu9Ni%Ys$+`Rr3-*)2=lw{A@u^amyIrt*s2Oy_+xSb@_*S)U1p3UpIUS<=Vx6YSQE5 z7q?%2f7@5*TF+hvRImNvtM-lodI^N(@p>)X!`0P?`@Dzm*^9j1x?1PXoZlQ|aK-pR zk^fn5T`!%J`kR70yiV%qb?URP47^})!PxMc@r5T`r_SqN{Hk+}S3}q9>`9+ZK^mG` zzE8P4eYOW_tT4HD_Vju0tG;JeKY7H2<}epQ_5YyU!U@FccpX-fUl5;@T9%rlS5i@O z`mDd^Sb{twafY^A0JMA{tOt1>IE=Ee3H>pxoZ?itE%-wW6#~M5m{UQI^*xG zX!iVV(ho%+c#m3Gq$K7YE5t}f9MdMWn7%2{ABMf|LboiTiuH| zuc&%7E?vgzPxgnTW_xC_x3>eDrsmH5Ai-p@{acI*@9)&!JNT2<>A5@c;p8URD4A literal 0 HcmV?d00001 From 1d9dc5ac15355b79a6760cc84a6121159cf5d4e0 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 12:29:23 +0200 Subject: [PATCH 06/13] wip Signed-off-by: Jan Kowalleck --- .../.editorconfig | 11 +++++++++++ .../.gitattributes | 2 ++ .../README.md | 6 ++++++ .../my_licenses/richtext.rtf | Bin 0 -> 210 bytes .../my_licenses/utf-16be_withBOM.txt | Bin 0 -> 94 bytes .../my_licenses/utf-16le_withBOM.txt | Bin 0 -> 86 bytes .../my_licenses/utf-8_noBOM.txt | 4 ++++ .../my_licenses/utf-8_withBOM.txt | 4 ++++ .../pyproject.toml | 16 ++++++++++++++++ .../broken-with-malicious-pth/init.py | 1 + 10 files changed, 44 insertions(+) create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/richtext.rtf create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16be_withBOM.txt create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16le_withBOM.txt create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-8_noBOM.txt create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-8_withBOM.txt create mode 100644 tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/pyproject.toml diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig new file mode 100644 index 000000000..a860ebadf --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.editorconfig @@ -0,0 +1,11 @@ +# EditorConfig is awesome: https://editorconfig.org + +[my_licenses/utf-8*] +charset = utf-8 + +[my_licenses/utf-16le*] +charset = utf-16le + +[my_licenses/utf-16be*] +charset = utf-16be + diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes new file mode 100644 index 000000000..e2462c370 --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/.gitattributes @@ -0,0 +1,2 @@ +Licenses/* binary +Licenses/*.txt binary diff=txt diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md new file mode 100644 index 000000000..94e9b731d --- /dev/null +++ b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/README.md @@ -0,0 +1,6 @@ +# PEP 639 - regression 868 + +see + +PEP-630 expects license gfiles to be UTF8 encoded text. +some license files may not be text, some may not be UTF8 encoded, but still be added as license files. diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/richtext.rtf b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/richtext.rtf new file mode 100644 index 0000000000000000000000000000000000000000..2e6251f1d073d5884a176bc89e8f3f582f773b9a GIT binary patch literal 210 zcmW-bF$=;l5QUu!{STQPFZD1@OOonP`rmC`J{}Jq- za^PrkAJs$biyI9JVFx=rLxnSaguibIO+}+cRTeau*ibSWfRfjzhZj(yI2m1)lEFFyRulEn;-74N5%jE literal 0 HcmV?d00001 diff --git a/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16be_withBOM.txt b/tests/_data/infiles/_helpers/local_pckages/with-license-pep639_regression-issue868/my_licenses/utf-16be_withBOM.txt new file mode 100644 index 0000000000000000000000000000000000000000..b030bead0d064ea06a4729e30f0d4c2b6129c4af GIT binary patch literal 94 zcmezOpP_^ygCUclm_dOd4M^uOqykwWJ}(0oLn%-;jX{^ekim>02`rP!kjIeBkk60; c$^z Y4pa%!ufX8M;LqR-6tTU*e2 None: system_site_packages=False, symlinks=os_name != 'nt', with_pip=False, + clear=True, # explicitely important, since the env might be broken on purpose ).create(env_dir) pip_install( From 72110d8e81d00dfd42260bc4a26a6be4d6a19d6b Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 13:06:14 +0200 Subject: [PATCH 07/13] wip Signed-off-by: Jan Kowalleck --- cyclonedx_py/_internal/environment.py | 23 ++++++++++++++++------- tests/integration/test_cli_environment.py | 20 +++++++++++++++++++- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py index c6dd5f9a3..84ebf0e4d 100644 --- a/cyclonedx_py/_internal/environment.py +++ b/cyclonedx_py/_internal/environment.py @@ -19,7 +19,7 @@ from argparse import OPTIONAL, ArgumentParser from collections.abc import Iterable from importlib.metadata import distributions -from json import loads +from json import loads as json_loads from os import getcwd, name as os_name from os.path import exists, isdir, join from subprocess import run # nosec @@ -111,6 +111,11 @@ def make_argument_parser(**kwargs: Any) -> 'ArgumentParser': • Build an SBOM from uv environment: $ %(prog)s "$(uv python find)" """) + p.add_argument('-S', + action='store_false', + dest='import_site', + help="Don't imply 'import site' during path detection of a given python.\n" + 'This should prevent evaluation of .pth files at cost of component detection') p.add_argument('--gather-license-texts', action='store_true', dest='gather_license_texts', @@ -137,6 +142,7 @@ def __init__(self, *, self._gather_license_texts = gather_license_texts def __call__(self, *, # type:ignore[override] + import_site: bool, python: Optional[str], pyproject_file: Optional[str], mc_type: 'ComponentType', @@ -155,7 +161,7 @@ def __call__(self, *, # type:ignore[override] path: list[str] if python: - path = self.__path4python(python) + path = self.__path4python(python, import_site) else: path = sys_path.copy() if path[0] in ('', getcwd()): @@ -278,8 +284,8 @@ def __py_interpreter(value: str) -> str: raise ValueError(f'No such file or directory: {value}') if isdir(value): for venv_loc in ( - ('bin', 'python'), # unix - ('Scripts', 'python.exe'), # win + ('bin', 'python'), # unix + ('Scripts', 'python.exe'), # win ): maybe = join(value, *venv_loc) if exists(maybe): @@ -287,8 +293,11 @@ def __py_interpreter(value: str) -> str: raise ValueError(f'Failed to find python in directory: {value}') return value - def __path4python(self, python: str) -> list[str]: - cmd = self.__py_interpreter(python), '-c', 'import json,sys;json.dump(sys.path,sys.stdout)' + def __path4python(self, python: str, import_site: bool) -> list[str]: + cmd = [self.__py_interpreter(python), '-c', 'import json,sys;json.dump(sys.path,sys.stdout)'] + if not import_site: + cmd.insert(1, '-S') + self._logger.debug('fetch `path` from python interpreter cmd: %r', cmd) res = run(cmd, capture_output=True, encoding='utf8', shell=False) # nosec if res.returncode != 0: @@ -297,4 +306,4 @@ def __path4python(self, python: str) -> list[str]: f'stdout: {res.stdout}\n' f'stderr: {res.stderr}\n') self._logger.debug('got `path` from Python interpreter: %r', res.stdout) - return loads(res.stdout) # type:ignore[no-any-return] + return json_loads(res.stdout) # type:ignore[no-any-return] diff --git a/tests/integration/test_cli_environment.py b/tests/integration/test_cli_environment.py index 50b192468..96e85b861 100644 --- a/tests/integration/test_cli_environment.py +++ b/tests/integration/test_cli_environment.py @@ -127,7 +127,25 @@ def test_with_sites_detection_fails(self) -> None: join(projectdir, '.venv') ) self.assertNotEqual(0, res, err) - self.assertIn('FOOOOO', err) + self.assertIn('JSONDecodeError', err) + + def test_with_sites_evaluation_suppressed(self) -> None: + projectdir = join(INFILES_DIRECTORY, 'environment', 'broken-with-malicious-pth') + sv = SchemaVersion.V1_6 + of = OutputFormat.JSON + res, out, err = run_cli( + 'environment', + '-vvv', + '--sv', sv.to_version(), + '--of', of.name, + '--output-reproducible', + '-o=-', + '--pyproject', join(projectdir, 'pyproject.toml'), + '-S', # the important part + join(projectdir, '.venv') + ) + self.assertEqual(0, res, err) + self.assertEqualSnapshot(out, 'test_with_sites_evaluation_suppressed', projectdir, sv, of) def test_with_current_python(self) -> None: sv = SchemaVersion.V1_6 From 008ecbcf27620ee16d10cd23f3c72f9d91806f84 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 13:17:21 +0200 Subject: [PATCH 08/13] wip Signed-off-by: Jan Kowalleck --- tests/integration/test_cli_environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_cli_environment.py b/tests/integration/test_cli_environment.py index 96e85b861..a657feb16 100644 --- a/tests/integration/test_cli_environment.py +++ b/tests/integration/test_cli_environment.py @@ -127,7 +127,7 @@ def test_with_sites_detection_fails(self) -> None: join(projectdir, '.venv') ) self.assertNotEqual(0, res, err) - self.assertIn('JSONDecodeError', err) + self.assertIn('JSONDecodeError', err) # due to pownage def test_with_sites_evaluation_suppressed(self) -> None: projectdir = join(INFILES_DIRECTORY, 'environment', 'broken-with-malicious-pth') From 3081205cc129baa136b205aec1727a2fbb91a276 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 13:17:26 +0200 Subject: [PATCH 09/13] wip Signed-off-by: Jan Kowalleck --- ...sed_broken-with-malicious-pth_1.6.json.bin | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/_data/snapshots/environment/test_with_sites_evaluation_suppressed_broken-with-malicious-pth_1.6.json.bin diff --git a/tests/_data/snapshots/environment/test_with_sites_evaluation_suppressed_broken-with-malicious-pth_1.6.json.bin b/tests/_data/snapshots/environment/test_with_sites_evaluation_suppressed_broken-with-malicious-pth_1.6.json.bin new file mode 100644 index 000000000..6b8e08d7e --- /dev/null +++ b/tests/_data/snapshots/environment/test_with_sites_evaluation_suppressed_broken-with-malicious-pth_1.6.json.bin @@ -0,0 +1,88 @@ +{ + "dependencies": [ + { + "ref": "root-component" + } + ], + "metadata": { + "component": { + "bom-ref": "root-component", + "description": "packages with malicious pth", + "name": "with_malicious_pth", + "type": "application", + "version": "0.1.0" + }, + "properties": [ + { + "name": "cdx:reproducible", + "value": "true" + } + ], + "tools": { + "components": [ + { + "description": "CycloneDX Software Bill of Materials (SBOM) generator for Python projects and environments", + "externalReferences": [ + { + "type": "build-system", + "url": "https://github.com/CycloneDX/cyclonedx-python/actions" + }, + { + "type": "distribution", + "url": "https://pypi.org/project/cyclonedx-bom/" + }, + { + "type": "documentation", + "url": "https://cyclonedx-bom-tool.readthedocs.io/" + }, + { + "type": "issue-tracker", + "url": "https://github.com/CycloneDX/cyclonedx-python/issues" + }, + { + "type": "license", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE" + }, + { + "type": "release-notes", + "url": "https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md" + }, + { + "type": "vcs", + "url": "https://github.com/CycloneDX/cyclonedx-python/" + }, + { + "type": "website", + "url": "https://github.com/CycloneDX/cyclonedx-python/#readme" + } + ], + "group": "CycloneDX", + "licenses": [ + { + "license": { + "acknowledgement": "declared", + "id": "Apache-2.0" + } + } + ], + "name": "cyclonedx-py", + "type": "application", + "version": "thisVersion-testing" + }, + { + "description": "stripped", + "externalReferences": [ ], + "group": "CycloneDX", + "licenses": [ ], + "name": "cyclonedx-python-lib", + "type": "library", + "version": "libVersion-testing" + } + ] + } + }, + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6" +} \ No newline at end of file From 470a8f93f32ab7da32e0d796b12d8a056bc6f674 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 13:28:12 +0200 Subject: [PATCH 10/13] wip Signed-off-by: Jan Kowalleck --- cyclonedx_py/_internal/environment.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py index 84ebf0e4d..cae3bd890 100644 --- a/cyclonedx_py/_internal/environment.py +++ b/cyclonedx_py/_internal/environment.py @@ -19,7 +19,7 @@ from argparse import OPTIONAL, ArgumentParser from collections.abc import Iterable from importlib.metadata import distributions -from json import loads as json_loads +from json import JSONDecodeError, loads as json_loads from os import getcwd, name as os_name from os.path import exists, isdir, join from subprocess import run # nosec @@ -294,7 +294,8 @@ def __py_interpreter(value: str) -> str: return value def __path4python(self, python: str, import_site: bool) -> list[str]: - cmd = [self.__py_interpreter(python), '-c', 'import json,sys;json.dump(sys.path,sys.stdout)'] + cmd = [self.__py_interpreter(python), + '-c', 'import json,sys;json.dump(sys.path,sys.stdout)'] if not import_site: cmd.insert(1, '-S') @@ -306,4 +307,12 @@ def __path4python(self, python: str, import_site: bool) -> list[str]: f'stdout: {res.stdout}\n' f'stderr: {res.stderr}\n') self._logger.debug('got `path` from Python interpreter: %r', res.stdout) - return json_loads(res.stdout) # type:ignore[no-any-return] + try: + path = json_loads(res.stdout) + except JSONDecodeError as err: + raise ValueError('Fail fetching `path` from Python interpreter.\n' + f'stdout: {res.stdout}\n') from err + if type(path) is not list or any(type(p) is not str for p in path): + raise TypeError('Fail fetching `path` from Python interpreter.\n' + f'stdout: {res.stdout}\n') + return path From cd05f74652501f15df46cb5cd1dce14a052f03dd Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 13:52:57 +0200 Subject: [PATCH 11/13] docs Signed-off-by: Jan Kowalleck --- cyclonedx_py/_internal/environment.py | 4 ++-- docs/usage.rst | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py index cae3bd890..b82a53f30 100644 --- a/cyclonedx_py/_internal/environment.py +++ b/cyclonedx_py/_internal/environment.py @@ -114,8 +114,8 @@ def make_argument_parser(**kwargs: Any) -> 'ArgumentParser': p.add_argument('-S', action='store_false', dest='import_site', - help="Don't imply 'import site' during path detection of a given python.\n" - 'This should prevent evaluation of .pth files at cost of component detection') + help='Do not implicitly import site during path detection for the specified Python interpreter.\n' + 'This prevents evaluation of `*.pth` files, but may result in incomplete component detection.') p.add_argument('--gather-license-texts', action='store_true', dest='gather_license_texts', diff --git a/docs/usage.rst b/docs/usage.rst index 2bd433744..00e0152d7 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -70,6 +70,8 @@ The full documentation can be issued by running with ``environment --help``: options: -h, --help show this help message and exit + -S Do not implicitly import site during path detection for the specified Python interpreter. + This prevents evaluation of `*.pth` files, but may result in incomplete component detection. --gather-license-texts Enable license text gathering. --pyproject Path to the root component's `pyproject.toml` file. From 7ebd4b314be7ecf54cc1b9b499e3a1684498cf32 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 13:56:17 +0200 Subject: [PATCH 12/13] docs Signed-off-by: Jan Kowalleck --- cyclonedx_py/_internal/environment.py | 4 ++-- docs/usage.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py index b82a53f30..0eda5e03d 100644 --- a/cyclonedx_py/_internal/environment.py +++ b/cyclonedx_py/_internal/environment.py @@ -114,8 +114,8 @@ def make_argument_parser(**kwargs: Any) -> 'ArgumentParser': p.add_argument('-S', action='store_false', dest='import_site', - help='Do not implicitly import site during path detection for the specified Python interpreter.\n' - 'This prevents evaluation of `*.pth` files, but may result in incomplete component detection.') + help='Do not implicitly import site during Python path detection.\n' + 'Prevents evaluation of `*.pth` files, but may lead to incomplete component detection.') p.add_argument('--gather-license-texts', action='store_true', dest='gather_license_texts', diff --git a/docs/usage.rst b/docs/usage.rst index 00e0152d7..3dc040ad8 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -70,8 +70,8 @@ The full documentation can be issued by running with ``environment --help``: options: -h, --help show this help message and exit - -S Do not implicitly import site during path detection for the specified Python interpreter. - This prevents evaluation of `*.pth` files, but may result in incomplete component detection. + -S Do not implicitly import site during Python path detection. + Prevents evaluation of `*.pth` files, but may lead to incomplete component detection. --gather-license-texts Enable license text gathering. --pyproject Path to the root component's `pyproject.toml` file. From 71e08d63529a41a0715783c40e1dbbb267343e09 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 30 Mar 2026 13:57:44 +0200 Subject: [PATCH 13/13] docs Signed-off-by: Jan Kowalleck --- cyclonedx_py/_internal/environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py index 0eda5e03d..b0eb7f9e9 100644 --- a/cyclonedx_py/_internal/environment.py +++ b/cyclonedx_py/_internal/environment.py @@ -111,7 +111,7 @@ def make_argument_parser(**kwargs: Any) -> 'ArgumentParser': • Build an SBOM from uv environment: $ %(prog)s "$(uv python find)" """) - p.add_argument('-S', + p.add_argument('-S', # mimic `python -S` action='store_false', dest='import_site', help='Do not implicitly import site during Python path detection.\n'