{ njs_str("require.hasOwnProperty('length')"),
njs_str("true") },
- { njs_str("var fs = require('fs'); typeof fs"),
- njs_str("object") },
-
- { njs_str("var fs = require('fs'); Object.isExtensible(fs)"),
- njs_str("true") },
+ /* setTimeout(). */
- { njs_str("require('fs') === require('fs')"),
- njs_str("true") },
+ { njs_str("setTimeout()"),
+ njs_str("TypeError: too few arguments") },
- { njs_str("require('fs').a = 1; require('fs').a"),
- njs_str("1") },
+ { njs_str("setTimeout(function(){})"),
+ njs_str("InternalError: not supported by host environment") },
- /* require('fs').readFile() */
+ { njs_str("setTimeout(function(){}, 12)"),
+ njs_str("InternalError: not supported by host environment") },
- { njs_str("var fs = require('fs');"
- "fs.readFile()"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ /* clearTimeout(). */
- { njs_str("var fs = require('fs');"
- "var path = Buffer.from('/broken'); path[3] = 0;"
- "fs.readFile(path)"),
- njs_str("TypeError: \"path\" must be a Buffer without null bytes") },
+ { njs_str("clearTimeout()"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.readFile('/njs_unknown_path')"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("clearTimeout(123)"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.readFile('/njs_unknown_path', 'utf8')"),
- njs_str("TypeError: \"callback\" must be a function") },
+ /* Trick: number to boolean. */
- { njs_str("var fs = require('fs');"
- "fs.readFile('/njs_unknown_path', {flag:'xx'})"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("var a = 0; !!a"),
+ njs_str("false") },
- { njs_str("var fs = require('fs');"
- "fs.readFile('/njs_unknown_path', {flag:'xx'}, 1)"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("var a = 5; !!a"),
+ njs_str("true") },
- { njs_str("var fs = require('fs');"
- "fs.readFile('/njs_unknown_path', {flag:'xx'}, function () {})"),
- njs_str("TypeError: Unknown file open flags: \"xx\"") },
+ /* Trick: flooring. */
- { njs_str("var fs = require('fs');"
- "fs.readFile('/njs_unknown_path', {encoding:'ascii'}, function () {})"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ { njs_str("var n = -10.12345; ~~n"),
+ njs_str("-10") },
- { njs_str("var fs = require('fs');"
- "fs.readFile('/njs_unknown_path', 'ascii', function () {})"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ { njs_str("var n = 10.12345; ~~n"),
+ njs_str("10") },
- /* require('fs').readFileSync() */
+ /* es5id: 8.2_A1_T1 */
+ /* es5id: 8.2_A1_T2 */
- { njs_str("var fs = require('fs');"
- "fs.readFileSync()"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ { njs_str("var x = null;"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.readFileSync({})"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ /* es5id: 8.2_A2 */
- { njs_str("var fs = require('fs');"
- "fs.readFileSync('/njs_unknown_path', {flag:'xx'})"),
- njs_str("TypeError: Unknown file open flags: \"xx\"") },
+ { njs_str("var null;"),
+ njs_str("SyntaxError: Unexpected token \"null\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.readFileSync(Buffer.from('/njs_unknown_path'), {encoding:'ascii'})"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ /* es5id: 8.2_A3 */
- { njs_str("var fs = require('fs');"
- "fs.readFileSync('/njs_unknown_path', 'ascii')"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ { njs_str("typeof(null) === \"object\""),
+ njs_str("true") },
- { njs_str("var fs = require('fs');"
- "fs.readFileSync('/njs_unknown_path', true)"),
- njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
+ /* Module. */
+ { njs_str("import;"),
+ njs_str("SyntaxError: Non-default import is not supported in 1") },
- /* require('fs').writeFile() */
+ { njs_str("import {x} from y"),
+ njs_str("SyntaxError: Non-default import is not supported in 1") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile()"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ { njs_str("import x from y"),
+ njs_str("SyntaxError: Unexpected token \"y\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile({}, '', function () {})"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ { njs_str("import x from {"),
+ njs_str("SyntaxError: Unexpected token \"{\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path')"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("import x from ''"),
+ njs_str("SyntaxError: Cannot find module \"\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path', '')"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("import x from 'crypto'"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path', '', undefined)"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("import x from 'crypto' 1"),
+ njs_str("SyntaxError: Unexpected token \"1\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path', '', 'utf8')"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("if (1) {import x from 'crypto'}"),
+ njs_str("SyntaxError: Illegal import statement in 1") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path', '', {flag:'xx'}, function () {})"),
- njs_str("TypeError: Unknown file open flags: \"xx\"") },
+ { njs_str("export"),
+ njs_str("SyntaxError: Illegal export statement in 1") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path', '', {encoding:'ascii'}, function () {})"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ { njs_str("Object.assign(undefined)"),
+ njs_str("TypeError: cannot convert null or undefined to object") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path', '', 'ascii', function () {})"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ { njs_str("Object.assign(null)"),
+ njs_str("TypeError: cannot convert null or undefined to object") },
- { njs_str("var fs = require('fs');"
- "fs.writeFile('/njs_unknown_path', '', true, function () {})"),
- njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
+ { njs_str("Object.assign({x:123}).toString()"),
+ njs_str("[object Object]") },
- /* require('fs').writeFileSync() */
+ { njs_str("Object.assign({x:123}).x"),
+ njs_str("123") },
- { njs_str("var fs = require('fs');"
- "fs.writeFileSync()"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ { njs_str("Object.assign(true)"),
+ njs_str("true") },
- { njs_str("var fs = require('fs');"
- "fs.writeFileSync({}, '')"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ { njs_str("Object.assign(123)"),
+ njs_str("123") },
- { njs_str("var fs = require('fs');"
- "fs.writeFileSync('/njs_unknown_path', '', {flag:'xx'})"),
- njs_str("TypeError: Unknown file open flags: \"xx\"") },
+ { njs_str("var o1 = {a:1, b:1, c:1}; var o2 = {b:2, c:2}; "
+ "var o3 = {c:3}; var obj = Object.assign({}, o1, o2, o3); "
+ "Object.values(obj);"),
+ njs_str("1,2,3") },
- { njs_str("var fs = require('fs');"
- "fs.writeFileSync('/njs_unknown_path', '', {encoding:'ascii'})"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ { njs_str("var v1 = 'abc'; var v2 = true; var v3 = 10; "
+ "var obj = Object.assign({}, v1, null, v2, undefined, v3); "
+ "Object.values(obj);"),
+ njs_str("a,b,c") },
- { njs_str("var fs = require('fs');"
- "fs.writeFileSync('/njs_unknown_path', '', 'ascii')"),
- njs_str("TypeError: \"ascii\" encoding is not supported") },
+ { njs_str("Object.assign(true, {a:123})"),
+ njs_str("true") },
- { njs_str("var fs = require('fs');"
- "fs.writeFileSync('/njs_unknown_path', '', true)"),
- njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
+ { njs_str("Object.assign(true, {a:123}).a"),
+ njs_str("123") },
- /* require('fs').renameSync() */
+ { njs_str("var y = Object.create({s:123}); y.z = 456;"
+ "Object.assign({}, y).s;"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.renameSync()"),
- njs_str("TypeError: \"oldPath\" must be a string or Buffer") },
+ { njs_str("var obj = {s:123}; Object.defineProperty(obj,"
+ "'p1', {value:12, enumerable:false});"
+ "Object.assign({}, obj).p1"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.renameSync('/njs_unknown_path')"),
- njs_str("TypeError: \"newPath\" must be a string or Buffer") },
+ { njs_str("var obj = {s:123}; Object.defineProperty(obj,"
+ "'x', {value:12, writable:false});"
+ "Object.assign(obj, {x:4})"),
+ njs_str("TypeError: Cannot assign to read-only property \"x\" of object") },
- { njs_str("var fs = require('fs');"
- "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
- ".map((x) => { try { fs.renameSync(x, '/njs_unknown_path'); } "
- " catch (e) { return (e instanceof TypeError); } })"
- ".every((x) => x === true)"),
- njs_str("true")},
+ { njs_str("var obj = {foo:1, get bar() {return 2;}};"
+ "var copy = Object.assign({}, obj);"
+ "Object.getOwnPropertyDescriptor(copy, 'bar').get"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
- ".map((x) => { try { fs.renameSync('/njs_unknown_path', x); } "
- " catch (e) { return (e instanceof TypeError); } })"
- ".every((x) => x === true)"),
- njs_str("true")},
+ { njs_str("try{var x = Object.defineProperty({}, 'foo',"
+ "{value:1, writable:false});"
+ "Object.assign(x, {bar:2}, {foo:2});}catch(error){};"
+ "x.bar"),
+ njs_str("2") },
- /* require('fs').access() */
+ { njs_str("var a = Object.defineProperty({}, 'a',"
+ "{get(){Object.defineProperty(this, 'b',"
+ "{value:2,enumerable:false});"
+ "return 1}, enumerable:1}); a.b =1;"
+ "var x = Object.assign({}, a);x.b;"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.access()"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ /* let and const */
- { njs_str("var fs = require('fs');"
- "fs.access('/njs_unknown_path')"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("var let = 123;"
+ "let"),
+ njs_str("SyntaxError: Unexpected token \"let\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.access('/njs_unknown_path', fs.constants.F_OK)"),
- njs_str("TypeError: \"callback\" must be a function") },
+ { njs_str("var const = 123"),
+ njs_str("SyntaxError: Unexpected token \"const\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.access('/njs_unknown_path', 'fail', function () {})"),
- njs_str("TypeError: \"mode\" must be a number") },
+ /* Async */
- /* require('fs').accessSync() */
+ { njs_str("var async;"
+ "function f() {"
+ " async\n"
+ " function foo() {}"
+ "}"
+ "f()"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.accessSync()"),
- njs_str("TypeError: \"path\" must be a string or Buffer") },
+ { njs_str("var async;"
+ "function f() {"
+ " async;"
+ " function foo() {}"
+ "}"
+ "f()"),
+ njs_str("undefined") },
- { njs_str("var fs = require('fs');"
- "fs.accessSync('/njs_unknown_path', 'fail')"),
- njs_str("TypeError: \"mode\" must be a number") },
+ { njs_str("var async;"
+ "async\n"
+ "function foo() {}"),
+ njs_str("undefined") },
- { njs_str("var "
- "fs = require('fs'),"
- "func = ["
- "'access',"
- "'accessSync',"
- "'readFile',"
- "'readFileSync',"
- "'writeFile',"
- "'writeFileSync',"
- "'appendFile',"
- "'appendFileSync',"
- "'rename',"
- "'renameSync',"
- "'symlink',"
- "'symlinkSync',"
- "'unlink',"
- "'unlinkSync',"
- "'realpath',"
- "'realpathSync',"
- "'mkdir',"
- "'mkdirSync',"
- "'rmdir',"
- "'rmdirSync',"
- "'readdir',"
- "'readdirSync',"
- "],"
- "test = (fname) =>"
- "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
- ".map((x) => { try { fs[fname](x); } "
- " catch (e) { return (e instanceof TypeError); } })"
- ".every((x) => x === true);"
- "func.map(test).every((x) => x)"),
- njs_str("true")},
+ { njs_str("new\""),
+ njs_str("SyntaxError: Unterminated string \"\"\" in 1") },
- /* require('fs').promises */
+ { njs_str("new\"\\UFFFF"),
+ njs_str("SyntaxError: Unterminated string \"\"\\UFFFF\" in 1") },
- { njs_str("var fs = require('fs');"
- "typeof fs.promises"),
- njs_str("object") },
+ { njs_str("new/la"),
+ njs_str("SyntaxError: Unterminated RegExp \"/la\" in 1") },
- { njs_str("var "
- "fs = require('fs').promises,"
- "func = ["
- "'access',"
- "'readFile',"
- "'writeFile',"
- "'appendFile',"
- "'rename',"
- "'symlink',"
- "'unlink',"
- "'realpath',"
- "'mkdir',"
- "'rmdir',"
- "'readdir',"
- "];"
- "func.every((x) => typeof fs[x] == 'function')"),
- njs_str("true")},
+ { njs_str("{name; {/ / /}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- /* require('fs').constants */
+ { njs_str("[(]"),
+ njs_str("SyntaxError: Unexpected token \"]\" in 1") },
- { njs_str("var fs = require('fs');"
- "typeof fs.constants"),
- njs_str("object") },
+ { njs_str("[...]"),
+ njs_str("SyntaxError: Unexpected token \"]\" in 1") },
- { njs_str("var "
- "fsc = require('fs').constants,"
- "items = ["
- "'F_OK',"
- "'R_OK',"
- "'W_OK',"
- "'X_OK',"
- "];"
- "items.every((x) => typeof fsc[x] == 'number')"),
- njs_str("true")},
+ { njs_str("switch () {}"),
+ njs_str("SyntaxError: Unexpected token \")\" in 1") },
- /* require('fs').Dirent */
+ { njs_str("switch ([(]) {}"),
+ njs_str("SyntaxError: Unexpected token \"]\" in 1") },
- { njs_str("var fs = require('fs');"
- "typeof fs.Dirent"),
- njs_str("function") },
+ { njs_str("{{}{-}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var fs = require('fs');"
- "fs.Dirent('file', 123)"),
- njs_str("TypeError: the Dirent constructor must be called with new") },
+ { njs_str("{{}{+}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var fs = require('fs');"
- "var e = new fs.Dirent('file', 123); [e.name, e.type]"),
- njs_str("file,123") },
+ { njs_str("{{}{delete}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var "
- "fs = require('fs'),"
- "e = new fs.Dirent('file', 0),"
- "func = ["
- "'isDirectory',"
- "'isFile',"
- "'isBlockDevice',"
- "'isCharacterDevice',"
- "'isSymbolicLink',"
- "'isFIFO',"
- "'isSocket',"
- "];"
- "func.every((x) => typeof e[x] == 'function')"),
- njs_str("true")},
+ { njs_str("{{}{++}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- /* require('crypto').createHash() */
+ { njs_str("{{}{++1}"),
+ njs_str("ReferenceError: Invalid left-hand side in prefix operation in 1") },
- { njs_str("var h = require('crypto').createHash('sha1');"
- "[Object.prototype.toString.call(h), njs.dump(h),h]"),
- njs_str("[object Hash],Hash {},[object Hash]") },
+ { njs_str("{{}{1++}"),
+ njs_str("ReferenceError: Invalid left-hand side in postfix operation in 1") },
- { njs_str("var h = require('crypto').createHash('sha1');"
- "var Hash = h.constructor; "
- "Hash('sha1').update('AB').digest('hex')"),
- njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d") },
+ { njs_str("{{}{1/}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.constructor.name"),
- njs_str("Hash") },
+ { njs_str("{{}{1>>}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hash = require('crypto').createHash.bind(undefined, 'md5');"
- "['hex', 'base64', 'base64url'].map(e => {"
- " var h = hash().update('AB').digest().toString(e);"
- " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
- " var h3 = hash().update('A').update('B').digest(e);"
- " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
- " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
- " return h;"
- "})"),
- njs_str("b86fc6b051f63d73de262d4c34e3a0a9,"
- "uG/GsFH2PXPeJi1MNOOgqQ==,"
- "uG_GsFH2PXPeJi1MNOOgqQ") },
+ { njs_str("{{}{r=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
- "['hex', 'base64', 'base64url'].map(e => {"
- " var h = hash().update('4142', 'hex').digest().toString(e);"
- " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
- " var h3 = hash().update('A').update('B').digest(e);"
- " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
- " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
- " return h;"
- "})"),
- njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d,"
- "BtlFlCqiamG+GMPiK/GbvKjdK10=,"
- "BtlFlCqiamG-GMPiK_GbvKjdK10") },
+ { njs_str("{{}{var a = }"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
- "['hex', 'base64', 'base64url'].every(e => {"
- " var h = hash().digest(e);"
- " var h2 = hash().update('').digest(e);"
- " if (h !== h2) {throw new Error(`digest($e):$h != update('').digest($e):$h2`)};"
- " return true;"
- "})"),
- njs_str("true") },
+ { njs_str("{{}T=>}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
- "["
- " ['AB'],"
- " ['4142', 'hex'],"
- " ['QUI=', 'base64'],"
- " ['QUI', 'base64url']"
- "].every(args => {"
- " return hash().update(args[0], args[1]).digest('hex') === '06d945942aa26a61be18c3e22bf19bbca8dd2b5d';"
- "})"),
- njs_str("true") },
+ { njs_str("{{}a = b +}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha256');"
- "['hex', 'base64', 'base64url'].map(e => {"
- " var h = hash().update('AB').digest().toString(e);"
- " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
- " var h3 = hash().update('A').update('B').digest(e);"
- " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
- " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
- " return h;"
- "})"),
- njs_str("38164fbd17603d73f696b8b4d72664d735bb6a7c88577687fd2ae33fd6964153,"
- "OBZPvRdgPXP2lri01yZk1zW7anyIV3aH/SrjP9aWQVM=,"
- "OBZPvRdgPXP2lri01yZk1zW7anyIV3aH_SrjP9aWQVM") },
+ { njs_str("{{}a = b -}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hash = require('crypto').createHash;"
- "njs.dump(['', 'abc'.repeat(100)].map(v => {"
- " return ['md5', 'sha1', 'sha256'].map(h => {"
- " return hash(h).update(v).digest('hex');"
- " })"
- "}))"),
- njs_str("[['d41d8cd98f00b204e9800998ecf8427e',"
- "'da39a3ee5e6b4b0d3255bfef95601890afd80709',"
- "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'],"
- "['f571117acbd8153c8dc3c81b8817773a',"
- "'c95466320eaae6d19ee314ae4f135b12d45ced9a',"
- "'d9f5aeb06abebb3be3f38adec9a2e3b94228d52193be923eb4e24c9b56ee0930']]") },
+ { njs_str("{{}a = b *}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHash()"),
- njs_str("TypeError: algorithm must be a string") },
+ { njs_str("{{}a = b /}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHash([])"),
- njs_str("TypeError: algorithm must be a string") },
+ { njs_str("{{}a = b %}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHash('sha512')"),
- njs_str("TypeError: not supported algorithm: \"sha512\"") },
+ { njs_str("{{}a = b++}"),
+ njs_str("ReferenceError: \"a\" is not defined") },
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update()"),
- njs_str("TypeError: data argument \"undefined\" is not a string or Buffer-like object") },
+ { njs_str("{{}a = b--}"),
+ njs_str("ReferenceError: \"a\" is not defined") },
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update({})"),
- njs_str("TypeError: data argument \"object\" is not a string or Buffer-like object") },
+ { njs_str("{{}a =}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('A').digest('latin1')"),
- njs_str("TypeError: Unknown digest encoding: \"latin1\"") },
+ { njs_str("{{}a +=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("require('crypto').createHash('sha1').digest() instanceof Buffer"),
- njs_str("true") },
-
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('A').digest('hex'); h.digest('hex')"),
- njs_str("Error: Digest already called") },
+ { njs_str("{{}a -=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHash('sha1');"
- "h.update('A').digest('hex'); h.update('B')"),
- njs_str("Error: Digest already called") },
+ { njs_str("{{}a *=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("typeof require('crypto').createHash('md5')"),
- njs_str("object") },
+ { njs_str("{{}a /=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- /* require('crypto').createHmac() */
+ { njs_str("{{}a %=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha1', '');"
- "[Object.prototype.toString.call(h), njs.dump(h),h]"),
- njs_str("[object Hmac],Hmac {},[object Hmac]") },
+ { njs_str("{{}a ===}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'md5', '');"
- "['hex', 'base64', 'base64url'].map(e => {"
- " var h = hmac().update('AB').digest().toString(e);"
- " var h2 = hmac().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
- " var h3 = hmac().update('A').update('B').digest(e);"
- " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
- " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
- " return h;"
- "})"),
- njs_str("9e0e9e545ef63d41dfb653daecf8ebc7,"
- "ng6eVF72PUHftlPa7Pjrxw==,"
- "ng6eVF72PUHftlPa7Pjrxw") },
+ { njs_str("{{}a ==}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'sha1', '');"
- "['hex', 'base64', 'base64url'].map(e => {"
- " var h = hmac().update('AB').digest().toString(e);"
- " var h2 = hmac().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
- " var h3 = hmac().update('A').update('B').digest(e);"
- " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
- " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
- " return h;"
- "})"),
- njs_str("d32c0b6637cc2dfe4670f3fe48ef4434123c4810,"
- "0ywLZjfMLf5GcPP+SO9ENBI8SBA=,"
- "0ywLZjfMLf5GcPP-SO9ENBI8SBA") },
+ { njs_str("{{}a !=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hash = require('crypto').createHmac.bind(undefined, 'sha1', '');"
- "["
- " ['AB'],"
- " ['4142', 'hex'],"
- " ['QUI=', 'base64'],"
- " ['QUI', 'base64url']"
- "].every(args => {"
- " return hash().update(args[0], args[1]).digest('hex') === 'd32c0b6637cc2dfe4670f3fe48ef4434123c4810';"
- "})"),
- njs_str("true") },
+ { njs_str("{{}a !==}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'sha256', '');"
- "['hex', 'base64', 'base64url'].map(e => {"
- " var h = hmac().update('AB').digest().toString(e);"
- " var h2 = hmac().update(Buffer.from('AB')).digest(e);"
- " var h3 = hmac().update('A').update('B').digest(e);"
- " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
- " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
- " return h;"
- "})"),
- njs_str("d53400095496267cf02e5dbd4b0bf9fbfb5f36f311ea7d9809af5487421743e3,"
- "1TQACVSWJnzwLl29Swv5+/tfNvMR6n2YCa9Uh0IXQ+M=,"
- "1TQACVSWJnzwLl29Swv5-_tfNvMR6n2YCa9Uh0IXQ-M") },
+ { njs_str("{{}a >}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var hmac = require('crypto').createHmac;"
- "njs.dump(['', 'abc'.repeat(100)].map(v => {"
- " return ['md5', 'sha1', 'sha256'].map(h => {"
- " return hmac(h, Buffer.from('secret')).update(v).digest('hex');"
- " })"
- "}))"),
- njs_str("[['5c8db03f04cec0f43bcb060023914190',"
- "'25af6174a0fcecc4d346680a72b7ce644b9a88e8',"
- "'f9e66e179b6747ae54108f82f8ade8b3c25d76fd30afde6c395822c530196169'],"
- "['91eb74a225cdd3bbfccc34396c6e3ac5',"
- "'0aac71e3a813a7acc4a809cfdedb2ecba04ffc5e',"
- "'8660d2d51d6f20f61d5aadfb6c43df7fd05fc2fc4967d8aec1846f3d9ec03987']]") },
+ { njs_str("{{}a <}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha1', '');"
- "var Hmac = h.constructor; "
- "Hmac('sha1', '').digest('hex')"),
- njs_str("fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") },
+ { njs_str("{{}a <=}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha1', '');"
- "h.constructor.name"),
- njs_str("Hmac") },
+ { njs_str("{{}a &&}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("require('crypto').createHmac('sha1', '').digest() instanceof Buffer"),
- njs_str("true") },
+ { njs_str("{{}a ||}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha256', 'A'.repeat(64));"
- "h.update('AB').digest('hex')"),
- njs_str("ee9dce43b12eb3e865614ad9c1a8d4fad4b6eac2b64647bd24cd192888d3f367") },
+ { njs_str("{{}a ??}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha256', 'A'.repeat(100));"
- "h.update('AB').digest('hex')"),
- njs_str("5647b6c429701ff512f0f18232b4507065d2376ca8899a816a0a6e721bf8ddcc") },
+ { njs_str("{{}a &}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac()"),
- njs_str("TypeError: algorithm must be a string") },
+ { njs_str("{{}a |}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac([])"),
- njs_str("TypeError: algorithm must be a string") },
+ { njs_str("{{}a ^}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha512', '')"),
- njs_str("TypeError: not supported algorithm: \"sha512\"") },
+ { njs_str("{{}a <<}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha1', [])"),
- njs_str("TypeError: key argument \"array\" is not a string or Buffer-like object") },
+ { njs_str("{{}a >>}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('A').digest('hex'); h.digest('hex')"),
- njs_str("Error: Digest already called") },
+ { njs_str("{{}new}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
- "h.update('A').digest('hex'); h.update('B')"),
- njs_str("Error: Digest already called") },
+ { njs_str("{{}delete}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("typeof require('crypto').createHmac('md5', 'a')"),
- njs_str("object") },
+ { njs_str("{{}void}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var cr = require('crypto'); var h = cr.createHash('sha1');"
- "h.update.call(cr.createHmac('sha1', 's'), '')"),
- njs_str("TypeError: \"this\" is not a hash object") },
+ { njs_str("{{}typeof}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- /* setTimeout(). */
+ { njs_str("{{} ({a: 1, b: {}\n}\n})\n}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 3") },
- { njs_str("setTimeout()"),
- njs_str("TypeError: too few arguments") },
+ { njs_str("object?."),
+ njs_str("SyntaxError: Unexpected end of input in 1") },
- { njs_str("setTimeout(function(){})"),
- njs_str("InternalError: not supported by host environment") },
+ { njs_str("`${{a: 1, b}}`"),
+ njs_str("ReferenceError: \"b\" is not defined") },
- { njs_str("setTimeout(function(){}, 12)"),
- njs_str("InternalError: not supported by host environment") },
+ { njs_str("`${{a: 1, b:}}`"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- /* clearTimeout(). */
+ { njs_str("`${{a: 1, b:,}}`"),
+ njs_str("SyntaxError: Unexpected token \",\" in 1") },
- { njs_str("clearTimeout()"),
- njs_str("undefined") },
+ { njs_str("`${{a: 1, b: 2,}}`"),
+ njs_str("[object Object]") },
- { njs_str("clearTimeout(123)"),
- njs_str("undefined") },
+ { njs_str("`${{a: 1,, b: 2}}`"),
+ njs_str("SyntaxError: Unexpected token \",\" in 1") },
- /* Trick: number to boolean. */
+ { njs_str("`${{f(){-} - {}}`"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var a = 0; !!a"),
- njs_str("false") },
+ { njs_str("for (;1-;) {}"),
+ njs_str("SyntaxError: Unexpected token \";\" in 1") },
- { njs_str("var a = 5; !!a"),
- njs_str("true") },
+ { njs_str("var str = String(str); str"),
+ njs_str("undefined") },
- /* Trick: flooring. */
+ { njs_str("var t = \"123\"; t = parseInt(t); t"),
+ njs_str("123") },
- { njs_str("var n = -10.12345; ~~n"),
- njs_str("-10") },
+ /* TextEncoder. */
- { njs_str("var n = 10.12345; ~~n"),
- njs_str("10") },
+ { njs_str("var en = new TextEncoder(); typeof en.encode()"),
+ njs_str("object") },
- /* es5id: 8.2_A1_T1 */
- /* es5id: 8.2_A1_T2 */
+ { njs_str("var en = new TextEncoder(); en.encode()"),
+ njs_str("") },
- { njs_str("var x = null;"),
- njs_str("undefined") },
+ { njs_str("var en = new TextEncoder(); var res = en.encode('α'); res"),
+ njs_str("206,177") },
- /* es5id: 8.2_A2 */
+ { njs_str("var en = new TextEncoder(); var res = en.encode('α1α'); res[2]"),
+ njs_str("49") },
- { njs_str("var null;"),
- njs_str("SyntaxError: Unexpected token \"null\" in 1") },
+ { njs_str("var en = new TextEncoder(); en.encode(String.bytesFrom([0xCE]))"),
+ njs_str("239,191,189") },
- /* es5id: 8.2_A3 */
+ { njs_str("var en = new TextEncoder();"
+ "en.encode(String.bytesFrom([0xCE, 0xB1, 0xCE]))"),
+ njs_str("206,177,239,191,189") },
- { njs_str("typeof(null) === \"object\""),
- njs_str("true") },
+ { njs_str("var en = new TextEncoder();"
+ "en.encode(String.bytesFrom([0xCE, 0xCE, 0xB1]))"),
+ njs_str("239,191,189,206,177") },
- /* Module. */
+ { njs_str("var en = new TextEncoder(); en.encoding"),
+ njs_str("utf-8") },
- { njs_str("import;"),
- njs_str("SyntaxError: Non-default import is not supported in 1") },
+ { njs_str("TextEncoder.prototype.encode.apply({}, [])"),
+ njs_str("TypeError: \"this\" is not a TextEncoder") },
- { njs_str("import {x} from y"),
- njs_str("SyntaxError: Non-default import is not supported in 1") },
+ { njs_str("var en = new TextEncoder();"
+ "var utf8 = new Uint8Array(5);"
+ "var res = en.encodeInto('ααααα', utf8); njs.dump(res)"),
+ njs_str("{read:2,written:4}") },
- { njs_str("import x from y"),
- njs_str("SyntaxError: Unexpected token \"y\" in 1") },
+ { njs_str("var en = new TextEncoder();"
+ "var utf8 = new Uint8Array(10);"
+ "var res = en.encodeInto('ααααα', utf8); njs.dump(res)"),
+ njs_str("{read:5,written:10}") },
- { njs_str("import x from {"),
- njs_str("SyntaxError: Unexpected token \"{\" in 1") },
+ { njs_str("var en = new TextEncoder();"
+ "var utf8 = new Uint8Array(10);"
+ "en.encodeInto('ααααα', utf8.subarray(2)); utf8[0]"),
+ njs_str("0") },
- { njs_str("import x from ''"),
- njs_str("SyntaxError: Cannot find module \"\" in 1") },
+ { njs_str("var str = String.bytesFrom([0xCE]);"
+ "var en = new TextEncoder();"
+ "var utf8 = new Uint8Array(3);"
+ "var res = en.encodeInto(str, utf8); "
+ "[njs.dump(res), utf8]"),
+ njs_str("{read:1,written:3},239,191,189") },
- { njs_str("import x from 'crypto'"),
- njs_str("undefined") },
-
- { njs_str("import x from 'crypto' 1"),
- njs_str("SyntaxError: Unexpected token \"1\" in 1") },
+ { njs_str("var str = String.bytesFrom([0xCE]);"
+ "var en = new TextEncoder();"
+ "var utf8 = new Uint8Array(5);"
+ "en.encodeInto(str, utf8); utf8"),
+ njs_str("239,191,189,0,0") },
- { njs_str("if (1) {import x from 'crypto'}"),
- njs_str("SyntaxError: Illegal import statement in 1") },
+ { njs_str("var str = String.bytesFrom([0xCE, 0xB1, 0xCE]);"
+ "var en = new TextEncoder();"
+ "var utf8 = new Uint8Array(5);"
+ "var res = en.encodeInto(str, utf8);"
+ "[njs.dump(res), utf8]"),
+ njs_str("{read:2,written:5},206,177,239,191,189") },
- { njs_str("export"),
- njs_str("SyntaxError: Illegal export statement in 1") },
+ { njs_str("var str = String.bytesFrom([0xCE, 0xCE, 0xB1]);"
+ "var en = new TextEncoder();"
+ "var utf8 = new Uint8Array(5);"
+ "var res = en.encodeInto(str, utf8);"
+ "[njs.dump(res), utf8]"),
+ njs_str("{read:2,written:5},239,191,189,206,177") },
- { njs_str("Object.assign(undefined)"),
- njs_str("TypeError: cannot convert null or undefined to object") },
+ { njs_str("TextEncoder.prototype.encodeInto.apply({}, [])"),
+ njs_str("TypeError: \"this\" is not a TextEncoder") },
- { njs_str("Object.assign(null)"),
- njs_str("TypeError: cannot convert null or undefined to object") },
+ { njs_str("(new TextEncoder()).encodeInto('', 0.12) "),
+ njs_str("TypeError: The \"destination\" argument must be an instance of Uint8Array") },
- { njs_str("Object.assign({x:123}).toString()"),
- njs_str("[object Object]") },
+ /* TextDecoder. */
- { njs_str("Object.assign({x:123}).x"),
- njs_str("123") },
+ { njs_str("var de = new TextDecoder();"
+ "var u8arr = new Uint8Array([240, 160, 174, 183]);"
+ "var u16arr = new Uint16Array(u8arr.buffer);"
+ "var u32arr = new Uint32Array(u8arr.buffer);"
+ "[u8arr, u16arr, u32arr].map(v=>de.decode(v)).join(',')"),
+ njs_str("𠮷,𠮷,𠮷") },
- { njs_str("Object.assign(true)"),
- njs_str("true") },
+ { njs_str("var de = new TextDecoder();"
+ "[new Uint8Array([240, 160]), "
+ " new Uint8Array([174]), "
+ " new Uint8Array([183])].map(v=>de.decode(v, {stream: 1}))[2]"),
+ njs_str("𠮷") },
- { njs_str("Object.assign(123)"),
- njs_str("123") },
+ { njs_str("var de = new TextDecoder();"
+ "de.decode(new Uint8Array([240, 160]), {stream: 1});"
+ "de.decode(new Uint8Array([174]), {stream: 1});"
+ "de.decode(new Uint8Array([183]))"),
+ njs_str("𠮷") },
- { njs_str("var o1 = {a:1, b:1, c:1}; var o2 = {b:2, c:2}; "
- "var o3 = {c:3}; var obj = Object.assign({}, o1, o2, o3); "
- "Object.values(obj);"),
- njs_str("1,2,3") },
+ { njs_str("var de = new TextDecoder();"
+ "de.decode(new Uint8Array([240, 160]), {stream: 1});"
+ "de.decode()"),
+ njs_str("�") },
- { njs_str("var v1 = 'abc'; var v2 = true; var v3 = 10; "
- "var obj = Object.assign({}, v1, null, v2, undefined, v3); "
- "Object.values(obj);"),
- njs_str("a,b,c") },
+ { njs_str("var de = new TextDecoder('utf-8', {fatal: true});"
+ "de.decode(new Uint8Array([240, 160]))"),
+ njs_str("TypeError: The encoded data was not valid") },
- { njs_str("Object.assign(true, {a:123})"),
- njs_str("true") },
+ { njs_str("var de = new TextDecoder('utf-8', {fatal: false});"
+ "de.decode(new Uint8Array([240, 160]))"),
+ njs_str("�") },
- { njs_str("Object.assign(true, {a:123}).a"),
- njs_str("123") },
+ { njs_str("var en = new TextEncoder();"
+ "var de = new TextDecoder('utf-8', {ignoreBOM: true});"
+ "en.encode(de.decode(new Uint8Array([239, 187, 191, 50])))"),
+ njs_str("239,187,191,50") },
- { njs_str("var y = Object.create({s:123}); y.z = 456;"
- "Object.assign({}, y).s;"),
- njs_str("undefined") },
+ { njs_str("var en = new TextEncoder();"
+ "var de = new TextDecoder('utf-8', {ignoreBOM: false});"
+ "en.encode(de.decode(new Uint8Array([239, 187, 191, 50])))"),
+ njs_str("50") },
- { njs_str("var obj = {s:123}; Object.defineProperty(obj,"
- "'p1', {value:12, enumerable:false});"
- "Object.assign({}, obj).p1"),
- njs_str("undefined") },
+ { njs_str("var en = new TextEncoder(); var de = new TextDecoder();"
+ "en.encode(de.decode(new Uint8Array([239, 187, 191, 50])))"),
+ njs_str("50") },
- { njs_str("var obj = {s:123}; Object.defineProperty(obj,"
- "'x', {value:12, writable:false});"
- "Object.assign(obj, {x:4})"),
- njs_str("TypeError: Cannot assign to read-only property \"x\" of object") },
+ { njs_str("var de = new TextDecoder(); de.decode('')"),
+ njs_str("TypeError: The \"input\" argument must be an instance of TypedArray") },
- { njs_str("var obj = {foo:1, get bar() {return 2;}};"
- "var copy = Object.assign({}, obj);"
- "Object.getOwnPropertyDescriptor(copy, 'bar').get"),
- njs_str("undefined") },
+ { njs_str("var de = new TextDecoder({})"),
+ njs_str("RangeError: The \"[object Object]\" encoding is not supported") },
- { njs_str("try{var x = Object.defineProperty({}, 'foo',"
- "{value:1, writable:false});"
- "Object.assign(x, {bar:2}, {foo:2});}catch(error){};"
- "x.bar"),
- njs_str("2") },
+ { njs_str("var de = new TextDecoder('foo')"),
+ njs_str("RangeError: The \"foo\" encoding is not supported") },
- { njs_str("var a = Object.defineProperty({}, 'a',"
- "{get(){Object.defineProperty(this, 'b',"
- "{value:2,enumerable:false});"
- "return 1}, enumerable:1}); a.b =1;"
- "var x = Object.assign({}, a);x.b;"),
- njs_str("undefined") },
+ { njs_str("var de = new TextDecoder(); de.encoding"),
+ njs_str("utf-8") },
- /* let and const */
+ { njs_str("var de = new TextDecoder(); de.fatal"),
+ njs_str("false") },
- { njs_str("var let = 123;"
- "let"),
- njs_str("SyntaxError: Unexpected token \"let\" in 1") },
+ { njs_str("var de = new TextDecoder(); de.ignoreBOM"),
+ njs_str("false") },
- { njs_str("var const = 123"),
- njs_str("SyntaxError: Unexpected token \"const\" in 1") },
+ { njs_str("TextDecoder.prototype.decode.apply({}, new Uint8Array([1]))"),
+ njs_str("TypeError: \"this\" is not a TextDecoder") },
- /* Async */
+ { njs_str("var de = new TextDecoder();"
+ "var buf = new Uint32Array([1,2,3]).buffer;"
+ "var en = new TextEncoder();"
+ "njs.dump(new Uint32Array(en.encode(de.decode(buf)).buffer))"),
+ njs_str("Uint32Array [1,2,3]") },
- { njs_str("var async;"
- "function f() {"
- " async\n"
- " function foo() {}"
- "}"
- "f()"),
- njs_str("undefined") },
+ { njs_str("var de = new TextDecoder();"
+ "var buf = new Uint32Array([1,2,3]).subarray(1,2);"
+ "var en = new TextEncoder();"
+ "njs.dump(new Uint32Array(en.encode(de.decode(buf)).buffer))"),
+ njs_str("Uint32Array [2]") },
- { njs_str("var async;"
- "function f() {"
- " async;"
- " function foo() {}"
- "}"
- "f()"),
- njs_str("undefined") },
+ /* let */
- { njs_str("var async;"
- "async\n"
- "function foo() {}"),
+ { njs_str("let x"),
njs_str("undefined") },
- { njs_str("new\""),
- njs_str("SyntaxError: Unterminated string \"\"\" in 1") },
+ { njs_str("let x = 123; x"),
+ njs_str("123") },
- { njs_str("new\"\\UFFFF"),
- njs_str("SyntaxError: Unterminated string \"\"\\UFFFF\" in 1") },
+ { njs_str("let x = [123]; x"),
+ njs_str("123") },
- { njs_str("new/la"),
- njs_str("SyntaxError: Unterminated RegExp \"/la\" in 1") },
+ { njs_str("let x = () => x; x()"),
+ njs_str("[object Function]") },
- { njs_str("{name; {/ / /}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let x = (() => x)()"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("[(]"),
- njs_str("SyntaxError: Unexpected token \"]\" in 1") },
+ { njs_str("x; let x"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("[...]"),
- njs_str("SyntaxError: Unexpected token \"]\" in 1") },
+ { njs_str("x; let x = 123"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("switch () {}"),
- njs_str("SyntaxError: Unexpected token \")\" in 1") },
+ { njs_str("let x = x + 123"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("switch ([(]) {}"),
- njs_str("SyntaxError: Unexpected token \"]\" in 1") },
+ { njs_str("let x = (x, 1)"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}{-}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let x = x"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}{+}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let x; var x"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("{{}{delete}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("var x; let x"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("{{}{++}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let x; function x() {}"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("{{}{++1}"),
- njs_str("ReferenceError: Invalid left-hand side in prefix operation in 1") },
+ { njs_str("function x() {} let x"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("{{}{1++}"),
- njs_str("ReferenceError: Invalid left-hand side in postfix operation in 1") },
+ { njs_str("function x() {let x; var x}"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("{{}{1/}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("function x() {var x; let x}"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("{{}{1>>}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("var x = function f() {let f}"),
+ njs_str("undefined") },
- { njs_str("{{}{r=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let a; let x = 1;"
+ "{let x = 2; a = x}"
+ "[x, a]"),
+ njs_str("1,2") },
- { njs_str("{{}{var a = }"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let a; let x = 1;"
+ "if (true) {let x = 2; a = x}"
+ "[x, a]"),
+ njs_str("1,2") },
- { njs_str("{{}T=>}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("var a = 5, b = 10, arr = [];"
+ "{let a = 4; var b = 1; arr.push(a); arr.push(b)}"
+ "arr.push(a); arr.push(b); arr"),
+ njs_str("4,1,5,1") },
- { njs_str("{{}a = b +}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("function func() {return x}"
+ "let x = 123;"
+ "func()"),
+ njs_str("123") },
- { njs_str("{{}a = b -}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("function func() {return x}"
+ "func();"
+ "let x = 123"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a = b *}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("function func() {return () => x}"
+ "let x = 123;"
+ "func()()"),
+ njs_str("123") },
- { njs_str("{{}a = b /}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("function func() {x = x + 1; let x}"),
+ njs_str("undefined") },
- { njs_str("{{}a = b %}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("function func() {return () => x}"
+ "func()();"
+ "let x = 123;"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a = b++}"),
- njs_str("ReferenceError: \"a\" is not defined") },
+ { njs_str("var arr = [];"
+ ""
+ "for (var i = 0; i < 10; i++) {"
+ " let x = i;"
+ ""
+ " arr.push( (n) => {x += n; return x} );"
+ "}"
+ ""
+ "["
+ " arr[0](2), arr[1](1), arr[2](4), arr[3](7), arr[4](0),"
+ " arr[5](1), arr[6](2), arr[7](5), arr[8](8), arr[9](10)"
+ "]"),
+ njs_str("2,2,6,10,4,6,8,12,16,19") },
- { njs_str("{{}a = b--}"),
- njs_str("ReferenceError: \"a\" is not defined") },
+ { njs_str("var arr = [];"
+ ""
+ "for (let i = 0; i < 10; i++) {"
+ " arr.push( (n) => {i += n; return i} );"
+ "}"
+ ""
+ "["
+ " arr[0](2), arr[1](1), arr[2](4), arr[3](7), arr[4](0),"
+ " arr[5](1), arr[6](2), arr[7](5), arr[8](8), arr[9](10)"
+ "]"),
+ njs_str("2,2,6,10,4,6,8,12,16,19") },
- { njs_str("{{}a =}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("for (let i = 0; i < 1; i++) {"
+ " let i = i + 2;"
+ "}"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a +=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let arr = [], res = [];"
+ "for (let i = 0, f = function() { return i }; i < 5; i++) {"
+ " arr.push(f);"
+ "}"
+ "for (let i = 0; i < 5; i++) {"
+ " res.push(arr[i]());"
+ "} res"),
+ njs_str("0,0,0,0,0") },
- { njs_str("{{}a -=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let arr = [], res = [];"
+ "for (let i = 0; arr.push(() => i), i < 10; i++) {}"
+ "for (let k = 0; k < 10; k++) {res.push(arr[k]())}"
+ "res"),
+ njs_str("0,1,2,3,4,5,6,7,8,9") },
- { njs_str("{{}a *=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let res = [];"
+ "for (let n in [1,2,3]) {res.push(n)}"
+ "res"),
+ njs_str("0,1,2") },
- { njs_str("{{}a /=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let arr = [], res = [];"
+ ""
+ "for (let n in [1,2,3]) {"
+ " arr.push(() => n);"
+ "}"
+ ""
+ "for (let n in arr) {"
+ " res.push(arr[n]());"
+ "}"
+ "res"),
+ njs_str("0,1,2") },
- { njs_str("{{}a %=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let arr = [];"
+ ""
+ "for (let n in [1,2,3]) {"
+ " let n = 1;"
+ " arr.push(n);"
+ "}"
+ "arr"),
+ njs_str("1,1,1") },
- { njs_str("{{}a ===}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("for (let n in [1,2,3]) {"
+ " let n = n + 1;"
+ "}"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a ==}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("for (let n in [1,2,3]) {}"
+ "n"),
+ njs_str("ReferenceError: \"n\" is not defined") },
- { njs_str("{{}a !=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("for (let n in [1,n,3]) {}"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a !==}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("(function() {"
+ "function f() {return x + 1}"
+ "function abc() {f()};"
+ "abc();"
+ "let x;"
+ "}())"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a >}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("function func() {var x = 1; {let x = x + 1} } func()"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a <}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("if (false) let x = 1"),
+ njs_str("SyntaxError: let declaration cannot appear in a single-statement context in 1") },
- { njs_str("{{}a <=}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("while (false) let x = 1"),
+ njs_str("SyntaxError: let declaration cannot appear in a single-statement context in 1") },
- { njs_str("{{}a &&}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("for (;;) let x = 1"),
+ njs_str("SyntaxError: let declaration cannot appear in a single-statement context in 1") },
- { njs_str("{{}a ||}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("try {} catch (e) {let e}"),
+ njs_str("SyntaxError: \"e\" has already been declared in 1") },
- { njs_str("{{}a ??}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let arr = [], x = 2;"
+ "switch(true) {default: let x = 1; arr.push(x)}"
+ "arr.push(x); arr"),
+ njs_str("1,2") },
- { njs_str("{{}a &}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("switch(true) {case false: let x = 1; default: x = 2}"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}a |}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let res;"
+ "switch(true) {case true: let x = 1; default: x = 2; res = x} res"),
+ njs_str("2") },
- { njs_str("{{}a ^}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let null"),
+ njs_str("SyntaxError: Unexpected token \"null\" in 1") },
- { njs_str("{{}a <<}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let continue"),
+ njs_str("SyntaxError: Unexpected token \"continue\" in 1") },
- { njs_str("{{}a >>}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let undefined"),
+ njs_str("SyntaxError: \"undefined\" has already been declared in 1") },
- { njs_str("{{}new}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let a = 1; globalThis.a"),
+ njs_str("undefined") },
- { njs_str("{{}delete}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("if (false) {x = 2} else {x = 1} let x;"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("{{}void}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let let"),
+ njs_str("SyntaxError: Unexpected token \"let\" in 1") },
- { njs_str("{{}typeof}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("let null"),
+ njs_str("SyntaxError: Unexpected token \"null\" in 1") },
- { njs_str("{{} ({a: 1, b: {}\n}\n})\n}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 3") },
+ { njs_str("function let() {}"),
+ njs_str("SyntaxError: Unexpected token \"let\" in 1") },
- { njs_str("object?."),
- njs_str("SyntaxError: Unexpected end of input in 1") },
+ { njs_str("function static() {}"),
+ njs_str("SyntaxError: Unexpected token \"static\" in 1") },
- { njs_str("`${{a: 1, b}}`"),
- njs_str("ReferenceError: \"b\" is not defined") },
+ /* const */
- { njs_str("`${{a: 1, b:}}`"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("const x"),
+ njs_str("SyntaxError: missing initializer in const declaration") },
- { njs_str("`${{a: 1, b:,}}`"),
- njs_str("SyntaxError: Unexpected token \",\" in 1") },
+ { njs_str("const x = 1; x"),
+ njs_str("1") },
- { njs_str("`${{a: 1, b: 2,}}`"),
- njs_str("[object Object]") },
+ { njs_str("const x = 1; x = 1"),
+ njs_str("TypeError: assignment to constant variable") },
- { njs_str("`${{a: 1,, b: 2}}`"),
- njs_str("SyntaxError: Unexpected token \",\" in 1") },
+ { njs_str("function abc() {const x}"),
+ njs_str("SyntaxError: missing initializer in const declaration") },
- { njs_str("`${{f(){-} - {}}`"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("const x = [123]; x"),
+ njs_str("123") },
- { njs_str("for (;1-;) {}"),
- njs_str("SyntaxError: Unexpected token \";\" in 1") },
+ { njs_str("const x = () => x; x()"),
+ njs_str("[object Function]") },
- { njs_str("var str = String(str); str"),
- njs_str("undefined") },
+ { njs_str("const x = (() => x)()"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("var t = \"123\"; t = parseInt(t); t"),
- njs_str("123") },
+ { njs_str("x; const x = 123"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- /* Query String */
+ { njs_str("const x = x + 123"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz'}") },
+ { njs_str("const x; var x"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=');"
- "njs.dump(obj)"),
- njs_str("{baz:''}") },
+ { njs_str("const x; let x"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("let x; const x"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz'}") },
+ { njs_str("const x = 1; function x() {}"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('&baz=fuz');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz'}") },
+ { njs_str("function x() {} const x = 1"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('&&&&&baz=fuz');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz'}") },
+ { njs_str("function x() {const x; var x}"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('=fuz');"
- "njs.dump(obj)"),
- njs_str("{:'fuz'}") },
+ { njs_str("function x() {var x; const x}"),
+ njs_str("SyntaxError: \"x\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('=fuz=');"
- "njs.dump(obj)"),
- njs_str("{:'fuz='}") },
+ { njs_str("const x = function f() {const f = 1}"),
+ njs_str("undefined") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('===fu=z');"
- "njs.dump(obj)"),
- njs_str("{:'==fu=z'}") },
+ { njs_str("let res; const x = 1;"
+ "{const x = 2; res = x}"
+ "[x, res]"),
+ njs_str("1,2") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&baz=tax');"
- "njs.dump(obj)"),
- njs_str("{baz:['fuz','tax']}") },
+ { njs_str("let res; const x = 1;"
+ "if (true) {const x = 2; res = x}"
+ "[x, res]"),
+ njs_str("1,2") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('freespace');"
- "njs.dump(obj)"),
- njs_str("{freespace:''}") },
+ { njs_str("function func() {return x}"
+ "const x = 123;"
+ "func()"),
+ njs_str("123") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('name&value=12');"
- "njs.dump(obj)"),
- njs_str("{name:'',value:'12'}") },
+ { njs_str("function func() {return x}"
+ "func();"
+ "const x = 123"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', 'fuz');"
- "njs.dump(obj)"),
- njs_str("{baz:'',&muz:'tax'}") },
+ { njs_str("function func() {return () => x}"
+ "const x = 123;"
+ "func()()"),
+ njs_str("123") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', '');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("function func() {return () => x++}"
+ "const x = 123;"
+ "func()()"),
+ njs_str("TypeError: assignment to constant variable") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', null);"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("for (const i = 0; i < 1; i++) {}"),
+ njs_str("TypeError: assignment to constant variable") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', undefined);"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("let res = [];"
+ "for (const n in [1,2,3]) {res.push(n)}"
+ "res"),
+ njs_str("0,1,2") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz123muz=tax', 123);"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("let arr = [], res = [];"
+ ""
+ "for (const n in [1,2,3]) {"
+ " arr.push(() => n);"
+ "}"
+ ""
+ "for (let n in arr) {"
+ " res.push(arr[n]());"
+ "}"
+ "res"),
+ njs_str("0,1,2") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuzαααmuz=tax', 'ααα');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("let arr = [];"
+ ""
+ "for (const n in [1,2,3]) {"
+ " let n = 1;"
+ " arr.push(n);"
+ "}"
+ "arr"),
+ njs_str("1,1,1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', '=');"
- "njs.dump(obj)"),
- njs_str("{baz:'',fuz&muz:'',tax:''}") },
+ { njs_str("for (const n in [1,2,3]) {"
+ " let n = n + 1;"
+ "}"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', null, 'fuz');"
- "njs.dump(obj)"),
- njs_str("{baz=:'',muz=tax:''}") },
+ { njs_str("for (const n in [1,2,3]) {}"
+ "n"),
+ njs_str("ReferenceError: \"n\" is not defined") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', null, '&');"
- "njs.dump(obj)"),
- njs_str("{baz=fuz:'',muz=tax:''}") },
+ { njs_str("for (const n in [1,n,3]) {}"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz123fuz&muz123tax', null, 123);"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("(function() {"
+ "function f() {return x + 1}"
+ "function abc() {f()};"
+ "abc();"
+ "const x = 1;"
+ "}())"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('bazαααfuz&muzαααtax', null, 'ααα');"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz',muz:'tax'}") },
+ { njs_str("if (false) const x = 1"),
+ njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=fuz&muz=tax', null, null, {maxKeys: 1});"
- "njs.dump(obj)"),
- njs_str("{baz:'fuz'}") },
+ { njs_str("while (false) const x = 1"),
+ njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
- { njs_str("var qs = require('querystring'); var out = [];"
- "var obj = qs.parse('baz=fuz&muz=tax', null, null, {decodeURIComponent: (key) => {out.push(key)}});"
- "out.join('; ');"),
- njs_str("baz; fuz; muz; tax") },
+ { njs_str("for (;;) const x = 1"),
+ njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
- { njs_str("var qs = require('querystring'); var i = 0;"
- "var obj = qs.parse('baz=fuz&muz=tax', null, null, {decodeURIComponent: (key) => 'α' + i++});"
- "njs.dump(obj);"),
- njs_str("{α0:'α1',α2:'α3'}") },
+ { njs_str("try {} catch (e) {const e = 1}"),
+ njs_str("SyntaxError: \"e\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "qs.parse('baz=fuz&muz=tax', null, null, {decodeURIComponent: 123});"),
- njs_str("TypeError: option decodeURIComponent is not a function") },
+ { njs_str("let arr = []; const x = 2;"
+ "switch(true) {default: const x = 1; arr.push(x)}"
+ "arr.push(x); arr"),
+ njs_str("1,2") },
- { njs_str("var qs = require('querystring');"
- "qs.unescape = 123;"
- "qs.parse('baz=fuz&muz=tax');"),
- njs_str("TypeError: QueryString.unescape is not a function") },
+ { njs_str("let res;"
+ "switch(true) {case true: const x = 1; default: x = 2; res = x} res"),
+ njs_str("TypeError: assignment to constant variable") },
- { njs_str("var qs = require('querystring'); var out = [];"
- "qs.unescape = (key) => {out.push(key)};"
- "qs.parse('baz=fuz&muz=tax');"
- "out.join('; ');"),
- njs_str("baz; fuz; muz; tax") },
+ { njs_str("const null"),
+ njs_str("SyntaxError: Unexpected token \"null\" in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('ba%32z=f%32uz');"
- "njs.dump(obj)"),
- njs_str("{ba2z:'f2uz'}") },
+ { njs_str("const continue"),
+ njs_str("SyntaxError: Unexpected token \"continue\" in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('ba%32z=f%32uz');"
- "njs.dump(obj)"),
- njs_str("{ba2z:'f2uz'}") },
+ { njs_str("const undefined"),
+ njs_str("SyntaxError: \"undefined\" has already been declared in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('ba%F0%9F%92%A9z=f%F0%9F%92%A9uz');"
- "njs.dump(obj)"),
- njs_str("{ba💩z:'f💩uz'}") },
+ { njs_str("const a = 1; globalThis.a"),
+ njs_str("undefined") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('======');"
- "njs.dump(obj)"),
- njs_str("{:'====='}") },
+ { njs_str("if (false) {x = 2} else {x = 1} const x = 0"),
+ njs_str("ReferenceError: cannot access variable before initialization") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=%F0%9F%A9');"
- "njs.dump(obj)"),
- njs_str("{baz:'�'}") },
+ { njs_str("const const"),
+ njs_str("SyntaxError: Unexpected token \"const\" in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=αααααα%\x00\x01\x02αααα');"
- "njs.dump(obj)"),
- njs_str("{baz:'αααααα%\\u0000\\u0001\\u0002αααα'}") },
+ /* Async/Await */
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=%F6α');"
- "njs.dump(obj)"),
- njs_str("{baz:'�α'}") },
+ { njs_str("async function f() {}; f.prototype"),
+ njs_str("undefined") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=%F6');"
- "njs.dump(obj)"),
- njs_str("{baz:'�'}") },
+ { njs_str("async function f() {await 1}"),
+ njs_str("undefined") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=%FG');"
- "njs.dump(obj)"),
- njs_str("{baz:'%FG'}") },
+ { njs_str("function f() {await 1}"),
+ njs_str("SyntaxError: await is only valid in async functions in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=%F');"
- "njs.dump(obj)"),
- njs_str("{baz:'%F'}") },
+ { njs_str("async function f() {function a() {await 1}}"),
+ njs_str("SyntaxError: await is only valid in async functions in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('baz=%');"
- "njs.dump(obj)"),
- njs_str("{baz:'%'}") },
+ { njs_str("async function f() {() => {await 1}}"),
+ njs_str("SyntaxError: await is only valid in async functions in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = qs.parse('ba+z=f+uz');"
- "njs.dump(obj)"),
- njs_str("{ba z:'f uz'}") },
-
-
- { njs_str("var qs = require('querystring');"
- "qs.parse('X='+'α'.repeat(33)).X.length"),
- njs_str("33") },
+ { njs_str("function f() {async () => {await 1}}"),
+ njs_str("undefined") },
- { njs_str("var qs = require('querystring');"
- "var x = qs.parse('X='+'α1'.repeat(33)).X;"
- "[x.length, x[33], x[34]]"),
- njs_str("66,1,α") },
+ { njs_str("let f = async () => {await 1}"),
+ njs_str("undefined") },
- { njs_str("var qs = require('querystring');"
- "var s = qs.parse('X='+String.bytesFrom(Array(16).fill(0x9d))).X;"
- "[s.length, s.toUTF8().length, s[15]]"),
- njs_str("16,48,�") },
+ { njs_str("let f = () => {await 1}"),
+ njs_str("SyntaxError: await is only valid in async functions in 1") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz'})"),
- njs_str("baz=fuz") },
+ { njs_str("(async function() {await 1})"),
+ njs_str("[object AsyncFunction]") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'})"),
- njs_str("baz=fuz&muz=tax") },
+ { njs_str("(function() {await 1})"),
+ njs_str("SyntaxError: await is only valid in async functions in 1") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baαz': 'fαuz', 'muαz': 'tαax'});"),
- njs_str("ba%CE%B1z=f%CE%B1uz&mu%CE%B1z=t%CE%B1ax") },
+ { njs_str("let ctor = Object.getPrototypeOf(async function(){}).constructor;"
+ "ctor"),
+ njs_str("[object Function]") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': ['fuz', 'tax']})"),
- njs_str("baz=fuz&baz=tax") },
+ { njs_str("let ctor = Object.getPrototypeOf(async function(){}).constructor;"
+ "ctor()"),
+ njs_str("[object AsyncFunction]") },
- { njs_str("var qs = require('querystring');"
- njs_declare_sparse_array("arr", 2)
- "arr[0] = 0; arr[1] = 1.5;"
- "qs.stringify({'baz': arr})"),
- njs_str("baz=0&baz=1.5") },
+ { njs_str("let ctor = Object.getPrototypeOf(async function(){}).constructor;"
+ "new ctor();"),
+ njs_str("[object AsyncFunction]") },
- { njs_str("var qs = require('querystring'); var out = [];"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, null, null, {encodeURIComponent: (key) => {out.push(key)}});"
- "out.join('; ')"),
- njs_str("baz; fuz; muz; tax") },
+ { njs_str("let f = new Function('x', 'await 1; return x'); f(1)"),
+ njs_str("SyntaxError: await is only valid in async functions in runtime:1") },
- { njs_str("var qs = require('querystring'); "
- "qs.stringify({a: 'b'}, null, null, "
- " {encodeURIComponent: () => String.bytesFrom([0x9d])})"),
- njs_str("TypeError: got non-UTF8 string from encoder") },
+ { njs_str("new AsyncFunction()"),
+ njs_str("ReferenceError: \"AsyncFunction\" is not defined") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, null, null, {encodeURIComponent: 123});"
- "out.join('; ')"),
- njs_str("TypeError: option encodeURIComponent is not a function") },
+ { njs_str("(async function() {console.log(await 111)})"),
+ njs_str("SyntaxError: await in arguments not supported in 1") },
- { njs_str("var qs = require('querystring');"
- "qs.escape = 123;"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'})"),
- njs_str("TypeError: QueryString.escape is not a function") },
+ { njs_str("(async function() {console.log('Number: ' + await 111)})"),
+ njs_str("SyntaxError: await in arguments not supported in 1") },
- { njs_str("var qs = require('querystring'); var out = [];"
- "qs.escape = (key) => {out.push(key)};"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'});"
- "out.join('; ')"),
- njs_str("baz; fuz; muz; tax") },
+ { njs_str("function f(a) {}"
+ "(async function() {f(await 111)})"),
+ njs_str("SyntaxError: await in arguments not supported in 1") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, '****')"),
- njs_str("baz=fuz****muz=tax") },
+ { njs_str("async () => [await x(1)(),]; async () => [await x(1)()]"),
+ njs_str("[object AsyncFunction]") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, null, '^^^^')"),
- njs_str("baz^^^^fuz&muz^^^^tax") },
+ { njs_str("function f(a, b, c) {}"
+ "(async function() {f(1, 'a', await 111)})"),
+ njs_str("SyntaxError: await in arguments not supported in 1") },
- { njs_str("var qs = require('querystring');"
- "var obj = {A:'α'}; obj['δ'] = 'D';"
- "var s = qs.stringify(obj,'γ=','&β'); [s, s.length]"),
- njs_str("A&β%CE%B1γ=%CE%B4&βD,20") },
+ { njs_str("function f(a) {}"
+ "(async function() {f('Number: ' + await 111)})"),
+ njs_str("SyntaxError: await in arguments not supported in 1") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, '', '')"),
- njs_str("baz=fuz&muz=tax") },
+ { njs_str("async function af() {await encrypt({},}"),
+ njs_str("SyntaxError: Unexpected token \"}\" in 1") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, undefined, undefined)"),
- njs_str("baz=fuz&muz=tax") },
+ { njs_str("let x = {async af() {await Promise.resolve(1)}}; x.af"),
+ njs_str("[object AsyncFunction]") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, '?', '/')"),
- njs_str("baz/fuz?muz/tax") },
+ { njs_str("let name = 'af', x = {async [name]() {await Promise.resolve(1)}}; x.af"),
+ njs_str("[object AsyncFunction]") },
+};
- { njs_str("var qs = require('querystring');"
- "qs.stringify('123')"),
- njs_str("") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify(123)"),
- njs_str("") },
+static njs_unit_test_t njs_safe_test[] =
+{
+ { njs_str("(new Function('return this'))() === globalThis"),
+ njs_str("true") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({X: String.bytesFrom(Array(4).fill(0x9d))})"),
- njs_str("X=%9D%9D%9D%9D") },
+ { njs_str("(new Function('return this;'))() === globalThis"),
+ njs_str("true") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({X:{toString(){return 3}}})"),
- njs_str("X=") },
+ { njs_str("(new Function('return this '))() === globalThis"),
+ njs_str("true") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify({ name: undefined, age: 12 })"),
- njs_str("name=&age=12") },
+ { njs_str("(new Function('return thi'))()"),
+ njs_str("TypeError: function constructor is disabled in \"safe\" mode") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify(Object.create({ name: undefined, age: 12 }))"),
- njs_str("") },
+ { njs_str("(new Function('){return 1337})//', 'return this'))()"),
+ njs_str("TypeError: function constructor is disabled in \"safe\" mode") },
+};
- { njs_str("var qs = require('querystring');"
- "qs.stringify([])"),
- njs_str("") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify(['','',''])"),
- njs_str("0=&1=&2=") },
+static njs_unit_test_t njs_denormals_test[] =
+{
+ { njs_str("2.2250738585072014e-308"),
+ njs_str("2.2250738585072014e-308") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify([undefined, null, Symbol(), Object(0), Object('test'), Object(false),,,])"),
- njs_str("0=&1=&2=&3=&4=&5=") },
+#ifndef NJS_SUNC
+ { njs_str("2.2250738585072014E-308.toString(2) == ('0.' + '0'.repeat(1021) + '1')"),
+ njs_str("true") },
-#if 0
- { njs_str("var qs = require('querystring');"
- "qs.stringify([NaN, Infinity, -Infinity, 2**69, 2**70])"),
- njs_str("0=&1=&2=&3=590295810358705700000&4=1.1805916207174113e%2B21") },
-#else
- { njs_str("var qs = require('querystring');"
- "qs.stringify([NaN, Infinity, -Infinity, 2**69, 2**70])"),
- njs_str("0=&1=&2=&3=590295810358705700000&4=1.1805916207174114e%2B21") },
-#endif
+ { njs_str("Number('2.2250738585072014E-323')"),
+ njs_str("2.5e-323") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify([[1,2,3],[4,5,6]])"),
- njs_str("0=1&0=2&0=3&1=4&1=5&1=6") },
+ { njs_str("Number('2.2250738585072014E-323') + 0"),
+ njs_str("2.5e-323") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify([['a',,,],['b',,,]])"),
- njs_str("0=a&0=&0=&1=b&1=&1=") },
+ /* Smallest positive double (next_double(0)). */
+ { njs_str("5E-324.toString(36) === '0.' + '0'.repeat(207) + '3'"),
+ njs_str("true") },
- { njs_str("var qs = require('querystring');"
- "qs.stringify([[,'a','b',,]])"),
- njs_str("0=&0=a&0=b&0=") },
+ /* Maximum fraction length. */
+ { njs_str("2.2250738585072014E-323.toString(2) == ('0.' + '0'.repeat(1071) + '101')"),
+ njs_str("true") },
- { njs_str("var qs = require('querystring');"
- "qs.escape('abcααααdef')"),
- njs_str("abc%CE%B1%CE%B1%CE%B1%CE%B1def") },
+ /* Denormals. */
+ { njs_str("var zeros = count => '0'.repeat(count);"
+ "["
+ " [1.8858070859709815e-308, `0.${zeros(1022)}1101100011110111011100000100011001111101110001010111`],"
+ // FIXME: " [Number.MIN_VALUE, `0.${zeros(1073)}1`]"
+ " [-5.06631661953108e-309, `-0.${zeros(1024)}11101001001010000001101111010101011111111011010111`],"
+ " [6.22574126804e-313, `0.${zeros(1037)}11101010101101100111000110100111001`],"
+ " [-4e-323, `-0.${zeros(1070)}1`],"
+ "].every(t=>t[0].toString(2) === t[1])"),
+ njs_str("true") },
- { njs_str("var qs = require('querystring');"
- "qs.unescape('abc%CE%B1%CE%B1%CE%B1%CE%B1def')"),
- njs_str("abcααααdef") },
+ { njs_str("4.94065645841246544176568792868e-324.toExponential()"),
+ njs_str("5e-324") },
- /* TextEncoder. */
+ { njs_str("4.94065645841246544176568792868e-324.toExponential(10)"),
+ njs_str("4.9406564584e-324") },
+#endif
- { njs_str("var en = new TextEncoder(); typeof en.encode()"),
- njs_str("object") },
+};
- { njs_str("var en = new TextEncoder(); en.encode()"),
- njs_str("") },
- { njs_str("var en = new TextEncoder(); var res = en.encode('α'); res"),
- njs_str("206,177") },
+static njs_unit_test_t njs_disabled_denormals_test[] =
+{
+ { njs_str("Number('2.2250738585072014E-323')"),
+ njs_str("0") },
- { njs_str("var en = new TextEncoder(); var res = en.encode('α1α'); res[2]"),
- njs_str("49") },
+ { njs_str("Number('2.2250738585072014E-323') + 0"),
+ njs_str("0") },
- { njs_str("var en = new TextEncoder(); en.encode(String.bytesFrom([0xCE]))"),
- njs_str("239,191,189") },
+ /* Smallest positive double (next_double(0)). */
+ { njs_str("5E-324.toString(36)"),
+ njs_str("0") },
- { njs_str("var en = new TextEncoder();"
- "en.encode(String.bytesFrom([0xCE, 0xB1, 0xCE]))"),
- njs_str("206,177,239,191,189") },
+ { njs_str("2.2250738585072014E-323.toString(2)"),
+ njs_str("0") },
- { njs_str("var en = new TextEncoder();"
- "en.encode(String.bytesFrom([0xCE, 0xCE, 0xB1]))"),
- njs_str("239,191,189,206,177") },
+ /* Smallest normal double. */
- { njs_str("var en = new TextEncoder(); en.encoding"),
- njs_str("utf-8") },
+ { njs_str("2.2250738585072014e-308"),
+ njs_str("2.2250738585072014e-308") },
- { njs_str("TextEncoder.prototype.encode.apply({}, [])"),
- njs_str("TypeError: \"this\" is not a TextEncoder") },
+ { njs_str("2.2250738585072014e-308/2"),
+ njs_str("0") },
- { njs_str("var en = new TextEncoder();"
- "var utf8 = new Uint8Array(5);"
- "var res = en.encodeInto('ααααα', utf8); njs.dump(res)"),
- njs_str("{read:2,written:4}") },
-
- { njs_str("var en = new TextEncoder();"
- "var utf8 = new Uint8Array(10);"
- "var res = en.encodeInto('ααααα', utf8); njs.dump(res)"),
- njs_str("{read:5,written:10}") },
-
- { njs_str("var en = new TextEncoder();"
- "var utf8 = new Uint8Array(10);"
- "en.encodeInto('ααααα', utf8.subarray(2)); utf8[0]"),
- njs_str("0") },
+ /* Denormals. */
+ { njs_str("["
+ "1.8858070859709815e-308,"
+ "-5.06631661953108e-309,"
+ "6.22574126804e-313,"
+ "-4e-323,"
+ "].map(v=>v.toString(2))"),
+ njs_str("0,0,0,0") },
+};
- { njs_str("var str = String.bytesFrom([0xCE]);"
- "var en = new TextEncoder();"
- "var utf8 = new Uint8Array(3);"
- "var res = en.encodeInto(str, utf8); "
- "[njs.dump(res), utf8]"),
- njs_str("{read:1,written:3},239,191,189") },
- { njs_str("var str = String.bytesFrom([0xCE]);"
- "var en = new TextEncoder();"
- "var utf8 = new Uint8Array(5);"
- "en.encodeInto(str, utf8); utf8"),
- njs_str("239,191,189,0,0") },
+static njs_unit_test_t njs_fs_module_test[] =
+{
+ { njs_str("var fs = require('fs'); typeof fs"),
+ njs_str("object") },
- { njs_str("var str = String.bytesFrom([0xCE, 0xB1, 0xCE]);"
- "var en = new TextEncoder();"
- "var utf8 = new Uint8Array(5);"
- "var res = en.encodeInto(str, utf8);"
- "[njs.dump(res), utf8]"),
- njs_str("{read:2,written:5},206,177,239,191,189") },
+ { njs_str("var fs = require('fs'); Object.isExtensible(fs)"),
+ njs_str("true") },
- { njs_str("var str = String.bytesFrom([0xCE, 0xCE, 0xB1]);"
- "var en = new TextEncoder();"
- "var utf8 = new Uint8Array(5);"
- "var res = en.encodeInto(str, utf8);"
- "[njs.dump(res), utf8]"),
- njs_str("{read:2,written:5},239,191,189,206,177") },
+ { njs_str("require('fs') === require('fs')"),
+ njs_str("true") },
- { njs_str("TextEncoder.prototype.encodeInto.apply({}, [])"),
- njs_str("TypeError: \"this\" is not a TextEncoder") },
+ { njs_str("require('fs').a = 1; require('fs').a"),
+ njs_str("1") },
- { njs_str("(new TextEncoder()).encodeInto('', 0.12) "),
- njs_str("TypeError: The \"destination\" argument must be an instance of Uint8Array") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile()"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- /* TextDecoder. */
+ { njs_str("var fs = require('fs');"
+ "var path = Buffer.from('/broken'); path[3] = 0;"
+ "fs.readFile(path)"),
+ njs_str("TypeError: \"path\" must be a Buffer without null bytes") },
- { njs_str("var de = new TextDecoder();"
- "var u8arr = new Uint8Array([240, 160, 174, 183]);"
- "var u16arr = new Uint16Array(u8arr.buffer);"
- "var u32arr = new Uint32Array(u8arr.buffer);"
- "[u8arr, u16arr, u32arr].map(v=>de.decode(v)).join(',')"),
- njs_str("𠮷,𠮷,𠮷") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile('/njs_unknown_path')"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("var de = new TextDecoder();"
- "[new Uint8Array([240, 160]), "
- " new Uint8Array([174]), "
- " new Uint8Array([183])].map(v=>de.decode(v, {stream: 1}))[2]"),
- njs_str("𠮷") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile('/njs_unknown_path', 'utf8')"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("var de = new TextDecoder();"
- "de.decode(new Uint8Array([240, 160]), {stream: 1});"
- "de.decode(new Uint8Array([174]), {stream: 1});"
- "de.decode(new Uint8Array([183]))"),
- njs_str("𠮷") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile('/njs_unknown_path', {flag:'xx'})"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("var de = new TextDecoder();"
- "de.decode(new Uint8Array([240, 160]), {stream: 1});"
- "de.decode()"),
- njs_str("�") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile('/njs_unknown_path', {flag:'xx'}, 1)"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("var de = new TextDecoder('utf-8', {fatal: true});"
- "de.decode(new Uint8Array([240, 160]))"),
- njs_str("TypeError: The encoded data was not valid") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile('/njs_unknown_path', {flag:'xx'}, function () {})"),
+ njs_str("TypeError: Unknown file open flags: \"xx\"") },
- { njs_str("var de = new TextDecoder('utf-8', {fatal: false});"
- "de.decode(new Uint8Array([240, 160]))"),
- njs_str("�") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile('/njs_unknown_path', {encoding:'ascii'}, function () {})"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var en = new TextEncoder();"
- "var de = new TextDecoder('utf-8', {ignoreBOM: true});"
- "en.encode(de.decode(new Uint8Array([239, 187, 191, 50])))"),
- njs_str("239,187,191,50") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFile('/njs_unknown_path', 'ascii', function () {})"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var en = new TextEncoder();"
- "var de = new TextDecoder('utf-8', {ignoreBOM: false});"
- "en.encode(de.decode(new Uint8Array([239, 187, 191, 50])))"),
- njs_str("50") },
+ /* require('fs').readFileSync() */
- { njs_str("var en = new TextEncoder(); var de = new TextDecoder();"
- "en.encode(de.decode(new Uint8Array([239, 187, 191, 50])))"),
- njs_str("50") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFileSync()"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- { njs_str("var de = new TextDecoder(); de.decode('')"),
- njs_str("TypeError: The \"input\" argument must be an instance of TypedArray") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFileSync({})"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- { njs_str("var de = new TextDecoder({})"),
- njs_str("RangeError: The \"[object Object]\" encoding is not supported") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFileSync('/njs_unknown_path', {flag:'xx'})"),
+ njs_str("TypeError: Unknown file open flags: \"xx\"") },
- { njs_str("var de = new TextDecoder('foo')"),
- njs_str("RangeError: The \"foo\" encoding is not supported") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFileSync(Buffer.from('/njs_unknown_path'), {encoding:'ascii'})"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var de = new TextDecoder(); de.encoding"),
- njs_str("utf-8") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFileSync('/njs_unknown_path', 'ascii')"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var de = new TextDecoder(); de.fatal"),
- njs_str("false") },
+ { njs_str("var fs = require('fs');"
+ "fs.readFileSync('/njs_unknown_path', true)"),
+ njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
- { njs_str("var de = new TextDecoder(); de.ignoreBOM"),
- njs_str("false") },
- { njs_str("TextDecoder.prototype.decode.apply({}, new Uint8Array([1]))"),
- njs_str("TypeError: \"this\" is not a TextDecoder") },
+ /* require('fs').writeFile() */
- { njs_str("var de = new TextDecoder();"
- "var buf = new Uint32Array([1,2,3]).buffer;"
- "var en = new TextEncoder();"
- "njs.dump(new Uint32Array(en.encode(de.decode(buf)).buffer))"),
- njs_str("Uint32Array [1,2,3]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile()"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- { njs_str("var de = new TextDecoder();"
- "var buf = new Uint32Array([1,2,3]).subarray(1,2);"
- "var en = new TextEncoder();"
- "njs.dump(new Uint32Array(en.encode(de.decode(buf)).buffer))"),
- njs_str("Uint32Array [2]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile({}, '', function () {})"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- /* Buffer */
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path')"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("new Buffer();"),
- njs_str("TypeError: Buffer is not a constructor") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path', '')"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("var buf = Buffer.alloc();"),
- njs_str("TypeError: \"size\" argument must be of type number") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path', '', undefined)"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("var buf = Buffer.alloc('best buffer');"),
- njs_str("TypeError: \"size\" argument must be of type number") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path', '', 'utf8')"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("var buf = Buffer.alloc(-1);"),
- njs_str("RangeError: invalid size") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path', '', {flag:'xx'}, function () {})"),
+ njs_str("TypeError: Unknown file open flags: \"xx\"") },
- { njs_str("var buf = Buffer.alloc(4); njs.dump(buf)"),
- njs_str("Buffer [0,0,0,0]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path', '', {encoding:'ascii'}, function () {})"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var buf = Buffer.alloc(4, 88); buf"),
- njs_str("XXXX") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path', '', 'ascii', function () {})"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var buf = Buffer.alloc(4, 945); njs.dump(buf)"),
- njs_str("Buffer [177,177,177,177]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFile('/njs_unknown_path', '', true, function () {})"),
+ njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
- { njs_str("var buf = Buffer.alloc(4, -1); njs.dump(buf)"),
- njs_str("Buffer [255,255,255,255]") },
+ /* require('fs').writeFileSync() */
- { njs_str("var buf = Buffer.alloc(4, -1, 'utf-128'); njs.dump(buf)"),
- njs_str("Buffer [255,255,255,255]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFileSync()"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- { njs_str("var buf = Buffer.alloc(10, 'α'); buf"),
- njs_str("ααααα") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFileSync({}, '')"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- { njs_str("var buf = Buffer.alloc(4, 'α'); njs.dump(buf)"),
- njs_str("Buffer [206,177,206,177]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFileSync('/njs_unknown_path', '', {flag:'xx'})"),
+ njs_str("TypeError: Unknown file open flags: \"xx\"") },
- { njs_str("var buf = Buffer.alloc(2, 'ααααα'); njs.dump(buf)"),
- njs_str("Buffer [206,177]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFileSync('/njs_unknown_path', '', {encoding:'ascii'})"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var buf = Buffer.alloc(1, 'α'); njs.dump(buf)"),
- njs_str("Buffer [206]") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFileSync('/njs_unknown_path', '', 'ascii')"),
+ njs_str("TypeError: \"ascii\" encoding is not supported") },
- { njs_str("var buf = Buffer.alloc(4, 'ZXZpbA==', 'base64'); buf"),
- njs_str("evil") },
+ { njs_str("var fs = require('fs');"
+ "fs.writeFileSync('/njs_unknown_path', '', true)"),
+ njs_str("TypeError: Unknown options type: \"boolean\" (a string or object required)") },
- { njs_str("var buf = Buffer.alloc(8, 'ZXZpbA==', 'base64'); buf"),
- njs_str("evilevil") },
+ /* require('fs').renameSync() */
- { njs_str("var buf = Buffer.alloc(8, 'evil', 'utf-128'); buf"),
- njs_str("TypeError: \"utf-128\" encoding is not supported") },
+ { njs_str("var fs = require('fs');"
+ "fs.renameSync()"),
+ njs_str("TypeError: \"oldPath\" must be a string or Buffer") },
- { njs_str("var foo = new Uint8Array(10).fill(88);"
- "var buf = Buffer.alloc(8, foo); buf"),
- njs_str("XXXXXXXX") },
+ { njs_str("var fs = require('fs');"
+ "fs.renameSync('/njs_unknown_path')"),
+ njs_str("TypeError: \"newPath\" must be a string or Buffer") },
- { njs_str("[1,2,10,20].every(v => {"
- " var src = new Uint16Array(v).fill(0xB1CE);"
- " var buf = Buffer.alloc(10, src);"
- " return buf.toString() === " njs_evar("'ααααα'", "'�αααα�'")
- "})"),
- njs_str("true") },
+ { njs_str("var fs = require('fs');"
+ "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
+ ".map((x) => { try { fs.renameSync(x, '/njs_unknown_path'); } "
+ " catch (e) { return (e instanceof TypeError); } })"
+ ".every((x) => x === true)"),
+ njs_str("true")},
- { njs_str("var foo = Buffer.alloc(10, 'α');"
- "var buf = Buffer.alloc(4, foo); buf"),
- njs_str("αα") },
+ { njs_str("var fs = require('fs');"
+ "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
+ ".map((x) => { try { fs.renameSync('/njs_unknown_path', x); } "
+ " catch (e) { return (e instanceof TypeError); } })"
+ ".every((x) => x === true)"),
+ njs_str("true")},
- { njs_str("var buf = Buffer.allocUnsafe(10).fill('α'); buf"),
- njs_str("ααααα") },
+ /* require('fs').access() */
- { njs_str("var buf = Buffer.allocUnsafe(-1)"),
- njs_str("RangeError: invalid size") },
+ { njs_str("var fs = require('fs');"
+ "fs.access()"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- { njs_str("["
- " ['6576696c', 'hex', 4],"
- " ['6576696', 'hex', 3],"
- " ['', 'hex', 0],"
- " ['', 'base64', 0],"
- " ['ZXZpbA==', 'base64', 4],"
- " ['ZXZpbA', 'base64url', 4],"
- " ['ααααα', undefined, 10],"
- "].every(args => Buffer.byteLength(args[0], args[1]) == args[2])"),
- njs_str("true") },
+ { njs_str("var fs = require('fs');"
+ "fs.access('/njs_unknown_path')"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("Buffer.from([])"),
- njs_str("") },
+ { njs_str("var fs = require('fs');"
+ "fs.access('/njs_unknown_path', fs.constants.F_OK)"),
+ njs_str("TypeError: \"callback\" must be a function") },
- { njs_str("Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])"),
- njs_str("buffer") },
+ { njs_str("var fs = require('fs');"
+ "fs.access('/njs_unknown_path', 'fail', function () {})"),
+ njs_str("TypeError: \"mode\" must be a number") },
- { njs_str(njs_declare_sparse_array("arr", 6)
- "[0x62, 0x75, 0x66, 0x66, 0x65, 0x72].map((v, i) => {arr[i] = v;});"
- "Buffer.from(arr)"),
- njs_str("buffer") },
+ /* require('fs').accessSync() */
- { njs_str("Buffer.from({length:3, 0:0x62, 1:0x75, 2:0x66})"),
- njs_str("buf") },
+ { njs_str("var fs = require('fs');"
+ "fs.accessSync()"),
+ njs_str("TypeError: \"path\" must be a string or Buffer") },
- { njs_str("njs.dump(Buffer.from([-1,1,255,22323,-Infinity,Infinity,NaN]))"),
- njs_str("Buffer [255,1,255,51,0,0,0]") },
+ { njs_str("var fs = require('fs');"
+ "fs.accessSync('/njs_unknown_path', 'fail')"),
+ njs_str("TypeError: \"mode\" must be a number") },
- { njs_str("var buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); njs.dump(buf)"),
- njs_str("Buffer [98,117,102,102,101,114]") },
+ { njs_str("var "
+ "fs = require('fs'),"
+ "func = ["
+ "'access',"
+ "'accessSync',"
+ "'readFile',"
+ "'readFileSync',"
+ "'writeFile',"
+ "'writeFileSync',"
+ "'appendFile',"
+ "'appendFileSync',"
+ "'rename',"
+ "'renameSync',"
+ "'symlink',"
+ "'symlinkSync',"
+ "'unlink',"
+ "'unlinkSync',"
+ "'realpath',"
+ "'realpathSync',"
+ "'mkdir',"
+ "'mkdirSync',"
+ "'rmdir',"
+ "'rmdirSync',"
+ "'readdir',"
+ "'readdirSync',"
+ "],"
+ "test = (fname) =>"
+ "[undefined, null, false, NaN, Symbol(), {}, Object('/njs_unknown_path')]"
+ ".map((x) => { try { fs[fname](x); } "
+ " catch (e) { return (e instanceof TypeError); } })"
+ ".every((x) => x === true);"
+ "func.map(test).every((x) => x)"),
+ njs_str("true")},
- { njs_str("var buf = Buffer.from([1,2,3]); njs.dump(Buffer.from(buf.toJSON()))"),
- njs_str("Buffer [1,2,3]") },
+ /* require('fs').promises */
- { njs_str("["
- " {type: 'B'},"
- " {type: undefined},"
- " {type:'Buffer'},"
- " {type:'Buffer', data:null},"
- " {type:'Buffer', data:{}},"
- "].every(v=>{ try { Buffer.from(v)} catch(e) {return e.name == 'TypeError'}})"),
- njs_str("true") },
+ { njs_str("var fs = require('fs');"
+ "typeof fs.promises"),
+ njs_str("object") },
- { njs_str("var foo = new Uint16Array(2);"
- "foo[0] = 5000; foo[1] = 4000;"
- "var buf = Buffer.from(foo.buffer);"
- "foo[1] = 6000;"
- "njs.dump(buf)"),
- njs_str("Buffer [" njs_evar("136,19,112,23", "19,136,23,112") "]") },
+ { njs_str("var "
+ "fs = require('fs').promises,"
+ "func = ["
+ "'access',"
+ "'readFile',"
+ "'writeFile',"
+ "'appendFile',"
+ "'rename',"
+ "'symlink',"
+ "'unlink',"
+ "'realpath',"
+ "'mkdir',"
+ "'rmdir',"
+ "'readdir',"
+ "];"
+ "func.every((x) => typeof fs[x] == 'function')"),
+ njs_str("true")},
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, 1); njs.dump(buf)"),
- njs_str("Buffer [" njs_evar("3,182,3", "182,3,182") "]") },
+ /* require('fs').constants */
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, -1); njs.dump(buf)"),
- njs_str("RangeError: invalid index") },
+ { njs_str("var fs = require('fs');"
+ "typeof fs.constants"),
+ njs_str("object") },
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, 5); njs.dump(buf)"),
- njs_str("RangeError: \"offset\" is outside of buffer bounds") },
+ { njs_str("var "
+ "fsc = require('fs').constants,"
+ "items = ["
+ "'F_OK',"
+ "'R_OK',"
+ "'W_OK',"
+ "'X_OK',"
+ "];"
+ "items.every((x) => typeof fsc[x] == 'number')"),
+ njs_str("true")},
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, 2, 1); njs.dump(buf)"),
- njs_str("Buffer [" njs_evar("182", "3") "]") },
+ /* require('fs').Dirent */
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, 2, -1); njs.dump(buf)"),
- njs_str("Buffer []") },
+ { njs_str("var fs = require('fs');"
+ "typeof fs.Dirent"),
+ njs_str("function") },
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, 2, 3); njs.dump(buf)"),
- njs_str("RangeError: \"length\" is outside of buffer bounds") },
+ { njs_str("var fs = require('fs');"
+ "fs.Dirent('file', 123)"),
+ njs_str("TypeError: the Dirent constructor must be called with new") },
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, 2, 0); njs.dump(buf)"),
- njs_str("Buffer []") },
+ { njs_str("var fs = require('fs');"
+ "var e = new fs.Dirent('file', 123); [e.name, e.type]"),
+ njs_str("file,123") },
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, 2, 2); njs.dump(buf)"),
- njs_str("Buffer [" njs_evar("182,3", "3,182") "]") },
+ { njs_str("var "
+ "fs = require('fs'),"
+ "e = new fs.Dirent('file', 0),"
+ "func = ["
+ "'isDirectory',"
+ "'isFile',"
+ "'isBlockDevice',"
+ "'isCharacterDevice',"
+ "'isSymbolicLink',"
+ "'isFIFO',"
+ "'isSocket',"
+ "];"
+ "func.every((x) => typeof e[x] == 'function')"),
+ njs_str("true")},
+};
- { njs_str("var foo = new Uint16Array(2).fill(950);"
- "var buf = Buffer.from(foo.buffer, '2', '2'); njs.dump(buf)"),
- njs_str("Buffer [" njs_evar("182,3", "3,182") "]") },
- { njs_str("var foo = new Uint32Array(1).fill(0xF1F2F3F4);"
- "var buf = Buffer.from(foo); njs.dump(buf)"),
- njs_str("Buffer [244]") },
+static njs_unit_test_t njs_crypto_module_test[] =
+{
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "[Object.prototype.toString.call(h), njs.dump(h),h]"),
+ njs_str("[object Hash],Hash {},[object Hash]") },
- { njs_str("var foo = new Uint32Array(2).fill(0xF1F2F3F4);"
- "var buf = Buffer.from(foo); njs.dump(buf)"),
- njs_str("Buffer [244,244]") },
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "var Hash = h.constructor; "
+ "Hash('sha1').update('AB').digest('hex')"),
+ njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d") },
- { njs_str("var foo = new Uint8Array(5);"
- "foo[0] = 1; foo[1] = 2; foo[2] = 3; foo[3] = 4; foo[4] = 5;"
- "foo = foo.subarray(1, 3);"
- "var buf = Buffer.from(foo); njs.dump(buf)"),
- njs_str("Buffer [2,3]") },
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "h.constructor.name"),
+ njs_str("Hash") },
- { njs_str("var buf = Buffer.from(''); njs.dump(buf)"),
- njs_str("Buffer []") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'md5');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hash().update('AB').digest().toString(e);"
+ " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hash().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("b86fc6b051f63d73de262d4c34e3a0a9,"
+ "uG/GsFH2PXPeJi1MNOOgqQ==,"
+ "uG_GsFH2PXPeJi1MNOOgqQ") },
- { njs_str("var buf = Buffer.from('α'); njs.dump(buf)"),
- njs_str("Buffer [206,177]") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hash().update('4142', 'hex').digest().toString(e);"
+ " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hash().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("06d945942aa26a61be18c3e22bf19bbca8dd2b5d,"
+ "BtlFlCqiamG+GMPiK/GbvKjdK10=,"
+ "BtlFlCqiamG-GMPiK_GbvKjdK10") },
- { njs_str("var arr = new Array(1,2,3); arr.valueOf = () => arr;"
- "njs.dump(Buffer.from(arr))"),
- njs_str("Buffer [1,2,3]") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
+ "['hex', 'base64', 'base64url'].every(e => {"
+ " var h = hash().digest(e);"
+ " var h2 = hash().update('').digest(e);"
+ " if (h !== h2) {throw new Error(`digest($e):$h != update('').digest($e):$h2`)};"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("var obj = new Object(); obj.valueOf = () => obj;"
- "Buffer.from(obj)"),
- njs_str("TypeError: first argument object is not a string or Buffer-like object") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha1');"
+ "["
+ " ['AB'],"
+ " ['4142', 'hex'],"
+ " ['QUI=', 'base64'],"
+ " ['QUI', 'base64url']"
+ "].every(args => {"
+ " return hash().update(args[0], args[1]).digest('hex') === '06d945942aa26a61be18c3e22bf19bbca8dd2b5d';"
+ "})"),
+ njs_str("true") },
- { njs_str("var obj = new Object(); obj.valueOf = () => undefined;"
- "njs.dump(Buffer.from(obj))"),
- njs_str("TypeError: first argument undefined is not a string or Buffer-like object") },
+ { njs_str("var hash = require('crypto').createHash.bind(undefined, 'sha256');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hash().update('AB').digest().toString(e);"
+ " var h2 = hash().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hash().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("38164fbd17603d73f696b8b4d72664d735bb6a7c88577687fd2ae33fd6964153,"
+ "OBZPvRdgPXP2lri01yZk1zW7anyIV3aH/SrjP9aWQVM=,"
+ "OBZPvRdgPXP2lri01yZk1zW7anyIV3aH_SrjP9aWQVM") },
- { njs_str("var arr = new Array(1,2,3); arr.valueOf = () => null;"
- "njs.dump(Buffer.from(arr))"),
- njs_str("Buffer [1,2,3]") },
+ { njs_str("var hash = require('crypto').createHash;"
+ "njs.dump(['', 'abc'.repeat(100)].map(v => {"
+ " return ['md5', 'sha1', 'sha256'].map(h => {"
+ " return hash(h).update(v).digest('hex');"
+ " })"
+ "}))"),
+ njs_str("[['d41d8cd98f00b204e9800998ecf8427e',"
+ "'da39a3ee5e6b4b0d3255bfef95601890afd80709',"
+ "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'],"
+ "['f571117acbd8153c8dc3c81b8817773a',"
+ "'c95466320eaae6d19ee314ae4f135b12d45ced9a',"
+ "'d9f5aeb06abebb3be3f38adec9a2e3b94228d52193be923eb4e24c9b56ee0930']]") },
- { njs_str("var obj = new Object(); obj.valueOf = () => new Array(1,2,3);"
- "njs.dump(Buffer.from(obj))"),
- njs_str("Buffer [1,2,3]") },
+ { njs_str("var h = require('crypto').createHash()"),
+ njs_str("TypeError: algorithm must be a string") },
- { njs_str("njs.dump(Buffer.from(new String('test')))"),
- njs_str("Buffer [116,101,115,116]") },
+ { njs_str("var h = require('crypto').createHash([])"),
+ njs_str("TypeError: algorithm must be a string") },
- { njs_str("["
- " ['6576696c', 'hex'],"
- " ['ZXZpbA==', 'base64'],"
- " ['ZXZpbA==#', 'base64'],"
- " ['ZXZpbA', 'base64url'],"
- " ['ZXZpbA##', 'base64url'],"
- "].every(args => Buffer.from(args[0], args[1]) == 'evil')"),
+ { njs_str("var h = require('crypto').createHash('sha512')"),
+ njs_str("TypeError: not supported algorithm: \"sha512\"") },
+
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "h.update()"),
+ njs_str("TypeError: data argument \"undefined\" is not a string or Buffer-like object") },
+
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "h.update({})"),
+ njs_str("TypeError: data argument \"object\" is not a string or Buffer-like object") },
+
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "h.update('A').digest('latin1')"),
+ njs_str("TypeError: Unknown digest encoding: \"latin1\"") },
+
+ { njs_str("require('crypto').createHash('sha1').digest() instanceof Buffer"),
njs_str("true") },
- { njs_str("var buf = Buffer.from(String.bytesFrom([0xF3])); buf"),
- njs_str("�") },
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "h.update('A').digest('hex'); h.digest('hex')"),
+ njs_str("Error: Digest already called") },
- { njs_str("Buffer.from('', 'utf-128')"),
- njs_str("TypeError: \"utf-128\" encoding is not supported") },
+ { njs_str("var h = require('crypto').createHash('sha1');"
+ "h.update('A').digest('hex'); h.update('B')"),
+ njs_str("Error: Digest already called") },
- { njs_str("[Buffer.from('α'), new Uint8Array(10), {}, 1]"
- ".map(v=>Buffer.isBuffer(v))"),
- njs_str("true,false,false,false") },
+ { njs_str("typeof require('crypto').createHash('md5')"),
+ njs_str("object") },
- { njs_str("['utf8', 'utf-8', 'hex', 'base64', 'base64url', 'utf-88', '1hex']"
- ".map(v=>Buffer.isEncoding(v))"),
- njs_str("true,true,true,true,true,false,false") },
+ { njs_str("var h = require('crypto').createHmac('sha1', '');"
+ "[Object.prototype.toString.call(h), njs.dump(h),h]"),
+ njs_str("[object Hmac],Hmac {},[object Hmac]") },
- { njs_str("["
- " ['ABC', 'ABCD', -1],"
- " ['ABCD', 'ABC', 1],"
- " ['ABC', 'ACB', -1],"
- " ['ACB', 'ABC', 1],"
- " ['ABC', 'ABC', 0],"
- " ['', 'ABC', -1],"
- " ['', '', 0],"
- "].every(args => {"
- " if (Buffer.compare(Buffer.from(args[0]), Buffer.from(args[1])) != args[2]) {"
- " throw new TypeError("
- " `Buffer.compare(Buffer.from(${args[0]}), Buffer.from(${args[1]})) != ${args[2]}`);"
- " }"
- " return true;"
+ { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'md5', '');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hmac().update('AB').digest().toString(e);"
+ " var h2 = hmac().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hmac().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
"})"),
- njs_str("true") },
+ njs_str("9e0e9e545ef63d41dfb653daecf8ebc7,"
+ "ng6eVF72PUHftlPa7Pjrxw==,"
+ "ng6eVF72PUHftlPa7Pjrxw") },
- { njs_str("["
- " ['ABC', 'ABCD', -1],"
- " ['ABCD', 'ABC', 1],"
- " ['ABC', 'ACB', -1],"
- " ['ACB', 'ABC', 1],"
- " ['ABC', 'ABC', 0],"
- " ['', 'ABC', -1],"
- " ['', '', 0],"
- "].every(args => {"
- " if (Buffer.from(args[0]).compare(Buffer.from(args[1])) != args[2]) {"
- " throw new TypeError("
- " `Buffer.from(${args[0]}).compare(Buffer.from(${args[1]})) != ${args[2]}`);"
- " }"
- " return true;"
+ { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'sha1', '');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hmac().update('AB').digest().toString(e);"
+ " var h2 = hmac().update(Buffer.from('XABX').subarray(1,3)).digest(e);"
+ " var h3 = hmac().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
"})"),
- njs_str("true") },
+ njs_str("d32c0b6637cc2dfe4670f3fe48ef4434123c4810,"
+ "0ywLZjfMLf5GcPP+SO9ENBI8SBA=,"
+ "0ywLZjfMLf5GcPP-SO9ENBI8SBA") },
- { njs_str("var buf = Buffer.from('ABCD');"
+ { njs_str("var hash = require('crypto').createHmac.bind(undefined, 'sha1', '');"
"["
- " [0,3,0,2, -1],"
- " [0,2,0,3, 1],"
- " [3,4,3,4, 0],"
- " [undefined, undefined, undefined, undefined, 0],"
- " [-1, undefined, undefined, undefined, 'invalid index'],"
- " [0, -1, undefined, undefined, 'invalid index'],"
- " [0, 0, -1, undefined, 'invalid index'],"
- " [0, 0, 0, -1, 'invalid index'],"
- "]"
- ".every(as => {"
- " try {"
- " if (buf.compare(buf, as[0], as[1], as[2], as[3]) != as[4]) {"
- " throw new TypeError("
- " `buf.compare(${as[0]}, ${as[1]}, ${as[2]}, ${as[3]}) != ${as[4]}`);"
- " }"
- " } catch (e) { return e.message == as[4]}"
- " return true;"
+ " ['AB'],"
+ " ['4142', 'hex'],"
+ " ['QUI=', 'base64'],"
+ " ['QUI', 'base64url']"
+ "].every(args => {"
+ " return hash().update(args[0], args[1]).digest('hex') === 'd32c0b6637cc2dfe4670f3fe48ef4434123c4810';"
"})"),
njs_str("true") },
- { njs_str("var buf1 = Buffer.from('ABCD');"
- "var buf2 = Buffer.from('ABCD');"
- "buf1.compare(buf2, 5)"),
- njs_str("RangeError: \"targetStart\" is out of range: 5") },
-
- { njs_str("var buf1 = Buffer.from('ABCD');"
- "var buf2 = Buffer.from('ABCD');"
- "buf1.compare(buf2, 0, 3, 5)"),
- njs_str("RangeError: \"sourceStart\" is out of range: 5") },
+ { njs_str("var hmac = require('crypto').createHmac.bind(undefined, 'sha256', '');"
+ "['hex', 'base64', 'base64url'].map(e => {"
+ " var h = hmac().update('AB').digest().toString(e);"
+ " var h2 = hmac().update(Buffer.from('AB')).digest(e);"
+ " var h3 = hmac().update('A').update('B').digest(e);"
+ " if (h !== h2) {throw new Error(`digest().toString($e):$h != digest($e):$h2`)};"
+ " if (h !== h3) {throw new Error(`digest().toString($e):$h != update('A').update('B').digest($e):$h3`)};"
+ " return h;"
+ "})"),
+ njs_str("d53400095496267cf02e5dbd4b0bf9fbfb5f36f311ea7d9809af5487421743e3,"
+ "1TQACVSWJnzwLl29Swv5+/tfNvMR6n2YCa9Uh0IXQ+M=,"
+ "1TQACVSWJnzwLl29Swv5-_tfNvMR6n2YCa9Uh0IXQ-M") },
- { njs_str("var arr = new Uint8Array(4);"
- "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
- "arr = arr.subarray(1, 4);"
- "var buf = Buffer.from('ABCD');"
- "buf.compare(arr, 0, 3, 1, 4)"),
- njs_str("0") },
+ { njs_str("var hmac = require('crypto').createHmac;"
+ "njs.dump(['', 'abc'.repeat(100)].map(v => {"
+ " return ['md5', 'sha1', 'sha256'].map(h => {"
+ " return hmac(h, Buffer.from('secret')).update(v).digest('hex');"
+ " })"
+ "}))"),
+ njs_str("[['5c8db03f04cec0f43bcb060023914190',"
+ "'25af6174a0fcecc4d346680a72b7ce644b9a88e8',"
+ "'f9e66e179b6747ae54108f82f8ade8b3c25d76fd30afde6c395822c530196169'],"
+ "['91eb74a225cdd3bbfccc34396c6e3ac5',"
+ "'0aac71e3a813a7acc4a809cfdedb2ecba04ffc5e',"
+ "'8660d2d51d6f20f61d5aadfb6c43df7fd05fc2fc4967d8aec1846f3d9ec03987']]") },
- { njs_str("['123', 'abc', '124', '', 'AB', 'ABCD']"
- ".map(v=>Buffer.from(v)).sort(Buffer.compare).map(v=>v.toString())"),
- njs_str(",123,124,AB,ABCD,abc") },
+ { njs_str("var h = require('crypto').createHmac('sha1', '');"
+ "var Hmac = h.constructor; "
+ "Hmac('sha1', '').digest('hex')"),
+ njs_str("fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") },
- { njs_str("Buffer.compare(Buffer.alloc(1), 'text')"),
- njs_str("TypeError: \"target\" argument must be an instance of Buffer or Uint8Array") },
+ { njs_str("var h = require('crypto').createHmac('sha1', '');"
+ "h.constructor.name"),
+ njs_str("Hmac") },
- { njs_str("Buffer.compare('text', Buffer.from('ACB'))"),
- njs_str("TypeError: \"source\" argument must be an instance of Buffer or Uint8Array") },
+ { njs_str("require('crypto').createHmac('sha1', '').digest() instanceof Buffer"),
+ njs_str("true") },
- { njs_str("Buffer.concat()"),
- njs_str("TypeError: \"list\" argument must be an instance of Array") },
+ { njs_str("var h = require('crypto').createHmac('sha256', 'A'.repeat(64));"
+ "h.update('AB').digest('hex')"),
+ njs_str("ee9dce43b12eb3e865614ad9c1a8d4fad4b6eac2b64647bd24cd192888d3f367") },
- { njs_str("Buffer.concat([])"),
- njs_str("") },
+ { njs_str("var h = require('crypto').createHmac('sha256', 'A'.repeat(100));"
+ "h.update('AB').digest('hex')"),
+ njs_str("5647b6c429701ff512f0f18232b4507065d2376ca8899a816a0a6e721bf8ddcc") },
- { njs_str("Buffer.concat([new Uint16Array(10)])"),
- njs_str("TypeError: \"list[0]\" argument must be an instance of Buffer or Uint8Array") },
+ { njs_str("var h = require('crypto').createHmac()"),
+ njs_str("TypeError: algorithm must be a string") },
- { njs_str("Buffer.concat([new Uint8Array(2), new Uint8Array(1)]).fill('abc')"),
- njs_str("abc") },
+ { njs_str("var h = require('crypto').createHmac([])"),
+ njs_str("TypeError: algorithm must be a string") },
- { njs_str("Buffer.concat([Buffer.from('AB'), Buffer.from('CD')])"),
- njs_str("ABCD") },
-
- { njs_str("Buffer.concat([new Uint8Array(2), new Uint8Array(1)], 2).fill('abc')"),
- njs_str("ab") },
+ { njs_str("var h = require('crypto').createHmac('sha512', '')"),
+ njs_str("TypeError: not supported algorithm: \"sha512\"") },
- { njs_str("Buffer.concat([new Uint8Array(2), new Uint8Array(1)], 6).fill('abc')"),
- njs_str("abcabc") },
+ { njs_str("var h = require('crypto').createHmac('sha1', [])"),
+ njs_str("TypeError: key argument \"array\" is not a string or Buffer-like object") },
- { njs_str(njs_declare_sparse_array("list", 2)
- "list[0] = new Uint8Array(2); list[1] = new Uint8Array(3);"
- "Buffer.concat(list).fill('ab');"),
- njs_str("ababa") },
+ { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
+ "h.update('A').digest('hex'); h.digest('hex')"),
+ njs_str("Error: Digest already called") },
- { njs_str("Buffer.concat([], '123')"),
- njs_str("TypeError: \"length\" argument must be of type number") },
+ { njs_str("var h = require('crypto').createHmac('sha1', 'secret key');"
+ "h.update('A').digest('hex'); h.update('B')"),
+ njs_str("Error: Digest already called") },
- { njs_str("Buffer.concat([], -1)"),
- njs_str("RangeError: \"length\" is out of range") },
+ { njs_str("typeof require('crypto').createHmac('md5', 'a')"),
+ njs_str("object") },
- { njs_str("var buf = Buffer.from('α'); buf[1]"),
- njs_str("177") },
+ { njs_str("var cr = require('crypto'); var h = cr.createHash('sha1');"
+ "h.update.call(cr.createHmac('sha1', 's'), '')"),
+ njs_str("TypeError: \"this\" is not a hash object") },
+};
- { njs_str("var buf = Buffer.from('α'); buf[1] = 1; njs.dump(buf)"),
- njs_str("Buffer [206,1]") },
+static njs_unit_test_t njs_querystring_module_test[] =
+{
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz'}") },
- { njs_str("var arrBuf = new ArrayBuffer(16);"
- "var buf = Buffer.from(arrBuf); buf.buffer === arrBuf"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=');"
+ "njs.dump(obj)"),
+ njs_str("{baz:''}") },
- { njs_str("["
- " [[0], 4, '65,66,67,68,0,0,0,0,0,0'],"
- " [[5], 4, '0,0,0,0,0,65,66,67,68,0'],"
- " [[8], 2, '0,0,0,0,0,0,0,0,65,66'],"
- " [[8,2,4], 2, '0,0,0,0,0,0,0,0,67,68'],"
- " [[10], 0, '0,0,0,0,0,0,0,0,0,0'],"
- "]"
- ".every(args => {"
- " var buf1 = Buffer.from('ABCD');"
- " var buf2 = Buffer.alloc(10, 0);"
- " var as = args[0];"
- " var length = buf1.copy(buf2, as[0], as[1], as[2]);"
- ""
- " if (length != args[1]) {"
- " throw new TypeError(`buf1.copy(buf2, ${as[0]}, ${as[1]}, ${as[2]}): ${length} != ${args[1]}`)"
- " }"
- ""
- " if (njs.dump(buf2) != `Buffer [${args[2]}]`) {"
- " throw new TypeError("
- " `buf1.copy(buf2, ${as[0]}, ${as[1]}, ${as[2]}): ${njs.dump(buf2)} != Buffer [${args[2]}]`);"
- " }"
- " return true;"
- "})"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("["
- " [[0], 'ABCDEF'],"
- " [[0,2], 'CDEFEF'],"
- " [[0,2,6], 'CDEFEF'],"
- " [[1,2,4], 'ACDDEF'],"
- " [[1,2,3], 'ACCDEF']"
- "]"
- ".every(args => {"
- " var buf = Buffer.from('ABCDEF');"
- " var as = args[0];"
- " buf.copy(buf, as[0], as[1], as[2]);"
- ""
- " if (buf.toString() != args[1]) {"
- " throw new TypeError("
- " `buf.copy(buf, ${as[0]}, ${as[1]}, ${as[2]}): buf.toString() != ${args[1]}`);"
- " }"
- " return true;"
- "})"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz'}") },
- { njs_str("var buf1 = Buffer.from('ABCD');"
- "var buf2 = Buffer.alloc(10, 0);"
- "buf1.copy(buf2, -1)"),
- njs_str("RangeError: invalid index") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('&baz=fuz');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz'}") },
- { njs_str("var buf1 = Buffer.from('ABCD');"
- "var buf2 = Buffer.alloc(10, 0);"
- "buf1.copy(buf2, 0, -1)"),
- njs_str("RangeError: invalid index") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('&&&&&baz=fuz');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz'}") },
- { njs_str("var buf1 = Buffer.from('ABCD');"
- "var buf2 = Buffer.alloc(10, 0);"
- "buf1.copy(buf2, 0, 5)"),
- njs_str("RangeError: \"sourceStart\" is out of range: 5") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('=fuz');"
+ "njs.dump(obj)"),
+ njs_str("{:'fuz'}") },
- { njs_str("var arr = new Uint8Array(4);"
- "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
- "arr = arr.subarray(1, 4);"
- "var buf1 = Buffer.from(arr);"
- "var buf2 = Buffer.alloc(10, 0);"
- "var length = buf1.copy(buf2, 1, 1, 2); [length, njs.dump(buf2)]"),
- njs_str("1,Buffer [0,67,0,0,0,0,0,0,0,0]") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('=fuz=');"
+ "njs.dump(obj)"),
+ njs_str("{:'fuz='}") },
- { njs_str("var arr = new Uint8Array(4);"
- "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
- "arr = arr.subarray(1, 4);"
- "var buf1 = Buffer.from(arr);"
- "var buf2 = Buffer.alloc(10, 0);"
- "var length = buf1.copy(buf2, 1, 1, 2); [length, njs.dump(buf2)]"),
- njs_str("1,Buffer [0,67,0,0,0,0,0,0,0,0]") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('===fu=z');"
+ "njs.dump(obj)"),
+ njs_str("{:'==fu=z'}") },
- { njs_str("["
- " ['ABC', 'ABCD', false],"
- " ['ABCD', 'ABC', false],"
- " ['ABC', 'ACB', false],"
- " ['ACB', 'ABC', false],"
- " ['ABC', 'ABC', true],"
- " ['', 'ABC', false],"
- " ['', '', true],"
- "].every(args => {"
- " if (Buffer.from(args[0]).equals(Buffer.from(args[1])) != args[2]) {"
- " throw new TypeError("
- " `Buffer.from(${args[0]}).compare(Buffer.from(${args[1]})) != ${args[2]}`);"
- " }"
- " return true;"
- "})"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&baz=tax');"
+ "njs.dump(obj)"),
+ njs_str("{baz:['fuz','tax']}") },
- { njs_str("Buffer.from([1,2]).equals(new ArrayBuffer(1))"),
- njs_str("TypeError: \"target\" argument must be an instance of Buffer or Uint8Array") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('freespace');"
+ "njs.dump(obj)"),
+ njs_str("{freespace:''}") },
- { njs_str("Buffer.from([1,2]).equals(1)"),
- njs_str("TypeError: \"target\" argument must be an instance of Buffer or Uint8Array") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('name&value=12');"
+ "njs.dump(obj)"),
+ njs_str("{name:'',value:'12'}") },
- { njs_str("var buf = Buffer.alloc(4);"
- "buf.fill('ZXZpbA==', 'base64')"),
- njs_str("evil") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', 'fuz');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'',&muz:'tax'}") },
- { njs_str("var buf = Buffer.alloc(4);"
- "buf.fill('6576696c', 'hex')"),
- njs_str("evil") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', '');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("var buf = Buffer.alloc(4);"
- "buf.fill('ZXZpbA==', '')"),
- njs_str("TypeError: \"\" encoding is not supported") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', null);"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("var buf = Buffer.alloc(8);"
- "buf.fill('6576696c', 'hex')"),
- njs_str("evilevil") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', undefined);"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("var buf = Buffer.alloc(10);"
- "buf.fill('evil')"),
- njs_str("evilevilev") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz123muz=tax', 123);"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("var buf = Buffer.allocUnsafe(5);"
- "buf[3] = 1;"
- "buf.fill(''); njs.dump(buf)"),
- njs_str("Buffer [0,0,0,0,0]") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuzαααmuz=tax', 'ααα');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("var arr = new Uint8Array(4);"
- "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
- "arr = arr.subarray(1, 4);"
- "var buf = Buffer.allocUnsafe(6);"
- "buf.fill(arr); njs.dump(buf)"),
- njs_str("Buffer [66,67,68,66,67,68]") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', '=');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'',fuz&muz:'',tax:''}") },
- { njs_str("var buf = Buffer.alloc(6, 'ABCDEF');"
- "buf.fill(buf, 2, 6)"),
- njs_str("ABABCD") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', null, 'fuz');"
+ "njs.dump(obj)"),
+ njs_str("{baz=:'',muz=tax:''}") },
- { njs_str("Buffer.alloc(6).fill(0x41)"),
- njs_str("AAAAAA") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', null, '&');"
+ "njs.dump(obj)"),
+ njs_str("{baz=fuz:'',muz=tax:''}") },
- { njs_str("Buffer.alloc(6).fill({valueOf(){return 0x42}})"),
- njs_str("BBBBBB") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz123fuz&muz123tax', null, 123);"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("njs.dump(Buffer.alloc(3).fill(-1))"),
- njs_str("Buffer [255,255,255]") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('bazαααfuz&muzαααtax', null, 'ααα');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz',muz:'tax'}") },
- { njs_str("[NaN, Infinity, -Infinity, undefined, null, {}]"
- ".every(v => njs.dump(Buffer.alloc(3).fill(v)) == 'Buffer [0,0,0]')"),
- njs_str("true") },
-
- { njs_str("njs.dump(Buffer.alloc(6).fill({valueOf(){throw 'Oops'}}, 4,3))"),
- njs_str("Buffer [0,0,0,0,0,0]") },
-
- { njs_str("njs.dump(Buffer.alloc(6).fill({valueOf(){throw 'Oops'}}, 3,3))"),
- njs_str("Buffer [0,0,0,0,0,0]") },
-
- { njs_str("njs.dump(Buffer.alloc(6).fill({valueOf(){throw 'Oops'}}, 2,3))"),
- njs_str("Oops") },
-
- { njs_str("njs.dump(Buffer.alloc(5).fill('α'))"),
- njs_str("Buffer [206,177,206,177,206]") },
-
- { njs_str("Buffer.alloc(4).fill('ABCD', -1)"),
- njs_str("RangeError: invalid index") },
-
- { njs_str("Buffer.alloc(4).fill('ABCD', 5)"),
- njs_str("RangeError: \"offset\" is out of range") },
-
- { njs_str("Buffer.alloc(4).fill('ABCD', 0, -1)"),
- njs_str("RangeError: invalid index") },
-
- { njs_str("Buffer.alloc(4).fill('ABCD', 0, 5)"),
- njs_str("RangeError: \"end\" is out of range") },
-
- { njs_str("Buffer.alloc(513).fill('A'.repeat(512)).length"),
- njs_str("513") },
-
- { njs_str("njs.dump(Buffer.alloc(4).fill((new Uint8Array(5)).fill(1)))"),
- njs_str("Buffer [1,1,1,1]") },
-
- { njs_str("var src = new Uint8Array(10).fill(255);"
- "var u8 = new Uint8Array(src.buffer, 1, 8);"
- "u8.set([1,2,3,4,5,6,7,8]);"
- "njs.dump(Buffer.alloc(9).fill(u8))"),
- njs_str("Buffer [1,2,3,4,5,6,7,8,1]") },
-
- { njs_str("Buffer.alloc(513).fill((new Uint8Array(512)).fill(1)).length"),
- njs_str("513") },
-
- { njs_str("Buffer.alloc(4).fill('ABCD', undefined, undefined, 'utf-128')"),
- njs_str("TypeError: \"utf-128\" encoding is not supported") },
-
- { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 3);"
- "buf1.fill('B', 1, 2); njs.dump(buf1)"),
- njs_str("Buffer [66,66]") },
-
- { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 3);"
- "buf1.fill(0x42, 1, 2); njs.dump(buf1)"),
- njs_str("Buffer [66,66]") },
-
- { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 2);"
- "var buf2 = Buffer.from('ABCD').subarray(1, 3);"
- "buf2.fill(buf1, 1, 2); njs.dump(buf2)"),
- njs_str("Buffer [66,66]") },
-
- { njs_str("var buf = Buffer.from('ABCD');"
- "['BC', 'CB', 'ABCD', 'ABCDE', ''].map(v=>buf.indexOf(v))"),
- njs_str("1,-1,0,-1,0") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=fuz&muz=tax', null, null, {maxKeys: 1});"
+ "njs.dump(obj)"),
+ njs_str("{baz:'fuz'}") },
- { njs_str("var buf = Buffer.from('ABCD');"
- "[0,5,-2,-1].map(v=>buf.indexOf('C', v))"),
- njs_str("2,-1,2,-1") },
+ { njs_str("var qs = require('querystring'); var out = [];"
+ "var obj = qs.parse('baz=fuz&muz=tax', null, null, {decodeURIComponent: (key) => {out.push(key)}});"
+ "out.join('; ');"),
+ njs_str("baz; fuz; muz; tax") },
- { njs_str("var buf = Buffer.from('evil');"
- "buf.indexOf('ZXZpbA==', undefined, 'base64')"),
- njs_str("0") },
+ { njs_str("var qs = require('querystring'); var i = 0;"
+ "var obj = qs.parse('baz=fuz&muz=tax', null, null, {decodeURIComponent: (key) => 'α' + i++});"
+ "njs.dump(obj);"),
+ njs_str("{α0:'α1',α2:'α3'}") },
- { njs_str("var buf = Buffer.from('evil');"
- "buf.indexOf('6576696c', undefined, 'hex')"),
- njs_str("0") },
+ { njs_str("var qs = require('querystring');"
+ "qs.parse('baz=fuz&muz=tax', null, null, {decodeURIComponent: 123});"),
+ njs_str("TypeError: option decodeURIComponent is not a function") },
- { njs_str("var buf = Buffer.from('ABCD');"
- "buf.indexOf('C', undefined, 'utf-128')"),
- njs_str("TypeError: \"utf-128\" encoding is not supported") },
+ { njs_str("var qs = require('querystring');"
+ "qs.unescape = 123;"
+ "qs.parse('baz=fuz&muz=tax');"),
+ njs_str("TypeError: QueryString.unescape is not a function") },
- { njs_str("var buf = Buffer.from('ABCDABC');"
- "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.indexOf(Buffer.from(v)))"),
- njs_str("1,-1,0,-1,0,2,-1") },
+ { njs_str("var qs = require('querystring'); var out = [];"
+ "qs.unescape = (key) => {out.push(key)};"
+ "qs.parse('baz=fuz&muz=tax');"
+ "out.join('; ');"),
+ njs_str("baz; fuz; muz; tax") },
- { njs_str("var buf = Buffer.from('ABCDABC');"
- "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.includes(Buffer.from(v)))"),
- njs_str("true,false,true,false,true,true,false") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('ba%32z=f%32uz');"
+ "njs.dump(obj)"),
+ njs_str("{ba2z:'f2uz'}") },
- { njs_str("var buf = Buffer.from('ZABCDABC').subarray(1);"
- "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.indexOf(Buffer.from(v)))"),
- njs_str("1,-1,0,-1,0,2,-1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('ba%32z=f%32uz');"
+ "njs.dump(obj)"),
+ njs_str("{ba2z:'f2uz'}") },
- { njs_str("var buf = Buffer.from('ABCD');"
- "buf.indexOf(0x43)"),
- njs_str("2") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('ba%F0%9F%92%A9z=f%F0%9F%92%A9uz');"
+ "njs.dump(obj)"),
+ njs_str("{ba💩z:'f💩uz'}") },
- { njs_str("var buf = Buffer.from('ABCD');"
- "buf.indexOf(0x43, -2)"),
- njs_str("2") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('======');"
+ "njs.dump(obj)"),
+ njs_str("{:'====='}") },
- { njs_str("var buf = Buffer.from('ABCD');"
- "buf.indexOf(0x43, -1)"),
- njs_str("-1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=%F0%9F%A9');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'�'}") },
- { njs_str("var buf1 = Buffer.from('ABCD');"
- "var buf2 = Buffer.from('XXCX').subarray(2, 3);"
- "buf1.indexOf(buf2)"),
- njs_str("2") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=αααααα%\x00\x01\x02αααα');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'αααααα%\\u0000\\u0001\\u0002αααα'}") },
- { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 4);"
- "buf1.indexOf(0x43)"),
- njs_str("1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=%F6α');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'�α'}") },
- { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 4);"
- "buf1.indexOf('C')"),
- njs_str("1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=%F6');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'�'}") },
- { njs_str("var buf = Buffer.from('ABCDABC');"
- "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(v))"),
- njs_str("5,-1,0,-1,7,6,-1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=%FG');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'%FG'}") },
- { njs_str("var buf = Buffer.from('ABCDABC');"
- "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(Buffer.from(v)))"),
- njs_str("5,-1,0,-1,7,6,-1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=%F');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'%F'}") },
- { njs_str("var buf = Buffer.from('ZABCDABC').subarray(1);"
- "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(v))"),
- njs_str("5,-1,0,-1,7,6,-1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('baz=%');"
+ "njs.dump(obj)"),
+ njs_str("{baz:'%'}") },
- { njs_str("var buf = Buffer.from('ZABCDABC').subarray(1);"
- "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(Buffer.from(v)))"),
- njs_str("5,-1,0,-1,7,6,-1") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = qs.parse('ba+z=f+uz');"
+ "njs.dump(obj)"),
+ njs_str("{ba z:'f uz'}") },
- { njs_str("var buf = Buffer.from('CABCD');"
- "[2,-2,1,-10,10,-5,-4,0].map(v=>buf.lastIndexOf('C', v))"),
- njs_str("0,3,0,-1,3,0,0,0") },
- { njs_str("var buf = Buffer.from('CABCD');"
- "[2,-2,1,-10,10,-5,-4,0].map(v=>buf.lastIndexOf(Buffer.from('CZ').subarray(0,1), v))"),
- njs_str("0,3,0,-1,3,0,0,0") },
+ { njs_str("var qs = require('querystring');"
+ "qs.parse('X='+'α'.repeat(33)).X.length"),
+ njs_str("33") },
- { njs_str("var buf = Buffer.from('CABCD');"
- "buf.lastIndexOf(0x43)"),
- njs_str("3") },
+ { njs_str("var qs = require('querystring');"
+ "var x = qs.parse('X='+'α1'.repeat(33)).X;"
+ "[x.length, x[33], x[34]]"),
+ njs_str("66,1,α") },
- { njs_str("var buf = Buffer.from('CABCD');"
- "[2,1,0,4,5,-1,-5].map(v=>buf.lastIndexOf(0x43, v))"),
- njs_str("0,0,0,3,3,3,0") },
+ { njs_str("var qs = require('querystring');"
+ "var s = qs.parse('X='+String.bytesFrom(Array(16).fill(0x9d))).X;"
+ "[s.length, s.toUTF8().length, s[15]]"),
+ njs_str("16,48,�") },
- { njs_str("var buf1 = Buffer.from('ACBCD').subarray(1, 4);"
- "var buf2 = Buffer.from('C');"
- "buf1.lastIndexOf(buf2)"),
- njs_str("2") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz'})"),
+ njs_str("baz=fuz") },
- { njs_str("var buf1 = Buffer.from('XXCXX').subarray(2,3);"
- "buf1.lastIndexOf(Buffer.from('X'))"),
- njs_str("-1") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'})"),
+ njs_str("baz=fuz&muz=tax") },
- { njs_str("var buf = Buffer.from('ACBCD').subarray(1, 4);"
- "buf.lastIndexOf(0x43)"),
- njs_str("2") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baαz': 'fαuz', 'muαz': 'tαax'});"),
+ njs_str("ba%CE%B1z=f%CE%B1uz&mu%CE%B1z=t%CE%B1ax") },
- { njs_str("var buf = Buffer.from('ACBCD').subarray(1, 4);"
- "buf.lastIndexOf('C')"),
- njs_str("2") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': ['fuz', 'tax']})"),
+ njs_str("baz=fuz&baz=tax") },
- { njs_str("['swap16', 'swap32', 'swap64'].every(method => {"
- " var buf = Buffer.from([]);"
- " buf[method]();"
- " return njs.dump(buf) === 'Buffer []';"
- "})"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ njs_declare_sparse_array("arr", 2)
+ "arr[0] = 0; arr[1] = 1.5;"
+ "qs.stringify({'baz': arr})"),
+ njs_str("baz=0&baz=1.5") },
- { njs_str("['swap16', 'swap32', 'swap64'].every(method => {"
- " var buf = Buffer.from([1,2,3]);"
- " try { buf[method]() } "
- " catch(e) {return e.message === `Buffer size must be a multiple of ${method.substr(4)}-bits`};"
- "})"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring'); var out = [];"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, null, null, {encodeURIComponent: (key) => {out.push(key)}});"
+ "out.join('; ')"),
+ njs_str("baz; fuz; muz; tax") },
- { njs_str("['swap16', 'swap32', 'swap64'].map(method => {"
- " var buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);"
- " buf[method]();"
- " return njs.dump(buf);"
- "})"),
- njs_str("Buffer [2,1,4,3,6,5,8,7],"
- "Buffer [4,3,2,1,8,7,6,5],"
- "Buffer [8,7,6,5,4,3,2,1]") },
+ { njs_str("var qs = require('querystring'); "
+ "qs.stringify({a: 'b'}, null, null, "
+ " {encodeURIComponent: () => String.bytesFrom([0x9d])})"),
+ njs_str("TypeError: got non-UTF8 string from encoder") },
- { njs_str("['swap16', 'swap32', 'swap64'].map(method => {"
- " var u8 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]);"
- " var buf = Buffer.from(u8.buffer, 1);"
- " buf[method]();"
- " return njs.dump(buf);"
- "})"),
- njs_str("Buffer [2,1,4,3,6,5,8,7],"
- "Buffer [4,3,2,1,8,7,6,5],"
- "Buffer [8,7,6,5,4,3,2,1]") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, null, null, {encodeURIComponent: 123});"
+ "out.join('; ')"),
+ njs_str("TypeError: option encodeURIComponent is not a function") },
- { njs_str("njs.dump(Buffer.from('αααα').toJSON())"),
- njs_str("{type:'Buffer',data:[206,177,206,177,206,177,206,177]}") },
+ { njs_str("var qs = require('querystring');"
+ "qs.escape = 123;"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'})"),
+ njs_str("TypeError: QueryString.escape is not a function") },
- { njs_str("njs.dump(Buffer.from('').toJSON())"),
- njs_str("{type:'Buffer',data:[]}") },
+ { njs_str("var qs = require('querystring'); var out = [];"
+ "qs.escape = (key) => {out.push(key)};"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'});"
+ "out.join('; ')"),
+ njs_str("baz; fuz; muz; tax") },
- { njs_str("["
- " [['base64'], 'ZXZpbA=='],"
- " [['base64url'], 'ZXZpbA'],"
- " [['hex'], '6576696c'],"
- " [[undefined,1,3], 'vi'],"
- " [[undefined,5], ''],"
- " [[undefined,undefined,5], 'evil'],"
- " [[undefined,undefined,undefined], 'evil'],"
- "].every(args => {"
- " var buf = Buffer.from('evil');"
- " var as = args[0];"
- " if (buf.toString(as[0], as[1], as[2]) != args[1]) {"
- " throw new TypeError("
- " `buf.toString(${as[0]}, ${as[1]}, ${as[2]}) != ${args[1]}`);"
- " }"
- " return true;"
- "})"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, '****')"),
+ njs_str("baz=fuz****muz=tax") },
- { njs_str("Buffer.from('evil').toString('utf-128')"),
- njs_str("TypeError: \"utf-128\" encoding is not supported") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, null, '^^^^')"),
+ njs_str("baz^^^^fuz&muz^^^^tax") },
- { njs_str("var buf = Buffer.allocUnsafe(4);"
- "var len = buf.write('ZXZpbA==', 'base64'); [len, buf]"),
- njs_str("4,evil") },
+ { njs_str("var qs = require('querystring');"
+ "var obj = {A:'α'}; obj['δ'] = 'D';"
+ "var s = qs.stringify(obj,'γ=','&β'); [s, s.length]"),
+ njs_str("A&β%CE%B1γ=%CE%B4&βD,20") },
- { njs_str("var buf = Buffer.allocUnsafe(4);"
- "var len = buf.write('ZXZpbA==', undefined, 'base64'); [len, buf]"),
- njs_str("4,evil") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, '', '')"),
+ njs_str("baz=fuz&muz=tax") },
- { njs_str("var buf = Buffer.allocUnsafe(4);"
- "var len = buf.write('ZXZpbA==', undefined, undefined, 'base64'); [len, buf]"),
- njs_str("4,evil") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, undefined, undefined)"),
+ njs_str("baz=fuz&muz=tax") },
- { njs_str("Buffer.allocUnsafe(4).write()"),
- njs_str("TypeError: first argument must be a string") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({'baz': 'fuz', 'muz': 'tax'}, '?', '/')"),
+ njs_str("baz/fuz?muz/tax") },
- { njs_str("Buffer.allocUnsafe(4).write({a: 1})"),
- njs_str("TypeError: first argument must be a string") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify('123')"),
+ njs_str("") },
- { njs_str("Buffer.alloc(4).write('evil', 4, 1);"),
- njs_str("RangeError: \"offset\" is out of range") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify(123)"),
+ njs_str("") },
- { njs_str("Buffer.alloc(4).write('evil', -1);"),
- njs_str("RangeError: invalid index") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({X: String.bytesFrom(Array(4).fill(0x9d))})"),
+ njs_str("X=%9D%9D%9D%9D") },
- { njs_str("var buf = Buffer.alloc(4);"
- "var len = buf.write('evil', 3, 1); [len, njs.dump(buf)]"),
- njs_str("1,Buffer [0,0,0,101]") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({X:{toString(){return 3}}})"),
+ njs_str("X=") },
- { njs_str("var buf = Buffer.alloc(4);"
- "var len = buf.write('evil', 0, 5); [len, buf]"),
- njs_str("4,evil") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify({ name: undefined, age: 12 })"),
+ njs_str("name=&age=12") },
- { njs_str("Buffer.alloc(4).write('evil', undefined, -1);"),
- njs_str("RangeError: invalid index") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify(Object.create({ name: undefined, age: 12 }))"),
+ njs_str("") },
- { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
- "[1,2,3,4,5,6].map(byte => [buf.readUIntLE(0, byte), buf.readUIntLE(1, byte)])"),
- njs_str("250,251,"
- "64506,64763,"
- "16579578,16645371,"
- "4261215226,4278058235,"
- "1095182908410,1099494718715,"
- "281470647991290,274877890034939") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify([])"),
+ njs_str("") },
- { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
- "[1,2,3,4,5,6].map(byte => [buf.readIntLE(0, byte), buf.readIntLE(1, byte)])"),
- njs_str("-6,-5,"
- "-1030,-773,"
- "-197638,-131845,"
- "-33752070,-16909061,"
- "-4328719366,-16909061,"
- "-4328719366,-6597086675717") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify(['','',''])"),
+ njs_str("0=&1=&2=") },
- { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
- "[1,2,3,4,5,6].map(byte => [buf.readUIntBE(0, byte), buf.readUIntBE(1, byte)])"),
- njs_str("250,251,"
- "64251,64508,"
- "16448508,16514301,"
- "4210818301,4227661310,"
- "1077969485310,1082281295615,"
- "275960188239615,277064011677689") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify([undefined, null, Symbol(), Object(0), Object('test'), Object(false),,,])"),
+ njs_str("0=&1=&2=&3=&4=&5=") },
- { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
- "[1,2,3,4,5,6].map(byte => [buf.readIntBE(0, byte), buf.readIntBE(1, byte)])"),
- njs_str("-6,-5,"
- "-1285,-1028,"
- "-328708,-262915,"
- "-84148995,-67305986,"
- "-21542142466,-17230332161,"
- "-5514788471041,-4410965032967") },
+#if 0
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify([NaN, Infinity, -Infinity, 2**69, 2**70])"),
+ njs_str("0=&1=&2=&3=590295810358705700000&4=1.1805916207174113e%2B21") },
+#else
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify([NaN, Infinity, -Infinity, 2**69, 2**70])"),
+ njs_str("0=&1=&2=&3=590295810358705700000&4=1.1805916207174114e%2B21") },
+#endif
- { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
- "function t(sign, endianness, offset) { "
- " return [1,2,4].every(size => {"
- " var method = `read${sign}Int${size * 8}`;"
- " if (size > 1) { method += endianness};"
- " var gmethod = `read${sign}Int${endianness}`;"
- " var gv = buf[gmethod](offset, size);"
- " var sv = buf[method](offset);"
- " if (gv != sv) {throw Error(`${gmethod}(${offset},${size}):${gv} != ${method}(${offset}):${sv}`)}"
- " return true;"
- " });"
- "}; "
- "t('U', 'LE', 0) && t('U', 'LE', 1)"
- "&& t('', 'LE', 0) && t('', 'LE', 1)"
- "&& t('U', 'BE', 0) && t('U', 'BE', 1)"
- "&& t('', 'BE', 0) && t('', 'BE', 1)"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify([[1,2,3],[4,5,6]])"),
+ njs_str("0=1&0=2&0=3&1=4&1=5&1=6") },
- { njs_str("var buf = Buffer.alloc(9);"
- "function t(sign, endianness, offset) { "
- " return [1,2,4].every(size => {"
- " var rgmethod = `read${sign}Int${endianness}`;"
- " var wgmethod = `write${sign}Int${endianness}`;"
- " var rmethod = `read${sign}Int${size * 8}`;"
- " var wmethod = `write${sign}Int${size * 8}`;"
- " if (size > 1) { rmethod += endianness; wmethod += endianness; };"
- " var v = 0x7abbccddeeff & (size * 8 - 1);"
- ""
- " var ret = buf[wgmethod](v, offset, size);"
- " if(ret !== offset + size) {"
- " throw Error(`${wgmethod} returned ${ret}, need ${offset + size}`);"
- " }"
- ""
- " var gv = buf[rgmethod](offset, size);"
- ""
- " buf.fill(0);"
- " buf[wmethod](v, offset);"
- " var sv = buf[rmethod](offset);"
- " if (gv != sv) {throw Error(`${wmethod}(${v}, ${offset}):${sv} != ${wgmethod}(${v},${offset}):${gv}`)}"
- " return true;"
- " });"
- "}; "
- "t('U', 'LE', 0) && t('U', 'LE', 1)"
- "&& t('', 'LE', 0) && t('', 'LE', 1)"
- "&& t('U', 'BE', 0) && t('U', 'BE', 1)"
- "&& t('', 'BE', 0) && t('', 'BE', 1)"),
- njs_str("true") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify([['a',,,],['b',,,]])"),
+ njs_str("0=a&0=&0=&1=b&1=&1=") },
- { njs_str(njs_buffer_byte_map("writeUIntLE", "+", 1)),
- njs_str("Buffer [128,0,0,0,0,0],"
- "Buffer [0,64,0,0,0,0],"
- "Buffer [0,0,32,0,0,0],"
- "Buffer [0,0,0,16,0,0],"
- "Buffer [0,0,0,0,8,0],"
- "Buffer [0,0,0,0,0,4]") },
+ { njs_str("var qs = require('querystring');"
+ "qs.stringify([[,'a','b',,]])"),
+ njs_str("0=&0=a&0=b&0=") },
- { njs_str(njs_buffer_byte_map("writeUIntBE", "+", 1)),
- njs_str("Buffer [128,0,0,0,0,0],"
- "Buffer [64,0,0,0,0,0],"
- "Buffer [32,0,0,0,0,0],"
- "Buffer [16,0,0,0,0,0],"
- "Buffer [8,0,0,0,0,0],"
- "Buffer [4,0,0,0,0,0]") },
+ { njs_str("var qs = require('querystring');"
+ "qs.escape('abcααααdef')"),
+ njs_str("abc%CE%B1%CE%B1%CE%B1%CE%B1def") },
- { njs_str(njs_buffer_byte_map("writeIntLE", "-", 2)),
- njs_str("Buffer [192,0,0,0,0,0],"
- "Buffer [0,224,0,0,0,0],"
- "Buffer [0,0,240,0,0,0],"
- "Buffer [0,0,0,248,0,0],"
- "Buffer [0,0,0,0,252,0],"
- "Buffer [0,0,0,0,0,254]") },
+ { njs_str("var qs = require('querystring');"
+ "qs.unescape('abc%CE%B1%CE%B1%CE%B1%CE%B1def')"),
+ njs_str("abcααααdef") },
+};
- { njs_str(njs_buffer_byte_map("writeIntBE", "-", 2)),
- njs_str("Buffer [192,0,0,0,0,0],"
- "Buffer [224,0,0,0,0,0],"
- "Buffer [240,0,0,0,0,0],"
- "Buffer [248,0,0,0,0,0],"
- "Buffer [252,0,0,0,0,0],"
- "Buffer [254,0,0,0,0,0]") },
- { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleBE()"),
- njs_str("8.20788039913184e-304") },
+static njs_unit_test_t njs_buffer_module_test[] =
+{
+ { njs_str("new Buffer();"),
+ njs_str("TypeError: Buffer is not a constructor") },
- { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleLE()"),
- njs_str("5.447603722011605e-270") },
+ { njs_str("var buf = Buffer.alloc();"),
+ njs_str("TypeError: \"size\" argument must be of type number") },
- { njs_str("Buffer.from([1, 2, 3, 4]).readFloatBE()"),
- njs_str("2.387939260590663e-38") },
+ { njs_str("var buf = Buffer.alloc('best buffer');"),
+ njs_str("TypeError: \"size\" argument must be of type number") },
- { njs_str("Buffer.from([1, 2, 3, 4]).readFloatLE()"),
- njs_str("1.539989614439558e-36") },
+ { njs_str("var buf = Buffer.alloc(-1);"),
+ njs_str("RangeError: invalid size") },
- { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleBE(1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(4); njs.dump(buf)"),
+ njs_str("Buffer [0,0,0,0]") },
- { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleLE(1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(4, 88); buf"),
+ njs_str("XXXX") },
- { njs_str("Buffer.from([1, 2, 3, 4]).readFloatBE(1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(4, 945); njs.dump(buf)"),
+ njs_str("Buffer [177,177,177,177]") },
- { njs_str("Buffer.from([1, 2, 3, 4]).readFloatLE(1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(4, -1); njs.dump(buf)"),
+ njs_str("Buffer [255,255,255,255]") },
- { njs_str("var buf = Buffer.allocUnsafe(8);"
- "buf.writeDoubleBE(123.456); njs.dump(buf)"),
- njs_str("Buffer [64,94,221,47,26,159,190,119]") },
+ { njs_str("var buf = Buffer.alloc(4, -1, 'utf-128'); njs.dump(buf)"),
+ njs_str("Buffer [255,255,255,255]") },
- { njs_str("var buf = Buffer.allocUnsafe(8);"
- "buf.writeDoubleLE(123.456); njs.dump(buf)"),
- njs_str("Buffer [119,190,159,26,47,221,94,64]") },
+ { njs_str("var buf = Buffer.alloc(10, 'α'); buf"),
+ njs_str("ααααα") },
- { njs_str("var buf = Buffer.allocUnsafe(4);"
- "buf.writeFloatBE(123.456); njs.dump(buf)"),
- njs_str("Buffer [66,246,233,121]") },
+ { njs_str("var buf = Buffer.alloc(4, 'α'); njs.dump(buf)"),
+ njs_str("Buffer [206,177,206,177]") },
- { njs_str("var buf = Buffer.allocUnsafe(4);"
- "buf.writeFloatLE(123.456); njs.dump(buf)"),
- njs_str("Buffer [121,233,246,66]") },
+ { njs_str("var buf = Buffer.alloc(2, 'ααααα'); njs.dump(buf)"),
+ njs_str("Buffer [206,177]") },
- { njs_str("var buf = Buffer.allocUnsafe(8).writeDoubleBE(123.456, 1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(1, 'α'); njs.dump(buf)"),
+ njs_str("Buffer [206]") },
- { njs_str("var buf = Buffer.allocUnsafe(8).writeDoubleLE(123.456, 1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(4, 'ZXZpbA==', 'base64'); buf"),
+ njs_str("evil") },
- { njs_str("var buf = Buffer.allocUnsafe(4).writeFloatBE(123.456, 1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(8, 'ZXZpbA==', 'base64'); buf"),
+ njs_str("evilevil") },
- { njs_str("var buf = Buffer.allocUnsafe(4).writeFloatLE(123.456, 1)"),
- njs_str("RangeError: index 1 is outside the bound of the buffer") },
+ { njs_str("var buf = Buffer.alloc(8, 'evil', 'utf-128'); buf"),
+ njs_str("TypeError: \"utf-128\" encoding is not supported") },
- { njs_str("var buffer = require('buffer');"
- "buffer.Buffer.alloc(5).fill('ABC')"),
- njs_str("ABCAB") },
+ { njs_str("var foo = new Uint8Array(10).fill(88);"
+ "var buf = Buffer.alloc(8, foo); buf"),
+ njs_str("XXXXXXXX") },
- { njs_str("var buffer = require('buffer');"
- "typeof buffer.kMaxLength === 'number' "),
+ { njs_str("[1,2,10,20].every(v => {"
+ " var src = new Uint16Array(v).fill(0xB1CE);"
+ " var buf = Buffer.alloc(10, src);"
+ " return buf.toString() === " njs_evar("'ααααα'", "'�αααα�'")
+ "})"),
njs_str("true") },
- { njs_str("var buffer = require('buffer');"
- "typeof buffer.constants.MAX_LENGTH === 'number' "),
+ { njs_str("var foo = Buffer.alloc(10, 'α');"
+ "var buf = Buffer.alloc(4, foo); buf"),
+ njs_str("αα") },
+
+ { njs_str("var buf = Buffer.allocUnsafe(10).fill('α'); buf"),
+ njs_str("ααααα") },
+
+ { njs_str("var buf = Buffer.allocUnsafe(-1)"),
+ njs_str("RangeError: invalid size") },
+
+ { njs_str("["
+ " ['6576696c', 'hex', 4],"
+ " ['6576696', 'hex', 3],"
+ " ['', 'hex', 0],"
+ " ['', 'base64', 0],"
+ " ['ZXZpbA==', 'base64', 4],"
+ " ['ZXZpbA', 'base64url', 4],"
+ " ['ααααα', undefined, 10],"
+ "].every(args => Buffer.byteLength(args[0], args[1]) == args[2])"),
njs_str("true") },
- { njs_str("var buffer = require('buffer');"
- "typeof buffer.constants.MAX_STRING_LENGTH === 'number' "),
+ { njs_str("Buffer.from([])"),
+ njs_str("") },
+
+ { njs_str("Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])"),
+ njs_str("buffer") },
+
+ { njs_str(njs_declare_sparse_array("arr", 6)
+ "[0x62, 0x75, 0x66, 0x66, 0x65, 0x72].map((v, i) => {arr[i] = v;});"
+ "Buffer.from(arr)"),
+ njs_str("buffer") },
+
+ { njs_str("Buffer.from({length:3, 0:0x62, 1:0x75, 2:0x66})"),
+ njs_str("buf") },
+
+ { njs_str("njs.dump(Buffer.from([-1,1,255,22323,-Infinity,Infinity,NaN]))"),
+ njs_str("Buffer [255,1,255,51,0,0,0]") },
+
+ { njs_str("var buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); njs.dump(buf)"),
+ njs_str("Buffer [98,117,102,102,101,114]") },
+
+ { njs_str("var buf = Buffer.from([1,2,3]); njs.dump(Buffer.from(buf.toJSON()))"),
+ njs_str("Buffer [1,2,3]") },
+
+ { njs_str("["
+ " {type: 'B'},"
+ " {type: undefined},"
+ " {type:'Buffer'},"
+ " {type:'Buffer', data:null},"
+ " {type:'Buffer', data:{}},"
+ "].every(v=>{ try { Buffer.from(v)} catch(e) {return e.name == 'TypeError'}})"),
njs_str("true") },
- /* let */
+ { njs_str("var foo = new Uint16Array(2);"
+ "foo[0] = 5000; foo[1] = 4000;"
+ "var buf = Buffer.from(foo.buffer);"
+ "foo[1] = 6000;"
+ "njs.dump(buf)"),
+ njs_str("Buffer [" njs_evar("136,19,112,23", "19,136,23,112") "]") },
- { njs_str("let x"),
- njs_str("undefined") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, 1); njs.dump(buf)"),
+ njs_str("Buffer [" njs_evar("3,182,3", "182,3,182") "]") },
- { njs_str("let x = 123; x"),
- njs_str("123") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, -1); njs.dump(buf)"),
+ njs_str("RangeError: invalid index") },
- { njs_str("let x = [123]; x"),
- njs_str("123") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, 5); njs.dump(buf)"),
+ njs_str("RangeError: \"offset\" is outside of buffer bounds") },
- { njs_str("let x = () => x; x()"),
- njs_str("[object Function]") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, 2, 1); njs.dump(buf)"),
+ njs_str("Buffer [" njs_evar("182", "3") "]") },
- { njs_str("let x = (() => x)()"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, 2, -1); njs.dump(buf)"),
+ njs_str("Buffer []") },
- { njs_str("x; let x"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, 2, 3); njs.dump(buf)"),
+ njs_str("RangeError: \"length\" is outside of buffer bounds") },
- { njs_str("x; let x = 123"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, 2, 0); njs.dump(buf)"),
+ njs_str("Buffer []") },
- { njs_str("let x = x + 123"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, 2, 2); njs.dump(buf)"),
+ njs_str("Buffer [" njs_evar("182,3", "3,182") "]") },
- { njs_str("let x = (x, 1)"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var foo = new Uint16Array(2).fill(950);"
+ "var buf = Buffer.from(foo.buffer, '2', '2'); njs.dump(buf)"),
+ njs_str("Buffer [" njs_evar("182,3", "3,182") "]") },
- { njs_str("let x = x"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var foo = new Uint32Array(1).fill(0xF1F2F3F4);"
+ "var buf = Buffer.from(foo); njs.dump(buf)"),
+ njs_str("Buffer [244]") },
+
+ { njs_str("var foo = new Uint32Array(2).fill(0xF1F2F3F4);"
+ "var buf = Buffer.from(foo); njs.dump(buf)"),
+ njs_str("Buffer [244,244]") },
+
+ { njs_str("var foo = new Uint8Array(5);"
+ "foo[0] = 1; foo[1] = 2; foo[2] = 3; foo[3] = 4; foo[4] = 5;"
+ "foo = foo.subarray(1, 3);"
+ "var buf = Buffer.from(foo); njs.dump(buf)"),
+ njs_str("Buffer [2,3]") },
+
+ { njs_str("var buf = Buffer.from(''); njs.dump(buf)"),
+ njs_str("Buffer []") },
+
+ { njs_str("var buf = Buffer.from('α'); njs.dump(buf)"),
+ njs_str("Buffer [206,177]") },
+
+ { njs_str("var arr = new Array(1,2,3); arr.valueOf = () => arr;"
+ "njs.dump(Buffer.from(arr))"),
+ njs_str("Buffer [1,2,3]") },
+
+ { njs_str("var obj = new Object(); obj.valueOf = () => obj;"
+ "Buffer.from(obj)"),
+ njs_str("TypeError: first argument object is not a string or Buffer-like object") },
+
+ { njs_str("var obj = new Object(); obj.valueOf = () => undefined;"
+ "njs.dump(Buffer.from(obj))"),
+ njs_str("TypeError: first argument undefined is not a string or Buffer-like object") },
+
+ { njs_str("var arr = new Array(1,2,3); arr.valueOf = () => null;"
+ "njs.dump(Buffer.from(arr))"),
+ njs_str("Buffer [1,2,3]") },
+
+ { njs_str("var obj = new Object(); obj.valueOf = () => new Array(1,2,3);"
+ "njs.dump(Buffer.from(obj))"),
+ njs_str("Buffer [1,2,3]") },
- { njs_str("let x; var x"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("njs.dump(Buffer.from(new String('test')))"),
+ njs_str("Buffer [116,101,115,116]") },
- { njs_str("var x; let x"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("["
+ " ['6576696c', 'hex'],"
+ " ['ZXZpbA==', 'base64'],"
+ " ['ZXZpbA==#', 'base64'],"
+ " ['ZXZpbA', 'base64url'],"
+ " ['ZXZpbA##', 'base64url'],"
+ "].every(args => Buffer.from(args[0], args[1]) == 'evil')"),
+ njs_str("true") },
- { njs_str("let x; function x() {}"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("var buf = Buffer.from(String.bytesFrom([0xF3])); buf"),
+ njs_str("�") },
- { njs_str("function x() {} let x"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("Buffer.from('', 'utf-128')"),
+ njs_str("TypeError: \"utf-128\" encoding is not supported") },
- { njs_str("function x() {let x; var x}"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("[Buffer.from('α'), new Uint8Array(10), {}, 1]"
+ ".map(v=>Buffer.isBuffer(v))"),
+ njs_str("true,false,false,false") },
- { njs_str("function x() {var x; let x}"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("['utf8', 'utf-8', 'hex', 'base64', 'base64url', 'utf-88', '1hex']"
+ ".map(v=>Buffer.isEncoding(v))"),
+ njs_str("true,true,true,true,true,false,false") },
- { njs_str("var x = function f() {let f}"),
- njs_str("undefined") },
+ { njs_str("["
+ " ['ABC', 'ABCD', -1],"
+ " ['ABCD', 'ABC', 1],"
+ " ['ABC', 'ACB', -1],"
+ " ['ACB', 'ABC', 1],"
+ " ['ABC', 'ABC', 0],"
+ " ['', 'ABC', -1],"
+ " ['', '', 0],"
+ "].every(args => {"
+ " if (Buffer.compare(Buffer.from(args[0]), Buffer.from(args[1])) != args[2]) {"
+ " throw new TypeError("
+ " `Buffer.compare(Buffer.from(${args[0]}), Buffer.from(${args[1]})) != ${args[2]}`);"
+ " }"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("let a; let x = 1;"
- "{let x = 2; a = x}"
- "[x, a]"),
- njs_str("1,2") },
+ { njs_str("["
+ " ['ABC', 'ABCD', -1],"
+ " ['ABCD', 'ABC', 1],"
+ " ['ABC', 'ACB', -1],"
+ " ['ACB', 'ABC', 1],"
+ " ['ABC', 'ABC', 0],"
+ " ['', 'ABC', -1],"
+ " ['', '', 0],"
+ "].every(args => {"
+ " if (Buffer.from(args[0]).compare(Buffer.from(args[1])) != args[2]) {"
+ " throw new TypeError("
+ " `Buffer.from(${args[0]}).compare(Buffer.from(${args[1]})) != ${args[2]}`);"
+ " }"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("let a; let x = 1;"
- "if (true) {let x = 2; a = x}"
- "[x, a]"),
- njs_str("1,2") },
+ { njs_str("var buf = Buffer.from('ABCD');"
+ "["
+ " [0,3,0,2, -1],"
+ " [0,2,0,3, 1],"
+ " [3,4,3,4, 0],"
+ " [undefined, undefined, undefined, undefined, 0],"
+ " [-1, undefined, undefined, undefined, 'invalid index'],"
+ " [0, -1, undefined, undefined, 'invalid index'],"
+ " [0, 0, -1, undefined, 'invalid index'],"
+ " [0, 0, 0, -1, 'invalid index'],"
+ "]"
+ ".every(as => {"
+ " try {"
+ " if (buf.compare(buf, as[0], as[1], as[2], as[3]) != as[4]) {"
+ " throw new TypeError("
+ " `buf.compare(${as[0]}, ${as[1]}, ${as[2]}, ${as[3]}) != ${as[4]}`);"
+ " }"
+ " } catch (e) { return e.message == as[4]}"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("var a = 5, b = 10, arr = [];"
- "{let a = 4; var b = 1; arr.push(a); arr.push(b)}"
- "arr.push(a); arr.push(b); arr"),
- njs_str("4,1,5,1") },
+ { njs_str("var buf1 = Buffer.from('ABCD');"
+ "var buf2 = Buffer.from('ABCD');"
+ "buf1.compare(buf2, 5)"),
+ njs_str("RangeError: \"targetStart\" is out of range: 5") },
- { njs_str("function func() {return x}"
- "let x = 123;"
- "func()"),
- njs_str("123") },
+ { njs_str("var buf1 = Buffer.from('ABCD');"
+ "var buf2 = Buffer.from('ABCD');"
+ "buf1.compare(buf2, 0, 3, 5)"),
+ njs_str("RangeError: \"sourceStart\" is out of range: 5") },
- { njs_str("function func() {return x}"
- "func();"
- "let x = 123"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var arr = new Uint8Array(4);"
+ "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
+ "arr = arr.subarray(1, 4);"
+ "var buf = Buffer.from('ABCD');"
+ "buf.compare(arr, 0, 3, 1, 4)"),
+ njs_str("0") },
- { njs_str("function func() {return () => x}"
- "let x = 123;"
- "func()()"),
- njs_str("123") },
+ { njs_str("['123', 'abc', '124', '', 'AB', 'ABCD']"
+ ".map(v=>Buffer.from(v)).sort(Buffer.compare).map(v=>v.toString())"),
+ njs_str(",123,124,AB,ABCD,abc") },
- { njs_str("function func() {x = x + 1; let x}"),
- njs_str("undefined") },
+ { njs_str("Buffer.compare(Buffer.alloc(1), 'text')"),
+ njs_str("TypeError: \"target\" argument must be an instance of Buffer or Uint8Array") },
- { njs_str("function func() {return () => x}"
- "func()();"
- "let x = 123;"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("Buffer.compare('text', Buffer.from('ACB'))"),
+ njs_str("TypeError: \"source\" argument must be an instance of Buffer or Uint8Array") },
- { njs_str("var arr = [];"
- ""
- "for (var i = 0; i < 10; i++) {"
- " let x = i;"
- ""
- " arr.push( (n) => {x += n; return x} );"
- "}"
- ""
- "["
- " arr[0](2), arr[1](1), arr[2](4), arr[3](7), arr[4](0),"
- " arr[5](1), arr[6](2), arr[7](5), arr[8](8), arr[9](10)"
- "]"),
- njs_str("2,2,6,10,4,6,8,12,16,19") },
+ { njs_str("Buffer.concat()"),
+ njs_str("TypeError: \"list\" argument must be an instance of Array") },
- { njs_str("var arr = [];"
- ""
- "for (let i = 0; i < 10; i++) {"
- " arr.push( (n) => {i += n; return i} );"
- "}"
- ""
- "["
- " arr[0](2), arr[1](1), arr[2](4), arr[3](7), arr[4](0),"
- " arr[5](1), arr[6](2), arr[7](5), arr[8](8), arr[9](10)"
- "]"),
- njs_str("2,2,6,10,4,6,8,12,16,19") },
+ { njs_str("Buffer.concat([])"),
+ njs_str("") },
- { njs_str("for (let i = 0; i < 1; i++) {"
- " let i = i + 2;"
- "}"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("Buffer.concat([new Uint16Array(10)])"),
+ njs_str("TypeError: \"list[0]\" argument must be an instance of Buffer or Uint8Array") },
- { njs_str("let arr = [], res = [];"
- "for (let i = 0, f = function() { return i }; i < 5; i++) {"
- " arr.push(f);"
- "}"
- "for (let i = 0; i < 5; i++) {"
- " res.push(arr[i]());"
- "} res"),
- njs_str("0,0,0,0,0") },
+ { njs_str("Buffer.concat([new Uint8Array(2), new Uint8Array(1)]).fill('abc')"),
+ njs_str("abc") },
- { njs_str("let arr = [], res = [];"
- "for (let i = 0; arr.push(() => i), i < 10; i++) {}"
- "for (let k = 0; k < 10; k++) {res.push(arr[k]())}"
- "res"),
- njs_str("0,1,2,3,4,5,6,7,8,9") },
+ { njs_str("Buffer.concat([Buffer.from('AB'), Buffer.from('CD')])"),
+ njs_str("ABCD") },
- { njs_str("let res = [];"
- "for (let n in [1,2,3]) {res.push(n)}"
- "res"),
- njs_str("0,1,2") },
+ { njs_str("Buffer.concat([new Uint8Array(2), new Uint8Array(1)], 2).fill('abc')"),
+ njs_str("ab") },
- { njs_str("let arr = [], res = [];"
- ""
- "for (let n in [1,2,3]) {"
- " arr.push(() => n);"
- "}"
- ""
- "for (let n in arr) {"
- " res.push(arr[n]());"
- "}"
- "res"),
- njs_str("0,1,2") },
+ { njs_str("Buffer.concat([new Uint8Array(2), new Uint8Array(1)], 6).fill('abc')"),
+ njs_str("abcabc") },
- { njs_str("let arr = [];"
- ""
- "for (let n in [1,2,3]) {"
- " let n = 1;"
- " arr.push(n);"
- "}"
- "arr"),
- njs_str("1,1,1") },
+ { njs_str(njs_declare_sparse_array("list", 2)
+ "list[0] = new Uint8Array(2); list[1] = new Uint8Array(3);"
+ "Buffer.concat(list).fill('ab');"),
+ njs_str("ababa") },
- { njs_str("for (let n in [1,2,3]) {"
- " let n = n + 1;"
- "}"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("Buffer.concat([], '123')"),
+ njs_str("TypeError: \"length\" argument must be of type number") },
- { njs_str("for (let n in [1,2,3]) {}"
- "n"),
- njs_str("ReferenceError: \"n\" is not defined") },
+ { njs_str("Buffer.concat([], -1)"),
+ njs_str("RangeError: \"length\" is out of range") },
- { njs_str("for (let n in [1,n,3]) {}"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf = Buffer.from('α'); buf[1]"),
+ njs_str("177") },
- { njs_str("(function() {"
- "function f() {return x + 1}"
- "function abc() {f()};"
- "abc();"
- "let x;"
- "}())"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf = Buffer.from('α'); buf[1] = 1; njs.dump(buf)"),
+ njs_str("Buffer [206,1]") },
- { njs_str("function func() {var x = 1; {let x = x + 1} } func()"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var arrBuf = new ArrayBuffer(16);"
+ "var buf = Buffer.from(arrBuf); buf.buffer === arrBuf"),
+ njs_str("true") },
- { njs_str("if (false) let x = 1"),
- njs_str("SyntaxError: let declaration cannot appear in a single-statement context in 1") },
+ { njs_str("["
+ " [[0], 4, '65,66,67,68,0,0,0,0,0,0'],"
+ " [[5], 4, '0,0,0,0,0,65,66,67,68,0'],"
+ " [[8], 2, '0,0,0,0,0,0,0,0,65,66'],"
+ " [[8,2,4], 2, '0,0,0,0,0,0,0,0,67,68'],"
+ " [[10], 0, '0,0,0,0,0,0,0,0,0,0'],"
+ "]"
+ ".every(args => {"
+ " var buf1 = Buffer.from('ABCD');"
+ " var buf2 = Buffer.alloc(10, 0);"
+ " var as = args[0];"
+ " var length = buf1.copy(buf2, as[0], as[1], as[2]);"
+ ""
+ " if (length != args[1]) {"
+ " throw new TypeError(`buf1.copy(buf2, ${as[0]}, ${as[1]}, ${as[2]}): ${length} != ${args[1]}`)"
+ " }"
+ ""
+ " if (njs.dump(buf2) != `Buffer [${args[2]}]`) {"
+ " throw new TypeError("
+ " `buf1.copy(buf2, ${as[0]}, ${as[1]}, ${as[2]}): ${njs.dump(buf2)} != Buffer [${args[2]}]`);"
+ " }"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("while (false) let x = 1"),
- njs_str("SyntaxError: let declaration cannot appear in a single-statement context in 1") },
+ { njs_str("["
+ " [[0], 'ABCDEF'],"
+ " [[0,2], 'CDEFEF'],"
+ " [[0,2,6], 'CDEFEF'],"
+ " [[1,2,4], 'ACDDEF'],"
+ " [[1,2,3], 'ACCDEF']"
+ "]"
+ ".every(args => {"
+ " var buf = Buffer.from('ABCDEF');"
+ " var as = args[0];"
+ " buf.copy(buf, as[0], as[1], as[2]);"
+ ""
+ " if (buf.toString() != args[1]) {"
+ " throw new TypeError("
+ " `buf.copy(buf, ${as[0]}, ${as[1]}, ${as[2]}): buf.toString() != ${args[1]}`);"
+ " }"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("for (;;) let x = 1"),
- njs_str("SyntaxError: let declaration cannot appear in a single-statement context in 1") },
+ { njs_str("var buf1 = Buffer.from('ABCD');"
+ "var buf2 = Buffer.alloc(10, 0);"
+ "buf1.copy(buf2, -1)"),
+ njs_str("RangeError: invalid index") },
- { njs_str("try {} catch (e) {let e}"),
- njs_str("SyntaxError: \"e\" has already been declared in 1") },
+ { njs_str("var buf1 = Buffer.from('ABCD');"
+ "var buf2 = Buffer.alloc(10, 0);"
+ "buf1.copy(buf2, 0, -1)"),
+ njs_str("RangeError: invalid index") },
- { njs_str("let arr = [], x = 2;"
- "switch(true) {default: let x = 1; arr.push(x)}"
- "arr.push(x); arr"),
- njs_str("1,2") },
+ { njs_str("var buf1 = Buffer.from('ABCD');"
+ "var buf2 = Buffer.alloc(10, 0);"
+ "buf1.copy(buf2, 0, 5)"),
+ njs_str("RangeError: \"sourceStart\" is out of range: 5") },
- { njs_str("switch(true) {case false: let x = 1; default: x = 2}"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var arr = new Uint8Array(4);"
+ "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
+ "arr = arr.subarray(1, 4);"
+ "var buf1 = Buffer.from(arr);"
+ "var buf2 = Buffer.alloc(10, 0);"
+ "var length = buf1.copy(buf2, 1, 1, 2); [length, njs.dump(buf2)]"),
+ njs_str("1,Buffer [0,67,0,0,0,0,0,0,0,0]") },
- { njs_str("let res;"
- "switch(true) {case true: let x = 1; default: x = 2; res = x} res"),
- njs_str("2") },
+ { njs_str("var arr = new Uint8Array(4);"
+ "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
+ "arr = arr.subarray(1, 4);"
+ "var buf1 = Buffer.from(arr);"
+ "var buf2 = Buffer.alloc(10, 0);"
+ "var length = buf1.copy(buf2, 1, 1, 2); [length, njs.dump(buf2)]"),
+ njs_str("1,Buffer [0,67,0,0,0,0,0,0,0,0]") },
- { njs_str("let null"),
- njs_str("SyntaxError: Unexpected token \"null\" in 1") },
+ { njs_str("["
+ " ['ABC', 'ABCD', false],"
+ " ['ABCD', 'ABC', false],"
+ " ['ABC', 'ACB', false],"
+ " ['ACB', 'ABC', false],"
+ " ['ABC', 'ABC', true],"
+ " ['', 'ABC', false],"
+ " ['', '', true],"
+ "].every(args => {"
+ " if (Buffer.from(args[0]).equals(Buffer.from(args[1])) != args[2]) {"
+ " throw new TypeError("
+ " `Buffer.from(${args[0]}).compare(Buffer.from(${args[1]})) != ${args[2]}`);"
+ " }"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("let continue"),
- njs_str("SyntaxError: Unexpected token \"continue\" in 1") },
+ { njs_str("Buffer.from([1,2]).equals(new ArrayBuffer(1))"),
+ njs_str("TypeError: \"target\" argument must be an instance of Buffer or Uint8Array") },
- { njs_str("let undefined"),
- njs_str("SyntaxError: \"undefined\" has already been declared in 1") },
+ { njs_str("Buffer.from([1,2]).equals(1)"),
+ njs_str("TypeError: \"target\" argument must be an instance of Buffer or Uint8Array") },
- { njs_str("let a = 1; globalThis.a"),
- njs_str("undefined") },
+ { njs_str("var buf = Buffer.alloc(4);"
+ "buf.fill('ZXZpbA==', 'base64')"),
+ njs_str("evil") },
- { njs_str("if (false) {x = 2} else {x = 1} let x;"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf = Buffer.alloc(4);"
+ "buf.fill('6576696c', 'hex')"),
+ njs_str("evil") },
- { njs_str("let let"),
- njs_str("SyntaxError: Unexpected token \"let\" in 1") },
+ { njs_str("var buf = Buffer.alloc(4);"
+ "buf.fill('ZXZpbA==', '')"),
+ njs_str("TypeError: \"\" encoding is not supported") },
- { njs_str("let null"),
- njs_str("SyntaxError: Unexpected token \"null\" in 1") },
+ { njs_str("var buf = Buffer.alloc(8);"
+ "buf.fill('6576696c', 'hex')"),
+ njs_str("evilevil") },
- { njs_str("function let() {}"),
- njs_str("SyntaxError: Unexpected token \"let\" in 1") },
+ { njs_str("var buf = Buffer.alloc(10);"
+ "buf.fill('evil')"),
+ njs_str("evilevilev") },
- { njs_str("function static() {}"),
- njs_str("SyntaxError: Unexpected token \"static\" in 1") },
+ { njs_str("var buf = Buffer.allocUnsafe(5);"
+ "buf[3] = 1;"
+ "buf.fill(''); njs.dump(buf)"),
+ njs_str("Buffer [0,0,0,0,0]") },
- /* const */
+ { njs_str("var arr = new Uint8Array(4);"
+ "arr[0] = 0x41; arr[1] = 0x42; arr[2] = 0x43; arr[3] = 0x44;"
+ "arr = arr.subarray(1, 4);"
+ "var buf = Buffer.allocUnsafe(6);"
+ "buf.fill(arr); njs.dump(buf)"),
+ njs_str("Buffer [66,67,68,66,67,68]") },
- { njs_str("const x"),
- njs_str("SyntaxError: missing initializer in const declaration") },
+ { njs_str("var buf = Buffer.alloc(6, 'ABCDEF');"
+ "buf.fill(buf, 2, 6)"),
+ njs_str("ABABCD") },
- { njs_str("const x = 1; x"),
- njs_str("1") },
+ { njs_str("Buffer.alloc(6).fill(0x41)"),
+ njs_str("AAAAAA") },
- { njs_str("const x = 1; x = 1"),
- njs_str("TypeError: assignment to constant variable") },
+ { njs_str("Buffer.alloc(6).fill({valueOf(){return 0x42}})"),
+ njs_str("BBBBBB") },
- { njs_str("function abc() {const x}"),
- njs_str("SyntaxError: missing initializer in const declaration") },
+ { njs_str("njs.dump(Buffer.alloc(3).fill(-1))"),
+ njs_str("Buffer [255,255,255]") },
- { njs_str("const x = [123]; x"),
- njs_str("123") },
+ { njs_str("[NaN, Infinity, -Infinity, undefined, null, {}]"
+ ".every(v => njs.dump(Buffer.alloc(3).fill(v)) == 'Buffer [0,0,0]')"),
+ njs_str("true") },
- { njs_str("const x = () => x; x()"),
- njs_str("[object Function]") },
+ { njs_str("njs.dump(Buffer.alloc(6).fill({valueOf(){throw 'Oops'}}, 4,3))"),
+ njs_str("Buffer [0,0,0,0,0,0]") },
- { njs_str("const x = (() => x)()"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("njs.dump(Buffer.alloc(6).fill({valueOf(){throw 'Oops'}}, 3,3))"),
+ njs_str("Buffer [0,0,0,0,0,0]") },
- { njs_str("x; const x = 123"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("njs.dump(Buffer.alloc(6).fill({valueOf(){throw 'Oops'}}, 2,3))"),
+ njs_str("Oops") },
- { njs_str("const x = x + 123"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("njs.dump(Buffer.alloc(5).fill('α'))"),
+ njs_str("Buffer [206,177,206,177,206]") },
- { njs_str("const x; var x"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("Buffer.alloc(4).fill('ABCD', -1)"),
+ njs_str("RangeError: invalid index") },
- { njs_str("const x; let x"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("Buffer.alloc(4).fill('ABCD', 5)"),
+ njs_str("RangeError: \"offset\" is out of range") },
- { njs_str("let x; const x"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("Buffer.alloc(4).fill('ABCD', 0, -1)"),
+ njs_str("RangeError: invalid index") },
- { njs_str("const x = 1; function x() {}"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("Buffer.alloc(4).fill('ABCD', 0, 5)"),
+ njs_str("RangeError: \"end\" is out of range") },
- { njs_str("function x() {} const x = 1"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("Buffer.alloc(513).fill('A'.repeat(512)).length"),
+ njs_str("513") },
- { njs_str("function x() {const x; var x}"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("njs.dump(Buffer.alloc(4).fill((new Uint8Array(5)).fill(1)))"),
+ njs_str("Buffer [1,1,1,1]") },
- { njs_str("function x() {var x; const x}"),
- njs_str("SyntaxError: \"x\" has already been declared in 1") },
+ { njs_str("var src = new Uint8Array(10).fill(255);"
+ "var u8 = new Uint8Array(src.buffer, 1, 8);"
+ "u8.set([1,2,3,4,5,6,7,8]);"
+ "njs.dump(Buffer.alloc(9).fill(u8))"),
+ njs_str("Buffer [1,2,3,4,5,6,7,8,1]") },
- { njs_str("const x = function f() {const f = 1}"),
- njs_str("undefined") },
+ { njs_str("Buffer.alloc(513).fill((new Uint8Array(512)).fill(1)).length"),
+ njs_str("513") },
- { njs_str("let res; const x = 1;"
- "{const x = 2; res = x}"
- "[x, res]"),
- njs_str("1,2") },
+ { njs_str("Buffer.alloc(4).fill('ABCD', undefined, undefined, 'utf-128')"),
+ njs_str("TypeError: \"utf-128\" encoding is not supported") },
- { njs_str("let res; const x = 1;"
- "if (true) {const x = 2; res = x}"
- "[x, res]"),
- njs_str("1,2") },
+ { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 3);"
+ "buf1.fill('B', 1, 2); njs.dump(buf1)"),
+ njs_str("Buffer [66,66]") },
- { njs_str("function func() {return x}"
- "const x = 123;"
- "func()"),
- njs_str("123") },
+ { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 3);"
+ "buf1.fill(0x42, 1, 2); njs.dump(buf1)"),
+ njs_str("Buffer [66,66]") },
- { njs_str("function func() {return x}"
- "func();"
- "const x = 123"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 2);"
+ "var buf2 = Buffer.from('ABCD').subarray(1, 3);"
+ "buf2.fill(buf1, 1, 2); njs.dump(buf2)"),
+ njs_str("Buffer [66,66]") },
- { njs_str("function func() {return () => x}"
- "const x = 123;"
- "func()()"),
- njs_str("123") },
+ { njs_str("var buf = Buffer.from('ABCD');"
+ "['BC', 'CB', 'ABCD', 'ABCDE', ''].map(v=>buf.indexOf(v))"),
+ njs_str("1,-1,0,-1,0") },
- { njs_str("function func() {return () => x++}"
- "const x = 123;"
- "func()()"),
- njs_str("TypeError: assignment to constant variable") },
+ { njs_str("var buf = Buffer.from('ABCD');"
+ "[0,5,-2,-1].map(v=>buf.indexOf('C', v))"),
+ njs_str("2,-1,2,-1") },
- { njs_str("for (const i = 0; i < 1; i++) {}"),
- njs_str("TypeError: assignment to constant variable") },
+ { njs_str("var buf = Buffer.from('evil');"
+ "buf.indexOf('ZXZpbA==', undefined, 'base64')"),
+ njs_str("0") },
- { njs_str("let res = [];"
- "for (const n in [1,2,3]) {res.push(n)}"
- "res"),
- njs_str("0,1,2") },
+ { njs_str("var buf = Buffer.from('evil');"
+ "buf.indexOf('6576696c', undefined, 'hex')"),
+ njs_str("0") },
- { njs_str("let arr = [], res = [];"
- ""
- "for (const n in [1,2,3]) {"
- " arr.push(() => n);"
- "}"
- ""
- "for (let n in arr) {"
- " res.push(arr[n]());"
- "}"
- "res"),
- njs_str("0,1,2") },
+ { njs_str("var buf = Buffer.from('ABCD');"
+ "buf.indexOf('C', undefined, 'utf-128')"),
+ njs_str("TypeError: \"utf-128\" encoding is not supported") },
- { njs_str("let arr = [];"
- ""
- "for (const n in [1,2,3]) {"
- " let n = 1;"
- " arr.push(n);"
- "}"
- "arr"),
- njs_str("1,1,1") },
+ { njs_str("var buf = Buffer.from('ABCDABC');"
+ "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.indexOf(Buffer.from(v)))"),
+ njs_str("1,-1,0,-1,0,2,-1") },
- { njs_str("for (const n in [1,2,3]) {"
- " let n = n + 1;"
- "}"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf = Buffer.from('ABCDABC');"
+ "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.includes(Buffer.from(v)))"),
+ njs_str("true,false,true,false,true,true,false") },
- { njs_str("for (const n in [1,2,3]) {}"
- "n"),
- njs_str("ReferenceError: \"n\" is not defined") },
+ { njs_str("var buf = Buffer.from('ZABCDABC').subarray(1);"
+ "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.indexOf(Buffer.from(v)))"),
+ njs_str("1,-1,0,-1,0,2,-1") },
- { njs_str("for (const n in [1,n,3]) {}"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf = Buffer.from('ABCD');"
+ "buf.indexOf(0x43)"),
+ njs_str("2") },
- { njs_str("(function() {"
- "function f() {return x + 1}"
- "function abc() {f()};"
- "abc();"
- "const x = 1;"
- "}())"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf = Buffer.from('ABCD');"
+ "buf.indexOf(0x43, -2)"),
+ njs_str("2") },
- { njs_str("if (false) const x = 1"),
- njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
+ { njs_str("var buf = Buffer.from('ABCD');"
+ "buf.indexOf(0x43, -1)"),
+ njs_str("-1") },
- { njs_str("while (false) const x = 1"),
- njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
+ { njs_str("var buf1 = Buffer.from('ABCD');"
+ "var buf2 = Buffer.from('XXCX').subarray(2, 3);"
+ "buf1.indexOf(buf2)"),
+ njs_str("2") },
- { njs_str("for (;;) const x = 1"),
- njs_str("SyntaxError: const declaration cannot appear in a single-statement context in 1") },
+ { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 4);"
+ "buf1.indexOf(0x43)"),
+ njs_str("1") },
- { njs_str("try {} catch (e) {const e = 1}"),
- njs_str("SyntaxError: \"e\" has already been declared in 1") },
+ { njs_str("var buf1 = Buffer.from('ABCD').subarray(1, 4);"
+ "buf1.indexOf('C')"),
+ njs_str("1") },
- { njs_str("let arr = []; const x = 2;"
- "switch(true) {default: const x = 1; arr.push(x)}"
- "arr.push(x); arr"),
- njs_str("1,2") },
+ { njs_str("var buf = Buffer.from('ABCDABC');"
+ "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(v))"),
+ njs_str("5,-1,0,-1,7,6,-1") },
- { njs_str("let res;"
- "switch(true) {case true: const x = 1; default: x = 2; res = x} res"),
- njs_str("TypeError: assignment to constant variable") },
+ { njs_str("var buf = Buffer.from('ABCDABC');"
+ "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(Buffer.from(v)))"),
+ njs_str("5,-1,0,-1,7,6,-1") },
- { njs_str("const null"),
- njs_str("SyntaxError: Unexpected token \"null\" in 1") },
+ { njs_str("var buf = Buffer.from('ZABCDABC').subarray(1);"
+ "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(v))"),
+ njs_str("5,-1,0,-1,7,6,-1") },
- { njs_str("const continue"),
- njs_str("SyntaxError: Unexpected token \"continue\" in 1") },
+ { njs_str("var buf = Buffer.from('ZABCDABC').subarray(1);"
+ "['BC', 'CB', 'ABCD', 'ABCDE', '', 'C', 'ABCDABCD'].map(v=>buf.lastIndexOf(Buffer.from(v)))"),
+ njs_str("5,-1,0,-1,7,6,-1") },
- { njs_str("const undefined"),
- njs_str("SyntaxError: \"undefined\" has already been declared in 1") },
+ { njs_str("var buf = Buffer.from('CABCD');"
+ "[2,-2,1,-10,10,-5,-4,0].map(v=>buf.lastIndexOf('C', v))"),
+ njs_str("0,3,0,-1,3,0,0,0") },
- { njs_str("const a = 1; globalThis.a"),
- njs_str("undefined") },
+ { njs_str("var buf = Buffer.from('CABCD');"
+ "[2,-2,1,-10,10,-5,-4,0].map(v=>buf.lastIndexOf(Buffer.from('CZ').subarray(0,1), v))"),
+ njs_str("0,3,0,-1,3,0,0,0") },
- { njs_str("if (false) {x = 2} else {x = 1} const x = 0"),
- njs_str("ReferenceError: cannot access variable before initialization") },
+ { njs_str("var buf = Buffer.from('CABCD');"
+ "buf.lastIndexOf(0x43)"),
+ njs_str("3") },
- { njs_str("const const"),
- njs_str("SyntaxError: Unexpected token \"const\" in 1") },
+ { njs_str("var buf = Buffer.from('CABCD');"
+ "[2,1,0,4,5,-1,-5].map(v=>buf.lastIndexOf(0x43, v))"),
+ njs_str("0,0,0,3,3,3,0") },
- /* Async/Await */
+ { njs_str("var buf1 = Buffer.from('ACBCD').subarray(1, 4);"
+ "var buf2 = Buffer.from('C');"
+ "buf1.lastIndexOf(buf2)"),
+ njs_str("2") },
- { njs_str("async function f() {}; f.prototype"),
- njs_str("undefined") },
+ { njs_str("var buf1 = Buffer.from('XXCXX').subarray(2,3);"
+ "buf1.lastIndexOf(Buffer.from('X'))"),
+ njs_str("-1") },
- { njs_str("async function f() {await 1}"),
- njs_str("undefined") },
+ { njs_str("var buf = Buffer.from('ACBCD').subarray(1, 4);"
+ "buf.lastIndexOf(0x43)"),
+ njs_str("2") },
- { njs_str("function f() {await 1}"),
- njs_str("SyntaxError: await is only valid in async functions in 1") },
+ { njs_str("var buf = Buffer.from('ACBCD').subarray(1, 4);"
+ "buf.lastIndexOf('C')"),
+ njs_str("2") },
- { njs_str("async function f() {function a() {await 1}}"),
- njs_str("SyntaxError: await is only valid in async functions in 1") },
+ { njs_str("['swap16', 'swap32', 'swap64'].every(method => {"
+ " var buf = Buffer.from([]);"
+ " buf[method]();"
+ " return njs.dump(buf) === 'Buffer []';"
+ "})"),
+ njs_str("true") },
- { njs_str("async function f() {() => {await 1}}"),
- njs_str("SyntaxError: await is only valid in async functions in 1") },
+ { njs_str("['swap16', 'swap32', 'swap64'].every(method => {"
+ " var buf = Buffer.from([1,2,3]);"
+ " try { buf[method]() } "
+ " catch(e) {return e.message === `Buffer size must be a multiple of ${method.substr(4)}-bits`};"
+ "})"),
+ njs_str("true") },
- { njs_str("function f() {async () => {await 1}}"),
- njs_str("undefined") },
+ { njs_str("['swap16', 'swap32', 'swap64'].map(method => {"
+ " var buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]);"
+ " buf[method]();"
+ " return njs.dump(buf);"
+ "})"),
+ njs_str("Buffer [2,1,4,3,6,5,8,7],"
+ "Buffer [4,3,2,1,8,7,6,5],"
+ "Buffer [8,7,6,5,4,3,2,1]") },
- { njs_str("let f = async () => {await 1}"),
- njs_str("undefined") },
+ { njs_str("['swap16', 'swap32', 'swap64'].map(method => {"
+ " var u8 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]);"
+ " var buf = Buffer.from(u8.buffer, 1);"
+ " buf[method]();"
+ " return njs.dump(buf);"
+ "})"),
+ njs_str("Buffer [2,1,4,3,6,5,8,7],"
+ "Buffer [4,3,2,1,8,7,6,5],"
+ "Buffer [8,7,6,5,4,3,2,1]") },
- { njs_str("let f = () => {await 1}"),
- njs_str("SyntaxError: await is only valid in async functions in 1") },
+ { njs_str("njs.dump(Buffer.from('αααα').toJSON())"),
+ njs_str("{type:'Buffer',data:[206,177,206,177,206,177,206,177]}") },
- { njs_str("(async function() {await 1})"),
- njs_str("[object AsyncFunction]") },
+ { njs_str("njs.dump(Buffer.from('').toJSON())"),
+ njs_str("{type:'Buffer',data:[]}") },
- { njs_str("(function() {await 1})"),
- njs_str("SyntaxError: await is only valid in async functions in 1") },
+ { njs_str("["
+ " [['base64'], 'ZXZpbA=='],"
+ " [['base64url'], 'ZXZpbA'],"
+ " [['hex'], '6576696c'],"
+ " [[undefined,1,3], 'vi'],"
+ " [[undefined,5], ''],"
+ " [[undefined,undefined,5], 'evil'],"
+ " [[undefined,undefined,undefined], 'evil'],"
+ "].every(args => {"
+ " var buf = Buffer.from('evil');"
+ " var as = args[0];"
+ " if (buf.toString(as[0], as[1], as[2]) != args[1]) {"
+ " throw new TypeError("
+ " `buf.toString(${as[0]}, ${as[1]}, ${as[2]}) != ${args[1]}`);"
+ " }"
+ " return true;"
+ "})"),
+ njs_str("true") },
- { njs_str("let ctor = Object.getPrototypeOf(async function(){}).constructor;"
- "ctor"),
- njs_str("[object Function]") },
+ { njs_str("Buffer.from('evil').toString('utf-128')"),
+ njs_str("TypeError: \"utf-128\" encoding is not supported") },
- { njs_str("let ctor = Object.getPrototypeOf(async function(){}).constructor;"
- "ctor()"),
- njs_str("[object AsyncFunction]") },
+ { njs_str("var buf = Buffer.allocUnsafe(4);"
+ "var len = buf.write('ZXZpbA==', 'base64'); [len, buf]"),
+ njs_str("4,evil") },
- { njs_str("let ctor = Object.getPrototypeOf(async function(){}).constructor;"
- "new ctor();"),
- njs_str("[object AsyncFunction]") },
+ { njs_str("var buf = Buffer.allocUnsafe(4);"
+ "var len = buf.write('ZXZpbA==', undefined, 'base64'); [len, buf]"),
+ njs_str("4,evil") },
- { njs_str("let f = new Function('x', 'await 1; return x'); f(1)"),
- njs_str("SyntaxError: await is only valid in async functions in runtime:1") },
+ { njs_str("var buf = Buffer.allocUnsafe(4);"
+ "var len = buf.write('ZXZpbA==', undefined, undefined, 'base64'); [len, buf]"),
+ njs_str("4,evil") },
- { njs_str("new AsyncFunction()"),
- njs_str("ReferenceError: \"AsyncFunction\" is not defined") },
+ { njs_str("Buffer.allocUnsafe(4).write()"),
+ njs_str("TypeError: first argument must be a string") },
- { njs_str("(async function() {console.log(await 111)})"),
- njs_str("SyntaxError: await in arguments not supported in 1") },
+ { njs_str("Buffer.allocUnsafe(4).write({a: 1})"),
+ njs_str("TypeError: first argument must be a string") },
- { njs_str("(async function() {console.log('Number: ' + await 111)})"),
- njs_str("SyntaxError: await in arguments not supported in 1") },
+ { njs_str("Buffer.alloc(4).write('evil', 4, 1);"),
+ njs_str("RangeError: \"offset\" is out of range") },
- { njs_str("function f(a) {}"
- "(async function() {f(await 111)})"),
- njs_str("SyntaxError: await in arguments not supported in 1") },
+ { njs_str("Buffer.alloc(4).write('evil', -1);"),
+ njs_str("RangeError: invalid index") },
- { njs_str("async () => [await x(1)(),]; async () => [await x(1)()]"),
- njs_str("[object AsyncFunction]") },
+ { njs_str("var buf = Buffer.alloc(4);"
+ "var len = buf.write('evil', 3, 1); [len, njs.dump(buf)]"),
+ njs_str("1,Buffer [0,0,0,101]") },
- { njs_str("function f(a, b, c) {}"
- "(async function() {f(1, 'a', await 111)})"),
- njs_str("SyntaxError: await in arguments not supported in 1") },
+ { njs_str("var buf = Buffer.alloc(4);"
+ "var len = buf.write('evil', 0, 5); [len, buf]"),
+ njs_str("4,evil") },
- { njs_str("function f(a) {}"
- "(async function() {f('Number: ' + await 111)})"),
- njs_str("SyntaxError: await in arguments not supported in 1") },
+ { njs_str("Buffer.alloc(4).write('evil', undefined, -1);"),
+ njs_str("RangeError: invalid index") },
- { njs_str("async function af() {await encrypt({},}"),
- njs_str("SyntaxError: Unexpected token \"}\" in 1") },
+ { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
+ "[1,2,3,4,5,6].map(byte => [buf.readUIntLE(0, byte), buf.readUIntLE(1, byte)])"),
+ njs_str("250,251,"
+ "64506,64763,"
+ "16579578,16645371,"
+ "4261215226,4278058235,"
+ "1095182908410,1099494718715,"
+ "281470647991290,274877890034939") },
- { njs_str("let x = {async af() {await Promise.resolve(1)}}; x.af"),
- njs_str("[object AsyncFunction]") },
+ { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
+ "[1,2,3,4,5,6].map(byte => [buf.readIntLE(0, byte), buf.readIntLE(1, byte)])"),
+ njs_str("-6,-5,"
+ "-1030,-773,"
+ "-197638,-131845,"
+ "-33752070,-16909061,"
+ "-4328719366,-16909061,"
+ "-4328719366,-6597086675717") },
- { njs_str("let name = 'af', x = {async [name]() {await Promise.resolve(1)}}; x.af"),
- njs_str("[object AsyncFunction]") },
-};
+ { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
+ "[1,2,3,4,5,6].map(byte => [buf.readUIntBE(0, byte), buf.readUIntBE(1, byte)])"),
+ njs_str("250,251,"
+ "64251,64508,"
+ "16448508,16514301,"
+ "4210818301,4227661310,"
+ "1077969485310,1082281295615,"
+ "275960188239615,277064011677689") },
+ { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
+ "[1,2,3,4,5,6].map(byte => [buf.readIntBE(0, byte), buf.readIntBE(1, byte)])"),
+ njs_str("-6,-5,"
+ "-1285,-1028,"
+ "-328708,-262915,"
+ "-84148995,-67305986,"
+ "-21542142466,-17230332161,"
+ "-5514788471041,-4410965032967") },
-static njs_unit_test_t njs_safe_test[] =
-{
- { njs_str("(new Function('return this'))() === globalThis"),
+ { njs_str("var buf = Buffer.from([0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0xF9, 0xf8]);"
+ "function t(sign, endianness, offset) { "
+ " return [1,2,4].every(size => {"
+ " var method = `read${sign}Int${size * 8}`;"
+ " if (size > 1) { method += endianness};"
+ " var gmethod = `read${sign}Int${endianness}`;"
+ " var gv = buf[gmethod](offset, size);"
+ " var sv = buf[method](offset);"
+ " if (gv != sv) {throw Error(`${gmethod}(${offset},${size}):${gv} != ${method}(${offset}):${sv}`)}"
+ " return true;"
+ " });"
+ "}; "
+ "t('U', 'LE', 0) && t('U', 'LE', 1)"
+ "&& t('', 'LE', 0) && t('', 'LE', 1)"
+ "&& t('U', 'BE', 0) && t('U', 'BE', 1)"
+ "&& t('', 'BE', 0) && t('', 'BE', 1)"),
njs_str("true") },
- { njs_str("(new Function('return this;'))() === globalThis"),
+ { njs_str("var buf = Buffer.alloc(9);"
+ "function t(sign, endianness, offset) { "
+ " return [1,2,4].every(size => {"
+ " var rgmethod = `read${sign}Int${endianness}`;"
+ " var wgmethod = `write${sign}Int${endianness}`;"
+ " var rmethod = `read${sign}Int${size * 8}`;"
+ " var wmethod = `write${sign}Int${size * 8}`;"
+ " if (size > 1) { rmethod += endianness; wmethod += endianness; };"
+ " var v = 0x7abbccddeeff & (size * 8 - 1);"
+ ""
+ " var ret = buf[wgmethod](v, offset, size);"
+ " if(ret !== offset + size) {"
+ " throw Error(`${wgmethod} returned ${ret}, need ${offset + size}`);"
+ " }"
+ ""
+ " var gv = buf[rgmethod](offset, size);"
+ ""
+ " buf.fill(0);"
+ " buf[wmethod](v, offset);"
+ " var sv = buf[rmethod](offset);"
+ " if (gv != sv) {throw Error(`${wmethod}(${v}, ${offset}):${sv} != ${wgmethod}(${v},${offset}):${gv}`)}"
+ " return true;"
+ " });"
+ "}; "
+ "t('U', 'LE', 0) && t('U', 'LE', 1)"
+ "&& t('', 'LE', 0) && t('', 'LE', 1)"
+ "&& t('U', 'BE', 0) && t('U', 'BE', 1)"
+ "&& t('', 'BE', 0) && t('', 'BE', 1)"),
njs_str("true") },
- { njs_str("(new Function('return this '))() === globalThis"),
- njs_str("true") },
+ { njs_str(njs_buffer_byte_map("writeUIntLE", "+", 1)),
+ njs_str("Buffer [128,0,0,0,0,0],"
+ "Buffer [0,64,0,0,0,0],"
+ "Buffer [0,0,32,0,0,0],"
+ "Buffer [0,0,0,16,0,0],"
+ "Buffer [0,0,0,0,8,0],"
+ "Buffer [0,0,0,0,0,4]") },
- { njs_str("(new Function('return thi'))()"),
- njs_str("TypeError: function constructor is disabled in \"safe\" mode") },
+ { njs_str(njs_buffer_byte_map("writeUIntBE", "+", 1)),
+ njs_str("Buffer [128,0,0,0,0,0],"
+ "Buffer [64,0,0,0,0,0],"
+ "Buffer [32,0,0,0,0,0],"
+ "Buffer [16,0,0,0,0,0],"
+ "Buffer [8,0,0,0,0,0],"
+ "Buffer [4,0,0,0,0,0]") },
- { njs_str("(new Function('){return 1337})//', 'return this'))()"),
- njs_str("TypeError: function constructor is disabled in \"safe\" mode") },
-};
+ { njs_str(njs_buffer_byte_map("writeIntLE", "-", 2)),
+ njs_str("Buffer [192,0,0,0,0,0],"
+ "Buffer [0,224,0,0,0,0],"
+ "Buffer [0,0,240,0,0,0],"
+ "Buffer [0,0,0,248,0,0],"
+ "Buffer [0,0,0,0,252,0],"
+ "Buffer [0,0,0,0,0,254]") },
+ { njs_str(njs_buffer_byte_map("writeIntBE", "-", 2)),
+ njs_str("Buffer [192,0,0,0,0,0],"
+ "Buffer [224,0,0,0,0,0],"
+ "Buffer [240,0,0,0,0,0],"
+ "Buffer [248,0,0,0,0,0],"
+ "Buffer [252,0,0,0,0,0],"
+ "Buffer [254,0,0,0,0,0]") },
-static njs_unit_test_t njs_denormals_test[] =
-{
- { njs_str("2.2250738585072014e-308"),
- njs_str("2.2250738585072014e-308") },
+ { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleBE()"),
+ njs_str("8.20788039913184e-304") },
-#ifndef NJS_SUNC
- { njs_str("2.2250738585072014E-308.toString(2) == ('0.' + '0'.repeat(1021) + '1')"),
- njs_str("true") },
+ { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleLE()"),
+ njs_str("5.447603722011605e-270") },
- { njs_str("Number('2.2250738585072014E-323')"),
- njs_str("2.5e-323") },
+ { njs_str("Buffer.from([1, 2, 3, 4]).readFloatBE()"),
+ njs_str("2.387939260590663e-38") },
- { njs_str("Number('2.2250738585072014E-323') + 0"),
- njs_str("2.5e-323") },
+ { njs_str("Buffer.from([1, 2, 3, 4]).readFloatLE()"),
+ njs_str("1.539989614439558e-36") },
- /* Smallest positive double (next_double(0)). */
- { njs_str("5E-324.toString(36) === '0.' + '0'.repeat(207) + '3'"),
- njs_str("true") },
+ { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleBE(1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- /* Maximum fraction length. */
- { njs_str("2.2250738585072014E-323.toString(2) == ('0.' + '0'.repeat(1071) + '101')"),
- njs_str("true") },
+ { njs_str("Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]).readDoubleLE(1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- /* Denormals. */
- { njs_str("var zeros = count => '0'.repeat(count);"
- "["
- " [1.8858070859709815e-308, `0.${zeros(1022)}1101100011110111011100000100011001111101110001010111`],"
- // FIXME: " [Number.MIN_VALUE, `0.${zeros(1073)}1`]"
- " [-5.06631661953108e-309, `-0.${zeros(1024)}11101001001010000001101111010101011111111011010111`],"
- " [6.22574126804e-313, `0.${zeros(1037)}11101010101101100111000110100111001`],"
- " [-4e-323, `-0.${zeros(1070)}1`],"
- "].every(t=>t[0].toString(2) === t[1])"),
- njs_str("true") },
+ { njs_str("Buffer.from([1, 2, 3, 4]).readFloatBE(1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- { njs_str("4.94065645841246544176568792868e-324.toExponential()"),
- njs_str("5e-324") },
+ { njs_str("Buffer.from([1, 2, 3, 4]).readFloatLE(1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- { njs_str("4.94065645841246544176568792868e-324.toExponential(10)"),
- njs_str("4.9406564584e-324") },
-#endif
+ { njs_str("var buf = Buffer.allocUnsafe(8);"
+ "buf.writeDoubleBE(123.456); njs.dump(buf)"),
+ njs_str("Buffer [64,94,221,47,26,159,190,119]") },
-};
+ { njs_str("var buf = Buffer.allocUnsafe(8);"
+ "buf.writeDoubleLE(123.456); njs.dump(buf)"),
+ njs_str("Buffer [119,190,159,26,47,221,94,64]") },
+ { njs_str("var buf = Buffer.allocUnsafe(4);"
+ "buf.writeFloatBE(123.456); njs.dump(buf)"),
+ njs_str("Buffer [66,246,233,121]") },
-static njs_unit_test_t njs_disabled_denormals_test[] =
-{
- { njs_str("Number('2.2250738585072014E-323')"),
- njs_str("0") },
+ { njs_str("var buf = Buffer.allocUnsafe(4);"
+ "buf.writeFloatLE(123.456); njs.dump(buf)"),
+ njs_str("Buffer [121,233,246,66]") },
- { njs_str("Number('2.2250738585072014E-323') + 0"),
- njs_str("0") },
+ { njs_str("var buf = Buffer.allocUnsafe(8).writeDoubleBE(123.456, 1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- /* Smallest positive double (next_double(0)). */
- { njs_str("5E-324.toString(36)"),
- njs_str("0") },
+ { njs_str("var buf = Buffer.allocUnsafe(8).writeDoubleLE(123.456, 1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- { njs_str("2.2250738585072014E-323.toString(2)"),
- njs_str("0") },
+ { njs_str("var buf = Buffer.allocUnsafe(4).writeFloatBE(123.456, 1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- /* Smallest normal double. */
+ { njs_str("var buf = Buffer.allocUnsafe(4).writeFloatLE(123.456, 1)"),
+ njs_str("RangeError: index 1 is outside the bound of the buffer") },
- { njs_str("2.2250738585072014e-308"),
- njs_str("2.2250738585072014e-308") },
+ { njs_str("var buffer = require('buffer');"
+ "buffer.Buffer.alloc(5).fill('ABC')"),
+ njs_str("ABCAB") },
- { njs_str("2.2250738585072014e-308/2"),
- njs_str("0") },
+ { njs_str("var buffer = require('buffer');"
+ "typeof buffer.kMaxLength === 'number' "),
+ njs_str("true") },
- /* Denormals. */
- { njs_str("["
- "1.8858070859709815e-308,"
- "-5.06631661953108e-309,"
- "6.22574126804e-313,"
- "-4e-323,"
- "].map(v=>v.toString(2))"),
- njs_str("0,0,0,0") },
+ { njs_str("var buffer = require('buffer');"
+ "typeof buffer.constants.MAX_LENGTH === 'number' "),
+ njs_str("true") },
+
+ { njs_str("var buffer = require('buffer');"
+ "typeof buffer.constants.MAX_STRING_LENGTH === 'number' "),
+ njs_str("true") },
};
njs_nitems(njs_module_test),
njs_unit_test },
+ { njs_str("fs module"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_fs_module_test,
+ njs_nitems(njs_fs_module_test),
+ njs_unit_test },
+
+ { njs_str("crypto module"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_crypto_module_test,
+ njs_nitems(njs_crypto_module_test),
+ njs_unit_test },
+
+ { njs_str("querystring module"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_querystring_module_test,
+ njs_nitems(njs_querystring_module_test),
+ njs_unit_test },
+
+ { njs_str("buffer module"),
+ { .repeat = 1, .unsafe = 1 },
+ njs_buffer_module_test,
+ njs_nitems(njs_buffer_module_test),
+ njs_unit_test },
+
{ njs_str("externals"),
{ .externals = 1, .repeat = 1, .unsafe = 1 },
njs_externals_test,