Skip to content

Commit b984972

Browse files
committed
utils.h: reject preceding non-digits in strToInt()
1 parent b5ea328 commit b984972

2 files changed

Lines changed: 42 additions & 32 deletions

File tree

lib/utils.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr)
220220
tmp = std::stoll(str, &idx);
221221
if (idx != str.size()) {
222222
if (err)
223-
*err = "not an integer";
223+
*err = "not an integer (pos)";
224224
return false;
225225
}
226226
} catch (const std::out_of_range&) {
@@ -229,14 +229,19 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr)
229229
return false;
230230
} catch (const std::invalid_argument &) {
231231
if (err)
232-
*err = "not an integer";
232+
*err = "not an integer (invalid_argument)";
233233
return false;
234234
}
235235
if (str.front() == '-' && std::numeric_limits<T>::min() == 0) {
236236
if (err)
237237
*err = "needs to be positive";
238238
return false;
239239
}
240+
if (str.front() != '+' && str.front() != '-' && !isdigit(str.front())) {
241+
if (err)
242+
*err = "not an integer";
243+
return false;
244+
}
240245
if (tmp < std::numeric_limits<T>::min() || tmp > std::numeric_limits<T>::max()) {
241246
if (err)
242247
*err = "out of range (limits)";
@@ -255,7 +260,7 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr)
255260
tmp = std::stoull(str, &idx);
256261
if (idx != str.size()) {
257262
if (err)
258-
*err = "not an integer";
263+
*err = "not an integer (pos)";
259264
return false;
260265
}
261266
} catch (const std::out_of_range&) {
@@ -264,14 +269,19 @@ bool strToInt(const std::string& str, T &num, std::string* err = nullptr)
264269
return false;
265270
} catch (const std::invalid_argument &) {
266271
if (err)
267-
*err = "not an integer";
272+
*err = "not an integer (invalid_argument)";
268273
return false;
269274
}
270275
if (str.front() == '-') {
271276
if (err)
272277
*err = "needs to be positive";
273278
return false;
274279
}
280+
if (str.front() != '+' && !isdigit(str.front())) {
281+
if (err)
282+
*err = "not an integer";
283+
return false;
284+
}
275285
if (tmp > std::numeric_limits<T>::max()) {
276286
if (err)
277287
*err = "out of range (limits)";

test/testutils.cpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -232,34 +232,34 @@ class TestUtils : public TestFixture {
232232
ASSERT_EQUALS(0, ::strToInt<int>("-0"));
233233
ASSERT_EQUALS(0, ::strToInt<std::size_t>("0"));
234234
ASSERT_EQUALS(0, ::strToInt<std::size_t>("+0"));
235-
ASSERT_THROW_EQUALS(::strToInt<int>(""), std::runtime_error, "converting '' to integer failed - not an integer");
236-
ASSERT_THROW_EQUALS(::strToInt<std::size_t>(""), std::runtime_error, "converting '' to integer failed - not an integer");
237-
ASSERT_THROW_EQUALS(::strToInt<int>(" "), std::runtime_error, "converting ' ' to integer failed - not an integer");
238-
ASSERT_THROW_EQUALS(::strToInt<std::size_t>(" "), std::runtime_error, "converting ' ' to integer failed - not an integer");
235+
ASSERT_THROW_EQUALS(::strToInt<int>(""), std::runtime_error, "converting '' to integer failed - not an integer (invalid_argument)");
236+
ASSERT_THROW_EQUALS(::strToInt<std::size_t>(""), std::runtime_error, "converting '' to integer failed - not an integer (invalid_argument)");
237+
ASSERT_THROW_EQUALS(::strToInt<int>(" "), std::runtime_error, "converting ' ' to integer failed - not an integer (invalid_argument)");
238+
ASSERT_THROW_EQUALS(::strToInt<std::size_t>(" "), std::runtime_error, "converting ' ' to integer failed - not an integer (invalid_argument)");
239239
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("-1"), std::runtime_error, "converting '-1' to integer failed - needs to be positive");
240240
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("-0"), std::runtime_error, "converting '-0' to integer failed - needs to be positive");
241241
ASSERT_THROW_EQUALS(::strToInt<std::size_t>("-1"), std::runtime_error, "converting '-1' to integer failed - needs to be positive");
242242
ASSERT_THROW_EQUALS(::strToInt<std::size_t>("-0"), std::runtime_error, "converting '-0' to integer failed - needs to be positive");
243-
ASSERT_THROW_EQUALS(::strToInt<int>("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer");
244-
ASSERT_THROW_EQUALS(::strToInt<int>("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer");
245-
ASSERT_THROW_EQUALS(::strToInt<int>("+1.0"), std::runtime_error, "converting '+1.0' to integer failed - not an integer");
246-
ASSERT_THROW_EQUALS(::strToInt<int>("-1.0"), std::runtime_error, "converting '-1.0' to integer failed - not an integer");
247-
ASSERT_THROW_EQUALS(::strToInt<int>("one"), std::runtime_error, "converting 'one' to integer failed - not an integer");
248-
//ASSERT_THROW_EQUALS(::strToInt<int>(" 1"), std::runtime_error, "converting ' 1' to integer failed - not an integer"); // TODO: should fail
249-
//ASSERT_THROW_EQUALS(::strToInt<int>("\t1"), std::runtime_error, "converting '\t1' to integer failed - not an integer"); // TODO should fail
250-
ASSERT_THROW_EQUALS(::strToInt<int>("1 "), std::runtime_error, "converting '1 ' to integer failed - not an integer");
251-
ASSERT_THROW_EQUALS(::strToInt<int>("1\t"), std::runtime_error, "converting '1\t' to integer failed - not an integer");
252-
ASSERT_THROW_EQUALS(::strToInt<int>("+ 1"), std::runtime_error, "converting '+ 1' to integer failed - not an integer");
253-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer");
254-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer");
255-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("+1.0"), std::runtime_error, "converting '+1.0' to integer failed - not an integer");
256-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("-1.0"), std::runtime_error, "converting '-1.0' to integer failed - not an integer");
257-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("one"), std::runtime_error, "converting 'one' to integer failed - not an integer");
258-
//ASSERT_THROW_EQUALS(::strToInt<unsigned int>(" 1"), std::runtime_error, "converting ' 1' to integer failed - not an integer"); // TODO: should fail
259-
//ASSERT_THROW_EQUALS(::strToInt<unsigned int>("\t1"), std::runtime_error, "converting '\t1' to integer failed - not an integer"); // TODO: should fail
260-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1 "), std::runtime_error, "converting '1 ' to integer failed - not an integer");
261-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1\t"), std::runtime_error, "converting '1\t' to integer failed - not an integer");
262-
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("- 1"), std::runtime_error, "converting '- 1' to integer failed - not an integer");
243+
ASSERT_THROW_EQUALS(::strToInt<int>("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer (pos)");
244+
ASSERT_THROW_EQUALS(::strToInt<int>("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer (pos)");
245+
ASSERT_THROW_EQUALS(::strToInt<int>("+1.0"), std::runtime_error, "converting '+1.0' to integer failed - not an integer (pos)");
246+
ASSERT_THROW_EQUALS(::strToInt<int>("-1.0"), std::runtime_error, "converting '-1.0' to integer failed - not an integer (pos)");
247+
ASSERT_THROW_EQUALS(::strToInt<int>("one"), std::runtime_error, "converting 'one' to integer failed - not an integer (invalid_argument)");
248+
ASSERT_THROW_EQUALS(::strToInt<int>(" 1"), std::runtime_error, "converting ' 1' to integer failed - not an integer");
249+
ASSERT_THROW_EQUALS(::strToInt<int>("\t1"), std::runtime_error, "converting '\t1' to integer failed - not an integer");
250+
ASSERT_THROW_EQUALS(::strToInt<int>("1 "), std::runtime_error, "converting '1 ' to integer failed - not an integer (pos)");
251+
ASSERT_THROW_EQUALS(::strToInt<int>("1\t"), std::runtime_error, "converting '1\t' to integer failed - not an integer (pos)");
252+
ASSERT_THROW_EQUALS(::strToInt<int>("+ 1"), std::runtime_error, "converting '+ 1' to integer failed - not an integer (invalid_argument)");
253+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1ms"), std::runtime_error, "converting '1ms' to integer failed - not an integer (pos)");
254+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1.0"), std::runtime_error, "converting '1.0' to integer failed - not an integer (pos)");
255+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("+1.0"), std::runtime_error, "converting '+1.0' to integer failed - not an integer (pos)");
256+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("-1.0"), std::runtime_error, "converting '-1.0' to integer failed - not an integer (pos)");
257+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("one"), std::runtime_error, "converting 'one' to integer failed - not an integer (invalid_argument)");
258+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>(" 1"), std::runtime_error, "converting ' 1' to integer failed - not an integer");
259+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("\t1"), std::runtime_error, "converting '\t1' to integer failed - not an integer");
260+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1 "), std::runtime_error, "converting '1 ' to integer failed - not an integer (pos)");
261+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("1\t"), std::runtime_error, "converting '1\t' to integer failed - not an integer (pos)");
262+
ASSERT_THROW_EQUALS(::strToInt<unsigned int>("- 1"), std::runtime_error, "converting '- 1' to integer failed - not an integer (invalid_argument)");
263263
ASSERT_THROW_EQUALS(::strToInt<int>(std::to_string(static_cast<int64_t>(std::numeric_limits<int>::max()) + 1)), std::runtime_error, "converting '2147483648' to integer failed - out of range (limits)");
264264
ASSERT_THROW_EQUALS(::strToInt<int>(std::to_string(static_cast<int64_t>(std::numeric_limits<int>::min()) - 1)), std::runtime_error, "converting '-2147483649' to integer failed - out of range (limits)");
265265
ASSERT_THROW_EQUALS(::strToInt<int8_t>(std::to_string(static_cast<int64_t>(std::numeric_limits<int8_t>::max()) + 1)), std::runtime_error, "converting '128' to integer failed - out of range (limits)");
@@ -335,25 +335,25 @@ class TestUtils : public TestFixture {
335335
long tmp;
336336
std::string err;
337337
ASSERT(!::strToInt("1ms", tmp, &err));
338-
ASSERT_EQUALS("not an integer", err);
338+
ASSERT_EQUALS("not an integer (pos)", err);
339339
}
340340
{
341341
long tmp;
342342
std::string err;
343343
ASSERT(!::strToInt("1.0", tmp, &err));
344-
ASSERT_EQUALS("not an integer", err);
344+
ASSERT_EQUALS("not an integer (pos)", err);
345345
}
346346
{
347347
long tmp;
348348
std::string err;
349349
ASSERT(!::strToInt("one", tmp, &err));
350-
ASSERT_EQUALS("not an integer", err);
350+
ASSERT_EQUALS("not an integer (invalid_argument)", err);
351351
}
352352
{
353353
std::size_t tmp;
354354
std::string err;
355355
ASSERT(!::strToInt("1ms", tmp, &err));
356-
ASSERT_EQUALS("not an integer", err);
356+
ASSERT_EQUALS("not an integer (pos)", err);
357357
}
358358
{
359359
long tmp;

0 commit comments

Comments
 (0)