mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-20 04:24:36 +08:00
project: Fix potential buffer write-past-end for version components
This fixes two errors: not accounting for the trailing null and a misunderstanding of what std::numeric_limits::digits10 means.
This commit is contained in:
@@ -224,7 +224,8 @@ bool cmProjectCommand(std::vector<std::string> const& args,
|
|||||||
std::array<std::string, MAX_VERSION_COMPONENTS> version_components;
|
std::array<std::string, MAX_VERSION_COMPONENTS> version_components;
|
||||||
|
|
||||||
if (cmp0096 == cmPolicies::OLD || cmp0096 == cmPolicies::WARN) {
|
if (cmp0096 == cmPolicies::OLD || cmp0096 == cmPolicies::WARN) {
|
||||||
char vb[MAX_VERSION_COMPONENTS][std::numeric_limits<unsigned>::digits10];
|
char vb[MAX_VERSION_COMPONENTS]
|
||||||
|
[std::numeric_limits<unsigned>::digits10 + 2];
|
||||||
unsigned v[MAX_VERSION_COMPONENTS] = { 0, 0, 0, 0 };
|
unsigned v[MAX_VERSION_COMPONENTS] = { 0, 0, 0, 0 };
|
||||||
const int vc = std::sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1],
|
const int vc = std::sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1],
|
||||||
&v[2], &v[3]);
|
&v[2], &v[3]);
|
||||||
|
@@ -22,6 +22,7 @@ run_cmake(VersionInvalid)
|
|||||||
run_cmake(VersionMissingLanguages)
|
run_cmake(VersionMissingLanguages)
|
||||||
run_cmake(VersionMissingValueOkay)
|
run_cmake(VersionMissingValueOkay)
|
||||||
run_cmake(VersionTwice)
|
run_cmake(VersionTwice)
|
||||||
|
run_cmake(VersionMax)
|
||||||
|
|
||||||
run_cmake(CMP0048-OLD)
|
run_cmake(CMP0048-OLD)
|
||||||
run_cmake(CMP0048-OLD-VERSION)
|
run_cmake(CMP0048-OLD-VERSION)
|
||||||
|
32
Tests/RunCMake/project/VersionMax.cmake
Normal file
32
Tests/RunCMake/project/VersionMax.cmake
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
cmake_policy(SET CMP0048 NEW)
|
||||||
|
cmake_policy(SET CMP0096 OLD)
|
||||||
|
|
||||||
|
enable_language(C)
|
||||||
|
include(CheckTypeSize)
|
||||||
|
check_type_size(unsigned __sizeOfUnsigned BUILTIN_TYPES_ONLY LANGUAGE C)
|
||||||
|
|
||||||
|
# We can't use math() to compute this because it only supports up to
|
||||||
|
# 64-bit signed integers, so hard-code the types we expect to encounter
|
||||||
|
if(__sizeOfUnsigned EQUAL 0)
|
||||||
|
message(STATUS "Multi-architecture build, skipping project version check")
|
||||||
|
return()
|
||||||
|
elseif(__sizeOfUnsigned EQUAL 4)
|
||||||
|
set(maxVal 4294967295)
|
||||||
|
elseif(__sizeOfUnsigned EQUAL 8)
|
||||||
|
set(maxVal 18446744073709551615)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Test needs to be updated for unsigned integer size ${__sizeOfUnsigned}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# The real value of this test is when an address sanitizer is enabled.
|
||||||
|
# It catches situations where the size of the buffer used to compute or
|
||||||
|
# hold the version components as strings is too small.
|
||||||
|
project(ProjectA VERSION ${maxVal}.${maxVal}.${maxVal}.${maxVal} LANGUAGES NONE)
|
||||||
|
|
||||||
|
if(NOT ${PROJECT_VERSION_MAJOR} EQUAL ${maxVal})
|
||||||
|
message(FATAL_ERROR "Project version number parsing failed round trip.\n"
|
||||||
|
"Expected: ${maxVal}\n"
|
||||||
|
"Computed: ${PROJECT_VERSION_MAJOR}"
|
||||||
|
)
|
||||||
|
endif()
|
Reference in New Issue
Block a user