diff options
author | Frederic Boisnard <fredericx.boisnard@intel.com> | 2012-03-21 14:47:00 +0100 |
---|---|---|
committer | David Wagner <david.wagner@intel.com> | 2014-02-12 17:03:10 +0100 |
commit | 8b01852701d50869318663f568270f977d93dbdf (patch) | |
tree | b26462e5ae9e3b7cb10a9ed0511da6c2a7e6cd75 /parameter/IntegerParameterType.cpp | |
parent | 170f0a44b8309a954cd4802e85ac3dd6944a35fa (diff) | |
download | external_parameter-framework-8b01852701d50869318663f568270f977d93dbdf.zip external_parameter-framework-8b01852701d50869318663f568270f977d93dbdf.tar.gz external_parameter-framework-8b01852701d50869318663f568270f977d93dbdf.tar.bz2 |
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 <fredericx.boisnard@intel.com>
Reviewed-on: http://android.intel.com:8080/55443
Reviewed-by: Mendi, EduardoX <eduardox.mendi@intel.com>
Tested-by: Mendi, EduardoX <eduardox.mendi@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
Diffstat (limited to 'parameter/IntegerParameterType.cpp')
-rw-r--r-- | parameter/IntegerParameterType.cpp | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/parameter/IntegerParameterType.cpp b/parameter/IntegerParameterType.cpp index fb55f08..80d2c90 100644 --- a/parameter/IntegerParameterType.cpp +++ b/parameter/IntegerParameterType.cpp @@ -35,6 +35,7 @@ #include "ParameterAccessContext.h" #include <assert.h> #include "ParameterAdaptation.h" +#include <errno.h> #define base CParameterType @@ -147,45 +148,55 @@ bool CIntegerParameterType::toBlackboard(const string& strValue, uint32_t& uiVal bool bValueProvidedAsHexa = !strValue.compare(0, 2, "0x"); // Get value - int32_t iData; + int64_t iData; + // Reset errno to check if it is updated during the conversion (strtol/strtoul) + errno = 0; + char *pcStrEnd; + + // Convert the input string if (_bSigned) { - iData = strtoul(strValue.c_str(), NULL, 0); + iData = strtoll(strValue.c_str(), &pcStrEnd, 0); } else { - iData = strtol(strValue.c_str(), NULL, 0); + iData = strtoull(strValue.c_str(), &pcStrEnd, 0); } - if (bValueProvidedAsHexa && isEncodable(iData)) { - // Sign extend - signExtend(iData); - } + // Conversion error when the input string does not contain any digit or the number is out of range (int32_t type) + bool bConversionSucceeded = !errno && (strValue.c_str() != pcStrEnd); + // Check against Min / Max if (_bSigned) { - if (!checkValueAgainstRange<int32_t>(strValue, iData, parameterAccessContext, bValueProvidedAsHexa)) { + if (bConversionSucceeded && bValueProvidedAsHexa && isEncodable((uint64_t)iData, !bValueProvidedAsHexa)) { + + // Sign extend + signExtend(iData); + } + + if (!checkValueAgainstRange<int64_t>(strValue, iData, (int32_t)_uiMin, (int32_t)_uiMax, parameterAccessContext, bValueProvidedAsHexa, bConversionSucceeded)) { return false; } } else { - if (!checkValueAgainstRange<uint32_t>(strValue, iData, parameterAccessContext, bValueProvidedAsHexa)) { + if (!checkValueAgainstRange<uint64_t>(strValue, iData, _uiMin, _uiMax, parameterAccessContext, bValueProvidedAsHexa, bConversionSucceeded)) { return false; } } - uiValue = iData; + uiValue = (uint32_t)iData; return true; } bool CIntegerParameterType::fromBlackboard(string& strValue, const uint32_t& uiValue, CParameterAccessContext& parameterAccessContext) const { - // Check consistency - assert(isEncodable(uiValue)); + // Check unsigned value is encodable + assert(isEncodable(uiValue, false)); // Format ostringstream strStream; @@ -371,9 +382,9 @@ uint32_t CIntegerParameterType::getDefaultValue() const } // Range checking -template <typename type> bool CIntegerParameterType::checkValueAgainstRange(const string& strValue, type value, CParameterAccessContext& parameterAccessContext, bool bHexaValue) const +template <typename type> bool CIntegerParameterType::checkValueAgainstRange(const string& strValue, type value, type minValue, type maxValue, CParameterAccessContext& parameterAccessContext, bool bHexaValue, bool bConversionSucceeded) const { - if ((type)value < (type)_uiMin || (type)value > (type)_uiMax) { + if (!bConversionSucceeded || value < minValue || value > maxValue) { ostringstream strStream; @@ -382,13 +393,13 @@ template <typename type> bool CIntegerParameterType::checkValueAgainstRange(cons if (bHexaValue) { // Format Min - strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(_uiMin); + strStream << "0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(minValue); // Format Max - strStream << ", 0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(_uiMax); + strStream << ", 0x" << hex << uppercase << setw(getSize()*2) << setfill('0') << makeEncodable(maxValue); } else { - strStream << (type)_uiMin << ", " << (type)_uiMax; + strStream << minValue << ", " << maxValue; } strStream << "] for " << getKind(); |