diff --git a/.gitattributes b/.gitattributes index 331c9fd..764bf45 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,6 +12,6 @@ tools/owned_vm_request.cs text eol=lf tools/run_vm_request_queue.ps1 text eol=lf tools/fixtures/vm_request_*.ps1 text eol=lf third_party/conpty/LICENSE text eol=lf -third_party/qt/LICENSES/LGPL-3.0-only.txt text eol=lf +third_party/qt/LICENSES/*.txt text eol=lf third_party/msvc_runtime/NOTICE.txt text eol=lf experiments/core/fixtures/*.bin binary diff --git a/.github/workflows/qt-cpp.yml b/.github/workflows/qt-cpp.yml index 8a12dba..2451d35 100644 --- a/.github/workflows/qt-cpp.yml +++ b/.github/workflows/qt-cpp.yml @@ -20,9 +20,16 @@ jobs: with: python-version: '3.12' - name: Verify preparation failure contracts - run: python -m unittest tools.test_prepare_qt_build tools.test_prepare_msvc_runtime tools.test_msvc_runtime tools.test_stage_qt_product -v + run: python -m unittest tools.test_prepare_qt_build tools.test_prepare_msvc_runtime tools.test_msvc_runtime tools.test_stage_qt_product tools.test_build_qt_component_inventory -v - name: Prepare manifest-pinned Qt qtbase, Microsoft ConPTY and CRT run: python -m tools.prepare_qt_build + - name: Verify deployed Qt component inventory against the pinned archive and SBOM + run: | + python -m tools.build_qt_component_inventory check ` + --cache local/qt-downloads ` + --sbom local/qt-build-deps/qt/sbom/qtbase-6.10.3.spdx.json ` + --sdk-dir local/qt-build-deps/qt + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - name: Preserve path-free dependency preparation identity if: always() uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 @@ -64,6 +71,8 @@ jobs: path: | local/qt-product-staging.json local/qt-product-staging/product-manifest.json + local/qt-product-staging/licenses/qt/components.json + local/qt-product-staging/QT-THIRD-PARTY-NOTICES.txt local/qt-product-staging/THIRD-PARTY-NOTICES.txt - name: Record complete path-free runtime manifests run: | diff --git a/docs/FEATURES.md b/docs/FEATURES.md index c3f0244..da80a49 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -41,7 +41,7 @@ `DA1` 当前只在 strict/replay 路径回复 `ESC[?6c`;recovery 产品路径保持静默。`?1004`/`?9001` 与单参数 `CSI 1t/2t/3t` 接受后忽略,不代表焦点上报、Win32 输入模式或窗口操作已实现。`?2004`、鼠标模式、DA2 和 OSC 10/11 仍缺;详见 [#28](https://github.com/JavaZeroo/termforge/issues/28)。 -Qt 构建显式准备并部署[固定微软 CRT 14.51.36247.0](../third_party/msvc_runtime/README.md),不安装到 System32。隔离 Windows 的[限定加载与 cmd 验证](../experiments/shell/results/2026-10-29-qt-crt-deploy/README.md)保留原包失败、原 52 文件不变且仅追加 CRT/原许可后的成功,以及新源码包的独立验证;它不解除完整产品打包、Qt/第三方分发审计、实际 DPI/IME 或物理呈现的验收缺口。正式入口现有 [`packaging/qt-product/manifest.json`](../packaging/qt-product/manifest.json) 冻结的工程 staging:只接收固定依赖准备摘要和逐文件字节都匹配的构建目录,输出路径无关的逐文件 SHA-256 与许可索引,并拒绝测试夹具或未固定来源;它仍不是 R2 包,干净 Windows 运行、96/144 DPI、完整 Qt 第三方许可清单与最终验收未完成。 +Qt 构建显式准备并部署[固定微软 CRT 14.51.36247.0](../third_party/msvc_runtime/README.md),不安装到 System32。隔离 Windows 的[限定加载与 cmd 验证](../experiments/shell/results/2026-10-29-qt-crt-deploy/README.md)保留原包失败、原 52 文件不变且仅追加 CRT/原许可后的成功,以及新源码包的独立验证;它不解除完整产品打包、实际 DPI/IME 或物理呈现的验收缺口。正式入口现有 [`packaging/qt-product/manifest.json`](../packaging/qt-product/manifest.json) 冻结的工程 staging:只接收固定依赖准备摘要和逐文件字节都匹配的构建目录,输出路径无关的逐文件 SHA-256 与许可索引,并拒绝测试夹具或未固定来源。Qt 部署组件来源/许可材料已按固定 SBOM 与源码归档整理为 [`components.json`](../third_party/qt/components.json)(42 个组件、22 份规范文本,明确区分未部署声明与内部构建声明),但仍标为 `materials_prepared_user_review_pending`;对应源码/替换条件、干净 Windows 运行、96/144 DPI 与最终验收未完成,staging 也不是 R2 包。 官方参考的基础文字行为已按 [R1-01 合同](research/windterm-r1-text-contract.md)完成两组各两轮的自动取证;这为独立实现提供行为依据,产品能力仍按下表分别验收。 @@ -92,7 +92,7 @@ Qt 构建显式准备并部署[固定微软 CRT 14.51.36247.0](../third_party/ms | 八会话文字工作流 | **限定验收**:[R1 固定源码整体验收](../experiments/shell/results/2026-10-24-r1-system-workflow/validation.json)覆盖同次 8 会话/拒绝第 9 个、后台有限洪流、历史/Find/实际选择与 CF 复制/确认粘贴/真实拼音、切换缩放、淘汰、取消关闭和重复回收;实际字节、目标隔离、动作与 Job/desktop 回收有独立审计 | 限定 Windows 固定拼音、本地 cmd 与有界负载;这是固定 R1 配置的组合验收,不能替代 R2 候选/新后端组合。实际呈现、常用 TUI、长期稳定及 UI/性能等价仍未验收 | R1 | | 活体资源与滚动端点 | **限定测量**:普通启动默认关闭;[R1 组合审计](../experiments/shell/results/2026-10-24-r1-system-workflow/validation.json)绑定实际接收、state 与同 revision 的 WM_PAINT/BitBlt/GdiFlush 提交,保留跨时钟校准与阶段资源,可离线重算 | launcher-tree 不等于 UI 归因;观察进程成本不等于增量采样成本,短命进程及退出 CPU 可能漏采。短驻留不证明长期无泄漏,`presented_done=null`,不构成性能通过 | R1;扩展 R4 / R5 | | 自动正确性与构建 | **限定验收**:Windows shell/ConPTY/呈现及 Windows/Linux 核心 CI、差分/恢复/队列/生命周期场景 | 产品打包、干净机器使用、依赖升级、长期回归和更广平台矩阵;#40 的 CI 纯夹具超时、窄窗口选择 #73、四 shell 原事件 #80、hosted 准备 #81 和[复制夹具 OpenClipboard 5 #85](https://github.com/JavaZeroo/termforge/issues/85) 等原失败已按各责任项记录修正或用户接受的未复现收口;当前开放的是 #44/#80/#99,由 #38 汇总;#72 保存判据与 #80 同步条件的限定修正不代替其他配置或未知根因验收 | R2 / R4 | -| Windows 产品交付 | **实现中,未验收**:首个 [v0.1.0-alpha.1 预发布](releases/v0.1.0-alpha.1.md)提供 Windows x64、静态 MSVC 运行库、附资源许可和构建身份的免安装 ZIP;正式 Qt 路线已有可复现的工程 staging/清单入口(见上),但没有正式 Qt 产品包。两者均未签名,已验环境限 Windows 11 本机与 Server 2025 CI,布局仍写入 LOCALAPPDATA | 旧 Win32 体验包不是正式 Qt 路线的 R2 基础开发包;staging 也不等于产品包或验收。干净机器与更广平台矩阵、Qt 第三方分发审计、签名/安装、配置升级及持续运行仍待完成。Windows 10 未验收,Server 2022 句柄基线已按 ADR-0009 改记录制,不代表产品在该平台验收 | R2 / R3 | +| Windows 产品交付 | **实现中,未验收**:首个 [v0.1.0-alpha.1 预发布](releases/v0.1.0-alpha.1.md)提供 Windows x64、静态 MSVC 运行库、附资源许可和构建身份的免安装 ZIP;正式 Qt 路线已有可复现的工程 staging/清单入口与部署组件来源/许可材料(见上),但没有正式 Qt 产品包。两者均未签名,已验环境限 Windows 11 本机与 Server 2025 CI,布局仍写入 LOCALAPPDATA | 旧 Win32 体验包不是正式 Qt 路线的 R2 基础开发包;staging 与组件清单也不等于产品包、对应源码交付或验收。干净机器与更广平台矩阵、Qt 对应源码/替换条件审查、签名/安装、配置升级及持续运行仍待完成。Windows 10 未验收,Server 2022 句柄基线已按 ADR-0009 改记录制,不代表产品在该平台验收 | R2 / R3 | | Linux/macOS 与其他架构 | **未实现**客户端;Linux 核心 CI 已有。[官方平台范围台账](../research/windterm-2.7.0-platform-scope.md)已固定 2.7.0 的 Windows x86/x64、macOS x64、Linux x64 资产及声明下限;这不是 TermForge 支持或实测结论 | 最终需真实 Linux/macOS 客户端;平台调查可提前进行,整合及完整验收排在 Windows 11 x64 完整版本之后。其他系统版本、最低版本和架构由用户后续明确;旧系统及 ARM 等保持调查记录,不自动承诺或排除,也不能由核心 CI 推断产品支持 | 持续调查;R5 全平台出口 | | 吞吐、响应、内存与稳定性 | **实现中,未验收**:已有机制实验、连续 CPU 区间校准与合成回归;候选字素改动的受限诊断中 project/interactive 吞吐中位数约下降 16%/9%,由 [#54](https://github.com/JavaZeroo/termforge/issues/54) 跟踪。[冻结批次执行器](../experiments/measure/R54-COST.md#冻结批次执行器windows)核对构建来源、原始输出、停止规则与逐轮配对统计;[独立 hosted 构建与实测](../experiments/measure/results/2026-10-27-r54-hosted/README.md)已验证来源和失败保留,但首批因环境护栏停止,尚无完整成本批次;[共享宿主CPU诊断](../experiments/measure/results/2026-10-27-r54-cpu-boundary/README.md)及[新hosted六位置](../experiments/measure/results/2026-10-27-r54-cpu-hosted/README.md)分别记录完整子进程/执行器分量;后者仍有3.333%–5.263%未归属余额,不改原护栏或判成本通过 | 旧诊断的共享宿主、allocator 包装与缺少真实呈现/输入时延端点使其不构成正式预算;新的不完整批次也不作吞吐结论。仍需同负载/同正确性、无插桩对照、观测开销和长期/多会话公平性;可靠原版基线后提出逐项预算及允许波动范围,**由用户明确确认**。与 WindTerm 的实际差距**待取证** | 当前优先;贯穿 R1–R5 | | 大历史与动态内存压缩 | **未实现**产品能力;WindTerm 压缩属于官方性能声明,内部机制尚未证实 | 1/10/100 万行等明确规模下的内存/滚动/搜索/淘汰实验;根据瓶颈决定独立存储/压缩实现 | R4 | diff --git a/packaging/qt-product/manifest.json b/packaging/qt-product/manifest.json index 77a472c..bc192cd 100644 --- a/packaging/qt-product/manifest.json +++ b/packaging/qt-product/manifest.json @@ -71,10 +71,9 @@ }, "qt": { "license_manifest": "third_party/qt/manifest.json", - "bundled_texts": [ - "licenses/LGPL-3.0-only.txt" - ], - "status": "third_party_component_inventory_pending" + "component_inventory": "third_party/qt/components.json", + "third_party_notices": "QT-THIRD-PARTY-NOTICES.txt", + "status": "component_inventory_prepared_user_review_pending" }, "conpty": { "license_manifest": "third_party/conpty/manifest.json", @@ -108,7 +107,7 @@ "r2_acceptance": false, "clean_machine_run": "not_performed", "single_screen_96_144_dpi": "not_verified_in_this_slice", - "full_third_party_license_inventory": "pending", + "full_third_party_license_inventory": "materials_prepared_user_review_pending", "performance_equivalence": false } } diff --git a/src/qt/README.md b/src/qt/README.md index f3df1ea..47c8af6 100644 --- a/src/qt/README.md +++ b/src/qt/README.md @@ -42,11 +42,11 @@ python -m tools.stage_qt_product stage ` python -m tools.stage_qt_product verify --staging local/qt-product-staging ``` -staging 只接收 [`packaging/qt-product/manifest.json`](../../packaging/qt-product/manifest.json) 冻结的文件集合,并要求依赖准备摘要、固定 Qt SDK 树哈希、ConPTY/CRT/字体许可标识和每个实际文件字节都匹配;缺文件、测试夹具、额外文件、来源不符或摘要与当前仓库清单不一致都会明确失败。输出 `product-manifest.json` 记录 source commit/tree、构建参数、入口、逐文件 SHA-256、许可文件与仍未闭合的分发项,不含本机绝对路径;同目录由 `tools/msvc_runtime.py manifest` 生成的 `runtime-manifest.json` 视为派生证据,不进入 staging。本地产物只写入忽略的 `local/`。 +staging 只接收 [`packaging/qt-product/manifest.json`](../../packaging/qt-product/manifest.json) 冻结的文件集合,并要求依赖准备摘要、固定 Qt SDK 树哈希、ConPTY/CRT/字体许可标识和每个实际文件字节都匹配;缺文件、测试夹具、额外文件、来源不符或摘要与当前仓库清单不一致都会明确失败。Qt 部署组件清单 [`components.json`](../../third_party/qt/components.json) 会对照固定 SDK 的 SBOM 重新推导并核验,随后连同 22 份规范许可文本、`QT-THIRD-PARTY-NOTICES.txt` 和机器可读清单副本一起进入 staging。输出 `product-manifest.json` 记录 source commit/tree、构建参数、入口、逐文件 SHA-256、部署组件证据、许可文件与仍未闭合的分发项,不含本机绝对路径;同目录由 `tools/msvc_runtime.py manifest` 生成的 `runtime-manifest.json` 视为派生证据,不进入 staging。本地产物只写入忽略的 `local/`。 当前主线注册的 Qt CTest 包括上述六项与 `qt_terminal_modes_retained`(只缩宽的保留/投影契约)、`qt_unicode_render`(固定 Unicode 样本的独立接收 + 离屏绘制/fallback 记录)、`qt_eight_session`(八会话目标隔离与生命周期);IME 合成事件检查在 `qt_cpp_shell` 内。历史冻结包的 `qt_ime_input_test.exe` 不属于当前主线构建目标,不用于替代这组验证。旧六阶段 `--resize` 仍以显式诊断运行并保留失败,不注册进默认 CI。 -固定 ConPTY/CRT 输入缺失或篡改时构建明确失败;实际工具集更新到固定 CRT 之外时须重新审查依赖。产品中的 shell 启动失败保留可关闭的错误窗口。随目录保留 Qt 动态运行库、平台插件、`conpty-backend/`、`assets/fonts/`、十个固定 CRT DLL 及其原许可/NOTICE;每次构建重新校验并部署 CRT,不运行安装器、不修改 System32。windeployqt 显式跳过系统 D3D/DXC 重分发文件;`icuuc.dll` 由 Windows 11 提供,构建目录中由 windeployqt 从 System32 复制的副本在 staging 核对一致后被排除,不随包分发。`tools/msvc_runtime.py manifest` 仍可记录构建目录的全部运行时文件。当前产物是工程候选 staging,不是 R2 包:干净 Windows 运行、单屏 96/144 DPI、完整 IME/TUI/reliability、Qt 第三方分发审计及最终包验收仍未完成。 +固定 ConPTY/CRT 输入缺失或篡改时构建明确失败;实际工具集更新到固定 CRT 之外时须重新审查依赖。产品中的 shell 启动失败保留可关闭的错误窗口。随目录保留 Qt 动态运行库、平台插件、`conpty-backend/`、`assets/fonts/`、十个固定 CRT DLL 及其原许可/NOTICE;每次构建重新校验并部署 CRT,不运行安装器、不修改 System32。windeployqt 显式跳过系统 D3D/DXC 重分发文件;`icuuc.dll` 由 Windows 11 提供,构建目录中由 windeployqt 从 System32 复制的副本在 staging 核对一致后被排除,不随包分发。`tools/msvc_runtime.py manifest` 仍可记录构建目录的全部运行时文件。当前产物是工程候选 staging,不是 R2 包:Qt 部署组件来源/许可材料已整理(42 个组件、22 份许可文本,`materials_prepared_user_review_pending`),但对应源码/替换条件审查、干净 Windows 运行、单屏 96/144 DPI、完整 IME/TUI/reliability 及最终包验收仍未完成。 ## 独立验证面 diff --git a/third_party/qt/LICENSES/Apache-2.0.txt b/third_party/qt/LICENSES/Apache-2.0.txt new file mode 100644 index 0000000..136d900 --- /dev/null +++ b/third_party/qt/LICENSES/Apache-2.0.txt @@ -0,0 +1,61 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +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. diff --git a/third_party/qt/LICENSES/BSD-2-Clause.txt b/third_party/qt/LICENSES/BSD-2-Clause.txt new file mode 100644 index 0000000..7e7fb71 --- /dev/null +++ b/third_party/qt/LICENSES/BSD-2-Clause.txt @@ -0,0 +1,10 @@ + + +Copyright (c) . + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/qt/LICENSES/BSD-3-Clause.txt b/third_party/qt/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000..b91bbd8 --- /dev/null +++ b/third_party/qt/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,9 @@ +Copyright (c) . + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/qt/LICENSES/CC0-1.0.txt b/third_party/qt/LICENSES/CC0-1.0.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/third_party/qt/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/third_party/qt/LICENSES/FTL.txt b/third_party/qt/LICENSES/FTL.txt new file mode 100644 index 0000000..c406d15 --- /dev/null +++ b/third_party/qt/LICENSES/FTL.txt @@ -0,0 +1,169 @@ + The FreeType Project LICENSE + ---------------------------- + + 2006-Jan-27 + + Copyright 1996-2002, 2006 by + David Turner, Robert Wilhelm, and Werner Lemberg + + + +Introduction +============ + + The FreeType Project is distributed in several archive packages; + some of them may contain, in addition to the FreeType font engine, + various tools and contributions which rely on, or relate to, the + FreeType Project. + + This license applies to all files found in such packages, and + which do not fall under their own explicit license. The license + affects thus the FreeType font engine, the test programs, + documentation and makefiles, at the very least. + + This license was inspired by the BSD, Artistic, and IJG + (Independent JPEG Group) licenses, which all encourage inclusion + and use of free software in commercial and freeware products + alike. As a consequence, its main points are that: + + o We don't promise that this software works. However, we will be + interested in any kind of bug reports. (`as is' distribution) + + o You can use this software for whatever you want, in parts or + full form, without having to pay us. (`royalty-free' usage) + + o You may not pretend that you wrote this software. If you use + it, or only parts of it, in a program, you must acknowledge + somewhere in your documentation that you have used the + FreeType code. (`credits') + + We specifically permit and encourage the inclusion of this + software, with or without modifications, in commercial products. + We disclaim all warranties covering The FreeType Project and + assume no liability related to The FreeType Project. + + + Finally, many people asked us for a preferred form for a + credit/disclaimer to use in compliance with this license. We thus + encourage you to use the following text: + + """ + Portions of this software are copyright © The FreeType + Project (www.freetype.org). All rights reserved. + """ + + Please replace with the value from the FreeType version you + actually use. + + +Legal Terms +=========== + +0. Definitions +-------------- + + Throughout this license, the terms `package', `FreeType Project', + and `FreeType archive' refer to the set of files originally + distributed by the authors (David Turner, Robert Wilhelm, and + Werner Lemberg) as the `FreeType Project', be they named as alpha, + beta or final release. + + `You' refers to the licensee, or person using the project, where + `using' is a generic term including compiling the project's source + code as well as linking it to form a `program' or `executable'. + This program is referred to as `a program using the FreeType + engine'. + + This license applies to all files distributed in the original + FreeType Project, including all source code, binaries and + documentation, unless otherwise stated in the file in its + original, unmodified form as distributed in the original archive. + If you are unsure whether or not a particular file is covered by + this license, you must contact us to verify this. + + The FreeType Project is copyright (C) 1996-2000 by David Turner, + Robert Wilhelm, and Werner Lemberg. All rights reserved except as + specified below. + +1. No Warranty +-------------- + + THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO + USE, OF THE FREETYPE PROJECT. + +2. Redistribution +----------------- + + This license grants a worldwide, royalty-free, perpetual and + irrevocable right and license to use, execute, perform, compile, + display, copy, create derivative works of, distribute and + sublicense the FreeType Project (in both source and object code + forms) and derivative works thereof for any purpose; and to + authorize others to exercise some or all of the rights granted + herein, subject to the following conditions: + + o Redistribution of source code must retain this license file + (`FTL.TXT') unaltered; any additions, deletions or changes to + the original files must be clearly indicated in accompanying + documentation. The copyright notices of the unaltered, + original files must be preserved in all copies of source + files. + + o Redistribution in binary form must provide a disclaimer that + states that the software is based in part of the work of the + FreeType Team, in the distribution documentation. We also + encourage you to put an URL to the FreeType web page in your + documentation, though this isn't mandatory. + + These conditions apply to any software derived from or based on + the FreeType Project, not just the unmodified files. If you use + our work, you must acknowledge us. However, no fee need be paid + to us. + +3. Advertising +-------------- + + Neither the FreeType authors and contributors nor you shall use + the name of the other for commercial, advertising, or promotional + purposes without specific prior written permission. + + We suggest, but do not require, that you use one or more of the + following phrases to refer to this software in your documentation + or advertising materials: `FreeType Project', `FreeType Engine', + `FreeType library', or `FreeType Distribution'. + + As you have not signed this license, you are not required to + accept it. However, as the FreeType Project is copyrighted + material, only this license, or another one contracted with the + authors, grants you the right to use, distribute, and modify it. + Therefore, by using, distributing, or modifying the FreeType + Project, you indicate that you understand and accept all the terms + of this license. + +4. Contacts +----------- + + There are two mailing lists related to FreeType: + + o freetype@nongnu.org + + Discusses general use and applications of FreeType, as well as + future and wanted additions to the library and distribution. + If you are looking for support, start in this list if you + haven't found anything to help you in the documentation. + + o freetype-devel@nongnu.org + + Discusses bugs, as well as engine internals, design issues, + specific licenses, porting, etc. + + Our home page can be found at + + https://www.freetype.org + + +--- end of FTL.TXT --- diff --git a/third_party/qt/LICENSES/GPL-2.0-only.txt b/third_party/qt/LICENSES/GPL-2.0-only.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/third_party/qt/LICENSES/GPL-2.0-only.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/third_party/qt/LICENSES/HPND.txt b/third_party/qt/LICENSES/HPND.txt new file mode 100644 index 0000000..e54a695 --- /dev/null +++ b/third_party/qt/LICENSES/HPND.txt @@ -0,0 +1,21 @@ +Historical Permission Notice and Disclaimer + +Copyright + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies, and that both that +copyright notice and this permission notice appear in supporting +documentation , and that the name of +not be used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. +makes no representations about the suitability of this software for any +purpose. It is provided "as is" without express or implied warranty. + + DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS . IN NO +EVENT SHALL BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF +USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/third_party/qt/LICENSES/IJG.txt b/third_party/qt/LICENSES/IJG.txt new file mode 100644 index 0000000..eec5341 --- /dev/null +++ b/third_party/qt/LICENSES/IJG.txt @@ -0,0 +1,34 @@ +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. diff --git a/third_party/qt/LICENSES/Imlib2.txt b/third_party/qt/LICENSES/Imlib2.txt new file mode 100644 index 0000000..b8430d8 --- /dev/null +++ b/third_party/qt/LICENSES/Imlib2.txt @@ -0,0 +1,7 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies of the Software and its Copyright notices. In addition publicly documented acknowledgment must be given that this software has been used if no source code of this software is made available publicly. Making the source available publicly means including the source for this software with the distribution, or a method to get this software via some reasonable mechanism (electronic transfer via a network or media) as well as making an offer to supply the source on request. This Copyright notice serves as an offer to supply the source on on request as well. Instead of this, supplying acknowledgments of use of this software in either Copyright notices, Manuals, Publicity and Marketing documents or any documentation provided with any product containing this software. This License does not apply to any software that links to the libraries provided by this software (statically or dynamically), but only to the software provided. + +Please see the COPYING-PLAIN for a plain-english explanation of this notice and its intent. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/qt/LICENSES/Libpng.txt b/third_party/qt/LICENSES/Libpng.txt new file mode 100644 index 0000000..81c1c4d --- /dev/null +++ b/third_party/qt/LICENSES/Libpng.txt @@ -0,0 +1,73 @@ +This copy of the libpng notices is provided for your convenience. In case of any discrepancy between this copy and the notices in the file png.h that is included in the libpng distribution, the latter shall prevail. + +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + +If you modify libpng you may insert additional notices immediately following this sentence. + +This code is released under the libpng license. + +libpng versions 1.2.6, August 15, 2004, through 1.4.5, December 9, 2010, are Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.2.5 with the following individual added to the list of Contributing Authors + +Cosmin Truta + +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors + +Simon-Pierre Cadieux +Eric S. Raymond +Gilles Vollant + +and with the following additions to the disclaimer: + +There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-0.96, with the following individuals added to the list of Contributing Authors: + +Tom Lane +Glenn Randers-Pehrson +Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996, 1997 Andreas Digger +Distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: + +John Bowler +Kevin Bracey +Sam Bushell +Magnus Holmgren +Greg Roelofs +Tom Tanner + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: + +Andreas Dilger +Dave Martindale +Guy Eric Schalnat +Paul Schmidt +Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, including, without limitation, the warranties of merchantability and of fitness for any purpose. The Contributing Authors and Group 42, Inc. assume no liability for direct, indirect, incidental, special, exemplary, or consequential damages, which may result from the use of the PNG Reference Library, even if advised of the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented. + 2. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. + 3. This Copyright notice may not be removed or altered from any source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. + +A "png_get_copyright" function is available, for convenient use in "about" boxes and the like: + +printf("%s",png_get_copyright(NULL)); + +Also, the PNG logo (in PNG format, of course) is supplied in the files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +December 9, 2010 diff --git a/third_party/qt/LICENSES/LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception.txt b/third_party/qt/LICENSES/LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception.txt new file mode 100644 index 0000000..9f4ae05 --- /dev/null +++ b/third_party/qt/LICENSES/LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception.txt @@ -0,0 +1,12 @@ +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES +------------------------------------------ + +The second condition in the BSD licence (covering binary redistributions) does not apply all the way down a chain of software. If binary package A includes PCRE2, it must respect the condition, but if package B is software that includes package A, the condition is not imposed on package B unless it uses PCRE2 independently. diff --git a/third_party/qt/LICENSES/LicenseRef-ICC-License.txt b/third_party/qt/LICENSES/LicenseRef-ICC-License.txt new file mode 100644 index 0000000..e25b1d3 --- /dev/null +++ b/third_party/qt/LICENSES/LicenseRef-ICC-License.txt @@ -0,0 +1,10 @@ +For the file sRGB2014.icc: + +Copyright International Color Consortium, 2015 + +This profile is made available by the International Color Consortium, and may be copied, +distributed, embedded, made, used, and sold without restriction. Altered versions of this +profile shall have the original identification and copyright information removed and +shall not be misrepresented as the original profile. + +(original source location: http://www.color.org/srgbprofiles.xalter) diff --git a/third_party/qt/LICENSES/LicenseRef-Lcs-Telegraphics.txt b/third_party/qt/LICENSES/LicenseRef-Lcs-Telegraphics.txt new file mode 100644 index 0000000..6c03ad2 --- /dev/null +++ b/third_party/qt/LICENSES/LicenseRef-Lcs-Telegraphics.txt @@ -0,0 +1,2 @@ +The text and information contained in this file may be freely used, +copied, or distributed without compensation or licensing restrictions. diff --git a/third_party/qt/LICENSES/LicenseRef-SHA1-Public-Domain.txt b/third_party/qt/LICENSES/LicenseRef-SHA1-Public-Domain.txt new file mode 100644 index 0000000..2ebbf9a --- /dev/null +++ b/third_party/qt/LICENSES/LicenseRef-SHA1-Public-Domain.txt @@ -0,0 +1,3 @@ +100% free public domain implementation of the SHA-1 algorithm +by Dominik Reichl +Web: http://www.dominik-reichl.de/ diff --git a/third_party/qt/LICENSES/MIT-open-group.txt b/third_party/qt/LICENSES/MIT-open-group.txt new file mode 100644 index 0000000..8b6789a --- /dev/null +++ b/third_party/qt/LICENSES/MIT-open-group.txt @@ -0,0 +1,9 @@ + + +Copyright The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/qt/LICENSES/MIT.txt b/third_party/qt/LICENSES/MIT.txt new file mode 100644 index 0000000..bc65af3 --- /dev/null +++ b/third_party/qt/LICENSES/MIT.txt @@ -0,0 +1,11 @@ + + +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/third_party/qt/LICENSES/MPL-2.0.txt b/third_party/qt/LICENSES/MPL-2.0.txt new file mode 100644 index 0000000..d0a1fa1 --- /dev/null +++ b/third_party/qt/LICENSES/MPL-2.0.txt @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at https://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/third_party/qt/LICENSES/Unicode-3.0.txt b/third_party/qt/LICENSES/Unicode-3.0.txt new file mode 100644 index 0000000..739715c --- /dev/null +++ b/third_party/qt/LICENSES/Unicode-3.0.txt @@ -0,0 +1,39 @@ +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 2004-2023 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. diff --git a/third_party/qt/LICENSES/X11.txt b/third_party/qt/LICENSES/X11.txt new file mode 100644 index 0000000..e1cd1e0 --- /dev/null +++ b/third_party/qt/LICENSES/X11.txt @@ -0,0 +1,24 @@ +X11 License + +Copyright (C) 1996 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be used in +advertising or otherwise to promote the sale, use or other dealings in this Software +without prior written authorization from the X Consortium. + +X Window System is a trademark of X Consortium, Inc. diff --git a/third_party/qt/LICENSES/Zlib.txt b/third_party/qt/LICENSES/Zlib.txt new file mode 100644 index 0000000..9c57e18 --- /dev/null +++ b/third_party/qt/LICENSES/Zlib.txt @@ -0,0 +1,28 @@ + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* receiving +lengthy legal documents to sign. The sources are provided for free but without +warranty of any kind. The library has been entirely written by Jean-loup +Gailly and Mark Adler; it does not include third-party code. + +If you redistribute modified sources, we would appreciate that you include in +the file ChangeLog history information documenting your changes. Please read +the FAQ for more information on the distribution of modified source versions. + diff --git a/third_party/qt/LICENSES/libpng-2.0.txt b/third_party/qt/LICENSES/libpng-2.0.txt new file mode 100644 index 0000000..25f298f --- /dev/null +++ b/third_party/qt/LICENSES/libpng-2.0.txt @@ -0,0 +1,134 @@ +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE +========================================= + +PNG Reference Library License version 2 +--------------------------------------- + + * Copyright (c) 1995-2024 The PNG Reference Library Authors. + * Copyright (c) 2018-2024 Cosmin Truta. + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * Copyright (c) 1996-1997 Andreas Dilger. + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + +The software is supplied "as is", without warranty of any kind, +express or implied, including, without limitation, the warranties +of merchantability, fitness for a particular purpose, title, and +non-infringement. In no event shall the Copyright owners, or +anyone distributing the software, be liable for any damages or +other liability, whether in contract, tort or otherwise, arising +from, out of, or in connection with the software, or the use or +other dealings in the software, even if advised of the possibility +of such damage. + +Permission is hereby granted to use, copy, modify, and distribute +this software, or portions hereof, for any purpose, without fee, +subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you + use this software in a product, an acknowledgment in the product + documentation would be appreciated, but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + + +PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) +----------------------------------------------------------------------- + +libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are +Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are +derived from libpng-1.0.6, and are distributed according to the same +disclaimer and license as libpng-1.0.6 with the following individuals +added to the list of Contributing Authors: + + Simon-Pierre Cadieux + Eric S. Raymond + Mans Rullgard + Cosmin Truta + Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov + +and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of + the library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is + with the user. + +Some files in the "contrib" directory and some configure-generated +files that are distributed with libpng have other copyright owners, and +are released under other open source licenses. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from +libpng-0.96, and are distributed according to the same disclaimer and +license as libpng-0.96, with the following individuals added to the +list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, +and are distributed according to the same disclaimer and license as +libpng-0.88, with the following individuals added to the list of +Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +Some files in the "scripts" directory have other copyright owners, +but are released under this license. + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing +Authors and Group 42, Inc. disclaim all warranties, expressed or +implied, including, without limitation, the warranties of +merchantability and of fitness for any purpose. The Contributing +Authors and Group 42, Inc. assume no liability for direct, indirect, +incidental, special, exemplary, or consequential damages, which may +result from the use of the PNG Reference Library, even if advised of +the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + + 1. The origin of this source code must not be misrepresented. + + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, +without fee, and encourage the use of this source code as a component +to supporting the PNG file format in commercial products. If you use +this source code in a product, acknowledgment is not required but would +be appreciated. diff --git a/third_party/qt/README.md b/third_party/qt/README.md index 7fcac19..476f91b 100644 --- a/third_party/qt/README.md +++ b/third_party/qt/README.md @@ -49,10 +49,20 @@ CI 的 `windows-2025` 已实际解析到 `windows-2025-vs2026`,该映像没有 `windeployqt` 调用显式带 `--no-system-d3d-compiler --no-system-dxc-compiler`:系统 D3D 编译器与微软 DXC OOB 重分发文件既不在本仓库固定依赖中,也不是当前 Widgets 光栅入口静态链接的依赖,因此不从开发机 Windows SDK/System32 借用。`Qt6Core.dll` 静态导入的 `icuuc.dll` 由 Windows 11 System32 提供;构建目录中由 windeployqt 复制的副本只作为来源证据核对(必须与 System32 字节一致),staging 排除它而不随包分发。 -[`packaging/qt-product/manifest.json`](../../packaging/qt-product/manifest.json) 冻结正式入口实际部署的 Qt 库/插件集合、OS 提供项、被排除的系统重分发文件与许可证据。`python -m tools.stage_qt_product stage` 只接受该清单、当前固定依赖准备摘要、固定 SDK 树哈希与逐文件字节都匹配的构建目录,输出路径无关的 `product-manifest.json`(含 source commit/tree、构建参数、入口、逐文件 SHA-256 和许可证据);`verify` 子命令可重新核对已生成 staging 的文件集合与哈希。该 staging 是工程候选,不是 R2 包:干净 Windows 运行、单屏 96/144 DPI、完整第三方许可清单及最终包验收均未完成。 +[`packaging/qt-product/manifest.json`](../../packaging/qt-product/manifest.json) 冻结正式入口实际部署的 Qt 库/插件集合、OS 提供项、被排除的系统重分发文件与许可证据。`python -m tools.stage_qt_product stage` 只接受该清单、当前固定依赖准备摘要、固定 SDK 树哈希与逐文件字节都匹配的构建目录,输出路径无关的 `product-manifest.json`(含 source commit/tree、构建参数、入口、逐文件 SHA-256 和许可证据);它会带入 [components.json](components.json) 冻结的部署组件清单、22 份规范许可文本、机器可读清单副本与 `QT-THIRD-PARTY-NOTICES.txt`。`verify` 子命令可重新核对已生成 staging 的文件集合与哈希。该 staging 是工程候选,不是 R2 包:干净 Windows 运行、单屏 96/144 DPI、对应源码/替换条件审查及最终包验收均未完成。 + +## 部署组件与许可清单 + +[components.json](components.json) 由 `python -m tools.build_qt_component_inventory build` 从**同一固定 qtbase 6.10.3 源码归档**与 SDK 自带 SPDX SBOM 生成;`check` 子命令会重新解压固定归档、重算并逐字节比较已提交清单与许可文本,CI 每次运行该检查。证据分层如下: + +- **已部署组件(42 个)**:仅当 SBOM 包关系把第三方包连到实际部署的 Qt 模块/插件包时才列入;每个组件还须与源码归档中的 `qt_attribution.json` 条目(Id、版本、许可 id、许可文件)交叉核对。清单记录部署文件、上游来源、归属文件成员与 SHA-256、上游许可文件与版权声明。 +- **未部署声明**:源码树中存在但 SBOM 无对应包、归属模块未部署的声明分别列入 `declared_not_deployed`;仅通过内部构建/平台包可达的构建工具声明(如 extra-cmake-modules、KWin CMake 模块)列入 `excluded_attributions`,并标注理由。源码树中存在不等于部署二进制包含。 +- **字节身份限制(实测)**:固定归档内 SBOM 的 packaged-file 校验只含 SHA-1 且**与归档内 SDK 二进制不匹配**;因此 SBOM 仅作为模块/组件关系证据,部署文件字节身份由固定归档 SHA-256、`prepare_qt_build` SDK 树哈希和 staging 逐字节核对承担。该限制记录在清单 `sbom.binary_file_checksums` 中。 +- **许可文本**:22 个被引用许可 id 的规范文本从同一源码归档 `LICENSES/.txt` 提取并随仓库提交([LICENSES/](LICENSES/));组件原始的许可/版权文件身份记录在清单中而不重复提交。Qt 模块采用动态链接 LGPL-3.0-only 选项,其余备选许可文本不随包分发。 +- **状态**:`materials_prepared_user_review_pending`。对应源码交付、重链接/替换条件、法律与干净机器验证仍未完成;清单与 notice 是事实索引,不是再分发结论。 ## 许可与分发边界 Qt 模块保留自己的许可,不由项目 MIT 许可覆盖。[Qt 6.10 许可说明](https://doc.qt.io/qt-6.10/licensing.html)与 SDK SBOM/头文件显示,当前 Core、Gui、Widgets、Test 的模块许可选项包含 LGPL-3.0-only,以及相应 GPL/商业许可选项;manifest 保留精确 SPDX 表达式及实际 SBOM 身份。当前应用计划采用**动态链接的 LGPLv3 路径**,这不是对完整产品分发条件已经满足的声明。仓库随附从固定 qtbase 6.10.3 源码归档 `LICENSES/LGPL-3.0-only.txt` 提取的许可原文([LICENSES/LGPL-3.0-only.txt](LICENSES/LGPL-3.0-only.txt)),staging 会把该文本连同其归档成员身份与 SHA-256 一起带入产品目录。 -Qt 内还包含使用其他许可的第三方代码;不能仅凭模块级许可表达式代替实际部署文件清单。产品分发前仍须完成运行库/插件及第三方许可声明、对应源码与替换条件的核对,以及干净机器运行验证;当前记录只支持本地构建依赖的来源与身份。staging 的许可索引将该项明确标为 `third_party_component_inventory_pending`,不将其写成已完成的再分发结论。 +Qt 内还包含使用其他许可的第三方代码;不能仅凭模块级许可表达式代替实际部署文件清单。部署组件清单与规范许可文本已按固定 SBOM/源码归档整理,但产品分发前仍须完成对应源码与替换条件的核对,以及干净机器运行验证;当前记录只支持本地构建依赖、部署文件与许可材料的来源和身份。staging 的许可索引将该状态标为 `component_inventory_prepared_user_review_pending`,不将其写成已完成的再分发结论。 diff --git a/third_party/qt/components.json b/third_party/qt/components.json new file mode 100644 index 0000000..270abe4 --- /dev/null +++ b/third_party/qt/components.json @@ -0,0 +1,2438 @@ +{ + "schema": "termforge-qt-deployed-components-v1", + "scope": "Qt 6.10.3 third-party component and license evidence for the fixed Windows x64 product staging. Materials for review; not a legal redistribution conclusion.", + "review_status": "materials_prepared_user_review_pending", + "qt_version": "6.10.3", + "source": { + "url": "https://download.qt.io/archive/qt/6.10/6.10.3/submodules/qtbase-everywhere-src-6.10.3.tar.xz", + "bytes": 50509856, + "sha256": "383dc907816338f0cba72088a524c07458dfc69ce684ca9132fcc4fe91c24b0b" + }, + "sbom": { + "path": "sbom/qtbase-6.10.3.spdx.json", + "sha256": "51bdcf25ae10a6af0ce10030bf816ab10da0b2f70b35e0e9c55bd4b43241e659", + "spdx_version": "SPDX-2.3", + "created": "2026-03-27T14:37:20Z", + "binary_file_checksums": { + "algorithm": "SHA1", + "checked_files": 13, + "matching_files": 0, + "mismatched_files": [ + "Qt6Core.dll", + "Qt6Gui.dll", + "Qt6Network.dll", + "Qt6Widgets.dll", + "generic/qtuiotouchplugin.dll", + "imageformats/qgif.dll", + "imageformats/qico.dll", + "imageformats/qjpeg.dll", + "networkinformation/qnetworklistmanager.dll", + "platforms/qwindows.dll", + "styles/qmodernwindowsstyle.dll", + "tls/qcertonlybackend.dll", + "tls/qschannelbackend.dll" + ], + "note": "The SBOM ships in the pinned binary archive, but its packaged-file SHA-1 values do not match the archived SDK binaries. Per-file byte identity therefore comes from the pinned archive/SDK tree identity, not from SBOM file checksums." + } + }, + "method": { + "deployed_file_mapping": "Each staged Qt library/plugin maps to the single non-Debug SBOM packaged file; its owning SBOM package supplies the module/plugin class.", + "component_mapping": "Third-party packages reached from the owning package through DEPENDS_ON edges are included; traversal follows only third-party packages and stops at internal Qt packages. Existence in the source tree alone is not treated as shipped.", + "attribution_cross_check": "Each component's SBOM package comment is resolved to a qt_attribution.json member and entry index in the pinned source archive; Id, license ids, version and license files are verified.", + "license_texts": "Canonical LICENSES/.txt files come from the same pinned source archive; component-specific upstream license files are recorded by member and SHA-256." + }, + "deployed_files": { + "Qt6Core.dll": { + "module_package": "Core", + "component_ids": [ + "blake2", + "doubleconversion", + "easing", + "md4", + "md5", + "pcre2", + "pcre2-sljit", + "rfc6234", + "sha1", + "sha3_endian", + "sha3_keccak", + "siphash", + "tika-mimetypes", + "tinycbor", + "tlexpected", + "unicode-character-database", + "unicode-cldr", + "zlib" + ] + }, + "Qt6Gui.dll": { + "module_package": "Gui", + "component_ids": [ + "aglfn", + "d3d12memoryallocator", + "emoji-segmenter", + "freetype", + "freetype-bdf", + "freetype-pcf", + "freetype-zlib", + "grayraster", + "harfbuzz-ng", + "icc-srgb-color-profile", + "libpng", + "md4c", + "opengl-es2-headers", + "opengl-headers", + "rhi-miniengine-d3d12-mipmap", + "smooth-scaling-algorithm", + "vulkan-xml-spec", + "vulkanmemoryallocator", + "webgradients", + "xserverhelper", + "zlib" + ] + }, + "Qt6Network.dll": { + "module_package": "Network", + "component_ids": [ + "libpsl", + "psl-data", + "zlib" + ] + }, + "Qt6Widgets.dll": { + "module_package": "Widgets", + "component_ids": [] + }, + "generic/qtuiotouchplugin.dll": { + "module_package": "QTuioTouchPlugin", + "component_ids": [] + }, + "imageformats/qgif.dll": { + "module_package": "QGifPlugin", + "component_ids": [] + }, + "imageformats/qico.dll": { + "module_package": "QICOPlugin", + "component_ids": [] + }, + "imageformats/qjpeg.dll": { + "module_package": "QJpegPlugin", + "component_ids": [ + "libjpeg" + ] + }, + "networkinformation/qnetworklistmanager.dll": { + "module_package": "QNLMNIPlugin", + "component_ids": [] + }, + "platforms/qwindows.dll": { + "module_package": "QWindowsIntegrationPlugin", + "component_ids": [ + "wintab" + ] + }, + "styles/qmodernwindowsstyle.dll": { + "module_package": "QModernWindowsStylePlugin", + "component_ids": [] + }, + "tls/qcertonlybackend.dll": { + "module_package": "QTlsBackendCertOnlyPlugin", + "component_ids": [] + }, + "tls/qschannelbackend.dll": { + "module_package": "QSchannelBackendPlugin", + "component_ids": [] + } + }, + "components": { + "aglfn": { + "id": "aglfn", + "name": "Adobe Glyph List For New Fonts", + "version": "1.7", + "license_expression": "BSD-3-Clause", + "license_ids": [ + "BSD-3-Clause" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_aglfn" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/text/qt_attribution.json", + "entry_index": 0, + "bytes": 807, + "sha256": "73066a55ff52c6546753e1dc0802d8890d58e93e7efa394565cd8bdd0df0995b", + "qt_usage": "Used by PDF generator to make it easier for reader applications to resolve the original contents of rendered text.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/gui/text/LICENSE.AGLFN.txt", + "bytes": 1425, + "sha256": "40818155548ff41c67d3a40edf355e9658992b292c227f4c1147425cedc746c6" + } + ], + "copyright": "Copyright 2002, 2003, 2005, 2006, 2008, 2010, 2015 Adobe Systems" + }, + "source": { + "homepage": "https://github.com/adobe-type-tools/agl-aglfn", + "download_location": "https://github.com/adobe-type-tools/agl-aglfn", + "purl": "pkg:github/adobe-type-tools/agl-aglfn@$" + } + }, + "blake2": { + "id": "blake2", + "name": "BLAKE2 (reference implementation)", + "version": "ed1974ea83433eba7b2d95c5dcd9ac33cb847913", + "license_expression": "CC0-1.0 OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "CC0-1.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_blake2" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/blake2/qt_attribution.json", + "entry_index": 0, + "bytes": 926, + "sha256": "bab552307bdd03ed9a4cf7f8f1397c3d18d4dbee19ee576033284104785245be", + "qt_usage": "Used in Qt Core (QCryptographicHash).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/blake2/COPYING", + "bytes": 17914, + "sha256": "4103f471877ed0bae500752c5fcd7ecca409d4a4a8dc2ad40437daba60f1a2bc" + } + ], + "copyright": "Copyright 2012, Samuel Neves " + }, + "source": { + "homepage": "https://blake2.net/", + "download_location": "https://github.com/BLAKE2/BLAKE2/tree/ed1974ea83433eba7b2d95c5dcd9ac33cb847913", + "purl": "pkg:github/BLAKE2/BLAKE2@$" + } + }, + "d3d12memoryallocator": { + "id": "d3d12memoryallocator", + "name": "D3D12 Memory Allocator", + "version": "f128d39b7a95b4235bd228d231646278dc6c24b2", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_d3d12memoryallocator" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/D3D12MemoryAllocator/qt_attribution.json", + "entry_index": 0, + "bytes": 727, + "sha256": "182d7e5ed90dc592b01a50635c85f4039ca6f25f88ec4700b08faf6f07fda09e", + "qt_usage": "Memory management for the D3D12 backend of QRhi.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/D3D12MemoryAllocator/LICENSE.txt", + "bytes": 1099, + "sha256": "1b3941c52b26d42c510afbdf205a8b96a6d64f5a7b8ebff0287979fd91dfd52f" + } + ], + "copyright": "Copyright (c) 2019-2022 Advanced Micro Devices, Inc. All rights reserved." + }, + "source": { + "homepage": "https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator", + "download_location": "https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator", + "purl": "pkg:github/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator@$" + } + }, + "doubleconversion": { + "id": "doubleconversion", + "name": "Efficient Binary-Decimal and Decimal-Binary Conversion Routines for IEEE Doubles", + "version": "3.4.0", + "license_expression": "BSD-3-Clause", + "license_ids": [ + "BSD-3-Clause" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_doubleconversion" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/double-conversion/qt_attribution.json", + "entry_index": 0, + "bytes": 771, + "sha256": "4d9c7505a7c12e4e6b57bbee63af926c861abb5515cdf802b8f3491e321146fe", + "qt_usage": "Used in Qt Core. Configure with -system-doubleconversion or -no-doubleconversion to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/double-conversion/LICENSE", + "bytes": 1527, + "sha256": "4af93c12062c58058378de2397dc1c92bbff9ddfb1d583a01c84127557ce97ca" + } + ], + "copyright": "Copyright 2006-2012, the V8 project authors" + }, + "source": { + "homepage": "https://github.com/google/double-conversion", + "download_location": "https://github.com/google/double-conversion/releases/tag/v3.4.0", + "purl": "pkg:github/google/double-conversion@v$" + } + }, + "easing": { + "id": "easing", + "name": "Easing Equations by Robert Penner", + "version": "unknown", + "license_expression": "BSD-3-Clause", + "license_ids": [ + "BSD-3-Clause" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_easing" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/easing/qt_attribution.json", + "entry_index": 0, + "bytes": 471, + "sha256": "77d67a1db5882bb0b9a1278b014885bee45a4c059d1da9f835b6da5bc4b9c93d", + "qt_usage": "Used in Qt Core (QEasingCurve).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/easing/LICENSE", + "bytes": 1505, + "sha256": "92fac99458f1754b73edf50f9c9983e0efaa06ad96e2afd5e538c79f45b4b191" + } + ], + "copyright": "Copyright (c) 2001 Robert Penner" + }, + "source": { + "homepage": "http://robertpenner.com/easing/", + "download_location": "http://robertpenner.com/easing/", + "purl": null + } + }, + "emoji-segmenter": { + "id": "emoji-segmenter", + "name": "Emoji Segmenter", + "version": "0.4.0", + "license_expression": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_emoji-segmenter" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/emoji-segmenter/qt_attribution.json", + "entry_index": 0, + "bytes": 682, + "sha256": "9a980fc0f9e478d2a7e9a571d4cd234c259aaf8e2ea3fb60a0a7cf02cc3c3700", + "qt_usage": "Used in QtGui for parsing complex emoji sequences. Can be configured using the -emojisegmenter option.", + "qt_parts": null, + "license_files": [], + "copyright": "Copyright 2019 Google LLC" + }, + "source": { + "homepage": "https://github.com/google/emoji-segmenter", + "download_location": "https://github.com/google/emoji-segmenter/releases/tag/0.4.0", + "purl": "pkg:github/google/emoji-segmenter@$" + } + }, + "freetype": { + "id": "freetype", + "name": "Freetype 2", + "version": "2.14.3", + "license_expression": "FTL OR GPL-2.0-only", + "license_ids": [ + "FTL", + "GPL-2.0-only" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "BundledFreetype" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/qt_attribution.json", + "entry_index": 0, + "bytes": 5328, + "sha256": "628b68bf60eb3bc1616342bc3545b63be2392e78bbebbc4c19f49675dd2ac8a7", + "qt_usage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/LICENSE.txt", + "bytes": 26234, + "sha256": "bf543cdda11864477b8d2ca2aa9afc2aaa8f9133461b4d962ed6ec73646256a1" + } + ], + "copyright": "Copyright (c) 2007-2014 Adobe Systems Incorporated\nCopyright (c) 2004-2026 Albert Chin-A-Young\nCopyright (c) 2018-2026 Armin Hasitzka, David Turner, Robert Wilhelm, and Werner Lemberg\nCopyright (c) 2000 Computing Research Labs, New Mexico State University\nCopyright (c) 1996-2026 David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg\nCopyright (c) 2004-2026 David Turner, Robert Wilhelm, Werner Lemberg and George Williams\nCopyright (c) 2022-2026 David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti\nCopyright (c) 2008-2026 David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya\nCopyright (c) 2003-2026 David Turner, Robert Wilhelm, and Werner Lemberg\nCopyright (c) 2005-2026 David Turner\nCopyright (c) 2007-2026 Derek Clegg and Michael Toftdal\nCopyright (c) 2007 Dmitry Timoshkov for Codeweavers\nCopyright (c) 2001-2015 Francesco Zappa Nardelli\nCopyright (c) 2005, 2007, 2008, 2013 George Williams\nCopyright (c) 2013-2026 Google, Inc. Google Author(s) Behdad Esfahbod and Stuart Gill\nCopyright (c) 2013-2022 Google, Inc.\nCopyright (c) 2003 Huw D M Davies for Codeweavers\nCopyright (c) 2010-2026 Joel Klinghed\nCopyright (c) 1996-2026 Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg\nCopyright (c) 2003-2026 Masatake YAMATO and Redhat K.K.\nCopyright (c) 2004-2026 Masatake YAMATO, Redhat K.K, David Turner, Robert Wilhelm, and Werner Lemberg\nCopyright (c) 2019-2026 Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg\nCopyright (c) 2009-2026 Oran Agra and Mickey Gabel\nCopyright (c) 2007-2026 Rahul Bhalerao \nCopyright (c) 2002-2026 Roberto Alameda\nCopyright (c) 2015-2026 Werner Lemberg\nCopyright (c) 2004-2026 suzuki toshiya, Masatake YAMATO, Red Hat K.K., David Turner, Robert Wilhelm, and Werner Lemberg\nCopyright (c) 2019 nyorain\nCopyright (c) 2022-2026 David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and Dominik Röttsches\nCopyright (C) 2009, 2023 Red Hat, Inc." + }, + "source": { + "homepage": "http://www.freetype.org", + "download_location": "https://download.savannah.gnu.org/releases/freetype/freetype-2.14.3.tar.gz", + "purl": [ + "pkg:github/freetype/freetype@VER-$" + ] + } + }, + "freetype-bdf": { + "id": "freetype-bdf", + "name": "Freetype 2 - Bitmap Distribution Format (BDF) support", + "version": "2.14.3", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 2, + "sbom_packages": [ + "BundledFreetype_Attribution_freetype-bdf" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/qt_attribution.json", + "entry_index": 2, + "bytes": 5328, + "sha256": "628b68bf60eb3bc1616342bc3545b63be2392e78bbebbc4c19f49675dd2ac8a7", + "qt_usage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/BDF-LICENSE.txt", + "bytes": 2305, + "sha256": "e4e792f29e66750f2e410fd7b50a567652c180f6ee15e1a4dfa0bb5cde524537" + } + ], + "copyright": "Copyright (c) 2000 Computing Research Labs, New Mexico State University\nCopyright (c) 2001-2014 Francesco Zappa Nardelli" + }, + "source": { + "homepage": "http://www.freetype.org", + "download_location": "https://download.savannah.gnu.org/releases/freetype/freetype-2.14.3.tar.gz", + "purl": null + } + }, + "freetype-pcf": { + "id": "freetype-pcf", + "name": "Freetype 2 - Portable Compiled Format (PCF) support", + "version": "2.14.3", + "license_expression": "MIT AND MIT-open-group", + "license_ids": [ + "MIT", + "MIT-open-group" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 2, + "sbom_packages": [ + "BundledFreetype_Attribution_freetype-pcf" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/qt_attribution.json", + "entry_index": 3, + "bytes": 5328, + "sha256": "628b68bf60eb3bc1616342bc3545b63be2392e78bbebbc4c19f49675dd2ac8a7", + "qt_usage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/PCF-LICENSE.txt", + "bytes": 2218, + "sha256": "6938597bfdeca0db191a8f9ede52eaf2482c2c71a0094c084747a1235f9958fe" + } + ], + "copyright": "Copyright (c) 2001, 2012 David Turner, Robert Wilhelm, and Werner Lemberg\nCopyright (c) 2000-2014 Francesco Zappa Nardelli\nCopyright (c) 1990, 1994, 1998 The Open Group" + }, + "source": { + "homepage": "http://www.freetype.org", + "download_location": "https://download.savannah.gnu.org/releases/freetype/freetype-2.14.3.tar.gz", + "purl": null + } + }, + "freetype-zlib": { + "id": "freetype-zlib", + "name": "Freetype 2 - zlib", + "version": "2.14.3", + "license_expression": "Zlib", + "license_ids": [ + "Zlib" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 2, + "sbom_packages": [ + "BundledFreetype_Attribution_freetype-zlib" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/qt_attribution.json", + "entry_index": 1, + "bytes": 5328, + "sha256": "628b68bf60eb3bc1616342bc3545b63be2392e78bbebbc4c19f49675dd2ac8a7", + "qt_usage": "Optionally used in Qt GUI and platform plugins. Configure with -no-freetype, or -system-freetype to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/ZLIB-LICENSE.txt", + "bytes": 962, + "sha256": "2b1f5d615382a151af3eb71462ad17d89e2efee8fa7664058d35d3d9237ebb19" + } + ], + "copyright": "Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler" + }, + "source": { + "homepage": "http://www.freetype.org", + "download_location": "https://download.savannah.gnu.org/releases/freetype/freetype-2.14.3.tar.gz", + "purl": null + } + }, + "grayraster": { + "id": "grayraster", + "name": "Anti-aliasing rasterizer from FreeType 2", + "version": "unknown", + "license_expression": "FTL OR GPL-2.0-only", + "license_ids": [ + "FTL", + "GPL-2.0-only" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_grayraster" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/painting/qt_attribution.json", + "entry_index": 0, + "bytes": 2256, + "sha256": "8cddd6c73a885f697261c4d6d60e5cd814a2544fcd407504b52a5eb9b7cc3600", + "qt_usage": "Used in Qt GUI.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/freetype/LICENSE.txt", + "bytes": 26234, + "sha256": "bf543cdda11864477b8d2ca2aa9afc2aaa8f9133461b4d962ed6ec73646256a1" + } + ], + "copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg." + }, + "source": { + "homepage": "http://www.freetype.org", + "download_location": "http://www.freetype.org", + "purl": "pkg:generic/freetype-grayraster?download_url=https://www.freetype.org/" + } + }, + "harfbuzz-ng": { + "id": "harfbuzz-ng", + "name": "HarfBuzz-NG", + "version": "13.2.1", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "BundledHarfbuzz" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/harfbuzz-ng/qt_attribution.json", + "entry_index": 0, + "bytes": 1646, + "sha256": "130a33ff008696865ff9df1a83b8566f2f8ab006d23d3e8acf922d09642ba6f5", + "qt_usage": "Optionally used in Qt GUI. Configure with -system-harfbuzz to force the use of the system library, or -qt-harfbuzz to link statically to the library that is bundled with your Qt version.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/harfbuzz-ng/COPYING", + "bytes": 1971, + "sha256": "ba8f810f2455c2f08e2d56bb49b72f37fcf68f1f4fade38977cfd7372050ad64" + } + ], + "copyright": "Copyright © 2010-2022 Google, Inc.\nCopyright © 2015-2020 Ebrahim Byagowi\nCopyright © 2019,2020 Facebook, Inc.\nCopyright © 2012,2015 Mozilla Foundation\nCopyright © 2011 Codethink Limited\nCopyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)\nCopyright © 2009 Keith Stribley\nCopyright © 2011 Martin Hosken and SIL International\nCopyright © 2007 Chris Wilson\nCopyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod\nCopyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc.\nCopyright © 1998-2005 David Turner and Werner Lemberg\nCopyright © 2016 Igalia S.L.\nCopyright © 2022 Matthias Clasen\nCopyright © 2018,2021 Khaled Hosny\nCopyright © 2018,2019,2020 Adobe, Inc\nCopyright © 2013-2015 Alexei Podtelezhnikov" + }, + "source": { + "homepage": "http://harfbuzz.org", + "download_location": "https://github.com/harfbuzz/harfbuzz/releases/tag/13.2.1", + "purl": "pkg:github/harfbuzz/harfbuzz@$" + } + }, + "icc-srgb-color-profile": { + "id": "icc-srgb-color-profile", + "name": "sRGB color profile icc file", + "version": "unknown", + "license_expression": "LicenseRef-ICC-License", + "license_ids": [ + "LicenseRef-ICC-License" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_icc-srgb-color-profile" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/icc/qt_attribution.json", + "entry_index": 0, + "bytes": 775, + "sha256": "509da9bd2b3f769c730aa4627b1080d65f39b0ecd4130111c9e1122e13cd35b5", + "qt_usage": "Used in Qt Gui (Embedded into PDF/A-1b files generated by QPrinter/QPdfWriter).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/icc/LICENSE.txt", + "bytes": 463, + "sha256": "9e34ff47b3a44814e183342e7e198d127a6740e29d20e8381fba7688dafc79dd" + } + ], + "copyright": "Copyright International Color Consortium, 2015" + }, + "source": { + "homepage": "http://www.color.org/", + "download_location": "http://www.color.org/", + "purl": "pkg:generic/icc-sRGB-color-profile?download_url=http://www.color.org/" + } + }, + "libjpeg": { + "id": "libjpeg", + "name": "LibJPEG-turbo", + "version": "3.1.4", + "license_expression": "IJG AND BSD-3-Clause", + "license_ids": [ + "BSD-3-Clause", + "IJG" + ], + "deployed_files": [ + "imageformats/qjpeg.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "BundledLibjpeg" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libjpeg/qt_attribution.json", + "entry_index": 0, + "bytes": 859, + "sha256": "a6ae6df0d944727fd06c0594f8974a21f49328f6d25fd40957037f8b62c12778", + "qt_usage": "Used in the qjpeg image plugin. Configure with -system-libjpeg or -no-libjpeg to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libjpeg/LICENSE", + "bytes": 5622, + "sha256": "e10114e6e40f3d0311c401ca25245ac5ef459a43c20f976fd63f03e816f5741f" + }, + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libjpeg/ijg-license.txt", + "bytes": 1815, + "sha256": "1cb448f5e2e6d3aca60943f4eee1a04675628dc0266a074a42bc1560ebc28d61" + }, + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libjpeg/COPYRIGHT.txt", + "bytes": 593, + "sha256": "67464ebd2f477d2f631234df7761ab578a17a07ea96fc9174c99638b9cefff6a" + } + ], + "copyright": "" + }, + "source": { + "homepage": "http://libjpeg-turbo.virtualgl.org/", + "download_location": "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.1.4/libjpeg-turbo-3.1.4.tar.gz", + "purl": "pkg:github/libjpeg-turbo/libjpeg-turbo@$" + } + }, + "libpng": { + "id": "libpng", + "name": "LibPNG", + "version": "1.6.56", + "license_expression": "Libpng AND libpng-2.0", + "license_ids": [ + "Libpng", + "libpng-2.0" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "BundledLibpng" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libpng/qt_attribution.json", + "entry_index": 0, + "bytes": 1763, + "sha256": "ec6c93f46ca94b98e6eeef9cd5d00a155c1c7257bfff74e0a6bd982367f3a22a", + "qt_usage": "Used in the qpng image plugin. Configure with -system-libpng or -no-libpng to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libpng/LICENSE", + "bytes": 5345, + "sha256": "bdb0a645ea18c60507d0368379b1ac5474b92255fcc2d115e07486a7672ba526" + } + ], + "copyright": "Copyright (c) 1995-2026 The PNG Reference Library Authors\nCopyright (c) 2000-2026 Cosmin Truta\nCopyright (c) 1998-2018 Glenn Randers-Pehrson\nCopyright (c) 1996-1997 Andreas Dilger\nCopyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\nCopyright (c) 2000-2017 Simon-Pierre Cadieux\nCopyright (c) 2000-2017 Eric S. Raymond\nCopyright (c) 2000-2017 Mans Rullgard\nCopyright (c) 2000-2017 Gilles Vollant\nCopyright (c) 2000-2017 James Yu\nCopyright (c) 2000-2017 Mandar Sahastrabuddhe\nCopyright (c) 1998-2000 Tom Lane\nCopyright (c) 1998-2000 Willem van Schaik\nCopyright (c) 1996-1997 John Bowler\nCopyright (c) 1996-1997 Kevin Bracey\nCopyright (c) 1996-1997 Sam Bushell\nCopyright (c) 1996-1997 Magnus Holmgren\nCopyright (c) 1996-1997 Greg Roelofs\nCopyright (c) 1996-1997 Tom Tanner\nCopyright (c) 1995-1996 Dave Martindale\nCopyright (c) 1995-1996 Paul Schmidt\nCopyright (c) 1995-1996 Tim Wegner" + }, + "source": { + "homepage": "http://www.libpng.org/pub/png/libpng.html", + "download_location": "https://download.sourceforge.net/libpng/libpng-1.6.56.tar.xz", + "purl": "pkg:github/pnggroup/libpng@v$" + } + }, + "libpsl": { + "id": "libpsl", + "name": "libpsl - C library to handle the Public Suffix List", + "version": "664f3dc85259ec65e30248a61fa1c45b7b0e4c3f", + "license_expression": "BSD-3-Clause", + "license_ids": [ + "BSD-3-Clause" + ], + "deployed_files": [ + "Qt6Network.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Network_Attribution_libpsl" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libpsl/qt_attribution.json", + "entry_index": 1, + "bytes": 2458, + "sha256": "249db4fc311357b0080ccbc123f49e8cd0004dfe86a44f2855f7ea5837ae40f1", + "qt_usage": "Used to compress the embedded copy of publicsuffix list and\nto lookup entries in it.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libpsl/src/LICENSE.chromium", + "bytes": 1664, + "sha256": "1d7f52747a9169751cdf2641a8299c0098e9ecdf9429296ffd55bdb14c9ed5b3" + } + ], + "copyright": "Copyright 2014-2016 The Chromium Authors. All rights reserved." + }, + "source": { + "homepage": "https://github.com/rockdaboot/libpsl", + "download_location": "https://github.com/rockdaboot/libpsl", + "purl": "pkg:github/rockdaboot/libpsl@$" + } + }, + "md4": { + "id": "md4", + "name": "MD4", + "version": "unknown", + "license_expression": "CC0-1.0", + "license_ids": [ + "CC0-1.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_md4" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/md4/qt_attribution.json", + "entry_index": 0, + "bytes": 574, + "sha256": "34bda63a2fcc23c83f2e5364ccd394553b4baa505b1f79ded9cc2161c56a9b4c", + "qt_usage": "Used in Qt Core (QCryptographicHash).", + "qt_parts": null, + "license_files": [], + "copyright": "Written by Alexander Peslyak - better known as Solar Designer - in 2001, and placed in the public domain. There's absolutely no warranty." + }, + "source": { + "homepage": null, + "download_location": "NOASSERTION", + "purl": null + } + }, + "md4c": { + "id": "md4c", + "name": "MD4C", + "version": "0.5.2", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_md4c" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/md4c/qt_attribution.json", + "entry_index": 0, + "bytes": 673, + "sha256": "59098b9262ac268e73495cb1b1603b5c899d5c532db6ca96e69ffac7062445f5", + "qt_usage": "Optionally used in QTextDocument if configured with textmarkdownreader.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/md4c/LICENSE.md", + "bytes": 1096, + "sha256": "d30937367d5413e7eaa218b1640b8946ff76fd34d97152f6979fd96169d5d0fc" + } + ], + "copyright": "Copyright © 2016-2024 Martin Mitáš" + }, + "source": { + "homepage": "https://github.com/mity/md4c", + "download_location": "https://github.com/mity/md4c/releases/tag/release-0.5.2", + "purl": "pkg:github/mity/md4c@release-$" + } + }, + "md5": { + "id": "md5", + "name": "MD5", + "version": "unknown", + "license_expression": "CC0-1.0", + "license_ids": [ + "CC0-1.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_md5" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/md5/qt_attribution.json", + "entry_index": 0, + "bytes": 446, + "sha256": "20b0f1b17ccd1bd5e8d763b1cdca4b095b8f0c037644b5ee18154536b7d8425e", + "qt_usage": "Used in Qt Core (QCryptographicHash).", + "qt_parts": null, + "license_files": [], + "copyright": "Written by Colin Plumb in 1993, no copyright is claimed. Ian Jackson ." + }, + "source": { + "homepage": null, + "download_location": "NOASSERTION", + "purl": null + } + }, + "opengl-es2-headers": { + "id": "opengl-es2-headers", + "name": "OpenGL ES 2 Headers", + "version": "Revision 27673", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_opengl-es2-headers" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/opengl/qt_attribution.json", + "entry_index": 1, + "bytes": 1526, + "sha256": "d05626e02386f22186b385b3ce2cd5a6431b84e2fc552c68f7133e38da552fc1", + "qt_usage": "Used on Windows and Linux in the OpenGL related headers of Qt GUI.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/gui/opengl/LICENSE.KHRONOS.txt", + "bytes": 1084, + "sha256": "2e484f3c26ff5008c704a3ca9dd809d43f24a004a1abb6c202660fbff0d19715" + } + ], + "copyright": "Copyright (c) 2013-2014 The Khronos Group Inc." + }, + "source": { + "homepage": "https://www.khronos.org/", + "download_location": "https://www.khronos.org/", + "purl": "pkg:generic/khronos-opengl-es2-headers?download_url=https://www.khronos.org/?revision=27673" + } + }, + "opengl-headers": { + "id": "opengl-headers", + "name": "OpenGL Headers", + "version": "Revision 27684", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_opengl-headers" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/opengl/qt_attribution.json", + "entry_index": 0, + "bytes": 1526, + "sha256": "d05626e02386f22186b385b3ce2cd5a6431b84e2fc552c68f7133e38da552fc1", + "qt_usage": "Used on Windows and Linux in the OpenGL related headers of Qt GUI.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/gui/opengl/LICENSE.KHRONOS.txt", + "bytes": 1084, + "sha256": "2e484f3c26ff5008c704a3ca9dd809d43f24a004a1abb6c202660fbff0d19715" + } + ], + "copyright": "Copyright (c) 2013-2014 The Khronos Group Inc." + }, + "source": { + "homepage": "https://www.khronos.org/", + "download_location": "https://www.khronos.org/", + "purl": "pkg:generic/khronos-opengl-headers?download_url=https://www.khronos.org/?revision=27684" + } + }, + "pcre2": { + "id": "pcre2", + "name": "PCRE2", + "version": "10.47", + "license_expression": "LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception", + "license_ids": [ + "LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "BundledPcre2" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/pcre2/qt_attribution.json", + "entry_index": 0, + "bytes": 1829, + "sha256": "e009f73100ef4aed400257a095cdb25ee31980c4a290f1aca52d147cb3067abc", + "qt_usage": "Used in Qt Core (QRegularExpression).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/pcre2/LICENCE.md", + "bytes": 4011, + "sha256": "197d8a73ffee0d6b09adba2f9c677b5f5aede24edf89258a68e48248d010d811" + } + ], + "copyright": "Copyright (c) 1997-2007 University of Cambridge\nCopyright (c) 2007-2024 Philip Hazel\nCopyright (c) 2010-2024 Zoltan Herczeg" + }, + "source": { + "homepage": "http://www.pcre.org/", + "download_location": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.47/pcre2-10.47.tar.bz2", + "purl": "pkg:github/PCRE2Project/pcre2@pcre2-$" + } + }, + "pcre2-sljit": { + "id": "pcre2-sljit", + "name": "PCRE2 - Stack-less Just-In-Time Compiler", + "version": "10.47", + "license_expression": "BSD-2-Clause", + "license_ids": [ + "BSD-2-Clause" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 2, + "sbom_packages": [ + "BundledPcre2_Attribution_pcre2-sljit" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/pcre2/qt_attribution.json", + "entry_index": 1, + "bytes": 1829, + "sha256": "e009f73100ef4aed400257a095cdb25ee31980c4a290f1aca52d147cb3067abc", + "qt_usage": "Used in Qt Core (QRegularExpression).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/pcre2/LICENSE-SLJIT", + "bytes": 1444, + "sha256": "5f216505c0f6ea3273caec89e766eef93cdeb7bbb0c429f9360116d7c938feeb" + } + ], + "copyright": "Copyright Zoltan Herczeg" + }, + "source": { + "homepage": "http://www.pcre.org/", + "download_location": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.47/pcre2-10.47.tar.bz2", + "purl": "pkg:github/PCRE2Project/pcre2@pcre2-$" + } + }, + "psl-data": { + "id": "psl-data", + "name": "The Public Suffix List", + "version": "2026-01-16_13-11-47_UTC", + "license_expression": "MPL-2.0", + "license_ids": [ + "MPL-2.0" + ], + "deployed_files": [ + "Qt6Network.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Network_Attribution_psl-data" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libpsl/qt_attribution.json", + "entry_index": 0, + "bytes": 2458, + "sha256": "249db4fc311357b0080ccbc123f49e8cd0004dfe86a44f2855f7ea5837ae40f1", + "qt_usage": "Used in Qt Network to avoid setting \"supercookies\" in the cookie jar\nsupported by Qt (by the QNetworkCookieJar class).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/libpsl/PSL-LICENSE.txt", + "bytes": 16726, + "sha256": "3f3d9e0024b1921b067d6f7f88deb4a60cbe7a78e76c64e3f1d7fc3b779b9d04" + } + ], + "copyright": "The list was originally provided by Jo Hermans .\nIt is now maintained on github (https://github.com/publicsuffix/list)." + }, + "source": { + "homepage": "http://publicsuffix.org/", + "download_location": "https://publicsuffix.org/list/public_suffix_list.dat", + "purl": "pkg:generic/psl-data@944fb53321606f08740f04ef7c386f64df34ff76?download_url=https://publicsuffix.org/list/public_suffix_list.dat" + } + }, + "rfc6234": { + "id": "rfc6234", + "name": "Secure Hash Algorithms SHA-384 and SHA-512", + "version": "unknown", + "license_expression": "BSD-3-Clause", + "license_ids": [ + "BSD-3-Clause" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_rfc6234" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/rfc6234/qt_attribution.json", + "entry_index": 0, + "bytes": 660, + "sha256": "fa24413bdc5015fc7fc84297fa17d4c8a598f8f7c76b9495a6e6b26a77b4a324", + "qt_usage": "Used in Qt Core (QCryptographicHash and QMessageAuthenticationCode)", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/rfc6234/LICENSE", + "bytes": 1568, + "sha256": "7ccebd514aaabc86192f957d773cebf06577c12fe9f25ecd419c6cac5da7a14c" + } + ], + "copyright": "Copyright (c) 2011 IETF Trust and the persons identified as authors of the code." + }, + "source": { + "homepage": null, + "download_location": "NOASSERTION", + "purl": null + } + }, + "rhi-miniengine-d3d12-mipmap": { + "id": "rhi-miniengine-d3d12-mipmap", + "name": "Mipmap generator for D3D12", + "version": "0aa79bad78992da0b6a8279ddb9002c1753cb849", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_rhi-miniengine-d3d12-mipmap" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/rhi/qt_attribution.json", + "entry_index": 0, + "bytes": 782, + "sha256": "59df3efb041ed346aa797602a76ef8d284e84c3cc6ace30967d6704fc65dbb47", + "qt_usage": "Compute shader for mipmap generation with Direct 3D 12", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/gui/rhi/LICENSE.MiniEngine.txt", + "bytes": 1077, + "sha256": "cf248820bf1178370bb4f1670a59f8748d46bc96d0f64080cd631511c6046409" + } + ], + "copyright": "Copyright (c) 2015 Microsoft" + }, + "source": { + "homepage": "https://github.com/microsoft/DirectX-Graphics-Samples", + "download_location": "https://github.com/microsoft/DirectX-Graphics-Samples", + "purl": "pkg:github/microsoft/DirectX-Graphics-Samples@$" + } + }, + "sha1": { + "id": "sha1", + "name": "Secure Hash Algorithm SHA-1", + "version": "unknown", + "license_expression": "LicenseRef-SHA1-Public-Domain", + "license_ids": [ + "LicenseRef-SHA1-Public-Domain" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_sha1" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/sha1/qt_attribution.json", + "entry_index": 0, + "bytes": 618, + "sha256": "53cab2c771f7f7ffbf6a58ff759e5846b746e91d98dfe467d5145edf8cd7d306", + "qt_usage": "Used in Qt Core (QCryptographicHash).", + "qt_parts": null, + "license_files": [], + "copyright": "Copyright (C) Dominik Reichl \nCopyright (C) 2016 The Qt Company Ltd" + }, + "source": { + "homepage": "http://www.dominik-reichl.de/projects/csha1/", + "download_location": "http://www.dominik-reichl.de/projects/csha1/", + "purl": "pkg:generic/csha1?download_url=https://www.dominik-reichl.de/projects/csha1/" + } + }, + "sha3_endian": { + "id": "sha3_endian", + "name": "Secure Hash Algorithm SHA-3 - brg_endian", + "version": "1.0.0", + "license_expression": "BSD-2-Clause", + "license_ids": [ + "BSD-2-Clause" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_sha3_endian" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/sha3/qt_attribution.json", + "entry_index": 0, + "bytes": 2322, + "sha256": "d904a6c21c150d9cac693c0806a469480306cb4e5879cc13c994fbadba71a56e", + "qt_usage": "Used in Qt Core (QCryptographicHash).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/sha3/BRG_ENDIAN_LICENSE", + "bytes": 645, + "sha256": "2fed6f252ca4a7e813811de3cd3cd08183edd4138bdee909410ef6eee394e82c" + } + ], + "copyright": "Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved." + }, + "source": { + "homepage": null, + "download_location": "NOASSERTION", + "purl": "pkg:github/BrianGladman/sha@$" + } + }, + "sha3_keccak": { + "id": "sha3_keccak", + "name": "Secure Hash Algorithm SHA-3 - Keccak", + "version": "3.2", + "license_expression": "CC0-1.0", + "license_ids": [ + "CC0-1.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_sha3_keccak" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/sha3/qt_attribution.json", + "entry_index": 1, + "bytes": 2322, + "sha256": "d904a6c21c150d9cac693c0806a469480306cb4e5879cc13c994fbadba71a56e", + "qt_usage": "Used in Qt Core (QCryptographicHash).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/sha3/CC0_LICENSE", + "bytes": 7013, + "sha256": "1f2786e2c5befeb4dcba6638db6528bf96ef5d2cf24bc85ab5a81ef00abef59d" + } + ], + "copyright": "Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche.\nTo the extent possible under law, the implementers have waived all copyright\nand related or neighboring rights to the source code in this file." + }, + "source": { + "homepage": null, + "download_location": "NOASSERTION", + "purl": "pkg:generic/sha3_keccak@$?download_url=https://keccak.team/obsolete/KeccakReferenceAndOptimized-3.2.zip" + } + }, + "siphash": { + "id": "siphash", + "name": "SipHash Algorithm", + "version": "unknown", + "license_expression": "CC0-1.0", + "license_ids": [ + "CC0-1.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_siphash" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/siphash/qt_attribution.json", + "entry_index": 0, + "bytes": 793, + "sha256": "8614947dfc0ca1d21aad2f88b4400598262ab8c08aa87c4f7acc0c2de6e5619e", + "qt_usage": "Used in Qt Core (QHash)", + "qt_parts": null, + "license_files": [], + "copyright": "Copyright (C) 2012-2014 Jean-Philippe Aumasson\nCopyright (C) 2012-2014 Daniel J. Bernstein \nCopyright (C) 2016 Intel Corporation" + }, + "source": { + "homepage": "https://131002.net/siphash/", + "download_location": "https://raw.githubusercontent.com/veorq/SipHash/adcbf09b1684a718f594faa650ffc56bacdb0777/siphash24.c", + "purl": "pkg:github/veorq/SipHash@adcbf09b1684a718f594faa650ffc56bacdb0777" + } + }, + "smooth-scaling-algorithm": { + "id": "smooth-scaling-algorithm", + "name": "Smooth Scaling Algorithm", + "version": "unknown", + "license_expression": "BSD-2-Clause AND Imlib2", + "license_ids": [ + "BSD-2-Clause", + "Imlib2" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_smooth-scaling-algorithm" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/painting/qt_attribution.json", + "entry_index": 1, + "bytes": 2256, + "sha256": "8cddd6c73a885f697261c4d6d60e5cd814a2544fcd407504b52a5eb9b7cc3600", + "qt_usage": "Used in Qt Gui (QImage::transformed() functions).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/gui/painting/LICENSE.QIMAGETRANSFORM.txt", + "bytes": 3004, + "sha256": "46b3cbfa2f2946b93291506351e9be1dd0a28d2a53260f5aa488abd36fbeca9d" + } + ], + "copyright": "Copyright (C) 2004, 2005 Daniel M. Duley.\n(C) Carsten Haitzler and various contributors.\n(C) Willem Monsuwe " + }, + "source": { + "homepage": null, + "download_location": "NOASSERTION", + "purl": null + } + }, + "tika-mimetypes": { + "id": "tika-mimetypes", + "name": "Apache Tika MimeType Definitions", + "version": "408c26e1e03e018a623e732dff6fb047a2fb8e19", + "license_expression": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_tika-mimetypes" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/corelib/mimetypes/3rdparty/qt_attribution.json", + "entry_index": 0, + "bytes": 1383, + "sha256": "c4489b84900db9b66a20ab237f162f406ef3f670d008d9f7e0038e651302649e", + "qt_usage": "Qt Core uses a copy of the Apache Tika MimeType Definitions if shared-mime-info isn't installed on the system.", + "qt_parts": null, + "license_files": [], + "copyright": "Copyright 2026 The Apache Software Foundation" + }, + "source": { + "homepage": "https://github.com/apache/tika/tree/main/tika-core/src/main/resources/org/apache/tika/mime", + "download_location": "https://github.com/apache/tika/blob/408c26e1e03e018a623e732dff6fb047a2fb8e19/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml", + "purl": "pkg:github/apache/tika@$#tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml" + } + }, + "tinycbor": { + "id": "tinycbor", + "name": "TinyCBOR", + "version": "7.0", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_tinycbor" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/tinycbor/qt_attribution.json", + "entry_index": 0, + "bytes": 685, + "sha256": "788408509fb7967042640f24ba78b263712e816d886303ba1733f49753d33863", + "qt_usage": "Used for QCborStreamReader and QCborStreamWriter.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/tinycbor/LICENSE", + "bytes": 1074, + "sha256": "3c6ba0b5bfa7830505301ffb336a17b0748e0d61c4d34216e9dc98f10e40395e" + } + ], + "copyright": "Copyright (C) 2015-2025 Intel Corporation" + }, + "source": { + "homepage": "https://github.com/intel/tinycbor", + "download_location": "https://github.com/intel/tinycbor/archive/v7.0/tinycbor-7.0.tar.gz", + "purl": "pkg:github/intel/tinycbor@v$" + } + }, + "tlexpected": { + "id": "tlexpected", + "name": "tl::expected", + "version": "41d3e1f48d682992a2230b2a715bca38b848b269", + "license_expression": "CC0-1.0", + "license_ids": [ + "CC0-1.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_tlexpected" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/corelib/global/qt_attribution.json", + "entry_index": 0, + "bytes": 814, + "sha256": "64698063a65a1502b986bd61163b5eb9c6bde87f93feb28e4eab43ff07a4f10a", + "qt_usage": "Available as a private type in all Qt modules", + "qt_parts": null, + "license_files": [], + "copyright": "To the extent possible under law, Sy Brand has waived all copyright and related or neighboring rights to the expected library. This work is published from: United Kingdom." + }, + "source": { + "homepage": "https://github.com/TartanLlama/expected/", + "download_location": "https://github.com/TartanLlama/expected/blob/41d3e1f48d682992a2230b2a715bca38b848b269/include/tl/expected.hpp", + "purl": null + } + }, + "unicode-character-database": { + "id": "unicode-character-database", + "name": "Unicode Character Database (UCD)", + "version": "36", + "license_expression": "Unicode-3.0", + "license_ids": [ + "Unicode-3.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_unicode-character-database" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/corelib/text/qt_attribution.json", + "entry_index": 0, + "bytes": 2170, + "sha256": "b6a2f9a2a33c4c0a951ffd15ceafd5c21dba5a4e5e2e246d5db3493440362302", + "qt_usage": "Qt Core uses data obtained from UCD files for working with characters and strings.", + "qt_parts": null, + "license_files": [], + "copyright": "Copyright (C) 1991-2025 Unicode, Inc." + }, + "source": { + "homepage": "https://www.unicode.org/ucd/", + "download_location": "https://www.unicode.org/ucd/", + "purl": null + } + }, + "unicode-cldr": { + "id": "unicode-cldr", + "name": "Unicode Common Locale Data Repository (CLDR)", + "version": "v48.1", + "license_expression": "Unicode-3.0", + "license_ids": [ + "Unicode-3.0" + ], + "deployed_files": [ + "Qt6Core.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Core_Attribution_unicode-cldr" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/corelib/text/qt_attribution.json", + "entry_index": 1, + "bytes": 2170, + "sha256": "b6a2f9a2a33c4c0a951ffd15ceafd5c21dba5a4e5e2e246d5db3493440362302", + "qt_usage": "Used in Qt Core (QTimeZone, QLocale).", + "qt_parts": null, + "license_files": [], + "copyright": "Copyright (C) 2004-2025 Unicode, Inc." + }, + "source": { + "homepage": "https://cldr.unicode.org/", + "download_location": "https://cldr.unicode.org/", + "purl": null + } + }, + "vulkan-xml-spec": { + "id": "vulkan-xml-spec", + "name": "Vulkan API Registry", + "version": "1.4.308", + "license_expression": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_vulkan-xml-spec" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/vulkan/qt_attribution.json", + "entry_index": 0, + "bytes": 801, + "sha256": "b4beb6ac27b066a6a71408da116fea60131c06ac9799c9763fe9cef28a76e7b9", + "qt_usage": "Used to dynamically generate the sources for the QVulkan(Device)Functions classes.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/gui/vulkan/LICENSE.txt", + "bytes": 11473, + "sha256": "5f618873b0cdd1e84c611c5529212c2524bfc887bdfd7d1f3b568bad3c649612" + } + ], + "copyright": "Copyright (c) 2015-2025 The Khronos Group Inc." + }, + "source": { + "homepage": "https://www.khronos.org/", + "download_location": "https://www.khronos.org/", + "purl": "pkg:github/KhronosGroup/Vulkan-Docs@v$?download_url=https://github.com/KhronosGroup/Vulkan-Docs/blob/v1.4.308/xml/vk.xml" + } + }, + "vulkanmemoryallocator": { + "id": "vulkanmemoryallocator", + "name": "Vulkan Memory Allocator", + "version": "3.2.1", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_vulkanmemoryallocator" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/VulkanMemoryAllocator/qt_attribution.json", + "entry_index": 0, + "bytes": 699, + "sha256": "833626a9e955bdae274f076786ca2cc7c8b50f9e382dff566db89ec69f8178cf", + "qt_usage": "Memory management for the Vulkan backend of QRhi.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/VulkanMemoryAllocator/LICENSE.txt", + "bytes": 1099, + "sha256": "846d97c8b74ccaa92b9ad031140a04363b3b3985f318094552f297b8bda1c68e" + } + ], + "copyright": "Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All rights reserved." + }, + "source": { + "homepage": "https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator", + "download_location": "https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator", + "purl": "pkg:github/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator@v$" + } + }, + "webgradients": { + "id": "webgradients", + "name": "WebGradients", + "version": "unknown", + "license_expression": "MIT", + "license_ids": [ + "MIT" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_webgradients" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/util/gradientgen/qt_attribution.json", + "entry_index": 0, + "bytes": 596, + "sha256": "6e87ac5d79ab92110e6e517b2c74e4f4fd15878540e93eea0300e529d3318572", + "qt_usage": "Used in Qt GUI to provide presets for QGradient.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/util/gradientgen/LICENSE.WEBGRADIENTS.txt", + "bytes": 1062, + "sha256": "9be732e45b638c74f9c0e5248541dd54dc7e8e9a5545df96b5c4b7c9ac0c68ba" + } + ], + "copyright": "Copyright (c) 2017 itmeo" + }, + "source": { + "homepage": "https://webgradients.com/", + "download_location": "https://webgradients.com/", + "purl": "pkg:generic/webgradients?download_url=https://webgradients.com/" + } + }, + "wintab": { + "id": "wintab", + "name": "Wintab API", + "version": "unknown", + "license_expression": "LicenseRef-Lcs-Telegraphics", + "license_ids": [ + "LicenseRef-Lcs-Telegraphics" + ], + "deployed_files": [ + "platforms/qwindows.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "QWindowsIntegrationPlugin_Attribution_wintab" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wintab/qt_attribution.json", + "entry_index": 0, + "bytes": 602, + "sha256": "b879ea91b719531d45e1cfe33d2241d060a9260200bd91a09ada074b16063f9c", + "qt_usage": "Used in the Qt platform plugin for Windows. Configure with -no-feature-tabletevent to avoid.", + "qt_parts": null, + "license_files": [], + "copyright": "Copyright 1991-1998 by LCS/Telegraphics." + }, + "source": { + "homepage": null, + "download_location": "NOASSERTION", + "purl": null + } + }, + "xserverhelper": { + "id": "xserverhelper", + "name": "X Server helper", + "version": "unknown", + "license_expression": "X11 AND HPND", + "license_ids": [ + "HPND", + "X11" + ], + "deployed_files": [ + "Qt6Gui.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "Gui_Attribution_xserverhelper" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/gui/painting/qt_attribution.json", + "entry_index": 2, + "bytes": 2256, + "sha256": "8cddd6c73a885f697261c4d6d60e5cd814a2544fcd407504b52a5eb9b7cc3600", + "qt_usage": "Used in Qt GUI (QRegion).", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/gui/painting/LICENSE.XCONSORTIUM.txt", + "bytes": 2294, + "sha256": "a216b01291eb38fc1af93cfccf1fc67b48d9923612e517c2a695e95b3f03c22c" + } + ], + "copyright": "Copyright (c) 1987, 1988 X Consortium\nCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts." + }, + "source": { + "homepage": "https://www.x.org/", + "download_location": "https://www.x.org/", + "purl": "pkg:generic/xserverhelper?download_url=https://www.x.org/" + } + }, + "zlib": { + "id": "zlib", + "name": "Data Compression Library (zlib)", + "version": "1.3.2", + "license_expression": "Zlib", + "license_ids": [ + "Zlib" + ], + "deployed_files": [ + "Qt6Core.dll", + "Qt6Gui.dll", + "Qt6Network.dll" + ], + "evidence": { + "level": "sbom_module_dependency", + "depth": 1, + "sbom_packages": [ + "BundledZLIB", + "Gui_Attribution_zlib", + "Network_Attribution_zlib" + ] + }, + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/zlib/qt_attribution.json", + "entry_index": 0, + "bytes": 731, + "sha256": "0346805e9c4048316dbc7c58d560a20c12482ea0218de264282212e9619b6d64", + "qt_usage": "Optionally used in Qt Core and development tools. Configure with -system-zlib to avoid.", + "qt_parts": null, + "license_files": [ + { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/zlib/LICENSE", + "bytes": 1465, + "sha256": "d7e3139972874dc8abdbbfce27ec1e6f942b28279dd7d27453630a8b4610e080" + } + ], + "copyright": "(C) 1995-2026 Jean-loup Gailly and Mark Adler" + }, + "source": { + "homepage": "https://zlib.net/", + "download_location": "https://github.com/madler/zlib/releases/download/v1.3.2/zlib-1.3.2.tar.gz", + "purl": "pkg:github/madler/zlib@v$" + } + } + }, + "excluded_attributions": [ + { + "id": "extra-cmake-modules", + "name": "extra-cmake-modules", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/cmake/3rdparty/extra-cmake-modules/qt_attribution.json", + "entry_index": 0, + "sha256": "f34f498d6c63a78a882b352fa38c9dd076a59b1696cd6a6f921151a61f2a02e0" + }, + "category": "internal_build_platform_attribution", + "qt_usage": "Used as part of the build system.", + "qt_parts": [ + "tools" + ], + "sbom_package": "Platform_Attribution_extra-cmake-modules", + "reason": "Reachable from a deployed module only through internal Qt build/platform packages; the attribution declares build-system/tool use, not a runtime component of the packaged binary." + }, + { + "id": "kwin", + "name": "KWin", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/cmake/3rdparty/kwin/qt_attribution.json", + "entry_index": 0, + "sha256": "bf3a3c09e99f1c9fab7553ebc4a7548b71dc23fcfdbe6e5df0fa0e7847c2efc3" + }, + "category": "internal_build_platform_attribution", + "qt_usage": "Used as part of the build system.", + "qt_parts": [ + "tools" + ], + "sbom_package": "Platform_Attribution_kwin", + "reason": "Reachable from a deployed module only through internal Qt build/platform packages; the attribution declares build-system/tool use, not a runtime component of the packaged binary." + } + ], + "declared_not_deployed": [ + { + "id": "android-native-style", + "name": "Native Style for Android", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/android/qt_attribution.json", + "entry_index": 0, + "sha256": "120710d661892ceb44a94556c56998795372334674c79710947282e8279ef415" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "forkfd", + "name": "forkfd", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/forkfd/qt_attribution.json", + "entry_index": 0, + "sha256": "525fd890017a3966f542da42a9ff0ca2a0d71bc45f80a4871de3e0bd0f612612" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "android-gradle-wrapper", + "name": "Gradle wrapper", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/gradle/qt_attribution.json", + "entry_index": 0, + "sha256": "d7de1769cedbb5d34133614f836e633c95cce2aee45dc89298702842e7d7a466" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "pixman", + "name": "Pixman", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/pixman/qt_attribution.json", + "entry_index": 0, + "sha256": "f1dc159b63bf84a4c9c367e8ff79aa748b63f5fc622d5080c0a7ddd98ddc7ac7" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "sqlite", + "name": "SQLite", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/sqlite/qt_attribution.json", + "entry_index": 0, + "sha256": "28288fab36e56b72bf92e525ce93091a5e2e2ff7eb475223426c4c090603406b" + }, + "category": "owning_package_not_deployed", + "sbom_package": "QSQLiteDriverPlugin_Attribution_sqlite", + "reason": "The owning SBOM package is not part of the deployed product files (no dependency path from a deployed Qt module/plugin)." + }, + { + "id": "dejayvu", + "name": "DejaVu Fonts", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wasm/qt_attribution.json", + "entry_index": 0, + "sha256": "2019d37665bfb2ce7d4931d0bdf7427ea178919399cf37c0fef14a229144936b" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "appmenu", + "name": "Wayland KDE DBus Menu Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/appmenu/qt_attribution.json", + "entry_index": 0, + "sha256": "b7200f7fdfd2223aaecbd9b2ec8e4145eebe4f0b376ffbcb3859154661fb1095" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-color-management-protocol", + "name": "Wayland Color Management Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/color-management/qt_attribution.json", + "entry_index": 0, + "sha256": "6081490578a0a5ff17e450a3f9a05a36a3433de0832f1b2b497ca3c8ec1f9ba9" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "fractional-scale-v1", + "name": "Wayland Fractional Scale Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/fractional-scale/qt_attribution.json", + "entry_index": 0, + "sha256": "bf87b7dc5bf42e91c9d98ad2a109d197141aaebffe563ab247dd771e0b9b07c8" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-fullscreen-protocol", + "name": "Wayland Fullscreen Shell Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/fullscreen-shell/qt_attribution.json", + "entry_index": 0, + "sha256": "24ebba6014034dcf2c9a23a5b1085dc9708eaa81c021dfe51ba3f6b51ba788a7" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-linux-dmabuf-unstable-v1", + "name": "Wayland Linux Dmabuf Unstable V1 Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/linux-dmabuf/qt_attribution.json", + "entry_index": 0, + "sha256": "64ea0d933ff0d0868e820b443c14feda5208f90bd02032cdc9a1b6881a05f446" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-pointer-gestures-protocol", + "name": "Wayland Pointer Gestures Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/pointer-gestures/qt_attribution.json", + "entry_index": 0, + "sha256": "3c85ce329ccb30c469aa3f3c71596eb915c9cccd645ac1192d94a8fe548556b7" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-pointer-warp-protocol", + "name": "Wayland Pointer Warp Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/pointer-warp/qt_attribution.json", + "entry_index": 0, + "sha256": "3eb309adae44fe120dab08dca8c4df57a34ac347ecf1764cafdd7542cd0a0a11" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "presentation-time.xml", + "name": "Presentation Time Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/presentation-time/qt_attribution.json", + "entry_index": 0, + "sha256": "c3af7f51726c7584d5e8ad74a29813d66cac6a215a9675da7cfc9a42f15c2d0a" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-scaler-protocol", + "name": "Wayland Scaler Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/scaler/qt_attribution.json", + "entry_index": 0, + "sha256": "8b7751412fc26d70f641d6bad9c6aadd406317cbf17359ffcc58651f58aa2fca" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-tablet-protocol", + "name": "Wayland Tablet Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/tablet/qt_attribution.json", + "entry_index": 0, + "sha256": "a46626dbac8fc1f57d5b34eb077425fc402fc0767b75ec06578e1465502883b5" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-text-input-unstable-v1", + "name": "Wayland Text Input Protocol v1", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/text-input/v1/qt_attribution.json", + "entry_index": 0, + "sha256": "882ac88020f0ecaea6d991f7e8d292542c9422592ede0396c4d217f040ef6a54" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-text-input-unstable-v2", + "name": "Wayland Text Input Protocol v2", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/text-input/v2/qt_attribution.json", + "entry_index": 0, + "sha256": "197d9edcc6fb17d7bc2b230f7061ce0d2ef90fa4291c86e87ae2817e8f2809fe" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-text-input-unstable-v3", + "name": "Wayland Text Input Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/text-input/v3/qt_attribution.json", + "entry_index": 0, + "sha256": "476225d10cb5789d993c38335c6cc442fdc19a8d91f1ceb7a3ddb50414a8e68a" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-viewporter-protocol", + "name": "Wayland Viewporter Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/viewporter/qt_attribution.json", + "entry_index": 0, + "sha256": "95139e441967bc289d174078f1ca0485363e8405bd8d06eb9946356c09c0a5e4" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-protocol", + "name": "Wayland Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/wayland/qt_attribution.json", + "entry_index": 0, + "sha256": "6fc69ab7ee19ea2567ff1cfd4a89937d658694fe1b26e198d633597a8557462f" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-eglstream-controller", + "name": "Wayland EGLStream Controller Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/wl-eglstream/qt_attribution.json", + "entry_index": 0, + "sha256": "2432510e17446887decd1fc58770aeeef060aff5331a8bfec7fb668555f3b347" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wlr-data-control-unstable-v1-protocol", + "name": "Wlr Data Control Unstable V1 Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/wlr-data-control/qt_attribution.json", + "entry_index": 0, + "sha256": "433a74149249d01d946d86aa0d88d30bc755523f1a978f640f6142e9c8fa1035" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-primary-selection-protocol", + "name": "Wayland Primary Selection Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/wp-primary-selection/qt_attribution.json", + "entry_index": 0, + "sha256": "14586c06e09439e9c2b7719766f68e219d0ff0231811e13e44f4587dabf52707" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-xdg-activation", + "name": "Wayland xdg-activation Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-activation/qt_attribution.json", + "entry_index": 0, + "sha256": "8f13cfd4c78a2f116d3e674c329d3d211b647d80190e7a95493528cd6dedbd89" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-xdg-decoration-protocol", + "name": "Wayland xdg-decoration Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-decoration/qt_attribution.json", + "entry_index": 0, + "sha256": "b8d9102ff3c7eccd840f7d5332d072e41e95eb055a8a9f2e3719a83005879c86" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "xdg-dialog-v1", + "name": "Wayland Dialog Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-dialog/qt_attribution.json", + "entry_index": 0, + "sha256": "c7918fb63ad5be29e9a95db3464a7832224c7d904d21617ccfc689e6b0ab04c0" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "xdg-foreign-unstable-v2", + "name": "Wayland XDG Foreign Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-foreign/qt_attribution.json", + "entry_index": 0, + "sha256": "0ed6fbddba411b647bbe895b6e7a842c2a884905206888c0b4df6b6cd3bb9f79" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-xdg-output-protocol", + "name": "Wayland XDG Output Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-output/qt_attribution.json", + "entry_index": 0, + "sha256": "c5e4f132de8d08a75af02682bba3a9349a00f49b773e23ef5543648209b76658" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-xdg-shell-protocol", + "name": "Wayland XDG Shell Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-shell/qt_attribution.json", + "entry_index": 0, + "sha256": "e1367b44fe28fce2eee7656cda75203f4102662bb6aa370b3c9f3eb5a2cc3f82" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-xdg-system-bell-protocol", + "name": "Wayland XDG System Bell Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-system-bell/qt_attribution.json", + "entry_index": 0, + "sha256": "43a10e6b73a26d9c75e99447f5e731d170047ed2e709878e61eb83f6453cb3da" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "wayland-xdg-toplevel-icon-protocol", + "name": "Wayland xdg-toplevel-icon Protocol", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/wayland/protocols/xdg-toplevel-icon/qt_attribution.json", + "entry_index": 0, + "sha256": "2e022951f22a56051a099b9045f4fb0c569daa896a218d23f47b0dac3e905c04" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "xcb-xinput", + "name": "XCB-XInput", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/3rdparty/xcb/qt_attribution.json", + "entry_index": 0, + "sha256": "8bae8861957bc0168d586d24da6e8e93edceb11796811c5f614d211f4674d437" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "qeventdispatcher_cf", + "name": "QEventDispatcher on macOS", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/corelib/kernel/qt_attribution.json", + "entry_index": 0, + "sha256": "27bb1f28d336f1f8f6d44689f28cb650f0844cc82672e36ae168d0716783fad5" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "libdbus-1-headers", + "name": "libdbus-1 headers", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/dbus/qt_attribution.json", + "entry_index": 0, + "sha256": "346532e1fb3bf653bc949408834c305646fc93f96650a2af9b2171d141c107ee" + }, + "category": "owning_package_not_deployed", + "sbom_package": "DBus_Attribution_libdbus-1-headers", + "reason": "The owning SBOM package is not part of the deployed product files (no dependency path from a deployed Qt module/plugin)." + }, + { + "id": "cocoa-platform-plugin", + "name": "Cocoa Platform Plugin", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/plugins/platforms/cocoa/qt_attribution.json", + "entry_index": 0, + "sha256": "27a435bfea96ca950f4a5ad6a82be7fe2a62bb4db0d8851e7a84fc5dce0c3ff3" + }, + "category": "source_declaration_not_in_sbom", + "reason": "The pinned source archive declares this attribution, but the shipped SBOM has no package for it; it is not established as compiled into a deployed binary." + }, + { + "id": "cmake-runcmake-test-modules", + "name": "cmake-runcmake-test-modules", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/testinternal/3rdparty/cmake/qt_attribution.json", + "entry_index": 0, + "sha256": "f194ea33cf9b0d44615a6fa9eb4d45e7796b50cb0a88cdadf5d9b15745bf52f0" + }, + "category": "owning_package_not_deployed", + "sbom_package": "TestInternalsPrivate_Attribution_cmake-runcmake-test-modules", + "reason": "The owning SBOM package is not part of the deployed product files (no dependency path from a deployed Qt module/plugin)." + }, + { + "id": "catch2", + "name": "Catch2", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/testlib/3rdparty/catch2/qt_attribution.json", + "entry_index": 0, + "sha256": "9d48fa7b86e9b0412b699e0411815766914478592da5bbb614a45443c14504b0" + }, + "category": "owning_package_not_deployed", + "sbom_package": "Test_Attribution_catch2", + "reason": "The owning SBOM package is not part of the deployed product files (no dependency path from a deployed Qt module/plugin)." + }, + { + "id": "cycle", + "name": "Cycle", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/testlib/3rdparty/cycle/qt_attribution.json", + "entry_index": 0, + "sha256": "a3ff23399b7ece1a0c6a9696e4f8c671a495f92a74c9c53ea5b66f27bd56b056" + }, + "category": "owning_package_not_deployed", + "sbom_package": "Test_Attribution_cycle", + "reason": "The owning SBOM package is not part of the deployed product files (no dependency path from a deployed Qt module/plugin)." + }, + { + "id": "linuxperf", + "name": "Linux Performance Events", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/testlib/3rdparty/linux/qt_attribution.json", + "entry_index": 0, + "sha256": "44299f5c08474790c164e73894b81b650463f9e40121041cefdeebd9b5eb734c" + }, + "category": "owning_package_not_deployed", + "sbom_package": "Test_Attribution_linuxperf", + "reason": "The owning SBOM package is not part of the deployed product files (no dependency path from a deployed Qt module/plugin)." + }, + { + "id": "valgrind", + "name": "Valgrind", + "attribution": { + "member": "qtbase-everywhere-src-6.10.3/src/testlib/3rdparty/valgrind/qt_attribution.json", + "entry_index": 0, + "sha256": "202daf86588d8cded6c492d490cec190e5790796fff23ec5065b116b78e70fbc" + }, + "category": "owning_package_not_deployed", + "sbom_package": "Test_Attribution_valgrind", + "reason": "The owning SBOM package is not part of the deployed product files (no dependency path from a deployed Qt module/plugin)." + } + ], + "license_texts": { + "Apache-2.0": { + "path": "third_party/qt/LICENSES/Apache-2.0.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/Apache-2.0.txt", + "bytes": 10398, + "sha256": "e3ba223bb1423f0aad8c3dfce0fe3148db48926d41e6fbc3afbbf5ff9e1c89cb" + }, + "BSD-2-Clause": { + "path": "third_party/qt/LICENSES/BSD-2-Clause.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/BSD-2-Clause.txt", + "bytes": 1276, + "sha256": "8fda146749ca071ac9cdce2e24d25444676ea48d1f9dccc2b7c15c054b717db8" + }, + "BSD-3-Clause": { + "path": "third_party/qt/LICENSES/BSD-3-Clause.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/BSD-3-Clause.txt", + "bytes": 1469, + "sha256": "9f0490f18656c6f2435bd14f603ef0c96434d1825615363dce43abb42ed1dcce" + }, + "CC0-1.0": { + "path": "third_party/qt/LICENSES/CC0-1.0.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/CC0-1.0.txt", + "bytes": 7048, + "sha256": "a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499" + }, + "FTL": { + "path": "third_party/qt/LICENSES/FTL.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/FTL.txt", + "bytes": 6743, + "sha256": "08c135755dd589039470f1fdbb400daaabaaa50d0b366d19cebff4d22986baa1" + }, + "GPL-2.0-only": { + "path": "third_party/qt/LICENSES/GPL-2.0-only.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/GPL-2.0-only.txt", + "bytes": 18092, + "sha256": "8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643" + }, + "HPND": { + "path": "third_party/qt/LICENSES/HPND.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/HPND.txt", + "bytes": 1188, + "sha256": "67ac968431270291f5e9cd3ed76705e1169f57082ee102093b2543b28cef63cf" + }, + "IJG": { + "path": "third_party/qt/LICENSES/IJG.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/IJG.txt", + "bytes": 1815, + "sha256": "1cb448f5e2e6d3aca60943f4eee1a04675628dc0266a074a42bc1560ebc28d61" + }, + "Imlib2": { + "path": "third_party/qt/LICENSES/Imlib2.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/Imlib2.txt", + "bytes": 1986, + "sha256": "8846f2baba1a7f4c36f7ca19a923a000d8a21afa37cf0fe006f6ce88a6058a89" + }, + "LGPL-3.0-only": { + "path": "third_party/qt/LICENSES/LGPL-3.0-only.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/LGPL-3.0-only.txt", + "bytes": 7651, + "sha256": "da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768" + }, + "Libpng": { + "path": "third_party/qt/LICENSES/Libpng.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/Libpng.txt", + "bytes": 4120, + "sha256": "58fe669792f9b4e0740bf75ecfe90b5326128bb2ce7e27e1c342abd9db4d8ea6" + }, + "LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception": { + "path": "third_party/qt/LICENSES/LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception.txt", + "bytes": 1852, + "sha256": "0526625fcc746a42d3f19a0ab357d3dc8479fdbe3bfd168825498f50215c7a63" + }, + "LicenseRef-ICC-License": { + "path": "third_party/qt/LICENSES/LicenseRef-ICC-License.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/LicenseRef-ICC-License.txt", + "bytes": 463, + "sha256": "9e34ff47b3a44814e183342e7e198d127a6740e29d20e8381fba7688dafc79dd" + }, + "LicenseRef-Lcs-Telegraphics": { + "path": "third_party/qt/LICENSES/LicenseRef-Lcs-Telegraphics.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/LicenseRef-Lcs-Telegraphics.txt", + "bytes": 139, + "sha256": "c10225ebbd5191bfdd761b0d7752c785f2453ab665d6c454473fb12d254668aa" + }, + "LicenseRef-SHA1-Public-Domain": { + "path": "third_party/qt/LICENSES/LicenseRef-SHA1-Public-Domain.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/LicenseRef-SHA1-Public-Domain.txt", + "bytes": 144, + "sha256": "65d86b8ec6b1cd8b8f6e64fd8710274ba00d6a3c520e00dfdcd1c3d2071f3305" + }, + "MIT": { + "path": "third_party/qt/LICENSES/MIT.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/MIT.txt", + "bytes": 1111, + "sha256": "d040359701c01996a017d5c515678929cd1b0625e64cb86db44025fbb6cdf1fc" + }, + "MIT-open-group": { + "path": "third_party/qt/LICENSES/MIT-open-group.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/MIT-open-group.txt", + "bytes": 897, + "sha256": "c55d2ab72d8a4f9e9cd8fbd1379268e575e8cfa16874affa5899b75a6d754514" + }, + "MPL-2.0": { + "path": "third_party/qt/LICENSES/MPL-2.0.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/MPL-2.0.txt", + "bytes": 16726, + "sha256": "3f3d9e0024b1921b067d6f7f88deb4a60cbe7a78e76c64e3f1d7fc3b779b9d04" + }, + "Unicode-3.0": { + "path": "third_party/qt/LICENSES/Unicode-3.0.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/Unicode-3.0.txt", + "bytes": 1995, + "sha256": "80bb6294022d8764adb36a9d65ebb6bd94efb1865918a71e31e6c247607d7634" + }, + "X11": { + "path": "third_party/qt/LICENSES/X11.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/X11.txt", + "bytes": 1338, + "sha256": "e2936c6509784b4f0ec27bac74182393866fad9422b29a70e085ff14aba87193" + }, + "Zlib": { + "path": "third_party/qt/LICENSES/Zlib.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/Zlib.txt", + "bytes": 1465, + "sha256": "d7e3139972874dc8abdbbfce27ec1e6f942b28279dd7d27453630a8b4610e080" + }, + "libpng-2.0": { + "path": "third_party/qt/LICENSES/libpng-2.0.txt", + "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/libpng-2.0.txt", + "bytes": 5345, + "sha256": "7317e078e2d3b5d7ba5a6159e650945153262b44b76f6700f8e9edb261c5143e" + } + }, + "qt_module_license": { + "expression": "LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only", + "selected_option": "LGPL-3.0-only", + "bundled_text": "third_party/qt/LICENSES/LGPL-3.0-only.txt", + "alternatives_not_bundled": [ + "LicenseRef-Qt-Commercial", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "note": "The product takes the dynamic-link LGPL-3.0-only option. Other alternative options are not bundled; corresponding-source and replacement conditions remain part of the pending review." + }, + "unresolved": [ + "SBOM packaged-file SHA-1 values do not match the pinned SDK binaries; SBOM is evidence for package relationships, while deployed-file byte identity is bound by the pinned archive and prepared SDK tree digest.", + "Two build-system attributions (extra-cmake-modules, KWin CMake modules) are excluded as tool-only declarations; they are listed under excluded_attributions.", + "Corresponding-source delivery, relinking/replacement conditions and a clean-machine run are not evaluated by this inventory and remain pending user review." + ] +} diff --git a/third_party/qt/manifest.json b/third_party/qt/manifest.json index 6976f8e..6f26043 100644 --- a/third_party/qt/manifest.json +++ b/third_party/qt/manifest.json @@ -87,7 +87,7 @@ "https://doc.qt.io/qt-6.10/licenses-used-in-qt.html" ], "third_party_code_scope": "Qt includes third-party components with their own licenses; the module-level expression is not a full deployed-file license inventory.", - "redistribution_review_status": "pending_before_product_distribution", + "redistribution_review_status": "materials_prepared_user_review_pending", "bundled_text_files": [ { "spdx": "LGPL-3.0-only", @@ -99,7 +99,23 @@ "source_archive_sha256": "383dc907816338f0cba72088a524c07458dfc69ce684ca9132fcc4fe91c24b0b", "source_archive_member": "qtbase-everywhere-src-6.10.3/LICENSES/LGPL-3.0-only.txt" } - ] + ], + "deployed_component_note": "The complete deployed-component and license-text set is recorded in components.json; bundled_text_files records the LGPL text the product itself relies on." + }, + "deployed_component_inventory": { + "path": "components.json", + "schema": "termforge-qt-deployed-components-v1", + "entry": "python -m tools.build_qt_component_inventory build", + "check_entry": "python -m tools.build_qt_component_inventory check", + "sbom_path_in_prepared_sdk": "sbom/qtbase-6.10.3.spdx.json", + "sbom_sha256": "51bdcf25ae10a6af0ce10030bf816ab10da0b2f70b35e0e9c55bd4b43241e659", + "evidence_levels": { + "sbom_module_dependency": "The SBOM package graph connects the component to the deployed module/plugin package; recorded for every shipped component.", + "source_attribution_match": "The component's Id, license ids, version and license files are cross-checked against qt_attribution.json from the pinned source archive.", + "excluded_attributions": "Build-system/tool-only attributions and packages owned by non-deployed modules; recorded as not shipped rather than silently ignored.", + "sbom_binary_checksum": "Not usable: the SBOM packaged-file SHA-1 values do not match the archived SDK binaries; deployed-file byte identity comes from the pinned archive and prepared SDK tree digest." + }, + "review_status": "materials_prepared_user_review_pending" }, "installer": { "name": "aqtinstall", @@ -119,8 +135,9 @@ "deployment_status": { "published_product_package": false, "clean_machine_runtime_validation": "pending", + "third_party_component_provenance": "materials_prepared_user_review_pending", "license_notices_and_corresponding_source_review": "pending", "sdk_translations_installed": false, - "note": "The current local build uses windeployqt without translations or compiler-runtime deployment; no standalone clean-machine runtime completeness is claimed." + "note": "The current local build uses windeployqt without translations or compiler-runtime deployment. Deployed-component provenance and canonical license texts are recorded in components.json; corresponding-source/replacement conditions and clean-machine runtime completeness are not claimed." } } diff --git a/tools/build_qt_component_inventory.py b/tools/build_qt_component_inventory.py new file mode 100644 index 0000000..6b1a785 --- /dev/null +++ b/tools/build_qt_component_inventory.py @@ -0,0 +1,671 @@ +"""Derive the deployed Qt third-party component and license inventory. + +The product ships a fixed set of Qt binaries from the manifest-pinned qtbase +6.10.3 archive. This tool reads that archive's own ``qt_attribution.json`` +files and the SPDX SBOM shipped in the prepared SDK, traces each deployed +library/plugin to its module package and the third-party packages that module +declares, and writes a machine-readable inventory plus the canonical license +texts needed for the shipped components. + +Evidence levels are kept explicit: a component is listed as deployed only when +the SBOM package graph connects it to the deployed module/plugin package; the +source archive attribution is then cross-checked for identity and license. +Source-tree-only declarations, build-tool attributions and packages owned by +modules that are not deployed are recorded as excluded instead of being +silently treated as shipped. + +The tool never authenticates, installs, executes, publishes or accepts the +product. It records facts and the remaining gaps; it does not produce a legal +redistribution conclusion. +""" +from __future__ import annotations + +import argparse +import hashlib +import json +from pathlib import Path +import posixpath +import re +import tarfile +import tempfile + +ROOT = Path(__file__).resolve().parents[1] +SCHEMA = "termforge-qt-deployed-components-v1" +OPERATION_SCHEMA = "termforge-qt-component-operation-v1" +INVENTORY_PATH = "third_party/qt/components.json" +LICENSES_PATH = "third_party/qt/LICENSES" +CONTRACT_PATH = "packaging/qt-product/manifest.json" +QT_MANIFEST_PATH = "third_party/qt/manifest.json" +SOURCE_PREFIX = "qtbase-everywhere-src-6.10.3/" +QT_MODULE_LICENSE = "LGPL-3.0-only" + +if __package__: + from tools.prepare_qt_build import PreparationError, acquire +else: # pragma: no cover - direct script execution is diagnostic only + from prepare_qt_build import PreparationError, acquire + + +class InventoryError(Exception): + """A fixed public code; never a raw process, network or filesystem message.""" + + +def sha256_bytes(data: bytes) -> str: + return hashlib.sha256(data).hexdigest() + + +def read_json(path: Path) -> dict: + try: + value = json.loads(path.read_text(encoding="utf-8")) + except (OSError, UnicodeError, json.JSONDecodeError): + raise InventoryError("input_unreadable") from None + if not isinstance(value, dict): + raise InventoryError("input_schema") + return value + + +def read_json_bytes(data: bytes, *, tolerant: bool = False) -> dict | list: + try: + return json.loads(data.decode("utf-8"), strict=not tolerant) + except (UnicodeError, json.JSONDecodeError): + raise InventoryError("attribution_json") from None + + +def license_ids(expression: str | None) -> list[str]: + """SPDX expression license ids, ignoring operators and WITH exceptions.""" + tokens = re.findall(r"[A-Za-z0-9.:_+\-]+", expression or "") + identifiers = [] + skip_exception = False + for token in tokens: + if token in ("OR", "AND"): + skip_exception = False + continue + if token == "WITH": + skip_exception = True + continue + if skip_exception: + skip_exception = False + continue + if token not in identifiers: + identifiers.append(token) + return sorted(identifiers) + + +def attribution_reference(package: dict) -> tuple[str, int] | None: + """Read the attribution file member and entry index from an SBOM package comment.""" + comment = package.get("comment") or "" + match = re.search(r"/src_dir/qtbase/(.+?qt_attribution\.json)", comment) + if not match: + return None + index = re.search(r"Entry index:\s*(\d+)", comment) + return match.group(1), int(index.group(1)) if index else 0 + + +def attribution_id(package: dict) -> str | None: + match = re.search(r"^\s*Id:\s*(\S+)\s*$", package.get("comment") or "", re.MULTILINE) + return match.group(1) if match else None + + +def is_third_party(package: dict) -> bool: + name = package.get("name", "") + if "_Attribution_" in name or name.startswith("Bundled"): + return True + location = package.get("downloadLocation") or "" + if not location or location == "NOASSERTION": + return False + if location.startswith("git://code.qt.io/qt/") or "qt.io" in location: + return False + return True + + +def sbom_indexes(sbom: dict): + packages = {entry["SPDXID"]: entry for entry in sbom.get("packages", []) if "SPDXID" in entry} + files = {entry["SPDXID"]: entry for entry in sbom.get("files", []) if "SPDXID" in entry} + contains = {} + contained_by = {} + depends = {} + for relationship in sbom.get("relationships", []): + kind = relationship.get("relationshipType") + source = relationship.get("spdxElementId") + target = relationship.get("relatedSpdxElement") + if kind == "CONTAINS": + contains.setdefault(source, []).append(target) + contained_by.setdefault(target, []).append(source) + elif kind == "DEPENDS_ON": + depends.setdefault(source, []).append(target) + return packages, files, contains, contained_by, depends + + +def sbom_file_for_deployed_name(sbom_files: dict, deployed_name: str) -> dict: + """Map a staged relative Qt file to its non-debug SBOM packaged-file entry.""" + candidates = [entry for entry in sbom_files.values() + if entry.get("fileName", "").endswith("/" + deployed_name) + and "Debug" not in entry.get("SPDXID", "")] + if len(candidates) != 1: + raise InventoryError(f"sbom_file:{deployed_name}") + return candidates[0] + + +def component_packages(depends: dict, packages: dict, module_id: str) -> dict[str, dict]: + """Third-party packages embedded in a module, following third-party edges only.""" + found: dict[str, dict] = {} + + def walk(package_id: str, depth: int): + for child in depends.get(package_id, []): + package = packages.get(child) + if package is None or not is_third_party(package): + continue + if child not in found or found[child]["depth"] > depth: + found[child] = {"package": package, "depth": depth} + walk(child, depth + 1) + + walk(module_id, 1) + return found + + +def sbom_component_map(sbom: dict, deployed_names: list[str]) -> dict[str, dict]: + """Per deployed file, the SBOM-proven third-party package set. + + Returns ``{deployed_file: {component_id: {...}}}`` where ``component_id`` + is the attribution id parsed from the SBOM package comment. The map is + derived purely from the SBOM, so staging and the inventory builder can + independently recompute and compare it without the source archive. + """ + packages, files, _, contained_by, depends = sbom_indexes(sbom) + result = {} + for name in deployed_names: + file_entry = sbom_file_for_deployed_name(files, name) + owners = sorted({owner for owner in contained_by.get(file_entry["SPDXID"], []) + if owner in packages}) + if len(owners) != 1: + raise InventoryError(f"sbom_owner:{name}") + embedded = component_packages(depends, packages, owners[0]) + components = {} + for package_id, detail in embedded.items(): + package = detail["package"] + identifier = attribution_id(package) + if identifier is None: + raise InventoryError(f"sbom_attribution_id:{package.get('name')}") + previous = components.get(identifier) + if previous is not None: + if (license_ids(previous["license_expression"]) != + license_ids(package.get("licenseConcluded"))): + raise InventoryError(f"sbom_license_conflict:{identifier}") + continue + components[identifier] = { + "license_expression": package.get("licenseConcluded"), + "depth": detail["depth"], + "package": package, + } + result[name] = {"module": packages[owners[0]].get("name"), "components": components} + return result + + +def load_source(archive_path: Path) -> tuple[dict[str, bytes], dict[tuple[str, int], dict], set[str]]: + """Read attribution files, license texts and member names from the pinned archive.""" + attributions: dict[tuple[str, int], dict] = {} + license_texts: dict[str, bytes] = {} + try: + with tarfile.open(archive_path, "r:xz") as archive: + members = {member.name: member for member in archive.getmembers() if member.isfile()} + archive_names = set(members) + for name in sorted(archive_names): + if not name.endswith("qt_attribution.json"): + continue + raw = archive.extractfile(members[name]).read() + data = read_json_bytes(raw, tolerant=True) + entries = data if isinstance(data, list) else [data] + relative = name[len(SOURCE_PREFIX):] if name.startswith(SOURCE_PREFIX) else name + for index, entry in enumerate(entries): + if not isinstance(entry, dict): + raise InventoryError("attribution_json") + attributions[(relative, index)] = { + "data": entry, + "bytes": len(raw), + "sha256": sha256_bytes(raw), + } + for name in sorted(archive_names): + match = re.fullmatch(re.escape(SOURCE_PREFIX) + r"LICENSES/([^/]+)\.txt", name) + if match: + license_texts[match.group(1)] = archive.extractfile(members[name]).read() + except (OSError, tarfile.TarError, EOFError): + raise InventoryError("source_archive_unreadable") from None + return license_texts, attributions, archive_names + + +def read_members(archive_path: Path, wanted: set[str]) -> dict[str, bytes]: + """Read selected archive members in a single pass.""" + result = {} + try: + with tarfile.open(archive_path, "r:xz") as archive: + for member in archive: + if member.isfile() and member.name in wanted: + result[member.name] = archive.extractfile(member).read() + if len(result) == len(wanted): + break + except (OSError, tarfile.TarError, EOFError): + raise InventoryError("source_archive_unreadable") from None + if set(result) != wanted: + raise InventoryError("source_member:mixed") + return result + + +def normalize_copyright(value) -> str: + if isinstance(value, list): + return "\n".join(str(item) for item in value) + return "" if value is None else str(value) + + +def license_file_members(entry: dict, attribution_relative: str) -> list[str]: + """Resolve declared license/copyright files to full source-archive members.""" + directory = posixpath.dirname(SOURCE_PREFIX + attribution_relative) + declared = entry.get("LicenseFile") + if isinstance(declared, str): + declared = [declared] + declared = list(declared or []) + list(entry.get("LicenseFiles") or []) + copyright_file = entry.get("CopyrightFile") + if isinstance(copyright_file, str): + declared.append(copyright_file) + resolved = [] + for relative in declared: + if not isinstance(relative, str) or not relative or relative.startswith("/"): + raise InventoryError("attribution_license_file") + member = posixpath.normpath(posixpath.join(directory, relative)) + if member not in resolved: + resolved.append(member) + return resolved + + +def derive_deployed_files(contract: dict) -> list[str]: + deployed = contract.get("qt_deployed") or {} + libraries = deployed.get("libraries") or [] + plugins = deployed.get("plugins") or [] + files = [] + for name in libraries: + if Path(name).name != name or not name.endswith(".dll"): + raise InventoryError("contract_deployed_files") + files.append(name) + for name in plugins: + relative = Path(name) + if len(relative.parts) < 2 or ".." in relative.parts or relative.suffix != ".dll": + raise InventoryError("contract_deployed_files") + files.append(name) + return sorted(files) + + +def derive_inventory(source_archive: Path, sbom: dict, sbom_sha256: str, sdk_dir: Path, + contract: dict, qt_manifest: dict) -> tuple[dict, dict[str, bytes]]: + deployed_names = derive_deployed_files(contract) + sbom_map = sbom_component_map(sbom, deployed_names) + license_texts, attributions, archive_names = load_source(source_archive) + + packages, files, _, contained_by, depends = sbom_indexes(sbom) + file_sha1_checks = {"algorithm": "SHA1", "compared_files": 0, "matching_files": 0, + "mismatched_files": []} + for name in deployed_names: + file_entry = sbom_file_for_deployed_name(files, name) + expected = next((checksum["checksumValue"] for checksum in file_entry.get("checksums", []) + if checksum.get("algorithm") == "SHA1"), None) + local = (sdk_dir / "bin" / name) if "/" not in name else (sdk_dir / "plugins" / name) + if not local.is_file(): + raise InventoryError(f"sdk_file:{name}") + actual = hashlib.sha1(local.read_bytes()).hexdigest() + file_sha1_checks["compared_files"] += 1 + if expected == actual: + file_sha1_checks["matching_files"] += 1 + else: + file_sha1_checks["mismatched_files"].append(name) + + components: dict[str, dict] = {} + expressions: dict[str, str] = {} + license_members_by_component: dict[str, list[str]] = {} + deployed_references: set[tuple[str, int]] = set() + for name in deployed_names: + for identifier, detail in sbom_map[name]["components"].items(): + package = detail["package"] + reference = attribution_reference(package) + if reference is None: + raise InventoryError(f"attribution_reference:{identifier}") + attribution = attributions.get(reference) + if attribution is None: + raise InventoryError(f"attribution_missing:{identifier}") + deployed_references.add(reference) + entry = attribution["data"] + if entry.get("Id") != identifier: + raise InventoryError(f"attribution_id:{identifier}") + expression = package.get("licenseConcluded") or "" + if license_ids(expression) != license_ids(entry.get("LicenseId")): + raise InventoryError(f"license_id:{identifier}") + if identifier in expressions and expressions[identifier] != expression: + raise InventoryError(f"license_expression_conflict:{identifier}") + expressions[identifier] = expression + attribution_version = entry.get("Version") + sbom_version = package.get("versionInfo") + if (attribution_version and sbom_version not in (None, "unknown") + and str(attribution_version) != str(sbom_version)): + raise InventoryError(f"version:{identifier}") + license_members = license_file_members(entry, reference[0]) + for member in license_members: + if member not in archive_names: + raise InventoryError(f"attribution_license_missing:{identifier}") + record = components.setdefault(identifier, { + "id": identifier, + "name": entry.get("Name", identifier), + "version": str(attribution_version or sbom_version or "unknown"), + "license_expression": expression, + "license_ids": license_ids(expression), + "deployed_files": set(), + "evidence": {"level": "sbom_module_dependency", "depth": detail["depth"], + "sbom_packages": []}, + "attribution": { + "member": SOURCE_PREFIX + reference[0], + "entry_index": reference[1], + "bytes": attribution["bytes"], + "sha256": attribution["sha256"], + "qt_usage": entry.get("QtUsage"), + "qt_parts": entry.get("QtParts"), + "license_files": [], + "copyright": normalize_copyright(entry.get("Copyright")), + }, + "source": { + "homepage": entry.get("Homepage"), + "download_location": entry.get("DownloadLocation") or package.get("downloadLocation"), + "purl": entry.get("PURL"), + }, + }) + record["deployed_files"].add(name) + record["evidence"]["depth"] = min(record["evidence"]["depth"], detail["depth"]) + sbom_name = package.get("name") + if sbom_name not in record["evidence"]["sbom_packages"]: + record["evidence"]["sbom_packages"].append(sbom_name) + license_members_by_component[identifier] = license_members + + needed_members = {member for members in license_members_by_component.values() for member in members} + member_bytes = read_members(source_archive, needed_members) if needed_members else {} + for identifier, members in license_members_by_component.items(): + components[identifier]["attribution"]["license_files"] = [ + {"member": member, "bytes": len(member_bytes[member]), + "sha256": sha256_bytes(member_bytes[member])} + for member in members + ] + + for record in components.values(): + if license_ids(record["license_expression"]) != record["license_ids"]: + raise InventoryError("license_expression") + record["deployed_files"] = sorted(record["deployed_files"]) + record["evidence"]["sbom_packages"] = sorted(record["evidence"]["sbom_packages"]) + + required_ids = sorted({identifier for record in components.values() + for identifier in record["license_ids"]} | {QT_MODULE_LICENSE}) + missing_texts = [identifier for identifier in required_ids if identifier not in license_texts] + if missing_texts: + raise InventoryError("license_text_missing:" + ",".join(missing_texts)) + + # Source-tree declarations that are not established as shipped. Two kinds + # are kept separate: attributions reachable only through internal build + # packages, and declarations owned by modules outside the deployed set. + sbom_attribution = {} + for package_id, package in packages.items(): + reference = attribution_reference(package) + if reference is not None: + sbom_attribution[reference] = package_id + reachable = set() + for name in deployed_names: + file_entry = sbom_file_for_deployed_name(files, name) + owners = sorted({owner for owner in contained_by.get(file_entry["SPDXID"], []) + if owner in packages}) + pending = [owners[0]] + while pending: + current = pending.pop() + for child in depends.get(current, []): + if child not in reachable: + reachable.add(child) + pending.append(child) + + excluded = [] + declared_not_deployed = [] + for (member, index), attribution in sorted(attributions.items()): + if (member, index) in deployed_references: + continue + entry = attribution["data"] + package_id = sbom_attribution.get((member, index)) + record = {"id": entry.get("Id"), "name": entry.get("Name"), + "attribution": {"member": SOURCE_PREFIX + member, "entry_index": index, + "sha256": attribution["sha256"]}} + if package_id is None: + record["category"] = "source_declaration_not_in_sbom" + record["reason"] = ("The pinned source archive declares this attribution, but the shipped " + "SBOM has no package for it; it is not established as compiled into a deployed binary.") + declared_not_deployed.append(record) + elif package_id in reachable: + record["category"] = "internal_build_platform_attribution" + record["qt_usage"] = entry.get("QtUsage") + record["qt_parts"] = entry.get("QtParts") + record["sbom_package"] = packages[package_id].get("name") + record["reason"] = ("Reachable from a deployed module only through internal Qt build/platform " + "packages; the attribution declares build-system/tool use, not a runtime " + "component of the packaged binary.") + excluded.append(record) + else: + owning = packages[package_id].get("name") + record["category"] = "owning_package_not_deployed" + record["sbom_package"] = owning + record["reason"] = ("The owning SBOM package is not part of the deployed product files " + "(no dependency path from a deployed Qt module/plugin).") + declared_not_deployed.append(record) + + qt_manifest_source = qt_manifest.get("source") or {} + inventory = { + "schema": SCHEMA, + "scope": ("Qt 6.10.3 third-party component and license evidence for the fixed Windows x64 " + "product staging. Materials for review; not a legal redistribution conclusion."), + "review_status": "materials_prepared_user_review_pending", + "qt_version": qt_manifest.get("version"), + "source": { + "url": qt_manifest_source.get("source_archive_url"), + "bytes": qt_manifest_source.get("source_archive_bytes"), + "sha256": qt_manifest_source.get("source_archive_sha256"), + }, + "sbom": { + "path": "sbom/qtbase-6.10.3.spdx.json", + "sha256": sbom_sha256, + "spdx_version": sbom.get("spdxVersion"), + "created": (sbom.get("creationInfo") or {}).get("created"), + "binary_file_checksums": { + "algorithm": file_sha1_checks["algorithm"], + "checked_files": file_sha1_checks["compared_files"], + "matching_files": file_sha1_checks["matching_files"], + "mismatched_files": file_sha1_checks["mismatched_files"], + "note": ("The SBOM ships in the pinned binary archive, but its packaged-file SHA-1 values " + "do not match the archived SDK binaries. Per-file byte identity therefore comes " + "from the pinned archive/SDK tree identity, not from SBOM file checksums."), + }, + }, + "method": { + "deployed_file_mapping": ("Each staged Qt library/plugin maps to the single non-Debug SBOM " + "packaged file; its owning SBOM package supplies the module/plugin class."), + "component_mapping": ("Third-party packages reached from the owning package through DEPENDS_ON " + "edges are included; traversal follows only third-party packages and stops at " + "internal Qt packages. Existence in the source tree alone is not treated as shipped."), + "attribution_cross_check": ("Each component's SBOM package comment is resolved to a " + "qt_attribution.json member and entry index in the pinned source " + "archive; Id, license ids, version and license files are verified."), + "license_texts": ("Canonical LICENSES/.txt files come from the same pinned source archive; " + "component-specific upstream license files are recorded by member and SHA-256."), + }, + "deployed_files": { + name: { + "module_package": sbom_map[name]["module"], + "component_ids": sorted(sbom_map[name]["components"]), + } + for name in deployed_names + }, + "components": {identifier: record for identifier, record in sorted(components.items())}, + "excluded_attributions": excluded, + "declared_not_deployed": declared_not_deployed, + "license_texts": { + identifier: { + "path": f"{LICENSES_PATH}/{identifier}.txt", + "source_archive_member": SOURCE_PREFIX + f"LICENSES/{identifier}.txt", + "bytes": len(license_texts[identifier]), + "sha256": sha256_bytes(license_texts[identifier]), + } + for identifier in required_ids + }, + "qt_module_license": { + "expression": "LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only", + "selected_option": QT_MODULE_LICENSE, + "bundled_text": f"{LICENSES_PATH}/{QT_MODULE_LICENSE}.txt", + "alternatives_not_bundled": ["LicenseRef-Qt-Commercial", "GPL-2.0-only", "GPL-3.0-only"], + "note": ("The product takes the dynamic-link LGPL-3.0-only option. Other alternative options " + "are not bundled; corresponding-source and replacement conditions remain part of " + "the pending review."), + }, + "unresolved": [ + ("SBOM packaged-file SHA-1 values do not match the pinned SDK binaries; SBOM is evidence for " + "package relationships, while deployed-file byte identity is bound by the pinned archive and " + "prepared SDK tree digest."), + ("Two build-system attributions (extra-cmake-modules, KWin CMake modules) are excluded as " + "tool-only declarations; they are listed under excluded_attributions."), + ("Corresponding-source delivery, relinking/replacement conditions and a clean-machine run are " + "not evaluated by this inventory and remain pending user review."), + ], + } + return inventory, {identifier: license_texts[identifier] for identifier in required_ids} + + +def resolve_archive(arguments, qt_manifest: dict) -> Path: + source = qt_manifest.get("source") or {} + name = Path(source.get("source_archive_url", "")).name + size = source.get("source_archive_bytes") + digest = source.get("source_archive_sha256") + if not name or not isinstance(size, int) or not isinstance(digest, str): + raise InventoryError("source_pin") + if arguments.source_archive is not None: + path = arguments.source_archive.resolve() + if not path.is_file() or path.stat().st_size != size or sha256_path(path) != digest: + raise InventoryError("source_archive_identity") + return path + cache = arguments.cache.resolve() + try: + return acquire(cache, name, source["source_archive_url"], size, digest, arguments.offline).resolve() + except PreparationError as error: + raise InventoryError(str(error)) from None + + +def sha256_path(path: Path) -> str: + with path.open("rb") as source: + return hashlib.file_digest(source, "sha256").hexdigest() + + +def json_bytes(value: dict) -> bytes: + return (json.dumps(value, ensure_ascii=False, indent=2) + "\n").encode("utf-8") + + +def write_outputs(inventory: dict, texts: dict[str, bytes], inventory_path: Path, licenses_dir: Path) -> None: + inventory_path.parent.mkdir(parents=True, exist_ok=True) + licenses_dir.mkdir(parents=True, exist_ok=True) + existing = {path.stem for path in licenses_dir.glob("*.txt")} + stale = sorted(existing - set(texts)) + if stale: + raise InventoryError("license_text_stale:" + ",".join(stale[:5])) + with tempfile.NamedTemporaryFile(prefix=".components-", dir=inventory_path.parent, delete=False) as handle: + candidate = Path(handle.name) + handle.write(json_bytes(inventory)) + try: + candidate.replace(inventory_path) + finally: + candidate.unlink(missing_ok=True) + for identifier, data in texts.items(): + target = licenses_dir / f"{identifier}.txt" + target.write_bytes(data) + + +def compare(existing_path: Path, derived: dict, texts: dict[str, bytes], licenses_dir: Path) -> dict: + existing = read_json(existing_path) + if existing != derived: + missing = sorted(set(derived) - set(existing)) + extra = sorted(set(existing) - set(derived)) + detail = [] + if missing: + detail.append("missing_sections:" + ",".join(missing[:5])) + if extra: + detail.append("extra_sections:" + ",".join(extra[:5])) + if not detail: + for key in sorted(set(existing) & set(derived)): + if existing[key] != derived[key]: + detail.append("section:" + key) + break + raise InventoryError("inventory_mismatch:" + ";".join(detail)) + for identifier, data in texts.items(): + target = licenses_dir / f"{identifier}.txt" + if not target.is_file() or target.read_bytes() != data: + raise InventoryError(f"license_text_mismatch:{identifier}") + return existing + + +def run(arguments, write: bool) -> dict: + qt_manifest = read_json(ROOT / QT_MANIFEST_PATH) + contract = read_json(ROOT / CONTRACT_PATH) + sbom_path = arguments.sbom.resolve() + try: + sbom_bytes = sbom_path.read_bytes() + except OSError: + raise InventoryError("sbom_unreadable") from None + try: + sbom = json.loads(sbom_bytes.decode("utf-8")) + except (UnicodeError, json.JSONDecodeError): + raise InventoryError("sbom_unreadable") from None + archive = resolve_archive(arguments, qt_manifest) + pinned_sbom = (qt_manifest.get("license") or {}).get("evidence", {}).get("sdk_sbom_sha256") + if pinned_sbom != sha256_bytes(sbom_bytes): + raise InventoryError("sbom_manifest_identity") + inventory, texts = derive_inventory(archive, sbom, sha256_bytes(sbom_bytes), + arguments.sdk_dir.resolve(), contract, qt_manifest) + inventory_path = arguments.inventory.resolve() + licenses_dir = arguments.licenses_dir.resolve() + if write: + write_outputs(inventory, texts, inventory_path, licenses_dir) + else: + compare(inventory_path, inventory, texts, licenses_dir) + return {"schema": OPERATION_SCHEMA, "status": "passed", + "operation": "build" if write else "check", + "components": len(inventory["components"]), + "license_texts": len(inventory["license_texts"]), + "deployed_files": len(inventory["deployed_files"]), + "sbom_sha256": inventory["sbom"]["sha256"], + "source_archive_sha256": inventory["source"]["sha256"], + "scope": "Inventory/license evidence only; no redistribution or platform acceptance."} + + +def main(argv=None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + for command, description in (("build", "Write the inventory and license texts"), + ("check", "Re-derive from the pinned inputs and require exact equality")): + subparser = commands.add_parser(command, help=description) + subparser.add_argument("--source-archive", type=Path, default=None, + help="Pinned qtbase source archive; acquired from --cache when omitted") + subparser.add_argument("--cache", type=Path, default=ROOT / "local/qt-downloads") + subparser.add_argument("--offline", action="store_true", + help="Require the pinned source archive to be already cached") + subparser.add_argument("--sbom", type=Path, required=True, + help="SPDX JSON from the prepared Qt SDK sbom directory") + subparser.add_argument("--sdk-dir", type=Path, required=True, + help="Prepared Qt SDK prefix used to compare SBOM SHA-1 file records") + subparser.add_argument("--inventory", type=Path, default=ROOT / INVENTORY_PATH) + subparser.add_argument("--licenses-dir", type=Path, default=ROOT / LICENSES_PATH) + arguments = parser.parse_args(argv) + try: + result = run(arguments, arguments.command == "build") + except InventoryError as error: + result = {"schema": OPERATION_SCHEMA, "status": "failed", + "operation": arguments.command, "error": str(error)} + except (OSError, ValueError, KeyError, TypeError): + result = {"schema": OPERATION_SCHEMA, "status": "failed", + "operation": arguments.command, "error": "inventory_input_failed"} + print(json.dumps(result, ensure_ascii=False, indent=2)) + return 0 if result["status"] == "passed" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/stage_qt_product.py b/tools/stage_qt_product.py index 2c58214..f4ee2c0 100644 --- a/tools/stage_qt_product.py +++ b/tools/stage_qt_product.py @@ -25,15 +25,23 @@ OPERATION_SCHEMA = "termforge-qt-product-operation-v1" CONTRACT_PATH = "packaging/qt-product/manifest.json" PREPARATION_SCHEMA = "termforge-qt-build-preparation-v1" +COMPONENT_SCHEMA = "termforge-qt-deployed-components-v1" ENTRY = "termforge_qt_shell.exe" NOTICES_PATH = "THIRD-PARTY-NOTICES.txt" +QT_NOTICES_PATH = "QT-THIRD-PARTY-NOTICES.txt" +QT_INVENTORY_STAGED = "licenses/qt/components.json" +QT_LICENSE_DIR = "licenses/qt" MANIFEST_PATH = "product-manifest.json" MAX_DETAIL = 8 if __package__: from tools.prepare_qt_build import tree_identity + from tools.build_qt_component_inventory import (derive_deployed_files, license_ids, + sbom_component_map) else: # pragma: no cover - direct script execution is diagnostic only from prepare_qt_build import tree_identity + from build_qt_component_inventory import (derive_deployed_files, license_ids, + sbom_component_map) class StagingError(Exception): @@ -236,7 +244,94 @@ def load_contract(root: Path) -> dict: return contract -def expected_files(root: Path, dependencies: Path, contract: dict, bin_dir: Path) -> dict: +def safe_relative(root: Path, relative: str, code: str) -> Path: + if not isinstance(relative, str): + raise StagingError(code) + candidate = Path(relative) + if candidate.is_absolute() or ".." in candidate.parts or len(candidate.parts) < 2: + raise StagingError(code) + path = root / candidate + if not path.is_file(): + raise StagingError(code) + return path + + +def load_component_inventory(root: Path, dependencies: Path, contract: dict) -> tuple[dict, str]: + """Load and cross-check the committed Qt third-party inventory against the SBOM.""" + evidence = contract["license_evidence"].get("qt") or {} + inventory = read_json(safe_relative(root, evidence.get("component_inventory"), + "component_inventory_contract")) + if (inventory.get("schema") != COMPONENT_SCHEMA or + inventory.get("review_status") != "materials_prepared_user_review_pending"): + raise StagingError("component_inventory_schema") + deployed = derive_deployed_files(contract) + deployed_files = inventory.get("deployed_files") + components = inventory.get("components") + if not isinstance(deployed_files, dict) or sorted(deployed_files) != deployed: + raise StagingError("component_inventory_deployed_files") + if not isinstance(components, dict) or not components: + raise StagingError("component_inventory_schema") + + sbom_path = dependencies / "qt" / "sbom" / "qtbase-6.10.3.spdx.json" + if not sbom_path.is_file(): + raise StagingError("component_inventory_sbom_missing") + try: + sbom = json.loads(sbom_path.read_text(encoding="utf-8")) + except (OSError, UnicodeError, json.JSONDecodeError): + raise StagingError("component_inventory_sbom_missing") from None + if inventory.get("sbom", {}).get("sha256") != sha256_path(sbom_path): + raise StagingError("component_inventory_sbom_identity") + try: + recomputed = sbom_component_map(sbom, deployed) + except Exception: # builder raises code-carrying errors; keep staging summary path-free + raise StagingError("component_inventory_sbom_mismatch") from None + for name in deployed: + declared = deployed_files[name] + actual = recomputed[name] + if declared.get("module_package") != actual["module"]: + raise StagingError("component_inventory_sbom_mismatch") + if sorted(declared.get("component_ids") or []) != sorted(actual["components"]): + raise StagingError("component_inventory_sbom_mismatch") + for identifier in declared.get("component_ids") or []: + if identifier not in components: + raise StagingError("component_inventory_sbom_mismatch") + + required = set() + for identifier, record in components.items(): + expression = record.get("license_expression") + identifiers = record.get("license_ids") + if license_ids(expression) != identifiers: + raise StagingError("component_inventory_license_ids") + required.update(identifiers) + if record.get("id") != identifier or not record.get("deployed_files"): + raise StagingError("component_inventory_schema") + module_option = (inventory.get("qt_module_license") or {}).get("selected_option") + if not isinstance(module_option, str): + raise StagingError("component_inventory_license_ids") + required.add(module_option) + texts = inventory.get("license_texts") + if not isinstance(texts, dict) or set(texts) != required: + raise StagingError("component_inventory_license_texts") + for identifier, identity in texts.items(): + source = safe_relative(root, identity.get("path"), f"component_license_identity:{identifier}") + if (source.stat().st_size != identity.get("bytes") or + sha256_path(source) != identity.get("sha256")): + raise StagingError(f"component_license_identity:{identifier}") + + qt_source = read_json(root / "third_party" / "qt" / "manifest.json").get("source") or {} + if inventory.get("source", {}).get("sha256") != qt_source.get("source_archive_sha256"): + raise StagingError("component_inventory_source_identity") + if inventory.get("qt_version") != summary_qt_version(root): + raise StagingError("component_inventory_schema") + return inventory, sha256_path(root / evidence["component_inventory"]) + + +def summary_qt_version(root: Path) -> str: + return read_json(root / "third_party" / "qt" / "manifest.json").get("version") + + +def expected_files(root: Path, dependencies: Path, contract: dict, bin_dir: Path, + inventory: dict, inventory_sha256: str) -> dict: """Map staged relative path to its verified origin and evidence class.""" expected = {} @@ -294,19 +389,12 @@ def add(path: str, source: Path, component: str, role: str, from_build: bool, raise StagingError("staging_contract_qt") add(name, dependencies / "qt" / "plugins" / relative, "qt", "runtime", True) - bundled_texts = qt_manifest.get("license", {}).get("bundled_text_files") or [] - declared_texts = contract["license_evidence"].get("qt", {}).get("bundled_texts") or [] - for target in declared_texts: - match = [entry for entry in bundled_texts - if isinstance(entry, dict) and Path(str(entry.get("path", ""))).name == Path(target).name] - if len(match) != 1: - raise StagingError("qt_license_manifest") - entry = match[0] - source = root / "third_party" / "qt" / entry["path"] - if (not source.is_file() or source.stat().st_size != entry.get("bytes") or - sha256_path(source) != entry.get("sha256")): - raise StagingError("qt_license_identity") - add(target, source, "qt", "license", False, entry.get("sha256")) + for identifier, identity in inventory["license_texts"].items(): + source = safe_relative(root, identity.get("path"), f"component_license_identity:{identifier}") + add(f"{QT_LICENSE_DIR}/{identifier}.txt", source, "qt", "license", False, + identity.get("sha256")) + add(QT_INVENTORY_STAGED, root / contract["license_evidence"]["qt"]["component_inventory"], + "qt", "evidence", False, inventory_sha256) conpty_manifest_path = root / "third_party" / "conpty" / "manifest.json" conpty_manifest = read_json(conpty_manifest_path) @@ -338,6 +426,7 @@ def add(path: str, source: Path, component: str, role: str, from_build: bool, runtime_manifest.get("notice_sha256")) add(NOTICES_PATH, root / CONTRACT_PATH, "termforge", "documentation", False) + add(QT_NOTICES_PATH, root / CONTRACT_PATH, "qt", "documentation", False) return expected @@ -401,24 +490,49 @@ def verify_build(bin_dir: Path, expected: dict, contract: dict, system_root: Pat return observed_os -def bundled_texts(root: Path, contract: dict) -> list[dict]: - """Declared Qt license texts with their pinned source identity.""" - qt_manifest = read_json(root / "third_party" / "qt" / "manifest.json") - available = qt_manifest.get("license", {}).get("bundled_text_files") or [] - bundled = [] - for target in contract["license_evidence"]["qt"]["bundled_texts"]: - matches = [entry for entry in available - if isinstance(entry, dict) and Path(str(entry.get("path", ""))).name == Path(target).name] - if len(matches) != 1: - raise StagingError("qt_license_manifest") - entry = matches[0] - bundled.append({"component": "qt", "path": target, - "source": f"third_party/qt/{entry['path']}", - "sha256": entry["sha256"], "spdx": entry.get("spdx")}) - return bundled - - -def notices_text(contract: dict, source: dict, summary: dict, observed_os: list[dict]) -> bytes: +def qt_component_notices(inventory: dict) -> bytes: + """Generate the Qt deployed-component notice index from the committed inventory.""" + lines = [ + "Qt 6.10.3 deployed third-party components - generated evidence index", + "", + "This file lists the source components that the pinned Qt SDK SBOM package graph", + "connects to the deployed Qt binaries, with their attribution and bundled license", + "texts. It is not a legal review or a redistribution clearance. Canonical license", + "texts are under licenses/qt/; the machine-readable inventory is", + "licenses/qt/components.json.", + "", + "Deployed Qt files: " + ", ".join(sorted(inventory["deployed_files"])), + "", + ] + for identifier, record in sorted(inventory["components"].items()): + attribution = record["attribution"] + lines.append(f"- {record['name']} {record['version']} [{identifier}]") + lines.append(f" license: {record['license_expression']}") + lines.append(f" deployed in: {', '.join(record['deployed_files'])}") + lines.append(f" attribution: {attribution['member']} entry {attribution['entry_index']}" + f" sha256 {attribution['sha256']}") + for license_file in attribution["license_files"]: + lines.append(f" upstream license file: {license_file['member']} sha256 {license_file['sha256']}") + if attribution.get("copyright"): + for line in attribution["copyright"].splitlines(): + lines.append(f" copyright: {line}") + lines.append(" bundled license texts: " + + ", ".join(f"{QT_LICENSE_DIR}/{item}.txt" for item in record["license_ids"])) + lines.append("") + lines.append("Recorded as not established for the deployed binaries:") + for record in sorted(inventory.get("excluded_attributions", []), key=lambda item: item["id"] or ""): + lines.append(f"- {record.get('name')} [{record.get('id')}]: {record.get('category')}") + for record in sorted(inventory.get("declared_not_deployed", []), key=lambda item: item["id"] or ""): + lines.append(f"- {record.get('name')} [{record.get('id')}]: {record.get('category')}") + lines.append("") + lines.append("Corresponding-source delivery, replacement conditions and a clean-machine") + lines.append("run remain pending user review.") + lines.append("") + return "\n".join(lines).encode("utf-8") + + +def notices_text(contract: dict, source: dict, summary: dict, observed_os: list[dict], + inventory: dict) -> bytes: qt = summary.get("qt_version", "unknown") conpty = summary.get("conpty_version", "unknown") runtime = (summary.get("msvc_runtime") or {}).get("version", "unknown") @@ -429,8 +543,10 @@ def notices_text(contract: dict, source: dict, summary: dict, observed_os: list[ "engineering staging. It is not a legal review or a redistribution clearance.", "", f"TermForge original code: MIT; bundled at LICENSE (source commit {source['commit']}).", - f"Qt {qt}: dynamic-link LGPL-3.0-only option; bundled license text at", - " licenses/LGPL-3.0-only.txt; full Qt third-party inventory is pending.", + f"Qt {qt}: dynamic-link LGPL-3.0-only option; component inventory and notices at", + f" {QT_INVENTORY_STAGED} and {QT_NOTICES_PATH}; canonical Qt license texts under", + f" {QT_LICENSE_DIR}/. {len(inventory['components'])} deployed third-party components", + " are traced from the pinned SDK SBOM and source attributions.", f"Microsoft Windows Console ConPTY {conpty}: MIT; bundled at conpty-backend/LICENSE.", f"Microsoft Visual C++ v14 Runtime {runtime}: bundled with its original license", " and NOTICE at LICENSE-MICROSOFT-VC-REDIST.docx and NOTICE.txt.", @@ -440,8 +556,8 @@ def notices_text(contract: dict, source: dict, summary: dict, observed_os: list[ + ", ".join(entry["name"] for entry in contract["os_provided"]) + ".", "Deliberately not deployed because they are neither pinned nor linked by this", " entry: " + ", ".join(entry["name"] for entry in contract["excluded_system_redistributables"]) + ".", - "Redistribution clearance: pending user review (Qt/third-party deployed file", - " inventory, corresponding-source conditions and clean-machine run).", + "Redistribution clearance: pending user review (corresponding-source conditions,", + " replacement relinking conditions and a clean-machine run).", "", ] return "\n".join(lines).encode("utf-8") @@ -449,19 +565,20 @@ def notices_text(contract: dict, source: dict, summary: dict, observed_os: list[ def product_manifest(root: Path, contract: dict, source: dict, build: dict, summary: dict, expected: dict, observed_os: list[dict], tool_sha256: str, - contract_sha256: str, bundled: list[dict]) -> dict: + contract_sha256: str, inventory: dict, inventory_sha256: str) -> dict: files = {} for path, spec in sorted(expected.items()): - if path == MANIFEST_PATH: - continue - if path == NOTICES_PATH: + if path in (MANIFEST_PATH, NOTICES_PATH, QT_NOTICES_PATH): continue data = spec["source"].read_bytes() files[path] = {"bytes": len(data), "sha256": sha256_bytes(data), "component": spec["component"], "role": spec["role"]} - notices = notices_text(contract, source, summary, observed_os) + notices = notices_text(contract, source, summary, observed_os, inventory) files[NOTICES_PATH] = {"bytes": len(notices), "sha256": sha256_bytes(notices), "component": "termforge", "role": "documentation"} + qt_notices = qt_component_notices(inventory) + files[QT_NOTICES_PATH] = {"bytes": len(qt_notices), "sha256": sha256_bytes(qt_notices), + "component": "qt", "role": "documentation"} def manifest_sha(relative: str) -> str: return sha256_path(root / relative) @@ -493,6 +610,18 @@ def manifest_sha(relative: str) -> str: "prepared_sdk": summary.get("sdk"), "license_manifest": "third_party/qt/manifest.json", "license_manifest_sha256": manifest_sha("third_party/qt/manifest.json"), + "component_inventory": { + "path": "third_party/qt/components.json", + "sha256": inventory_sha256, + "sbom_sha256": inventory.get("sbom", {}).get("sha256"), + "deployed_files": len(inventory["deployed_files"]), + "third_party_components": len(inventory["components"]), + "excluded_attributions": len(inventory.get("excluded_attributions", [])), + "declared_not_deployed": len(inventory.get("declared_not_deployed", [])), + "review_status": inventory.get("review_status"), + "staged_copy": QT_INVENTORY_STAGED, + "notices": QT_NOTICES_PATH, + }, }, "conpty": { "version": summary.get("conpty_version"), @@ -525,11 +654,18 @@ def manifest_sha(relative: str) -> str: "termforge": {"spdx": "MIT", "bundled_paths": ["LICENSE"], "sha256": files["LICENSE"]["sha256"], "scope": "original TermForge code and documentation"}, - "qt": {"selected_option": "LGPL-3.0-only (dynamic link)", - "bundled_paths": [item["path"] for item in bundled], - "bundled_sha256": {item["path"]: item["sha256"] for item in bundled}, - "evidence_manifest": "third_party/qt/manifest.json", - "status": "third_party_component_inventory_pending"}, + "qt": { + "selected_option": "LGPL-3.0-only (dynamic link)", + "bundled_paths": sorted(f"{QT_LICENSE_DIR}/{identifier}.txt" + for identifier in inventory["license_texts"]), + "component_inventory": QT_INVENTORY_STAGED, + "third_party_notices": QT_NOTICES_PATH, + "evidence_manifest": "third_party/qt/components.json", + "sbom_sha256": inventory.get("sbom", {}).get("sha256"), + "deployed_files": len(inventory["deployed_files"]), + "third_party_components": len(inventory["components"]), + "status": inventory.get("review_status"), + }, "conpty": {"spdx": "MIT", "bundled_paths": ["conpty-backend/LICENSE"], "evidence_manifest": "conpty-backend/manifest.json", "status": "bundled"}, "msvc_runtime": {"bundled_paths": ["LICENSE-MICROSOFT-VC-REDIST.docx", "NOTICE.txt"], @@ -540,7 +676,7 @@ def manifest_sha(relative: str) -> str: }, "redistribution_clearance": { "status": "pending_user_review", - "reason": "The Qt third-party deployed-file inventory, corresponding-source and replacement conditions, and a clean-machine run are not closed. This staging is an engineering candidate, not a redistribution clearance.", + "reason": "The Qt deployed-component inventory and canonical license texts are prepared, but corresponding-source/replacement conditions, a clean-machine run and user review are not closed. This staging is an engineering candidate, not a redistribution clearance.", }, "claims": contract["claims"], "files": dict(sorted(files.items())), @@ -552,7 +688,8 @@ def manifest_sha(relative: str) -> str: "limitations": [ "No clean Windows machine extraction/run has been performed for this staging.", "Single-screen 96/144 DPI, IME, resize/history and reliability acceptance are outside this build-preparation slice.", - "Qt's deployed third-party component licenses, corresponding-source conditions and clean-machine runtime completeness remain open.", + "Qt's deployed-component provenance and license texts are recorded, but corresponding-source/replacement conditions and clean-machine runtime completeness remain open.", + "The pinned SBOM's per-file SHA-1 values do not match the archived SDK binaries; byte identity is bound by the pinned archive/SDK tree identity instead.", "icuuc.dll is provided by the Windows 11 system and is not bundled; this staging is not validated on other Windows versions.", "No tag, release or published binary is created by this tool.", ], @@ -616,22 +753,26 @@ def stage(source_root: Path, bin_dir: Path, dependencies: Path, dependency_summa raise StagingError("build_directory") contract = load_contract(source_root) summary = verify_dependency_summary(source_root, dependencies, dependency_summary) + inventory, inventory_sha256 = load_component_inventory(source_root, dependencies, contract) source = source_identity(source_root, allow_dirty) build = build_configuration(bin_dir) - expected = expected_files(source_root, dependencies, contract, bin_dir) - bundled = bundled_texts(source_root, contract) + expected = expected_files(source_root, dependencies, contract, bin_dir, + inventory, inventory_sha256) system = Path(system_root or os.environ.get("SystemRoot", r"C:\Windows")) observed_os = verify_build(bin_dir, expected, contract, system) out.parent.mkdir(parents=True, exist_ok=True) - notices = notices_text(contract, source, summary, observed_os) + notices = notices_text(contract, source, summary, observed_os, inventory) + qt_notices = qt_component_notices(inventory) with tempfile.TemporaryDirectory(prefix="qt-product-", dir=out.parent) as temporary: staging = Path(temporary) / "product" staging.mkdir() for path, spec in sorted(expected.items()): if path == NOTICES_PATH: data = notices + elif path == QT_NOTICES_PATH: + data = qt_notices else: data = spec["source"].read_bytes() if spec["pinned_sha256"] is not None and sha256_bytes(data) != spec["pinned_sha256"]: @@ -641,7 +782,8 @@ def stage(source_root: Path, bin_dir: Path, dependencies: Path, dependency_summa target.write_bytes(data) manifest = product_manifest(source_root, contract, source, build, summary, expected, observed_os, sha256_path(Path(__file__).resolve()), - sha256_path(source_root / CONTRACT_PATH), bundled) + sha256_path(source_root / CONTRACT_PATH), + inventory, inventory_sha256) manifest_bytes = (json.dumps(manifest, ensure_ascii=False, indent=2) + "\n").encode("utf-8") (staging / MANIFEST_PATH).write_bytes(manifest_bytes) identity = tree_identity(staging) @@ -650,6 +792,8 @@ def stage(source_root: Path, bin_dir: Path, dependencies: Path, dependency_summa "source": {key: source[key] for key in ("commit", "tree", "dirty", "development_override")}, "product": {"entry_executable": ENTRY, "files": len(manifest["files"]), "distribution_state": "engineering_candidate_not_released"}, + "qt_components": len(inventory["components"]), + "qt_license_texts": len(inventory["license_texts"]), "os_provided": [entry["name"] for entry in observed_os], "claims": contract["claims"], "scope": "Engineering product staging only; no release, clean-machine acceptance or R2 acceptance."} diff --git a/tools/test_build_qt_component_inventory.py b/tools/test_build_qt_component_inventory.py new file mode 100644 index 0000000..77db18a --- /dev/null +++ b/tools/test_build_qt_component_inventory.py @@ -0,0 +1,296 @@ +"""Offline contract tests for the deployed Qt component/license inventory builder.""" +from __future__ import annotations + +import argparse +import hashlib +import io +import json +from pathlib import Path +import tarfile +import tempfile +import unittest +from unittest.mock import patch + +if __package__: + from . import build_qt_component_inventory as builder +else: + import build_qt_component_inventory as builder + +PREFIX = "qtbase-everywhere-src-6.10.3/" + + +def digest(data: bytes) -> str: + return hashlib.sha256(data).hexdigest() + + +def sha1(data: bytes) -> str: + return hashlib.sha1(data).hexdigest() + + +def write_archive(path: Path, members: dict[str, bytes]) -> bytes: + with tarfile.open(path, "w:xz") as archive: + for name, data in sorted(members.items()): + info = tarfile.TarInfo(name) + info.size = len(data) + archive.addfile(info, io.BytesIO(data)) + return path.read_bytes() + + +def attribution(member: str, entry: dict, data: bytes) -> bytes: + return (json.dumps(entry, indent=2) + "\n").encode("utf-8") + + +class Fixture: + def __init__(self, case: unittest.TestCase): + temporary = tempfile.TemporaryDirectory(prefix="termforge qt inventory fixture ") + case.addCleanup(temporary.cleanup) + self.base = Path(temporary.name) + self.root = self.base / "repo" + self.sdk = self.base / "sdk" + for directory in ("third_party/qt/LICENSES", "packaging/qt-product"): + (self.root / directory).mkdir(parents=True, exist_ok=True) + (self.sdk / "bin").mkdir(parents=True) + (self.sdk / "plugins/platforms").mkdir(parents=True) + (self.sdk / "bin/Qt6Core.dll").write_bytes(b"core fixture binary") + (self.sdk / "plugins/platforms/qwindows.dll").write_bytes(b"windows plugin fixture") + + self.license_texts = { + "Zlib": b"Zlib fixture license text\n", + "MIT": b"MIT fixture license text\n", + "LGPL-3.0-only": b"LGPL fixture license text\n", + } + self.members = {} + for identifier, data in self.license_texts.items(): + self.members[PREFIX + f"LICENSES/{identifier}.txt"] = data + self.members[PREFIX + "src/3rdparty/zlib/LICENSE"] = b"upstream zlib license text\n" + self.members[PREFIX + "src/3rdparty/zlib/qt_attribution.json"] = attribution("zlib", { + "Id": "zlib", "Name": "Data Compression Library (zlib)", "Version": "1.3.2", + "QtUsage": "Used in Qt Core.", "Homepage": "https://zlib.net/", + "License": "zlib License", "LicenseId": "Zlib", "LicenseFile": "LICENSE", + "Copyright": "(C) 1995-2026 Jean-loup Gailly and Mark Adler", + }, b"") + self.members[PREFIX + "cmake/3rdparty/toolmod/qt_attribution.json"] = attribution("toolmod", { + "Id": "toolmod", "Name": "Build Tool Module", "Version": "5.0.0", + "QtUsage": "Used as part of the build system.", "QtParts": ["tools"], + "License": "MIT License", "LicenseId": "MIT", "LicenseFile": "LICENSE", + "Copyright": "Copyright fixture tool authors", + }, b"") + self.members[PREFIX + "cmake/3rdparty/toolmod/LICENSE"] = b"tool module license\n" + self.members[PREFIX + "src/3rdparty/unused/qt_attribution.json"] = attribution("unused", { + "Id": "unused-module", "Name": "Unused Module", "License": "MIT License", + "LicenseId": "MIT", "Copyright": "Copyright unused", + }, b"") + self.members[PREFIX + "src/3rdparty/sourceonly/qt_attribution.json"] = attribution("sourceonly", { + "Id": "source-only", "Name": "Source Only Declaration", "License": "MIT License", + "LicenseId": "MIT", "Copyright": "Copyright source only", + }, b"") + self.archive_path = self.base / "qtbase.tar.xz" + self.archive_bytes = write_archive(self.archive_path, self.members) + + self.sbom = { + "spdxVersion": "SPDX-2.3", + "creationInfo": {"created": "2026-01-01T00:00:00Z"}, + "packages": [ + {"SPDXID": "SPDXRef-Package-core", "name": "Core"}, + {"SPDXID": "SPDXRef-Package-platform", "name": "Platform"}, + {"SPDXID": "SPDXRef-Package-win", "name": "QWindowsIntegrationPlugin"}, + {"SPDXID": "SPDXRef-Package-zlib", "name": "BundledZLIB", + "versionInfo": "1.3.2", "downloadLocation": "https://zlib.example/zlib-1.3.2.tar.gz", + "licenseConcluded": "Zlib", + "comment": ("\nCMake target name: BundledZLIB\n Information extracted from:\n" + " /src_dir/qtbase/src/3rdparty/zlib/qt_attribution.json\n" + " Entry index: 0\n Id: zlib\n")}, + {"SPDXID": "SPDXRef-Package-toolmod", "name": "Platform_Attribution_toolmod", + "versionInfo": "5.0.0", "downloadLocation": "https://example.invalid/toolmod", + "licenseConcluded": "MIT", + "comment": ("\nCMake target name: Platform_Attribution_toolmod\n" + " Information extracted from:\n" + " /src_dir/qtbase/cmake/3rdparty/toolmod/qt_attribution.json\n" + " Entry index: 0\n Id: toolmod\n")}, + {"SPDXID": "SPDXRef-Package-unused", "name": "Unused_Attribution_unused-module", + "downloadLocation": "https://example.invalid/unused", "licenseConcluded": "MIT", + "comment": ("\n Information extracted from:\n" + " /src_dir/qtbase/src/3rdparty/unused/qt_attribution.json\n" + " Entry index: 0\n Id: unused-module\n")}, + ], + "files": [ + {"SPDXID": "SPDXRef-File-core", "fileName": "./bin/Qt6Core.dll", + "checksums": [{"algorithm": "SHA1", "checksumValue": "0" * 40}]}, + {"SPDXID": "SPDXRef-File-win", "fileName": "./plugins/platforms/qwindows.dll", + "checksums": [{"algorithm": "SHA1", "checksumValue": "0" * 40}]}, + ], + "relationships": [ + {"spdxElementId": "SPDXRef-Package-core", "relatedSpdxElement": "SPDXRef-File-core", + "relationshipType": "CONTAINS"}, + {"spdxElementId": "SPDXRef-Package-win", "relatedSpdxElement": "SPDXRef-File-win", + "relationshipType": "CONTAINS"}, + {"spdxElementId": "SPDXRef-Package-core", "relatedSpdxElement": "SPDXRef-Package-zlib", + "relationshipType": "DEPENDS_ON"}, + {"spdxElementId": "SPDXRef-Package-core", "relatedSpdxElement": "SPDXRef-Package-platform", + "relationshipType": "DEPENDS_ON"}, + {"spdxElementId": "SPDXRef-Package-platform", + "relatedSpdxElement": "SPDXRef-Package-toolmod", "relationshipType": "DEPENDS_ON"}, + ], + } + self.sbom_path = self.base / "qtbase.spdx.json" + self.write_sbom() + + self.contract = {"qt_deployed": {"libraries": ["Qt6Core.dll"], + "plugins": ["platforms/qwindows.dll"]}} + (self.root / "packaging/qt-product/manifest.json").write_text( + json.dumps(self.contract, indent=2) + "\n", encoding="utf-8") + self.qt_manifest = { + "version": "6.10.3", + "source": { + "source_archive_url": "https://download.qt.io/qtbase-everywhere-src-6.10.3.tar.xz", + "source_archive_bytes": len(self.archive_bytes), + "source_archive_sha256": digest(self.archive_bytes), + }, + "license": {"evidence": {"sdk_sbom_sha256": digest(self.sbom_path.read_bytes())}}, + } + (self.root / "third_party/qt/manifest.json").write_text( + json.dumps(self.qt_manifest, indent=2) + "\n", encoding="utf-8") + self.inventory_path = self.root / "third_party/qt/components.json" + self.licenses_dir = self.root / "third_party/qt/LICENSES" + + def write_sbom(self): + self.sbom_path.write_text(json.dumps(self.sbom, indent=2) + "\n", encoding="utf-8") + + def arguments(self, command: str) -> argparse.Namespace: + return argparse.Namespace( + command=command, source_archive=self.archive_path, cache=self.base / "cache", + offline=True, sbom=self.sbom_path, sdk_dir=self.sdk, + inventory=self.inventory_path, licenses_dir=self.licenses_dir) + + def run(self, command: str): + with patch.object(builder, "ROOT", self.root): + return builder.run(self.arguments(command), command == "build") + + +class InventoryTests(unittest.TestCase): + def setUp(self): + self.fixture = Fixture(self) + + def test_build_writes_components_exclusions_and_license_texts(self): + result = self.fixture.run("build") + self.assertEqual(result["status"], "passed") + inventory = json.loads(self.fixture.inventory_path.read_text(encoding="utf-8")) + self.assertEqual(inventory["schema"], builder.SCHEMA) + self.assertEqual(inventory["deployed_files"]["Qt6Core.dll"]["module_package"], "Core") + self.assertEqual(inventory["deployed_files"]["Qt6Core.dll"]["component_ids"], ["zlib"]) + self.assertEqual(inventory["deployed_files"]["platforms/qwindows.dll"]["component_ids"], []) + self.assertEqual(list(inventory["components"]), ["zlib"]) + zlib = inventory["components"]["zlib"] + self.assertEqual(zlib["license_expression"], "Zlib") + self.assertEqual(zlib["deployed_files"], ["Qt6Core.dll"]) + self.assertTrue(zlib["attribution"]["member"].endswith("src/3rdparty/zlib/qt_attribution.json")) + self.assertEqual(zlib["attribution"]["license_files"][0]["sha256"], + digest(self.fixture.members[PREFIX + "src/3rdparty/zlib/LICENSE"])) + self.assertEqual(sorted(inventory["license_texts"]), ["LGPL-3.0-only", "Zlib"]) + self.assertEqual(inventory["license_texts"]["Zlib"]["sha256"], + digest(self.fixture.license_texts["Zlib"])) + self.assertTrue((self.fixture.licenses_dir / "Zlib.txt").is_file()) + self.assertEqual([item["category"] for item in inventory["excluded_attributions"]], + ["internal_build_platform_attribution"]) + categories = {(item["id"], item["category"]) for item in inventory["declared_not_deployed"]} + self.assertIn(("unused-module", "owning_package_not_deployed"), categories) + self.assertIn(("source-only", "source_declaration_not_in_sbom"), categories) + self.assertEqual(inventory["sbom"]["binary_file_checksums"]["matching_files"], 0) + self.assertEqual(len(inventory["sbom"]["binary_file_checksums"]["mismatched_files"]), 2) + self.assertEqual(self.fixture.run("check")["status"], "passed") + + first = self.fixture.inventory_path.read_bytes() + first_texts = {path.name: path.read_bytes() for path in self.fixture.licenses_dir.glob("*.txt")} + self.fixture.run("build") + self.assertEqual(self.fixture.inventory_path.read_bytes(), first) + self.assertEqual({path.name: path.read_bytes() + for path in self.fixture.licenses_dir.glob("*.txt")}, first_texts) + + def test_check_detects_inventory_and_license_drift(self): + self.fixture.run("build") + inventory = json.loads(self.fixture.inventory_path.read_text(encoding="utf-8")) + inventory["components"]["zlib"]["name"] = "tampered" + self.fixture.inventory_path.write_text(json.dumps(inventory, indent=2) + "\n", encoding="utf-8") + with self.assertRaises(builder.InventoryError) as raised: + self.fixture.run("check") + self.assertIn("inventory_mismatch", str(raised.exception)) + + self.fixture.run("build") + (self.fixture.licenses_dir / "Zlib.txt").write_bytes(b"tampered license\n") + with self.assertRaises(builder.InventoryError) as raised: + self.fixture.run("check") + self.assertIn("license_text_mismatch:Zlib", str(raised.exception)) + + def test_archive_and_sbom_identity_are_enforced(self): + fixture = Fixture(self) + fixture.qt_manifest["source"]["source_archive_sha256"] = "f" * 64 + (fixture.root / "third_party/qt/manifest.json").write_text( + json.dumps(fixture.qt_manifest, indent=2) + "\n", encoding="utf-8") + with self.assertRaises(builder.InventoryError) as raised: + fixture.run("build") + self.assertIn("source_archive_identity", str(raised.exception)) + + fixture = Fixture(self) + fixture.qt_manifest["license"]["evidence"]["sdk_sbom_sha256"] = "f" * 64 + (fixture.root / "third_party/qt/manifest.json").write_text( + json.dumps(fixture.qt_manifest, indent=2) + "\n", encoding="utf-8") + with self.assertRaises(builder.InventoryError) as raised: + fixture.run("build") + self.assertIn("sbom_manifest_identity", str(raised.exception)) + + def test_missing_deployed_file_or_license_text_fails_closed(self): + fixture = Fixture(self) + fixture.sbom["files"] = [entry for entry in fixture.sbom["files"] + if entry["fileName"] != "./bin/Qt6Core.dll"] + fixture.write_sbom() + fixture.qt_manifest["license"]["evidence"]["sdk_sbom_sha256"] = digest( + fixture.sbom_path.read_bytes()) + (fixture.root / "third_party/qt/manifest.json").write_text( + json.dumps(fixture.qt_manifest, indent=2) + "\n", encoding="utf-8") + with self.assertRaises(builder.InventoryError) as raised: + fixture.run("build") + self.assertIn("sbom_file:Qt6Core.dll", str(raised.exception)) + + fixture = Fixture(self) + members = dict(fixture.members) + del members[PREFIX + "LICENSES/Zlib.txt"] + fixture.members = members + fixture.archive_bytes = write_archive(fixture.archive_path, members) + fixture.qt_manifest["source"]["source_archive_bytes"] = len(fixture.archive_bytes) + fixture.qt_manifest["source"]["source_archive_sha256"] = digest(fixture.archive_bytes) + (fixture.root / "third_party/qt/manifest.json").write_text( + json.dumps(fixture.qt_manifest, indent=2) + "\n", encoding="utf-8") + with self.assertRaises(builder.InventoryError) as raised: + fixture.run("build") + self.assertIn("license_text_missing:Zlib", str(raised.exception)) + + def test_license_expression_parsing(self): + self.assertEqual(builder.license_ids("FTL OR GPL-2.0-only"), + ["FTL", "GPL-2.0-only"]) + self.assertEqual(builder.license_ids("MIT AND MIT-open-group"), + ["MIT", "MIT-open-group"]) + self.assertEqual(builder.license_ids("GPL-3.0-only WITH Qt-GPL-exception-1.0"), + ["GPL-3.0-only"]) + self.assertEqual(builder.license_ids(None), []) + + def test_sbom_checksum_comparison_records_matches(self): + fixture = Fixture(self) + for entry in fixture.sbom["files"]: + name = entry["fileName"].split("/")[-1] + local = (fixture.sdk / "bin" / name) if entry["fileName"].startswith("./bin") else ( + fixture.sdk / "plugins/platforms" / name) + entry["checksums"] = [{"algorithm": "SHA1", "checksumValue": sha1(local.read_bytes())}] + fixture.write_sbom() + fixture.qt_manifest["license"]["evidence"]["sdk_sbom_sha256"] = digest( + fixture.sbom_path.read_bytes()) + (fixture.root / "third_party/qt/manifest.json").write_text( + json.dumps(fixture.qt_manifest, indent=2) + "\n", encoding="utf-8") + fixture.run("build") + inventory = json.loads(fixture.inventory_path.read_text(encoding="utf-8")) + checks = inventory["sbom"]["binary_file_checksums"] + self.assertEqual(checks["matching_files"], 2) + self.assertEqual(checks["mismatched_files"], []) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/test_stage_qt_product.py b/tools/test_stage_qt_product.py index a80063d..cdb59d0 100644 --- a/tools/test_stage_qt_product.py +++ b/tools/test_stage_qt_product.py @@ -49,6 +49,10 @@ def git(root: Path, *arguments: str) -> str: return result.stdout.strip() +def make_deployed_names(contract: dict) -> list[str]: + return list(contract["qt_deployed"]["libraries"]) + list(contract["qt_deployed"]["plugins"]) + + class Fixture: """A synthetic repository, dependency preparation and build output.""" @@ -72,6 +76,7 @@ def __init__(self, case: unittest.TestCase): self._fonts() self._manifests() self._dependencies() + self._component_evidence() self._build_output() self._commit() @@ -169,6 +174,85 @@ def _dependencies(self): self.runtime_manifest["notice_sha256"] = digest((crt / "NOTICE.txt").read_bytes()) (self.root / "third_party/msvc_runtime/manifest.json").write_text( json.dumps(self.runtime_manifest, indent=2) + "\n", encoding="utf-8") + + def _component_evidence(self): + """Fake SBOM, license texts and inventory consistent with the contract.""" + modules = {"Qt6Core.dll": "Core", "Qt6Gui.dll": "Gui", + "Qt6Widgets.dll": "Widgets", "Qt6Network.dll": "Network"} + packages = [] + files = [] + relationships = [] + deployed_files = {} + for index, name in enumerate(make_deployed_names(self.contract)): + module = modules.get(name, "Plugin" + str(index)) + package_id = f"SPDXRef-Package-{index}" + file_id = f"SPDXRef-File-{index}" + packages.append({"SPDXID": package_id, "name": module}) + files.append({"SPDXID": file_id, + "fileName": ("./bin/" + name) if "/" not in name else ("./plugins/" + name)}) + relationships.append({"spdxElementId": package_id, "relatedSpdxElement": file_id, + "relationshipType": "CONTAINS"}) + ids = [] + if name == "Qt6Core.dll": + ids = ["zlib"] + relationships.append({"spdxElementId": package_id, + "relatedSpdxElement": "SPDXRef-Package-zlib", + "relationshipType": "DEPENDS_ON"}) + deployed_files[name] = {"module_package": module, "component_ids": ids} + packages.append({ + "SPDXID": "SPDXRef-Package-zlib", "name": "BundledZLIB", + "downloadLocation": "https://zlib.example/zlib-1.3.2.tar.gz", + "licenseConcluded": "Zlib", + "comment": ("\nCMake target name: BundledZLIB\n Information extracted from:\n" + " /src_dir/qtbase/src/3rdparty/zlib/qt_attribution.json\n" + " Entry index: 0\n Id: zlib\n"), + }) + sbom = {"spdxVersion": "SPDX-2.3", + "creationInfo": {"created": "2026-01-01T00:00:00Z"}, + "packages": packages, "files": files, "relationships": relationships} + sbom_path = self.deps / "qt/sbom/qtbase-6.10.3.spdx.json" + sbom_path.parent.mkdir(parents=True, exist_ok=True) + sbom_data = (json.dumps(sbom, indent=2) + "\n").encode("utf-8") + sbom_path.write_bytes(sbom_data) + + license_data = {} + for identifier, data in (("Zlib", b"Zlib fixture license text\n"), + ("LGPL-3.0-only", + (self.root / "third_party/qt/LICENSES/LGPL-3.0-only.txt").read_bytes())): + path = self.root / "third_party/qt/LICENSES" / f"{identifier}.txt" + path.write_bytes(data) + license_data[identifier] = { + "path": f"third_party/qt/LICENSES/{identifier}.txt", + "bytes": len(data), "sha256": digest(data)} + inventory = { + "schema": stage_qt_product.COMPONENT_SCHEMA, + "review_status": "materials_prepared_user_review_pending", + "qt_version": "6.10.3", + "source": {"sha256": None}, + "sbom": {"sha256": digest(sbom_data)}, + "deployed_files": deployed_files, + "components": { + "zlib": { + "id": "zlib", "name": "Zlib fixture", "version": "1.3.2", + "license_expression": "Zlib", "license_ids": ["Zlib"], + "deployed_files": ["Qt6Core.dll"], + "evidence": {"level": "sbom_module_dependency", "depth": 1, + "sbom_packages": ["BundledZLIB"]}, + "attribution": {"member": "fixture/src/3rdparty/zlib/qt_attribution.json", + "entry_index": 0, "bytes": 1, "sha256": "a" * 64, + "qt_usage": "fixture", "qt_parts": None, + "license_files": [], "copyright": "fixture"}, + "source": {"homepage": None, "download_location": None, "purl": None}, + } + }, + "excluded_attributions": [], + "declared_not_deployed": [], + "license_texts": license_data, + "qt_module_license": {"selected_option": "LGPL-3.0-only"}, + "unresolved": [], + } + (self.root / "third_party/qt/components.json").write_text( + json.dumps(inventory, indent=2) + "\n", encoding="utf-8") qt_manifest = json.loads((self.root / "third_party/qt/manifest.json").read_text(encoding="utf-8")) self.write_preparation_summary(qt_manifest) @@ -269,9 +353,15 @@ def test_stage_produces_a_frozen_path_free_manifest(self): self.assertFalse(manifest["source"]["dirty"]) self.assertEqual(manifest["source"]["commit"], git(self.fixture.root, "rev-parse", "HEAD")) self.assertEqual(manifest["dependencies"]["qt"]["version"], "6.10.3") - self.assertIn("licenses/LGPL-3.0-only.txt", manifest["files"]) + self.assertIn("licenses/qt/LGPL-3.0-only.txt", manifest["files"]) + self.assertIn("licenses/qt/Zlib.txt", manifest["files"]) + self.assertIn("licenses/qt/components.json", manifest["files"]) + self.assertIn("QT-THIRD-PARTY-NOTICES.txt", manifest["files"]) self.assertIn("THIRD-PARTY-NOTICES.txt", manifest["files"]) self.assertIn("conpty-backend/LICENSE", manifest["files"]) + self.assertEqual(manifest["dependencies"]["qt"]["component_inventory"]["third_party_components"], 1) + self.assertEqual(manifest["licenses"]["qt"]["status"], + "materials_prepared_user_review_pending") self.assertEqual(manifest["test_fixtures"]["included"], []) self.assertEqual(manifest["os_provided"][0]["name"], "icuuc.dll") self.assertTrue(manifest["os_provided"][0]["present_in_build"]) @@ -285,6 +375,10 @@ def test_stage_produces_a_frozen_path_free_manifest(self): notices = (out / "THIRD-PARTY-NOTICES.txt").read_text(encoding="utf-8") self.assertIn("pending user review", notices) self.assertIn("D3Dcompiler_47.dll", notices) + self.assertIn("traced from the pinned SDK SBOM", notices) + qt_notices = (out / "QT-THIRD-PARTY-NOTICES.txt").read_text(encoding="utf-8") + self.assertIn("Zlib fixture", qt_notices) + self.assertIn("licenses/qt/Zlib.txt", qt_notices) staged = {path.relative_to(out).as_posix() for path in out.rglob("*") if path.is_file()} self.assertEqual(staged, set(manifest["files"]) | {"product-manifest.json"}) self.assertNotIn(str(self.fixture.root), json.dumps(manifest)) @@ -326,6 +420,36 @@ def test_missing_entry_and_test_fixture_are_rejected(self): (self.fixture.bin / "termforge_qt_shell.exe").unlink() self.assert_failure("missing_product_file:termforge_qt_shell.exe") + def test_component_inventory_and_license_evidence_fail_closed(self): + with self.subTest("missing canonical license text"): + fixture = Fixture(self) + (fixture.root / "third_party/qt/LICENSES/Zlib.txt").unlink() + with self.assertRaises(stage_qt_product.StagingError) as raised: + fixture.stage() + self.assertIn("component_license_identity:Zlib", str(raised.exception)) + with self.subTest("tampered canonical license text"): + fixture = Fixture(self) + target = fixture.root / "third_party/qt/LICENSES/Zlib.txt" + target.write_bytes(target.read_bytes() + b"tampered") + with self.assertRaises(stage_qt_product.StagingError) as raised: + fixture.stage(allow_dirty=True) + self.assertIn("component_license_identity:Zlib", str(raised.exception)) + with self.subTest("inventory disagrees with the SBOM"): + fixture = Fixture(self) + inventory_path = fixture.root / "third_party/qt/components.json" + inventory = json.loads(inventory_path.read_text(encoding="utf-8")) + inventory["deployed_files"]["Qt6Core.dll"]["component_ids"] = [] + inventory_path.write_text(json.dumps(inventory, indent=2) + "\n", encoding="utf-8") + with self.assertRaises(stage_qt_product.StagingError) as raised: + fixture.stage() + self.assertIn("component_inventory_sbom_mismatch", str(raised.exception)) + with self.subTest("contract points at a missing inventory"): + fixture = Fixture(self) + (fixture.root / "third_party/qt/components.json").unlink() + with self.assertRaises(stage_qt_product.StagingError) as raised: + fixture.stage() + self.assertIn("component_inventory_contract", str(raised.exception)) + def test_extra_test_executable_is_rejected_by_name(self): (self.fixture.bin / "qt_cpp_shell_smoke.exe").write_bytes(pe_fixture("exe")) self.assert_failure("test_fixture_in_product:qt_cpp_shell_smoke.exe") @@ -407,7 +531,7 @@ def test_pinned_font_and_license_text_tampering_fails(self): (second.root / "third_party/qt/LICENSES/LGPL-3.0-only.txt").write_bytes(b"tampered license\n") with self.assertRaises(stage_qt_product.StagingError) as raised: second.stage(allow_dirty=True) - self.assertIn("qt_license_identity", str(raised.exception)) + self.assertIn("component_license_identity:LGPL-3.0-only", str(raised.exception)) def test_pe_identity_rejects_wrong_architectures(self): with self.assertRaises(stage_qt_product.StagingError): @@ -453,3 +577,4 @@ def test_cli_verify_reports_a_path_free_failure(self): if __name__ == "__main__": unittest.main() +