@@ -44,6 +44,7 @@ static const struct CWE CWE628(628U); // Function Call with Incorrectly Specif
4444static const struct CWE CWE664 (664U ); // Improper Control of a Resource Through its Lifetime
4545static const struct CWE CWE704 (704U ); // Incorrect Type Conversion or Cast
4646static const struct CWE CWE762 (762U ); // Mismatched Memory Management Routines
47+ static const struct CWE CWE786 (786U ); // Access of Memory Location Before Start of Buffer
4748static const struct CWE CWE788 (788U ); // Access of Memory Location After End of Buffer
4849static const struct CWE CWE825 (825U ); // Expired Pointer Dereference
4950static const struct CWE CWE834 (834U ); // Excessive Iteration
@@ -437,6 +438,42 @@ void CheckStl::stlOutOfBoundsError(const Token *tok, const std::string &num, con
437438 reportError (tok, Severity::error, " stlOutOfBounds" , " When " + num + " ==" + var + " .size(), " + var + " [" + num + " ] is out of bounds." , CWE788, false );
438439}
439440
441+ void CheckStl::negativeIndex ()
442+ {
443+ // Negative index is out of bounds..
444+ const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase ();
445+ const std::size_t functions = symbolDatabase->functionScopes .size ();
446+ for (std::size_t ii = 0 ; ii < functions; ++ii) {
447+ const Scope * scope = symbolDatabase->functionScopes [ii];
448+ for (const Token* tok = scope->classStart ->next (); tok != scope->classEnd ; tok = tok->next ()) {
449+ if (!Token::Match (tok, " %var% [" ))
450+ continue ;
451+ const Variable * const var = tok->variable ();
452+ if (!var || tok == var->nameToken ())
453+ continue ;
454+ const Library::Container * const container = _settings->library .detectContainer (var->typeStartToken ());
455+ if (!container || !container->arrayLike_indexOp )
456+ continue ;
457+ const ValueFlow::Value *index = tok->next ()->astOperand2 ()->getValueLE (-1 , _settings);
458+ if (!index)
459+ continue ;
460+ negativeIndexError (tok, *index);
461+ }
462+ }
463+ }
464+
465+ void CheckStl::negativeIndexError (const Token *tok, const ValueFlow::Value &index)
466+ {
467+ const ErrorPath errorPath = getErrorPath (tok, &index, " Negative array index" );
468+ std::ostringstream errmsg;
469+ if (index.condition )
470+ errmsg << ValueFlow::eitherTheConditionIsRedundant (index.condition )
471+ << " , otherwise there is negative array index " << index.intvalue << " ." ;
472+ else
473+ errmsg << " Array index " << index.intvalue << " is out of bounds." ;
474+ reportError (errorPath, index.errorSeverity () ? Severity::error : Severity::warning, " negativeContainerIndex" , errmsg.str (), CWE786, index.inconclusive );
475+ }
476+
440477void CheckStl::erase ()
441478{
442479 const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase ();
0 commit comments