This is an archive of the discontinued LLVM Phabricator instance.

[clang-tidy] New misc-istream-overflow check
AbandonedPublic

Authored by cryptoad on Feb 10 2017, 11:07 AM.

Details

Summary

This is a new check for a somewhat obscure istream::operator>> behavior, when
the destination is a character array. Characters will be copied to the
destination until a separator is found, with no regard for the size of the
destination. In order to prevent a potential overflow, one would have to
set the width property of the stream via width() or std::setw(), and keep in
mind that the width is reset to 0 after each operator>> call.

With this check, we attempt to assess that istream::operator>> is used
properly, setting a width prior to the call when needed, and if sizes can be
deduced, make sure they are consistent.

Event Timeline

cryptoad created this revision.Feb 10 2017, 11:07 AM

Please mention this check in docs/ReleaseNotes.rst (in alphabetical order).

docs/clang-tidy/checks/misc-istream-overflow.rst
7

Please highlight language constructs with ``. Same below.

29

Please use .. code-block:: c++. See other checks documentation as example. Same below.

Eugene.Zelenko set the repository for this revision to rL LLVM.
Eugene.Zelenko added subscribers: Prazek, cfe-commits.

Nice check! :)

clang-tidy/misc/IstreamOverflowCheck.cpp
60–62

same here

79–81

debug?

112–117

please remove unnecessary braces

126–133

same here

cryptoad marked 5 inline comments as done.Feb 10 2017, 1:17 PM
cryptoad added inline comments.
clang-tidy/misc/IstreamOverflowCheck.cpp
79–81

Oops!
I'd like to somehow keep that in there (for debug purposes). Any preferred way> (ifdef DEBUG or other).

cryptoad updated this revision to Diff 88047.Feb 10 2017, 1:17 PM

Addressing first batch of comments.

cryptoad updated this revision to Diff 88048.Feb 10 2017, 1:19 PM

Missing line separators.

Shouldn't this be a path sensitive check within the clang static analyzer instead? So branches are properly handled and interprocedural analysis is done.

Shouldn't this be a path sensitive check within the clang static analyzer instead? So branches are properly handled and interprocedural analysis is done.

Do you have some examples? I would argue, that even if you would have code that firstly uses width(), and then after a while reads input, then this is bugprone, and probably the line initializing width should be just before reading.

Shouldn't this be a path sensitive check within the clang static analyzer instead? So branches are properly handled and interprocedural analysis is done.

Do you have some examples? I would argue, that even if you would have code that firstly uses width(), and then after a while reads input, then this is bugprone, and probably the line initializing width should be just before reading.

You are right, reasonable code sets the width right before reading the input. But do we only want to catch bugs in reasonable code?

Shouldn't this be a path sensitive check within the clang static analyzer instead? So branches are properly handled and interprocedural analysis is done.

Do you have some examples? I would argue, that even if you would have code that firstly uses width(), and then after a while reads input, then this is bugprone, and probably the line initializing width should be just before reading.

You are right, reasonable code sets the width right before reading the input. But do we only want to catch bugs in reasonable code?

We will catch bugs in resonable and not resonable code. But because clang-tidy is a linter, we will also warn about cases that might be valid, but looks buggy, making code resonable.
We won't gonna have any false negatives (missed bugs), we only can have more false positives (warnings about correct code), but because it is linter, it totally make sense to warn about these cases.

aaron.ballman edited edge metadata.Feb 12 2017, 5:50 AM

Shouldn't this be a path sensitive check within the clang static analyzer instead? So branches are properly handled and interprocedural analysis is done.

I agree; I think this check should be part of the static analyzer because it is path sensitive if we want it to be particularly useful. As it stands now, it will catch trivial bugs, but by designing it as a clang-tidy check, it isn't easily extensible to catch the bigger bugs across procedures.

alexfh requested changes to this revision.Feb 12 2017, 2:41 PM

Shouldn't this be a path sensitive check within the clang static analyzer instead? So branches are properly handled and interprocedural analysis is done.

I agree; I think this check should be part of the static analyzer because it is path sensitive if we want it to be particularly useful. As it stands now, it will catch trivial bugs, but by designing it as a clang-tidy check, it isn't easily extensible to catch the bigger bugs across procedures.

I totally agree with Aaron and Gabor. This analysis can't be properly implemented without path sensitivity and I can imagine many valid situations where it will be too noisy (custom functions or stream manipulators that hide width setting, for example). Clang-tidy has a bunch of lint-style analyses, but when there is a more appropriate technology to implement a certain analysis, it should be preferred. It's all trade-offs, but here path sensitive analysis seems to be a much better tool for the job.

This revision now requires changes to proceed.Feb 12 2017, 2:41 PM

So if I understand correctly, the consensus is to abandon this and rewrite it to be part of the clang static analyzer?

So if I understand correctly, the consensus is to abandon this and rewrite it to be part of the clang static analyzer?

That's correct.

cryptoad abandoned this revision.Feb 13 2017, 7:55 AM