Skip to content

Poco::strToInt<> fails for values right above the type's boundary / limit #2250

@Montellese

Description

@Montellese

Expected behavior

uint8_t value_u8;
assertTrue(Poco::strToInt<uint8_t>("255", value_u8, 10));
assertTrue(value_u8 == 255);
assertFalse(Poco::strToInt<uint8_t>("256", value_u8, 10));
assertFalse(Poco::strToInt<uint8_t>("257", value_u8, 10));
assertFalse(Poco::strToInt<uint8_t>("258", value_u8, 10));
assertFalse(Poco::strToInt<uint8_t>("259", value_u8, 10);
assertFalse(Poco::strToInt<uint8_t>("260", value_u8, 10));

uint16_t value_u16;
assertTrue(Poco::strToInt<uint16_t >("65535", value_u16, 10));
assertTrue(value_u16 == 65535);
assertFalse(Poco::strToInt<uint16_t >("65536", value_u16, 10));
assertFalse(Poco::strToInt<uint16_t >("65537", value_u16, 10));
assertFalse(Poco::strToInt<uint16_t >("65538", value_u16, 10));
assertFalse(Poco::strToInt<uint16_t >("65539", value_u16, 10);
assertFalse(Poco::strToInt<uint16_t >("65530", value_u16, 10));

Actual behavior

uint8_t value_u8;
assertTrue(Poco::strToInt<uint8_t>("255", value_u8, 10));
assertTrue(value_u8 == 255);
assertTrue(Poco::strToInt<uint8_t>("256", value_u8, 10));
assertTrue(value_u8 == 0);
assertTrue(Poco::strToInt<uint8_t>("257", value_u8, 10));
assertTrue(value_u8 == 1);
assertTrue(Poco::strToInt<uint8_t>("258", value_u8, 10));
assertTrue(value_u8 == 2);
assertTrue(Poco::strToInt<uint8_t>("259", value_u8, 10));
assertTrue(value_u8 == 3);
assertFalse(Poco::strToInt<uint8_t>("260", value_u8, 10));

uint16_t value_u16;
assertTrue(Poco::strToInt<uint16_t >("65535", value_u16, 10));
assertTrue(value_u16 == 65535);
assertTrue(Poco::strToInt<uint16_t >("65536", value_u16, 10));
assertTrue(value_u16 == 0);
assertTrue(Poco::strToInt<uint16_t >("65537", value_u16, 10));
assertTrue(value_u16 == 1);
assertTrue(Poco::strToInt<uint16_t >("65538", value_u16, 10));
assertTrue(value_u16 == 2);
assertTrue(Poco::strToInt<uint16_t >("65539", value_u16, 10);
assertTrue(value_u16 == 3);
assertFalse(Poco::strToInt<uint16_t >("65530", value_u16, 10));

It looks like the logic in

I limitCheck = std::numeric_limits<I>::max() / base;
falsifies all boundary / limit checks within the base range containing the actual limit. The unit tests of the Poco::NumberParser (which uses Poco::strToInt<>()) only check the lower and upper limit but not beyond those limits and therefore don't check the invalid case.

Steps to reproduce the problem

see above

POCO version

libpoco-dev 1.3.6p1-5.1build1

Compiler and version

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609

Operating system and version

Ubuntu 16.04
Kernel 4.13.0-36-generic

Other relevant information

none

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions