From b558d014078372de4dd1252dbbb1e252294e1b69 Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Mon, 17 Aug 2026 13:00:04 -0700 Subject: [PATCH] Fix SPDX generation with older CMake (#53440) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- scripts/cmake/z_vcpkg_spdx.cmake | 42 ++++++++++++++++-- .../test_ports/unit-test-cmake/portfile.cmake | 3 ++ .../unit-test-cmake/test-z_vcpkg_spdx.cmake | 44 +++++++++++++++++++ scripts/test_ports/unit-test-cmake/vcpkg.json | 6 ++- 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 scripts/test_ports/unit-test-cmake/test-z_vcpkg_spdx.cmake diff --git a/scripts/cmake/z_vcpkg_spdx.cmake b/scripts/cmake/z_vcpkg_spdx.cmake index 60e9e0e919..5a2b71abd2 100644 --- a/scripts/cmake/z_vcpkg_spdx.cmake +++ b/scripts/cmake/z_vcpkg_spdx.cmake @@ -1,3 +1,39 @@ +function(z_vcpkg_spdx_json_string_encode_compat out_var value) + set(encoded "${value}") + string(REPLACE "\\" "\\\\" encoded "${encoded}") # that is, replace \ with \\ + string(REPLACE "\"" "\\\"" encoded "${encoded}") # that is, replace " with \" + string(ASCII 8 backspace) + string(ASCII 12 form_feed) + string(REPLACE "${backspace}" "\\b" encoded "${encoded}") + string(REPLACE "${form_feed}" "\\f" encoded "${encoded}") + string(REPLACE "\n" "\\n" encoded "${encoded}") + string(REPLACE "\r" "\\r" encoded "${encoded}") + string(REPLACE "\t" "\\t" encoded "${encoded}") + + foreach(code RANGE 1 31) + string(ASCII "${code}" character) + math(EXPR hexadecimal "${code}" OUTPUT_FORMAT HEXADECIMAL) + string(SUBSTRING "${hexadecimal}" 2 -1 hexadecimal) + if(code LESS 16) + set(escape "\\u000${hexadecimal}") + else() + set(escape "\\u00${hexadecimal}") + endif() + string(REPLACE "${character}" "${escape}" encoded "${encoded}") + endforeach() + + set("${out_var}" "\"${encoded}\"" PARENT_SCOPE) +endfunction() + +function(z_vcpkg_spdx_json_string_encode out_var value) + if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3") + string(JSON encoded STRING_ENCODE "${value}") + else() + z_vcpkg_spdx_json_string_encode_compat(encoded "${value}") + endif() + set("${out_var}" "${encoded}" PARENT_SCOPE) +endfunction() + function(z_vcpkg_add_spdx_resource) cmake_parse_arguments(PARSE_ARGV 0 "arg" "" @@ -12,13 +48,13 @@ function(z_vcpkg_add_spdx_resource) set(resource "{}") string(JSON resource SET "${resource}" "SPDXID" "\"SPDXRef-resource-${resource_index}\"") - string(JSON value STRING_ENCODE "${arg_NAME}") + z_vcpkg_spdx_json_string_encode(value "${arg_NAME}") string(JSON resource SET "${resource}" "name" "${value}") if(DEFINED arg_FILENAME) - string(JSON value STRING_ENCODE "${arg_FILENAME}") + z_vcpkg_spdx_json_string_encode(value "${arg_FILENAME}") string(JSON resource SET "${resource}" "packageFileName" "${value}") endif() - string(JSON value STRING_ENCODE "${arg_DOWNLOAD_LOCATION}") + z_vcpkg_spdx_json_string_encode(value "${arg_DOWNLOAD_LOCATION}") string(JSON resource SET "${resource}" "downloadLocation" "${value}") foreach(property IN ITEMS licenseConcluded licenseDeclared copyrightText) string(JSON resource SET "${resource}" "${property}" [["NOASSERTION"]]) diff --git a/scripts/test_ports/unit-test-cmake/portfile.cmake b/scripts/test_ports/unit-test-cmake/portfile.cmake index 7898154242..2107497e69 100644 --- a/scripts/test_ports/unit-test-cmake/portfile.cmake +++ b/scripts/test_ports/unit-test-cmake/portfile.cmake @@ -27,6 +27,9 @@ endif() if("setup-pkgconfig-path" IN_LIST FEATURES) include("${CMAKE_CURRENT_LIST_DIR}/test-z_vcpkg_setup_pkgconfig_path.cmake") endif() +if("spdx" IN_LIST FEATURES) + include("${CMAKE_CURRENT_LIST_DIR}/test-z_vcpkg_spdx.cmake") +endif() if("fixup-pkgconfig" IN_LIST FEATURES) include("${CMAKE_CURRENT_LIST_DIR}/test-vcpkg_fixup_pkgconfig.cmake") endif() diff --git a/scripts/test_ports/unit-test-cmake/test-z_vcpkg_spdx.cmake b/scripts/test_ports/unit-test-cmake/test-z_vcpkg_spdx.cmake new file mode 100644 index 0000000000..1665bafaa0 --- /dev/null +++ b/scripts/test_ports/unit-test-cmake/test-z_vcpkg_spdx.cmake @@ -0,0 +1,44 @@ +string(ASCII 1 control_character) +string(ASCII 8 backspace) +string(ASCII 12 form_feed) +set(expected_name "name; with \"quotes\", \\slashes\\, /solidus, ${backspace}backspace, ${form_feed}form feed,\nnewlines,\rcarriage returns,\ttabs, and ${control_character}controls") +set(expected_filename "archive;\"name\".tar.gz") +set(expected_download_location "https://example.com/a;b?query=\"value\"") + +set(expected_encoded_name [["name; with \"quotes\", \\slashes\\, /solidus, \bbackspace, \fform feed,\nnewlines,\rcarriage returns,\ttabs, and \u0001controls"]]) +foreach(encoder IN ITEMS z_vcpkg_spdx_json_string_encode z_vcpkg_spdx_json_string_encode_compat) + cmake_language(CALL "${encoder}" encoded_name "${expected_name}") + if(NOT encoded_name STREQUAL expected_encoded_name) + message(SEND_ERROR "${encoder} does not match string(JSON STRING_ENCODE): + expected: ${expected_encoded_name} + actual : ${encoded_name}") + set_has_error() + endif() +endforeach() + +set_property(GLOBAL PROPERTY Z_VCPKG_SPDX_OBJECTS "") +z_vcpkg_add_spdx_resource( + NAME "${expected_name}" + FILENAME "${expected_filename}" + DOWNLOAD_LOCATION "${expected_download_location}" +) + +get_property(resources GLOBAL PROPERTY Z_VCPKG_SPDX_OBJECTS) +vcpkg_list(GET resources 0 resource) +foreach(property IN ITEMS name packageFileName downloadLocation) + string(JSON actual_value GET "${resource}" "${property}") + if(property STREQUAL "name") + set(expected_value "${expected_name}") + elseif(property STREQUAL "packageFileName") + set(expected_value "${expected_filename}") + else() + set(expected_value "${expected_download_location}") + endif() + + if(NOT actual_value STREQUAL expected_value) + message(SEND_ERROR "SPDX ${property} was encoded incorrectly: + expected: \"${expected_value}\" + actual : \"${actual_value}\"") + set_has_error() + endif() +endforeach() diff --git a/scripts/test_ports/unit-test-cmake/vcpkg.json b/scripts/test_ports/unit-test-cmake/vcpkg.json index e981be1006..4ad726434b 100644 --- a/scripts/test_ports/unit-test-cmake/vcpkg.json +++ b/scripts/test_ports/unit-test-cmake/vcpkg.json @@ -17,7 +17,8 @@ "list", "merge-libs", "minimum-required", - "setup-pkgconfig-path" + "setup-pkgconfig-path", + "spdx" ], "features": { "backup-restore-env-vars": { @@ -56,6 +57,9 @@ }, "setup-pkgconfig-path": { "description": "Test the z_vcpkg_setup/restore_pkgconfig_path functions" + }, + "spdx": { + "description": "Test SPDX resource generation" } } }