From 8a9eabeeaca94abca7296f9fdf503a3ea6fdb771 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Mon, 17 Oct 2016 23:33:49 -0400 Subject: [PATCH] [clib] Add buffer length argument to all functions returning strings If the buffer is not long enough, the string is truncated and the return value is the required buffer length. Otherwise, the return value is 0. --- include/cantera/base/stringUtils.h | 7 ++++++- include/cantera/clib/ctxml.h | 6 +++--- src/base/stringUtils.cpp | 4 +++- src/clib/ct.cpp | 12 ++++-------- src/clib/ctonedim.cpp | 4 +--- src/clib/ctxml.cpp | 18 ++++++------------ src/matlab/xmlmethods.cpp | 4 ++-- 7 files changed, 25 insertions(+), 30 deletions(-) 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");