Check for NULL constraint and raise exception if found.

User is not allowed to provide a NULL constraint to the various ARG
constructors. This patch makes sure the Constraint is not NULL before
dereferencing and raises a logic_error if it is NULL.

Also included the two new tests test88 and test89 in runtests script.
This commit is contained in:
Daniel Aarno 2015-05-11 22:47:42 +02:00
parent e2ed6cfbc4
commit 4970b7e793
8 changed files with 59 additions and 6 deletions

View File

@ -2,7 +2,7 @@
noinst_PROGRAMS = test1 test2 test3 test4 test5 test6 test7 test8 test9 \
test10 test11 test12 test13 test14 test15 test16 \
test17 test18 test19 test20 test21 test22 test23 test24 \
test25 test26 test27
test25 test26 test27 test28
test1_SOURCES = test1.cpp
test2_SOURCES = test2.cpp
@ -31,6 +31,7 @@ test24_SOURCES = test24.cpp
test25_SOURCES = test25.cpp
test26_SOURCES = test26.cpp
test27_SOURCES = test27.cpp
test28_SOURCES = test28.cpp
AM_CPPFLAGS = -I$(top_srcdir)/include

35
examples/test28.cpp Normal file
View File

@ -0,0 +1,35 @@
#include <iostream>
#include "tclap/CmdLine.h"
using namespace TCLAP;
using namespace std;
int main()
{
try {
CmdLine cmd("test constraint bug");
ValueArg<int> arg("i","int", "tests int arg", false, 4711, NULL, cmd);
cout << "Expected exception" << endl;
} catch(std::logic_error &e) { /* expected */ }
try {
CmdLine cmd("test constraint bug");
ValueArg<int> arg1("i","int", "tests int arg", false, 4711, NULL, NULL);
cout << "Expected exception" << endl;
} catch(std::logic_error &e) { /* expected */ }
try {
CmdLine cmd("test constraint bug");
MultiArg<int> arg1("i","int", "tests int arg", false, NULL, NULL);
cout << "Expected exception" << endl;
} catch(std::logic_error &e) { /* expected */ }
try {
CmdLine cmd("test constraint bug");
MultiArg<int> arg1("i","int", "tests int arg", false, NULL, cmd);
cout << "Expected exception" << endl;
} catch(std::logic_error &e) { /* expected */ }
cout << "Passed" << endl;
}

View File

@ -28,6 +28,7 @@
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <stdexcept>
namespace TCLAP {
@ -62,6 +63,12 @@ class Constraint
* functions but without a virtual destructor.
*/
virtual ~Constraint() { ; }
static std::string shortID(Constraint<T> *constraint) {
if (!constraint)
throw std::logic_error("Cannot create a ValueArg with a NULL constraint");
return constraint->shortID();
}
};
} //namespace TCLAP

View File

@ -276,7 +276,7 @@ MultiArg<T>::MultiArg(const std::string& flag,
Visitor* v)
: Arg( flag, name, desc, req, true, v ),
_values(std::vector<T>()),
_typeDesc( constraint->shortID() ),
_typeDesc( Constraint<T>::shortID(constraint) ),
_constraint( constraint ),
_allowMore(false)
{
@ -293,7 +293,7 @@ MultiArg<T>::MultiArg(const std::string& flag,
Visitor* v)
: Arg( flag, name, desc, req, true, v ),
_values(std::vector<T>()),
_typeDesc( constraint->shortID() ),
_typeDesc( Constraint<T>::shortID(constraint) ),
_constraint( constraint ),
_allowMore(false)
{

View File

@ -302,7 +302,7 @@ ValueArg<T>::ValueArg(const std::string& flag,
: Arg(flag, name, desc, req, true, v),
_value( val ),
_default( val ),
_typeDesc( constraint->shortID() ),
_typeDesc( Constraint<T>::shortID(constraint) ),
_constraint( constraint )
{ }
@ -318,7 +318,7 @@ ValueArg<T>::ValueArg(const std::string& flag,
: Arg(flag, name, desc, req, true, v),
_value( val ),
_default( val ),
_typeDesc( constraint->shortID() ), // TODO(macbishop): Will crash
_typeDesc( Constraint<T>::shortID(constraint) ), // TODO(macbishop): Will crash
// if constraint is NULL
_constraint( constraint )
{

View File

@ -6,7 +6,7 @@ cd $DIR
let "suc = 0"
let "fail = 0"
NUMTEST=87
NUMTEST=89
for (( tno = 1 ; $tno <= $NUMTEST ; tno = $tno + 1 )); do
./testCheck.sh $tno

1
tests/test89.out Normal file
View File

@ -0,0 +1 @@
Passed

9
tests/test89.sh Normal file
View File

@ -0,0 +1,9 @@
#!/bin/bash
../examples/test28 > tmp.out 2>&1
if cmp -s tmp.out $srcdir/test89.out; then
exit 0
else
exit 1
fi