summaryrefslogtreecommitdiffstats
path: root/parameter/IntegerParameterType.cpp
diff options
context:
space:
mode:
authorFrederic Boisnard <fredericx.boisnard@intel.com>2012-03-21 14:47:00 +0100
committerDavid Wagner <david.wagner@intel.com>2014-02-12 17:03:10 +0100
commit8b01852701d50869318663f568270f977d93dbdf (patch)
treeb26462e5ae9e3b7cb10a9ed0511da6c2a7e6cd75 /parameter/IntegerParameterType.cpp
parent170f0a44b8309a954cd4802e85ac3dd6944a35fa (diff)
downloadexternal_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.cpp45
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();