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);