-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
Added sanity checks before allocating memory after reads #3765
base: master
Are you sure you want to change the base?
Conversation
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.
Thanks for the PR @0sidharth
This is just a partial review, since I feel a lot of the code needs minor tweaking.
EDIT: Do check the errors on the CI
recognition/include/pcl/recognition/dense_quantized_multi_mod_template.h
Outdated
Show resolved
Hide resolved
io/include/pcl/compression/impl/organized_pointcloud_compression.hpp
Outdated
Show resolved
Hide resolved
I looked quickly at the style guide, but there are no mentioning of how sanity checks should generally be implemented. but I would suggest in stead of the following: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename real> void
pcl::BivariatePolynomialT<real>::readBinary (std::istream& os)
{
memoryCleanUp ();
os.read (reinterpret_cast<char*> (&this->degree), sizeof (int));
unsigned int paramCnt = getNoOfParametersFromDegree (this->degree);
parameters = new real[paramCnt];
os.read (reinterpret_cast<char*> (&(*this->parameters)), paramCnt * sizeof (real));
if (os.bad())
{
PCL_THROW_EXCEPTION (pcl::IOException, "Failure in reading degree from file");
}
else if (os.fail())
{
PCL_THROW_EXCEPTION (pcl::IOException, "failbit set while reading degree (formatting or extraction error");
}
else
{
unsigned int paramCnt = getNoOfParametersFromDegree (this->degree);
parameters = new real[paramCnt];
os.read (reinterpret_cast<char*> (&(*this->parameters)), paramCnt * sizeof (real));
}
} write it like this: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename real> void
pcl::BivariatePolynomialT<real>::readBinary (std::istream& os)
{
memoryCleanUp ();
os.read (reinterpret_cast<char*> (&this->degree), sizeof (int));
// Missing a check here on degree?
unsigned int paramCnt = getNoOfParametersFromDegree (this->degree);
parameters = new real[paramCnt];
os.read (reinterpret_cast<char*> (&(*this->parameters)), paramCnt * sizeof (real));
if (os.bad())
{
PCL_THROW_EXCEPTION (pcl::IOException, "Failure in reading degree from file");
}
if (os.fail())
{
PCL_THROW_EXCEPTION (pcl::IOException, "failbit set while reading degree (formatting or extraction error");
}
unsigned int paramCnt = getNoOfParametersFromDegree (this->degree);
parameters = new real[paramCnt];
os.read (reinterpret_cast<char*> (&(*this->parameters)), paramCnt * sizeof (real));
} I'm sure if there are any advantages writing two ifs after each other over, if-else - but I guess the two errors are not necessarily dependent on each other or related, so I think it gives better clarity that they are seperated. It is ofc. the same Genereally I don't think we need the last else clauses. If one of the errors are true, an exception is thrown. If not, we can continue execution the following code. but in the end its a "style" and I just skimmed it quickly, but generally I think it looks good. |
@kunaltyagi would it make sense to check (not sure what can be checked for though) the istream object in top of the method - before reading anything? |
Just quickly looked istream - maybe use good instead? EDIT: It also checks if EOF was reached, so not sure if it would be set, if it is a last variable that is read or it is only set if you try to read beyond the file. Edit2: Its also possible to use ! - which is synonym for fail, which checks both fail and bad bit. Depends if we want detailed description if it was either bad or fail - whatever the differences can be here. |
@larshg I had considered |
@kunaltyagi I looked over the CI errors, but couldn't find errors related to my code or specific lines where formatting fails. As for build, it is building on my Ubuntu 16.04, I don't understand why it is failing on 19.10 from the error message. Could you or any other maintainers guide me on what to do regarding these? |
@0sidharth Okay :) Well, its nice to get it more unified then! |
For the CI:
Using
The incoming stream is assumed to be working, just like elsewhere in PCL (eg: |
if (os.bad())
{
PCL_THROW_EXCEPTION (pcl::IOException, "Failure in reading degree from file");
}
if (os.fail())
{
PCL_THROW_EXCEPTION (pcl::IOException, "failbit set while reading degree (formatting or extraction error");
} If we are going to repeat this in many places, it's maybe worth adding a specialized macro. Something like PCL_CHECK_IO_STREAM(os, "degree") |
@taketwo Currently I have implemented a function to do the same, should I change it to a macro? |
Hmm. I think I do prefer a function rather than a macro. But it don't think it needs to be a static function of |
I know, macros are "bad", but I think in this case they are justified. I'm absolutely open to other suggestions, though. |
In light of this I yield my original position in favor of the macro. |
Alright, I have changed it from a function to a macro, please review it. |
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.
Partially reviewed, but some points mentioned are present in multiple of the files touched.
io/include/pcl/compression/impl/octree_pointcloud_compression.hpp
Outdated
Show resolved
Hide resolved
@0sidharth don't force push until the review is over. If you force push GitHub is no longer able to show reviewers only the subset of changes which were added and we need to check everything again. Not very time efficient. You should only force push after the reviews are complete, if we ask you to squash commits or rebase with master. |
io/include/pcl/compression/impl/organized_pointcloud_compression.hpp
Outdated
Show resolved
Hide resolved
recognition/include/pcl/recognition/dense_quantized_multi_mod_template.h
Outdated
Show resolved
Hide resolved
recognition/include/pcl/recognition/face_detection/face_common.h
Outdated
Show resolved
Hide resolved
recognition/include/pcl/recognition/face_detection/face_common.h
Outdated
Show resolved
Hide resolved
Changeset looks good, structurally. Only a few topical issues need to be addressed. |
… 0 except for some cases
recognition/include/pcl/recognition/dense_quantized_multi_mod_template.h
Outdated
Show resolved
Hide resolved
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.
LGTM. Waiting on sergio
Other stuff to have a look first. You'll need to wait. |
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.
Overall LGTM. We just need to address this new type of Exception which I believe to be necessary when some of the parsed values don't make sense.
|
||
if (point_diff_color_data_vector_size < 0) | ||
{ | ||
PCL_THROW_EXCEPTION (pcl::IOException, "Error! Size of pointDiffColorDataVector specified in the file is negative!"); |
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 exception is complaining about a bad/incorrect numerical value. It's not really an IO issue anymore. This is the wrong type of exception to throw in this situation, but unfortunately I don't see an existing PCL Exception which matches what we would likely want to express here. Maybe BadArgumentException
? Otherwise I'm open to create a new exception type and I'm looking for suggestions on a name which better expresses what is happening here.
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.
I don't think BadArgumentException
is suited for this situation. Perhaps a new exception BadValueInFileException
?
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.
Maybe just BadValue
so that it can be used in other contexts.
io/include/pcl/compression/impl/organized_pointcloud_compression.hpp
Outdated
Show resolved
Hide resolved
recognition/include/pcl/recognition/face_detection/face_common.h
Outdated
Show resolved
Hide resolved
Should we add multiple modules in the label for PR like this? |
I believe the usual policy is to not add anything if it touches a lot of modules. If they're low in number feel free to. |
…anity checks when encountering bad value
for (auto sub_node_index : sub_nodes) | ||
{ | ||
sub_nodes[sub_node_index].serialize (stream); | ||
sub_node_index.serialize (stream); |
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.
Use auto&
or const auto&
depending on context (L120, L165). There's no need for making extra copies.
Pinging for updates |
Aims to fix #3606 . Went through the 273 instances and added sanity checks. Many of these instances already had sanity checks and all of them vary a lot, so I have adapted what I thought would be optimal for the ones that did not have any checks. It's my first PR in PCL, so please point out any miscellaneous mistakes too.