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>
<arg nr="3"/> <arg nr="3"/>
</function> </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> <memory>
<alloc init="false">malloc</alloc> <alloc init="false">malloc</alloc>
<alloc init="true">calloc</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"); return Error(MISSING_ATTRIBUTE, "nr");
const bool bAnyArg = strcmp(argNrString, "any")==0; const bool bAnyArg = strcmp(argNrString, "any")==0;
const int nr = (bAnyArg) ? -1 : atoi(argNrString); const int nr = (bAnyArg) ? -1 : atoi(argNrString);
bool notbool = false; ArgumentChecks &ac = argumentChecks[name][nr];
bool notnull = false; ac.optional = functionnode->Attribute("default") != nullptr;
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;
for (const tinyxml2::XMLElement *argnode = functionnode->FirstChildElement(); argnode; argnode = argnode->NextSiblingElement()) { for (const tinyxml2::XMLElement *argnode = functionnode->FirstChildElement(); argnode; argnode = argnode->NextSiblingElement()) {
const std::string argnodename = argnode->Name(); const std::string argnodename = argnode->Name();
if (argnodename == "not-bool") if (argnodename == "not-bool")
notbool = true; ac.notbool = true;
else if (argnodename == "not-null") else if (argnodename == "not-null")
notnull = true; ac.notnull = true;
else if (argnodename == "not-uninit") else if (argnodename == "not-uninit")
notuninit = true; ac.notuninit = true;
else if (argnodename == "formatstr") else if (argnodename == "formatstr")
formatstr = true; ac.formatstr = true;
else if (argnodename == "strz") else if (argnodename == "strz")
strz = true; ac.strz = true;
else if (argnodename == "valid") { else if (argnodename == "valid") {
// Validate the validation expression // Validate the validation expression
const char *p = argnode->GetText(); 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()); return Error(BAD_ATTRIBUTE_VALUE, argnode->GetText());
// Set validation expression // Set validation expression
valid = argnode->GetText(); ac.valid = argnode->GetText();
} }
else if (argnodename == "minsize") { 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') if (strlen(argattr) != 1 || argattr[0]<'0' || argattr[0]>'9')
return Error(BAD_ATTRIBUTE_VALUE, argattr); 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) { if (type == ArgumentChecks::MinSize::MUL) {
const char *arg2attr = argnode->Attribute("arg2"); const char *arg2attr = argnode->Attribute("arg2");
if (!arg2attr) if (!arg2attr)
return Error(MISSING_ATTRIBUTE, "arg2"); return Error(MISSING_ATTRIBUTE, "arg2");
if (strlen(arg2attr) != 1 || arg2attr[0]<'0' || arg2attr[0]>'9') if (strlen(arg2attr) != 1 || arg2attr[0]<'0' || arg2attr[0]>'9')
return Error(BAD_ATTRIBUTE_VALUE, arg2attr); 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 else
unknown_elements.insert(argnodename); 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") { } else if (functionnodename == "ignorefunction") {
_ignorefunction.insert(name); _ignorefunction.insert(name);
} else if (functionnodename == "formatstr") { } else if (functionnodename == "formatstr") {

View File

@ -31,6 +31,7 @@
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
#include <cstring>
namespace tinyxml2 { namespace tinyxml2 {
class XMLDocument; class XMLDocument;
@ -228,7 +229,8 @@ public:
notuninit(false), notuninit(false),
formatstr(false), formatstr(false),
strz(false), strz(false),
optional(false) { optional(false),
iteratorInfo() {
} }
bool notbool; bool notbool;
@ -239,6 +241,26 @@ public:
bool optional; bool optional;
std::string valid; 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 { class MinSize {
public: public:
enum Type {NONE,STRLEN,ARGVALUE,SIZEOF,MUL}; enum Type {NONE,STRLEN,ARGVALUE,SIZEOF,MUL};
@ -278,6 +300,11 @@ public:
return arg ? arg->valid : emptyString; 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 { bool hasminsize(const std::string &functionName) const {
std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1; std::map<std::string, std::map<int, ArgumentChecks> >::const_iterator it1;
it1 = argumentChecks.find(functionName); it1 = argumentChecks.find(functionName);