I'm trying to remediate some Coverity findings on tainted values due to the use of atoi
and atof
. I switched to an istringstream
, but its not producing expected results for bases other than 10.
If I switch to base 16, enter 0xa and avoid the iss.ignore(2);
, then the result is 0:
$ ./tt.exe 0xa
X: 0
If I switch to base 16, enter 0xa and utilize the iss.ignore(2);
, then the result is an exception:
$ ./tt.exe 0xa
'0xa' is not a value
I visited CPP Reference on istringstream as recommended by @πάντα, but it does not discuss a limitation in this context.
Any ideas what I am doing wrong? Or, how can I get this to work as expected?
$ cat tt.cxx
#include <iostream>
#include <sstream>
#include <iomanip>
#include <stdexcept>
using namespace std;
template <class T>
T StringToValue(const std::string& str) {
std::istringstream iss(str);
T value;
if (str.length() >= 2) {
if (str[0] == '0' && (str[1] =='X' || str[1] =='x'))
{
iss.setf(std::ios_base::hex);
iss.ignore(2);
}
}
iss >> value;
if (iss.fail())
throw runtime_error("'" + str +"' is not a value");
return value;
}
int main(int argc, char* argv[])
{
try
{
int x = StringToValue<int>(argc >= 2 ? argv[1] : "ZZZ...");
cout << "X: " << x << endl;
}
catch(const runtime_error& ex)
{
cerr << ex.what() << endl;
return 1;
}
return 0;
}