Skip to content

Commit

Permalink
[clib] Add buffer length argument to all functions returning strings
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
speth committed Oct 18, 2016
1 parent c16c153 commit 8a9eabe
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 30 deletions.
7 changes: 6 additions & 1 deletion include/cantera/base/stringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,12 @@ void tokenizeString(const std::string& oval,
std::vector<std::string>& 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);

}

Expand Down
6 changes: 3 additions & 3 deletions include/cantera/clib/ctxml.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion src/base/stringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

}
12 changes: 4 additions & 8 deletions src/clib/ct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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<int>(copyString(k.reactionString(i), buf, len));
} catch (...) {
return handleAllExceptions(-1, ERR);
}
Expand Down
4 changes: 1 addition & 3 deletions src/clib/ctonedim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>(nm.size());
return copyString(dom.componentName(n), buf, sz);
} catch (...) {
return handleAllExceptions(-1, ERR);
}
Expand Down
18 changes: 6 additions & 12 deletions src/clib/ctxml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,19 @@ 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)+"'");
}
} catch (...) {
return handleAllExceptions(-1, ERR);
}
return 0;
}

int xml_addAttrib(int i, const char* key, const char* value)
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/matlab/xmlmethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 8a9eabe

Please sign in to comment.