diff --git a/cfg/std.cfg b/cfg/std.cfg
index d71e675e6..c2b7e44fe 100644
--- a/cfg/std.cfg
+++ b/cfg/std.cfg
@@ -4020,6 +4020,21 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
malloc
calloc
diff --git a/lib/library.cpp b/lib/library.cpp
index 404a321c4..187895709 100644
--- a/lib/library.cpp
+++ b/lib/library.cpp
@@ -556,25 +556,20 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
return Error(MISSING_ATTRIBUTE, "nr");
const bool bAnyArg = strcmp(argNrString, "any")==0;
const int nr = (bAnyArg) ? -1 : atoi(argNrString);
- bool notbool = false;
- bool notnull = false;
- bool notuninit = false;
- bool formatstr = false;
- bool strz = false;
- std::string& valid = argumentChecks[name][nr].valid;
- std::list& minsizes = argumentChecks[name][nr].minsizes;
+ ArgumentChecks &ac = argumentChecks[name][nr];
+ ac.optional = functionnode->Attribute("default") != nullptr;
for (const tinyxml2::XMLElement *argnode = functionnode->FirstChildElement(); argnode; argnode = argnode->NextSiblingElement()) {
const std::string argnodename = argnode->Name();
if (argnodename == "not-bool")
- notbool = true;
+ ac.notbool = true;
else if (argnodename == "not-null")
- notnull = true;
+ ac.notnull = true;
else if (argnodename == "not-uninit")
- notuninit = true;
+ ac.notuninit = true;
else if (argnodename == "formatstr")
- formatstr = true;
+ ac.formatstr = true;
else if (argnodename == "strz")
- strz = true;
+ ac.strz = true;
else if (argnodename == "valid") {
// Validate the validation expression
const char *p = argnode->GetText();
@@ -598,7 +593,7 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
return Error(BAD_ATTRIBUTE_VALUE, argnode->GetText());
// Set validation expression
- valid = argnode->GetText();
+ ac.valid = argnode->GetText();
}
else if (argnodename == "minsize") {
@@ -624,26 +619,25 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
if (strlen(argattr) != 1 || argattr[0]<'0' || argattr[0]>'9')
return Error(BAD_ATTRIBUTE_VALUE, argattr);
- minsizes.push_back(ArgumentChecks::MinSize(type,argattr[0]-'0'));
+ ac.minsizes.push_back(ArgumentChecks::MinSize(type,argattr[0]-'0'));
if (type == ArgumentChecks::MinSize::MUL) {
const char *arg2attr = argnode->Attribute("arg2");
if (!arg2attr)
return Error(MISSING_ATTRIBUTE, "arg2");
if (strlen(arg2attr) != 1 || arg2attr[0]<'0' || arg2attr[0]>'9')
return Error(BAD_ATTRIBUTE_VALUE, arg2attr);
- minsizes.back().arg2 = arg2attr[0] - '0';
+ ac.minsizes.back().arg2 = arg2attr[0] - '0';
}
}
+ else if (argnodename == "iterator") {
+ ac.iteratorInfo.setType(argnode->Attribute("type"));
+ ac.iteratorInfo.setContainer(argnode->Attribute("container"));
+ }
+
else
unknown_elements.insert(argnodename);
}
- argumentChecks[name][nr].notbool = notbool;
- argumentChecks[name][nr].notnull = notnull;
- argumentChecks[name][nr].notuninit = notuninit;
- argumentChecks[name][nr].formatstr = formatstr;
- argumentChecks[name][nr].strz = strz;
- argumentChecks[name][nr].optional = functionnode->Attribute("default") != nullptr;
} else if (functionnodename == "ignorefunction") {
_ignorefunction.insert(name);
} else if (functionnodename == "formatstr") {
diff --git a/lib/library.h b/lib/library.h
index d57ca6755..6fcc25b2a 100644
--- a/lib/library.h
+++ b/lib/library.h
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
namespace tinyxml2 {
class XMLDocument;
@@ -228,7 +229,8 @@ public:
notuninit(false),
formatstr(false),
strz(false),
- optional(false) {
+ optional(false),
+ iteratorInfo() {
}
bool notbool;
@@ -239,6 +241,26 @@ public:
bool optional;
std::string valid;
+ class IteratorInfo {
+ public:
+ IteratorInfo() : it(false), container(0), first(false), last(false) {}
+ void setContainer(const char *str) {
+ it = true;
+ container = str ? std::atoi(str) : 0;
+ }
+ void setType(const char *str) {
+ it = true;
+ first = str ? (std::strcmp(str,"first") == 0) : false;
+ last = str ? (std::strcmp(str,"last") == 0) : false;
+ }
+
+ bool it;
+ int container;
+ bool first;
+ bool last;
+ };
+ IteratorInfo iteratorInfo;
+
class MinSize {
public:
enum Type {NONE,STRLEN,ARGVALUE,SIZEOF,MUL};
@@ -278,6 +300,11 @@ public:
return arg ? arg->valid : emptyString;
}
+ const ArgumentChecks::IteratorInfo *getArgIteratorInfo(const Token *ftok, int argnr) const {
+ const ArgumentChecks *arg = getarg(ftok, argnr);
+ return arg && arg->iteratorInfo.it ? &arg->iteratorInfo : nullptr;
+ }
+
bool hasminsize(const std::string &functionName) const {
std::map >::const_iterator it1;
it1 = argumentChecks.find(functionName);