![]() |
PVS-Studio VS Chromium
Good has won this time. To be more exact, source codes of the Chromium project have won. Chromium is one of the best projects we have checked with PVS-Studio.
Chromium is an open-source web-browser developed by Google and intended to provide users with fast and safe Internet access. Chromium serves as the base for the Google Chrome browser. Moreover, Chromium is a preliminary version of Google Chrome as well as some other alternative web-browsers. From the programming viewpoint, Chromium is a solution consisting of 473 projects. The general size of the source C/C++ code is about 460 Mbytes and the number of lines is difficult to count. These 460 Mbytes include a lot of various libraries. If you exclude them, you will have about 155 Mbytes. It is much less but still a lot of lines. Moreover, everything is relative, you know. Many of these libraries were created by the Chromium developers within the task of creating Chromium itself. Although such libraries live by themselves, still we may refer them to the browser. Chromium had become the most quality and large project I have studied during testing of PVS-Studio. While handling the Chromium project it was not actually clear to us what was checking what: we have found and fixed several errors in PVS-Studio related to C++ file analysis and support of a specific project's structure. Many aspects and methods used in Chromium show the quality of its source code. For instance, most programmers determine the number of items in an array using the following construct: Code:
int XX[] = { 1, 2, 3, 4 };Code:
#define count_of(arg) (sizeof(arg) / sizeof(arg[0]))Code:
void Test(int C[3])But if you apply by accident count_of() to a pointer, the result will be a meaningless value. The issue is that the macro will not produce any warning for the programmer about a strange construct of the count_of(B) sort. This situation seems farfetched and artificial but I had encountered it in various applications. For example, consider this code from the Miranda IM project: Code:
#define SIZEOF(X) (sizeof(X)/sizeof(X[0]))Code:
void Test(int C[3])Code:
void Test(int (&C)[3])Let's return to Chromium. It uses a macro that allows you to avoid the above described errors. This is how it is implemented: Code:
template <typename T, size_t N>If you have gone crazy because of all this, just take my word for it - it works. And it works much better than the 'count_of()' macro we have discussed above. Since the ArraySizeHelper function takes an array by the reference, you cannot pass a simple pointer to it. Let's write a test code: Code:
template <typename T, size_t N>Let me give you one more sample which is of a different sort yet it shows the quality of the code as well. Code:
if (!file_util::Delete(db_name, false) &&Well, and what about the check by PVS-Studio? Chromium's code is perhaps the most quality code I've ever seen. This is confirmed by the low density of errors we've managed to find. If you take their quantity in general, there are certainly plenty of them. But if you divide the number of errors by the amount of code, it turns out that there are almost no errors. What are these errors? They are the most ordinary ones. Here are several samples: Code:
V512 A call of the 'memset' function will lead to underflow of the buffer '(exploded)'. platform time_win.cc 116Code:
void NaCl::Time::Explode(bool is_local, Exploded* exploded) const {Code:
V502 Perhaps the '?:' operator works in a different way than it was expected. The '?:' operator has a lower priority than the '-' operator. views custom_frame_view.cc 400Code:
static const int kClientEdgeThickness;Code:
int edge_height = titlebar_bottom->height() -Code:
V547 Expression 'count < 0' is always false. Unsigned type value is never < 0. ncdecode_tablegen ncdecode_tablegen.c 197Code:
static void CharAdvance(char** buffer, size_t* buffer_size, size_t count) {Code:
V511 The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof (salt)' expression. common visitedlink_common.cc 84Code:
void MD5Update(MD5Context* context, const void* buf, size_t len);The correct code should look this way: Code:
MD5Update(&ctx, salt, sizeof(salt[0]) * LINK_SALT_LENGTH);Code:
VisitedLinkCommon::Fingerprint VisitedLinkCommon::ComputeURLFingerprint(Code:
V501 There are identical sub-expressions 'host != buzz::XmlConstants::str_empty ()' to the left and to the right of the '&&' operator. chromoting_jingle_glue iq_request.cc 248Code:
void JingleInfoRequest::OnResponse(const buzz::XmlElement* stanza) {Code:
if (host != buzz::STR_EMPTY && port_str != buzz::STR_EMPTY) {Code:
V530 The return value of function 'empty' is required to be utilized. chrome_frame_npapi np_proxy_service.cc 293Code:
bool NpProxyService::GetProxyValueJSONString(std::string* output) {And here is even the handling of a null pointer: Code:
V522 Dereferencing of the null pointer 'plugin_instance' might take place. Check the logical condition. chrome_frame_npapi chrome_frame_npapi.cc 517Code:
bool ChromeFrameNPAPI::Invoke(...)Code:
V547 Expression 'current_idle_time < 0' is always false. Unsigned type value is never < 0. browser idle_win.cc 23Code:
IdleState CalculateIdleState(unsigned int idle_threshold) {Code:
V554 Incorrect use of auto_ptr. The memory allocated with 'new []' will be cleaned using 'delete'. interactive_ui_tests accessibility_win_browsertest.cc 306Code:
void AccessibleChecker::CheckAccessibleChildren(IAccessible* parent) {Code:
V547 Expression '* string != 0 || * string != '_'' is always true. Probably the '&&' operator should be used here. icui18n ucol_sit.cpp 242Code:
U_CDECL_BEGIN static const char* U_CALLCONVConclusionPVS-Studio was defeated. Chromium's source code is one of the best we have ever analyzed. We have found almost nothing in Chromium. To be more exact, we have found a lot of errors and this article demonstrates only a few of them. But if we keep in mind that all these errors are spread throughout the source code with the size of 460 Mbytes, it turns out that there are almost no errors at all. P.S. I'm answering to the question: will we inform the Chromium developers of the errors we've found? No, we won't. It is a very large amount of work and we cannot afford doing it for free. Checking Chromium is far from checking Miranda IM or checking Ultimate Toolbox. This is a hard work, we have to study all of the messages and make a decision whether there is an error in every particular case. To do that, we must be knowledgeable about the project. We will this article to the Chromium developers, and should they find it interesting, they will be able to analyze the project themselves and study all the diagnostic messages. Yes, they will have to purchase PVS-Studio for this purpose. But any Google department can easily afford this. |
Re: PVS-Studio VS Chromium
simply an awesome run though of the thing
got ma fullest attension + i once saw a little of the Chromium, but never thought of analyzing because the sight drew me all crazy :) good work :D |
Re: PVS-Studio VS Chromium
Just in case, I want to remind you that the article describes only some of the suspicious places in code. The analysis of the full PVS-Studio report is a huge task and it's better to be performed by the developers themselves. I will now cite some additional suspicious fragments from Chromium and it's libraries:
Code:
V564 The '&' operator is applied to bool type value. You've probably forgotten to include parentheses or intended to use the '&&' operator. base platform_file_win.cc 216 |
Re: PVS-Studio VS Chromium
|
| All times are GMT +5.5. The time now is 14:08. |