| <!-- |
| The res/js/fuzzer.js file must be included before this file. |
| |
| This in an HTML Import-able file that contains the definition |
| of the following elements: |
| |
| <fuzzer-info-sk> |
| |
| This element will query /json/details for all of the detailed fuzz reports of a given file (passed in by query params) and displayed. |
| This may be further scoped by function, line number and fuzz-type (either binary or api) |
| |
| To use this file import it: |
| |
| <link href="/res/imp/fuzzer-info-sk.html" rel="import" /> |
| |
| Usage: |
| |
| <fuzzer-info-sk></fuzzer-info-sk> |
| |
| Properties: |
| category: String. |
| exclude: Array of String, all fuzzes that have one or more of these strings as a flag will not |
| be shown. This array must be sorted lexographically. |
| include: Array of String, all fuzzes must have one or more of these strings as a flag to be |
| shown. This array must be sorted lexographically. |
| |
| Methods: |
| None. |
| |
| Events: |
| None. |
| --> |
| |
| <link rel="import" href="/res/imp/bower_components/iron-ajax/iron-ajax.html"> |
| <link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html"> |
| <link rel="import" href="/res/common/imp/url-params-sk.html"> |
| |
| <link rel="import" href="fuzzer-collapse-file-sk.html"> |
| <link rel="import" href="fuzzer-filter-sk.html"> |
| |
| <dom-module id="fuzzer-info-sk"> |
| <template> |
| <iron-ajax auto url="/json/details" |
| handle-as="json" |
| params="[[_urlParams]]" |
| last-response="{{_fuzzDetails}}"> |
| </iron-ajax> |
| |
| <template is="dom-repeat" items="[[_filteredFileDetails]]" as="file" sort="_byCount" filter="_excludeEmpty"> |
| <fuzzer-collapse-file-sk file="{{file}}" |
| category="[[category]]" |
| expand="[[_shouldExpand()]]"> |
| </fuzzer-collapse-file-sk> |
| </template> |
| <template is="dom-if" if="[[_isEmpty]]"> |
| <div>No results found (or server is still loading). Try refreshing this page later or adjusting your filters.</div> |
| </template> |
| |
| </template> |
| |
| <script> |
| Polymer({ |
| is: 'fuzzer-info-sk', |
| |
| properties: { |
| architecture: { |
| type: String, |
| value: function() { |
| return []; |
| } |
| }, |
| category: { |
| type: String, |
| value: "", |
| }, |
| include: { |
| type: Array, |
| value: function() { |
| return []; |
| } |
| }, |
| exclude: { |
| type: Array, |
| value: function() { |
| return []; |
| } |
| }, |
| _fuzzDetails: { |
| type: Array, |
| value: function() { |
| return []; |
| }, |
| }, |
| _filteredFileDetails: { |
| type: Array, |
| computed: "_filter(_fuzzDetails, architecture.*, include.*, exclude.*)", |
| }, |
| _isEmpty: { |
| type: Boolean, |
| computed: "_empty(_filteredFileDetails)", |
| }, |
| _urlParams: { |
| type: String, |
| computed: "_getURLParams(category)", |
| }, |
| }, |
| |
| _byCount: function(a, b) { |
| // Higher counts come first |
| return b.count - a.count; |
| }, |
| |
| _excludeEmpty: function(a) { |
| return a.count; |
| }, |
| |
| _empty: function(a) { |
| return !a || !a.length; |
| }, |
| |
| _filter: function(fuzzDetails){ |
| if (this._empty(fuzzDetails)) { |
| return []; |
| } |
| var exclude = this.exclude || []; |
| var include = this.include || []; |
| var architecture = this.architecture || []; |
| var fileDetails = this._group(fuzzDetails); |
| |
| // make a fresh copy of the data. This way, we can just completely replace the array |
| // without having to do Polymer's special array manipulation. |
| var retVal = JSON.parse(JSON.stringify(fileDetails)); |
| |
| retVal.forEach(function(file){ |
| var fileCount = 0; |
| file.byFunction.forEach(function(func) { |
| var funcCount = 0; |
| func.byLineNumber.forEach(function(line) { |
| line.reports = line.reports.filter(function(report) { |
| if (architecture.length > 0 && architecture.indexOf(report.architecture) === -1) { |
| return false; |
| } |
| for (let flags of Object.values(report.flags)) { |
| if (sk.sharesElement(exclude, flags)) { |
| return false; |
| } |
| } |
| if (include.length === 0) { |
| return true; |
| } |
| let sharedSomething = false; |
| for (let flags of Object.values(report.flags)) { |
| if (sk.sharesElement(include, flags)) { |
| sharedSomething = true; |
| } |
| } |
| return sharedSomething; |
| }); |
| line.count = line.reports.length; |
| funcCount += line.count; |
| }); |
| func.count = funcCount; |
| fileCount += funcCount |
| }); |
| file.count = fileCount; |
| }); |
| return retVal; |
| }, |
| |
| _getURLParams: function(category) { |
| return { |
| "category": category, |
| "file": fuzzer.paramFromPath("file"), |
| "func": fuzzer.paramFromPath("func"), |
| "line": fuzzer.paramFromPath("line"), |
| "name": fuzzer.paramFromPath("name"), |
| // TODO(kjlubick) Maybe make this user changeable |
| "badOrGrey": "bad", |
| }; |
| }, |
| |
| _group: function(fuzzes) { |
| var files = {}; |
| // files is a flat array of fuzzes. We want to turn it into an array |
| // of objects like: |
| // { |
| // fileName: String, |
| // count: Integer, |
| // byFunction: Array<{ |
| // functionName: String, |
| // count: Integer, |
| // byLineNumber: Array<{ |
| // lineNumber: Integer, |
| // count: Integer, |
| // reports: Array<Fuzz> |
| // }> |
| // }> |
| // } |
| // where Fuzz is the original object given to us by the server. See |
| // fuzzer-collapse-details-sk for the Fuzz schema. |
| |
| // First we group up the fuzzes by file, func, and line number |
| fuzzes.forEach(function(f){ |
| var file = f.fileName || "UNKNOWN"; |
| var func = f.functionName || "UNKNOWN"; |
| var line = f.lineNumber || -1; |
| if (!files[file]) { |
| files[file] = {}; |
| } |
| if (!files[file][func]) { |
| files[file][func] = {}; |
| } |
| if (!files[file][func][line]) { |
| files[file][func][line] = []; |
| } |
| files[file][func][line].push(f) |
| }); |
| |
| // Take the object and put it into arrays, so Polymer can use dom-repeats. |
| var fileData = []; |
| for (var file in files) { |
| var funcs = files[file]; |
| var byFunction = []; |
| for (var func in funcs) { |
| var lines = funcs[func]; |
| var byLineNumber = []; |
| for (line in lines) { |
| byLineNumber.push({ |
| count: 0, |
| lineNumber: line, |
| reports: lines[line], |
| }); |
| } |
| byFunction.push({ |
| count: 0, |
| functionName: func, |
| byLineNumber: byLineNumber, |
| }); |
| } |
| fileData.push({ |
| count: 0, |
| fileName: file, |
| byFunction: byFunction, |
| }) |
| } |
| |
| return fileData; |
| }, |
| |
| _shouldExpand: function(){ |
| return fuzzer.paramFromPath("file").length > 0 || fuzzer.paramFromPath("name").length > 0; |
| }, |
| }); |
| </script> |
| </dom-module> |