diff --git a/.github/generate-sbom.py b/.github/generate-sbom.py index 9e65121e6..3b15a7d91 100755 --- a/.github/generate-sbom.py +++ b/.github/generate-sbom.py @@ -26,6 +26,11 @@ def get_version() -> str: return version_file.read_text(encoding="utf-8").split('"')[1] +def load_dep_versions() -> dict[str, str]: + deps_file = Path(__file__).parent / "dependencies.json" + return json.loads(deps_file.read_text(encoding="utf-8")) + + def sha256_file(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() @@ -58,6 +63,7 @@ def generate(version: str) -> dict: purl = f"pkg:pypi/pillow@{version}" root = Path(__file__).parent.parent thirdparty = root / "src" / "thirdparty" + versions = load_dep_versions() metadata_component = { "bom-ref": purl, @@ -79,18 +85,18 @@ def generate(version: str) -> dict: } c_extensions = [ + ("PIL._avif", "AVIF image format extension"), ( "PIL._imaging", "Core image processing extension " "(decode, encode, map, display, outline, path, libImaging)", ), - ("PIL._imagingft", "FreeType font rendering extension"), ("PIL._imagingcms", "LittleCMS2 colour management extension"), - ("PIL._webp", "WebP image format extension"), - ("PIL._avif", "AVIF image format extension"), - ("PIL._imagingtk", "Tk/Tcl display extension"), + ("PIL._imagingft", "FreeType font rendering extension"), ("PIL._imagingmath", "Image math operations extension"), ("PIL._imagingmorph", "Image morphology extension"), + ("PIL._imagingtk", "Tk/Tcl display extension"), + ("PIL._webp", "WebP image format extension"), ] ext_components = [ @@ -107,6 +113,51 @@ def generate(version: str) -> dict: ] vendored_components = [ + { + "bom-ref": f"{purl}#thirdparty/fribidi-shim", + "type": "library", + "name": "fribidi-shim", + "version": "1.x", + "description": "FriBiDi runtime-loading shim " + "(vendored in src/thirdparty/fribidi-shim/); " + "loads libfribidi dynamically", + "licenses": [{"license": {"id": "LGPL-2.1-or-later"}}], + "hashes": [ + { + "alg": "SHA-256", + "content": sha256_file(thirdparty / "fribidi-shim" / "fribidi.c"), + } + ], + "pedigree": { + "notes": "Pillow-authored shim; not taken from an upstream project." + }, + "externalReferences": [ + {"type": "website", "url": "https://github.com/fribidi/fribidi"}, + ], + }, + { + "bom-ref": "pkg:github/python/pythoncapi-compat", + "type": "library", + "name": "pythoncapi_compat", + "description": "Backport header for new CPython C-API functions " + "(vendored in src/thirdparty/pythoncapi_compat.h)", + "licenses": [{"license": {"id": "0BSD"}}], + "hashes": [ + { + "alg": "SHA-256", + "content": sha256_file(thirdparty / "pythoncapi_compat.h"), + } + ], + "pedigree": { + "notes": "Vendored unmodified from upstream python/pythoncapi-compat." + }, + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/python/pythoncapi-compat", + }, + ], + }, { "bom-ref": f"{purl}#thirdparty/raqm", "type": "library", @@ -191,61 +242,99 @@ def generate(version: str) -> dict: }, ], }, - { - "bom-ref": f"{purl}#thirdparty/fribidi-shim", - "type": "library", - "name": "fribidi-shim", - "version": "1.x", - "description": "FriBiDi runtime-loading shim " - "(vendored in src/thirdparty/fribidi-shim/); " - "loads libfribidi dynamically", - "licenses": [{"license": {"id": "LGPL-2.1-or-later"}}], - "hashes": [ - { - "alg": "SHA-256", - "content": sha256_file(thirdparty / "fribidi-shim" / "fribidi.c"), - } - ], - "pedigree": { - "notes": "Pillow-authored shim; not taken from an upstream project." - }, - "externalReferences": [ - {"type": "website", "url": "https://github.com/fribidi/fribidi"}, - ], - }, - { - "bom-ref": "pkg:github/python/pythoncapi-compat", - "type": "library", - "name": "pythoncapi_compat", - "description": "Backport header for new CPython C-API functions " - "(vendored in src/thirdparty/pythoncapi_compat.h)", - "licenses": [{"license": {"id": "0BSD"}}], - "hashes": [ - { - "alg": "SHA-256", - "content": sha256_file(thirdparty / "pythoncapi_compat.h"), - } - ], - "pedigree": { - "notes": "Vendored unmodified from upstream python/pythoncapi-compat." - }, - "externalReferences": [ - { - "type": "vcs", - "url": "https://github.com/python/pythoncapi-compat", - }, - ], - }, ] native_deps = [ + { + "bom-ref": "pkg:generic/freetype2", + "type": "library", + "name": "FreeType", + "version": versions["freetype"], + "scope": "optional", + "description": "Font rendering (optional, used by PIL._imagingft). " + "Required for text/font support.", + "licenses": [{"license": {"id": "FTL"}}], + "externalReferences": [ + {"type": "website", "url": "https://freetype.org"}, + { + "type": "distribution", + "url": "https://download.savannah.gnu.org/releases/freetype/", + }, + ], + }, + { + "bom-ref": "pkg:generic/fribidi", + "type": "library", + "name": "FriBiDi", + "version": versions["fribidi"], + "scope": "optional", + "description": "Unicode bidi algorithm library (optional, " + "loaded at runtime by fribidi-shim).", + "licenses": [{"license": {"id": "LGPL-2.1-or-later"}}], + "externalReferences": [ + {"type": "website", "url": "https://github.com/fribidi/fribidi"}, + { + "type": "distribution", + "url": "https://github.com/fribidi/fribidi/releases", + }, + ], + }, + { + "bom-ref": "pkg:generic/harfbuzz", + "type": "library", + "name": "HarfBuzz", + "version": versions["harfbuzz"], + "scope": "optional", + "description": "Text shaping (optional, required by libraqm " + "for complex text layout).", + "licenses": [{"license": {"id": "MIT"}}], + "externalReferences": [ + {"type": "website", "url": "https://harfbuzz.github.io"}, + { + "type": "distribution", + "url": "https://github.com/harfbuzz/harfbuzz/releases", + }, + ], + }, + { + "bom-ref": "pkg:generic/libavif", + "type": "library", + "name": "libavif", + "version": versions["libavif"], + "scope": "optional", + "description": "AVIF codec (optional, used by PIL._avif).", + "licenses": [{"license": {"id": "BSD-2-Clause"}}], + "externalReferences": [ + {"type": "website", "url": "https://github.com/AOMediaCodec/libavif"}, + { + "type": "distribution", + "url": "https://github.com/AOMediaCodec/libavif/releases", + }, + ], + }, + { + "bom-ref": "pkg:generic/libimagequant", + "type": "library", + "name": "libimagequant", + "version": versions["libimagequant"], + "scope": "optional", + "description": "Improved colour quantization (optional).", + "licenses": [{"license": {"id": "GPL-3.0-or-later"}}], + "externalReferences": [ + {"type": "website", "url": "https://pngquant.org/lib/"}, + { + "type": "distribution", + "url": "https://github.com/ImageOptim/libimagequant/tags", + }, + ], + }, { "bom-ref": "pkg:generic/libjpeg", "type": "library", "name": "libjpeg / libjpeg-turbo", + "version": versions["jpegturbo"], "description": "JPEG codec (required by default; disable with " - "-C jpeg=disable). Tested with libjpeg 6b/8/9-9d " - "and libjpeg-turbo 2-3.", + "-C jpeg=disable).", "licenses": [ {"license": {"id": "IJG"}}, {"license": {"id": "BSD-3-Clause"}}, @@ -259,24 +348,13 @@ def generate(version: str) -> dict: }, ], }, - { - "bom-ref": "pkg:generic/zlib", - "type": "library", - "name": "zlib", - "description": "Deflate/PNG compression (required by default; " - "disable with -C zlib=disable).", - "licenses": [{"license": {"id": "Zlib"}}], - "externalReferences": [ - {"type": "website", "url": "https://zlib.net"}, - {"type": "distribution", "url": "https://zlib.net"}, - ], - }, { "bom-ref": "pkg:generic/libtiff", "type": "library", "name": "libtiff", + "version": versions["tiff"], "scope": "optional", - "description": "TIFF codec (optional). Tested with libtiff 4.0-4.7.1.", + "description": "TIFF codec (optional).", "licenses": [{"license": {"id": "libtiff"}}], "externalReferences": [ {"type": "website", "url": "https://libtiff.gitlab.io/libtiff/"}, @@ -286,42 +364,11 @@ def generate(version: str) -> dict: }, ], }, - { - "bom-ref": "pkg:generic/freetype2", - "type": "library", - "name": "FreeType", - "scope": "optional", - "description": "Font rendering (optional, used by PIL._imagingft). " - "Required for text/font support.", - "licenses": [{"license": {"id": "FTL"}}], - "externalReferences": [ - {"type": "website", "url": "https://freetype.org"}, - { - "type": "distribution", - "url": "https://download.savannah.gnu.org/releases/freetype/", - }, - ], - }, - { - "bom-ref": "pkg:generic/littlecms2", - "type": "library", - "name": "Little CMS 2", - "scope": "optional", - "description": "Colour management (optional, used by PIL._imagingcms). " - "Tested with lcms2 2.7-2.18.", - "licenses": [{"license": {"id": "MIT"}}], - "externalReferences": [ - {"type": "website", "url": "https://www.littlecms.com"}, - { - "type": "distribution", - "url": "https://github.com/mm2/Little-CMS/releases", - }, - ], - }, { "bom-ref": "pkg:generic/libwebp", "type": "library", "name": "libwebp", + "version": versions["libwebp"], "scope": "optional", "description": "WebP codec (optional, used by PIL._webp).", "licenses": [{"license": {"id": "BSD-3-Clause"}}], @@ -336,90 +383,11 @@ def generate(version: str) -> dict: }, ], }, - { - "bom-ref": "pkg:generic/openjpeg", - "type": "library", - "name": "OpenJPEG", - "scope": "optional", - "description": "JPEG 2000 codec (optional). " - "Tested with openjpeg 2.0.0-2.5.4.", - "licenses": [{"license": {"id": "BSD-2-Clause"}}], - "externalReferences": [ - {"type": "website", "url": "https://www.openjpeg.org"}, - { - "type": "distribution", - "url": "https://github.com/uclouvain/openjpeg/releases", - }, - ], - }, - { - "bom-ref": "pkg:generic/libavif", - "type": "library", - "name": "libavif", - "scope": "optional", - "description": "AVIF codec (optional, used by PIL._avif). " - "Requires libavif >= 1.0.0.", - "licenses": [{"license": {"id": "BSD-2-Clause"}}], - "externalReferences": [ - {"type": "website", "url": "https://github.com/AOMediaCodec/libavif"}, - { - "type": "distribution", - "url": "https://github.com/AOMediaCodec/libavif/releases", - }, - ], - }, - { - "bom-ref": "pkg:generic/harfbuzz", - "type": "library", - "name": "HarfBuzz", - "scope": "optional", - "description": "Text shaping (optional, required by libraqm " - "for complex text layout).", - "licenses": [{"license": {"id": "MIT"}}], - "externalReferences": [ - {"type": "website", "url": "https://harfbuzz.github.io"}, - { - "type": "distribution", - "url": "https://github.com/harfbuzz/harfbuzz/releases", - }, - ], - }, - { - "bom-ref": "pkg:generic/fribidi", - "type": "library", - "name": "FriBiDi", - "scope": "optional", - "description": "Unicode bidi algorithm library (optional, " - "loaded at runtime by fribidi-shim).", - "licenses": [{"license": {"id": "LGPL-2.1-or-later"}}], - "externalReferences": [ - {"type": "website", "url": "https://github.com/fribidi/fribidi"}, - { - "type": "distribution", - "url": "https://github.com/fribidi/fribidi/releases", - }, - ], - }, - { - "bom-ref": "pkg:generic/libimagequant", - "type": "library", - "name": "libimagequant", - "scope": "optional", - "description": "Improved colour quantization (optional). " - "Tested with 2.6-4.4.1.", - "licenses": [{"license": {"id": "GPL-3.0-or-later"}}], - "externalReferences": [ - {"type": "website", "url": "https://pngquant.org/lib/"}, - { - "type": "distribution", - "url": "https://github.com/ImageOptim/libimagequant/tags", - }, - ], - }, { "bom-ref": "pkg:generic/libxcb", "type": "library", "name": "libxcb", + "version": versions["libxcb"], "scope": "optional", "description": "X11 screen-grab support (optional, " "used by PIL._imaging on macOS and Linux).", @@ -432,6 +400,38 @@ def generate(version: str) -> dict: }, ], }, + { + "bom-ref": "pkg:generic/littlecms2", + "type": "library", + "name": "Little CMS 2", + "version": versions["lcms2"], + "scope": "optional", + "description": "Colour management (optional, used by PIL._imagingcms).", + "licenses": [{"license": {"id": "MIT"}}], + "externalReferences": [ + {"type": "website", "url": "https://www.littlecms.com"}, + { + "type": "distribution", + "url": "https://github.com/mm2/Little-CMS/releases", + }, + ], + }, + { + "bom-ref": "pkg:generic/openjpeg", + "type": "library", + "name": "OpenJPEG", + "version": versions["openjpeg"], + "scope": "optional", + "description": "JPEG 2000 codec (optional).", + "licenses": [{"license": {"id": "BSD-2-Clause"}}], + "externalReferences": [ + {"type": "website", "url": "https://www.openjpeg.org"}, + { + "type": "distribution", + "url": "https://github.com/uclouvain/openjpeg/releases", + }, + ], + }, { "bom-ref": "pkg:pypi/pybind11", "type": "library", @@ -447,6 +447,19 @@ def generate(version: str) -> dict: }, ], }, + { + "bom-ref": "pkg:generic/zlib", + "type": "library", + "name": "zlib", + "version": versions["zlib-ng"], + "description": "Deflate/PNG compression (required by default; " + "disable with -C zlib=disable).", + "licenses": [{"license": {"id": "Zlib"}}], + "externalReferences": [ + {"type": "website", "url": "https://zlib.net"}, + {"type": "distribution", "url": "https://zlib.net"}, + ], + }, ] dependencies = [ @@ -455,43 +468,43 @@ def generate(version: str) -> dict: "dependsOn": [e["bom-ref"] for e in ext_components], }, { - "ref": f"{purl}#c-ext/PIL._imaging", - "dependsOn": [ - "pkg:generic/libjpeg", - "pkg:generic/zlib", - "pkg:generic/libtiff", - "pkg:generic/openjpeg", - "pkg:generic/libimagequant", - "pkg:generic/libxcb", - ], + "ref": f"{purl}#c-ext/PIL._avif", + "dependsOn": ["pkg:generic/libavif"], }, { - "ref": f"{purl}#c-ext/PIL._imagingft", + "ref": f"{purl}#c-ext/PIL._imaging", "dependsOn": [ - "pkg:generic/freetype2", - f"{purl}#thirdparty/raqm", - f"{purl}#thirdparty/fribidi-shim", - "pkg:generic/harfbuzz", - "pkg:generic/fribidi", + "pkg:generic/libimagequant", + "pkg:generic/libjpeg", + "pkg:generic/libtiff", + "pkg:generic/libxcb", + "pkg:generic/openjpeg", + "pkg:generic/zlib", ], }, { "ref": f"{purl}#c-ext/PIL._imagingcms", "dependsOn": ["pkg:generic/littlecms2"], }, + { + "ref": f"{purl}#c-ext/PIL._imagingft", + "dependsOn": [ + "pkg:generic/freetype2", + "pkg:generic/fribidi", + "pkg:generic/harfbuzz", + f"{purl}#thirdparty/fribidi-shim", + f"{purl}#thirdparty/raqm", + ], + }, { "ref": f"{purl}#c-ext/PIL._webp", "dependsOn": ["pkg:generic/libwebp"], }, - { - "ref": f"{purl}#c-ext/PIL._avif", - "dependsOn": ["pkg:generic/libavif"], - }, { "ref": f"{purl}#thirdparty/raqm", "dependsOn": [ - f"{purl}#thirdparty/fribidi-shim", "pkg:generic/harfbuzz", + f"{purl}#thirdparty/fribidi-shim", ], }, ] diff --git a/.gitignore b/.gitignore index 3033c2ea7..4e9803957 100644 --- a/.gitignore +++ b/.gitignore @@ -97,3 +97,6 @@ pillow-test-images.zip # pyinstaller *.spec + +# Generated SBOM +pillow-*.cdx.json