From 8b01852701d50869318663f568270f977d93dbdf Mon Sep 17 00:00:00 2001 From: Frederic Boisnard Date: Wed, 21 Mar 2012 14:47:00 +0100 Subject: PFW: overflow not detected for int parameters BZ: 26285 The following errors were not detected by the PFW when setting parameters of type (U)INT8, (U)INT16, (U)INT32: - When setting a value out of the int32 range (ex: 999999999999999), the strtol/strtoul functions return the value -1 which was then assumed correct by the PFW. Now the errno value is checked to ensure that no range error was encountered by strtol/strtoul. - When the input string does not contain any digits, the strtol/strtoul functions return 0 which was assumed correct by the PFW. Now the endptr argument is checked to make sure that at least a part of the string was parsed. In any case an error message is displayed and the original value is not updated. Made the change compliant to 64-bit OSes. Applied the same corrections to Enum and FixedPoint types. Change-Id: I135538def791208a6eb6143444a3fc30337137e1 Orig-Change-Id: I1519dbf798228a9be579aaf612f456d5eb1b41b5 Signed-off-by: Frederic Boisnard Reviewed-on: http://android.intel.com:8080/55443 Reviewed-by: Mendi, EduardoX Tested-by: Mendi, EduardoX Reviewed-by: buildbot Tested-by: buildbot --- parameter/ParameterType.cpp | 63 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 13 deletions(-) (limited to 'parameter/ParameterType.cpp') diff --git a/parameter/ParameterType.cpp b/parameter/ParameterType.cpp index 7079a46..a271f73 100644 --- a/parameter/ParameterType.cpp +++ b/parameter/ParameterType.cpp @@ -97,7 +97,7 @@ void CParameterType::showProperties(string& strResult) const } // Scalar size - strResult += "Scalar size: " + toString(_uiSize) + " byte(s) \n"; + strResult += "Scalar size: " + toString(getSize()) + " byte(s) \n"; } // Default value handling (simulation only) @@ -118,40 +118,77 @@ CInstanceConfigurableElement* CParameterType::doInstantiate() const } } -// Sign extension +// Sign extension (32 bits) void CParameterType::signExtend(int32_t& iData) const { - uint32_t uiSizeInBits = _uiSize * 8; - uint32_t uiShift = 8 * sizeof(iData) - uiSizeInBits; + doSignExtend(iData); +} + +// Sign extension (64 bits) +void CParameterType::signExtend(int64_t& iData) const +{ + doSignExtend(iData); +} + +// Generic sign extension +template +void CParameterType::doSignExtend(type& data) const +{ + uint32_t uiSizeInBits = getSize() * 8; + uint32_t uiShift = 8 * sizeof(data) - uiSizeInBits; if (uiShift) { - iData = (iData << uiShift) >> uiShift; + data = (data << uiShift) >> uiShift; } } -// Check data has no bit set outside available range -bool CParameterType::isEncodable(uint32_t uiData) const +// Check data has no bit set outside available range (32 bits) +bool CParameterType::isEncodable(uint32_t uiData, bool bIsSigned) const { - uint32_t uiSizeInBits = _uiSize * 8; + return doIsEncodable(uiData, bIsSigned); +} - if (uiSizeInBits == 8 * sizeof(uiData)) { +// Check data has no bit set outside available range (64 bits) +bool CParameterType::isEncodable(uint64_t uiData, bool bIsSigned) const +{ + return doIsEncodable(uiData, bIsSigned); +} +// Generic encodability check +template +bool CParameterType::doIsEncodable(type data, bool bIsSigned) const +{ + if (getSize() == sizeof(data)) { + // Prevent inappropriate shifts return true; } - // Check high bits are clean - return !(uiData >> uiSizeInBits); + uint32_t uiShift = getSize() * 8; + + if (!bIsSigned) { + + // Check high bits are clean + return !(data >> uiShift); + + } else { + + // Negative value? + bool bIsValueExpectedNegative = (data & (1 << (uiShift - 1))) != 0; + + // Check high bits are clean + return bIsValueExpectedNegative ? !(~data >> uiShift) : !(data >> uiShift); + } } // Remove all bits set outside available range uint32_t CParameterType::makeEncodable(uint32_t uiData) const { - if (_uiSize == sizeof(uint32_t)) { + if (getSize() == sizeof(uint32_t)) { return uiData; } - uint32_t uiSizeInBits = _uiSize * 8; + uint32_t uiSizeInBits = getSize() * 8; uint32_t uiMask = (1 << uiSizeInBits) - 1; -- cgit v1.1