-
Notifications
You must be signed in to change notification settings - Fork 1.6k
avoid some unchecked pointer dereferences #4811
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -183,47 +183,46 @@ static int getMinFormatStringOutputLength(const std::vector<const Token*> ¶m | |
|
|
||
| //--------------------------------------------------------------------------- | ||
|
|
||
| static bool getDimensionsEtc(const Token * const arrayToken, const Settings *settings, std::vector<Dimension> * const dimensions, ErrorPath * const errorPath, bool * const mightBeLarger, MathLib::bigint* path) | ||
| static bool getDimensionsEtc(const Token * const arrayToken, const Settings *settings, std::vector<Dimension> &dimensions, ErrorPath &errorPath, bool &mightBeLarger, MathLib::bigint &path) | ||
| { | ||
| const Token *array = arrayToken; | ||
| while (Token::Match(array, ".|::")) | ||
| array = array->astOperand2(); | ||
|
|
||
| if (array->variable() && array->variable()->isArray() && !array->variable()->dimensions().empty()) { | ||
| *dimensions = array->variable()->dimensions(); | ||
| if (dimensions->size() >= 1 && ((*dimensions)[0].num <= 1 || !(*dimensions)[0].tok)) { | ||
| dimensions = array->variable()->dimensions(); | ||
| if (dimensions[0].num <= 1 || !dimensions[0].tok) { | ||
| visitAstNodes(arrayToken, | ||
| [&](const Token *child) { | ||
| if (child->originalName() == "->") { | ||
| *mightBeLarger = true; | ||
| mightBeLarger = true; | ||
| return ChildrenToVisit::none; | ||
| } | ||
| return ChildrenToVisit::op1_and_op2; | ||
| }); | ||
| } | ||
| } else if (const Token *stringLiteral = array->getValueTokenMinStrSize(settings, path)) { | ||
| } else if (const Token *stringLiteral = array->getValueTokenMinStrSize(settings, &path)) { | ||
| Dimension dim; | ||
| dim.tok = nullptr; | ||
| dim.num = Token::getStrArraySize(stringLiteral); | ||
| dim.known = array->hasKnownValue(); | ||
| dimensions->emplace_back(dim); | ||
| dimensions.emplace_back(dim); | ||
| } else if (array->valueType() && array->valueType()->pointer >= 1 && (array->valueType()->isIntegral() || array->valueType()->isFloat())) { | ||
| const ValueFlow::Value *value = getBufferSizeValue(array); | ||
| if (!value) | ||
| return false; | ||
| if (path) | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed this check since it is always provided and all other output parameters were unchecked. |
||
| *path = value->path; | ||
| *errorPath = value->errorPath; | ||
| path = value->path; | ||
| errorPath = value->errorPath; | ||
| Dimension dim; | ||
| dim.known = value->isKnown(); | ||
| dim.tok = nullptr; | ||
| const int typeSize = array->valueType()->typeSize(*settings, array->valueType()->pointer > 1); | ||
| if (typeSize == 0) | ||
| return false; | ||
| dim.num = value->intvalue / typeSize; | ||
| dimensions->emplace_back(dim); | ||
| dimensions.emplace_back(dim); | ||
| } | ||
| return !dimensions->empty(); | ||
| return !dimensions.empty(); | ||
| } | ||
|
|
||
| static ValueFlow::Value makeSizeValue(MathLib::bigint size, MathLib::bigint path) | ||
|
|
@@ -314,7 +313,7 @@ void CheckBufferOverrun::arrayIndex() | |
| ErrorPath errorPath; | ||
| bool mightBeLarger = false; | ||
| MathLib::bigint path = 0; | ||
| if (!getDimensionsEtc(tok->astOperand1(), mSettings, &dimensions, &errorPath, &mightBeLarger, &path)) | ||
| if (!getDimensionsEtc(tok->astOperand1(), mSettings, dimensions, errorPath, mightBeLarger, path)) | ||
| continue; | ||
|
|
||
| const Variable* const var = array->variable(); | ||
|
|
@@ -486,7 +485,7 @@ void CheckBufferOverrun::pointerArithmetic() | |
| ErrorPath errorPath; | ||
| bool mightBeLarger = false; | ||
| MathLib::bigint path = 0; | ||
| if (!getDimensionsEtc(arrayToken, mSettings, &dimensions, &errorPath, &mightBeLarger, &path)) | ||
| if (!getDimensionsEtc(arrayToken, mSettings, dimensions, errorPath, mightBeLarger, path)) | ||
| continue; | ||
|
|
||
| if (tok->str() == "+") { | ||
|
|
@@ -881,6 +880,8 @@ std::string CheckBufferOverrun::MyFileInfo::toString() const | |
|
|
||
| bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Check *check, const Token *argtok, MathLib::bigint *offset, int type) | ||
| { | ||
| if (!offset) | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved this check here since it would do all the work and then bailout if no output parameter was provided. |
||
| return false; | ||
| const CheckBufferOverrun *c = dynamic_cast<const CheckBufferOverrun *>(check); | ||
| if (!c) | ||
| return false; | ||
|
|
@@ -897,8 +898,6 @@ bool CheckBufferOverrun::isCtuUnsafeBufferUsage(const Check *check, const Token | |
| return false; | ||
| if (!indexTok->hasKnownIntValue()) | ||
| return false; | ||
| if (!offset) | ||
| return false; | ||
| *offset = indexTok->getKnownIntValue() * argtok->valueType()->typeSize(*c->mSettings); | ||
| return true; | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is my programming style.
If you call
addIncludePathsToList(fileList, pathNames).. both parameters by value (you can not see it's passed by reference looking at the call).. then that means theaddIncludePathsToListwill not modify pathNames.Since addIncludePathsToList modifies pathNames I think it's more explicit to write
addIncludePathsToList(fileList, &pathNames). You can see in the function call it might modify pathNames.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a coding style decision. This is about safety and proper C++. If the parameter is not optional you might pass a
nullptr(which we do but fortunately only is like three cases) and it will be dereferenced.If this would be our style than we would have to convert every modifying reference to a pointer and also add checking of the pointer to each and every call. That would be a mess and would probably also hurt performance in a big way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it a bit more this style doesn't really makes sense since you will only see this on the very first call and not subsequent ones in the chain.