- 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,6 +192,7 @@ 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));
if (value) {
value->type = MMS_ARRAY; value->type = MMS_ARRAY;
value->value.structure.size = componentCount; value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
@ -209,6 +210,7 @@ mmsMsg_parseDataElement(Data_t* dataElement)
} }
} }
} }
}
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
printf("MMS CLIENT: error parsing data element (invalid array size)!\n"); printf("MMS CLIENT: error parsing data element (invalid array size)!\n");
@ -222,6 +224,7 @@ 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));
if (value) {
value->type = MMS_STRUCTURE; value->type = MMS_STRUCTURE;
value->value.structure.size = componentCount; value->value.structure.size = componentCount;
value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*)); value->value.structure.components = (MmsValue**) GLOBAL_CALLOC(componentCount, sizeof(MmsValue*));
@ -239,6 +242,7 @@ mmsMsg_parseDataElement(Data_t* dataElement)
} }
} }
} }
}
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
printf("MMS CLIENT: error parsing data element (invalid structure size)!\n"); printf("MMS CLIENT: error parsing data element (invalid structure size)!\n");
@ -251,6 +255,7 @@ 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);
if (berInteger)
value = MmsValue_newIntegerFromBerInteger(berInteger); value = MmsValue_newIntegerFromBerInteger(berInteger);
} }
else { else {
@ -264,6 +269,7 @@ 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);
if (berInteger)
value = MmsValue_newUnsignedFromBerInteger(berInteger); value = MmsValue_newUnsignedFromBerInteger(berInteger);
} }
else { else {
@ -297,21 +303,33 @@ 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));
if (value) {
value->type = MMS_BIT_STRING; 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);
if (value->value.bitString.buf) {
memcpy(value->value.bitString.buf, memcpy(value->value.bitString.buf,
dataElement->choice.bitstring.buf, size); 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));
if (value) {
value->type = MMS_BIT_STRING; value->type = MMS_BIT_STRING;
value->value.bitString.size = 0; value->value.bitString.size = 0;
value->value.bitString.buf = NULL; value->value.bitString.buf = NULL;
} }
}
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
printf("MMS CLIENT: error parsing data element (bit string padding problem)!\n"); printf("MMS CLIENT: error parsing data element (bit string padding problem)!\n");
@ -329,6 +347,8 @@ 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));
if (value) {
value->type = MMS_FLOAT; value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 32; value->value.floatingPoint.formatWidth = 32;
@ -342,10 +362,13 @@ mmsMsg_parseDataElement(Data_t* dataElement)
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));
if (value) {
value->type = MMS_FLOAT; value->type = MMS_FLOAT;
value->value.floatingPoint.formatWidth = 64; value->value.floatingPoint.formatWidth = 64;
@ -360,15 +383,19 @@ mmsMsg_parseDataElement(Data_t* dataElement)
#endif #endif
} }
} }
}
else if (dataElement->present == Data_PR_utctime) { else if (dataElement->present == Data_PR_utctime) {
int size = dataElement->choice.utctime.size; int size = dataElement->choice.utctime.size;
if (size == 8) { if (size == 8) {
value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue)); value = (MmsValue*) GLOBAL_CALLOC(1, sizeof(MmsValue));
if (value) {
value->type = MMS_UTC_TIME; value->type = MMS_UTC_TIME;
memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8); memcpy(value->value.utcTime, dataElement->choice.utctime.buf, 8);
} }
}
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
printf("MMS CLIENT: error parsing UTC time (size is %i instead of 8\n", size); printf("MMS CLIENT: error parsing UTC time (size is %i instead of 8\n", size);
@ -378,13 +405,29 @@ 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));
if (value) {
value->type = MMS_OCTET_STRING; value->type = MMS_OCTET_STRING;
int size = dataElement->choice.octetstring.size; int size = dataElement->choice.octetstring.size;
value->value.octetString.size = size; value->value.octetString.size = size;
value->value.octetString.maxSize = size;
value->value.octetString.buf = (uint8_t*) GLOBAL_MALLOC(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); memcpy(value->value.octetString.buf, dataElement->choice.octetstring.buf, size);
} }
else {
GLOBAL_FREEMEM(value);
value = NULL;
}
}
}
} }
else if (dataElement->present == Data_PR_binarytime) { else if (dataElement->present == Data_PR_binarytime) {
@ -392,10 +435,13 @@ 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));
if (value) {
value->type = MMS_BINARY_TIME; value->type = MMS_BINARY_TIME;
value->value.binaryTime.size = size; value->value.binaryTime.size = size;
memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size); memcpy(value->value.binaryTime.buf, dataElement->choice.binarytime.buf, size);
} }
}
else { else {
if (DEBUG_MMS_CLIENT) if (DEBUG_MMS_CLIENT)
printf("MMS CLIENT: error parsing binary time (size must be 4 or 6, is %i\n", size); printf("MMS CLIENT: error parsing binary time (size must be 4 or 6, is %i\n", size);

@ -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;
if (self->value.octetString.maxSize < 0)
self->value.octetString.maxSize = -size;
else
self->value.octetString.maxSize = size; self->value.octetString.maxSize = size;
} }
if (size <= abs(self->value.octetString.maxSize)) {
memcpy(self->value.octetString.buf, update->value.octetString.buf, size); 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);
if (newValue->value.bitString.buf) {
memcpy(newValue->value.bitString.buf, self->value.bitString.buf, size); 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));
if (newValue->value.octetString.buf) {
memcpy(newValue->value.octetString.buf, self->value.octetString.buf, size); 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);
if (newValue->value.visibleString.buf) {
newValue->value.visibleString.size = size; newValue->value.visibleString.size = size;
strcpy(newValue->value.visibleString.buf, self->value.visibleString.buf); 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