Library: Add <iterator> element in <function> <arg>. Not used by any checks yet.

This commit is contained in:
Daniel Marjamäki 2016-10-25 23:07:18 +02:00
parent 6b168aba14
commit 08a618c476
3 changed files with 58 additions and 22 deletions

View File

@ -4020,6 +4020,21 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun
</arg>
<arg nr="3"/>
</function>
<!-- iterator std::find(iterator first, iterator last, T val) -->
<function name="std::find">
<noreturn>false</noreturn>
<arg nr="1">
<not-uninit/>
<iterator container="1" type="first"/>
</arg>
<arg nr="2">
<not-uninit/>
<iterator container="1" type="last"/>
</arg>
<arg nr="3">
<not-uninit/>
</arg>
</function>
<memory>
<alloc init="false">malloc</alloc>
<alloc init="true">calloc</alloc>

View File

@ -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<ArgumentChecks::MinSize>& 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") {

View File

@ -31,6 +31,7 @@
#include <string>
#include <list>
#include <vector>
#include <cstring>
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<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;
it1 = argumentChecks.find(functionName);