From 05604eb9cb7ced290af67dcc392f0a9a10e64386 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Apr 2012 10:32:46 -0400 Subject: list: Handle errors on empty lists more gracefully (#13138) Since commit ed1ea24c (Fix INSERT to allow inserting to empty list, 2006-05-15) the list command allows insertion into an empty list at index 0. Fix rejection of insertion at non-zero (negative) indices to present an error message instead of crashing. While at it, fix the error message of the GET and REMOVE_AT operations when the list is empty to not present a bogus allowed range. Add a "RunCMake.list" test to cover failure cases on empty lists. --- Source/cmListCommand.cxx | 15 ++++++++++++++- Tests/RunCMake/CMakeLists.txt | 1 + Tests/RunCMake/list/CMakeLists.txt | 3 +++ Tests/RunCMake/list/EmptyGet0-result.txt | 1 + Tests/RunCMake/list/EmptyGet0-stderr.txt | 4 ++++ Tests/RunCMake/list/EmptyGet0.cmake | 2 ++ Tests/RunCMake/list/EmptyInsert-1-result.txt | 1 + Tests/RunCMake/list/EmptyInsert-1-stderr.txt | 4 ++++ Tests/RunCMake/list/EmptyInsert-1.cmake | 2 ++ Tests/RunCMake/list/EmptyRemoveAt0-result.txt | 1 + Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt | 4 ++++ Tests/RunCMake/list/EmptyRemoveAt0.cmake | 2 ++ Tests/RunCMake/list/RunCMakeTest.cmake | 5 +++++ 13 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/list/CMakeLists.txt create mode 100644 Tests/RunCMake/list/EmptyGet0-result.txt create mode 100644 Tests/RunCMake/list/EmptyGet0-stderr.txt create mode 100644 Tests/RunCMake/list/EmptyGet0.cmake create mode 100644 Tests/RunCMake/list/EmptyInsert-1-result.txt create mode 100644 Tests/RunCMake/list/EmptyInsert-1-stderr.txt create mode 100644 Tests/RunCMake/list/EmptyInsert-1.cmake create mode 100644 Tests/RunCMake/list/EmptyRemoveAt0-result.txt create mode 100644 Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt create mode 100644 Tests/RunCMake/list/EmptyRemoveAt0.cmake create mode 100644 Tests/RunCMake/list/RunCMakeTest.cmake diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index cbbcbb0..908f3b0 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -204,6 +204,12 @@ bool cmListCommand::HandleGetCommand(std::vector const& args) this->Makefile->AddDefinition(variableName.c_str(), "NOTFOUND"); return true; } + // FIXME: Add policy to make non-existing lists an error like empty lists. + if(varArgsExpanded.empty()) + { + this->SetError("GET given empty list"); + return false; + } std::string value; size_t cc; @@ -318,7 +324,8 @@ bool cmListCommand::HandleInsertCommand(std::vector const& args) // expand the variable int item = atoi(args[2].c_str()); std::vector varArgsExpanded; - if ( !this->GetList(varArgsExpanded, listName.c_str()) && item != 0) + if((!this->GetList(varArgsExpanded, listName.c_str()) + || varArgsExpanded.empty()) && item != 0) { cmOStringStream str; str << "index: " << item << " out of range (0, 0)"; @@ -544,6 +551,12 @@ bool cmListCommand::HandleRemoveAtCommand( this->SetError("sub-command REMOVE_AT requires list to be present."); return false; } + // FIXME: Add policy to make non-existing lists an error like empty lists. + if(varArgsExpanded.empty()) + { + this->SetError("REMOVE_AT given empty list"); + return false; + } size_t cc; std::vector removed; diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 0b79efa..865a409 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -44,3 +44,4 @@ add_RunCMake_test(ObjectLibrary) add_RunCMake_test(build_command) add_RunCMake_test(find_package) +add_RunCMake_test(list) diff --git a/Tests/RunCMake/list/CMakeLists.txt b/Tests/RunCMake/list/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/list/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/list/EmptyGet0-result.txt b/Tests/RunCMake/list/EmptyGet0-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/EmptyGet0-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/EmptyGet0-stderr.txt b/Tests/RunCMake/list/EmptyGet0-stderr.txt new file mode 100644 index 0000000..0c61b01 --- /dev/null +++ b/Tests/RunCMake/list/EmptyGet0-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at EmptyGet0.cmake:2 \(list\): + list GET given empty list +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/EmptyGet0.cmake b/Tests/RunCMake/list/EmptyGet0.cmake new file mode 100644 index 0000000..4947108 --- /dev/null +++ b/Tests/RunCMake/list/EmptyGet0.cmake @@ -0,0 +1,2 @@ +set(mylist "") +list(GET mylist 0 result) diff --git a/Tests/RunCMake/list/EmptyInsert-1-result.txt b/Tests/RunCMake/list/EmptyInsert-1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/EmptyInsert-1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/EmptyInsert-1-stderr.txt b/Tests/RunCMake/list/EmptyInsert-1-stderr.txt new file mode 100644 index 0000000..0900ff9 --- /dev/null +++ b/Tests/RunCMake/list/EmptyInsert-1-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at EmptyInsert-1.cmake:2 \(list\): + list index: -1 out of range \(0, 0\) +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/EmptyInsert-1.cmake b/Tests/RunCMake/list/EmptyInsert-1.cmake new file mode 100644 index 0000000..140da5d --- /dev/null +++ b/Tests/RunCMake/list/EmptyInsert-1.cmake @@ -0,0 +1,2 @@ +set(mylist "") +list(INSERT mylist -1 x) diff --git a/Tests/RunCMake/list/EmptyRemoveAt0-result.txt b/Tests/RunCMake/list/EmptyRemoveAt0-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/EmptyRemoveAt0-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt b/Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt new file mode 100644 index 0000000..b24a0ed --- /dev/null +++ b/Tests/RunCMake/list/EmptyRemoveAt0-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at EmptyRemoveAt0.cmake:2 \(list\): + list REMOVE_AT given empty list +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/EmptyRemoveAt0.cmake b/Tests/RunCMake/list/EmptyRemoveAt0.cmake new file mode 100644 index 0000000..d6a3e85 --- /dev/null +++ b/Tests/RunCMake/list/EmptyRemoveAt0.cmake @@ -0,0 +1,2 @@ +set(mylist "") +list(REMOVE_AT mylist 0) diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake new file mode 100644 index 0000000..555051d --- /dev/null +++ b/Tests/RunCMake/list/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(EmptyGet0) +run_cmake(EmptyRemoveAt0) +run_cmake(EmptyInsert-1) -- cgit v0.12