320d98709f
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}
123 lines
3.7 KiB
JavaScript
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);
|
|
}
|
|
})();
|