- MMS server: more restrictive value type check when handling write access

This commit is contained in:
Michael Zillgith 2017-10-25 21:51:35 +02:00
parent 8a67fcc00b
commit 02689d1410
5 changed files with 73 additions and 2 deletions

View file

@ -91,6 +91,17 @@ MmsVariableSpecification_getNamedVariableRecursive(MmsVariableSpecification* sel
MmsType
MmsVariableSpecification_getType(MmsVariableSpecification* self);
/**
* \brief Check if the value has exactly the same type as this variable specfication
*
* \param self the MmsVariableSpecification instance
* \param value the value to check
*
* \return true if type is matching, false otherwise
*/
bool
MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, MmsValue* value);
/**
* \brief get the name of the variable
*

View file

@ -95,6 +95,64 @@ MmsVariableSpecification_getType(MmsVariableSpecification* self)
return self->type;
}
bool
MmsVariableSpecification_isValueOfType(MmsVariableSpecification* self, MmsValue* value)
{
if ((self->type) == (value->type)) {
if ((self->type == MMS_STRUCTURE) || (self->type == MMS_ARRAY)) {
int componentCount = self->typeSpec.structure.elementCount;
if (componentCount != (int) MmsValue_getArraySize(value))
return false;
if (self->type == MMS_STRUCTURE) {
int i;
for (i = 0; i < componentCount; i++) {
if (MmsVariableSpecification_isValueOfType(self->typeSpec.structure.elements[i], MmsValue_getElement(value, i)) == false)
return false;
}
return true;
}
else {
int i;
for (i = 0; i < componentCount; i++) {
if (MmsVariableSpecification_isValueOfType(self->typeSpec.array.elementTypeSpec, MmsValue_getElement(value, i)) == false)
return false;
}
}
}
else if (self->type == MMS_BIT_STRING) {
if (self->typeSpec.bitString == value->value.bitString.size)
return true;
if (self->typeSpec.bitString < 0) {
if (value->value.bitString.size <= (-self->typeSpec.bitString))
return true;
}
}
else if (self->type == MMS_FLOAT) {
if ((self->typeSpec.floatingpoint.exponentWidth == value->value.floatingPoint.exponentWidth) &&
(self->typeSpec.floatingpoint.formatWidth == value->value.floatingPoint.formatWidth))
return true;
}
else if (self->type == MMS_BINARY_TIME) {
if (self->typeSpec.binaryTime == value->value.binaryTime.size)
return true;
}
else
return true;
}
return false;
}
const char*
MmsVariableSpecification_getName(MmsVariableSpecification* self)
{

View file

@ -657,7 +657,7 @@ mmsServer_handleWriteRequest(
}
/* Check for correct type */
if (MmsValue_getType(value) != MmsVariableSpecification_getType(variable)) {
if (MmsVariableSpecification_isValueOfType(variable, value) == false) {
accessResults[i] = DATA_ACCESS_ERROR_TYPE_INCONSISTENT;
goto end_of_main_loop;
}

View file

@ -570,4 +570,5 @@ EXPORTS
IedServer_setFilestoreBasepath
IedModel_getDeviceByInst
MmsConnection_writeNamedVariableList
IedConnection_writeDataSetValues
IedConnection_writeDataSetValues
MmsVariableSpecification_isValueOfType

View file

@ -652,3 +652,4 @@ EXPORTS
SVClientASDU_hasRefrTm
SVClientASDU_getRefrTmAsMs
IedConnection_writeDataSetValues
MmsVariableSpecification_isValueOfType