From 15a0b0d04660fdec8c231ec4d1054ff5f5274610 Mon Sep 17 00:00:00 2001 From: Craig Scott Date: Sat, 26 Oct 2019 16:20:14 +1100 Subject: Help: math() expressions must be representable as signed 64-bit --- Help/command/math.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Help/command/math.rst b/Help/command/math.rst index 3cbe719..ddb1ec6 100644 --- a/Help/command/math.rst +++ b/Help/command/math.rst @@ -8,7 +8,8 @@ Evaluate a mathematical expression. math(EXPR "" [OUTPUT_FORMAT ]) Evaluates a mathematical ```` and sets ```` to the -resulting value. +resulting value. The result of the expression must be representable as a +64-bit signed integer. The mathematical expression must be given as a string (i.e. enclosed in double quotation marks). An example is ``"5 * (10 + 13)"``. -- cgit v0.12 From 82cdb26c93b595e3791818cc8f24dfc6935eb8a8 Mon Sep 17 00:00:00 2001 From: Craig Scott Date: Sat, 26 Oct 2019 16:30:22 +1100 Subject: 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. --- Source/cmProjectCommand.cxx | 3 ++- Tests/RunCMake/project/RunCMakeTest.cmake | 1 + Tests/RunCMake/project/VersionMax.cmake | 32 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/project/VersionMax.cmake diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index eb59b4f..7bb5209 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -224,7 +224,8 @@ bool cmProjectCommand(std::vector const& args, std::array version_components; if (cmp0096 == cmPolicies::OLD || cmp0096 == cmPolicies::WARN) { - char vb[MAX_VERSION_COMPONENTS][std::numeric_limits::digits10]; + char vb[MAX_VERSION_COMPONENTS] + [std::numeric_limits::digits10 + 2]; 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], &v[2], &v[3]); diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake index 8f43a51..6914699 100644 --- a/Tests/RunCMake/project/RunCMakeTest.cmake +++ b/Tests/RunCMake/project/RunCMakeTest.cmake @@ -22,6 +22,7 @@ run_cmake(VersionInvalid) run_cmake(VersionMissingLanguages) run_cmake(VersionMissingValueOkay) run_cmake(VersionTwice) +run_cmake(VersionMax) run_cmake(CMP0048-OLD) run_cmake(CMP0048-OLD-VERSION) diff --git a/Tests/RunCMake/project/VersionMax.cmake b/Tests/RunCMake/project/VersionMax.cmake new file mode 100644 index 0000000..e955364 --- /dev/null +++ b/Tests/RunCMake/project/VersionMax.cmake @@ -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() -- cgit v0.12