Update cppcheck-htmlreport (#2494)

* Try to use double quotes consistently
* minor CSS consistency changes
* fix HTML errors
* fix a few JS issues and switch to `textContent`
* use `addEventListener` instead of the onload event
* use `querySelector` and `querySelectorAll`

Co-authored-by: XhmikosR <xhmikosr@gmail.com>
This commit is contained in:
Sebastian 2020-01-18 01:49:46 +01:00 committed by GitHub
parent 7c7b0e55ed
commit 103532bb03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 89 additions and 75 deletions

View File

@ -48,12 +48,12 @@ h1 {
} }
.inconclusive { .inconclusive {
background-color: #B6B6B4; background-color: #b6b6b4;
} }
.inconclusive2 { .inconclusive2 {
background-color: #B6B6B4; background-color: #b6b6b4;
border: 1px dotted black; border: 1px dotted #000;
display: inline-block; display: inline-block;
margin-left: 4px; margin-left: 4px;
} }
@ -71,8 +71,8 @@ div.verbose div.content {
margin: 4px; margin: 4px;
max-width: 40%; max-width: 40%;
white-space: pre-wrap; white-space: pre-wrap;
border: 1px solid black; border: 1px solid #000;
background-color: #FFFFCC; background-color: #ffffcc;
cursor: auto; cursor: auto;
} }
@ -121,14 +121,14 @@ div.verbose div.content {
} }
.highlighttable { .highlighttable {
background-color:white; background-color: #fff;
z-index: 10; z-index: 10;
position: relative; position: relative;
margin: -10 px; margin: -10 px;
} }
#content { #content {
background-color: white; background-color: #fff;
-webkit-box-sizing: content-box; -webkit-box-sizing: content-box;
-moz-box-sizing: content-box; -moz-box-sizing: content-box;
box-sizing: content-box; box-sizing: content-box;
@ -141,7 +141,7 @@ div.verbose div.content {
} }
#content_index { #content_index {
background-color: white; background-color: #fff;
-webkit-box-sizing: content-box; -webkit-box-sizing: content-box;
-moz-box-sizing: content-box; -moz-box-sizing: content-box;
box-sizing: content-box; box-sizing: content-box;
@ -155,7 +155,7 @@ div.verbose div.content {
.linenos { .linenos {
border-right: thin solid #aaa; border-right: thin solid #aaa;
color: lightgray; color: #d3d3d3;
padding-right: 6px; padding-right: 6px;
} }
@ -173,7 +173,7 @@ div.verbose div.content {
""" """
HTML_HEAD = """ HTML_HEAD = """
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
@ -182,62 +182,76 @@ HTML_HEAD = """
<style> <style>
%s %s
</style> </style>
<script language="javascript"> <script>
function getStyle(el,styleProp) { function getStyle(el, styleProp) {
var y;
if (el.currentStyle) if (el.currentStyle)
var y = el.currentStyle[styleProp]; y = el.currentStyle[styleProp];
else if (window.getComputedStyle) else if (window.getComputedStyle)
var y = document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp); y = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
return y; return y;
} }
function toggle() { function toggle() {
var el = this.expandable_content; var el = this.expandable_content;
var mark = this.expandable_marker; var mark = this.expandable_marker;
if (el.style.display == "block") {
if (el.style.display === "block") {
el.style.display = "none"; el.style.display = "none";
mark.innerHTML = "[+]"; mark.textContent = "[+]";
} else { } else {
el.style.display = "block"; el.style.display = "block";
mark.innerHTML = "[-]"; mark.textContent = "[-]";
} }
} }
function init_expandables() { function init_expandables() {
var elts = document.getElementsByClassName("expandable"); var elts = document.querySelectorAll(".expandable");
for (var i = 0; i < elts.length; i++) {
for (var i = 0, len = elts.length; i < len; i++) {
var el = elts[i]; var el = elts[i];
var clickable = el.getElementsByTagName("span")[0]; var clickable = el.querySelector("span");
var marker = clickable.getElementsByClassName("marker")[0]; var marker = clickable.querySelector(".marker");
var content = el.getElementsByClassName("content")[0]; var content = el.querySelector(".content");
var width = clickable.clientWidth - parseInt(getStyle(content, "padding-left")) - parseInt(getStyle(content, "padding-right")); var width = clickable.clientWidth - parseInt(getStyle(content, "padding-left")) - parseInt(getStyle(content, "padding-right"));
content.style.width = width + "px"; content.style.width = width + "px";
clickable.expandable_content = content; clickable.expandable_content = content;
clickable.expandable_marker = marker; clickable.expandable_marker = marker;
clickable.onclick = toggle; clickable.addEventListener("click", toggle);
} }
} }
function set_class_display(c, st) { function set_class_display(c, st) {
var elements = document.querySelectorAll('.' + c), var elements = document.querySelectorAll("." + c);
len = elements.length;
for (i = 0; i < len; i++) { for (var i = 0, len = elements.length; i < len; i++) {
elements[i].style.display = st; elements[i].style.display = st;
} }
} }
function toggle_class_visibility(id) { function toggle_class_visibility(id) {
var box = document.getElementById(id); var box = document.getElementById(id);
set_class_display(id, box.checked ? '' : 'none'); set_class_display(id, box.checked ? "" : "none");
} }
function toggle_all(){
var elts = document.getElementsByTagName("input"); function toggle_all() {
var elts = document.querySelectorAll("input");
for (var i = 1; i < elts.length; i++) { for (var i = 1; i < elts.length; i++) {
var el = elts[i]; var el = elts[i];
el.checked ? el.checked=false : el.checked=true; if (el.checked) {
el.checked = false;
} else {
el.checked = true;
}
toggle_class_visibility(el.id); toggle_class_visibility(el.id);
} }
} }
window.addEventListener("load", init_expandables);
</script> </script>
</head> </head>
<body onload="init_expandables()"> <body>
<div id="header"> <div id="header">
<h1>Cppcheck report - %s: %s </h1> <h1>Cppcheck report - %s: %s </h1>
</div> </div>
@ -254,21 +268,21 @@ HTML_FOOTER = """
</div> </div>
<div id="footer"> <div id="footer">
<p> <p>
Cppcheck %s - a tool for static C/C++ code analysis</br> Cppcheck %s - a tool for static C/C++ code analysis<br>
</br> <br>
Internet: <a href="http://cppcheck.net">http://cppcheck.net</a></br> Internet: <a href="http://cppcheck.net">http://cppcheck.net</a><br>
IRC: <a href="irc://irc.freenode.net/cppcheck">irc://irc.freenode.net/cppcheck</a></br> IRC: <a href="irc://irc.freenode.net/cppcheck">irc://irc.freenode.net/cppcheck</a><br>
</p> </p>
</div> </div>
</body> </body>
</html> </html>
""" """
HTML_ERROR = "<span class='error2'>&lt;--- %s</span>\n" HTML_ERROR = "<span class=\"error2\">&lt;--- %s</span>\n"
HTML_INCONCLUSIVE = "<span class='inconclusive2'>&lt;--- %s</span>\n" HTML_INCONCLUSIVE = "<span class=\"inconclusive2\">&lt;--- %s</span>\n"
HTML_EXPANDABLE_ERROR = "<div class='verbose expandable'><span class='error2'>&lt;--- %s <span class='marker'>[+]</span></span><div class='content'>%s</div></div>\n""" HTML_EXPANDABLE_ERROR = "<div class=\"verbose expandable\"><span class=\"error2\">&lt;--- %s <span class=\"marker\">[+]</span></span><div class=\"content\">%s</div></div>\n"""
HTML_EXPANDABLE_INCONCLUSIVE = "<div class='verbose expandable'><span class='inconclusive2'>&lt;--- %s <span class='marker'>[+]</span></span><div class='content'>%s</div></div>\n""" HTML_EXPANDABLE_INCONCLUSIVE = "<div class=\"verbose expandable\"><span class=\"inconclusive2\">&lt;--- %s <span class=\"marker\">[+]</span></span><div class=\"content\">%s</div></div>\n"""
# escape() and unescape() takes care of &, < and >. # escape() and unescape() takes care of &, < and >.
html_escape_table = { html_escape_table = {
@ -518,7 +532,7 @@ if __name__ == '__main__':
filename.split('/')[-1])) filename.split('/')[-1]))
for error in sorted(errors, key=lambda k: k['line']): for error in sorted(errors, key=lambda k: k['line']):
output_file.write("<a href='%s#line-%d'> %s %s</a>" % (data['htmlfile'], error['line'], error['id'], error['line'])) output_file.write("<a href=\"%s#line-%d\"> %s %s</a>" % (data['htmlfile'], error['line'], error['id'], error['line']))
output_file.write(HTML_HEAD_END) output_file.write(HTML_HEAD_END)
try: try:
@ -528,8 +542,8 @@ if __name__ == '__main__':
lexer = guess_lexer(content) lexer = guess_lexer(content)
except ClassNotFound: except ClassNotFound:
sys.stderr.write("ERROR: Couldn't determine lexer for the file' " + source_filename + " '. Won't be able to syntax highlight this file.") sys.stderr.write("ERROR: Couldn't determine lexer for the file' " + source_filename + " '. Won't be able to syntax highlight this file.")
output_file.write("\n <tr><td colspan='5'> Could not generated content because pygments failed to retrieve the determine code type.</td></tr>") output_file.write("\n <tr><td colspan=\"5\"> Could not generate content because pygments failed to determine the code type.</td></tr>")
output_file.write("\n <tr><td colspan='5'> Sorry about this.</td></tr>") output_file.write("\n <tr><td colspan=\"5\"> Sorry about this.</td></tr>")
continue continue
if options.source_encoding: if options.source_encoding:
@ -572,7 +586,7 @@ if __name__ == '__main__':
except IndexError: except IndexError:
cnt_min = 0 cnt_min = 0
stat_fmt = "\n <tr><td><input type='checkbox' onclick='toggle_class_visibility(this.id)' id='{}' name='{}' checked></td><td>{}</td><td>{}</td></tr>" stat_fmt = "\n <tr><td><input type=\"checkbox\" onclick=\"toggle_class_visibility(this.id)\" id=\"{}\" name=\"{}\" checked></td><td>{}</td><td>{}</td></tr>"
for occurrences in reversed(range(cnt_min, cnt_max + 1)): for occurrences in reversed(range(cnt_min, cnt_max + 1)):
for _id in [k for k, v in sorted(counter.items()) if v == occurrences]: for _id in [k for k, v in sorted(counter.items()) if v == occurrences]:
stat_html.append(stat_fmt.format(_id, _id, dict(counter.most_common())[_id], _id)) stat_html.append(stat_fmt.format(_id, _id, dict(counter.most_common())[_id], _id))
@ -591,16 +605,16 @@ if __name__ == '__main__':
output_file.write('\n <tr><th>Line</th><th>Id</th><th>CWE</th><th>Severity</th><th>Message</th></tr>') output_file.write('\n <tr><th>Line</th><th>Id</th><th>CWE</th><th>Severity</th><th>Message</th></tr>')
for filename, data in sorted(files.items()): for filename, data in sorted(files.items()):
if filename in decode_errors: # don't print a link but a note if filename in decode_errors: # don't print a link but a note
output_file.write("\n <tr><td colspan='5'>%s</td></tr>" % (filename)) output_file.write("\n <tr><td colspan=\"5\">%s</td></tr>" % (filename))
output_file.write("\n <tr><td colspan='5'> Could not generated due to UnicodeDecodeError</td></tr>") output_file.write("\n <tr><td colspan=\"5\"> Could not generated due to UnicodeDecodeError</td></tr>")
else: else:
if filename.endswith('*'): # assume unmatched suppression if filename.endswith('*'): # assume unmatched suppression
output_file.write( output_file.write(
"\n <tr><td colspan='5'>%s</td></tr>" % "\n <tr><td colspan=\"5\">%s</td></tr>" %
(filename)) (filename))
else: else:
output_file.write( output_file.write(
"\n <tr><td colspan='5'><a href='%s'>%s</a></td></tr>" % "\n <tr><td colspan=\"5\"><a href=\"%s\">%s</a></td></tr>" %
(data['htmlfile'], filename)) (data['htmlfile'], filename))
for error in sorted(data['errors'], key=lambda k: k['line']): for error in sorted(data['errors'], key=lambda k: k['line']):
@ -614,7 +628,7 @@ if __name__ == '__main__':
try: try:
if error['cwe']: if error['cwe']:
cwe_url = "<a href='https://cwe.mitre.org/data/definitions/" + error['cwe'] + ".html'>" + error['cwe'] + "</a>" cwe_url = "<a href=\"https://cwe.mitre.org/data/definitions/" + error['cwe'] + ".html\">" + error['cwe'] + "</a>"
except KeyError: except KeyError:
cwe_url = "" cwe_url = ""
@ -686,7 +700,7 @@ if __name__ == '__main__':
continue continue
except KeyError: except KeyError:
continue continue
stats_file.write("<p>Top 10 files for " + sev + " severity, total findings: " + str(_sum) + "</br>\n") stats_file.write("<p>Top 10 files for " + sev + " severity, total findings: " + str(_sum) + "<br>\n")
# sort, so that the file with the most severities per type is first # sort, so that the file with the most severities per type is first
stats_list_sorted = sorted(stats_templist.items(), key=operator.itemgetter(1, 0), reverse=True) stats_list_sorted = sorted(stats_templist.items(), key=operator.itemgetter(1, 0), reverse=True)
@ -699,7 +713,7 @@ if __name__ == '__main__':
if (it == 0): if (it == 0):
LENGTH = len(str(i[1])) # <- length of longest number, now get the difference and try to make other numbers align to it LENGTH = len(str(i[1])) # <- length of longest number, now get the difference and try to make other numbers align to it
stats_file.write("&#160;" * 3 + str(i[1]) + "&#160;" * (1 + LENGTH - len(str(i[1]))) + "<a href=\"" + files[i[0]]['htmlfile'] + "\"> " + i[0] + "</a></br>\n") stats_file.write("&#160;" * 3 + str(i[1]) + "&#160;" * (1 + LENGTH - len(str(i[1]))) + "<a href=\"" + files[i[0]]['htmlfile'] + "\"> " + i[0] + "</a><br>\n")
it += 1 it += 1
if (it == 10): # print only the top 10 if (it == 10): # print only the top 10
break break