diff --git a/include/cantera/base/stringUtils.h b/include/cantera/base/stringUtils.h index 4a206cad7..734283be8 100644 --- a/include/cantera/base/stringUtils.h +++ b/include/cantera/base/stringUtils.h @@ -190,7 +190,12 @@ void tokenizeString(const std::string& oval, std::vector& v); //! Copy the contents of a std::string into a char array of a given length -void copyString(const std::string& source, char* dest, size_t length); +/*! + * If *length* is less than the size of *source*, the string will be truncated + * and the function will return the length of the buffer required to hold + * *source*. Otherwise, returns 0. + */ +size_t copyString(const std::string& source, char* dest, size_t length); } diff --git a/include/cantera/clib/ctxml.h b/include/cantera/clib/ctxml.h index cef79614a..5b4e11c80 100644 --- a/include/cantera/clib/ctxml.h +++ b/include/cantera/clib/ctxml.h @@ -20,11 +20,11 @@ extern "C" { CANTERA_CAPI int xml_clear(); CANTERA_CAPI int xml_copy(int i); CANTERA_CAPI int xml_build(int i, const char* file); - CANTERA_CAPI int xml_attrib(int i, const char* key, char* value); + CANTERA_CAPI int xml_attrib(int i, const char* key, size_t lenval, char* value); CANTERA_CAPI int xml_addAttrib(int i, const char* key, const char* value); CANTERA_CAPI int xml_addComment(int i, const char* comment); - CANTERA_CAPI int xml_value(int i, char* value); - CANTERA_CAPI int xml_tag(int i, char* tag); + CANTERA_CAPI int xml_value(int i, size_t lenval, char* value); + CANTERA_CAPI int xml_tag(int i, size_t lentag, char* tag); CANTERA_CAPI int xml_child(int i, const char* loc); CANTERA_CAPI int xml_child_bynumber(int i, int m); CANTERA_CAPI int xml_findID(int i, const char* id); diff --git a/src/base/stringUtils.cpp b/src/base/stringUtils.cpp index 82dff3e66..3fa9198e8 100644 --- a/src/base/stringUtils.cpp +++ b/src/base/stringUtils.cpp @@ -366,14 +366,16 @@ void tokenizeString(const std::string& oval, } } -void copyString(const std::string& source, char* dest, size_t length) +size_t copyString(const std::string& source, char* dest, size_t length) { const char* c_src = source.c_str(); size_t N = std::min(length, source.length()+1); + size_t ret = (length >= source.length() + 1) ? 0 : source.length() + 1; std::copy(c_src, c_src + N, dest); if (length != 0) { dest[length-1] = '\0'; } + return ret; } } diff --git a/src/clib/ct.cpp b/src/clib/ct.cpp index 642226a50..9a917d388 100644 --- a/src/clib/ct.cpp +++ b/src/clib/ct.cpp @@ -287,8 +287,7 @@ extern "C" { int thermo_getName(int n, size_t lennm, char* nm) { try { - copyString(ThermoCabinet::item(n).name(), nm, lennm); - return 0; + return copyString(ThermoCabinet::item(n).name(), nm, lennm); } catch (...) { return handleAllExceptions(-1, ERR); } @@ -307,8 +306,7 @@ extern "C" { int thermo_getSpeciesName(int n, size_t k, size_t lennm, char* nm) { try { - copyString(ThermoCabinet::item(n).speciesName(k), nm, lennm); - return 0; + return copyString(ThermoCabinet::item(n).speciesName(k), nm, lennm); } catch (...) { return handleAllExceptions(-1, ERR); } @@ -317,8 +315,7 @@ extern "C" { int thermo_getElementName(int n, size_t m, size_t lennm, char* nm) { try { - copyString(ThermoCabinet::item(n).elementName(m), nm, lennm); - return 0; + return copyString(ThermoCabinet::item(n).elementName(m), nm, lennm); } catch (...) { return handleAllExceptions(-1, ERR); } @@ -1210,8 +1207,7 @@ extern "C" { try { Kinetics& k = KineticsCabinet::item(n); k.checkReactionIndex(i); - copyString(k.reactionString(i), buf, len); - return 0; + return static_cast(copyString(k.reactionString(i), buf, len)); } catch (...) { return handleAllExceptions(-1, ERR); } diff --git a/src/clib/ctonedim.cpp b/src/clib/ctonedim.cpp index 293a0a1ce..be4375eab 100644 --- a/src/clib/ctonedim.cpp +++ b/src/clib/ctonedim.cpp @@ -92,9 +92,7 @@ extern "C" { try { Domain1D& dom = DomainCabinet::item(i); dom.checkComponentIndex(n); - string nm = dom.componentName(n); - copyString(nm, buf, sz); - return static_cast(nm.size()); + return copyString(dom.componentName(n), buf, sz); } catch (...) { return handleAllExceptions(-1, ERR); } diff --git a/src/clib/ctxml.cpp b/src/clib/ctxml.cpp index da1fd3256..bc9d15794 100644 --- a/src/clib/ctxml.cpp +++ b/src/clib/ctxml.cpp @@ -100,13 +100,12 @@ extern "C" { } } - int xml_attrib(int i, const char* key, char* value) + int xml_attrib(int i, const char* key, size_t lenval, char* value) { try { XML_Node& node = XmlCabinet::item(i); if (node.hasAttrib(key)) { - string v = node[key]; - strncpy(value, v.c_str(), 80); + return copyString(node[key], value, lenval); } else { throw CanteraError("xml_attrib","node " " has no attribute '"+string(key)+"'"); @@ -114,7 +113,6 @@ extern "C" { } catch (...) { return handleAllExceptions(-1, ERR); } - return 0; } int xml_addAttrib(int i, const char* key, const char* value) @@ -137,26 +135,22 @@ extern "C" { return 0; } - int xml_tag(int i, char* tag) + int xml_tag(int i, size_t lentag, char* tag) { try { - string v = XmlCabinet::item(i).name(); - strncpy(tag, v.c_str(), 80); + return copyString(XmlCabinet::item(i).name(), tag, lentag); } catch (...) { return handleAllExceptions(-1, ERR); } - return 0; } - int xml_value(int i, char* value) + int xml_value(int i, size_t lenval, char* value) { try { - string v = XmlCabinet::item(i).value(); - strncpy(value, v.c_str(), 80); + return copyString(XmlCabinet::item(i).value(), value, lenval); } catch (...) { return handleAllExceptions(-1, ERR); } - return 0; } int xml_child(int i, const char* loc) diff --git a/src/matlab/xmlmethods.cpp b/src/matlab/xmlmethods.cpp index 08bc1f8e1..aa8628462 100644 --- a/src/matlab/xmlmethods.cpp +++ b/src/matlab/xmlmethods.cpp @@ -115,11 +115,11 @@ void xmlmethods(int nlhs, mxArray* plhs[], case 20: // return an attribute key = getString(prhs[3]); - iok = xml_attrib(i, key, v); + iok = xml_attrib(i, key, 80, v); break; case 21: // return the value of the node - iok = xml_value(i, v); + iok = xml_value(i, 80, v); break; default: mexErrMsgTxt("unknown job parameter");