- improved MmsValue handling; fixed MmsValue(OCTET-STRIG) maximum size problem (LIB61850-150)

pull/383/head
Michael Zillgith 3 years ago
parent 9d9f03585f
commit f60ff65fc4

@ -273,7 +273,7 @@ parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues)
case 0x89: /* octet string */ case 0x89: /* octet string */
if (MmsValue_getType(value) == MMS_OCTET_STRING) { if (MmsValue_getType(value) == MMS_OCTET_STRING) {
if (elementLength <= value->value.octetString.maxSize) { if (elementLength <= abs(value->value.octetString.maxSize)) {
value->value.octetString.size = elementLength; value->value.octetString.size = elementLength;
memcpy(value->value.octetString.buf, buffer + bufPos, elementLength); memcpy(value->value.octetString.buf, buffer + bufPos, elementLength);
} }
@ -286,7 +286,7 @@ parseAllData(uint8_t* buffer, int allDataLength, MmsValue* dataSetValues)
uint8_t* oldBuf = value->value.octetString.buf; uint8_t* oldBuf = value->value.octetString.buf;
value->value.octetString.buf = newBuf; value->value.octetString.buf = newBuf;
value->value.octetString.maxSize = elementLength; value->value.octetString.maxSize = -elementLength;
value->value.octetString.size = elementLength; value->value.octetString.size = elementLength;
GLOBAL_FREEMEM(oldBuf); GLOBAL_FREEMEM(oldBuf);

@ -45,7 +45,7 @@ struct ATTRIBUTE_PACKED sMmsValue {
} floatingPoint; } floatingPoint;
struct { struct {
uint16_t size; uint16_t size;
uint16_t maxSize; int maxSize;
uint8_t* buf; uint8_t* buf;
} octetString; } octetString;
struct { struct {

@ -331,7 +331,7 @@ mmsClient_parseListOfAccessResults(AccessResult_t** accessResultList, int listSi
if (size >= 0) { if (size >= 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_OCTET_STRING; value->type = MMS_OCTET_STRING;
value->value.octetString.maxSize = size; value->value.octetString.maxSize = -size;
value->value.octetString.size = size; value->value.octetString.size = size;
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size); value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(value->value.octetString.buf, accessResultList[i]->choice.octetstring.buf, size); memcpy(value->value.octetString.buf, accessResultList[i]->choice.octetstring.buf, size);

@ -192,20 +192,22 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (componentCount > 0) { if (componentCount > 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_ARRAY; if (value) {
value->value.structure.size = componentCount; value->type = MMS_ARRAY;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
int i;
int i;
for (i = 0; i < componentCount; i++) {
value->value.structure.components[i] = for (i = 0; i < componentCount; i++) {
mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]); value->value.structure.components[i] =
mmsMsg_parseDataElement(dataElement->choice.array->list.array[i]);
if (value->value.structure.components[i] == NULL) {
MmsValue_delete(value); if (value->value.structure.components[i] == NULL) {
value = NULL; MmsValue_delete(value);
break; value = NULL;
break;
}
} }
} }
} }
@ -222,20 +224,22 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (componentCount > 0) { if (componentCount > 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_STRUCTURE; if (value) {
value->value.structure.size = componentCount; value->type = MMS_STRUCTURE;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
int i; int i;
for (i = 0; i < componentCount; i++) { for (i = 0; i < componentCount; i++) {
value->value.structure.components[i] = value->value.structure.components[i] =
mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]); mmsMsg_parseDataElement(dataElement->choice.structure->list.array[i]);
if (value->value.structure.components[i] == NULL) { if (value->value.structure.components[i] == NULL) {
MmsValue_delete(value); MmsValue_delete(value);
value = NULL; value = NULL;
break; break;
}
} }
} }
} }
@ -251,7 +255,8 @@ mmsMsg_parseDataElement(Data_t* dataElement)
Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer( Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer(
dataElement->choice.integer.buf, dataElement->choice.integer.size); dataElement->choice.integer.buf, dataElement->choice.integer.size);
value = MmsValue_newIntegerFromBerInteger(berInteger); if (berInteger)
value = MmsValue_newIntegerFromBerInteger(berInteger);
} }
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
@ -264,7 +269,8 @@ mmsMsg_parseDataElement(Data_t* dataElement)
Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer( Asn1PrimitiveValue* berInteger = BerInteger_createFromBuffer(
dataElement->choice.Unsigned.buf, dataElement->choice.Unsigned.size); dataElement->choice.Unsigned.buf, dataElement->choice.Unsigned.size);
value = MmsValue_newUnsignedFromBerInteger(berInteger); if (berInteger)
value = MmsValue_newUnsignedFromBerInteger(berInteger);
} }
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
@ -297,20 +303,32 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if ((bitSize > 0) && (maxSize >= bitSize)) { if ((bitSize > 0) && (maxSize >= bitSize)) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_BIT_STRING; if (value) {
value->type = MMS_BIT_STRING;
value->value.bitString.size = bitSize; value->value.bitString.size = bitSize;
value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size); value->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(value->value.bitString.buf,
dataElement->choice.bitstring.buf, size); if (value->value.bitString.buf) {
memcpy(value->value.bitString.buf,
dataElement->choice.bitstring.buf, size);
}
else {
GLOBAL_FREEMEM(value);
value = 0;
}
}
} }
else if (bitSize == 0) { else if (bitSize == 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_BIT_STRING; if (value) {
value->value.bitString.size = 0; value->type = MMS_BIT_STRING;
value->value.bitString.buf = NULL; value->value.bitString.size = 0;
value->value.bitString.buf = NULL;
}
} }
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
@ -329,35 +347,41 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (size == 5) { /* FLOAT32 */ if (size == 5) { /* FLOAT32 */
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 32; if (value) {
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0]; value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 32;
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1); uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
#if (ORDER_LITTLE_ENDIAN == 1) #if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4); memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 4);
#else #else
memcpy(value->value.floatingPoint.buf, floatBuf, 4); memcpy(value->value.floatingPoint.buf, floatBuf, 4);
#endif #endif
}
} }
if (size == 9) { /* FLOAT64 */ if (size == 9) { /* FLOAT64 */
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 64; if (value) {
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0]; value->type = MMS_FLOAT;
uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1); value->value.floatingPoint.formatWidth = 64;
value->value.floatingPoint.exponentWidth = dataElement->choice.floatingpoint.buf[0];
uint8_t* floatBuf = (dataElement->choice.floatingpoint.buf + 1);
#if (ORDER_LITTLE_ENDIAN == 1) #if (ORDER_LITTLE_ENDIAN == 1)
memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8); memcpyReverseByteOrder(value->value.floatingPoint.buf, floatBuf, 8);
#else #else
memcpy(value->value.floatingPoint.buf, floatBuf, 8); memcpy(value->value.floatingPoint.buf, floatBuf, 8);
#endif #endif
}
} }
} }
else if (dataElement->present == Data_PR_utctime) { else if (dataElement->present == Data_PR_utctime) {
@ -366,8 +390,11 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (size == 8) { if (size == 8) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_UTC_TIME;
memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8); if (value) {
value->type = MMS_UTC_TIME;
memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8);
}
} }
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
@ -378,12 +405,28 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if (dataElement->choice.octetstring.size >= 0) { if (dataElement->choice.octetstring.size >= 0) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_OCTET_STRING;
int size = dataElement->choice.octetstring.size; if (value) {
value->value.octetString.size = size; value->type = MMS_OCTET_STRING;
value->value.octetString.maxSize = size; int size = dataElement->choice.octetstring.size;
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size); value->value.octetString.size = size;
if (size > 0)
value->value.octetString.maxSize = -size;
else
value->value.octetString.maxSize = -8;
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(abs(value->value.octetString.maxSize));
if (value->value.octetString.buf) {
memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size);
}
else {
GLOBAL_FREEMEM(value);
value = NULL;
}
}
} }
} }
@ -392,9 +435,12 @@ mmsMsg_parseDataElement(Data_t* dataElement)
if ((size == 4) || (size == 6)) { if ((size == 4) || (size == 6)) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
value->type = MMS_BINARY_TIME;
value->value.binaryTime.size = size; if (value) {
memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size); value->type = MMS_BINARY_TIME;
value->value.binaryTime.size = size;
memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size);
}
} }
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)

