View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001532 | OpenFOAM | Bug | public | 2015-02-16 13:56 | 2015-02-18 18:21 |
Reporter | Assigned To | henry | |||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Platform | Linux | OS | SUSE Linux Enterprise Server | OS Version | 11.2 |
Summary | 0001532: readInt does not check for overflow | ||||
Description | readInt(const char*, int&) does not check for overflow nor in strtol(), nor while converting long to int. As a result, the resulting int value and the return bool value can be silently wrong. | ||||
Steps To Reproduce | Compile and run the following program: #include "fvCFD.H" int main(int argc, char *argv[]) { std::string s("12345678901234"); int a; bool res = readInt(s.c_str(), a); Info << a << " " << res <<endl; IStringStream str("12345678901234"); scalar x = readScalar(str); Info << x << endl; return 0; } It outputs -1 1 1.94289e+09 while it should output something like -1 0 1.23457e+13 The difference is the return (bool) value of readInt and the return value of readScalar. | ||||
Additional Information | I have ran into this problem in the following way. I have one OpenFOAM code that generates some dictionary, and another OpenFOAM code that reads this dictionary. Among others, there is a scalar value in this dictionary, that in one of my tests was equal to about 3.4e11. I have writePrecision 12 in my controlDict, so that scalar value was printed just like 340853124000 --- no decimal dot, no "e" sign. When I was reading it back, the ISstream::read(token& t) sees that there are only digits in the token, so it tries to call readLabel. The latter returns true despite the fact that the value overflows. A diff for a fix is attached. | ||||
Tags | No tags attached. | ||||
2015-02-16 13:56
|
readInt.diff (713 bytes)
diff --git a/src/OpenFOAM/primitives/ints/int/intIO.C b/src/OpenFOAM/primitives/ints/int/intIO.C index bd02519..74243d4 100644 --- a/src/OpenFOAM/primitives/ints/int/intIO.C +++ b/src/OpenFOAM/primitives/ints/int/intIO.C @@ -35,6 +35,7 @@ Description #include "IOstreams.H" #include <sstream> +#include <cerrno> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -91,9 +92,10 @@ int Foam::readInt(Istream& is) bool Foam::readInt(const char* buf, int& s) { char *endptr = NULL; + errno = 0; long l = strtol(buf, &endptr, 10); s = int(l); - return (*endptr == 0); + return (*endptr == 0) && (errno == 0) && (l >= INT_MIN) && (l <= INT_MAX); } |
|
Thanks for the report and fix. Resolved by commit 57407a029c02d290fc6fcce39e0db99c6fc50ac5 |
2015-02-18 17:41
|
|
|
The cast from long to int32_t in intIO.C can still overflow. Attached a small case that demonstrates it. Run icoFoam and check 0.005/U - the uniformFixedValue table will be incorrect. |
|
Would you like the patch removed? |
|
No, the patch is ok but only checks the result of strtol. In addition before you do the s = int32_t(l); you should first check for l<INT32_MIN or l>INT32_MAX (unless there is a better way of detecting overflow) |
|
This assumes that int32 != long int but it might. For int64 should we use strtol or strtoll? long int strtol(const char *nptr, char **endptr, int base); long long int strtoll(const char *nptr, char **endptr, int base); how do we know the correspondence between these functions and the int32 and int64 types? Another option would be to use strtoimax, what do you think? |
|
Didn't know about strtoimax. Looks a better fit. |
|
OK, I will make this change. I am assuming that intmax_t is not larger than int64_t and hence no need to test against INT64_MIN/MAX. |
Date Modified | Username | Field | Change |
---|---|---|---|
2015-02-16 13:56 |
|
New Issue | |
2015-02-16 13:56 |
|
File Added: readInt.diff | |
2015-02-16 22:03 | henry | Note Added: 0003806 | |
2015-02-16 22:03 | henry | Status | new => resolved |
2015-02-16 22:03 | henry | Resolution | open => fixed |
2015-02-16 22:03 | henry | Assigned To | => henry |
2015-02-18 17:41 |
|
File Added: cavity.tgz | |
2015-02-18 17:44 |
|
Note Added: 0003831 | |
2015-02-18 17:48 | henry | Note Added: 0003832 | |
2015-02-18 17:56 |
|
Note Added: 0003833 | |
2015-02-18 18:08 | henry | Note Added: 0003834 | |
2015-02-18 18:12 |
|
Note Added: 0003835 | |
2015-02-18 18:21 | henry | Note Added: 0003836 |