v8/tools/clusterfuzz/js_fuzzer/resources/differential_fuzz_library.js
Michael Achenbach 320d98709f Open source js-fuzzer
This is a JavaScript fuzzer originally authored by Oliver Chang. It
is a mutation based fuzzer using Babel code transformations. For more
information see the included README.md.

The original code was altered:
- Add new V8 copyright headers.
- Make the test expectation generator aware of the headers.
- Fix file endings for presubmit checks.
- Fix `npm test` on fresh checkout with a new fake DB.
- Make test skipping work with new v8/tools location.
- OWNERS file.
- New title section in README.md.

No-Try: true
Bug: chromium:1109770
Change-Id: Ie71752c0a37491a50500c49060a3c526716ef933
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2320330
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69164}
2020-07-31 11:34:39 +00:00

123 lines
3.7 KiB
JavaScript

// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Helpers for printing in correctness fuzzing.
// Global helper functions for printing.
var __prettyPrint;
var __prettyPrintExtra;
// Track caught exceptions.
var __caught = 0;
// Track a hash of all printed values - printing is cut off after a
// certain size.
var __hash = 0;
(function() {
const charCodeAt = String.prototype.charCodeAt;
const join = Array.prototype.join;
const map = Array.prototype.map;
const substring = String.prototype.substring;
const toString = Object.prototype.toString;
// Same as in mjsunit.js.
const classOf = function(object) {
// Argument must not be null or undefined.
const string = toString.call(object);
// String has format [object <ClassName>].
return substring.call(string, 8, string.length - 1);
};
// For standard cases use original prettyPrinted from mjsunit.
const origPrettyPrinted = prettyPrinted;
// Override prettyPrinted with a version that also recusively prints objects
// and arrays with a depth of 4. We don't track circles, but we'd cut off
// after a depth of 4 if there are any.
prettyPrinted = function prettyPrinted(value, depth=4) {
if (depth <= 0) {
return "...";
}
switch (typeof value) {
case "object":
if (value === null) return "null";
switch (classOf(value)) {
case "Array":
return prettyPrintedArray(value, depth);
case "Object":
return prettyPrintedObject(value, depth);
}
}
// Fall through to original version for all other types.
return origPrettyPrinted(value);
}
// Helper for pretty array with depth.
function prettyPrintedArray(array, depth) {
const result = map.call(array, (value, index, array) => {
if (value === undefined && !(index in array)) return "";
return prettyPrinted(value, depth - 1);
});
return `[${join.call(result, ", ")}]`;
}
// Helper for pretty objects with depth.
function prettyPrintedObject(object, depth) {
const keys = Object.keys(object);
const prettyValues = map.call(keys, (key) => {
return `${key}: ${prettyPrinted(object[key], depth - 1)}`;
});
const content = join.call(prettyValues, ", ");
return `${object.constructor.name || "Object"}{${content}}`;
}
// Helper for calculating a hash code of a string.
function hashCode(str) {
let hash = 0;
if (str.length == 0) {
return hash;
}
for (let i = 0; i < str.length; i++) {
const char = charCodeAt.call(str, i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return hash;
}
// Upper limit for calling extra printing. When reached, hashes of
// strings are tracked and printed instead.
let maxExtraPrinting = 100;
// Helper for pretty printing.
__prettyPrint = function(value, extra=false) {
let str = prettyPrinted(value);
// Change __hash with the contents of the full string to
// keep track of differences also when we don't print.
const hash = hashCode(str);
__hash = hashCode(hash + __hash.toString());
if (extra && maxExtraPrinting-- <= 0) {
return;
}
// Cut off long strings to prevent overloading I/O. We still track
// the hash of the full string.
if (str.length > 64) {
const head = substring.call(str, 0, 54);
const tail = substring.call(str, str.length - 10, str.length - 1);
str = `${head}[...]${tail}`;
}
print(str);
};
__prettyPrintExtra = function (value) {
__prettyPrint(value, true);
}
})();