- fix potential crash in ModelNode_getChild when an array element field is accessed without using the array index specifier (LIB61850-408)

v1.6_develop_417_rbac2
Michael Zillgith 2 years ago
parent c9d9271a52
commit a5f5597980

@ -649,106 +649,110 @@ ModelNode_getChildCount(ModelNode* modelNode) {
ModelNode* ModelNode*
ModelNode_getChild(ModelNode* self, const char* name) ModelNode_getChild(ModelNode* self, const char* name)
{ {
/* check for element separator */ /* check for element separator */
const char* separator = strchr(name, '.'); const char* separator = strchr(name, '.');
/* allow first character to be "." */ /* allow first character to be "." */
if (separator == name) if (separator == name)
name++; name++;
/* check for array separator */ /* check for array separator */
const char* arraySeparator = strchr(name, '('); const char* arraySeparator = strchr(name, '(');
if (arraySeparator) { if (arraySeparator) {
const char* arraySeparator2 = strchr(arraySeparator, ')'); const char* arraySeparator2 = strchr(arraySeparator, ')');
if (arraySeparator2) { if (arraySeparator2) {
int idx = (int) strtol(arraySeparator + 1, NULL, 10); int idx = (int) strtol(arraySeparator + 1, NULL, 10);
ModelNode* arrayNode = NULL; ModelNode* arrayNode = NULL;
if (name == arraySeparator) { if (name == arraySeparator) {
arrayNode = ModelNode_getChildWithIdx(self, idx); arrayNode = ModelNode_getChildWithIdx(self, idx);
} }
else { else {
char nameCopy[65]; char nameCopy[65];
const char* pos = name; const char* pos = name;
int cpyIdx = 0; int cpyIdx = 0;
while (pos < arraySeparator) { while (pos < arraySeparator) {
nameCopy[cpyIdx] = *pos; nameCopy[cpyIdx] = *pos;
cpyIdx++; cpyIdx++;
pos++; pos++;
} }
nameCopy[cpyIdx] = 0; nameCopy[cpyIdx] = 0;
ModelNode* childNode = ModelNode_getChild(self, nameCopy); ModelNode* childNode = ModelNode_getChild(self, nameCopy);
if (childNode) { if (childNode) {
arrayNode = ModelNode_getChildWithIdx(childNode, idx); arrayNode = ModelNode_getChildWithIdx(childNode, idx);
} }
else else
return NULL; return NULL;
} }
if (arrayNode) { if (arrayNode) {
if (*(arraySeparator2 + 1) == 0) { if (*(arraySeparator2 + 1) == 0) {
return arrayNode; return arrayNode;
} }
else { else {
if (*(arraySeparator2 + 1) == '.') if (*(arraySeparator2 + 1) == '.')
return ModelNode_getChild(arrayNode, arraySeparator2 + 2); return ModelNode_getChild(arrayNode, arraySeparator2 + 2);
else else
return ModelNode_getChild(arrayNode, arraySeparator2 + 1); return ModelNode_getChild(arrayNode, arraySeparator2 + 1);
} }
} }
else else
return NULL; return NULL;
}
else {
/* invalid name */
return NULL;
}
} }
else {
/* invalid name */
return NULL;
}
} int nameElementLength = 0;
int nameElementLength = 0; if (separator != NULL)
nameElementLength = (separator - name);
else
nameElementLength = strlen(name);
if (separator != NULL) ModelNode* nextNode = self->firstChild;
nameElementLength = (separator - name);
else
nameElementLength = strlen(name);
ModelNode* nextNode = self->firstChild; ModelNode* matchingNode = NULL;
ModelNode* matchingNode = NULL; while (nextNode) {
while (nextNode) { if (nextNode->name == NULL) {
int nodeNameLen = strlen(nextNode->name); break; /* is an array element */
}
if (nodeNameLen == nameElementLength) { int nodeNameLen = strlen(nextNode->name);
if (memcmp(nextNode->name, name, nodeNameLen) == 0) { if (nodeNameLen == nameElementLength) {
matchingNode = nextNode;
break;
}
}
nextNode = nextNode->sibling; if (memcmp(nextNode->name, name, nodeNameLen) == 0) {
} matchingNode = nextNode;
break;
}
}
if ((separator != NULL) && (matchingNode != NULL)) { nextNode = nextNode->sibling;
return ModelNode_getChild(matchingNode, separator + 1); }
}
else if ((separator != NULL) && (matchingNode != NULL)) {
return matchingNode; return ModelNode_getChild(matchingNode, separator + 1);
}
else
return matchingNode;
} }
ModelNode* ModelNode*

Loading…
Cancel
Save