@ -240,9 +240,11 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
if (updateStructuredComponent(self, update) == false) if (updateStructuredComponent(self, update) == false)
return false; return false;
break; break;
case MMS_BOOLEAN: case MMS_BOOLEAN:
self->value.boolean = update->value.boolean; self->value.boolean = update->value.boolean;
break; break;
case MMS_FLOAT: case MMS_FLOAT:
if (self->value.floatingPoint.formatWidth == update->value.floatingPoint.formatWidth) { if (self->value.floatingPoint.formatWidth == update->value.floatingPoint.formatWidth) {
self->value.floatingPoint.exponentWidth = update->value.floatingPoint.exponentWidth; self->value.floatingPoint.exponentWidth = update->value.floatingPoint.exponentWidth;
@ -252,6 +254,7 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
else else
return false; return false;
break; break;
case MMS_INTEGER: case MMS_INTEGER:
case MMS_UNSIGNED: case MMS_UNSIGNED:
if (BerInteger_setFromBerInteger(self->value.integer, update->value.integer)) if (BerInteger_setFromBerInteger(self->value.integer, update->value.integer))
@ -259,9 +262,11 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
else else
return false; return false;
break; break;
case MMS_UTC_TIME: case MMS_UTC_TIME:
memcpy(self->value.utcTime, update->value.utcTime, 8); memcpy(self->value.utcTime, update->value.utcTime, 8);
break; break;
case MMS_BIT_STRING: case MMS_BIT_STRING:
if (self->value.bitString.size == update->value.bitString.size) if (self->value.bitString.size == update->value.bitString.size)
memcpy(self->value.bitString.buf, update->value.bitString.buf, bitStringByteSize(self)); memcpy(self->value.bitString.buf, update->value.bitString.buf, bitStringByteSize(self));
@ -278,40 +283,55 @@ MmsValue_update(MmsValue* self, const MmsValue* update)
else else
return false; return false;
break; break;
case MMS_OCTET_STRING: case MMS_OCTET_STRING:
{ {
int size = update->value.octetString.size; int size = update->value.octetString.size;
if (size > self->value.octetString.maxSize) { if ((self->value.octetString.maxSize < 0) && (size > abs(self->value.octetString.maxSize))) {
GLOBAL_FREEMEM(self->value.octetString.buf); GLOBAL_FREEMEM(self->value.octetString.buf);
self->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size); self->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(size);
if (self->value.octetString.buf == NULL) if (self->value.octetString.buf == NULL)
return false; return false;
self->value.octetString.maxSize = size; if (self->value.octetString.maxSize < 0)
self->value.octetString.maxSize = -size;
else
self->value.octetString.maxSize = size;
} }
memcpy(self->value.octetString.buf, update->value.octetString.buf, size); if (size <= abs(self->value.octetString.maxSize)) {
memcpy(self->value.octetString.buf, update->value.octetString.buf, size);
self->value.octetString.size = size; self->value.octetString.size = size;
}
else {
return false;
}
} }
break; break;
case MMS_VISIBLE_STRING: case MMS_VISIBLE_STRING:
MmsValue_setVisibleString(self, update->value.visibleString.buf); MmsValue_setVisibleString(self, update->value.visibleString.buf);
break; break;
case MMS_STRING: case MMS_STRING:
MmsValue_setMmsString(self, update->value.visibleString.buf); MmsValue_setMmsString(self, update->value.visibleString.buf);
break; break;
case MMS_BINARY_TIME: case MMS_BINARY_TIME:
self->value.binaryTime.size = update->value.binaryTime.size; self->value.binaryTime.size = update->value.binaryTime.size;
memcpy(self->value.binaryTime.buf, update->value.binaryTime.buf, memcpy(self->value.binaryTime.buf, update->value.binaryTime.buf,
update->value.binaryTime.size); update->value.binaryTime.size);
break; break;
default: default:
return false; return false;
break; break;
} }
return true; return true;
} }
else else
@ -1046,7 +1066,7 @@ MmsValue_getSizeInMemory(const MmsValue* self)
break; break;
case MMS_OCTET_STRING: case MMS_OCTET_STRING:
memorySize += MemoryAllocator_getAlignedSize(self->value.octetString.maxSize); memorySize += MemoryAllocator_getAlignedSize(abs(self->value.octetString.maxSize));
break; break;
case MMS_STRING: case MMS_STRING:
@ -1106,8 +1126,8 @@ MmsValue_cloneToBuffer(const MmsValue* self, uint8_t* destinationAddress)
case MMS_OCTET_STRING: case MMS_OCTET_STRING:
newValue->value.octetString.buf = destinationAddress; newValue->value.octetString.buf = destinationAddress;
memcpy(destinationAddress, self->value.octetString.buf, self->value.octetString.maxSize); memcpy(destinationAddress, self->value.octetString.buf, abs(self->value.octetString.maxSize));
destinationAddress += MemoryAllocator_getAlignedSize(self->value.octetString.maxSize); destinationAddress += MemoryAllocator_getAlignedSize(abs(self->value.octetString.maxSize));
break; break;
case MMS_STRING: case MMS_STRING:
@ -1201,7 +1221,15 @@ MmsValue_clone(const MmsValue* self)
newValue->value.bitString.size = self->value.bitString.size; newValue->value.bitString.size = self->value.bitString.size;
size = bitStringByteSize(self); size = bitStringByteSize(self);
newValue->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size); newValue->value.bitString.buf = (uint8_t*) GLOBAL_MALLOC(size);
memcpy(newValue->value.bitString.buf, self->value.bitString.buf, size);
if (newValue->value.bitString.buf) {
memcpy(newValue->value.bitString.buf, self->value.bitString.buf, size);
}
else {
GLOBAL_FREEMEM(newValue);
newValue = NULL;
}
break; break;
case MMS_BOOLEAN: case MMS_BOOLEAN:
@ -1212,8 +1240,16 @@ MmsValue_clone(const MmsValue* self)
size = self->value.octetString.size; size = self->value.octetString.size;
newValue->value.octetString.size = size; newValue->value.octetString.size = size;
newValue->value.octetString.maxSize = self->value.octetString.maxSize; newValue->value.octetString.maxSize = self->value.octetString.maxSize;
newValue->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(self->value.octetString.maxSize); newValue->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(abs(self->value.octetString.maxSize));
memcpy(newValue->value.octetString.buf, self->value.octetString.buf, size);
if (newValue->value.octetString.buf) {
memcpy(newValue->value.octetString.buf, self->value.octetString.buf, size);
}
else {
GLOBAL_FREEMEM(newValue);
newValue = NULL;
}
break; break;
case MMS_UTC_TIME: case MMS_UTC_TIME:
@ -1229,8 +1265,16 @@ MmsValue_clone(const MmsValue* self)
case MMS_STRING: case MMS_STRING:
size = self->value.visibleString.size; size = self->value.visibleString.size;
newValue->value.visibleString.buf = (char*) GLOBAL_MALLOC(size + 1); newValue->value.visibleString.buf = (char*) GLOBAL_MALLOC(size + 1);
newValue->value.visibleString.size = size;
strcpy(newValue->value.visibleString.buf, self->value.visibleString.buf); if (newValue->value.visibleString.buf) {
newValue->value.visibleString.size = size;
strcpy(newValue->value.visibleString.buf, self->value.visibleString.buf);
}
else {
GLOBAL_FREEMEM(newValue);
newValue = NULL;
}
break; break;
case MMS_DATA_ACCESS_ERROR: case MMS_DATA_ACCESS_ERROR:
@ -1409,7 +1453,7 @@ MmsValue_newOctetString(int size, int maxSize)
self->type = MMS_OCTET_STRING; self->type = MMS_OCTET_STRING;
self->value.octetString.size = size; self->value.octetString.size = size;
self->value.octetString.maxSize = maxSize; self->value.octetString.maxSize = maxSize;
self->value.octetString.buf = (uint8_t*) GLOBAL_CALLOC(1, maxSize); self->value.octetString.buf = (uint8_t*) GLOBAL_CALLOC(1, abs(maxSize));
if (self->value.octetString.buf == NULL) { if (self->value.octetString.buf == NULL) {
GLOBAL_FREEMEM(self); GLOBAL_FREEMEM(self);
@ -1423,7 +1467,7 @@ MmsValue_newOctetString(int size, int maxSize)
void void
MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size) MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size)
{ {
if (size <= self->value.octetString.maxSize) { if (size <= abs(self->value.octetString.maxSize)) {
memcpy(self->value.octetString.buf, buf, size); memcpy(self->value.octetString.buf, buf, size);
self->value.octetString.size = size; self->value.octetString.size = size;
} }
@ -1432,7 +1476,7 @@ MmsValue_setOctetString(MmsValue* self, const uint8_t* buf, int size)
void void
MmsValue_setOctetStringOctet(MmsValue* self, int octetPos, uint8_t value) MmsValue_setOctetStringOctet(MmsValue* self, int octetPos, uint8_t value)
{ {
if ((octetPos >= 0) && (octetPos < self->value.octetString.maxSize)) { if ((octetPos >= 0) && (octetPos < abs(self->value.octetString.maxSize))) {
self->value.octetString.buf[octetPos] = value; self->value.octetString.buf[octetPos] = value;
if (octetPos >= self->value.octetString.size) { if (octetPos >= self->value.octetString.size) {
@ -1450,7 +1494,7 @@ MmsValue_getOctetStringSize(const MmsValue* self)
uint16_t uint16_t
MmsValue_getOctetStringMaxSize(MmsValue* self) MmsValue_getOctetStringMaxSize(MmsValue* self)
{ {
return self->value.octetString.maxSize; return abs(self->value.octetString.maxSize);
} }
uint8_t* uint8_t*

@ -394,7 +394,7 @@ MmsValue_getMaxEncodedSize(MmsValue* self)
size = 2 + self->value.binaryTime.size; size = 2 + self->value.binaryTime.size;
break; break;
case MMS_OCTET_STRING: case MMS_OCTET_STRING:
elementSize = self->value.octetString.maxSize; elementSize = abs(self->value.octetString.maxSize);
size = 1 + BerEncoder_determineLengthSize(elementSize) + elementSize; size = 1 + BerEncoder_determineLengthSize(elementSize) + elementSize;
break; break;
case MMS_FLOAT: case MMS_FLOAT:

Loading…
Cancel
Save