Improve string parsing and JSON parsing (#316)

* Improve string parsing and JSON parsing

- fix JSON parsing of non ASCII string contents
- more precise string parsing errors
- more precise JSON parsing errors
- add `JS_ParseState::buf_start` to compute line/column
- fix HTML comment detection at start of source code
- improve v8 Failure messages (pulled and modified `formatFailureText` from **mjsunit.js**) 
- ignore more v8 tests
This commit is contained in:
Charlie Gordon 2024-03-22 11:19:36 +01:00 committed by GitHub
parent 3781c2a6db
commit 5e5b00c48c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 237 additions and 146 deletions

174
quickjs.c
View file

@ -18392,6 +18392,7 @@ typedef struct JSParseState {
JSToken token;
BOOL got_lf; /* true if got line feed before the current token */
const uint8_t *last_ptr;
const uint8_t *buf_start;
const uint8_t *buf_ptr;
const uint8_t *buf_end;
const uint8_t *eol; // most recently seen end-of-line character
@ -18671,13 +18672,17 @@ static __exception int js_parse_string(JSParseState *s, int sep,
break;
}
if (c == '\\') {
const uint8_t *p0 = p;
c = *p;
/* XXX: need a specific JSON case to avoid
accepting invalid escapes */
switch(c) {
case '\0':
if (p >= s->buf_end)
goto invalid_char;
if (p >= s->buf_end) {
if (sep != '`')
goto invalid_char;
if (do_throw)
js_parse_error(s, "Unexpected end of input");
goto fail;
}
p++;
break;
case '\'':
@ -18700,22 +18705,19 @@ static __exception int js_parse_string(JSParseState *s, int sep,
}
continue;
default:
if (c >= '0' && c <= '9') {
if (s->cur_func && !(s->cur_func->js_mode & JS_MODE_STRICT) && sep != '`')
goto parse_escape;
if (c == '0' && !(p[1] >= '0' && p[1] <= '9')) {
p++;
c = '\0';
} else {
if (c >= '8' || sep == '`') {
/* Note: according to ES2021, \8 and \9 are not
accepted in strict mode or in templates. */
goto invalid_escape;
}
if (do_throw)
js_parse_error(s, "octal escape sequences are not allowed in strict mode");
goto fail;
if (c == '0' && !(p[1] >= '0' && p[1] <= '9')) {
/* accept isolated \0 */
p++;
c = '\0';
} else
if ((c >= '0' && c <= '9')
&& ((s->cur_func->js_mode & JS_MODE_STRICT) || sep == '`')) {
if (do_throw) {
js_parse_error(s, "%s are not allowed in %s",
(c >= '8') ? "\\8 and \\9" : "Octal escape sequences",
(sep == '`') ? "template strings" : "strict mode");
}
goto fail;
} else if (c >= 0x80) {
const uint8_t *p_next;
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p_next);
@ -18727,10 +18729,13 @@ static __exception int js_parse_string(JSParseState *s, int sep,
if (c == CP_LS || c == CP_PS)
continue;
} else {
parse_escape:
ret = lre_parse_escape(&p, TRUE);
if (ret == -1) {
goto invalid_escape;
if (do_throw) {
js_parse_error(s, "Invalid %s escape sequence",
c == 'u' ? "Unicode" : "hexadecimal");
}
goto fail;
} else if (ret < 0) {
/* ignore the '\' (could output a warning) */
p++;
@ -18760,10 +18765,6 @@ static __exception int js_parse_string(JSParseState *s, int sep,
if (do_throw)
js_parse_error(s, "invalid UTF-8 sequence");
goto fail;
invalid_escape:
if (do_throw)
js_parse_error(s, "malformed escape sequence in string literal");
goto fail;
invalid_char:
if (do_throw)
js_parse_error(s, "unexpected end of string");
@ -19258,8 +19259,8 @@ static __exception int next_token(JSParseState *s)
p += 2;
s->token.val = TOK_MINUS_ASSIGN;
} else if (p[1] == '-') {
if (s->allow_html_comments &&
p[2] == '>' && s->last_line_num != s->line_num) {
if (s->allow_html_comments && p[2] == '>' &&
(s->got_lf || s->last_ptr == s->buf_start)) {
/* Annex B: `-->` at beginning of line is an html comment end.
It extends to the end of the line.
*/
@ -19439,6 +19440,23 @@ static __exception int next_token(JSParseState *s)
return -1;
}
static int json_parse_error(JSParseState *s, const uint8_t *curp, const char *msg)
{
const uint8_t *p, *line_start;
int position = curp - s->buf_start;
int line = 1;
for (line_start = p = s->buf_start; p < curp; p++) {
/* column count does not account for TABs nor wide characters */
if (*p == '\r' || *p == '\n') {
p += 1 + (p[0] == '\r' && p[1] == '\n');
line++;
line_start = p;
}
}
return js_parse_error(s, "%s in JSON at position %d (line %d column %d)",
msg, position, line, (int)(p - line_start) + 1);
}
static int json_parse_string(JSParseState *s, const uint8_t **pp)
{
const uint8_t *p = *pp;
@ -19451,14 +19469,13 @@ static int json_parse_string(JSParseState *s, const uint8_t **pp)
for(;;) {
if (p >= s->buf_end) {
js_parse_error(s, "Unexpected end of JSON input");
goto fail;
goto end_of_input;
}
c = *p++;
if (c == '"')
break;
if (c < 0x20) {
js_parse_error(s, "Bad control character in string literal in JSON");
json_parse_error(s, p - 1, "Bad control character in string literal");
goto fail;
}
if (c == '\\') {
@ -19476,16 +19493,28 @@ static int json_parse_string(JSParseState *s, const uint8_t **pp)
c = 0;
for(i = 0; i < 4; i++) {
int h = from_hex(*p++);
if (h < 0)
goto invalid_escape;
if (h < 0) {
json_parse_error(s, p - 1, "Bad Unicode escape");
goto fail;
}
c = (c << 4) | h;
}
break;
default:
invalid_escape:
js_parse_error(s, "Bad escaped character in JSON");
if (p > s->buf_end)
goto end_of_input;
json_parse_error(s, p - 1, "Bad escaped character");
goto fail;
}
} else
if (c >= 0x80) {
const uint8_t *p_next;
c = unicode_from_utf8(p - 1, s->buf_end - p, &p_next);
if (c > 0x10FFFF) {
json_parse_error(s, p - 1, "Bad UTF-8 sequence");
goto fail;
}
p = p_next;
}
if (string_buffer_putc(b, c))
goto fail;
@ -19496,6 +19525,8 @@ static int json_parse_string(JSParseState *s, const uint8_t **pp)
*pp = p;
return 0;
end_of_input:
js_parse_error(s, "Unexpected end of JSON input");
fail:
string_buffer_free(b);
return -1;
@ -19513,7 +19544,7 @@ static int json_parse_number(JSParseState *s, const uint8_t **pp)
return js_parse_error(s, "Unexpected token '%c'", *p_start);
if (p[0] == '0' && is_digit(p[1]))
return js_parse_error(s, "Unexpected number in JSON");
return json_parse_error(s, p, "Unexpected number");
while (is_digit(*p))
p++;
@ -19521,7 +19552,7 @@ static int json_parse_number(JSParseState *s, const uint8_t **pp)
if (*p == '.') {
p++;
if (!is_digit(*p))
return js_parse_error(s, "Unterminated fractional number in JSON");
return json_parse_error(s, p, "Unterminated fractional number");
while (is_digit(*p))
p++;
}
@ -19530,7 +19561,7 @@ static int json_parse_number(JSParseState *s, const uint8_t **pp)
if (*p == '+' || *p == '-')
p++;
if (!is_digit(*p))
return js_parse_error(s, "Exponent part is missing a number in JSON");
return json_parse_error(s, p, "Exponent part is missing a number");
while (is_digit(*p))
p++;
}
@ -19659,17 +19690,17 @@ static __exception int json_next_token(JSParseState *s)
s->token.u.ident.is_reserved = FALSE;
s->token.val = TOK_IDENT;
break;
case '+':
if (!is_digit(p[1]))
goto def_token;
case '-':
if (!is_digit(p[1])) {
json_parse_error(s, p, "No number after minus sign");
goto fail;
}
goto parse_number;
case '0':
if (is_digit(p[1]))
goto def_token;
goto parse_number;
case '-':
if (!is_digit(p[1]))
goto def_token;
if (is_digit(p[1])) {
json_parse_error(s, p, "Unexpected number");
goto fail;
}
goto parse_number;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8':
@ -19681,7 +19712,17 @@ static __exception int json_next_token(JSParseState *s)
break;
default:
if (c >= 128) {
js_parse_error(s, "unexpected character");
const uint8_t *p_next;
c = unicode_from_utf8(p, s->buf_end - p, &p_next);
if (c == -1) {
js_parse_error(s, "Unexpected token '\\x%02x' in JSON", *p);
} else {
if (c > 0xFFFF) {
/* get high surrogate */
c = (c >> 10) - (0x10000 >> 10) + 0xD800;
}
js_parse_error(s, "Unexpected token '\\u%04x' in JSON", c);
}
goto fail;
}
def_token:
@ -32017,7 +32058,7 @@ static void js_parse_init(JSContext *ctx, JSParseState *s,
s->filename = filename;
s->line_num = 1;
s->col_num = 1;
s->buf_ptr = (const uint8_t *)input;
s->buf_start = s->buf_ptr = (const uint8_t *)input;
s->buf_end = s->buf_ptr + input_len;
s->mark = s->buf_ptr + min_int(1, input_len);
s->eol = s->buf_ptr;
@ -42476,15 +42517,6 @@ void JS_AddIntrinsicRegExp(JSContext *ctx)
/* JSON */
static int json_parse_expect(JSParseState *s, int tok)
{
if (s->token.val != tok) {
/* XXX: dump token correctly in all cases */
return js_parse_error(s, "expecting '%c'", tok);
}
return json_next_token(s);
}
static JSValue json_parse_value(JSParseState *s)
{
JSContext *ctx = s->ctx;
@ -42509,12 +42541,16 @@ static JSValue json_parse_value(JSParseState *s)
if (prop_name == JS_ATOM_NULL)
goto fail;
} else {
js_parse_error(s, "expecting property name");
json_parse_error(s, s->token.ptr, "Expected property name or '}'");
goto fail;
}
if (json_next_token(s))
goto fail1;
if (json_parse_expect(s, ':'))
if (s->token.val != ':') {
json_parse_error(s, s->token.ptr, "Expected ':' after property name");
goto fail1;
}
if (json_next_token(s))
goto fail1;
prop_val = json_parse_value(s);
if (JS_IsException(prop_val)) {
@ -42528,13 +42564,17 @@ static JSValue json_parse_value(JSParseState *s)
if (ret < 0)
goto fail;
if (s->token.val != ',')
if (s->token.val == '}')
break;
if (s->token.val != ',') {
json_parse_error(s, s->token.ptr, "Expected ',' or '}' after property value");
goto fail;
}
if (json_next_token(s))
goto fail;
}
}
if (json_parse_expect(s, '}'))
if (json_next_token(s))
goto fail;
}
break;
@ -42549,22 +42589,24 @@ static JSValue json_parse_value(JSParseState *s)
if (JS_IsException(val))
goto fail;
if (s->token.val != ']') {
idx = 0;
for(;;) {
for(idx = 0;; idx++) {
el = json_parse_value(s);
if (JS_IsException(el))
goto fail;
ret = JS_DefinePropertyValueUint32(ctx, val, idx, el, JS_PROP_C_W_E);
if (ret < 0)
goto fail;
if (s->token.val != ',')
if (s->token.val == ']')
break;
if (s->token.val != ',') {
json_parse_error(s, s->token.ptr, "Expected ',' or ']' after array element");
goto fail;
}
if (json_next_token(s))
goto fail;
idx++;
}
}
if (json_parse_expect(s, ']'))
if (json_next_token(s))
goto fail;
}
break;

View file

@ -6,6 +6,20 @@
globalThis.failWithMessage = function(message) {
if (count > 99) return
if (++count > 99) return print("<output elided>")
print(String(message).slice(0, 128))
print(String(message).slice(0, 300))
}
globalThis.formatFailureText = function(expectedText, found, name_opt) {
var message = "Fail" + "ure"
if (name_opt) {
// Fix this when we ditch the old test runner.
message += " (" + name_opt + ")"
}
var foundText = prettyPrinted(found)
if (expectedText.length <= 60 && foundText.length <= 60) {
message += ": expected <" + expectedText + "> found <" + foundText + ">"
} else {
message += ":\nexpected:\n" + expectedText + "\nfound:\n" + foundText
}
return message
}
})()

17
v8.js
View file

@ -20,13 +20,17 @@ const exclude = [
"regexp-indexof.js", // deprecated RegExp.lastMatch etc.
"regexp-static.js", // deprecated RegExp static properties.
"string-replace.js", // unstable output
"omit-default-ctors-array-iterator.js",
"mjsunit-assertion-error.js",
"mjsunit.js",
"mjsunit-assertion-error.js",
"mjsunit-assert-equals.js",
"mjsunit_suppressions.js",
"verify-assert-false.js", // self check
"verify-check-false.js", // self check
"clone-ic-regression-crbug-1466315.js", // spurious output
]
let files = scriptArgs.slice(1) // run only these tests
@ -37,7 +41,7 @@ for (const file of files) {
if (exclude.includes(file)) continue
const source = std.loadFile(dir + "/" + file)
if (/^(im|ex)port/m.test(source)) continue // TODO support modules
if (source.includes('Realm.create()')) continue // TODO support Realm object
if (source.includes('Realm.create')) continue // TODO support Realm object
if (source.includes('// MODULE')) continue // TODO support modules
if (source.includes('// Files:')) continue // TODO support includes
@ -59,6 +63,15 @@ for (const file of files) {
}
// exclude tests that use V8 intrinsics like %OptimizeFunctionOnNextCall
if (flags["--allow-natives-syntax"]) continue
if (flags["--allow-natives-for-differential-fuzzing"]) continue
if (flags["--dump-counters"]) continue
if (flags["--expose-cputracemark"]) continue
if (flags["--harmony-rab-gsab"]) continue
if (flags["--harmony-class-fields"]) continue
if (flags["--enable-experimental-regexp-engine"]) continue
if (flags["--experimental-stack-trace-frames"]) continue
if (flags["--js-float16array"]) continue
if (flags["--expose-cputracemark-as"]) continue
// exclude tests that use V8 extensions
if (flags["--expose-externalize-string"]) continue
// parse environment variables

176
v8.txt
View file

@ -66,7 +66,10 @@ async function two(x) {
try {
x = await x;
throw new Error();
}
} catch (e) {
return e.stack;
}
}
=== async-stack-traces-prepare-stacktrace-3.js
=== async-stack-traces-prepare-stacktrace-4.js
=== big-array-literal.js
@ -324,11 +327,7 @@ Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
=== function-length-accessor.js
=== function-name-eval-shadowed.js
Failure:
expected:
200
found:
function f() { eval("var f = 100"); f = 200; return f }
Failure: expected <200> found <function f() { eval("var f = 100"); f = 200; return f }>
=== function-names.js
=== function-property.js
=== function-prototype.js
@ -336,14 +335,10 @@ function f() { eval("var f = 100"); f = 200; return f }
=== function-without-prototype.js
=== function.js
Failure: expected <"undefined"> found <"function">
Failure:
expected:
42
found:
function anonymous(
Failure: expected <42> found <function anonymous(
) {
return anonymous;
}
}>
=== fuzz-accessors.js
=== get-own-property-descriptor-non-objects.js
=== get-own-property-descriptor.js
@ -368,9 +363,6 @@ return anonymous;
=== hex-parsing.js
=== holy-double-no-arg-array.js
=== html-comments.js
SyntaxError: unexpected token in expression: '>'
at html-comments.js:1:1
=== html-string-funcs.js
=== icu-date-lord-howe.js TZ=Australia/Lord_Howe LC_ALL=en
Failure:
@ -443,12 +435,12 @@ Failure:
expected:
"Unexpected token \n in JSON at position 3"
found:
"Bad control character in string literal in JSON"
"Bad control character in string literal in JSON at position 3 (line 1 column 4)"
Failure:
expected:
"Unexpected token \n in JSON at position 3"
found:
"Bad control character in string literal in JSON"
"Bad control character in string literal in JSON at position 3 (line 1 column 4)"
=== json-parser-recursive.js
=== json-replacer-number-wrapper-tostring.js
=== json-replacer-order.js
@ -639,43 +631,17 @@ SyntaxError: invalid assignment left-hand side
=== spread-large-set.js
=== spread-large-string.js
=== stack-traces-2.js
=== stack-traces-class-fields.js
Failure (during class construction doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js:35:3)
at
Failure (during class construction contains unexpected[0]): expected <59> found <-1>
Failure (during class instantiation doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js:35:3)
a
Failure (during class instantiation doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js:35:3)
a
Failure (during class instantiation contains unexpected[0]): expected <59> found <-1>
Failure (during class instantiation with super doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js:
Failure (during class instantiation with super doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js:
Failure (during class instantiation with super contains unexpected[1]): expected <59> found <-1>
Failure (during class instantiation with super2 doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super2 doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super2 contains unexpected[1]): expected <59> found <-1>
Failure (during class instantiation with super3 doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super3 doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super3 doesn't contain expected[3] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super3 contains unexpected[0]): expected <59> found <-1>
Failure (during class field call doesn't contain expected[0] stack = at thrower (stack-traces-class-fields.js:35:3)
at t
Failure (during static class field call doesn't contain expected[0] stack = at thrower (stack-traces-class-fields.js:35:3)
Failure (during class field call with FNI doesn't contain expected[0] stack = at x (stack-traces-class-fields.js:208:7)
Failure (during static class field call with FNI doesn't contain expected[0] stack = at x (stack-traces-class-fields.js:230:
=== stack-traces-custom-lazy.js
Failure:
expected:
"bar"
found:
" at <anonymous> (stack-traces-custom-lazy.js:47:46)\n at testPrepareStackTrace (stack-tra
" at <anonymous> (stack-traces-custom-lazy.js:47:46)\n at testPrepareStackTrace (stack-traces-custom-lazy.js:31:5)\n at <eval> (stack-traces-custom-lazy.js:47:60)\n"
Failure:
expected:
"bar"
found:
" at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n
" at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js
=== stack-traces-custom.js
TypeError: not a function
at <eval> (stack-traces-custom.js:20:21)
@ -687,58 +653,118 @@ Failure: expected <undefined> found <"">
=== stack-traces.js
Failure (testArrayNative doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:48:31)
at map (native)
at testArrayNative (stack-traces.js:48:37)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:267:47)
): expected <true> found <false>
Failure (testMethodNameInference doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:30:37)
at testMetho
at testMethodNameInference (stack-traces.js:31:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:269:63)
): expected <true> found <false>
Failure (testImplicitConversion doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:53:42)
at testImplic
at testImplicitConversion (stack-traces.js:54:19)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:270:61)
): expected <true> found <false>
Failure (testEval doesn't contain expected[0] stack = at Doo (<input>:1:17)
at <eval> (<input>:1:26)
at testEval (st
at testEval (stack-traces.js:58:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:271:33)
): expected <true> found <false>
Failure (testNestedEval doesn't contain expected[0] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer
at Outer (<input>:1:58)
at <eval> (<input>:1:70)
at testNestedEval (stack-traces.js:63:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:272:45)
):
Failure (testEvalWithSourceURL doesn't contain expected[0] stack = at Doo (<input>:1:17)
at <eval> (<input>:1:26)
at
at testEvalWithSourceURL (stack-traces.js:67:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:274:34)
): expected <true> found <false>
Failure (testNestedEvalWithSourceURL doesn't contain expected[0] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:36)
at <eval> (<input>:1:48)
at testNestedEvalWithSourceURL (stack-traces.js:73:3)
at testTrace (stack-traces.js:162:5)
at <eval> (
Failure (testNestedEvalWithSourceURL doesn't contain expected[1] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:36)
at <eval> (<input>:1:48)
at testNestedEvalWithSourceURL (stack-traces.js:73:3)
at testTrace (stack-traces.js:162:5)
at <eval> (
Failure (testValue doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:77:47)
at testValue (stack-traces
at testValue (stack-traces.js:78:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:278:35)
): expected <true> found <false>
Failure (testConstructor doesn't contain expected[0] stack = at Plonk (stack-traces.js:82:22)
at testConstructor (stack-
at testConstructor (stack-traces.js:83:7)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:279:47)
): expected <true> found <false>
Failure (testRenamedMethod doesn't contain expected[0] stack = at a$b$c$d (stack-traces.js:87:31)
at testRenamedMethod (
at testRenamedMethod (stack-traces.js:90:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:280:51)
): expected <true> found <false>
Failure (testAnonymousMethod doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:94:18)
at call (native)
at testAnonymousMethod (stack-traces.js:94:38)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:281:55)
): expected <true> found <false>
Failure (testFunctionName doesn't contain expected[2] stack = at foo_0 (stack-traces.js:101:9)
at foo_1 (stack-traces.js
at foo_1 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at boo_3 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at testFunctionName (stack-traces
Failure (testFunctionName doesn't contain expected[4] stack = at foo_0 (stack-traces.js:101:9)
at foo_1 (stack-traces.js
at foo_1 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at boo_3 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at testFunctionName (stack-traces
Failure (testDefaultCustomError doesn't contain expected[0] stack = at CustomError (stack-traces.js:130:33)
at testDefau
at testDefaultCustomError (stack-traces.js:138:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:287:5)
): expected <true> found <false>
Failure (testDefaultCustomError doesn't contain expected[1] stack = at CustomError (stack-traces.js:130:33)
at testDefau
at testDefaultCustomError (stack-traces.js:138:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:287:5)
): expected <true> found <false>
Failure (testStrippedCustomError doesn't contain expected[0] stack = at CustomError (stack-traces.js:130:33)
at testStri
at testStrippedCustomError (stack-traces.js:142:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:289:25)
): expected <true> found <false>
Failure (testClassNames doesn't contain expected[0] stack = at MyObj (stack-traces.js:145:22)
at <anonymous> (stack-trac
at <anonymous> (stack-traces.js:150:14)
at testClassNames (stack-traces.js:154:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:291:49)
): expected <true> found <false>
Failure (testClassNames doesn't contain expected[1] stack = at MyObj (stack-traces.js:145:22)
at <anonymous> (stack-trac
at <anonymous> (stack-traces.js:150:14)
at testClassNames (stack-traces.js:154:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:291:49)
): expected <true> found <false>
Failure (UnintendedCallerCensorship didn't contain new ReferenceError): expected <true> found <false>
Failure: expected <"abc"> found <undefined>
Failure:
expected:
"abc"
found:
" at <eval> (stack-traces.js:371:13)\n"
Failure:
expected:
undefined
found:
" at <eval> (stack-traces.js:375:13)\n"
Failure: expected <"abc"> found <" at <eval> (stack-traces.js:371:13)\n">
Failure: expected <undefined> found <" at <eval> (stack-traces.js:375:13)\n">
TypeError: not a function
at <eval> (stack-traces.js:381:1)
@ -809,13 +835,9 @@ Did not throw exception
Did not throw exception
Did not throw exception
Failure: expected <null> found <undefined>
Failure:
expected:
undefined
found:
function non_strict() {
Failure: expected <undefined> found <function non_strict() {
return return_my_caller();
}
}>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>