diff --git a/simgear/props/props.cxx b/simgear/props/props.cxx index f73e773e..83b586c0 100644 --- a/simgear/props/props.cxx +++ b/simgear/props/props.cxx @@ -229,11 +229,13 @@ parse_path (const string &path, vector &components) static char * copy_string (const char * s) { - // FIXME: potential buffer overflow. - // For some reason, strnlen and - // strncpy cause all kinds of crashes. - char * copy = new char[strlen(s) + 1]; - strcpy(copy, s); + unsigned long int slen = strlen(s); + char * copy = new char[slen + 1]; + + // the source string length is known so no need to check for '\0' + // when copying every single character + memcpy(copy, s, slen); + *(copy + slen) = '\0'; return copy; } @@ -252,12 +254,32 @@ find_child (const char * name, int index, const vector& node int nNodes = nodes.size(); for (int i = 0; i < nNodes; i++) { SGPropertyNode * node = nodes[i]; - if (compare_strings(node->getName(), name) && node->getIndex() == index) + + // searching for a mathing index is a lot less time consuming than + // comparing two strings so do that first. + if (node->getIndex() == index && compare_strings(node->getName(), name)) return i; } return -1; } +/** + * Locate the last child node with a given name. +*/ +static int +find_last_child (const char * name, const vector& nodes) +{ + int nNodes = nodes.size(); + int pos = -1; + + for (int i = 0; i < nNodes; i++) { + SGPropertyNode * node = nodes[i]; + if (compare_strings(node->getName(), name)) + pos++; + } + return pos; +} + /** * Locate another node, given a relative path. @@ -824,6 +846,21 @@ SGPropertyNode::getAliasTarget () const return (_type == ALIAS ? _value.alias : 0); } +/** + * create a non-const child by name after the last node with the same name. + */ +SGPropertyNode * +SGPropertyNode::addChild (const char * name) +{ + int pos = find_last_child(name, _children); + + SGPropertyNode_ptr node; + node = new SGPropertyNode(name, ++pos, this); + _children.push_back(node); + fireChildAdded(node); + return node; +} + /** * Get a non-const child by index. diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index d25637e0..cc1ed537 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -622,6 +622,10 @@ public: return (getChild(name, index) != 0); } + /** + * Create a child node after the last node with the same name. + */ + SGPropertyNode * addChild (const char * name); /** * Get a child node by name and index.