From 0ea74f3d028708f7bae9137c9913d284366fa488 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 24 Oct 2024 15:37:15 +0200 Subject: [PATCH 01/93] test,crypto: make crypto tests work with BoringSSL PR-URL: https://github.com/nodejs/node/pull/55491 Reviewed-By: Richard Lau Reviewed-By: Yagiz Nizipli Reviewed-By: Luigi Pinca Reviewed-By: Filip Skokan --- test/parallel/test-crypto-dh-errors.js | 4 ++-- test/parallel/test-crypto-private-decrypt-gh32240.js | 2 +- test/parallel/test-tls-getcertificate-x509.js | 9 ++------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/test/parallel/test-crypto-dh-errors.js b/test/parallel/test-crypto-dh-errors.js index fcf1922bcdba73..476ca64b4425b5 100644 --- a/test/parallel/test-crypto-dh-errors.js +++ b/test/parallel/test-crypto-dh-errors.js @@ -43,7 +43,7 @@ for (const g of [-1, 1]) { const ex = { code: 'ERR_OSSL_DH_BAD_GENERATOR', name: 'Error', - message: /bad generator/, + message: /(?:bad[_ ]generator)/i, }; assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); @@ -55,7 +55,7 @@ for (const g of [Buffer.from([]), const ex = { code: 'ERR_OSSL_DH_BAD_GENERATOR', name: 'Error', - message: /bad generator/, + message: /(?:bad[_ ]generator)/i, }; assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); diff --git a/test/parallel/test-crypto-private-decrypt-gh32240.js b/test/parallel/test-crypto-private-decrypt-gh32240.js index 1785f5eef3d202..e88227a215ba4f 100644 --- a/test/parallel/test-crypto-private-decrypt-gh32240.js +++ b/test/parallel/test-crypto-private-decrypt-gh32240.js @@ -24,7 +24,7 @@ const pkeyEncrypted = pair.privateKey.export({ type: 'pkcs1', format: 'pem', - cipher: 'aes128', + cipher: 'aes-128-cbc', passphrase: 'secret', }); diff --git a/test/parallel/test-tls-getcertificate-x509.js b/test/parallel/test-tls-getcertificate-x509.js index aa685ca9e09cf0..704aa33e6edfab 100644 --- a/test/parallel/test-tls-getcertificate-x509.js +++ b/test/parallel/test-tls-getcertificate-x509.js @@ -20,9 +20,7 @@ const server = tls.createServer(options, function(cleartext) { server.once('secureConnection', common.mustCall(function(socket) { const cert = socket.getX509Certificate(); assert(cert instanceof X509Certificate); - assert.strictEqual( - cert.serialNumber, - '5B75D77EDC7FB5B7FA9F1424DA4C64FB815DCBDE'); + assert.match(cert.serialNumber, /5B75D77EDC7FB5B7FA9F1424DA4C64FB815DCBDE/i); })); server.listen(0, common.mustCall(function() { @@ -33,10 +31,7 @@ server.listen(0, common.mustCall(function() { const peerCert = socket.getPeerX509Certificate(); assert(peerCert.issuerCertificate instanceof X509Certificate); assert.strictEqual(peerCert.issuerCertificate.issuerCertificate, undefined); - assert.strictEqual( - peerCert.issuerCertificate.serialNumber, - '147D36C1C2F74206DE9FAB5F2226D78ADB00A425' - ); + assert.match(peerCert.issuerCertificate.serialNumber, /147D36C1C2F74206DE9FAB5F2226D78ADB00A425/i); server.close(); })); socket.end('Hello'); From 69dd1e13c3ce82ef484f23191e7a4196ad9883c0 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Thu, 24 Oct 2024 20:27:58 +0200 Subject: [PATCH 02/93] module: add module.stripTypeScriptTypes PR-URL: https://github.com/nodejs/node/pull/55282 Fixes: https://github.com/nodejs/node/issues/54300 Reviewed-By: Yagiz Nizipli Reviewed-By: Joyee Cheung Reviewed-By: Chemi Atlow Reviewed-By: Paolo Insogna Reviewed-By: Chengzhong Wu Reviewed-By: James M Snell Reviewed-By: Richard Lau --- doc/api/module.md | 101 ++++++++++++++++ lib/internal/main/eval_string.js | 6 +- lib/internal/modules/cjs/loader.js | 10 +- lib/internal/modules/esm/get_format.js | 5 +- lib/internal/modules/esm/translators.js | 8 +- lib/internal/modules/helpers.js | 74 +----------- lib/internal/modules/typescript.js | 146 +++++++++++++++++++++++ lib/module.js | 3 +- test/parallel/test-bootstrap-modules.js | 1 + test/parallel/test-module-strip-types.js | 92 ++++++++++++++ 10 files changed, 358 insertions(+), 88 deletions(-) create mode 100644 lib/internal/modules/typescript.js create mode 100644 test/parallel/test-module-strip-types.js diff --git a/doc/api/module.md b/doc/api/module.md index 21c290aea311aa..440dfca6b822e7 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -270,6 +270,105 @@ changes: Register a module that exports [hooks][] that customize Node.js module resolution and loading behavior. See [Customization hooks][]. +## `module.stripTypeScriptTypes(code[, options])` + + + +> Stability: 1.0 - Early development + +* `code` {string} The code to strip type annotations from. +* `options` {Object} + * `mode` {string} **Default:** `'strip'`. Possible values are: + * `'strip'` Only strip type annotations without performing the transformation of TypeScript features. + * `'transform'` Strip type annotations and transform TypeScript features to JavaScript. + * `sourceMap` {boolean} **Default:** `false`. Only when `mode` is `'transform'`, if `true`, a source map + will be generated for the transformed code. + * `sourceUrl` {string} Specifies the source url used in the source map. +* Returns: {string} The code with type annotations stripped. + `module.stripTypeScriptTypes()` removes type annotations from TypeScript code. It + can be used to strip type annotations from TypeScript code before running it + with `vm.runInContext()` or `vm.compileFunction()`. + By default, it will throw an error if the code contains TypeScript features + that require transformation such as `Enums`, + see [type-stripping][] for more information. + When mode is `'transform'`, it also transforms TypeScript features to JavaScript, + see [transform TypeScript features][] for more information. + When mode is `'strip'`, source maps are not generated, because locations are preserved. + If `sourceMap` is provided, when mode is `'strip'`, an error will be thrown. + +_WARNING_: The output of this function should not be considered stable across Node.js versions, +due to changes in the TypeScript parser. + +```mjs +import { stripTypeScriptTypes } from 'node:module'; +const code = 'const a: number = 1;'; +const strippedCode = stripTypeScriptTypes(code); +console.log(strippedCode); +// Prints: const a = 1; +``` + +```cjs +const { stripTypeScriptTypes } = require('node:module'); +const code = 'const a: number = 1;'; +const strippedCode = stripTypeScriptTypes(code); +console.log(strippedCode); +// Prints: const a = 1; +``` + +If `sourceUrl` is provided, it will be used appended as a comment at the end of the output: + +```mjs +import { stripTypeScriptTypes } from 'node:module'; +const code = 'const a: number = 1;'; +const strippedCode = stripTypeScriptTypes(code, { mode: 'strip', sourceUrl: 'source.ts' }); +console.log(strippedCode); +// Prints: const a = 1\n\n//# sourceURL=source.ts; +``` + +```cjs +const { stripTypeScriptTypes } = require('node:module'); +const code = 'const a: number = 1;'; +const strippedCode = stripTypeScriptTypes(code, { mode: 'strip', sourceUrl: 'source.ts' }); +console.log(strippedCode); +// Prints: const a = 1\n\n//# sourceURL=source.ts; +``` + +When `mode` is `'transform'`, the code is transformed to JavaScript: + +```mjs +import { stripTypeScriptTypes } from 'node:module'; +const code = ` + namespace MathUtil { + export const add = (a: number, b: number) => a + b; + }`; +const strippedCode = stripTypeScriptTypes(code, { mode: 'transform', sourceMap: true }); +console.log(strippedCode); +// Prints: +// var MathUtil; +// (function(MathUtil) { +// MathUtil.add = (a, b)=>a + b; +// })(MathUtil || (MathUtil = {})); +// # sourceMappingURL=data:application/json;base64, ... +``` + +```cjs +const { stripTypeScriptTypes } = require('node:module'); +const code = ` + namespace MathUtil { + export const add = (a: number, b: number) => a + b; + }`; +const strippedCode = stripTypeScriptTypes(code, { mode: 'transform', sourceMap: true }); +console.log(strippedCode); +// Prints: +// var MathUtil; +// (function(MathUtil) { +// MathUtil.add = (a, b)=>a + b; +// })(MathUtil || (MathUtil = {})); +// # sourceMappingURL=data:application/json;base64, ... +``` + ### `module.syncBuiltinESMExports()` + +> Stability: 1.1 - Active Development + +* `specifier` {string|URL} The specifier for the module whose `package.json` to + retrieve. When passing a _bare specifier_, the `package.json` at the root of + the package is returned. When passing a _relative specifier_ or an _absolute specifier_, + the closest parent `package.json` is returned. +* `base` {string|URL} The absolute location (`file:` URL string or FS path) of the + containing module. For CJS, use `__filename` (not `__dirname`!); for ESM, use + `import.meta.url`. You do not need to pass it if `specifier` is an `absolute specifier`. +* Returns: {string|undefined} A path if the `package.json` is found. When `startLocation` + is a package, the package's root `package.json`; when a relative or unresolved, the closest + `package.json` to the `startLocation`. + +> **Caveat**: Do not use this to try to determine module format. There are many things effecting +> that determination; the `type` field of package.json is the _least_ definitive (ex file extension +> superceeds it, and a loader hook superceeds that). + +```text +/path/to/project + ├ packages/ + ├ bar/ + ├ bar.js + └ package.json // name = '@foo/bar' + └ qux/ + ├ node_modules/ + └ some-package/ + └ package.json // name = 'some-package' + ├ qux.js + └ package.json // name = '@foo/qux' + ├ main.js + └ package.json // name = '@foo' +``` + +```mjs +// /path/to/project/packages/bar/bar.js +import { findPackageJSON } from 'node:module'; + +findPackageJSON('..', import.meta.url); +// '/path/to/project/package.json' +// Same result when passing an absolute specifier instead: +findPackageJSON(new URL('../', import.meta.url)); +findPackageJSON(import.meta.resolve('../')); + +findPackageJSON('some-package', import.meta.url); +// '/path/to/project/packages/bar/node_modules/some-package/package.json' +// When passing an absolute specifier, you might get a different result if the +// resolved module is inside a subfolder that has nested `package.json`. +findPackageJSON(import.meta.resolve('some-package')); +// '/path/to/project/packages/bar/node_modules/some-package/some-subfolder/package.json' + +findPackageJSON('@foo/qux', import.meta.url); +// '/path/to/project/packages/qux/package.json' +``` + +```cjs +// /path/to/project/packages/bar/bar.js +const { findPackageJSON } = require('node:module'); +const { pathToFileURL } = require('node:url'); +const path = require('node:path'); + +findPackageJSON('..', __filename); +// '/path/to/project/package.json' +// Same result when passing an absolute specifier instead: +findPackageJSON(pathToFileURL(path.join(__dirname, '..'))); + +findPackageJSON('some-package', __filename); +// '/path/to/project/packages/bar/node_modules/some-package/package.json' +// When passing an absolute specifier, you might get a different result if the +// resolved module is inside a subfolder that has nested `package.json`. +findPackageJSON(pathToFileURL(require.resolve('some-package'))); +// '/path/to/project/packages/bar/node_modules/some-package/some-subfolder/package.json' + +findPackageJSON('@foo/qux', __filename); +// '/path/to/project/packages/qux/package.json' +``` + ### `module.isBuiltin(moduleName)` -> Stability: 1.0 - Early development +> Stability: 1.1 - Active development Enables the transformation of TypeScript-only syntax into JavaScript code. Implies `--experimental-strip-types` and `--enable-source-maps`. @@ -1120,7 +1120,7 @@ Enable the experimental [`node:sqlite`][] module. added: v22.6.0 --> -> Stability: 1.0 - Early development +> Stability: 1.1 - Active development Enable experimental type-stripping for TypeScript files. For more information, see the [TypeScript type-stripping][] documentation. diff --git a/doc/api/module.md b/doc/api/module.md index dcee85d6d00793..26469eb18aa41c 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -358,7 +358,7 @@ resolution and loading behavior. See [Customization hooks][]. added: REPLACEME --> -> Stability: 1.0 - Early development +> Stability: 1.1 - Active development * `code` {string} The code to strip type annotations from. * `options` {Object} diff --git a/doc/api/process.md b/doc/api/process.md index f30b3ee335b9f5..b56d0e4e1386bd 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -1993,7 +1993,7 @@ A boolean value that is `true` if the current Node.js build includes support for added: v23.0.0 --> -> Stability: 1.0 - Early development +> Stability: 1.1 - Active development * {boolean|string} diff --git a/doc/api/typescript.md b/doc/api/typescript.md index 3b3f615953cb93..c6dfb774c3f068 100644 --- a/doc/api/typescript.md +++ b/doc/api/typescript.md @@ -7,7 +7,7 @@ changes: description: Added `--experimental-transform-types` flag. --> -> Stability: 1.0 - Early development +> Stability: 1.1 - Active development ## Enabling @@ -50,7 +50,7 @@ To use TypeScript with full support for all TypeScript features, including added: v22.6.0 --> -> Stability: 1.0 - Early development +> Stability: 1.1 - Active development The flag [`--experimental-strip-types`][] enables Node.js to run TypeScript files. By default Node.js will execute only files that contain no From f628fc43cb4987a2dfc698e70ed9eb60f121c31e Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 28 Oct 2024 09:33:39 +0100 Subject: [PATCH 15/93] fs: make `dirent.path` writable PR-URL: https://github.com/nodejs/node/pull/55547 Refs: https://github.com/nodejs/node/issues/55538 Reviewed-By: Matteo Collina Reviewed-By: LiviaMedeiros Reviewed-By: Yagiz Nizipli Reviewed-By: Rafael Gonzaga Reviewed-By: Chemi Atlow --- doc/api/fs.md | 5 ++++- lib/internal/fs/utils.js | 4 ++++ test/parallel/test-fs-utils-get-dirents.js | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index c2d26a4a908c05..a6628e7bee061d 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -6822,6 +6822,9 @@ deprecated: - v20.12.0 - v18.20.0 changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/55547 + description: The property is no longer read-only. - version: v23.0.0 pr-url: https://github.com/nodejs/node/pull/51050 description: Accessing this property emits a warning. It is now read-only. @@ -6831,7 +6834,7 @@ changes: * {string} -Alias for `dirent.parentPath`. Read-only. +Alias for `dirent.parentPath`. ### Class: `fs.FSWatcher` diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 2d85ed2196529d..5080bbf2580889 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -49,6 +49,7 @@ const { once, deprecate, isWindows, + setOwnProperty, } = require('internal/util'); const { toPathIfFileURL } = require('internal/url'); const { @@ -214,6 +215,9 @@ ObjectDefineProperty(Dirent.prototype, 'path', { get: deprecate(function() { return this.parentPath; }, 'dirent.path is deprecated in favor of dirent.parentPath', 'DEP0178'), + set(value) { + setOwnProperty(this, 'path', value); + }, configurable: true, enumerable: false, }); diff --git a/test/parallel/test-fs-utils-get-dirents.js b/test/parallel/test-fs-utils-get-dirents.js index dfc851090b269d..97dca15f38343d 100644 --- a/test/parallel/test-fs-utils-get-dirents.js +++ b/test/parallel/test-fs-utils-get-dirents.js @@ -78,6 +78,18 @@ const filename = 'foo'; }, )); } +{ + // Reassigning `.path` property should not trigger a warning + const dirent = getDirent( + tmpdir.path, + filename, + UV_DIRENT_UNKNOWN, + ); + assert.strictEqual(dirent.name, filename); + dirent.path = 'some other value'; + assert.strictEqual(dirent.parentPath, tmpdir.path); + assert.strictEqual(dirent.path, 'some other value'); +} { // string + Buffer const filenameBuffer = Buffer.from(filename); From f8df27aa5ad01c402b3fda06a3c8e8685b003713 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Mon, 28 Oct 2024 10:27:31 +0100 Subject: [PATCH 16/93] build: fix GN arg used in generate_config_gypi.py PR-URL: https://github.com/nodejs/node/pull/55530 Reviewed-By: Cheng Zhao Reviewed-By: Yagiz Nizipli Reviewed-By: Luigi Pinca --- tools/generate_config_gypi.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/generate_config_gypi.py b/tools/generate_config_gypi.py index 45b3ac5006140f..c9dd4a24a39c50 100755 --- a/tools/generate_config_gypi.py +++ b/tools/generate_config_gypi.py @@ -19,11 +19,7 @@ # Regex used for parsing results of "gn args". GN_RE = re.compile(r'(\w+)\s+=\s+(.*?)$', re.MULTILINE) - -if sys.platform == 'win32': - GN = 'gn.exe' -else: - GN = 'gn' +GN = 'gn.bat' if sys.platform == 'win32' else 'gn' def bool_to_number(v): return 1 if v else 0 From a9e08cfe6d1fa0cbf45a4098dc040ac336d5f4ae Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 28 Oct 2024 13:21:22 +0100 Subject: [PATCH 17/93] module: allow ESM that failed to be required to be re-imported When a ESM module cannot be loaded by require due to the presence of TLA, its module status would be stopped at kInstantiated. In this case, when it's imported again, we should allow it to be evaluated asynchronously, as it's also a common pattern for users to retry with dynamic import when require fails. PR-URL: https://github.com/nodejs/node/pull/55502 Fixes: https://github.com/nodejs/node/issues/55500 Refs: https://github.com/nodejs/node/issues/52697 Reviewed-By: Matteo Collina Reviewed-By: Chemi Atlow --- lib/internal/modules/esm/module_job.js | 24 ++++++++++--- ...est-require-module-retry-import-errored.js | 35 +++++++++++++++++++ ...-require-module-retry-import-evaluating.js | 32 +++++++++++++++++ .../test-require-module-tla-retry-import-2.js | 26 ++++++++++++++ .../test-require-module-tla-retry-import.js | 25 +++++++++++++ .../es-modules/tla/await-export-promise.mjs | 4 +++ test/fixtures/es-modules/tla/export-async.mjs | 2 ++ .../es-modules/tla/export-promise.mjs | 8 +++++ 8 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 test/es-module/test-require-module-retry-import-errored.js create mode 100644 test/es-module/test-require-module-retry-import-evaluating.js create mode 100644 test/es-module/test-require-module-tla-retry-import-2.js create mode 100644 test/es-module/test-require-module-tla-retry-import.js create mode 100644 test/fixtures/es-modules/tla/await-export-promise.mjs create mode 100644 test/fixtures/es-modules/tla/export-async.mjs create mode 100644 test/fixtures/es-modules/tla/export-promise.mjs diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index 413fcd27703e3e..ece30c3864d6a7 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -22,7 +22,7 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { debug = fn; }); -const { ModuleWrap, kEvaluated } = internalBinding('module_wrap'); +const { ModuleWrap, kInstantiated } = internalBinding('module_wrap'); const { privateSymbols: { entry_point_module_private_symbol, @@ -354,10 +354,26 @@ class ModuleJobSync extends ModuleJobBase { } async run() { + // This path is hit by a require'd module that is imported again. const status = this.module.getStatus(); - assert(status === kEvaluated, - `A require()-d module that is imported again must be evaluated. Status = ${status}`); - return { __proto__: null, module: this.module }; + if (status > kInstantiated) { + if (this.evaluationPromise) { + await this.evaluationPromise; + } + return { __proto__: null, module: this.module }; + } else if (status === kInstantiated) { + // The evaluation may have been canceled because instantiateSync() detected TLA first. + // But when it is imported again, it's fine to re-evaluate it asynchronously. + const timeout = -1; + const breakOnSigint = false; + this.evaluationPromise = this.module.evaluate(timeout, breakOnSigint); + await this.evaluationPromise; + this.evaluationPromise = undefined; + return { __proto__: null, module: this.module }; + } + + assert.fail('Unexpected status of a module that is imported again after being required. ' + + `Status = ${status}`); } runSync() { diff --git a/test/es-module/test-require-module-retry-import-errored.js b/test/es-module/test-require-module-retry-import-errored.js new file mode 100644 index 00000000000000..4736087d2624a5 --- /dev/null +++ b/test/es-module/test-require-module-retry-import-errored.js @@ -0,0 +1,35 @@ +// This tests that after failing to require an ESM that contains TLA, +// retrying with import() still works, and produces consistent results. +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { exportedReject } = require('../fixtures/es-modules/tla/export-promise.mjs'); + +assert.throws(() => { + require('../fixtures/es-modules/tla/await-export-promise.mjs'); +}, { + code: 'ERR_REQUIRE_ASYNC_MODULE' +}); + +const interval = setInterval(() => {}, 1000); // Keep the test running, because await alone doesn't. +const err = new Error('rejected'); + +const p1 = import('../fixtures/es-modules/tla/await-export-promise.mjs') + .then(common.mustNotCall(), common.mustCall((e) => { + assert.strictEqual(e, err); + })); + +const p2 = import('../fixtures/es-modules/tla/await-export-promise.mjs') + .then(common.mustNotCall(), common.mustCall((e) => { + assert.strictEqual(e, err); + })); + +const p3 = import('../fixtures/es-modules/tla/await-export-promise.mjs') + .then(common.mustNotCall(), common.mustCall((e) => { + assert.strictEqual(e, err); + })); + +exportedReject(err); + +Promise.all([p1, p2, p3]).then(common.mustCall(() => { clearInterval(interval); })); diff --git a/test/es-module/test-require-module-retry-import-evaluating.js b/test/es-module/test-require-module-retry-import-evaluating.js new file mode 100644 index 00000000000000..df70432f1136e4 --- /dev/null +++ b/test/es-module/test-require-module-retry-import-evaluating.js @@ -0,0 +1,32 @@ +// This tests that after failing to require an ESM that contains TLA, +// retrying with import() still works, and produces consistent results. +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const { exportedResolve } = require('../fixtures/es-modules/tla/export-promise.mjs'); + +assert.throws(() => { + require('../fixtures/es-modules/tla/await-export-promise.mjs'); +}, { + code: 'ERR_REQUIRE_ASYNC_MODULE' +}); + +const interval = setInterval(() => {}, 1000); // Keep the test running, because await alone doesn't. +const value = { hello: 'world' }; + +const p1 = import('../fixtures/es-modules/tla/await-export-promise.mjs').then(common.mustCall((ns) => { + assert.strictEqual(ns.default, value); +}), common.mustNotCall()); + +const p2 = import('../fixtures/es-modules/tla/await-export-promise.mjs').then(common.mustCall((ns) => { + assert.strictEqual(ns.default, value); +}), common.mustNotCall()); + +const p3 = import('../fixtures/es-modules/tla/await-export-promise.mjs').then(common.mustCall((ns) => { + assert.strictEqual(ns.default, value); +}), common.mustNotCall()); + +exportedResolve(value); + +Promise.all([p1, p2, p3]).then(common.mustCall(() => { clearInterval(interval); })); diff --git a/test/es-module/test-require-module-tla-retry-import-2.js b/test/es-module/test-require-module-tla-retry-import-2.js new file mode 100644 index 00000000000000..aa9c344dd398d7 --- /dev/null +++ b/test/es-module/test-require-module-tla-retry-import-2.js @@ -0,0 +1,26 @@ +// This tests that after loading a ESM with import() and then retrying +// with require(), it errors as expected, and produces consistent results. +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +let ns; +async function test() { + const newNs = await import('../fixtures/es-modules/tla/export-async.mjs'); + if (ns === undefined) { + ns = newNs; + } else { + // Check that re-evalaution is returning the same namespace. + assert.strictEqual(ns, newNs); + } + assert.strictEqual(ns.hello, 'world'); + + assert.throws(() => { + require('../fixtures/es-modules/tla/export-async.mjs'); + }, { + code: 'ERR_REQUIRE_ASYNC_MODULE' + }); +} + +// Run the test twice to check consistency after caching. +test().then(common.mustCall(test)).catch(common.mustNotCall()); diff --git a/test/es-module/test-require-module-tla-retry-import.js b/test/es-module/test-require-module-tla-retry-import.js new file mode 100644 index 00000000000000..70f918fa4f463f --- /dev/null +++ b/test/es-module/test-require-module-tla-retry-import.js @@ -0,0 +1,25 @@ +// This tests that after failing to require an ESM that contains TLA, +// retrying with import() still works, and produces consistent results. +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +let ns; +async function test() { + assert.throws(() => { + require('../fixtures/es-modules/tla/export-async.mjs'); + }, { + code: 'ERR_REQUIRE_ASYNC_MODULE' + }); + const newNs = await import('../fixtures/es-modules/tla/export-async.mjs'); + if (ns === undefined) { + ns = newNs; + } else { + // Check that re-evalaution is returning the same namespace. + assert.strictEqual(ns, newNs); + } + assert.strictEqual(ns.hello, 'world'); +} + +// Run the test twice to check consistency after caching. +test().then(common.mustCall(test)).catch(common.mustNotCall()); diff --git a/test/fixtures/es-modules/tla/await-export-promise.mjs b/test/fixtures/es-modules/tla/await-export-promise.mjs new file mode 100644 index 00000000000000..0129793e42b54a --- /dev/null +++ b/test/fixtures/es-modules/tla/await-export-promise.mjs @@ -0,0 +1,4 @@ +import promise from './export-promise.mjs'; +let result; +result = await promise; +export default result; diff --git a/test/fixtures/es-modules/tla/export-async.mjs b/test/fixtures/es-modules/tla/export-async.mjs new file mode 100644 index 00000000000000..b6de9a5a5f68e9 --- /dev/null +++ b/test/fixtures/es-modules/tla/export-async.mjs @@ -0,0 +1,2 @@ +let hello = await Promise.resolve('world'); +export { hello }; diff --git a/test/fixtures/es-modules/tla/export-promise.mjs b/test/fixtures/es-modules/tla/export-promise.mjs new file mode 100644 index 00000000000000..74864d232e3c35 --- /dev/null +++ b/test/fixtures/es-modules/tla/export-promise.mjs @@ -0,0 +1,8 @@ +let exportedResolve; +let exportedReject; +const promise = new Promise((resolve, reject) => { + exportedResolve = resolve; + exportedReject = reject; +}); +export default promise; +export { exportedResolve, exportedReject }; From f92f20b930efa3341726d9ceab07a3d3c71a7278 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 28 Oct 2024 13:57:58 +0100 Subject: [PATCH 18/93] http: don't emit error after destroy PR-URL: https://github.com/nodejs/node/pull/55457 Reviewed-By: Yagiz Nizipli Reviewed-By: Matteo Collina Reviewed-By: Luigi Pinca Reviewed-By: Ethan Arrowood Reviewed-By: James M Snell Reviewed-By: Jake Yuesong Li --- lib/_http_outgoing.js | 6 ++++- test/parallel/test-http-outgoing-destroyed.js | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 7a402a0f900f30..23b850d1522c97 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -908,6 +908,10 @@ OutgoingMessage.prototype.write = function write(chunk, encoding, callback) { }; function onError(msg, err, callback) { + if (msg.destroyed) { + return; + } + const triggerAsyncId = msg.socket ? msg.socket[async_id_symbol] : undefined; defaultTriggerAsyncIdScope(triggerAsyncId, process.nextTick, @@ -919,7 +923,7 @@ function onError(msg, err, callback) { function emitErrorNt(msg, err, callback) { callback(err); - if (typeof msg.emit === 'function' && !msg._closed) { + if (typeof msg.emit === 'function' && !msg.destroyed) { msg.emit('error', err); } } diff --git a/test/parallel/test-http-outgoing-destroyed.js b/test/parallel/test-http-outgoing-destroyed.js index 2dd3d76fde7d40..4f8fd47eaa8222 100644 --- a/test/parallel/test-http-outgoing-destroyed.js +++ b/test/parallel/test-http-outgoing-destroyed.js @@ -51,5 +51,27 @@ const assert = require('assert'); .on('error', common.mustCall()) .write('asd'); }); +} +{ + const server = http.createServer(common.mustCall((req, res) => { + assert.strictEqual(res.closed, false); + res.end(); + res.destroy(); + // Make sure not to emit 'error' after .destroy(). + res.end('asd'); + assert.strictEqual(res.errored, undefined); + })).listen(0, () => { + http + .request({ + port: server.address().port, + method: 'GET' + }) + .on('response', common.mustCall((res) => { + res.resume().on('end', common.mustCall(() => { + server.close(); + })); + })) + .end(); + }); } From efa142c108988c04cba3216489cfbb47edd3f5db Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Mon, 28 Oct 2024 20:32:26 -0400 Subject: [PATCH 19/93] src: migrate `String::Value` to `String::ValueView` Fixes #54417 Ref: #55452 PR-URL: https://github.com/nodejs/node/pull/55458 Refs: https://github.com/nodejs/node/issues/55452 Reviewed-By: Vladimir Morozov Reviewed-By: Yagiz Nizipli Reviewed-By: James M Snell --- src/inspector_js_api.cc | 6 +++--- src/node_buffer.cc | 27 ++++++++++++--------------- src/string_bytes.cc | 20 ++++++++++---------- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index 282575601545d1..a43f1a361ef702 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -245,9 +245,9 @@ static void AsyncTaskScheduledWrapper(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK(args[0]->IsString()); - Local task_name = args[0].As(); - String::Value task_name_value(args.GetIsolate(), task_name); - StringView task_name_view(*task_name_value, task_name_value.length()); + + TwoByteValue task_name_buffer(args.GetIsolate(), args[0]); + StringView task_name_view(*task_name_buffer, task_name_buffer.length()); CHECK(args[1]->IsNumber()); int64_t task_id = args[1]->IntegerValue(env->context()).FromJust(); diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 2402adb3483e3e..6ea9442ef7c1fe 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -965,11 +965,9 @@ void IndexOfString(const FunctionCallbackInfo& args) { size_t result = haystack_length; if (enc == UCS2) { - String::Value needle_value(isolate, needle); - if (*needle_value == nullptr) - return args.GetReturnValue().Set(-1); + TwoByteValue needle_buffer(isolate, needle); - if (haystack_length < 2 || needle_value.length() < 1) { + if (haystack_length < 2 || needle_buffer.length() < 1) { return args.GetReturnValue().Set(-1); } @@ -989,13 +987,12 @@ void IndexOfString(const FunctionCallbackInfo& args) { offset / 2, is_forward); } else { - result = - nbytes::SearchString(reinterpret_cast(haystack), - haystack_length / 2, - reinterpret_cast(*needle_value), - needle_value.length(), - offset / 2, - is_forward); + result = nbytes::SearchString(reinterpret_cast(haystack), + haystack_length / 2, + needle_buffer.out(), + needle_buffer.length(), + offset / 2, + is_forward); } result *= 2; } else if (enc == UTF8) { @@ -1295,10 +1292,10 @@ static void Btoa(const FunctionCallbackInfo& args) { input->Length(), buffer.out()); } else { - String::Value value(env->isolate(), input); + String::ValueView value(env->isolate(), input); MaybeStackBuffer stack_buf(value.length()); size_t out_len = simdutf::convert_utf16_to_latin1( - reinterpret_cast(*value), + reinterpret_cast(value.data16()), value.length(), stack_buf.out()); if (out_len == 0) { // error @@ -1355,8 +1352,8 @@ static void Atob(const FunctionCallbackInfo& args) { buffer.SetLength(expected_length); result = simdutf::base64_to_binary(data, input->Length(), buffer.out()); } else { // 16-bit case - String::Value value(env->isolate(), input); - auto data = reinterpret_cast(*value); + String::ValueView value(env->isolate(), input); + auto data = reinterpret_cast(value.data16()); size_t expected_length = simdutf::maximal_binary_length_from_base64(data, value.length()); buffer.AllocateSufficientStorage(expected_length); diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 8a94d0eb63245c..9e12fd1585639b 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -305,11 +305,10 @@ size_t StringBytes::Write(Isolate* isolate, input_view.length()); } } else { - String::Value value(isolate, str); size_t written_len = buflen; auto result = simdutf::base64_to_binary_safe( - reinterpret_cast(*value), - value.length(), + reinterpret_cast(input_view.data16()), + input_view.length(), buf, written_len, simdutf::base64_url); @@ -319,7 +318,8 @@ size_t StringBytes::Write(Isolate* isolate, // The input does not follow the WHATWG forgiving-base64 specification // (adapted for base64url with + and / replaced by - and _). // https://infra.spec.whatwg.org/#forgiving-base64-decode - nbytes = nbytes::Base64Decode(buf, buflen, *value, value.length()); + nbytes = nbytes::Base64Decode( + buf, buflen, input_view.data16(), input_view.length()); } } break; @@ -344,11 +344,10 @@ size_t StringBytes::Write(Isolate* isolate, input_view.length()); } } else { - String::Value value(isolate, str); size_t written_len = buflen; auto result = simdutf::base64_to_binary_safe( - reinterpret_cast(*value), - value.length(), + reinterpret_cast(input_view.data16()), + input_view.length(), buf, written_len); if (result.error == simdutf::error_code::SUCCESS) { @@ -356,7 +355,8 @@ size_t StringBytes::Write(Isolate* isolate, } else { // The input does not follow the WHATWG base64 specification // https://infra.spec.whatwg.org/#forgiving-base64-decode - nbytes = nbytes::Base64Decode(buf, buflen, *value, value.length()); + nbytes = nbytes::Base64Decode( + buf, buflen, input_view.data16(), input_view.length()); } } break; @@ -369,8 +369,8 @@ size_t StringBytes::Write(Isolate* isolate, reinterpret_cast(input_view.data8()), input_view.length()); } else { - String::Value value(isolate, str); - nbytes = nbytes::HexDecode(buf, buflen, *value, value.length()); + String::ValueView value(isolate, str); + nbytes = nbytes::HexDecode(buf, buflen, value.data8(), value.length()); } break; From 50552fdc9241659e3d0c5abc3a90ecbd6f63d961 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Mon, 28 Oct 2024 21:36:48 -0400 Subject: [PATCH 20/93] deps: update acorn to 8.13.0 PR-URL: https://github.com/nodejs/node/pull/55558 Reviewed-By: Luigi Pinca Reviewed-By: Marco Ippolito Reviewed-By: Rafael Gonzaga --- deps/acorn/acorn/CHANGELOG.md | 6 ++++++ deps/acorn/acorn/dist/acorn.js | 10 +++++----- deps/acorn/acorn/dist/acorn.mjs | 10 +++++----- deps/acorn/acorn/package.json | 2 +- src/acorn_version.h | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/deps/acorn/acorn/CHANGELOG.md b/deps/acorn/acorn/CHANGELOG.md index c404a235c5eef4..1e090161fffa80 100644 --- a/deps/acorn/acorn/CHANGELOG.md +++ b/deps/acorn/acorn/CHANGELOG.md @@ -1,3 +1,9 @@ +## 8.13.0 (2024-10-16) + +### New features + +Upgrade to Unicode 16.0. + ## 8.12.1 (2024-07-03) ### Bug fixes diff --git a/deps/acorn/acorn/dist/acorn.js b/deps/acorn/acorn/dist/acorn.js index 68bf2a714e294d..7cd26fa36b5caa 100644 --- a/deps/acorn/acorn/dist/acorn.js +++ b/deps/acorn/acorn/dist/acorn.js @@ -5,16 +5,16 @@ })(this, (function (exports) { 'use strict'; // This file was generated. Do not modify manually! - var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 80, 3, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 343, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 726, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; // This file was generated. Do not modify manually! - var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 4026, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 757, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191]; + var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 2, 60, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 42, 9, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 496, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191]; // This file was generated. Do not modify manually! - var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65"; + var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65"; // This file was generated. Do not modify manually! - var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; // These are a run-length and offset encoded representation of the // >0xffff code points that are a valid part of identifiers. The @@ -5990,7 +5990,7 @@ // [walk]: util/walk.js - var version = "8.12.1"; + var version = "8.13.0"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/dist/acorn.mjs b/deps/acorn/acorn/dist/acorn.mjs index 3fd7cb30c67b0e..21b860f275a064 100644 --- a/deps/acorn/acorn/dist/acorn.mjs +++ b/deps/acorn/acorn/dist/acorn.mjs @@ -1,14 +1,14 @@ // This file was generated. Do not modify manually! -var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 81, 2, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 9, 5351, 0, 7, 14, 13835, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 983, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; +var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 80, 3, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 343, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 726, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; // This file was generated. Do not modify manually! -var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 4026, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 757, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191]; +var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 2, 60, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 42, 9, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 496, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191]; // This file was generated. Do not modify manually! -var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65"; +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65"; // This file was generated. Do not modify manually! -var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; // These are a run-length and offset encoded representation of the // >0xffff code points that are a valid part of identifiers. The @@ -5984,7 +5984,7 @@ pp.readWord = function() { // [walk]: util/walk.js -var version = "8.12.1"; +var version = "8.13.0"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/package.json b/deps/acorn/acorn/package.json index 355692a301ea5d..3396013bbbf060 100644 --- a/deps/acorn/acorn/package.json +++ b/deps/acorn/acorn/package.json @@ -16,7 +16,7 @@ ], "./package.json": "./package.json" }, - "version": "8.12.1", + "version": "8.13.0", "engines": { "node": ">=0.4.0" }, diff --git a/src/acorn_version.h b/src/acorn_version.h index b625cceb704283..fdafbf96987762 100644 --- a/src/acorn_version.h +++ b/src/acorn_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-acorn.sh #ifndef SRC_ACORN_VERSION_H_ #define SRC_ACORN_VERSION_H_ -#define ACORN_VERSION "8.12.1" +#define ACORN_VERSION "8.13.0" #endif // SRC_ACORN_VERSION_H_ From 3a1d49053587e328874c2e705132b53a40026752 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Mon, 28 Oct 2024 22:11:33 -0400 Subject: [PATCH 21/93] deps: update nghttp2 to 1.64.0 PR-URL: https://github.com/nodejs/node/pull/55559 Reviewed-By: Luigi Pinca Reviewed-By: Marco Ippolito --- deps/nghttp2/lib/Makefile.in | 1 + deps/nghttp2/lib/includes/Makefile.in | 1 + deps/nghttp2/lib/includes/nghttp2/nghttp2.h | 220 +- .../nghttp2/lib/includes/nghttp2/nghttp2ver.h | 4 +- deps/nghttp2/lib/nghttp2_callbacks.c | 100 +- deps/nghttp2/lib/nghttp2_debug.c | 6 +- deps/nghttp2/lib/nghttp2_frame.c | 12 +- deps/nghttp2/lib/nghttp2_hd.c | 189 +- deps/nghttp2/lib/nghttp2_hd_huffman.c | 2 +- deps/nghttp2/lib/nghttp2_hd_huffman_data.c | 9896 ++++++++--------- deps/nghttp2/lib/nghttp2_helper.c | 770 +- deps/nghttp2/lib/nghttp2_helper.h | 36 +- deps/nghttp2/lib/nghttp2_http.c | 90 +- deps/nghttp2/lib/nghttp2_map.c | 218 +- deps/nghttp2/lib/nghttp2_map.h | 60 +- deps/nghttp2/lib/nghttp2_option.c | 6 +- deps/nghttp2/lib/nghttp2_queue.c | 2 +- deps/nghttp2/lib/nghttp2_session.c | 552 +- deps/nghttp2/lib/nghttp2_stream.c | 14 +- deps/nghttp2/lib/nghttp2_stream.h | 15 +- deps/nghttp2/lib/nghttp2_submit.c | 43 +- deps/nghttp2/lib/nghttp2_time.c | 2 +- deps/nghttp2/lib/sfparse.c | 29 +- 23 files changed, 6139 insertions(+), 6129 deletions(-) diff --git a/deps/nghttp2/lib/Makefile.in b/deps/nghttp2/lib/Makefile.in index c4ab62421eaab0..14686ef14b1a4f 100644 --- a/deps/nghttp2/lib/Makefile.in +++ b/deps/nghttp2/lib/Makefile.in @@ -327,6 +327,7 @@ EXTRABPFCFLAGS = @EXTRABPFCFLAGS@ EXTRACFLAG = @EXTRACFLAG@ EXTRA_DEFS = @EXTRA_DEFS@ FGREP = @FGREP@ +FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX20 = @HAVE_CXX20@ INSTALL = @INSTALL@ diff --git a/deps/nghttp2/lib/includes/Makefile.in b/deps/nghttp2/lib/includes/Makefile.in index e2150c10c6dd1d..778dcb874c926b 100644 --- a/deps/nghttp2/lib/includes/Makefile.in +++ b/deps/nghttp2/lib/includes/Makefile.in @@ -232,6 +232,7 @@ EXTRABPFCFLAGS = @EXTRABPFCFLAGS@ EXTRACFLAG = @EXTRACFLAG@ EXTRA_DEFS = @EXTRA_DEFS@ FGREP = @FGREP@ +FILECMD = @FILECMD@ GREP = @GREP@ HAVE_CXX20 = @HAVE_CXX20@ INSTALL = @INSTALL@ diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h index 5afd02479c34eb..2ef49b8d68f4ed 100644 --- a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h +++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h @@ -57,8 +57,8 @@ extern "C" { #ifdef NGHTTP2_STATICLIB # define NGHTTP2_EXTERN -#elif defined(WIN32) || (__has_declspec_attribute(dllexport) && \ - __has_declspec_attribute(dllimport)) +#elif defined(WIN32) || \ + (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport)) # ifdef BUILDING_NGHTTP2 # define NGHTTP2_EXTERN __declspec(dllexport) # else /* !BUILDING_NGHTTP2 */ @@ -977,8 +977,8 @@ typedef enum { * signal the entire session failure. */ typedef ssize_t (*nghttp2_data_source_read_callback)( - nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, - uint32_t *data_flags, nghttp2_data_source *source, void *user_data); + nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, + uint32_t *data_flags, nghttp2_data_source *source, void *user_data); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -1046,8 +1046,8 @@ typedef ssize_t (*nghttp2_data_source_read_callback)( * signal the entire session failure. */ typedef nghttp2_ssize (*nghttp2_data_source_read_callback2)( - nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, - uint32_t *data_flags, nghttp2_data_source *source, void *user_data); + nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, + uint32_t *data_flags, nghttp2_data_source *source, void *user_data); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -1708,8 +1708,8 @@ typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session, * `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`. */ typedef int (*nghttp2_on_invalid_frame_recv_callback)( - nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, - void *user_data); + nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, + void *user_data); /** * @functypedef @@ -2069,9 +2069,9 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session, * not reset. */ typedef int (*nghttp2_on_invalid_header_callback)( - nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, - size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, - void *user_data); + nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, + size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, + void *user_data); /** * @functypedef @@ -2102,8 +2102,8 @@ typedef int (*nghttp2_on_invalid_header_callback)( * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. */ typedef int (*nghttp2_on_invalid_header_callback2)( - nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, - nghttp2_rcbuf *value, uint8_t flags, void *user_data); + nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, + nghttp2_rcbuf *value, uint8_t flags, void *user_data); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -2155,8 +2155,8 @@ typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session, * `nghttp2_session_callbacks_set_select_padding_callback2()`. */ typedef nghttp2_ssize (*nghttp2_select_padding_callback2)( - nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen, - void *user_data); + nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen, + void *user_data); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -2190,9 +2190,9 @@ typedef nghttp2_ssize (*nghttp2_select_padding_callback2)( * `nghttp2_session_callbacks_set_data_source_read_length_callback()`. */ typedef ssize_t (*nghttp2_data_source_read_length_callback)( - nghttp2_session *session, uint8_t frame_type, int32_t stream_id, - int32_t session_remote_window_size, int32_t stream_remote_window_size, - uint32_t remote_max_frame_size, void *user_data); + nghttp2_session *session, uint8_t frame_type, int32_t stream_id, + int32_t session_remote_window_size, int32_t stream_remote_window_size, + uint32_t remote_max_frame_size, void *user_data); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -2222,9 +2222,9 @@ typedef ssize_t (*nghttp2_data_source_read_length_callback)( * `nghttp2_session_callbacks_set_data_source_read_length_callback2()`. */ typedef nghttp2_ssize (*nghttp2_data_source_read_length_callback2)( - nghttp2_session *session, uint8_t frame_type, int32_t stream_id, - int32_t session_remote_window_size, int32_t stream_remote_window_size, - uint32_t remote_max_frame_size, void *user_data); + nghttp2_session *session, uint8_t frame_type, int32_t stream_id, + int32_t session_remote_window_size, int32_t stream_remote_window_size, + uint32_t remote_max_frame_size, void *user_data); /** * @functypedef @@ -2274,8 +2274,8 @@ typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session, * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. */ typedef int (*nghttp2_on_extension_chunk_recv_callback)( - nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, - size_t len, void *user_data); + nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, + size_t len, void *user_data); /** * @functypedef @@ -2386,8 +2386,8 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session, * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. */ typedef nghttp2_ssize (*nghttp2_pack_extension_callback2)( - nghttp2_session *session, uint8_t *buf, size_t len, - const nghttp2_frame *frame, void *user_data); + nghttp2_session *session, uint8_t *buf, size_t len, + const nghttp2_frame *frame, void *user_data); /** * @functypedef @@ -2499,7 +2499,7 @@ nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks); * transmit. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback( - nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback); + nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -2512,7 +2512,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback( * transmit. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback2( - nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback); + nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -2529,7 +2529,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback2( * received data. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback); + nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -2542,7 +2542,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback( * received data. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback2( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback); + nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback); /** * @function @@ -2551,8 +2551,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback2( * `nghttp2_session_mem_recv2()` when a frame is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_recv_callback on_frame_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_recv_callback on_frame_recv_callback); /** * @function @@ -2563,8 +2563,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_recv_callback( */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback); /** * @function @@ -2573,8 +2573,8 @@ nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( * is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback); /** * @function @@ -2582,8 +2582,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_data_chunk_recv_callback( * Sets callback function invoked before a non-DATA frame is sent. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_before_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_before_frame_send_callback before_frame_send_callback); + nghttp2_session_callbacks *cbs, + nghttp2_before_frame_send_callback before_frame_send_callback); /** * @function @@ -2591,8 +2591,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_before_frame_send_callback( * Sets callback function invoked after a frame is sent. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_send_callback on_frame_send_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_send_callback on_frame_send_callback); /** * @function @@ -2601,8 +2601,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_send_callback( * because of an error. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_not_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_not_send_callback on_frame_not_send_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_not_send_callback on_frame_not_send_callback); /** * @function @@ -2610,8 +2610,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_frame_not_send_callback( * Sets callback function invoked when the stream is closed. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_stream_close_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_stream_close_callback on_stream_close_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_stream_close_callback on_stream_close_callback); /** * @function @@ -2620,8 +2620,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_stream_close_callback( * in HEADERS or PUSH_PROMISE is started. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_headers_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_headers_callback on_begin_headers_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_headers_callback on_begin_headers_callback); /** * @function @@ -2633,8 +2633,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_headers_callback( * set callbacks, the latter has the precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback on_header_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback on_header_callback); /** * @function @@ -2643,8 +2643,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback( * received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback2 on_header_callback2); + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback2 on_header_callback2); /** * @function @@ -2656,8 +2656,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2( * used to set callbacks, the latter takes the precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback on_invalid_header_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback on_invalid_header_callback); /** * @function @@ -2666,8 +2666,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback( * pair is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback2 on_invalid_header_callback2); + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback2 on_invalid_header_callback2); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -2684,8 +2684,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2( * given frame. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback select_padding_callback); + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback select_padding_callback); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -2697,8 +2697,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback( * given frame. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback2 select_padding_callback); + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback2 select_padding_callback); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -2715,8 +2715,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback2( */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_data_source_read_length_callback( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback data_source_read_length_callback); + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback data_source_read_length_callback); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -2728,8 +2728,8 @@ nghttp2_session_callbacks_set_data_source_read_length_callback( */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_data_source_read_length_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback2 data_source_read_length_callback); + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback2 data_source_read_length_callback); /** * @function @@ -2737,8 +2737,8 @@ nghttp2_session_callbacks_set_data_source_read_length_callback2( * Sets callback function invoked when a frame header is received. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_frame_callback on_begin_frame_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_frame_callback on_begin_frame_callback); /** * @function @@ -2748,8 +2748,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback( * :type:`nghttp2_data_source_read_callback2` to avoid data copy. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback( - nghttp2_session_callbacks *cbs, - nghttp2_send_data_callback send_data_callback); + nghttp2_session_callbacks *cbs, + nghttp2_send_data_callback send_data_callback); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -2765,8 +2765,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback( * application to pack extension frame payload in wire format. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback pack_extension_callback); + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback pack_extension_callback); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -2777,8 +2777,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback( * application to pack extension frame payload in wire format. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback2 pack_extension_callback); + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback2 pack_extension_callback); /** * @function @@ -2787,8 +2787,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback2( * application to unpack extension frame payload from wire format. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_unpack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_unpack_extension_callback unpack_extension_callback); + nghttp2_session_callbacks *cbs, + nghttp2_unpack_extension_callback unpack_extension_callback); /** * @function @@ -2798,8 +2798,8 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_unpack_extension_callback( */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback); + nghttp2_session_callbacks *cbs, + nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback); /** * @function @@ -2818,7 +2818,7 @@ nghttp2_session_callbacks_set_on_extension_chunk_recv_callback( * precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback( - nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback); + nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback); /** * @function @@ -2831,7 +2831,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback( * precedence. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2( - nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2); + nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2); /** * @functypedef @@ -3195,7 +3195,7 @@ nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option, */ NGHTTP2_EXTERN void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - nghttp2_option *option, int val); + nghttp2_option *option, int val); /** * @function @@ -3351,8 +3351,8 @@ nghttp2_session_server_new2(nghttp2_session **session_ptr, * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_client_new3( - nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, nghttp2_mem *mem); + nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, + void *user_data, const nghttp2_option *option, nghttp2_mem *mem); /** * @function @@ -3376,8 +3376,8 @@ NGHTTP2_EXTERN int nghttp2_session_client_new3( * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_server_new3( - nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, - void *user_data, const nghttp2_option *option, nghttp2_mem *mem); + nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks, + void *user_data, const nghttp2_option *option, nghttp2_mem *mem); /** * @function @@ -3807,7 +3807,7 @@ nghttp2_session_get_outbound_queue_size(nghttp2_session *session); * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -3827,7 +3827,7 @@ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length( * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -3842,7 +3842,7 @@ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size( * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_local_window_size( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -3910,7 +3910,7 @@ nghttp2_session_get_local_window_size(nghttp2_session *session); * This function returns -1 if it fails. */ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_remote_window_size( - nghttp2_session *session, int32_t stream_id); + nghttp2_session *session, int32_t stream_id); /** * @function @@ -4064,7 +4064,7 @@ NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session); * :enum:`nghttp2_settings_id`. */ NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings( - nghttp2_session *session, nghttp2_settings_id id); + nghttp2_session *session, nghttp2_settings_id id); /** * @function @@ -4074,7 +4074,7 @@ NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings( * in :enum:`nghttp2_settings_id`. */ NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings( - nghttp2_session *session, nghttp2_settings_id id); + nghttp2_session *session, nghttp2_settings_id id); /** * @function @@ -4399,7 +4399,7 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session, * The provided |buflen| size is too small to hold the output. */ NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload( - uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); + uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -4425,7 +4425,7 @@ NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload( * The provided |buflen| size is too small to hold the output. */ NGHTTP2_EXTERN nghttp2_ssize nghttp2_pack_settings_payload2( - uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); + uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv); /** * @function @@ -4583,9 +4583,9 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); * */ NGHTTP2_EXTERN int32_t nghttp2_submit_request( - nghttp2_session *session, const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd, - void *stream_user_data); + nghttp2_session *session, const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd, + void *stream_user_data); #endif /* NGHTTP2_NO_SSIZE_T */ @@ -4674,9 +4674,9 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request( * */ NGHTTP2_EXTERN int32_t nghttp2_submit_request2( - nghttp2_session *session, const nghttp2_priority_spec *pri_spec, - const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider2 *data_prd, - void *stream_user_data); + nghttp2_session *session, const nghttp2_priority_spec *pri_spec, + const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider2 *data_prd, + void *stream_user_data); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -4975,9 +4975,9 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, * */ NGHTTP2_EXTERN int32_t nghttp2_submit_headers( - nghttp2_session *session, uint8_t flags, int32_t stream_id, - const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen, - void *stream_user_data); + nghttp2_session *session, uint8_t flags, int32_t stream_id, + const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen, + void *stream_user_data); #ifndef NGHTTP2_NO_SSIZE_T /** @@ -5308,8 +5308,8 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session, * */ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise( - nghttp2_session *session, uint8_t flags, int32_t stream_id, - const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data); + nghttp2_session *session, uint8_t flags, int32_t stream_id, + const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data); /** * @function @@ -5802,8 +5802,8 @@ NGHTTP2_EXTERN int nghttp2_submit_priority_update(nghttp2_session *session, * found. */ NGHTTP2_EXTERN int nghttp2_session_change_extpri_stream_priority( - nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri, - int ignore_client_signal); + nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri, + int ignore_client_signal); /** * @function @@ -5831,7 +5831,7 @@ NGHTTP2_EXTERN int nghttp2_session_change_extpri_stream_priority( * found. */ NGHTTP2_EXTERN int nghttp2_session_get_extpri_stream_priority( - nghttp2_session *session, nghttp2_extpri *extpri, int32_t stream_id); + nghttp2_session *session, nghttp2_extpri *extpri, int32_t stream_id); /** * @function @@ -6073,6 +6073,12 @@ NGHTTP2_EXTERN int nghttp2_check_path(const uint8_t *value, size_t len); * :authority or host header field is valid according to * https://tools.ietf.org/html/rfc3986#section-3.2 * + * Note that :authority and host field values are not authority. They + * do not include userinfo in RFC 3986, see + * https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2, that + * is, it does not include '@'. This function treats '@' as a valid + * character. + * * |value| is valid if it merely consists of the allowed characters. * In particular, it does not check whether |value| follows the syntax * of authority. @@ -6304,8 +6310,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, * The provided |buflen| size is too small to hold the output. */ NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_deflate_hd_vec2( - nghttp2_hd_deflater *deflater, const nghttp2_vec *vec, size_t veclen, - const nghttp2_nv *nva, size_t nvlen); + nghttp2_hd_deflater *deflater, const nghttp2_vec *vec, size_t veclen, + const nghttp2_nv *nva, size_t nvlen); /** * @function @@ -6728,8 +6734,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater, * */ NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_inflate_hd3( - nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, int *inflate_flags, - const uint8_t *in, size_t inlen, int in_final); + nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, int *inflate_flags, + const uint8_t *in, size_t inlen, int in_final); /** * @function @@ -7002,7 +7008,7 @@ typedef void (*nghttp2_debug_vprintf_callback)(const char *format, * this is important. */ NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback); + nghttp2_debug_vprintf_callback debug_vprintf_callback); #ifdef __cplusplus } diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h index 40570cfa1d1392..827c99896846e3 100644 --- a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h +++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h @@ -29,7 +29,7 @@ * @macro * Version number of the nghttp2 library release */ -#define NGHTTP2_VERSION "1.63.0" +#define NGHTTP2_VERSION "1.64.0" /** * @macro @@ -37,6 +37,6 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define NGHTTP2_VERSION_NUM 0x013f00 +#define NGHTTP2_VERSION_NUM 0x014000 #endif /* NGHTTP2VER_H */ diff --git a/deps/nghttp2/lib/nghttp2_callbacks.c b/deps/nghttp2/lib/nghttp2_callbacks.c index 1776f7d276b79f..32fedd52d85a3f 100644 --- a/deps/nghttp2/lib/nghttp2_callbacks.c +++ b/deps/nghttp2/lib/nghttp2_callbacks.c @@ -41,163 +41,163 @@ void nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks) { } void nghttp2_session_callbacks_set_send_callback( - nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) { + nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) { cbs->send_callback = send_callback; } void nghttp2_session_callbacks_set_send_callback2( - nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback) { + nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback) { cbs->send_callback2 = send_callback; } void nghttp2_session_callbacks_set_recv_callback( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) { + nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) { cbs->recv_callback = recv_callback; } void nghttp2_session_callbacks_set_recv_callback2( - nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback) { + nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback) { cbs->recv_callback2 = recv_callback; } void nghttp2_session_callbacks_set_on_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_recv_callback on_frame_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_recv_callback on_frame_recv_callback) { cbs->on_frame_recv_callback = on_frame_recv_callback; } void nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback) { cbs->on_invalid_frame_recv_callback = on_invalid_frame_recv_callback; } void nghttp2_session_callbacks_set_on_data_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback) { cbs->on_data_chunk_recv_callback = on_data_chunk_recv_callback; } void nghttp2_session_callbacks_set_before_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_before_frame_send_callback before_frame_send_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_before_frame_send_callback before_frame_send_callback) { cbs->before_frame_send_callback = before_frame_send_callback; } void nghttp2_session_callbacks_set_on_frame_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_send_callback on_frame_send_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_send_callback on_frame_send_callback) { cbs->on_frame_send_callback = on_frame_send_callback; } void nghttp2_session_callbacks_set_on_frame_not_send_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_frame_not_send_callback on_frame_not_send_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_frame_not_send_callback on_frame_not_send_callback) { cbs->on_frame_not_send_callback = on_frame_not_send_callback; } void nghttp2_session_callbacks_set_on_stream_close_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_stream_close_callback on_stream_close_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_stream_close_callback on_stream_close_callback) { cbs->on_stream_close_callback = on_stream_close_callback; } void nghttp2_session_callbacks_set_on_begin_headers_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_headers_callback on_begin_headers_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_headers_callback on_begin_headers_callback) { cbs->on_begin_headers_callback = on_begin_headers_callback; } void nghttp2_session_callbacks_set_on_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback on_header_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback on_header_callback) { cbs->on_header_callback = on_header_callback; } void nghttp2_session_callbacks_set_on_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_header_callback2 on_header_callback2) { + nghttp2_session_callbacks *cbs, + nghttp2_on_header_callback2 on_header_callback2) { cbs->on_header_callback2 = on_header_callback2; } void nghttp2_session_callbacks_set_on_invalid_header_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback on_invalid_header_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback on_invalid_header_callback) { cbs->on_invalid_header_callback = on_invalid_header_callback; } void nghttp2_session_callbacks_set_on_invalid_header_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) { + nghttp2_session_callbacks *cbs, + nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) { cbs->on_invalid_header_callback2 = on_invalid_header_callback2; } void nghttp2_session_callbacks_set_select_padding_callback( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback select_padding_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback select_padding_callback) { cbs->select_padding_callback = select_padding_callback; } void nghttp2_session_callbacks_set_select_padding_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_select_padding_callback2 select_padding_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_select_padding_callback2 select_padding_callback) { cbs->select_padding_callback2 = select_padding_callback; } void nghttp2_session_callbacks_set_data_source_read_length_callback( - nghttp2_session_callbacks *cbs, - nghttp2_data_source_read_length_callback data_source_read_length_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback data_source_read_length_callback) { cbs->read_length_callback = data_source_read_length_callback; } void nghttp2_session_callbacks_set_data_source_read_length_callback2( - nghttp2_session_callbacks *cbs, nghttp2_data_source_read_length_callback2 - data_source_read_length_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_data_source_read_length_callback2 data_source_read_length_callback) { cbs->read_length_callback2 = data_source_read_length_callback; } void nghttp2_session_callbacks_set_on_begin_frame_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_begin_frame_callback on_begin_frame_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_begin_frame_callback on_begin_frame_callback) { cbs->on_begin_frame_callback = on_begin_frame_callback; } void nghttp2_session_callbacks_set_send_data_callback( - nghttp2_session_callbacks *cbs, - nghttp2_send_data_callback send_data_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_send_data_callback send_data_callback) { cbs->send_data_callback = send_data_callback; } void nghttp2_session_callbacks_set_pack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback pack_extension_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback pack_extension_callback) { cbs->pack_extension_callback = pack_extension_callback; } void nghttp2_session_callbacks_set_pack_extension_callback2( - nghttp2_session_callbacks *cbs, - nghttp2_pack_extension_callback2 pack_extension_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_pack_extension_callback2 pack_extension_callback) { cbs->pack_extension_callback2 = pack_extension_callback; } void nghttp2_session_callbacks_set_unpack_extension_callback( - nghttp2_session_callbacks *cbs, - nghttp2_unpack_extension_callback unpack_extension_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_unpack_extension_callback unpack_extension_callback) { cbs->unpack_extension_callback = unpack_extension_callback; } void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback( - nghttp2_session_callbacks *cbs, - nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) { + nghttp2_session_callbacks *cbs, + nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) { cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback; } void nghttp2_session_callbacks_set_error_callback( - nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) { + nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) { cbs->error_callback = error_callback; } void nghttp2_session_callbacks_set_error_callback2( - nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) { + nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) { cbs->error_callback2 = error_callback2; } diff --git a/deps/nghttp2/lib/nghttp2_debug.c b/deps/nghttp2/lib/nghttp2_debug.c index cb2779700bd38b..09dd2b28587af5 100644 --- a/deps/nghttp2/lib/nghttp2_debug.c +++ b/deps/nghttp2/lib/nghttp2_debug.c @@ -34,7 +34,7 @@ static void nghttp2_default_debug_vfprintf_callback(const char *fmt, } static nghttp2_debug_vprintf_callback static_debug_vprintf_callback = - nghttp2_default_debug_vfprintf_callback; + nghttp2_default_debug_vfprintf_callback; void nghttp2_debug_vprintf(const char *format, ...) { if (static_debug_vprintf_callback) { @@ -46,14 +46,14 @@ void nghttp2_debug_vprintf(const char *format, ...) { } void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback) { + nghttp2_debug_vprintf_callback debug_vprintf_callback) { static_debug_vprintf_callback = debug_vprintf_callback; } #else /* !DEBUGBUILD */ void nghttp2_set_debug_vprintf_callback( - nghttp2_debug_vprintf_callback debug_vprintf_callback) { + nghttp2_debug_vprintf_callback debug_vprintf_callback) { (void)debug_vprintf_callback; } diff --git a/deps/nghttp2/lib/nghttp2_frame.c b/deps/nghttp2/lib/nghttp2_frame.c index 77cb463df5441f..edc2aaaae9ed75 100644 --- a/deps/nghttp2/lib/nghttp2_frame.c +++ b/deps/nghttp2/lib/nghttp2_frame.c @@ -492,7 +492,7 @@ int nghttp2_frame_pack_settings(nghttp2_bufs *bufs, nghttp2_settings *frame) { nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); buf->last += - nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv); + nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv); return 0; } @@ -537,7 +537,7 @@ int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr, } *iv_ptr = - nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry)); + nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry)); if (*iv_ptr == NULL) { return NGHTTP2_ERR_NOMEM; @@ -589,7 +589,7 @@ int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs, void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame, const uint8_t *payload) { frame->promised_stream_id = - nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; + nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; frame->nva = NULL; frame->nvlen = 0; } @@ -608,7 +608,7 @@ void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) { nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd); buf->last = - nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data)); + nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data)); } void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame, @@ -709,7 +709,7 @@ void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs, void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame, const uint8_t *payload) { frame->window_size_increment = - nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK; + nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK; } void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) { @@ -926,7 +926,7 @@ void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame, priority_update = frame->payload; priority_update->stream_id = - nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; + nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK; if (payloadlen > 4) { priority_update->field_value = payload + 4; diff --git a/deps/nghttp2/lib/nghttp2_hd.c b/deps/nghttp2/lib/nghttp2_hd.c index a4137ef14ab719..55fc2cc6bfea3d 100644 --- a/deps/nghttp2/lib/nghttp2_hd.c +++ b/deps/nghttp2/lib/nghttp2_hd.c @@ -35,11 +35,11 @@ /* Make scalar initialization form of nghttp2_hd_entry */ #define MAKE_STATIC_ENT(N, V, T, H) \ { \ - {NULL, NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \ - {NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \ - {(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \ - T, \ - H, \ + {NULL, NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \ + {NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \ + {(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \ + T, \ + H, \ } /* Generated by mkstatictbl.py */ @@ -47,67 +47,67 @@ first enum value if same header names are repeated (e.g., :status). */ static const nghttp2_hd_static_entry static_table[] = { - MAKE_STATIC_ENT(":authority", "", 0, 3153725150u), - MAKE_STATIC_ENT(":method", "GET", 1, 695666056u), - MAKE_STATIC_ENT(":method", "POST", 1, 695666056u), - MAKE_STATIC_ENT(":path", "/", 3, 3292848686u), - MAKE_STATIC_ENT(":path", "/index.html", 3, 3292848686u), - MAKE_STATIC_ENT(":scheme", "http", 5, 2510477674u), - MAKE_STATIC_ENT(":scheme", "https", 5, 2510477674u), - MAKE_STATIC_ENT(":status", "200", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "204", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "206", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "304", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "400", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "404", 7, 4000288983u), - MAKE_STATIC_ENT(":status", "500", 7, 4000288983u), - MAKE_STATIC_ENT("accept-charset", "", 14, 3664010344u), - MAKE_STATIC_ENT("accept-encoding", "gzip, deflate", 15, 3379649177u), - MAKE_STATIC_ENT("accept-language", "", 16, 1979086614u), - MAKE_STATIC_ENT("accept-ranges", "", 17, 1713753958u), - MAKE_STATIC_ENT("accept", "", 18, 136609321u), - MAKE_STATIC_ENT("access-control-allow-origin", "", 19, 2710797292u), - MAKE_STATIC_ENT("age", "", 20, 742476188u), - MAKE_STATIC_ENT("allow", "", 21, 2930878514u), - MAKE_STATIC_ENT("authorization", "", 22, 2436257726u), - MAKE_STATIC_ENT("cache-control", "", 23, 1355326669u), - MAKE_STATIC_ENT("content-disposition", "", 24, 3889184348u), - MAKE_STATIC_ENT("content-encoding", "", 25, 65203592u), - MAKE_STATIC_ENT("content-language", "", 26, 24973587u), - MAKE_STATIC_ENT("content-length", "", 27, 1308181789u), - MAKE_STATIC_ENT("content-location", "", 28, 2302364718u), - MAKE_STATIC_ENT("content-range", "", 29, 3555523146u), - MAKE_STATIC_ENT("content-type", "", 30, 4244048277u), - MAKE_STATIC_ENT("cookie", "", 31, 2007449791u), - MAKE_STATIC_ENT("date", "", 32, 3564297305u), - MAKE_STATIC_ENT("etag", "", 33, 113792960u), - MAKE_STATIC_ENT("expect", "", 34, 2530896728u), - MAKE_STATIC_ENT("expires", "", 35, 1049544579u), - MAKE_STATIC_ENT("from", "", 36, 2513272949u), - MAKE_STATIC_ENT("host", "", 37, 2952701295u), - MAKE_STATIC_ENT("if-match", "", 38, 3597694698u), - MAKE_STATIC_ENT("if-modified-since", "", 39, 2213050793u), - MAKE_STATIC_ENT("if-none-match", "", 40, 2536202615u), - MAKE_STATIC_ENT("if-range", "", 41, 2340978238u), - MAKE_STATIC_ENT("if-unmodified-since", "", 42, 3794814858u), - MAKE_STATIC_ENT("last-modified", "", 43, 3226950251u), - MAKE_STATIC_ENT("link", "", 44, 232457833u), - MAKE_STATIC_ENT("location", "", 45, 200649126u), - MAKE_STATIC_ENT("max-forwards", "", 46, 1826162134u), - MAKE_STATIC_ENT("proxy-authenticate", "", 47, 2709445359u), - MAKE_STATIC_ENT("proxy-authorization", "", 48, 2686392507u), - MAKE_STATIC_ENT("range", "", 49, 4208725202u), - MAKE_STATIC_ENT("referer", "", 50, 3969579366u), - MAKE_STATIC_ENT("refresh", "", 51, 3572655668u), - MAKE_STATIC_ENT("retry-after", "", 52, 3336180598u), - MAKE_STATIC_ENT("server", "", 53, 1085029842u), - MAKE_STATIC_ENT("set-cookie", "", 54, 1848371000u), - MAKE_STATIC_ENT("strict-transport-security", "", 55, 4138147361u), - MAKE_STATIC_ENT("transfer-encoding", "", 56, 3719590988u), - MAKE_STATIC_ENT("user-agent", "", 57, 606444526u), - MAKE_STATIC_ENT("vary", "", 58, 1085005381u), - MAKE_STATIC_ENT("via", "", 59, 1762798611u), - MAKE_STATIC_ENT("www-authenticate", "", 60, 779865858u), + MAKE_STATIC_ENT(":authority", "", 0, 3153725150u), + MAKE_STATIC_ENT(":method", "GET", 1, 695666056u), + MAKE_STATIC_ENT(":method", "POST", 1, 695666056u), + MAKE_STATIC_ENT(":path", "/", 3, 3292848686u), + MAKE_STATIC_ENT(":path", "/index.html", 3, 3292848686u), + MAKE_STATIC_ENT(":scheme", "http", 5, 2510477674u), + MAKE_STATIC_ENT(":scheme", "https", 5, 2510477674u), + MAKE_STATIC_ENT(":status", "200", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "204", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "206", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "304", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "400", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "404", 7, 4000288983u), + MAKE_STATIC_ENT(":status", "500", 7, 4000288983u), + MAKE_STATIC_ENT("accept-charset", "", 14, 3664010344u), + MAKE_STATIC_ENT("accept-encoding", "gzip, deflate", 15, 3379649177u), + MAKE_STATIC_ENT("accept-language", "", 16, 1979086614u), + MAKE_STATIC_ENT("accept-ranges", "", 17, 1713753958u), + MAKE_STATIC_ENT("accept", "", 18, 136609321u), + MAKE_STATIC_ENT("access-control-allow-origin", "", 19, 2710797292u), + MAKE_STATIC_ENT("age", "", 20, 742476188u), + MAKE_STATIC_ENT("allow", "", 21, 2930878514u), + MAKE_STATIC_ENT("authorization", "", 22, 2436257726u), + MAKE_STATIC_ENT("cache-control", "", 23, 1355326669u), + MAKE_STATIC_ENT("content-disposition", "", 24, 3889184348u), + MAKE_STATIC_ENT("content-encoding", "", 25, 65203592u), + MAKE_STATIC_ENT("content-language", "", 26, 24973587u), + MAKE_STATIC_ENT("content-length", "", 27, 1308181789u), + MAKE_STATIC_ENT("content-location", "", 28, 2302364718u), + MAKE_STATIC_ENT("content-range", "", 29, 3555523146u), + MAKE_STATIC_ENT("content-type", "", 30, 4244048277u), + MAKE_STATIC_ENT("cookie", "", 31, 2007449791u), + MAKE_STATIC_ENT("date", "", 32, 3564297305u), + MAKE_STATIC_ENT("etag", "", 33, 113792960u), + MAKE_STATIC_ENT("expect", "", 34, 2530896728u), + MAKE_STATIC_ENT("expires", "", 35, 1049544579u), + MAKE_STATIC_ENT("from", "", 36, 2513272949u), + MAKE_STATIC_ENT("host", "", 37, 2952701295u), + MAKE_STATIC_ENT("if-match", "", 38, 3597694698u), + MAKE_STATIC_ENT("if-modified-since", "", 39, 2213050793u), + MAKE_STATIC_ENT("if-none-match", "", 40, 2536202615u), + MAKE_STATIC_ENT("if-range", "", 41, 2340978238u), + MAKE_STATIC_ENT("if-unmodified-since", "", 42, 3794814858u), + MAKE_STATIC_ENT("last-modified", "", 43, 3226950251u), + MAKE_STATIC_ENT("link", "", 44, 232457833u), + MAKE_STATIC_ENT("location", "", 45, 200649126u), + MAKE_STATIC_ENT("max-forwards", "", 46, 1826162134u), + MAKE_STATIC_ENT("proxy-authenticate", "", 47, 2709445359u), + MAKE_STATIC_ENT("proxy-authorization", "", 48, 2686392507u), + MAKE_STATIC_ENT("range", "", 49, 4208725202u), + MAKE_STATIC_ENT("referer", "", 50, 3969579366u), + MAKE_STATIC_ENT("refresh", "", 51, 3572655668u), + MAKE_STATIC_ENT("retry-after", "", 52, 3336180598u), + MAKE_STATIC_ENT("server", "", 53, 1085029842u), + MAKE_STATIC_ENT("set-cookie", "", 54, 1848371000u), + MAKE_STATIC_ENT("strict-transport-security", "", 55, 4138147361u), + MAKE_STATIC_ENT("transfer-encoding", "", 56, 3719590988u), + MAKE_STATIC_ENT("user-agent", "", 57, 606444526u), + MAKE_STATIC_ENT("vary", "", 58, 1085005381u), + MAKE_STATIC_ENT("via", "", 59, 1762798611u), + MAKE_STATIC_ENT("www-authenticate", "", 60, 779865858u), }; static int memeq(const void *s1, const void *s2, size_t n) { @@ -678,8 +678,8 @@ static int hd_context_init(nghttp2_hd_context *context, nghttp2_mem *mem) { context->bad = 0; context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; rv = hd_ringbuf_init( - &context->hd_table, - context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem); + &context->hd_table, + context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem); if (rv != 0) { return rv; } @@ -696,7 +696,7 @@ static void hd_context_free(nghttp2_hd_context *context) { int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem) { return nghttp2_hd_deflate_init2( - deflater, NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, mem); + deflater, NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, mem); } int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater, @@ -1078,8 +1078,8 @@ static int emit_newname_block(nghttp2_bufs *bufs, const nghttp2_nv *nv, int rv; DEBUGF( - "deflatehd: emit newname namelen=%zu, valuelen=%zu, indexing_mode=%d\n", - nv->namelen, nv->valuelen, indexing_mode); + "deflatehd: emit newname namelen=%zu, valuelen=%zu, indexing_mode=%d\n", + nv->namelen, nv->valuelen, indexing_mode); rv = nghttp2_bufs_addb(bufs, pack_first_byte(indexing_mode)); if (rv != 0) { @@ -1112,12 +1112,11 @@ static int add_hd_table_incremental(nghttp2_hd_context *context, while (context->hd_table_bufsize + room > context->hd_table_bufsize_max && context->hd_table.len > 0) { - size_t idx = context->hd_table.len - 1; nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx); context->hd_table_bufsize -= - entry_room(ent->nv.name->len, ent->nv.value->len); + entry_room(ent->nv.name->len, ent->nv.value->len); DEBUGF("hpack: remove item from header table: %s: %s\n", (char *)ent->nv.name->base, (char *)ent->nv.value->base); @@ -1233,7 +1232,7 @@ static void hd_context_shrink_table_size(nghttp2_hd_context *context, size_t idx = context->hd_table.len - 1; nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx); context->hd_table_bufsize -= - entry_room(ent->nv.name->len, ent->nv.value->len); + entry_room(ent->nv.name->len, ent->nv.value->len); hd_ringbuf_pop_back(&context->hd_table); if (map) { hd_map_remove(map, ent); @@ -1245,14 +1244,14 @@ static void hd_context_shrink_table_size(nghttp2_hd_context *context, } int nghttp2_hd_deflate_change_table_size( - nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) { + nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) { size_t next_bufsize = nghttp2_min_size( - settings_max_dynamic_table_size, deflater->deflate_hd_table_bufsize_max); + settings_max_dynamic_table_size, deflater->deflate_hd_table_bufsize_max); deflater->ctx.hd_table_bufsize_max = next_bufsize; deflater->min_hd_table_bufsize_max = - nghttp2_min_size(deflater->min_hd_table_bufsize_max, next_bufsize); + nghttp2_min_size(deflater->min_hd_table_bufsize_max, next_bufsize); deflater->notify_table_size_change = 1; @@ -1261,7 +1260,7 @@ int nghttp2_hd_deflate_change_table_size( } int nghttp2_hd_inflate_change_table_size( - nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_table_size) { + nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_table_size) { switch (inflater->state) { case NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE: case NGHTTP2_HD_STATE_INFLATE_START: @@ -1304,7 +1303,7 @@ nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t idx) { assert(INDEX_RANGE_VALID(context, idx)); if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) { return hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH) - ->nv; + ->nv; } else { const nghttp2_hd_static_entry *ent = &static_table[idx]; nghttp2_hd_nv nv = {(nghttp2_rcbuf *)&ent->name, @@ -1320,7 +1319,7 @@ static const nghttp2_nv *nghttp2_hd_table_get2(nghttp2_hd_context *context, if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) { return &hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH) - ->cnv; + ->cnv; } return &static_table[idx].cnv; @@ -1334,7 +1333,7 @@ static int hd_deflate_decide_indexing(nghttp2_hd_deflater *deflater, token == NGHTTP2_TOKEN_IF_NONE_MATCH || token == NGHTTP2_TOKEN_LOCATION || token == NGHTTP2_TOKEN_SET_COOKIE || entry_room(nv->namelen, nv->valuelen) > - deflater->ctx.hd_table_bufsize_max * 3 / 4) { + deflater->ctx.hd_table_bufsize_max * 3 / 4) { return NGHTTP2_HD_WITHOUT_INDEXING; } @@ -1367,12 +1366,11 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs, entropy secret data (e.g., id/password). Also cookie header field with less than 20 bytes value is also never indexed. This is the same criteria used in Firefox codebase. */ - indexing_mode = - token == NGHTTP2_TOKEN_AUTHORIZATION || - (token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) || - (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) - ? NGHTTP2_HD_NEVER_INDEXING - : hd_deflate_decide_indexing(deflater, nv, token); + indexing_mode = token == NGHTTP2_TOKEN_AUTHORIZATION || + (token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) || + (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) + ? NGHTTP2_HD_NEVER_INDEXING + : hd_deflate_decide_indexing(deflater, nv, token); res = search_hd_table(&deflater->ctx, nv, token, indexing_mode, &deflater->map, hash); @@ -1380,7 +1378,6 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs, idx = res.index; if (res.name_value_match) { - DEBUGF("deflatehd: name/value match index=%td\n", idx); rv = emit_indexed_block(bufs, (size_t)idx); @@ -1458,7 +1455,6 @@ int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater, deflater->min_hd_table_bufsize_max = UINT32_MAX; if (deflater->ctx.hd_table_bufsize_max > min_hd_table_bufsize_max) { - rv = emit_table_size(bufs, min_hd_table_bufsize_max); if (rv != 0) { @@ -1962,9 +1958,9 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, case NGHTTP2_HD_STATE_READ_TABLE_SIZE: rfin = 0; rv = hd_inflate_read_len( - inflater, &rfin, in, last, 5, - nghttp2_min_size(inflater->min_hd_table_bufsize_max, - inflater->settings_hd_table_bufsize_max)); + inflater, &rfin, in, last, 5, + nghttp2_min_size(inflater->min_hd_table_bufsize_max, + inflater->settings_hd_table_bufsize_max)); if (rv < 0) { goto fail; } @@ -2051,8 +2047,8 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF; - rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, - mem); + rv = + nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, mem); } else { inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME; rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left + 1, mem); @@ -2136,8 +2132,8 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater, inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF; - rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, - mem); + rv = + nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, mem); } else { inflater->state = NGHTTP2_HD_STATE_READ_VALUE; @@ -2308,7 +2304,6 @@ void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater) { int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t idx, nghttp2_nv *nv, int indexing_mode) { - return emit_indname_block(bufs, idx, nv, indexing_mode); } diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman.c b/deps/nghttp2/lib/nghttp2_hd_huffman.c index f848f3690b347d..de2620076a6e0d 100644 --- a/deps/nghttp2/lib/nghttp2_hd_huffman.c +++ b/deps/nghttp2/lib/nghttp2_hd_huffman.c @@ -94,7 +94,7 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src, if (nbits) { rv = nghttp2_bufs_addb( - bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1))); + bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1))); if (rv != 0) { return rv; } diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman_data.c b/deps/nghttp2/lib/nghttp2_hd_huffman_data.c index 2e2e13f7bee0ff..c8f4a6fa266708 100644 --- a/deps/nghttp2/lib/nghttp2_hd_huffman_data.c +++ b/deps/nghttp2/lib/nghttp2_hd_huffman_data.c @@ -27,4954 +27,4954 @@ /* Generated by mkhufftbl.py */ const nghttp2_huff_sym huff_sym_table[] = { - {13, 0xffc00000u}, {23, 0xffffb000u}, {28, 0xfffffe20u}, {28, 0xfffffe30u}, - {28, 0xfffffe40u}, {28, 0xfffffe50u}, {28, 0xfffffe60u}, {28, 0xfffffe70u}, - {28, 0xfffffe80u}, {24, 0xffffea00u}, {30, 0xfffffff0u}, {28, 0xfffffe90u}, - {28, 0xfffffea0u}, {30, 0xfffffff4u}, {28, 0xfffffeb0u}, {28, 0xfffffec0u}, - {28, 0xfffffed0u}, {28, 0xfffffee0u}, {28, 0xfffffef0u}, {28, 0xffffff00u}, - {28, 0xffffff10u}, {28, 0xffffff20u}, {30, 0xfffffff8u}, {28, 0xffffff30u}, - {28, 0xffffff40u}, {28, 0xffffff50u}, {28, 0xffffff60u}, {28, 0xffffff70u}, - {28, 0xffffff80u}, {28, 0xffffff90u}, {28, 0xffffffa0u}, {28, 0xffffffb0u}, - {6, 0x50000000u}, {10, 0xfe000000u}, {10, 0xfe400000u}, {12, 0xffa00000u}, - {13, 0xffc80000u}, {6, 0x54000000u}, {8, 0xf8000000u}, {11, 0xff400000u}, - {10, 0xfe800000u}, {10, 0xfec00000u}, {8, 0xf9000000u}, {11, 0xff600000u}, - {8, 0xfa000000u}, {6, 0x58000000u}, {6, 0x5c000000u}, {6, 0x60000000u}, - {5, 0x0u}, {5, 0x8000000u}, {5, 0x10000000u}, {6, 0x64000000u}, - {6, 0x68000000u}, {6, 0x6c000000u}, {6, 0x70000000u}, {6, 0x74000000u}, - {6, 0x78000000u}, {6, 0x7c000000u}, {7, 0xb8000000u}, {8, 0xfb000000u}, - {15, 0xfff80000u}, {6, 0x80000000u}, {12, 0xffb00000u}, {10, 0xff000000u}, - {13, 0xffd00000u}, {6, 0x84000000u}, {7, 0xba000000u}, {7, 0xbc000000u}, - {7, 0xbe000000u}, {7, 0xc0000000u}, {7, 0xc2000000u}, {7, 0xc4000000u}, - {7, 0xc6000000u}, {7, 0xc8000000u}, {7, 0xca000000u}, {7, 0xcc000000u}, - {7, 0xce000000u}, {7, 0xd0000000u}, {7, 0xd2000000u}, {7, 0xd4000000u}, - {7, 0xd6000000u}, {7, 0xd8000000u}, {7, 0xda000000u}, {7, 0xdc000000u}, - {7, 0xde000000u}, {7, 0xe0000000u}, {7, 0xe2000000u}, {7, 0xe4000000u}, - {8, 0xfc000000u}, {7, 0xe6000000u}, {8, 0xfd000000u}, {13, 0xffd80000u}, - {19, 0xfffe0000u}, {13, 0xffe00000u}, {14, 0xfff00000u}, {6, 0x88000000u}, - {15, 0xfffa0000u}, {5, 0x18000000u}, {6, 0x8c000000u}, {5, 0x20000000u}, - {6, 0x90000000u}, {5, 0x28000000u}, {6, 0x94000000u}, {6, 0x98000000u}, - {6, 0x9c000000u}, {5, 0x30000000u}, {7, 0xe8000000u}, {7, 0xea000000u}, - {6, 0xa0000000u}, {6, 0xa4000000u}, {6, 0xa8000000u}, {5, 0x38000000u}, - {6, 0xac000000u}, {7, 0xec000000u}, {6, 0xb0000000u}, {5, 0x40000000u}, - {5, 0x48000000u}, {6, 0xb4000000u}, {7, 0xee000000u}, {7, 0xf0000000u}, - {7, 0xf2000000u}, {7, 0xf4000000u}, {7, 0xf6000000u}, {15, 0xfffc0000u}, - {11, 0xff800000u}, {14, 0xfff40000u}, {13, 0xffe80000u}, {28, 0xffffffc0u}, - {20, 0xfffe6000u}, {22, 0xffff4800u}, {20, 0xfffe7000u}, {20, 0xfffe8000u}, - {22, 0xffff4c00u}, {22, 0xffff5000u}, {22, 0xffff5400u}, {23, 0xffffb200u}, - {22, 0xffff5800u}, {23, 0xffffb400u}, {23, 0xffffb600u}, {23, 0xffffb800u}, - {23, 0xffffba00u}, {23, 0xffffbc00u}, {24, 0xffffeb00u}, {23, 0xffffbe00u}, - {24, 0xffffec00u}, {24, 0xffffed00u}, {22, 0xffff5c00u}, {23, 0xffffc000u}, - {24, 0xffffee00u}, {23, 0xffffc200u}, {23, 0xffffc400u}, {23, 0xffffc600u}, - {23, 0xffffc800u}, {21, 0xfffee000u}, {22, 0xffff6000u}, {23, 0xffffca00u}, - {22, 0xffff6400u}, {23, 0xffffcc00u}, {23, 0xffffce00u}, {24, 0xffffef00u}, - {22, 0xffff6800u}, {21, 0xfffee800u}, {20, 0xfffe9000u}, {22, 0xffff6c00u}, - {22, 0xffff7000u}, {23, 0xffffd000u}, {23, 0xffffd200u}, {21, 0xfffef000u}, - {23, 0xffffd400u}, {22, 0xffff7400u}, {22, 0xffff7800u}, {24, 0xfffff000u}, - {21, 0xfffef800u}, {22, 0xffff7c00u}, {23, 0xffffd600u}, {23, 0xffffd800u}, - {21, 0xffff0000u}, {21, 0xffff0800u}, {22, 0xffff8000u}, {21, 0xffff1000u}, - {23, 0xffffda00u}, {22, 0xffff8400u}, {23, 0xffffdc00u}, {23, 0xffffde00u}, - {20, 0xfffea000u}, {22, 0xffff8800u}, {22, 0xffff8c00u}, {22, 0xffff9000u}, - {23, 0xffffe000u}, {22, 0xffff9400u}, {22, 0xffff9800u}, {23, 0xffffe200u}, - {26, 0xfffff800u}, {26, 0xfffff840u}, {20, 0xfffeb000u}, {19, 0xfffe2000u}, - {22, 0xffff9c00u}, {23, 0xffffe400u}, {22, 0xffffa000u}, {25, 0xfffff600u}, - {26, 0xfffff880u}, {26, 0xfffff8c0u}, {26, 0xfffff900u}, {27, 0xfffffbc0u}, - {27, 0xfffffbe0u}, {26, 0xfffff940u}, {24, 0xfffff100u}, {25, 0xfffff680u}, - {19, 0xfffe4000u}, {21, 0xffff1800u}, {26, 0xfffff980u}, {27, 0xfffffc00u}, - {27, 0xfffffc20u}, {26, 0xfffff9c0u}, {27, 0xfffffc40u}, {24, 0xfffff200u}, - {21, 0xffff2000u}, {21, 0xffff2800u}, {26, 0xfffffa00u}, {26, 0xfffffa40u}, - {28, 0xffffffd0u}, {27, 0xfffffc60u}, {27, 0xfffffc80u}, {27, 0xfffffca0u}, - {20, 0xfffec000u}, {24, 0xfffff300u}, {20, 0xfffed000u}, {21, 0xffff3000u}, - {22, 0xffffa400u}, {21, 0xffff3800u}, {21, 0xffff4000u}, {23, 0xffffe600u}, - {22, 0xffffa800u}, {22, 0xffffac00u}, {25, 0xfffff700u}, {25, 0xfffff780u}, - {24, 0xfffff400u}, {24, 0xfffff500u}, {26, 0xfffffa80u}, {23, 0xffffe800u}, - {26, 0xfffffac0u}, {27, 0xfffffcc0u}, {26, 0xfffffb00u}, {26, 0xfffffb40u}, - {27, 0xfffffce0u}, {27, 0xfffffd00u}, {27, 0xfffffd20u}, {27, 0xfffffd40u}, - {27, 0xfffffd60u}, {28, 0xffffffe0u}, {27, 0xfffffd80u}, {27, 0xfffffda0u}, - {27, 0xfffffdc0u}, {27, 0xfffffde0u}, {27, 0xfffffe00u}, {26, 0xfffffb80u}, - {30, 0xfffffffcu}}; + {13, 0xffc00000u}, {23, 0xffffb000u}, {28, 0xfffffe20u}, {28, 0xfffffe30u}, + {28, 0xfffffe40u}, {28, 0xfffffe50u}, {28, 0xfffffe60u}, {28, 0xfffffe70u}, + {28, 0xfffffe80u}, {24, 0xffffea00u}, {30, 0xfffffff0u}, {28, 0xfffffe90u}, + {28, 0xfffffea0u}, {30, 0xfffffff4u}, {28, 0xfffffeb0u}, {28, 0xfffffec0u}, + {28, 0xfffffed0u}, {28, 0xfffffee0u}, {28, 0xfffffef0u}, {28, 0xffffff00u}, + {28, 0xffffff10u}, {28, 0xffffff20u}, {30, 0xfffffff8u}, {28, 0xffffff30u}, + {28, 0xffffff40u}, {28, 0xffffff50u}, {28, 0xffffff60u}, {28, 0xffffff70u}, + {28, 0xffffff80u}, {28, 0xffffff90u}, {28, 0xffffffa0u}, {28, 0xffffffb0u}, + {6, 0x50000000u}, {10, 0xfe000000u}, {10, 0xfe400000u}, {12, 0xffa00000u}, + {13, 0xffc80000u}, {6, 0x54000000u}, {8, 0xf8000000u}, {11, 0xff400000u}, + {10, 0xfe800000u}, {10, 0xfec00000u}, {8, 0xf9000000u}, {11, 0xff600000u}, + {8, 0xfa000000u}, {6, 0x58000000u}, {6, 0x5c000000u}, {6, 0x60000000u}, + {5, 0x0u}, {5, 0x8000000u}, {5, 0x10000000u}, {6, 0x64000000u}, + {6, 0x68000000u}, {6, 0x6c000000u}, {6, 0x70000000u}, {6, 0x74000000u}, + {6, 0x78000000u}, {6, 0x7c000000u}, {7, 0xb8000000u}, {8, 0xfb000000u}, + {15, 0xfff80000u}, {6, 0x80000000u}, {12, 0xffb00000u}, {10, 0xff000000u}, + {13, 0xffd00000u}, {6, 0x84000000u}, {7, 0xba000000u}, {7, 0xbc000000u}, + {7, 0xbe000000u}, {7, 0xc0000000u}, {7, 0xc2000000u}, {7, 0xc4000000u}, + {7, 0xc6000000u}, {7, 0xc8000000u}, {7, 0xca000000u}, {7, 0xcc000000u}, + {7, 0xce000000u}, {7, 0xd0000000u}, {7, 0xd2000000u}, {7, 0xd4000000u}, + {7, 0xd6000000u}, {7, 0xd8000000u}, {7, 0xda000000u}, {7, 0xdc000000u}, + {7, 0xde000000u}, {7, 0xe0000000u}, {7, 0xe2000000u}, {7, 0xe4000000u}, + {8, 0xfc000000u}, {7, 0xe6000000u}, {8, 0xfd000000u}, {13, 0xffd80000u}, + {19, 0xfffe0000u}, {13, 0xffe00000u}, {14, 0xfff00000u}, {6, 0x88000000u}, + {15, 0xfffa0000u}, {5, 0x18000000u}, {6, 0x8c000000u}, {5, 0x20000000u}, + {6, 0x90000000u}, {5, 0x28000000u}, {6, 0x94000000u}, {6, 0x98000000u}, + {6, 0x9c000000u}, {5, 0x30000000u}, {7, 0xe8000000u}, {7, 0xea000000u}, + {6, 0xa0000000u}, {6, 0xa4000000u}, {6, 0xa8000000u}, {5, 0x38000000u}, + {6, 0xac000000u}, {7, 0xec000000u}, {6, 0xb0000000u}, {5, 0x40000000u}, + {5, 0x48000000u}, {6, 0xb4000000u}, {7, 0xee000000u}, {7, 0xf0000000u}, + {7, 0xf2000000u}, {7, 0xf4000000u}, {7, 0xf6000000u}, {15, 0xfffc0000u}, + {11, 0xff800000u}, {14, 0xfff40000u}, {13, 0xffe80000u}, {28, 0xffffffc0u}, + {20, 0xfffe6000u}, {22, 0xffff4800u}, {20, 0xfffe7000u}, {20, 0xfffe8000u}, + {22, 0xffff4c00u}, {22, 0xffff5000u}, {22, 0xffff5400u}, {23, 0xffffb200u}, + {22, 0xffff5800u}, {23, 0xffffb400u}, {23, 0xffffb600u}, {23, 0xffffb800u}, + {23, 0xffffba00u}, {23, 0xffffbc00u}, {24, 0xffffeb00u}, {23, 0xffffbe00u}, + {24, 0xffffec00u}, {24, 0xffffed00u}, {22, 0xffff5c00u}, {23, 0xffffc000u}, + {24, 0xffffee00u}, {23, 0xffffc200u}, {23, 0xffffc400u}, {23, 0xffffc600u}, + {23, 0xffffc800u}, {21, 0xfffee000u}, {22, 0xffff6000u}, {23, 0xffffca00u}, + {22, 0xffff6400u}, {23, 0xffffcc00u}, {23, 0xffffce00u}, {24, 0xffffef00u}, + {22, 0xffff6800u}, {21, 0xfffee800u}, {20, 0xfffe9000u}, {22, 0xffff6c00u}, + {22, 0xffff7000u}, {23, 0xffffd000u}, {23, 0xffffd200u}, {21, 0xfffef000u}, + {23, 0xffffd400u}, {22, 0xffff7400u}, {22, 0xffff7800u}, {24, 0xfffff000u}, + {21, 0xfffef800u}, {22, 0xffff7c00u}, {23, 0xffffd600u}, {23, 0xffffd800u}, + {21, 0xffff0000u}, {21, 0xffff0800u}, {22, 0xffff8000u}, {21, 0xffff1000u}, + {23, 0xffffda00u}, {22, 0xffff8400u}, {23, 0xffffdc00u}, {23, 0xffffde00u}, + {20, 0xfffea000u}, {22, 0xffff8800u}, {22, 0xffff8c00u}, {22, 0xffff9000u}, + {23, 0xffffe000u}, {22, 0xffff9400u}, {22, 0xffff9800u}, {23, 0xffffe200u}, + {26, 0xfffff800u}, {26, 0xfffff840u}, {20, 0xfffeb000u}, {19, 0xfffe2000u}, + {22, 0xffff9c00u}, {23, 0xffffe400u}, {22, 0xffffa000u}, {25, 0xfffff600u}, + {26, 0xfffff880u}, {26, 0xfffff8c0u}, {26, 0xfffff900u}, {27, 0xfffffbc0u}, + {27, 0xfffffbe0u}, {26, 0xfffff940u}, {24, 0xfffff100u}, {25, 0xfffff680u}, + {19, 0xfffe4000u}, {21, 0xffff1800u}, {26, 0xfffff980u}, {27, 0xfffffc00u}, + {27, 0xfffffc20u}, {26, 0xfffff9c0u}, {27, 0xfffffc40u}, {24, 0xfffff200u}, + {21, 0xffff2000u}, {21, 0xffff2800u}, {26, 0xfffffa00u}, {26, 0xfffffa40u}, + {28, 0xffffffd0u}, {27, 0xfffffc60u}, {27, 0xfffffc80u}, {27, 0xfffffca0u}, + {20, 0xfffec000u}, {24, 0xfffff300u}, {20, 0xfffed000u}, {21, 0xffff3000u}, + {22, 0xffffa400u}, {21, 0xffff3800u}, {21, 0xffff4000u}, {23, 0xffffe600u}, + {22, 0xffffa800u}, {22, 0xffffac00u}, {25, 0xfffff700u}, {25, 0xfffff780u}, + {24, 0xfffff400u}, {24, 0xfffff500u}, {26, 0xfffffa80u}, {23, 0xffffe800u}, + {26, 0xfffffac0u}, {27, 0xfffffcc0u}, {26, 0xfffffb00u}, {26, 0xfffffb40u}, + {27, 0xfffffce0u}, {27, 0xfffffd00u}, {27, 0xfffffd20u}, {27, 0xfffffd40u}, + {27, 0xfffffd60u}, {28, 0xffffffe0u}, {27, 0xfffffd80u}, {27, 0xfffffda0u}, + {27, 0xfffffdc0u}, {27, 0xfffffde0u}, {27, 0xfffffe00u}, {26, 0xfffffb80u}, + {30, 0xfffffffcu}}; const nghttp2_huff_decode huff_decode_table[][16] = { - /* 0 */ - { - {0x04, 0}, - {0x05, 0}, - {0x07, 0}, - {0x08, 0}, - {0x0b, 0}, - {0x0c, 0}, - {0x10, 0}, - {0x13, 0}, - {0x19, 0}, - {0x1c, 0}, - {0x20, 0}, - {0x23, 0}, - {0x2a, 0}, - {0x31, 0}, - {0x39, 0}, - {0x4040, 0}, - }, - /* 1 */ - { - {0xc000, 48}, - {0xc000, 49}, - {0xc000, 50}, - {0xc000, 97}, - {0xc000, 99}, - {0xc000, 101}, - {0xc000, 105}, - {0xc000, 111}, - {0xc000, 115}, - {0xc000, 116}, - {0x0d, 0}, - {0x0e, 0}, - {0x11, 0}, - {0x12, 0}, - {0x14, 0}, - {0x15, 0}, - }, - /* 2 */ - { - {0x8001, 48}, - {0xc016, 48}, - {0x8001, 49}, - {0xc016, 49}, - {0x8001, 50}, - {0xc016, 50}, - {0x8001, 97}, - {0xc016, 97}, - {0x8001, 99}, - {0xc016, 99}, - {0x8001, 101}, - {0xc016, 101}, - {0x8001, 105}, - {0xc016, 105}, - {0x8001, 111}, - {0xc016, 111}, - }, - /* 3 */ - { - {0x8002, 48}, - {0x8009, 48}, - {0x8017, 48}, - {0xc028, 48}, - {0x8002, 49}, - {0x8009, 49}, - {0x8017, 49}, - {0xc028, 49}, - {0x8002, 50}, - {0x8009, 50}, - {0x8017, 50}, - {0xc028, 50}, - {0x8002, 97}, - {0x8009, 97}, - {0x8017, 97}, - {0xc028, 97}, - }, - /* 4 */ - { - {0x8003, 48}, - {0x8006, 48}, - {0x800a, 48}, - {0x800f, 48}, - {0x8018, 48}, - {0x801f, 48}, - {0x8029, 48}, - {0xc038, 48}, - {0x8003, 49}, - {0x8006, 49}, - {0x800a, 49}, - {0x800f, 49}, - {0x8018, 49}, - {0x801f, 49}, - {0x8029, 49}, - {0xc038, 49}, - }, - /* 5 */ - { - {0x8003, 50}, - {0x8006, 50}, - {0x800a, 50}, - {0x800f, 50}, - {0x8018, 50}, - {0x801f, 50}, - {0x8029, 50}, - {0xc038, 50}, - {0x8003, 97}, - {0x8006, 97}, - {0x800a, 97}, - {0x800f, 97}, - {0x8018, 97}, - {0x801f, 97}, - {0x8029, 97}, - {0xc038, 97}, - }, - /* 6 */ - { - {0x8002, 99}, - {0x8009, 99}, - {0x8017, 99}, - {0xc028, 99}, - {0x8002, 101}, - {0x8009, 101}, - {0x8017, 101}, - {0xc028, 101}, - {0x8002, 105}, - {0x8009, 105}, - {0x8017, 105}, - {0xc028, 105}, - {0x8002, 111}, - {0x8009, 111}, - {0x8017, 111}, - {0xc028, 111}, - }, - /* 7 */ - { - {0x8003, 99}, - {0x8006, 99}, - {0x800a, 99}, - {0x800f, 99}, - {0x8018, 99}, - {0x801f, 99}, - {0x8029, 99}, - {0xc038, 99}, - {0x8003, 101}, - {0x8006, 101}, - {0x800a, 101}, - {0x800f, 101}, - {0x8018, 101}, - {0x801f, 101}, - {0x8029, 101}, - {0xc038, 101}, - }, - /* 8 */ - { - {0x8003, 105}, - {0x8006, 105}, - {0x800a, 105}, - {0x800f, 105}, - {0x8018, 105}, - {0x801f, 105}, - {0x8029, 105}, - {0xc038, 105}, - {0x8003, 111}, - {0x8006, 111}, - {0x800a, 111}, - {0x800f, 111}, - {0x8018, 111}, - {0x801f, 111}, - {0x8029, 111}, - {0xc038, 111}, - }, - /* 9 */ - { - {0x8001, 115}, - {0xc016, 115}, - {0x8001, 116}, - {0xc016, 116}, - {0xc000, 32}, - {0xc000, 37}, - {0xc000, 45}, - {0xc000, 46}, - {0xc000, 47}, - {0xc000, 51}, - {0xc000, 52}, - {0xc000, 53}, - {0xc000, 54}, - {0xc000, 55}, - {0xc000, 56}, - {0xc000, 57}, - }, - /* 10 */ - { - {0x8002, 115}, - {0x8009, 115}, - {0x8017, 115}, - {0xc028, 115}, - {0x8002, 116}, - {0x8009, 116}, - {0x8017, 116}, - {0xc028, 116}, - {0x8001, 32}, - {0xc016, 32}, - {0x8001, 37}, - {0xc016, 37}, - {0x8001, 45}, - {0xc016, 45}, - {0x8001, 46}, - {0xc016, 46}, - }, - /* 11 */ - { - {0x8003, 115}, - {0x8006, 115}, - {0x800a, 115}, - {0x800f, 115}, - {0x8018, 115}, - {0x801f, 115}, - {0x8029, 115}, - {0xc038, 115}, - {0x8003, 116}, - {0x8006, 116}, - {0x800a, 116}, - {0x800f, 116}, - {0x8018, 116}, - {0x801f, 116}, - {0x8029, 116}, - {0xc038, 116}, - }, - /* 12 */ - { - {0x8002, 32}, - {0x8009, 32}, - {0x8017, 32}, - {0xc028, 32}, - {0x8002, 37}, - {0x8009, 37}, - {0x8017, 37}, - {0xc028, 37}, - {0x8002, 45}, - {0x8009, 45}, - {0x8017, 45}, - {0xc028, 45}, - {0x8002, 46}, - {0x8009, 46}, - {0x8017, 46}, - {0xc028, 46}, - }, - /* 13 */ - { - {0x8003, 32}, - {0x8006, 32}, - {0x800a, 32}, - {0x800f, 32}, - {0x8018, 32}, - {0x801f, 32}, - {0x8029, 32}, - {0xc038, 32}, - {0x8003, 37}, - {0x8006, 37}, - {0x800a, 37}, - {0x800f, 37}, - {0x8018, 37}, - {0x801f, 37}, - {0x8029, 37}, - {0xc038, 37}, - }, - /* 14 */ - { - {0x8003, 45}, - {0x8006, 45}, - {0x800a, 45}, - {0x800f, 45}, - {0x8018, 45}, - {0x801f, 45}, - {0x8029, 45}, - {0xc038, 45}, - {0x8003, 46}, - {0x8006, 46}, - {0x800a, 46}, - {0x800f, 46}, - {0x8018, 46}, - {0x801f, 46}, - {0x8029, 46}, - {0xc038, 46}, - }, - /* 15 */ - { - {0x8001, 47}, - {0xc016, 47}, - {0x8001, 51}, - {0xc016, 51}, - {0x8001, 52}, - {0xc016, 52}, - {0x8001, 53}, - {0xc016, 53}, - {0x8001, 54}, - {0xc016, 54}, - {0x8001, 55}, - {0xc016, 55}, - {0x8001, 56}, - {0xc016, 56}, - {0x8001, 57}, - {0xc016, 57}, - }, - /* 16 */ - { - {0x8002, 47}, - {0x8009, 47}, - {0x8017, 47}, - {0xc028, 47}, - {0x8002, 51}, - {0x8009, 51}, - {0x8017, 51}, - {0xc028, 51}, - {0x8002, 52}, - {0x8009, 52}, - {0x8017, 52}, - {0xc028, 52}, - {0x8002, 53}, - {0x8009, 53}, - {0x8017, 53}, - {0xc028, 53}, - }, - /* 17 */ - { - {0x8003, 47}, - {0x8006, 47}, - {0x800a, 47}, - {0x800f, 47}, - {0x8018, 47}, - {0x801f, 47}, - {0x8029, 47}, - {0xc038, 47}, - {0x8003, 51}, - {0x8006, 51}, - {0x800a, 51}, - {0x800f, 51}, - {0x8018, 51}, - {0x801f, 51}, - {0x8029, 51}, - {0xc038, 51}, - }, - /* 18 */ - { - {0x8003, 52}, - {0x8006, 52}, - {0x800a, 52}, - {0x800f, 52}, - {0x8018, 52}, - {0x801f, 52}, - {0x8029, 52}, - {0xc038, 52}, - {0x8003, 53}, - {0x8006, 53}, - {0x800a, 53}, - {0x800f, 53}, - {0x8018, 53}, - {0x801f, 53}, - {0x8029, 53}, - {0xc038, 53}, - }, - /* 19 */ - { - {0x8002, 54}, - {0x8009, 54}, - {0x8017, 54}, - {0xc028, 54}, - {0x8002, 55}, - {0x8009, 55}, - {0x8017, 55}, - {0xc028, 55}, - {0x8002, 56}, - {0x8009, 56}, - {0x8017, 56}, - {0xc028, 56}, - {0x8002, 57}, - {0x8009, 57}, - {0x8017, 57}, - {0xc028, 57}, - }, - /* 20 */ - { - {0x8003, 54}, - {0x8006, 54}, - {0x800a, 54}, - {0x800f, 54}, - {0x8018, 54}, - {0x801f, 54}, - {0x8029, 54}, - {0xc038, 54}, - {0x8003, 55}, - {0x8006, 55}, - {0x800a, 55}, - {0x800f, 55}, - {0x8018, 55}, - {0x801f, 55}, - {0x8029, 55}, - {0xc038, 55}, - }, - /* 21 */ - { - {0x8003, 56}, - {0x8006, 56}, - {0x800a, 56}, - {0x800f, 56}, - {0x8018, 56}, - {0x801f, 56}, - {0x8029, 56}, - {0xc038, 56}, - {0x8003, 57}, - {0x8006, 57}, - {0x800a, 57}, - {0x800f, 57}, - {0x8018, 57}, - {0x801f, 57}, - {0x8029, 57}, - {0xc038, 57}, - }, - /* 22 */ - { - {0x1a, 0}, - {0x1b, 0}, - {0x1d, 0}, - {0x1e, 0}, - {0x21, 0}, - {0x22, 0}, - {0x24, 0}, - {0x25, 0}, - {0x2b, 0}, - {0x2e, 0}, - {0x32, 0}, - {0x35, 0}, - {0x3a, 0}, - {0x3d, 0}, - {0x41, 0}, - {0x4044, 0}, - }, - /* 23 */ - { - {0xc000, 61}, - {0xc000, 65}, - {0xc000, 95}, - {0xc000, 98}, - {0xc000, 100}, - {0xc000, 102}, - {0xc000, 103}, - {0xc000, 104}, - {0xc000, 108}, - {0xc000, 109}, - {0xc000, 110}, - {0xc000, 112}, - {0xc000, 114}, - {0xc000, 117}, - {0x26, 0}, - {0x27, 0}, - }, - /* 24 */ - { - {0x8001, 61}, - {0xc016, 61}, - {0x8001, 65}, - {0xc016, 65}, - {0x8001, 95}, - {0xc016, 95}, - {0x8001, 98}, - {0xc016, 98}, - {0x8001, 100}, - {0xc016, 100}, - {0x8001, 102}, - {0xc016, 102}, - {0x8001, 103}, - {0xc016, 103}, - {0x8001, 104}, - {0xc016, 104}, - }, - /* 25 */ - { - {0x8002, 61}, - {0x8009, 61}, - {0x8017, 61}, - {0xc028, 61}, - {0x8002, 65}, - {0x8009, 65}, - {0x8017, 65}, - {0xc028, 65}, - {0x8002, 95}, - {0x8009, 95}, - {0x8017, 95}, - {0xc028, 95}, - {0x8002, 98}, - {0x8009, 98}, - {0x8017, 98}, - {0xc028, 98}, - }, - /* 26 */ - { - {0x8003, 61}, - {0x8006, 61}, - {0x800a, 61}, - {0x800f, 61}, - {0x8018, 61}, - {0x801f, 61}, - {0x8029, 61}, - {0xc038, 61}, - {0x8003, 65}, - {0x8006, 65}, - {0x800a, 65}, - {0x800f, 65}, - {0x8018, 65}, - {0x801f, 65}, - {0x8029, 65}, - {0xc038, 65}, - }, - /* 27 */ - { - {0x8003, 95}, - {0x8006, 95}, - {0x800a, 95}, - {0x800f, 95}, - {0x8018, 95}, - {0x801f, 95}, - {0x8029, 95}, - {0xc038, 95}, - {0x8003, 98}, - {0x8006, 98}, - {0x800a, 98}, - {0x800f, 98}, - {0x8018, 98}, - {0x801f, 98}, - {0x8029, 98}, - {0xc038, 98}, - }, - /* 28 */ - { - {0x8002, 100}, - {0x8009, 100}, - {0x8017, 100}, - {0xc028, 100}, - {0x8002, 102}, - {0x8009, 102}, - {0x8017, 102}, - {0xc028, 102}, - {0x8002, 103}, - {0x8009, 103}, - {0x8017, 103}, - {0xc028, 103}, - {0x8002, 104}, - {0x8009, 104}, - {0x8017, 104}, - {0xc028, 104}, - }, - /* 29 */ - { - {0x8003, 100}, - {0x8006, 100}, - {0x800a, 100}, - {0x800f, 100}, - {0x8018, 100}, - {0x801f, 100}, - {0x8029, 100}, - {0xc038, 100}, - {0x8003, 102}, - {0x8006, 102}, - {0x800a, 102}, - {0x800f, 102}, - {0x8018, 102}, - {0x801f, 102}, - {0x8029, 102}, - {0xc038, 102}, - }, - /* 30 */ - { - {0x8003, 103}, - {0x8006, 103}, - {0x800a, 103}, - {0x800f, 103}, - {0x8018, 103}, - {0x801f, 103}, - {0x8029, 103}, - {0xc038, 103}, - {0x8003, 104}, - {0x8006, 104}, - {0x800a, 104}, - {0x800f, 104}, - {0x8018, 104}, - {0x801f, 104}, - {0x8029, 104}, - {0xc038, 104}, - }, - /* 31 */ - { - {0x8001, 108}, - {0xc016, 108}, - {0x8001, 109}, - {0xc016, 109}, - {0x8001, 110}, - {0xc016, 110}, - {0x8001, 112}, - {0xc016, 112}, - {0x8001, 114}, - {0xc016, 114}, - {0x8001, 117}, - {0xc016, 117}, - {0xc000, 58}, - {0xc000, 66}, - {0xc000, 67}, - {0xc000, 68}, - }, - /* 32 */ - { - {0x8002, 108}, - {0x8009, 108}, - {0x8017, 108}, - {0xc028, 108}, - {0x8002, 109}, - {0x8009, 109}, - {0x8017, 109}, - {0xc028, 109}, - {0x8002, 110}, - {0x8009, 110}, - {0x8017, 110}, - {0xc028, 110}, - {0x8002, 112}, - {0x8009, 112}, - {0x8017, 112}, - {0xc028, 112}, - }, - /* 33 */ - { - {0x8003, 108}, - {0x8006, 108}, - {0x800a, 108}, - {0x800f, 108}, - {0x8018, 108}, - {0x801f, 108}, - {0x8029, 108}, - {0xc038, 108}, - {0x8003, 109}, - {0x8006, 109}, - {0x800a, 109}, - {0x800f, 109}, - {0x8018, 109}, - {0x801f, 109}, - {0x8029, 109}, - {0xc038, 109}, - }, - /* 34 */ - { - {0x8003, 110}, - {0x8006, 110}, - {0x800a, 110}, - {0x800f, 110}, - {0x8018, 110}, - {0x801f, 110}, - {0x8029, 110}, - {0xc038, 110}, - {0x8003, 112}, - {0x8006, 112}, - {0x800a, 112}, - {0x800f, 112}, - {0x8018, 112}, - {0x801f, 112}, - {0x8029, 112}, - {0xc038, 112}, - }, - /* 35 */ - { - {0x8002, 114}, - {0x8009, 114}, - {0x8017, 114}, - {0xc028, 114}, - {0x8002, 117}, - {0x8009, 117}, - {0x8017, 117}, - {0xc028, 117}, - {0x8001, 58}, - {0xc016, 58}, - {0x8001, 66}, - {0xc016, 66}, - {0x8001, 67}, - {0xc016, 67}, - {0x8001, 68}, - {0xc016, 68}, - }, - /* 36 */ - { - {0x8003, 114}, - {0x8006, 114}, - {0x800a, 114}, - {0x800f, 114}, - {0x8018, 114}, - {0x801f, 114}, - {0x8029, 114}, - {0xc038, 114}, - {0x8003, 117}, - {0x8006, 117}, - {0x800a, 117}, - {0x800f, 117}, - {0x8018, 117}, - {0x801f, 117}, - {0x8029, 117}, - {0xc038, 117}, - }, - /* 37 */ - { - {0x8002, 58}, - {0x8009, 58}, - {0x8017, 58}, - {0xc028, 58}, - {0x8002, 66}, - {0x8009, 66}, - {0x8017, 66}, - {0xc028, 66}, - {0x8002, 67}, - {0x8009, 67}, - {0x8017, 67}, - {0xc028, 67}, - {0x8002, 68}, - {0x8009, 68}, - {0x8017, 68}, - {0xc028, 68}, - }, - /* 38 */ - { - {0x8003, 58}, - {0x8006, 58}, - {0x800a, 58}, - {0x800f, 58}, - {0x8018, 58}, - {0x801f, 58}, - {0x8029, 58}, - {0xc038, 58}, - {0x8003, 66}, - {0x8006, 66}, - {0x800a, 66}, - {0x800f, 66}, - {0x8018, 66}, - {0x801f, 66}, - {0x8029, 66}, - {0xc038, 66}, - }, - /* 39 */ - { - {0x8003, 67}, - {0x8006, 67}, - {0x800a, 67}, - {0x800f, 67}, - {0x8018, 67}, - {0x801f, 67}, - {0x8029, 67}, - {0xc038, 67}, - {0x8003, 68}, - {0x8006, 68}, - {0x800a, 68}, - {0x800f, 68}, - {0x8018, 68}, - {0x801f, 68}, - {0x8029, 68}, - {0xc038, 68}, - }, - /* 40 */ - { - {0x2c, 0}, - {0x2d, 0}, - {0x2f, 0}, - {0x30, 0}, - {0x33, 0}, - {0x34, 0}, - {0x36, 0}, - {0x37, 0}, - {0x3b, 0}, - {0x3c, 0}, - {0x3e, 0}, - {0x3f, 0}, - {0x42, 0}, - {0x43, 0}, - {0x45, 0}, - {0x4048, 0}, - }, - /* 41 */ - { - {0xc000, 69}, - {0xc000, 70}, - {0xc000, 71}, - {0xc000, 72}, - {0xc000, 73}, - {0xc000, 74}, - {0xc000, 75}, - {0xc000, 76}, - {0xc000, 77}, - {0xc000, 78}, - {0xc000, 79}, - {0xc000, 80}, - {0xc000, 81}, - {0xc000, 82}, - {0xc000, 83}, - {0xc000, 84}, - }, - /* 42 */ - { - {0x8001, 69}, - {0xc016, 69}, - {0x8001, 70}, - {0xc016, 70}, - {0x8001, 71}, - {0xc016, 71}, - {0x8001, 72}, - {0xc016, 72}, - {0x8001, 73}, - {0xc016, 73}, - {0x8001, 74}, - {0xc016, 74}, - {0x8001, 75}, - {0xc016, 75}, - {0x8001, 76}, - {0xc016, 76}, - }, - /* 43 */ - { - {0x8002, 69}, - {0x8009, 69}, - {0x8017, 69}, - {0xc028, 69}, - {0x8002, 70}, - {0x8009, 70}, - {0x8017, 70}, - {0xc028, 70}, - {0x8002, 71}, - {0x8009, 71}, - {0x8017, 71}, - {0xc028, 71}, - {0x8002, 72}, - {0x8009, 72}, - {0x8017, 72}, - {0xc028, 72}, - }, - /* 44 */ - { - {0x8003, 69}, - {0x8006, 69}, - {0x800a, 69}, - {0x800f, 69}, - {0x8018, 69}, - {0x801f, 69}, - {0x8029, 69}, - {0xc038, 69}, - {0x8003, 70}, - {0x8006, 70}, - {0x800a, 70}, - {0x800f, 70}, - {0x8018, 70}, - {0x801f, 70}, - {0x8029, 70}, - {0xc038, 70}, - }, - /* 45 */ - { - {0x8003, 71}, - {0x8006, 71}, - {0x800a, 71}, - {0x800f, 71}, - {0x8018, 71}, - {0x801f, 71}, - {0x8029, 71}, - {0xc038, 71}, - {0x8003, 72}, - {0x8006, 72}, - {0x800a, 72}, - {0x800f, 72}, - {0x8018, 72}, - {0x801f, 72}, - {0x8029, 72}, - {0xc038, 72}, - }, - /* 46 */ - { - {0x8002, 73}, - {0x8009, 73}, - {0x8017, 73}, - {0xc028, 73}, - {0x8002, 74}, - {0x8009, 74}, - {0x8017, 74}, - {0xc028, 74}, - {0x8002, 75}, - {0x8009, 75}, - {0x8017, 75}, - {0xc028, 75}, - {0x8002, 76}, - {0x8009, 76}, - {0x8017, 76}, - {0xc028, 76}, - }, - /* 47 */ - { - {0x8003, 73}, - {0x8006, 73}, - {0x800a, 73}, - {0x800f, 73}, - {0x8018, 73}, - {0x801f, 73}, - {0x8029, 73}, - {0xc038, 73}, - {0x8003, 74}, - {0x8006, 74}, - {0x800a, 74}, - {0x800f, 74}, - {0x8018, 74}, - {0x801f, 74}, - {0x8029, 74}, - {0xc038, 74}, - }, - /* 48 */ - { - {0x8003, 75}, - {0x8006, 75}, - {0x800a, 75}, - {0x800f, 75}, - {0x8018, 75}, - {0x801f, 75}, - {0x8029, 75}, - {0xc038, 75}, - {0x8003, 76}, - {0x8006, 76}, - {0x800a, 76}, - {0x800f, 76}, - {0x8018, 76}, - {0x801f, 76}, - {0x8029, 76}, - {0xc038, 76}, - }, - /* 49 */ - { - {0x8001, 77}, - {0xc016, 77}, - {0x8001, 78}, - {0xc016, 78}, - {0x8001, 79}, - {0xc016, 79}, - {0x8001, 80}, - {0xc016, 80}, - {0x8001, 81}, - {0xc016, 81}, - {0x8001, 82}, - {0xc016, 82}, - {0x8001, 83}, - {0xc016, 83}, - {0x8001, 84}, - {0xc016, 84}, - }, - /* 50 */ - { - {0x8002, 77}, - {0x8009, 77}, - {0x8017, 77}, - {0xc028, 77}, - {0x8002, 78}, - {0x8009, 78}, - {0x8017, 78}, - {0xc028, 78}, - {0x8002, 79}, - {0x8009, 79}, - {0x8017, 79}, - {0xc028, 79}, - {0x8002, 80}, - {0x8009, 80}, - {0x8017, 80}, - {0xc028, 80}, - }, - /* 51 */ - { - {0x8003, 77}, - {0x8006, 77}, - {0x800a, 77}, - {0x800f, 77}, - {0x8018, 77}, - {0x801f, 77}, - {0x8029, 77}, - {0xc038, 77}, - {0x8003, 78}, - {0x8006, 78}, - {0x800a, 78}, - {0x800f, 78}, - {0x8018, 78}, - {0x801f, 78}, - {0x8029, 78}, - {0xc038, 78}, - }, - /* 52 */ - { - {0x8003, 79}, - {0x8006, 79}, - {0x800a, 79}, - {0x800f, 79}, - {0x8018, 79}, - {0x801f, 79}, - {0x8029, 79}, - {0xc038, 79}, - {0x8003, 80}, - {0x8006, 80}, - {0x800a, 80}, - {0x800f, 80}, - {0x8018, 80}, - {0x801f, 80}, - {0x8029, 80}, - {0xc038, 80}, - }, - /* 53 */ - { - {0x8002, 81}, - {0x8009, 81}, - {0x8017, 81}, - {0xc028, 81}, - {0x8002, 82}, - {0x8009, 82}, - {0x8017, 82}, - {0xc028, 82}, - {0x8002, 83}, - {0x8009, 83}, - {0x8017, 83}, - {0xc028, 83}, - {0x8002, 84}, - {0x8009, 84}, - {0x8017, 84}, - {0xc028, 84}, - }, - /* 54 */ - { - {0x8003, 81}, - {0x8006, 81}, - {0x800a, 81}, - {0x800f, 81}, - {0x8018, 81}, - {0x801f, 81}, - {0x8029, 81}, - {0xc038, 81}, - {0x8003, 82}, - {0x8006, 82}, - {0x800a, 82}, - {0x800f, 82}, - {0x8018, 82}, - {0x801f, 82}, - {0x8029, 82}, - {0xc038, 82}, - }, - /* 55 */ - { - {0x8003, 83}, - {0x8006, 83}, - {0x800a, 83}, - {0x800f, 83}, - {0x8018, 83}, - {0x801f, 83}, - {0x8029, 83}, - {0xc038, 83}, - {0x8003, 84}, - {0x8006, 84}, - {0x800a, 84}, - {0x800f, 84}, - {0x8018, 84}, - {0x801f, 84}, - {0x8029, 84}, - {0xc038, 84}, - }, - /* 56 */ - { - {0xc000, 85}, - {0xc000, 86}, - {0xc000, 87}, - {0xc000, 89}, - {0xc000, 106}, - {0xc000, 107}, - {0xc000, 113}, - {0xc000, 118}, - {0xc000, 119}, - {0xc000, 120}, - {0xc000, 121}, - {0xc000, 122}, - {0x46, 0}, - {0x47, 0}, - {0x49, 0}, - {0x404a, 0}, - }, - /* 57 */ - { - {0x8001, 85}, - {0xc016, 85}, - {0x8001, 86}, - {0xc016, 86}, - {0x8001, 87}, - {0xc016, 87}, - {0x8001, 89}, - {0xc016, 89}, - {0x8001, 106}, - {0xc016, 106}, - {0x8001, 107}, - {0xc016, 107}, - {0x8001, 113}, - {0xc016, 113}, - {0x8001, 118}, - {0xc016, 118}, - }, - /* 58 */ - { - {0x8002, 85}, - {0x8009, 85}, - {0x8017, 85}, - {0xc028, 85}, - {0x8002, 86}, - {0x8009, 86}, - {0x8017, 86}, - {0xc028, 86}, - {0x8002, 87}, - {0x8009, 87}, - {0x8017, 87}, - {0xc028, 87}, - {0x8002, 89}, - {0x8009, 89}, - {0x8017, 89}, - {0xc028, 89}, - }, - /* 59 */ - { - {0x8003, 85}, - {0x8006, 85}, - {0x800a, 85}, - {0x800f, 85}, - {0x8018, 85}, - {0x801f, 85}, - {0x8029, 85}, - {0xc038, 85}, - {0x8003, 86}, - {0x8006, 86}, - {0x800a, 86}, - {0x800f, 86}, - {0x8018, 86}, - {0x801f, 86}, - {0x8029, 86}, - {0xc038, 86}, - }, - /* 60 */ - { - {0x8003, 87}, - {0x8006, 87}, - {0x800a, 87}, - {0x800f, 87}, - {0x8018, 87}, - {0x801f, 87}, - {0x8029, 87}, - {0xc038, 87}, - {0x8003, 89}, - {0x8006, 89}, - {0x800a, 89}, - {0x800f, 89}, - {0x8018, 89}, - {0x801f, 89}, - {0x8029, 89}, - {0xc038, 89}, - }, - /* 61 */ - { - {0x8002, 106}, - {0x8009, 106}, - {0x8017, 106}, - {0xc028, 106}, - {0x8002, 107}, - {0x8009, 107}, - {0x8017, 107}, - {0xc028, 107}, - {0x8002, 113}, - {0x8009, 113}, - {0x8017, 113}, - {0xc028, 113}, - {0x8002, 118}, - {0x8009, 118}, - {0x8017, 118}, - {0xc028, 118}, - }, - /* 62 */ - { - {0x8003, 106}, - {0x8006, 106}, - {0x800a, 106}, - {0x800f, 106}, - {0x8018, 106}, - {0x801f, 106}, - {0x8029, 106}, - {0xc038, 106}, - {0x8003, 107}, - {0x8006, 107}, - {0x800a, 107}, - {0x800f, 107}, - {0x8018, 107}, - {0x801f, 107}, - {0x8029, 107}, - {0xc038, 107}, - }, - /* 63 */ - { - {0x8003, 113}, - {0x8006, 113}, - {0x800a, 113}, - {0x800f, 113}, - {0x8018, 113}, - {0x801f, 113}, - {0x8029, 113}, - {0xc038, 113}, - {0x8003, 118}, - {0x8006, 118}, - {0x800a, 118}, - {0x800f, 118}, - {0x8018, 118}, - {0x801f, 118}, - {0x8029, 118}, - {0xc038, 118}, - }, - /* 64 */ - { - {0x8001, 119}, - {0xc016, 119}, - {0x8001, 120}, - {0xc016, 120}, - {0x8001, 121}, - {0xc016, 121}, - {0x8001, 122}, - {0xc016, 122}, - {0xc000, 38}, - {0xc000, 42}, - {0xc000, 44}, - {0xc000, 59}, - {0xc000, 88}, - {0xc000, 90}, - {0x4b, 0}, - {0x4e, 0}, - }, - /* 65 */ - { - {0x8002, 119}, - {0x8009, 119}, - {0x8017, 119}, - {0xc028, 119}, - {0x8002, 120}, - {0x8009, 120}, - {0x8017, 120}, - {0xc028, 120}, - {0x8002, 121}, - {0x8009, 121}, - {0x8017, 121}, - {0xc028, 121}, - {0x8002, 122}, - {0x8009, 122}, - {0x8017, 122}, - {0xc028, 122}, - }, - /* 66 */ - { - {0x8003, 119}, - {0x8006, 119}, - {0x800a, 119}, - {0x800f, 119}, - {0x8018, 119}, - {0x801f, 119}, - {0x8029, 119}, - {0xc038, 119}, - {0x8003, 120}, - {0x8006, 120}, - {0x800a, 120}, - {0x800f, 120}, - {0x8018, 120}, - {0x801f, 120}, - {0x8029, 120}, - {0xc038, 120}, - }, - /* 67 */ - { - {0x8003, 121}, - {0x8006, 121}, - {0x800a, 121}, - {0x800f, 121}, - {0x8018, 121}, - {0x801f, 121}, - {0x8029, 121}, - {0xc038, 121}, - {0x8003, 122}, - {0x8006, 122}, - {0x800a, 122}, - {0x800f, 122}, - {0x8018, 122}, - {0x801f, 122}, - {0x8029, 122}, - {0xc038, 122}, - }, - /* 68 */ - { - {0x8001, 38}, - {0xc016, 38}, - {0x8001, 42}, - {0xc016, 42}, - {0x8001, 44}, - {0xc016, 44}, - {0x8001, 59}, - {0xc016, 59}, - {0x8001, 88}, - {0xc016, 88}, - {0x8001, 90}, - {0xc016, 90}, - {0x4c, 0}, - {0x4d, 0}, - {0x4f, 0}, - {0x51, 0}, - }, - /* 69 */ - { - {0x8002, 38}, - {0x8009, 38}, - {0x8017, 38}, - {0xc028, 38}, - {0x8002, 42}, - {0x8009, 42}, - {0x8017, 42}, - {0xc028, 42}, - {0x8002, 44}, - {0x8009, 44}, - {0x8017, 44}, - {0xc028, 44}, - {0x8002, 59}, - {0x8009, 59}, - {0x8017, 59}, - {0xc028, 59}, - }, - /* 70 */ - { - {0x8003, 38}, - {0x8006, 38}, - {0x800a, 38}, - {0x800f, 38}, - {0x8018, 38}, - {0x801f, 38}, - {0x8029, 38}, - {0xc038, 38}, - {0x8003, 42}, - {0x8006, 42}, - {0x800a, 42}, - {0x800f, 42}, - {0x8018, 42}, - {0x801f, 42}, - {0x8029, 42}, - {0xc038, 42}, - }, - /* 71 */ - { - {0x8003, 44}, - {0x8006, 44}, - {0x800a, 44}, - {0x800f, 44}, - {0x8018, 44}, - {0x801f, 44}, - {0x8029, 44}, - {0xc038, 44}, - {0x8003, 59}, - {0x8006, 59}, - {0x800a, 59}, - {0x800f, 59}, - {0x8018, 59}, - {0x801f, 59}, - {0x8029, 59}, - {0xc038, 59}, - }, - /* 72 */ - { - {0x8002, 88}, - {0x8009, 88}, - {0x8017, 88}, - {0xc028, 88}, - {0x8002, 90}, - {0x8009, 90}, - {0x8017, 90}, - {0xc028, 90}, - {0xc000, 33}, - {0xc000, 34}, - {0xc000, 40}, - {0xc000, 41}, - {0xc000, 63}, - {0x50, 0}, - {0x52, 0}, - {0x54, 0}, - }, - /* 73 */ - { - {0x8003, 88}, - {0x8006, 88}, - {0x800a, 88}, - {0x800f, 88}, - {0x8018, 88}, - {0x801f, 88}, - {0x8029, 88}, - {0xc038, 88}, - {0x8003, 90}, - {0x8006, 90}, - {0x800a, 90}, - {0x800f, 90}, - {0x8018, 90}, - {0x801f, 90}, - {0x8029, 90}, - {0xc038, 90}, - }, - /* 74 */ - { - {0x8001, 33}, - {0xc016, 33}, - {0x8001, 34}, - {0xc016, 34}, - {0x8001, 40}, - {0xc016, 40}, - {0x8001, 41}, - {0xc016, 41}, - {0x8001, 63}, - {0xc016, 63}, - {0xc000, 39}, - {0xc000, 43}, - {0xc000, 124}, - {0x53, 0}, - {0x55, 0}, - {0x58, 0}, - }, - /* 75 */ - { - {0x8002, 33}, - {0x8009, 33}, - {0x8017, 33}, - {0xc028, 33}, - {0x8002, 34}, - {0x8009, 34}, - {0x8017, 34}, - {0xc028, 34}, - {0x8002, 40}, - {0x8009, 40}, - {0x8017, 40}, - {0xc028, 40}, - {0x8002, 41}, - {0x8009, 41}, - {0x8017, 41}, - {0xc028, 41}, - }, - /* 76 */ - { - {0x8003, 33}, - {0x8006, 33}, - {0x800a, 33}, - {0x800f, 33}, - {0x8018, 33}, - {0x801f, 33}, - {0x8029, 33}, - {0xc038, 33}, - {0x8003, 34}, - {0x8006, 34}, - {0x800a, 34}, - {0x800f, 34}, - {0x8018, 34}, - {0x801f, 34}, - {0x8029, 34}, - {0xc038, 34}, - }, - /* 77 */ - { - {0x8003, 40}, - {0x8006, 40}, - {0x800a, 40}, - {0x800f, 40}, - {0x8018, 40}, - {0x801f, 40}, - {0x8029, 40}, - {0xc038, 40}, - {0x8003, 41}, - {0x8006, 41}, - {0x800a, 41}, - {0x800f, 41}, - {0x8018, 41}, - {0x801f, 41}, - {0x8029, 41}, - {0xc038, 41}, - }, - /* 78 */ - { - {0x8002, 63}, - {0x8009, 63}, - {0x8017, 63}, - {0xc028, 63}, - {0x8001, 39}, - {0xc016, 39}, - {0x8001, 43}, - {0xc016, 43}, - {0x8001, 124}, - {0xc016, 124}, - {0xc000, 35}, - {0xc000, 62}, - {0x56, 0}, - {0x57, 0}, - {0x59, 0}, - {0x5a, 0}, - }, - /* 79 */ - { - {0x8003, 63}, - {0x8006, 63}, - {0x800a, 63}, - {0x800f, 63}, - {0x8018, 63}, - {0x801f, 63}, - {0x8029, 63}, - {0xc038, 63}, - {0x8002, 39}, - {0x8009, 39}, - {0x8017, 39}, - {0xc028, 39}, - {0x8002, 43}, - {0x8009, 43}, - {0x8017, 43}, - {0xc028, 43}, - }, - /* 80 */ - { - {0x8003, 39}, - {0x8006, 39}, - {0x800a, 39}, - {0x800f, 39}, - {0x8018, 39}, - {0x801f, 39}, - {0x8029, 39}, - {0xc038, 39}, - {0x8003, 43}, - {0x8006, 43}, - {0x800a, 43}, - {0x800f, 43}, - {0x8018, 43}, - {0x801f, 43}, - {0x8029, 43}, - {0xc038, 43}, - }, - /* 81 */ - { - {0x8002, 124}, - {0x8009, 124}, - {0x8017, 124}, - {0xc028, 124}, - {0x8001, 35}, - {0xc016, 35}, - {0x8001, 62}, - {0xc016, 62}, - {0xc000, 0}, - {0xc000, 36}, - {0xc000, 64}, - {0xc000, 91}, - {0xc000, 93}, - {0xc000, 126}, - {0x5b, 0}, - {0x5c, 0}, - }, - /* 82 */ - { - {0x8003, 124}, - {0x8006, 124}, - {0x800a, 124}, - {0x800f, 124}, - {0x8018, 124}, - {0x801f, 124}, - {0x8029, 124}, - {0xc038, 124}, - {0x8002, 35}, - {0x8009, 35}, - {0x8017, 35}, - {0xc028, 35}, - {0x8002, 62}, - {0x8009, 62}, - {0x8017, 62}, - {0xc028, 62}, - }, - /* 83 */ - { - {0x8003, 35}, - {0x8006, 35}, - {0x800a, 35}, - {0x800f, 35}, - {0x8018, 35}, - {0x801f, 35}, - {0x8029, 35}, - {0xc038, 35}, - {0x8003, 62}, - {0x8006, 62}, - {0x800a, 62}, - {0x800f, 62}, - {0x8018, 62}, - {0x801f, 62}, - {0x8029, 62}, - {0xc038, 62}, - }, - /* 84 */ - { - {0x8001, 0}, - {0xc016, 0}, - {0x8001, 36}, - {0xc016, 36}, - {0x8001, 64}, - {0xc016, 64}, - {0x8001, 91}, - {0xc016, 91}, - {0x8001, 93}, - {0xc016, 93}, - {0x8001, 126}, - {0xc016, 126}, - {0xc000, 94}, - {0xc000, 125}, - {0x5d, 0}, - {0x5e, 0}, - }, - /* 85 */ - { - {0x8002, 0}, - {0x8009, 0}, - {0x8017, 0}, - {0xc028, 0}, - {0x8002, 36}, - {0x8009, 36}, - {0x8017, 36}, - {0xc028, 36}, - {0x8002, 64}, - {0x8009, 64}, - {0x8017, 64}, - {0xc028, 64}, - {0x8002, 91}, - {0x8009, 91}, - {0x8017, 91}, - {0xc028, 91}, - }, - /* 86 */ - { - {0x8003, 0}, - {0x8006, 0}, - {0x800a, 0}, - {0x800f, 0}, - {0x8018, 0}, - {0x801f, 0}, - {0x8029, 0}, - {0xc038, 0}, - {0x8003, 36}, - {0x8006, 36}, - {0x800a, 36}, - {0x800f, 36}, - {0x8018, 36}, - {0x801f, 36}, - {0x8029, 36}, - {0xc038, 36}, - }, - /* 87 */ - { - {0x8003, 64}, - {0x8006, 64}, - {0x800a, 64}, - {0x800f, 64}, - {0x8018, 64}, - {0x801f, 64}, - {0x8029, 64}, - {0xc038, 64}, - {0x8003, 91}, - {0x8006, 91}, - {0x800a, 91}, - {0x800f, 91}, - {0x8018, 91}, - {0x801f, 91}, - {0x8029, 91}, - {0xc038, 91}, - }, - /* 88 */ - { - {0x8002, 93}, - {0x8009, 93}, - {0x8017, 93}, - {0xc028, 93}, - {0x8002, 126}, - {0x8009, 126}, - {0x8017, 126}, - {0xc028, 126}, - {0x8001, 94}, - {0xc016, 94}, - {0x8001, 125}, - {0xc016, 125}, - {0xc000, 60}, - {0xc000, 96}, - {0xc000, 123}, - {0x5f, 0}, - }, - /* 89 */ - { - {0x8003, 93}, - {0x8006, 93}, - {0x800a, 93}, - {0x800f, 93}, - {0x8018, 93}, - {0x801f, 93}, - {0x8029, 93}, - {0xc038, 93}, - {0x8003, 126}, - {0x8006, 126}, - {0x800a, 126}, - {0x800f, 126}, - {0x8018, 126}, - {0x801f, 126}, - {0x8029, 126}, - {0xc038, 126}, - }, - /* 90 */ - { - {0x8002, 94}, - {0x8009, 94}, - {0x8017, 94}, - {0xc028, 94}, - {0x8002, 125}, - {0x8009, 125}, - {0x8017, 125}, - {0xc028, 125}, - {0x8001, 60}, - {0xc016, 60}, - {0x8001, 96}, - {0xc016, 96}, - {0x8001, 123}, - {0xc016, 123}, - {0x60, 0}, - {0x6e, 0}, - }, - /* 91 */ - { - {0x8003, 94}, - {0x8006, 94}, - {0x800a, 94}, - {0x800f, 94}, - {0x8018, 94}, - {0x801f, 94}, - {0x8029, 94}, - {0xc038, 94}, - {0x8003, 125}, - {0x8006, 125}, - {0x800a, 125}, - {0x800f, 125}, - {0x8018, 125}, - {0x801f, 125}, - {0x8029, 125}, - {0xc038, 125}, - }, - /* 92 */ - { - {0x8002, 60}, - {0x8009, 60}, - {0x8017, 60}, - {0xc028, 60}, - {0x8002, 96}, - {0x8009, 96}, - {0x8017, 96}, - {0xc028, 96}, - {0x8002, 123}, - {0x8009, 123}, - {0x8017, 123}, - {0xc028, 123}, - {0x61, 0}, - {0x65, 0}, - {0x6f, 0}, - {0x85, 0}, - }, - /* 93 */ - { - {0x8003, 60}, - {0x8006, 60}, - {0x800a, 60}, - {0x800f, 60}, - {0x8018, 60}, - {0x801f, 60}, - {0x8029, 60}, - {0xc038, 60}, - {0x8003, 96}, - {0x8006, 96}, - {0x800a, 96}, - {0x800f, 96}, - {0x8018, 96}, - {0x801f, 96}, - {0x8029, 96}, - {0xc038, 96}, - }, - /* 94 */ - { - {0x8003, 123}, - {0x8006, 123}, - {0x800a, 123}, - {0x800f, 123}, - {0x8018, 123}, - {0x801f, 123}, - {0x8029, 123}, - {0xc038, 123}, - {0x62, 0}, - {0x63, 0}, - {0x66, 0}, - {0x69, 0}, - {0x70, 0}, - {0x77, 0}, - {0x86, 0}, - {0x99, 0}, - }, - /* 95 */ - { - {0xc000, 92}, - {0xc000, 195}, - {0xc000, 208}, - {0x64, 0}, - {0x67, 0}, - {0x68, 0}, - {0x6a, 0}, - {0x6b, 0}, - {0x71, 0}, - {0x74, 0}, - {0x78, 0}, - {0x7e, 0}, - {0x87, 0}, - {0x8e, 0}, - {0x9a, 0}, - {0xa9, 0}, - }, - /* 96 */ - { - {0x8001, 92}, - {0xc016, 92}, - {0x8001, 195}, - {0xc016, 195}, - {0x8001, 208}, - {0xc016, 208}, - {0xc000, 128}, - {0xc000, 130}, - {0xc000, 131}, - {0xc000, 162}, - {0xc000, 184}, - {0xc000, 194}, - {0xc000, 224}, - {0xc000, 226}, - {0x6c, 0}, - {0x6d, 0}, - }, - /* 97 */ - { - {0x8002, 92}, - {0x8009, 92}, - {0x8017, 92}, - {0xc028, 92}, - {0x8002, 195}, - {0x8009, 195}, - {0x8017, 195}, - {0xc028, 195}, - {0x8002, 208}, - {0x8009, 208}, - {0x8017, 208}, - {0xc028, 208}, - {0x8001, 128}, - {0xc016, 128}, - {0x8001, 130}, - {0xc016, 130}, - }, - /* 98 */ - { - {0x8003, 92}, - {0x8006, 92}, - {0x800a, 92}, - {0x800f, 92}, - {0x8018, 92}, - {0x801f, 92}, - {0x8029, 92}, - {0xc038, 92}, - {0x8003, 195}, - {0x8006, 195}, - {0x800a, 195}, - {0x800f, 195}, - {0x8018, 195}, - {0x801f, 195}, - {0x8029, 195}, - {0xc038, 195}, - }, - /* 99 */ - { - {0x8003, 208}, - {0x8006, 208}, - {0x800a, 208}, - {0x800f, 208}, - {0x8018, 208}, - {0x801f, 208}, - {0x8029, 208}, - {0xc038, 208}, - {0x8002, 128}, - {0x8009, 128}, - {0x8017, 128}, - {0xc028, 128}, - {0x8002, 130}, - {0x8009, 130}, - {0x8017, 130}, - {0xc028, 130}, - }, - /* 100 */ - { - {0x8003, 128}, - {0x8006, 128}, - {0x800a, 128}, - {0x800f, 128}, - {0x8018, 128}, - {0x801f, 128}, - {0x8029, 128}, - {0xc038, 128}, - {0x8003, 130}, - {0x8006, 130}, - {0x800a, 130}, - {0x800f, 130}, - {0x8018, 130}, - {0x801f, 130}, - {0x8029, 130}, - {0xc038, 130}, - }, - /* 101 */ - { - {0x8001, 131}, - {0xc016, 131}, - {0x8001, 162}, - {0xc016, 162}, - {0x8001, 184}, - {0xc016, 184}, - {0x8001, 194}, - {0xc016, 194}, - {0x8001, 224}, - {0xc016, 224}, - {0x8001, 226}, - {0xc016, 226}, - {0xc000, 153}, - {0xc000, 161}, - {0xc000, 167}, - {0xc000, 172}, - }, - /* 102 */ - { - {0x8002, 131}, - {0x8009, 131}, - {0x8017, 131}, - {0xc028, 131}, - {0x8002, 162}, - {0x8009, 162}, - {0x8017, 162}, - {0xc028, 162}, - {0x8002, 184}, - {0x8009, 184}, - {0x8017, 184}, - {0xc028, 184}, - {0x8002, 194}, - {0x8009, 194}, - {0x8017, 194}, - {0xc028, 194}, - }, - /* 103 */ - { - {0x8003, 131}, - {0x8006, 131}, - {0x800a, 131}, - {0x800f, 131}, - {0x8018, 131}, - {0x801f, 131}, - {0x8029, 131}, - {0xc038, 131}, - {0x8003, 162}, - {0x8006, 162}, - {0x800a, 162}, - {0x800f, 162}, - {0x8018, 162}, - {0x801f, 162}, - {0x8029, 162}, - {0xc038, 162}, - }, - /* 104 */ - { - {0x8003, 184}, - {0x8006, 184}, - {0x800a, 184}, - {0x800f, 184}, - {0x8018, 184}, - {0x801f, 184}, - {0x8029, 184}, - {0xc038, 184}, - {0x8003, 194}, - {0x8006, 194}, - {0x800a, 194}, - {0x800f, 194}, - {0x8018, 194}, - {0x801f, 194}, - {0x8029, 194}, - {0xc038, 194}, - }, - /* 105 */ - { - {0x8002, 224}, - {0x8009, 224}, - {0x8017, 224}, - {0xc028, 224}, - {0x8002, 226}, - {0x8009, 226}, - {0x8017, 226}, - {0xc028, 226}, - {0x8001, 153}, - {0xc016, 153}, - {0x8001, 161}, - {0xc016, 161}, - {0x8001, 167}, - {0xc016, 167}, - {0x8001, 172}, - {0xc016, 172}, - }, - /* 106 */ - { - {0x8003, 224}, - {0x8006, 224}, - {0x800a, 224}, - {0x800f, 224}, - {0x8018, 224}, - {0x801f, 224}, - {0x8029, 224}, - {0xc038, 224}, - {0x8003, 226}, - {0x8006, 226}, - {0x800a, 226}, - {0x800f, 226}, - {0x8018, 226}, - {0x801f, 226}, - {0x8029, 226}, - {0xc038, 226}, - }, - /* 107 */ - { - {0x8002, 153}, - {0x8009, 153}, - {0x8017, 153}, - {0xc028, 153}, - {0x8002, 161}, - {0x8009, 161}, - {0x8017, 161}, - {0xc028, 161}, - {0x8002, 167}, - {0x8009, 167}, - {0x8017, 167}, - {0xc028, 167}, - {0x8002, 172}, - {0x8009, 172}, - {0x8017, 172}, - {0xc028, 172}, - }, - /* 108 */ - { - {0x8003, 153}, - {0x8006, 153}, - {0x800a, 153}, - {0x800f, 153}, - {0x8018, 153}, - {0x801f, 153}, - {0x8029, 153}, - {0xc038, 153}, - {0x8003, 161}, - {0x8006, 161}, - {0x800a, 161}, - {0x800f, 161}, - {0x8018, 161}, - {0x801f, 161}, - {0x8029, 161}, - {0xc038, 161}, - }, - /* 109 */ - { - {0x8003, 167}, - {0x8006, 167}, - {0x800a, 167}, - {0x800f, 167}, - {0x8018, 167}, - {0x801f, 167}, - {0x8029, 167}, - {0xc038, 167}, - {0x8003, 172}, - {0x8006, 172}, - {0x800a, 172}, - {0x800f, 172}, - {0x8018, 172}, - {0x801f, 172}, - {0x8029, 172}, - {0xc038, 172}, - }, - /* 110 */ - { - {0x72, 0}, - {0x73, 0}, - {0x75, 0}, - {0x76, 0}, - {0x79, 0}, - {0x7b, 0}, - {0x7f, 0}, - {0x82, 0}, - {0x88, 0}, - {0x8b, 0}, - {0x8f, 0}, - {0x92, 0}, - {0x9b, 0}, - {0xa2, 0}, - {0xaa, 0}, - {0xb4, 0}, - }, - /* 111 */ - { - {0xc000, 176}, - {0xc000, 177}, - {0xc000, 179}, - {0xc000, 209}, - {0xc000, 216}, - {0xc000, 217}, - {0xc000, 227}, - {0xc000, 229}, - {0xc000, 230}, - {0x7a, 0}, - {0x7c, 0}, - {0x7d, 0}, - {0x80, 0}, - {0x81, 0}, - {0x83, 0}, - {0x84, 0}, - }, - /* 112 */ - { - {0x8001, 176}, - {0xc016, 176}, - {0x8001, 177}, - {0xc016, 177}, - {0x8001, 179}, - {0xc016, 179}, - {0x8001, 209}, - {0xc016, 209}, - {0x8001, 216}, - {0xc016, 216}, - {0x8001, 217}, - {0xc016, 217}, - {0x8001, 227}, - {0xc016, 227}, - {0x8001, 229}, - {0xc016, 229}, - }, - /* 113 */ - { - {0x8002, 176}, - {0x8009, 176}, - {0x8017, 176}, - {0xc028, 176}, - {0x8002, 177}, - {0x8009, 177}, - {0x8017, 177}, - {0xc028, 177}, - {0x8002, 179}, - {0x8009, 179}, - {0x8017, 179}, - {0xc028, 179}, - {0x8002, 209}, - {0x8009, 209}, - {0x8017, 209}, - {0xc028, 209}, - }, - /* 114 */ - { - {0x8003, 176}, - {0x8006, 176}, - {0x800a, 176}, - {0x800f, 176}, - {0x8018, 176}, - {0x801f, 176}, - {0x8029, 176}, - {0xc038, 176}, - {0x8003, 177}, - {0x8006, 177}, - {0x800a, 177}, - {0x800f, 177}, - {0x8018, 177}, - {0x801f, 177}, - {0x8029, 177}, - {0xc038, 177}, - }, - /* 115 */ - { - {0x8003, 179}, - {0x8006, 179}, - {0x800a, 179}, - {0x800f, 179}, - {0x8018, 179}, - {0x801f, 179}, - {0x8029, 179}, - {0xc038, 179}, - {0x8003, 209}, - {0x8006, 209}, - {0x800a, 209}, - {0x800f, 209}, - {0x8018, 209}, - {0x801f, 209}, - {0x8029, 209}, - {0xc038, 209}, - }, - /* 116 */ - { - {0x8002, 216}, - {0x8009, 216}, - {0x8017, 216}, - {0xc028, 216}, - {0x8002, 217}, - {0x8009, 217}, - {0x8017, 217}, - {0xc028, 217}, - {0x8002, 227}, - {0x8009, 227}, - {0x8017, 227}, - {0xc028, 227}, - {0x8002, 229}, - {0x8009, 229}, - {0x8017, 229}, - {0xc028, 229}, - }, - /* 117 */ - { - {0x8003, 216}, - {0x8006, 216}, - {0x800a, 216}, - {0x800f, 216}, - {0x8018, 216}, - {0x801f, 216}, - {0x8029, 216}, - {0xc038, 216}, - {0x8003, 217}, - {0x8006, 217}, - {0x800a, 217}, - {0x800f, 217}, - {0x8018, 217}, - {0x801f, 217}, - {0x8029, 217}, - {0xc038, 217}, - }, - /* 118 */ - { - {0x8003, 227}, - {0x8006, 227}, - {0x800a, 227}, - {0x800f, 227}, - {0x8018, 227}, - {0x801f, 227}, - {0x8029, 227}, - {0xc038, 227}, - {0x8003, 229}, - {0x8006, 229}, - {0x800a, 229}, - {0x800f, 229}, - {0x8018, 229}, - {0x801f, 229}, - {0x8029, 229}, - {0xc038, 229}, - }, - /* 119 */ - { - {0x8001, 230}, - {0xc016, 230}, - {0xc000, 129}, - {0xc000, 132}, - {0xc000, 133}, - {0xc000, 134}, - {0xc000, 136}, - {0xc000, 146}, - {0xc000, 154}, - {0xc000, 156}, - {0xc000, 160}, - {0xc000, 163}, - {0xc000, 164}, - {0xc000, 169}, - {0xc000, 170}, - {0xc000, 173}, - }, - /* 120 */ - { - {0x8002, 230}, - {0x8009, 230}, - {0x8017, 230}, - {0xc028, 230}, - {0x8001, 129}, - {0xc016, 129}, - {0x8001, 132}, - {0xc016, 132}, - {0x8001, 133}, - {0xc016, 133}, - {0x8001, 134}, - {0xc016, 134}, - {0x8001, 136}, - {0xc016, 136}, - {0x8001, 146}, - {0xc016, 146}, - }, - /* 121 */ - { - {0x8003, 230}, - {0x8006, 230}, - {0x800a, 230}, - {0x800f, 230}, - {0x8018, 230}, - {0x801f, 230}, - {0x8029, 230}, - {0xc038, 230}, - {0x8002, 129}, - {0x8009, 129}, - {0x8017, 129}, - {0xc028, 129}, - {0x8002, 132}, - {0x8009, 132}, - {0x8017, 132}, - {0xc028, 132}, - }, - /* 122 */ - { - {0x8003, 129}, - {0x8006, 129}, - {0x800a, 129}, - {0x800f, 129}, - {0x8018, 129}, - {0x801f, 129}, - {0x8029, 129}, - {0xc038, 129}, - {0x8003, 132}, - {0x8006, 132}, - {0x800a, 132}, - {0x800f, 132}, - {0x8018, 132}, - {0x801f, 132}, - {0x8029, 132}, - {0xc038, 132}, - }, - /* 123 */ - { - {0x8002, 133}, - {0x8009, 133}, - {0x8017, 133}, - {0xc028, 133}, - {0x8002, 134}, - {0x8009, 134}, - {0x8017, 134}, - {0xc028, 134}, - {0x8002, 136}, - {0x8009, 136}, - {0x8017, 136}, - {0xc028, 136}, - {0x8002, 146}, - {0x8009, 146}, - {0x8017, 146}, - {0xc028, 146}, - }, - /* 124 */ - { - {0x8003, 133}, - {0x8006, 133}, - {0x800a, 133}, - {0x800f, 133}, - {0x8018, 133}, - {0x801f, 133}, - {0x8029, 133}, - {0xc038, 133}, - {0x8003, 134}, - {0x8006, 134}, - {0x800a, 134}, - {0x800f, 134}, - {0x8018, 134}, - {0x801f, 134}, - {0x8029, 134}, - {0xc038, 134}, - }, - /* 125 */ - { - {0x8003, 136}, - {0x8006, 136}, - {0x800a, 136}, - {0x800f, 136}, - {0x8018, 136}, - {0x801f, 136}, - {0x8029, 136}, - {0xc038, 136}, - {0x8003, 146}, - {0x8006, 146}, - {0x800a, 146}, - {0x800f, 146}, - {0x8018, 146}, - {0x801f, 146}, - {0x8029, 146}, - {0xc038, 146}, - }, - /* 126 */ - { - {0x8001, 154}, - {0xc016, 154}, - {0x8001, 156}, - {0xc016, 156}, - {0x8001, 160}, - {0xc016, 160}, - {0x8001, 163}, - {0xc016, 163}, - {0x8001, 164}, - {0xc016, 164}, - {0x8001, 169}, - {0xc016, 169}, - {0x8001, 170}, - {0xc016, 170}, - {0x8001, 173}, - {0xc016, 173}, - }, - /* 127 */ - { - {0x8002, 154}, - {0x8009, 154}, - {0x8017, 154}, - {0xc028, 154}, - {0x8002, 156}, - {0x8009, 156}, - {0x8017, 156}, - {0xc028, 156}, - {0x8002, 160}, - {0x8009, 160}, - {0x8017, 160}, - {0xc028, 160}, - {0x8002, 163}, - {0x8009, 163}, - {0x8017, 163}, - {0xc028, 163}, - }, - /* 128 */ - { - {0x8003, 154}, - {0x8006, 154}, - {0x800a, 154}, - {0x800f, 154}, - {0x8018, 154}, - {0x801f, 154}, - {0x8029, 154}, - {0xc038, 154}, - {0x8003, 156}, - {0x8006, 156}, - {0x800a, 156}, - {0x800f, 156}, - {0x8018, 156}, - {0x801f, 156}, - {0x8029, 156}, - {0xc038, 156}, - }, - /* 129 */ - { - {0x8003, 160}, - {0x8006, 160}, - {0x800a, 160}, - {0x800f, 160}, - {0x8018, 160}, - {0x801f, 160}, - {0x8029, 160}, - {0xc038, 160}, - {0x8003, 163}, - {0x8006, 163}, - {0x800a, 163}, - {0x800f, 163}, - {0x8018, 163}, - {0x801f, 163}, - {0x8029, 163}, - {0xc038, 163}, - }, - /* 130 */ - { - {0x8002, 164}, - {0x8009, 164}, - {0x8017, 164}, - {0xc028, 164}, - {0x8002, 169}, - {0x8009, 169}, - {0x8017, 169}, - {0xc028, 169}, - {0x8002, 170}, - {0x8009, 170}, - {0x8017, 170}, - {0xc028, 170}, - {0x8002, 173}, - {0x8009, 173}, - {0x8017, 173}, - {0xc028, 173}, - }, - /* 131 */ - { - {0x8003, 164}, - {0x8006, 164}, - {0x800a, 164}, - {0x800f, 164}, - {0x8018, 164}, - {0x801f, 164}, - {0x8029, 164}, - {0xc038, 164}, - {0x8003, 169}, - {0x8006, 169}, - {0x800a, 169}, - {0x800f, 169}, - {0x8018, 169}, - {0x801f, 169}, - {0x8029, 169}, - {0xc038, 169}, - }, - /* 132 */ - { - {0x8003, 170}, - {0x8006, 170}, - {0x800a, 170}, - {0x800f, 170}, - {0x8018, 170}, - {0x801f, 170}, - {0x8029, 170}, - {0xc038, 170}, - {0x8003, 173}, - {0x8006, 173}, - {0x800a, 173}, - {0x800f, 173}, - {0x8018, 173}, - {0x801f, 173}, - {0x8029, 173}, - {0xc038, 173}, - }, - /* 133 */ - { - {0x89, 0}, - {0x8a, 0}, - {0x8c, 0}, - {0x8d, 0}, - {0x90, 0}, - {0x91, 0}, - {0x93, 0}, - {0x96, 0}, - {0x9c, 0}, - {0x9f, 0}, - {0xa3, 0}, - {0xa6, 0}, - {0xab, 0}, - {0xae, 0}, - {0xb5, 0}, - {0xbe, 0}, - }, - /* 134 */ - { - {0xc000, 178}, - {0xc000, 181}, - {0xc000, 185}, - {0xc000, 186}, - {0xc000, 187}, - {0xc000, 189}, - {0xc000, 190}, - {0xc000, 196}, - {0xc000, 198}, - {0xc000, 228}, - {0xc000, 232}, - {0xc000, 233}, - {0x94, 0}, - {0x95, 0}, - {0x97, 0}, - {0x98, 0}, - }, - /* 135 */ - { - {0x8001, 178}, - {0xc016, 178}, - {0x8001, 181}, - {0xc016, 181}, - {0x8001, 185}, - {0xc016, 185}, - {0x8001, 186}, - {0xc016, 186}, - {0x8001, 187}, - {0xc016, 187}, - {0x8001, 189}, - {0xc016, 189}, - {0x8001, 190}, - {0xc016, 190}, - {0x8001, 196}, - {0xc016, 196}, - }, - /* 136 */ - { - {0x8002, 178}, - {0x8009, 178}, - {0x8017, 178}, - {0xc028, 178}, - {0x8002, 181}, - {0x8009, 181}, - {0x8017, 181}, - {0xc028, 181}, - {0x8002, 185}, - {0x8009, 185}, - {0x8017, 185}, - {0xc028, 185}, - {0x8002, 186}, - {0x8009, 186}, - {0x8017, 186}, - {0xc028, 186}, - }, - /* 137 */ - { - {0x8003, 178}, - {0x8006, 178}, - {0x800a, 178}, - {0x800f, 178}, - {0x8018, 178}, - {0x801f, 178}, - {0x8029, 178}, - {0xc038, 178}, - {0x8003, 181}, - {0x8006, 181}, - {0x800a, 181}, - {0x800f, 181}, - {0x8018, 181}, - {0x801f, 181}, - {0x8029, 181}, - {0xc038, 181}, - }, - /* 138 */ - { - {0x8003, 185}, - {0x8006, 185}, - {0x800a, 185}, - {0x800f, 185}, - {0x8018, 185}, - {0x801f, 185}, - {0x8029, 185}, - {0xc038, 185}, - {0x8003, 186}, - {0x8006, 186}, - {0x800a, 186}, - {0x800f, 186}, - {0x8018, 186}, - {0x801f, 186}, - {0x8029, 186}, - {0xc038, 186}, - }, - /* 139 */ - { - {0x8002, 187}, - {0x8009, 187}, - {0x8017, 187}, - {0xc028, 187}, - {0x8002, 189}, - {0x8009, 189}, - {0x8017, 189}, - {0xc028, 189}, - {0x8002, 190}, - {0x8009, 190}, - {0x8017, 190}, - {0xc028, 190}, - {0x8002, 196}, - {0x8009, 196}, - {0x8017, 196}, - {0xc028, 196}, - }, - /* 140 */ - { - {0x8003, 187}, - {0x8006, 187}, - {0x800a, 187}, - {0x800f, 187}, - {0x8018, 187}, - {0x801f, 187}, - {0x8029, 187}, - {0xc038, 187}, - {0x8003, 189}, - {0x8006, 189}, - {0x800a, 189}, - {0x800f, 189}, - {0x8018, 189}, - {0x801f, 189}, - {0x8029, 189}, - {0xc038, 189}, - }, - /* 141 */ - { - {0x8003, 190}, - {0x8006, 190}, - {0x800a, 190}, - {0x800f, 190}, - {0x8018, 190}, - {0x801f, 190}, - {0x8029, 190}, - {0xc038, 190}, - {0x8003, 196}, - {0x8006, 196}, - {0x800a, 196}, - {0x800f, 196}, - {0x8018, 196}, - {0x801f, 196}, - {0x8029, 196}, - {0xc038, 196}, - }, - /* 142 */ - { - {0x8001, 198}, - {0xc016, 198}, - {0x8001, 228}, - {0xc016, 228}, - {0x8001, 232}, - {0xc016, 232}, - {0x8001, 233}, - {0xc016, 233}, - {0xc000, 1}, - {0xc000, 135}, - {0xc000, 137}, - {0xc000, 138}, - {0xc000, 139}, - {0xc000, 140}, - {0xc000, 141}, - {0xc000, 143}, - }, - /* 143 */ - { - {0x8002, 198}, - {0x8009, 198}, - {0x8017, 198}, - {0xc028, 198}, - {0x8002, 228}, - {0x8009, 228}, - {0x8017, 228}, - {0xc028, 228}, - {0x8002, 232}, - {0x8009, 232}, - {0x8017, 232}, - {0xc028, 232}, - {0x8002, 233}, - {0x8009, 233}, - {0x8017, 233}, - {0xc028, 233}, - }, - /* 144 */ - { - {0x8003, 198}, - {0x8006, 198}, - {0x800a, 198}, - {0x800f, 198}, - {0x8018, 198}, - {0x801f, 198}, - {0x8029, 198}, - {0xc038, 198}, - {0x8003, 228}, - {0x8006, 228}, - {0x800a, 228}, - {0x800f, 228}, - {0x8018, 228}, - {0x801f, 228}, - {0x8029, 228}, - {0xc038, 228}, - }, - /* 145 */ - { - {0x8003, 232}, - {0x8006, 232}, - {0x800a, 232}, - {0x800f, 232}, - {0x8018, 232}, - {0x801f, 232}, - {0x8029, 232}, - {0xc038, 232}, - {0x8003, 233}, - {0x8006, 233}, - {0x800a, 233}, - {0x800f, 233}, - {0x8018, 233}, - {0x801f, 233}, - {0x8029, 233}, - {0xc038, 233}, - }, - /* 146 */ - { - {0x8001, 1}, - {0xc016, 1}, - {0x8001, 135}, - {0xc016, 135}, - {0x8001, 137}, - {0xc016, 137}, - {0x8001, 138}, - {0xc016, 138}, - {0x8001, 139}, - {0xc016, 139}, - {0x8001, 140}, - {0xc016, 140}, - {0x8001, 141}, - {0xc016, 141}, - {0x8001, 143}, - {0xc016, 143}, - }, - /* 147 */ - { - {0x8002, 1}, - {0x8009, 1}, - {0x8017, 1}, - {0xc028, 1}, - {0x8002, 135}, - {0x8009, 135}, - {0x8017, 135}, - {0xc028, 135}, - {0x8002, 137}, - {0x8009, 137}, - {0x8017, 137}, - {0xc028, 137}, - {0x8002, 138}, - {0x8009, 138}, - {0x8017, 138}, - {0xc028, 138}, - }, - /* 148 */ - { - {0x8003, 1}, - {0x8006, 1}, - {0x800a, 1}, - {0x800f, 1}, - {0x8018, 1}, - {0x801f, 1}, - {0x8029, 1}, - {0xc038, 1}, - {0x8003, 135}, - {0x8006, 135}, - {0x800a, 135}, - {0x800f, 135}, - {0x8018, 135}, - {0x801f, 135}, - {0x8029, 135}, - {0xc038, 135}, - }, - /* 149 */ - { - {0x8003, 137}, - {0x8006, 137}, - {0x800a, 137}, - {0x800f, 137}, - {0x8018, 137}, - {0x801f, 137}, - {0x8029, 137}, - {0xc038, 137}, - {0x8003, 138}, - {0x8006, 138}, - {0x800a, 138}, - {0x800f, 138}, - {0x8018, 138}, - {0x801f, 138}, - {0x8029, 138}, - {0xc038, 138}, - }, - /* 150 */ - { - {0x8002, 139}, - {0x8009, 139}, - {0x8017, 139}, - {0xc028, 139}, - {0x8002, 140}, - {0x8009, 140}, - {0x8017, 140}, - {0xc028, 140}, - {0x8002, 141}, - {0x8009, 141}, - {0x8017, 141}, - {0xc028, 141}, - {0x8002, 143}, - {0x8009, 143}, - {0x8017, 143}, - {0xc028, 143}, - }, - /* 151 */ - { - {0x8003, 139}, - {0x8006, 139}, - {0x800a, 139}, - {0x800f, 139}, - {0x8018, 139}, - {0x801f, 139}, - {0x8029, 139}, - {0xc038, 139}, - {0x8003, 140}, - {0x8006, 140}, - {0x800a, 140}, - {0x800f, 140}, - {0x8018, 140}, - {0x801f, 140}, - {0x8029, 140}, - {0xc038, 140}, - }, - /* 152 */ - { - {0x8003, 141}, - {0x8006, 141}, - {0x800a, 141}, - {0x800f, 141}, - {0x8018, 141}, - {0x801f, 141}, - {0x8029, 141}, - {0xc038, 141}, - {0x8003, 143}, - {0x8006, 143}, - {0x800a, 143}, - {0x800f, 143}, - {0x8018, 143}, - {0x801f, 143}, - {0x8029, 143}, - {0xc038, 143}, - }, - /* 153 */ - { - {0x9d, 0}, - {0x9e, 0}, - {0xa0, 0}, - {0xa1, 0}, - {0xa4, 0}, - {0xa5, 0}, - {0xa7, 0}, - {0xa8, 0}, - {0xac, 0}, - {0xad, 0}, - {0xaf, 0}, - {0xb1, 0}, - {0xb6, 0}, - {0xb9, 0}, - {0xbf, 0}, - {0xcf, 0}, - }, - /* 154 */ - { - {0xc000, 147}, - {0xc000, 149}, - {0xc000, 150}, - {0xc000, 151}, - {0xc000, 152}, - {0xc000, 155}, - {0xc000, 157}, - {0xc000, 158}, - {0xc000, 165}, - {0xc000, 166}, - {0xc000, 168}, - {0xc000, 174}, - {0xc000, 175}, - {0xc000, 180}, - {0xc000, 182}, - {0xc000, 183}, - }, - /* 155 */ - { - {0x8001, 147}, - {0xc016, 147}, - {0x8001, 149}, - {0xc016, 149}, - {0x8001, 150}, - {0xc016, 150}, - {0x8001, 151}, - {0xc016, 151}, - {0x8001, 152}, - {0xc016, 152}, - {0x8001, 155}, - {0xc016, 155}, - {0x8001, 157}, - {0xc016, 157}, - {0x8001, 158}, - {0xc016, 158}, - }, - /* 156 */ - { - {0x8002, 147}, - {0x8009, 147}, - {0x8017, 147}, - {0xc028, 147}, - {0x8002, 149}, - {0x8009, 149}, - {0x8017, 149}, - {0xc028, 149}, - {0x8002, 150}, - {0x8009, 150}, - {0x8017, 150}, - {0xc028, 150}, - {0x8002, 151}, - {0x8009, 151}, - {0x8017, 151}, - {0xc028, 151}, - }, - /* 157 */ - { - {0x8003, 147}, - {0x8006, 147}, - {0x800a, 147}, - {0x800f, 147}, - {0x8018, 147}, - {0x801f, 147}, - {0x8029, 147}, - {0xc038, 147}, - {0x8003, 149}, - {0x8006, 149}, - {0x800a, 149}, - {0x800f, 149}, - {0x8018, 149}, - {0x801f, 149}, - {0x8029, 149}, - {0xc038, 149}, - }, - /* 158 */ - { - {0x8003, 150}, - {0x8006, 150}, - {0x800a, 150}, - {0x800f, 150}, - {0x8018, 150}, - {0x801f, 150}, - {0x8029, 150}, - {0xc038, 150}, - {0x8003, 151}, - {0x8006, 151}, - {0x800a, 151}, - {0x800f, 151}, - {0x8018, 151}, - {0x801f, 151}, - {0x8029, 151}, - {0xc038, 151}, - }, - /* 159 */ - { - {0x8002, 152}, - {0x8009, 152}, - {0x8017, 152}, - {0xc028, 152}, - {0x8002, 155}, - {0x8009, 155}, - {0x8017, 155}, - {0xc028, 155}, - {0x8002, 157}, - {0x8009, 157}, - {0x8017, 157}, - {0xc028, 157}, - {0x8002, 158}, - {0x8009, 158}, - {0x8017, 158}, - {0xc028, 158}, - }, - /* 160 */ - { - {0x8003, 152}, - {0x8006, 152}, - {0x800a, 152}, - {0x800f, 152}, - {0x8018, 152}, - {0x801f, 152}, - {0x8029, 152}, - {0xc038, 152}, - {0x8003, 155}, - {0x8006, 155}, - {0x800a, 155}, - {0x800f, 155}, - {0x8018, 155}, - {0x801f, 155}, - {0x8029, 155}, - {0xc038, 155}, - }, - /* 161 */ - { - {0x8003, 157}, - {0x8006, 157}, - {0x800a, 157}, - {0x800f, 157}, - {0x8018, 157}, - {0x801f, 157}, - {0x8029, 157}, - {0xc038, 157}, - {0x8003, 158}, - {0x8006, 158}, - {0x800a, 158}, - {0x800f, 158}, - {0x8018, 158}, - {0x801f, 158}, - {0x8029, 158}, - {0xc038, 158}, - }, - /* 162 */ - { - {0x8001, 165}, - {0xc016, 165}, - {0x8001, 166}, - {0xc016, 166}, - {0x8001, 168}, - {0xc016, 168}, - {0x8001, 174}, - {0xc016, 174}, - {0x8001, 175}, - {0xc016, 175}, - {0x8001, 180}, - {0xc016, 180}, - {0x8001, 182}, - {0xc016, 182}, - {0x8001, 183}, - {0xc016, 183}, - }, - /* 163 */ - { - {0x8002, 165}, - {0x8009, 165}, - {0x8017, 165}, - {0xc028, 165}, - {0x8002, 166}, - {0x8009, 166}, - {0x8017, 166}, - {0xc028, 166}, - {0x8002, 168}, - {0x8009, 168}, - {0x8017, 168}, - {0xc028, 168}, - {0x8002, 174}, - {0x8009, 174}, - {0x8017, 174}, - {0xc028, 174}, - }, - /* 164 */ - { - {0x8003, 165}, - {0x8006, 165}, - {0x800a, 165}, - {0x800f, 165}, - {0x8018, 165}, - {0x801f, 165}, - {0x8029, 165}, - {0xc038, 165}, - {0x8003, 166}, - {0x8006, 166}, - {0x800a, 166}, - {0x800f, 166}, - {0x8018, 166}, - {0x801f, 166}, - {0x8029, 166}, - {0xc038, 166}, - }, - /* 165 */ - { - {0x8003, 168}, - {0x8006, 168}, - {0x800a, 168}, - {0x800f, 168}, - {0x8018, 168}, - {0x801f, 168}, - {0x8029, 168}, - {0xc038, 168}, - {0x8003, 174}, - {0x8006, 174}, - {0x800a, 174}, - {0x800f, 174}, - {0x8018, 174}, - {0x801f, 174}, - {0x8029, 174}, - {0xc038, 174}, - }, - /* 166 */ - { - {0x8002, 175}, - {0x8009, 175}, - {0x8017, 175}, - {0xc028, 175}, - {0x8002, 180}, - {0x8009, 180}, - {0x8017, 180}, - {0xc028, 180}, - {0x8002, 182}, - {0x8009, 182}, - {0x8017, 182}, - {0xc028, 182}, - {0x8002, 183}, - {0x8009, 183}, - {0x8017, 183}, - {0xc028, 183}, - }, - /* 167 */ - { - {0x8003, 175}, - {0x8006, 175}, - {0x800a, 175}, - {0x800f, 175}, - {0x8018, 175}, - {0x801f, 175}, - {0x8029, 175}, - {0xc038, 175}, - {0x8003, 180}, - {0x8006, 180}, - {0x800a, 180}, - {0x800f, 180}, - {0x8018, 180}, - {0x801f, 180}, - {0x8029, 180}, - {0xc038, 180}, - }, - /* 168 */ - { - {0x8003, 182}, - {0x8006, 182}, - {0x800a, 182}, - {0x800f, 182}, - {0x8018, 182}, - {0x801f, 182}, - {0x8029, 182}, - {0xc038, 182}, - {0x8003, 183}, - {0x8006, 183}, - {0x800a, 183}, - {0x800f, 183}, - {0x8018, 183}, - {0x801f, 183}, - {0x8029, 183}, - {0xc038, 183}, - }, - /* 169 */ - { - {0xc000, 188}, - {0xc000, 191}, - {0xc000, 197}, - {0xc000, 231}, - {0xc000, 239}, - {0xb0, 0}, - {0xb2, 0}, - {0xb3, 0}, - {0xb7, 0}, - {0xb8, 0}, - {0xba, 0}, - {0xbb, 0}, - {0xc0, 0}, - {0xc7, 0}, - {0xd0, 0}, - {0xdf, 0}, - }, - /* 170 */ - { - {0x8001, 188}, - {0xc016, 188}, - {0x8001, 191}, - {0xc016, 191}, - {0x8001, 197}, - {0xc016, 197}, - {0x8001, 231}, - {0xc016, 231}, - {0x8001, 239}, - {0xc016, 239}, - {0xc000, 9}, - {0xc000, 142}, - {0xc000, 144}, - {0xc000, 145}, - {0xc000, 148}, - {0xc000, 159}, - }, - /* 171 */ - { - {0x8002, 188}, - {0x8009, 188}, - {0x8017, 188}, - {0xc028, 188}, - {0x8002, 191}, - {0x8009, 191}, - {0x8017, 191}, - {0xc028, 191}, - {0x8002, 197}, - {0x8009, 197}, - {0x8017, 197}, - {0xc028, 197}, - {0x8002, 231}, - {0x8009, 231}, - {0x8017, 231}, - {0xc028, 231}, - }, - /* 172 */ - { - {0x8003, 188}, - {0x8006, 188}, - {0x800a, 188}, - {0x800f, 188}, - {0x8018, 188}, - {0x801f, 188}, - {0x8029, 188}, - {0xc038, 188}, - {0x8003, 191}, - {0x8006, 191}, - {0x800a, 191}, - {0x800f, 191}, - {0x8018, 191}, - {0x801f, 191}, - {0x8029, 191}, - {0xc038, 191}, - }, - /* 173 */ - { - {0x8003, 197}, - {0x8006, 197}, - {0x800a, 197}, - {0x800f, 197}, - {0x8018, 197}, - {0x801f, 197}, - {0x8029, 197}, - {0xc038, 197}, - {0x8003, 231}, - {0x8006, 231}, - {0x800a, 231}, - {0x800f, 231}, - {0x8018, 231}, - {0x801f, 231}, - {0x8029, 231}, - {0xc038, 231}, - }, - /* 174 */ - { - {0x8002, 239}, - {0x8009, 239}, - {0x8017, 239}, - {0xc028, 239}, - {0x8001, 9}, - {0xc016, 9}, - {0x8001, 142}, - {0xc016, 142}, - {0x8001, 144}, - {0xc016, 144}, - {0x8001, 145}, - {0xc016, 145}, - {0x8001, 148}, - {0xc016, 148}, - {0x8001, 159}, - {0xc016, 159}, - }, - /* 175 */ - { - {0x8003, 239}, - {0x8006, 239}, - {0x800a, 239}, - {0x800f, 239}, - {0x8018, 239}, - {0x801f, 239}, - {0x8029, 239}, - {0xc038, 239}, - {0x8002, 9}, - {0x8009, 9}, - {0x8017, 9}, - {0xc028, 9}, - {0x8002, 142}, - {0x8009, 142}, - {0x8017, 142}, - {0xc028, 142}, - }, - /* 176 */ - { - {0x8003, 9}, - {0x8006, 9}, - {0x800a, 9}, - {0x800f, 9}, - {0x8018, 9}, - {0x801f, 9}, - {0x8029, 9}, - {0xc038, 9}, - {0x8003, 142}, - {0x8006, 142}, - {0x800a, 142}, - {0x800f, 142}, - {0x8018, 142}, - {0x801f, 142}, - {0x8029, 142}, - {0xc038, 142}, - }, - /* 177 */ - { - {0x8002, 144}, - {0x8009, 144}, - {0x8017, 144}, - {0xc028, 144}, - {0x8002, 145}, - {0x8009, 145}, - {0x8017, 145}, - {0xc028, 145}, - {0x8002, 148}, - {0x8009, 148}, - {0x8017, 148}, - {0xc028, 148}, - {0x8002, 159}, - {0x8009, 159}, - {0x8017, 159}, - {0xc028, 159}, - }, - /* 178 */ - { - {0x8003, 144}, - {0x8006, 144}, - {0x800a, 144}, - {0x800f, 144}, - {0x8018, 144}, - {0x801f, 144}, - {0x8029, 144}, - {0xc038, 144}, - {0x8003, 145}, - {0x8006, 145}, - {0x800a, 145}, - {0x800f, 145}, - {0x8018, 145}, - {0x801f, 145}, - {0x8029, 145}, - {0xc038, 145}, - }, - /* 179 */ - { - {0x8003, 148}, - {0x8006, 148}, - {0x800a, 148}, - {0x800f, 148}, - {0x8018, 148}, - {0x801f, 148}, - {0x8029, 148}, - {0xc038, 148}, - {0x8003, 159}, - {0x8006, 159}, - {0x800a, 159}, - {0x800f, 159}, - {0x8018, 159}, - {0x801f, 159}, - {0x8029, 159}, - {0xc038, 159}, - }, - /* 180 */ - { - {0xc000, 171}, - {0xc000, 206}, - {0xc000, 215}, - {0xc000, 225}, - {0xc000, 236}, - {0xc000, 237}, - {0xbc, 0}, - {0xbd, 0}, - {0xc1, 0}, - {0xc4, 0}, - {0xc8, 0}, - {0xcb, 0}, - {0xd1, 0}, - {0xd8, 0}, - {0xe0, 0}, - {0xee, 0}, - }, - /* 181 */ - { - {0x8001, 171}, - {0xc016, 171}, - {0x8001, 206}, - {0xc016, 206}, - {0x8001, 215}, - {0xc016, 215}, - {0x8001, 225}, - {0xc016, 225}, - {0x8001, 236}, - {0xc016, 236}, - {0x8001, 237}, - {0xc016, 237}, - {0xc000, 199}, - {0xc000, 207}, - {0xc000, 234}, - {0xc000, 235}, - }, - /* 182 */ - { - {0x8002, 171}, - {0x8009, 171}, - {0x8017, 171}, - {0xc028, 171}, - {0x8002, 206}, - {0x8009, 206}, - {0x8017, 206}, - {0xc028, 206}, - {0x8002, 215}, - {0x8009, 215}, - {0x8017, 215}, - {0xc028, 215}, - {0x8002, 225}, - {0x8009, 225}, - {0x8017, 225}, - {0xc028, 225}, - }, - /* 183 */ - { - {0x8003, 171}, - {0x8006, 171}, - {0x800a, 171}, - {0x800f, 171}, - {0x8018, 171}, - {0x801f, 171}, - {0x8029, 171}, - {0xc038, 171}, - {0x8003, 206}, - {0x8006, 206}, - {0x800a, 206}, - {0x800f, 206}, - {0x8018, 206}, - {0x801f, 206}, - {0x8029, 206}, - {0xc038, 206}, - }, - /* 184 */ - { - {0x8003, 215}, - {0x8006, 215}, - {0x800a, 215}, - {0x800f, 215}, - {0x8018, 215}, - {0x801f, 215}, - {0x8029, 215}, - {0xc038, 215}, - {0x8003, 225}, - {0x8006, 225}, - {0x800a, 225}, - {0x800f, 225}, - {0x8018, 225}, - {0x801f, 225}, - {0x8029, 225}, - {0xc038, 225}, - }, - /* 185 */ - { - {0x8002, 236}, - {0x8009, 236}, - {0x8017, 236}, - {0xc028, 236}, - {0x8002, 237}, - {0x8009, 237}, - {0x8017, 237}, - {0xc028, 237}, - {0x8001, 199}, - {0xc016, 199}, - {0x8001, 207}, - {0xc016, 207}, - {0x8001, 234}, - {0xc016, 234}, - {0x8001, 235}, - {0xc016, 235}, - }, - /* 186 */ - { - {0x8003, 236}, - {0x8006, 236}, - {0x800a, 236}, - {0x800f, 236}, - {0x8018, 236}, - {0x801f, 236}, - {0x8029, 236}, - {0xc038, 236}, - {0x8003, 237}, - {0x8006, 237}, - {0x800a, 237}, - {0x800f, 237}, - {0x8018, 237}, - {0x801f, 237}, - {0x8029, 237}, - {0xc038, 237}, - }, - /* 187 */ - { - {0x8002, 199}, - {0x8009, 199}, - {0x8017, 199}, - {0xc028, 199}, - {0x8002, 207}, - {0x8009, 207}, - {0x8017, 207}, - {0xc028, 207}, - {0x8002, 234}, - {0x8009, 234}, - {0x8017, 234}, - {0xc028, 234}, - {0x8002, 235}, - {0x8009, 235}, - {0x8017, 235}, - {0xc028, 235}, - }, - /* 188 */ - { - {0x8003, 199}, - {0x8006, 199}, - {0x800a, 199}, - {0x800f, 199}, - {0x8018, 199}, - {0x801f, 199}, - {0x8029, 199}, - {0xc038, 199}, - {0x8003, 207}, - {0x8006, 207}, - {0x800a, 207}, - {0x800f, 207}, - {0x8018, 207}, - {0x801f, 207}, - {0x8029, 207}, - {0xc038, 207}, - }, - /* 189 */ - { - {0x8003, 234}, - {0x8006, 234}, - {0x800a, 234}, - {0x800f, 234}, - {0x8018, 234}, - {0x801f, 234}, - {0x8029, 234}, - {0xc038, 234}, - {0x8003, 235}, - {0x8006, 235}, - {0x800a, 235}, - {0x800f, 235}, - {0x8018, 235}, - {0x801f, 235}, - {0x8029, 235}, - {0xc038, 235}, - }, - /* 190 */ - { - {0xc2, 0}, - {0xc3, 0}, - {0xc5, 0}, - {0xc6, 0}, - {0xc9, 0}, - {0xca, 0}, - {0xcc, 0}, - {0xcd, 0}, - {0xd2, 0}, - {0xd5, 0}, - {0xd9, 0}, - {0xdc, 0}, - {0xe1, 0}, - {0xe7, 0}, - {0xef, 0}, - {0xf6, 0}, - }, - /* 191 */ - { - {0xc000, 192}, - {0xc000, 193}, - {0xc000, 200}, - {0xc000, 201}, - {0xc000, 202}, - {0xc000, 205}, - {0xc000, 210}, - {0xc000, 213}, - {0xc000, 218}, - {0xc000, 219}, - {0xc000, 238}, - {0xc000, 240}, - {0xc000, 242}, - {0xc000, 243}, - {0xc000, 255}, - {0xce, 0}, - }, - /* 192 */ - { - {0x8001, 192}, - {0xc016, 192}, - {0x8001, 193}, - {0xc016, 193}, - {0x8001, 200}, - {0xc016, 200}, - {0x8001, 201}, - {0xc016, 201}, - {0x8001, 202}, - {0xc016, 202}, - {0x8001, 205}, - {0xc016, 205}, - {0x8001, 210}, - {0xc016, 210}, - {0x8001, 213}, - {0xc016, 213}, - }, - /* 193 */ - { - {0x8002, 192}, - {0x8009, 192}, - {0x8017, 192}, - {0xc028, 192}, - {0x8002, 193}, - {0x8009, 193}, - {0x8017, 193}, - {0xc028, 193}, - {0x8002, 200}, - {0x8009, 200}, - {0x8017, 200}, - {0xc028, 200}, - {0x8002, 201}, - {0x8009, 201}, - {0x8017, 201}, - {0xc028, 201}, - }, - /* 194 */ - { - {0x8003, 192}, - {0x8006, 192}, - {0x800a, 192}, - {0x800f, 192}, - {0x8018, 192}, - {0x801f, 192}, - {0x8029, 192}, - {0xc038, 192}, - {0x8003, 193}, - {0x8006, 193}, - {0x800a, 193}, - {0x800f, 193}, - {0x8018, 193}, - {0x801f, 193}, - {0x8029, 193}, - {0xc038, 193}, - }, - /* 195 */ - { - {0x8003, 200}, - {0x8006, 200}, - {0x800a, 200}, - {0x800f, 200}, - {0x8018, 200}, - {0x801f, 200}, - {0x8029, 200}, - {0xc038, 200}, - {0x8003, 201}, - {0x8006, 201}, - {0x800a, 201}, - {0x800f, 201}, - {0x8018, 201}, - {0x801f, 201}, - {0x8029, 201}, - {0xc038, 201}, - }, - /* 196 */ - { - {0x8002, 202}, - {0x8009, 202}, - {0x8017, 202}, - {0xc028, 202}, - {0x8002, 205}, - {0x8009, 205}, - {0x8017, 205}, - {0xc028, 205}, - {0x8002, 210}, - {0x8009, 210}, - {0x8017, 210}, - {0xc028, 210}, - {0x8002, 213}, - {0x8009, 213}, - {0x8017, 213}, - {0xc028, 213}, - }, - /* 197 */ - { - {0x8003, 202}, - {0x8006, 202}, - {0x800a, 202}, - {0x800f, 202}, - {0x8018, 202}, - {0x801f, 202}, - {0x8029, 202}, - {0xc038, 202}, - {0x8003, 205}, - {0x8006, 205}, - {0x800a, 205}, - {0x800f, 205}, - {0x8018, 205}, - {0x801f, 205}, - {0x8029, 205}, - {0xc038, 205}, - }, - /* 198 */ - { - {0x8003, 210}, - {0x8006, 210}, - {0x800a, 210}, - {0x800f, 210}, - {0x8018, 210}, - {0x801f, 210}, - {0x8029, 210}, - {0xc038, 210}, - {0x8003, 213}, - {0x8006, 213}, - {0x800a, 213}, - {0x800f, 213}, - {0x8018, 213}, - {0x801f, 213}, - {0x8029, 213}, - {0xc038, 213}, - }, - /* 199 */ - { - {0x8001, 218}, - {0xc016, 218}, - {0x8001, 219}, - {0xc016, 219}, - {0x8001, 238}, - {0xc016, 238}, - {0x8001, 240}, - {0xc016, 240}, - {0x8001, 242}, - {0xc016, 242}, - {0x8001, 243}, - {0xc016, 243}, - {0x8001, 255}, - {0xc016, 255}, - {0xc000, 203}, - {0xc000, 204}, - }, - /* 200 */ - { - {0x8002, 218}, - {0x8009, 218}, - {0x8017, 218}, - {0xc028, 218}, - {0x8002, 219}, - {0x8009, 219}, - {0x8017, 219}, - {0xc028, 219}, - {0x8002, 238}, - {0x8009, 238}, - {0x8017, 238}, - {0xc028, 238}, - {0x8002, 240}, - {0x8009, 240}, - {0x8017, 240}, - {0xc028, 240}, - }, - /* 201 */ - { - {0x8003, 218}, - {0x8006, 218}, - {0x800a, 218}, - {0x800f, 218}, - {0x8018, 218}, - {0x801f, 218}, - {0x8029, 218}, - {0xc038, 218}, - {0x8003, 219}, - {0x8006, 219}, - {0x800a, 219}, - {0x800f, 219}, - {0x8018, 219}, - {0x801f, 219}, - {0x8029, 219}, - {0xc038, 219}, - }, - /* 202 */ - { - {0x8003, 238}, - {0x8006, 238}, - {0x800a, 238}, - {0x800f, 238}, - {0x8018, 238}, - {0x801f, 238}, - {0x8029, 238}, - {0xc038, 238}, - {0x8003, 240}, - {0x8006, 240}, - {0x800a, 240}, - {0x800f, 240}, - {0x8018, 240}, - {0x801f, 240}, - {0x8029, 240}, - {0xc038, 240}, - }, - /* 203 */ - { - {0x8002, 242}, - {0x8009, 242}, - {0x8017, 242}, - {0xc028, 242}, - {0x8002, 243}, - {0x8009, 243}, - {0x8017, 243}, - {0xc028, 243}, - {0x8002, 255}, - {0x8009, 255}, - {0x8017, 255}, - {0xc028, 255}, - {0x8001, 203}, - {0xc016, 203}, - {0x8001, 204}, - {0xc016, 204}, - }, - /* 204 */ - { - {0x8003, 242}, - {0x8006, 242}, - {0x800a, 242}, - {0x800f, 242}, - {0x8018, 242}, - {0x801f, 242}, - {0x8029, 242}, - {0xc038, 242}, - {0x8003, 243}, - {0x8006, 243}, - {0x800a, 243}, - {0x800f, 243}, - {0x8018, 243}, - {0x801f, 243}, - {0x8029, 243}, - {0xc038, 243}, - }, - /* 205 */ - { - {0x8003, 255}, - {0x8006, 255}, - {0x800a, 255}, - {0x800f, 255}, - {0x8018, 255}, - {0x801f, 255}, - {0x8029, 255}, - {0xc038, 255}, - {0x8002, 203}, - {0x8009, 203}, - {0x8017, 203}, - {0xc028, 203}, - {0x8002, 204}, - {0x8009, 204}, - {0x8017, 204}, - {0xc028, 204}, - }, - /* 206 */ - { - {0x8003, 203}, - {0x8006, 203}, - {0x800a, 203}, - {0x800f, 203}, - {0x8018, 203}, - {0x801f, 203}, - {0x8029, 203}, - {0xc038, 203}, - {0x8003, 204}, - {0x8006, 204}, - {0x800a, 204}, - {0x800f, 204}, - {0x8018, 204}, - {0x801f, 204}, - {0x8029, 204}, - {0xc038, 204}, - }, - /* 207 */ - { - {0xd3, 0}, - {0xd4, 0}, - {0xd6, 0}, - {0xd7, 0}, - {0xda, 0}, - {0xdb, 0}, - {0xdd, 0}, - {0xde, 0}, - {0xe2, 0}, - {0xe4, 0}, - {0xe8, 0}, - {0xeb, 0}, - {0xf0, 0}, - {0xf3, 0}, - {0xf7, 0}, - {0xfa, 0}, - }, - /* 208 */ - { - {0xc000, 211}, - {0xc000, 212}, - {0xc000, 214}, - {0xc000, 221}, - {0xc000, 222}, - {0xc000, 223}, - {0xc000, 241}, - {0xc000, 244}, - {0xc000, 245}, - {0xc000, 246}, - {0xc000, 247}, - {0xc000, 248}, - {0xc000, 250}, - {0xc000, 251}, - {0xc000, 252}, - {0xc000, 253}, - }, - /* 209 */ - { - {0x8001, 211}, - {0xc016, 211}, - {0x8001, 212}, - {0xc016, 212}, - {0x8001, 214}, - {0xc016, 214}, - {0x8001, 221}, - {0xc016, 221}, - {0x8001, 222}, - {0xc016, 222}, - {0x8001, 223}, - {0xc016, 223}, - {0x8001, 241}, - {0xc016, 241}, - {0x8001, 244}, - {0xc016, 244}, - }, - /* 210 */ - { - {0x8002, 211}, - {0x8009, 211}, - {0x8017, 211}, - {0xc028, 211}, - {0x8002, 212}, - {0x8009, 212}, - {0x8017, 212}, - {0xc028, 212}, - {0x8002, 214}, - {0x8009, 214}, - {0x8017, 214}, - {0xc028, 214}, - {0x8002, 221}, - {0x8009, 221}, - {0x8017, 221}, - {0xc028, 221}, - }, - /* 211 */ - { - {0x8003, 211}, - {0x8006, 211}, - {0x800a, 211}, - {0x800f, 211}, - {0x8018, 211}, - {0x801f, 211}, - {0x8029, 211}, - {0xc038, 211}, - {0x8003, 212}, - {0x8006, 212}, - {0x800a, 212}, - {0x800f, 212}, - {0x8018, 212}, - {0x801f, 212}, - {0x8029, 212}, - {0xc038, 212}, - }, - /* 212 */ - { - {0x8003, 214}, - {0x8006, 214}, - {0x800a, 214}, - {0x800f, 214}, - {0x8018, 214}, - {0x801f, 214}, - {0x8029, 214}, - {0xc038, 214}, - {0x8003, 221}, - {0x8006, 221}, - {0x800a, 221}, - {0x800f, 221}, - {0x8018, 221}, - {0x801f, 221}, - {0x8029, 221}, - {0xc038, 221}, - }, - /* 213 */ - { - {0x8002, 222}, - {0x8009, 222}, - {0x8017, 222}, - {0xc028, 222}, - {0x8002, 223}, - {0x8009, 223}, - {0x8017, 223}, - {0xc028, 223}, - {0x8002, 241}, - {0x8009, 241}, - {0x8017, 241}, - {0xc028, 241}, - {0x8002, 244}, - {0x8009, 244}, - {0x8017, 244}, - {0xc028, 244}, - }, - /* 214 */ - { - {0x8003, 222}, - {0x8006, 222}, - {0x800a, 222}, - {0x800f, 222}, - {0x8018, 222}, - {0x801f, 222}, - {0x8029, 222}, - {0xc038, 222}, - {0x8003, 223}, - {0x8006, 223}, - {0x800a, 223}, - {0x800f, 223}, - {0x8018, 223}, - {0x801f, 223}, - {0x8029, 223}, - {0xc038, 223}, - }, - /* 215 */ - { - {0x8003, 241}, - {0x8006, 241}, - {0x800a, 241}, - {0x800f, 241}, - {0x8018, 241}, - {0x801f, 241}, - {0x8029, 241}, - {0xc038, 241}, - {0x8003, 244}, - {0x8006, 244}, - {0x800a, 244}, - {0x800f, 244}, - {0x8018, 244}, - {0x801f, 244}, - {0x8029, 244}, - {0xc038, 244}, - }, - /* 216 */ - { - {0x8001, 245}, - {0xc016, 245}, - {0x8001, 246}, - {0xc016, 246}, - {0x8001, 247}, - {0xc016, 247}, - {0x8001, 248}, - {0xc016, 248}, - {0x8001, 250}, - {0xc016, 250}, - {0x8001, 251}, - {0xc016, 251}, - {0x8001, 252}, - {0xc016, 252}, - {0x8001, 253}, - {0xc016, 253}, - }, - /* 217 */ - { - {0x8002, 245}, - {0x8009, 245}, - {0x8017, 245}, - {0xc028, 245}, - {0x8002, 246}, - {0x8009, 246}, - {0x8017, 246}, - {0xc028, 246}, - {0x8002, 247}, - {0x8009, 247}, - {0x8017, 247}, - {0xc028, 247}, - {0x8002, 248}, - {0x8009, 248}, - {0x8017, 248}, - {0xc028, 248}, - }, - /* 218 */ - { - {0x8003, 245}, - {0x8006, 245}, - {0x800a, 245}, - {0x800f, 245}, - {0x8018, 245}, - {0x801f, 245}, - {0x8029, 245}, - {0xc038, 245}, - {0x8003, 246}, - {0x8006, 246}, - {0x800a, 246}, - {0x800f, 246}, - {0x8018, 246}, - {0x801f, 246}, - {0x8029, 246}, - {0xc038, 246}, - }, - /* 219 */ - { - {0x8003, 247}, - {0x8006, 247}, - {0x800a, 247}, - {0x800f, 247}, - {0x8018, 247}, - {0x801f, 247}, - {0x8029, 247}, - {0xc038, 247}, - {0x8003, 248}, - {0x8006, 248}, - {0x800a, 248}, - {0x800f, 248}, - {0x8018, 248}, - {0x801f, 248}, - {0x8029, 248}, - {0xc038, 248}, - }, - /* 220 */ - { - {0x8002, 250}, - {0x8009, 250}, - {0x8017, 250}, - {0xc028, 250}, - {0x8002, 251}, - {0x8009, 251}, - {0x8017, 251}, - {0xc028, 251}, - {0x8002, 252}, - {0x8009, 252}, - {0x8017, 252}, - {0xc028, 252}, - {0x8002, 253}, - {0x8009, 253}, - {0x8017, 253}, - {0xc028, 253}, - }, - /* 221 */ - { - {0x8003, 250}, - {0x8006, 250}, - {0x800a, 250}, - {0x800f, 250}, - {0x8018, 250}, - {0x801f, 250}, - {0x8029, 250}, - {0xc038, 250}, - {0x8003, 251}, - {0x8006, 251}, - {0x800a, 251}, - {0x800f, 251}, - {0x8018, 251}, - {0x801f, 251}, - {0x8029, 251}, - {0xc038, 251}, - }, - /* 222 */ - { - {0x8003, 252}, - {0x8006, 252}, - {0x800a, 252}, - {0x800f, 252}, - {0x8018, 252}, - {0x801f, 252}, - {0x8029, 252}, - {0xc038, 252}, - {0x8003, 253}, - {0x8006, 253}, - {0x800a, 253}, - {0x800f, 253}, - {0x8018, 253}, - {0x801f, 253}, - {0x8029, 253}, - {0xc038, 253}, - }, - /* 223 */ - { - {0xc000, 254}, - {0xe3, 0}, - {0xe5, 0}, - {0xe6, 0}, - {0xe9, 0}, - {0xea, 0}, - {0xec, 0}, - {0xed, 0}, - {0xf1, 0}, - {0xf2, 0}, - {0xf4, 0}, - {0xf5, 0}, - {0xf8, 0}, - {0xf9, 0}, - {0xfb, 0}, - {0xfc, 0}, - }, - /* 224 */ - { - {0x8001, 254}, - {0xc016, 254}, - {0xc000, 2}, - {0xc000, 3}, - {0xc000, 4}, - {0xc000, 5}, - {0xc000, 6}, - {0xc000, 7}, - {0xc000, 8}, - {0xc000, 11}, - {0xc000, 12}, - {0xc000, 14}, - {0xc000, 15}, - {0xc000, 16}, - {0xc000, 17}, - {0xc000, 18}, - }, - /* 225 */ - { - {0x8002, 254}, - {0x8009, 254}, - {0x8017, 254}, - {0xc028, 254}, - {0x8001, 2}, - {0xc016, 2}, - {0x8001, 3}, - {0xc016, 3}, - {0x8001, 4}, - {0xc016, 4}, - {0x8001, 5}, - {0xc016, 5}, - {0x8001, 6}, - {0xc016, 6}, - {0x8001, 7}, - {0xc016, 7}, - }, - /* 226 */ - { - {0x8003, 254}, - {0x8006, 254}, - {0x800a, 254}, - {0x800f, 254}, - {0x8018, 254}, - {0x801f, 254}, - {0x8029, 254}, - {0xc038, 254}, - {0x8002, 2}, - {0x8009, 2}, - {0x8017, 2}, - {0xc028, 2}, - {0x8002, 3}, - {0x8009, 3}, - {0x8017, 3}, - {0xc028, 3}, - }, - /* 227 */ - { - {0x8003, 2}, - {0x8006, 2}, - {0x800a, 2}, - {0x800f, 2}, - {0x8018, 2}, - {0x801f, 2}, - {0x8029, 2}, - {0xc038, 2}, - {0x8003, 3}, - {0x8006, 3}, - {0x800a, 3}, - {0x800f, 3}, - {0x8018, 3}, - {0x801f, 3}, - {0x8029, 3}, - {0xc038, 3}, - }, - /* 228 */ - { - {0x8002, 4}, - {0x8009, 4}, - {0x8017, 4}, - {0xc028, 4}, - {0x8002, 5}, - {0x8009, 5}, - {0x8017, 5}, - {0xc028, 5}, - {0x8002, 6}, - {0x8009, 6}, - {0x8017, 6}, - {0xc028, 6}, - {0x8002, 7}, - {0x8009, 7}, - {0x8017, 7}, - {0xc028, 7}, - }, - /* 229 */ - { - {0x8003, 4}, - {0x8006, 4}, - {0x800a, 4}, - {0x800f, 4}, - {0x8018, 4}, - {0x801f, 4}, - {0x8029, 4}, - {0xc038, 4}, - {0x8003, 5}, - {0x8006, 5}, - {0x800a, 5}, - {0x800f, 5}, - {0x8018, 5}, - {0x801f, 5}, - {0x8029, 5}, - {0xc038, 5}, - }, - /* 230 */ - { - {0x8003, 6}, - {0x8006, 6}, - {0x800a, 6}, - {0x800f, 6}, - {0x8018, 6}, - {0x801f, 6}, - {0x8029, 6}, - {0xc038, 6}, - {0x8003, 7}, - {0x8006, 7}, - {0x800a, 7}, - {0x800f, 7}, - {0x8018, 7}, - {0x801f, 7}, - {0x8029, 7}, - {0xc038, 7}, - }, - /* 231 */ - { - {0x8001, 8}, - {0xc016, 8}, - {0x8001, 11}, - {0xc016, 11}, - {0x8001, 12}, - {0xc016, 12}, - {0x8001, 14}, - {0xc016, 14}, - {0x8001, 15}, - {0xc016, 15}, - {0x8001, 16}, - {0xc016, 16}, - {0x8001, 17}, - {0xc016, 17}, - {0x8001, 18}, - {0xc016, 18}, - }, - /* 232 */ - { - {0x8002, 8}, - {0x8009, 8}, - {0x8017, 8}, - {0xc028, 8}, - {0x8002, 11}, - {0x8009, 11}, - {0x8017, 11}, - {0xc028, 11}, - {0x8002, 12}, - {0x8009, 12}, - {0x8017, 12}, - {0xc028, 12}, - {0x8002, 14}, - {0x8009, 14}, - {0x8017, 14}, - {0xc028, 14}, - }, - /* 233 */ - { - {0x8003, 8}, - {0x8006, 8}, - {0x800a, 8}, - {0x800f, 8}, - {0x8018, 8}, - {0x801f, 8}, - {0x8029, 8}, - {0xc038, 8}, - {0x8003, 11}, - {0x8006, 11}, - {0x800a, 11}, - {0x800f, 11}, - {0x8018, 11}, - {0x801f, 11}, - {0x8029, 11}, - {0xc038, 11}, - }, - /* 234 */ - { - {0x8003, 12}, - {0x8006, 12}, - {0x800a, 12}, - {0x800f, 12}, - {0x8018, 12}, - {0x801f, 12}, - {0x8029, 12}, - {0xc038, 12}, - {0x8003, 14}, - {0x8006, 14}, - {0x800a, 14}, - {0x800f, 14}, - {0x8018, 14}, - {0x801f, 14}, - {0x8029, 14}, - {0xc038, 14}, - }, - /* 235 */ - { - {0x8002, 15}, - {0x8009, 15}, - {0x8017, 15}, - {0xc028, 15}, - {0x8002, 16}, - {0x8009, 16}, - {0x8017, 16}, - {0xc028, 16}, - {0x8002, 17}, - {0x8009, 17}, - {0x8017, 17}, - {0xc028, 17}, - {0x8002, 18}, - {0x8009, 18}, - {0x8017, 18}, - {0xc028, 18}, - }, - /* 236 */ - { - {0x8003, 15}, - {0x8006, 15}, - {0x800a, 15}, - {0x800f, 15}, - {0x8018, 15}, - {0x801f, 15}, - {0x8029, 15}, - {0xc038, 15}, - {0x8003, 16}, - {0x8006, 16}, - {0x800a, 16}, - {0x800f, 16}, - {0x8018, 16}, - {0x801f, 16}, - {0x8029, 16}, - {0xc038, 16}, - }, - /* 237 */ - { - {0x8003, 17}, - {0x8006, 17}, - {0x800a, 17}, - {0x800f, 17}, - {0x8018, 17}, - {0x801f, 17}, - {0x8029, 17}, - {0xc038, 17}, - {0x8003, 18}, - {0x8006, 18}, - {0x800a, 18}, - {0x800f, 18}, - {0x8018, 18}, - {0x801f, 18}, - {0x8029, 18}, - {0xc038, 18}, - }, - /* 238 */ - { - {0xc000, 19}, - {0xc000, 20}, - {0xc000, 21}, - {0xc000, 23}, - {0xc000, 24}, - {0xc000, 25}, - {0xc000, 26}, - {0xc000, 27}, - {0xc000, 28}, - {0xc000, 29}, - {0xc000, 30}, - {0xc000, 31}, - {0xc000, 127}, - {0xc000, 220}, - {0xc000, 249}, - {0xfd, 0}, - }, - /* 239 */ - { - {0x8001, 19}, - {0xc016, 19}, - {0x8001, 20}, - {0xc016, 20}, - {0x8001, 21}, - {0xc016, 21}, - {0x8001, 23}, - {0xc016, 23}, - {0x8001, 24}, - {0xc016, 24}, - {0x8001, 25}, - {0xc016, 25}, - {0x8001, 26}, - {0xc016, 26}, - {0x8001, 27}, - {0xc016, 27}, - }, - /* 240 */ - { - {0x8002, 19}, - {0x8009, 19}, - {0x8017, 19}, - {0xc028, 19}, - {0x8002, 20}, - {0x8009, 20}, - {0x8017, 20}, - {0xc028, 20}, - {0x8002, 21}, - {0x8009, 21}, - {0x8017, 21}, - {0xc028, 21}, - {0x8002, 23}, - {0x8009, 23}, - {0x8017, 23}, - {0xc028, 23}, - }, - /* 241 */ - { - {0x8003, 19}, - {0x8006, 19}, - {0x800a, 19}, - {0x800f, 19}, - {0x8018, 19}, - {0x801f, 19}, - {0x8029, 19}, - {0xc038, 19}, - {0x8003, 20}, - {0x8006, 20}, - {0x800a, 20}, - {0x800f, 20}, - {0x8018, 20}, - {0x801f, 20}, - {0x8029, 20}, - {0xc038, 20}, - }, - /* 242 */ - { - {0x8003, 21}, - {0x8006, 21}, - {0x800a, 21}, - {0x800f, 21}, - {0x8018, 21}, - {0x801f, 21}, - {0x8029, 21}, - {0xc038, 21}, - {0x8003, 23}, - {0x8006, 23}, - {0x800a, 23}, - {0x800f, 23}, - {0x8018, 23}, - {0x801f, 23}, - {0x8029, 23}, - {0xc038, 23}, - }, - /* 243 */ - { - {0x8002, 24}, - {0x8009, 24}, - {0x8017, 24}, - {0xc028, 24}, - {0x8002, 25}, - {0x8009, 25}, - {0x8017, 25}, - {0xc028, 25}, - {0x8002, 26}, - {0x8009, 26}, - {0x8017, 26}, - {0xc028, 26}, - {0x8002, 27}, - {0x8009, 27}, - {0x8017, 27}, - {0xc028, 27}, - }, - /* 244 */ - { - {0x8003, 24}, - {0x8006, 24}, - {0x800a, 24}, - {0x800f, 24}, - {0x8018, 24}, - {0x801f, 24}, - {0x8029, 24}, - {0xc038, 24}, - {0x8003, 25}, - {0x8006, 25}, - {0x800a, 25}, - {0x800f, 25}, - {0x8018, 25}, - {0x801f, 25}, - {0x8029, 25}, - {0xc038, 25}, - }, - /* 245 */ - { - {0x8003, 26}, - {0x8006, 26}, - {0x800a, 26}, - {0x800f, 26}, - {0x8018, 26}, - {0x801f, 26}, - {0x8029, 26}, - {0xc038, 26}, - {0x8003, 27}, - {0x8006, 27}, - {0x800a, 27}, - {0x800f, 27}, - {0x8018, 27}, - {0x801f, 27}, - {0x8029, 27}, - {0xc038, 27}, - }, - /* 246 */ - { - {0x8001, 28}, - {0xc016, 28}, - {0x8001, 29}, - {0xc016, 29}, - {0x8001, 30}, - {0xc016, 30}, - {0x8001, 31}, - {0xc016, 31}, - {0x8001, 127}, - {0xc016, 127}, - {0x8001, 220}, - {0xc016, 220}, - {0x8001, 249}, - {0xc016, 249}, - {0xfe, 0}, - {0xff, 0}, - }, - /* 247 */ - { - {0x8002, 28}, - {0x8009, 28}, - {0x8017, 28}, - {0xc028, 28}, - {0x8002, 29}, - {0x8009, 29}, - {0x8017, 29}, - {0xc028, 29}, - {0x8002, 30}, - {0x8009, 30}, - {0x8017, 30}, - {0xc028, 30}, - {0x8002, 31}, - {0x8009, 31}, - {0x8017, 31}, - {0xc028, 31}, - }, - /* 248 */ - { - {0x8003, 28}, - {0x8006, 28}, - {0x800a, 28}, - {0x800f, 28}, - {0x8018, 28}, - {0x801f, 28}, - {0x8029, 28}, - {0xc038, 28}, - {0x8003, 29}, - {0x8006, 29}, - {0x800a, 29}, - {0x800f, 29}, - {0x8018, 29}, - {0x801f, 29}, - {0x8029, 29}, - {0xc038, 29}, - }, - /* 249 */ - { - {0x8003, 30}, - {0x8006, 30}, - {0x800a, 30}, - {0x800f, 30}, - {0x8018, 30}, - {0x801f, 30}, - {0x8029, 30}, - {0xc038, 30}, - {0x8003, 31}, - {0x8006, 31}, - {0x800a, 31}, - {0x800f, 31}, - {0x8018, 31}, - {0x801f, 31}, - {0x8029, 31}, - {0xc038, 31}, - }, - /* 250 */ - { - {0x8002, 127}, - {0x8009, 127}, - {0x8017, 127}, - {0xc028, 127}, - {0x8002, 220}, - {0x8009, 220}, - {0x8017, 220}, - {0xc028, 220}, - {0x8002, 249}, - {0x8009, 249}, - {0x8017, 249}, - {0xc028, 249}, - {0xc000, 10}, - {0xc000, 13}, - {0xc000, 22}, - {0x100, 0}, - }, - /* 251 */ - { - {0x8003, 127}, - {0x8006, 127}, - {0x800a, 127}, - {0x800f, 127}, - {0x8018, 127}, - {0x801f, 127}, - {0x8029, 127}, - {0xc038, 127}, - {0x8003, 220}, - {0x8006, 220}, - {0x800a, 220}, - {0x800f, 220}, - {0x8018, 220}, - {0x801f, 220}, - {0x8029, 220}, - {0xc038, 220}, - }, - /* 252 */ - { - {0x8003, 249}, - {0x8006, 249}, - {0x800a, 249}, - {0x800f, 249}, - {0x8018, 249}, - {0x801f, 249}, - {0x8029, 249}, - {0xc038, 249}, - {0x8001, 10}, - {0xc016, 10}, - {0x8001, 13}, - {0xc016, 13}, - {0x8001, 22}, - {0xc016, 22}, - {0x100, 0}, - {0x100, 0}, - }, - /* 253 */ - { - {0x8002, 10}, - {0x8009, 10}, - {0x8017, 10}, - {0xc028, 10}, - {0x8002, 13}, - {0x8009, 13}, - {0x8017, 13}, - {0xc028, 13}, - {0x8002, 22}, - {0x8009, 22}, - {0x8017, 22}, - {0xc028, 22}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, - /* 254 */ - { - {0x8003, 10}, - {0x8006, 10}, - {0x800a, 10}, - {0x800f, 10}, - {0x8018, 10}, - {0x801f, 10}, - {0x8029, 10}, - {0xc038, 10}, - {0x8003, 13}, - {0x8006, 13}, - {0x800a, 13}, - {0x800f, 13}, - {0x8018, 13}, - {0x801f, 13}, - {0x8029, 13}, - {0xc038, 13}, - }, - /* 255 */ - { - {0x8003, 22}, - {0x8006, 22}, - {0x800a, 22}, - {0x800f, 22}, - {0x8018, 22}, - {0x801f, 22}, - {0x8029, 22}, - {0xc038, 22}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, - /* 256 */ - { - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - {0x100, 0}, - }, + /* 0 */ + { + {0x04, 0}, + {0x05, 0}, + {0x07, 0}, + {0x08, 0}, + {0x0b, 0}, + {0x0c, 0}, + {0x10, 0}, + {0x13, 0}, + {0x19, 0}, + {0x1c, 0}, + {0x20, 0}, + {0x23, 0}, + {0x2a, 0}, + {0x31, 0}, + {0x39, 0}, + {0x4040, 0}, + }, + /* 1 */ + { + {0xc000, 48}, + {0xc000, 49}, + {0xc000, 50}, + {0xc000, 97}, + {0xc000, 99}, + {0xc000, 101}, + {0xc000, 105}, + {0xc000, 111}, + {0xc000, 115}, + {0xc000, 116}, + {0x0d, 0}, + {0x0e, 0}, + {0x11, 0}, + {0x12, 0}, + {0x14, 0}, + {0x15, 0}, + }, + /* 2 */ + { + {0x8001, 48}, + {0xc016, 48}, + {0x8001, 49}, + {0xc016, 49}, + {0x8001, 50}, + {0xc016, 50}, + {0x8001, 97}, + {0xc016, 97}, + {0x8001, 99}, + {0xc016, 99}, + {0x8001, 101}, + {0xc016, 101}, + {0x8001, 105}, + {0xc016, 105}, + {0x8001, 111}, + {0xc016, 111}, + }, + /* 3 */ + { + {0x8002, 48}, + {0x8009, 48}, + {0x8017, 48}, + {0xc028, 48}, + {0x8002, 49}, + {0x8009, 49}, + {0x8017, 49}, + {0xc028, 49}, + {0x8002, 50}, + {0x8009, 50}, + {0x8017, 50}, + {0xc028, 50}, + {0x8002, 97}, + {0x8009, 97}, + {0x8017, 97}, + {0xc028, 97}, + }, + /* 4 */ + { + {0x8003, 48}, + {0x8006, 48}, + {0x800a, 48}, + {0x800f, 48}, + {0x8018, 48}, + {0x801f, 48}, + {0x8029, 48}, + {0xc038, 48}, + {0x8003, 49}, + {0x8006, 49}, + {0x800a, 49}, + {0x800f, 49}, + {0x8018, 49}, + {0x801f, 49}, + {0x8029, 49}, + {0xc038, 49}, + }, + /* 5 */ + { + {0x8003, 50}, + {0x8006, 50}, + {0x800a, 50}, + {0x800f, 50}, + {0x8018, 50}, + {0x801f, 50}, + {0x8029, 50}, + {0xc038, 50}, + {0x8003, 97}, + {0x8006, 97}, + {0x800a, 97}, + {0x800f, 97}, + {0x8018, 97}, + {0x801f, 97}, + {0x8029, 97}, + {0xc038, 97}, + }, + /* 6 */ + { + {0x8002, 99}, + {0x8009, 99}, + {0x8017, 99}, + {0xc028, 99}, + {0x8002, 101}, + {0x8009, 101}, + {0x8017, 101}, + {0xc028, 101}, + {0x8002, 105}, + {0x8009, 105}, + {0x8017, 105}, + {0xc028, 105}, + {0x8002, 111}, + {0x8009, 111}, + {0x8017, 111}, + {0xc028, 111}, + }, + /* 7 */ + { + {0x8003, 99}, + {0x8006, 99}, + {0x800a, 99}, + {0x800f, 99}, + {0x8018, 99}, + {0x801f, 99}, + {0x8029, 99}, + {0xc038, 99}, + {0x8003, 101}, + {0x8006, 101}, + {0x800a, 101}, + {0x800f, 101}, + {0x8018, 101}, + {0x801f, 101}, + {0x8029, 101}, + {0xc038, 101}, + }, + /* 8 */ + { + {0x8003, 105}, + {0x8006, 105}, + {0x800a, 105}, + {0x800f, 105}, + {0x8018, 105}, + {0x801f, 105}, + {0x8029, 105}, + {0xc038, 105}, + {0x8003, 111}, + {0x8006, 111}, + {0x800a, 111}, + {0x800f, 111}, + {0x8018, 111}, + {0x801f, 111}, + {0x8029, 111}, + {0xc038, 111}, + }, + /* 9 */ + { + {0x8001, 115}, + {0xc016, 115}, + {0x8001, 116}, + {0xc016, 116}, + {0xc000, 32}, + {0xc000, 37}, + {0xc000, 45}, + {0xc000, 46}, + {0xc000, 47}, + {0xc000, 51}, + {0xc000, 52}, + {0xc000, 53}, + {0xc000, 54}, + {0xc000, 55}, + {0xc000, 56}, + {0xc000, 57}, + }, + /* 10 */ + { + {0x8002, 115}, + {0x8009, 115}, + {0x8017, 115}, + {0xc028, 115}, + {0x8002, 116}, + {0x8009, 116}, + {0x8017, 116}, + {0xc028, 116}, + {0x8001, 32}, + {0xc016, 32}, + {0x8001, 37}, + {0xc016, 37}, + {0x8001, 45}, + {0xc016, 45}, + {0x8001, 46}, + {0xc016, 46}, + }, + /* 11 */ + { + {0x8003, 115}, + {0x8006, 115}, + {0x800a, 115}, + {0x800f, 115}, + {0x8018, 115}, + {0x801f, 115}, + {0x8029, 115}, + {0xc038, 115}, + {0x8003, 116}, + {0x8006, 116}, + {0x800a, 116}, + {0x800f, 116}, + {0x8018, 116}, + {0x801f, 116}, + {0x8029, 116}, + {0xc038, 116}, + }, + /* 12 */ + { + {0x8002, 32}, + {0x8009, 32}, + {0x8017, 32}, + {0xc028, 32}, + {0x8002, 37}, + {0x8009, 37}, + {0x8017, 37}, + {0xc028, 37}, + {0x8002, 45}, + {0x8009, 45}, + {0x8017, 45}, + {0xc028, 45}, + {0x8002, 46}, + {0x8009, 46}, + {0x8017, 46}, + {0xc028, 46}, + }, + /* 13 */ + { + {0x8003, 32}, + {0x8006, 32}, + {0x800a, 32}, + {0x800f, 32}, + {0x8018, 32}, + {0x801f, 32}, + {0x8029, 32}, + {0xc038, 32}, + {0x8003, 37}, + {0x8006, 37}, + {0x800a, 37}, + {0x800f, 37}, + {0x8018, 37}, + {0x801f, 37}, + {0x8029, 37}, + {0xc038, 37}, + }, + /* 14 */ + { + {0x8003, 45}, + {0x8006, 45}, + {0x800a, 45}, + {0x800f, 45}, + {0x8018, 45}, + {0x801f, 45}, + {0x8029, 45}, + {0xc038, 45}, + {0x8003, 46}, + {0x8006, 46}, + {0x800a, 46}, + {0x800f, 46}, + {0x8018, 46}, + {0x801f, 46}, + {0x8029, 46}, + {0xc038, 46}, + }, + /* 15 */ + { + {0x8001, 47}, + {0xc016, 47}, + {0x8001, 51}, + {0xc016, 51}, + {0x8001, 52}, + {0xc016, 52}, + {0x8001, 53}, + {0xc016, 53}, + {0x8001, 54}, + {0xc016, 54}, + {0x8001, 55}, + {0xc016, 55}, + {0x8001, 56}, + {0xc016, 56}, + {0x8001, 57}, + {0xc016, 57}, + }, + /* 16 */ + { + {0x8002, 47}, + {0x8009, 47}, + {0x8017, 47}, + {0xc028, 47}, + {0x8002, 51}, + {0x8009, 51}, + {0x8017, 51}, + {0xc028, 51}, + {0x8002, 52}, + {0x8009, 52}, + {0x8017, 52}, + {0xc028, 52}, + {0x8002, 53}, + {0x8009, 53}, + {0x8017, 53}, + {0xc028, 53}, + }, + /* 17 */ + { + {0x8003, 47}, + {0x8006, 47}, + {0x800a, 47}, + {0x800f, 47}, + {0x8018, 47}, + {0x801f, 47}, + {0x8029, 47}, + {0xc038, 47}, + {0x8003, 51}, + {0x8006, 51}, + {0x800a, 51}, + {0x800f, 51}, + {0x8018, 51}, + {0x801f, 51}, + {0x8029, 51}, + {0xc038, 51}, + }, + /* 18 */ + { + {0x8003, 52}, + {0x8006, 52}, + {0x800a, 52}, + {0x800f, 52}, + {0x8018, 52}, + {0x801f, 52}, + {0x8029, 52}, + {0xc038, 52}, + {0x8003, 53}, + {0x8006, 53}, + {0x800a, 53}, + {0x800f, 53}, + {0x8018, 53}, + {0x801f, 53}, + {0x8029, 53}, + {0xc038, 53}, + }, + /* 19 */ + { + {0x8002, 54}, + {0x8009, 54}, + {0x8017, 54}, + {0xc028, 54}, + {0x8002, 55}, + {0x8009, 55}, + {0x8017, 55}, + {0xc028, 55}, + {0x8002, 56}, + {0x8009, 56}, + {0x8017, 56}, + {0xc028, 56}, + {0x8002, 57}, + {0x8009, 57}, + {0x8017, 57}, + {0xc028, 57}, + }, + /* 20 */ + { + {0x8003, 54}, + {0x8006, 54}, + {0x800a, 54}, + {0x800f, 54}, + {0x8018, 54}, + {0x801f, 54}, + {0x8029, 54}, + {0xc038, 54}, + {0x8003, 55}, + {0x8006, 55}, + {0x800a, 55}, + {0x800f, 55}, + {0x8018, 55}, + {0x801f, 55}, + {0x8029, 55}, + {0xc038, 55}, + }, + /* 21 */ + { + {0x8003, 56}, + {0x8006, 56}, + {0x800a, 56}, + {0x800f, 56}, + {0x8018, 56}, + {0x801f, 56}, + {0x8029, 56}, + {0xc038, 56}, + {0x8003, 57}, + {0x8006, 57}, + {0x800a, 57}, + {0x800f, 57}, + {0x8018, 57}, + {0x801f, 57}, + {0x8029, 57}, + {0xc038, 57}, + }, + /* 22 */ + { + {0x1a, 0}, + {0x1b, 0}, + {0x1d, 0}, + {0x1e, 0}, + {0x21, 0}, + {0x22, 0}, + {0x24, 0}, + {0x25, 0}, + {0x2b, 0}, + {0x2e, 0}, + {0x32, 0}, + {0x35, 0}, + {0x3a, 0}, + {0x3d, 0}, + {0x41, 0}, + {0x4044, 0}, + }, + /* 23 */ + { + {0xc000, 61}, + {0xc000, 65}, + {0xc000, 95}, + {0xc000, 98}, + {0xc000, 100}, + {0xc000, 102}, + {0xc000, 103}, + {0xc000, 104}, + {0xc000, 108}, + {0xc000, 109}, + {0xc000, 110}, + {0xc000, 112}, + {0xc000, 114}, + {0xc000, 117}, + {0x26, 0}, + {0x27, 0}, + }, + /* 24 */ + { + {0x8001, 61}, + {0xc016, 61}, + {0x8001, 65}, + {0xc016, 65}, + {0x8001, 95}, + {0xc016, 95}, + {0x8001, 98}, + {0xc016, 98}, + {0x8001, 100}, + {0xc016, 100}, + {0x8001, 102}, + {0xc016, 102}, + {0x8001, 103}, + {0xc016, 103}, + {0x8001, 104}, + {0xc016, 104}, + }, + /* 25 */ + { + {0x8002, 61}, + {0x8009, 61}, + {0x8017, 61}, + {0xc028, 61}, + {0x8002, 65}, + {0x8009, 65}, + {0x8017, 65}, + {0xc028, 65}, + {0x8002, 95}, + {0x8009, 95}, + {0x8017, 95}, + {0xc028, 95}, + {0x8002, 98}, + {0x8009, 98}, + {0x8017, 98}, + {0xc028, 98}, + }, + /* 26 */ + { + {0x8003, 61}, + {0x8006, 61}, + {0x800a, 61}, + {0x800f, 61}, + {0x8018, 61}, + {0x801f, 61}, + {0x8029, 61}, + {0xc038, 61}, + {0x8003, 65}, + {0x8006, 65}, + {0x800a, 65}, + {0x800f, 65}, + {0x8018, 65}, + {0x801f, 65}, + {0x8029, 65}, + {0xc038, 65}, + }, + /* 27 */ + { + {0x8003, 95}, + {0x8006, 95}, + {0x800a, 95}, + {0x800f, 95}, + {0x8018, 95}, + {0x801f, 95}, + {0x8029, 95}, + {0xc038, 95}, + {0x8003, 98}, + {0x8006, 98}, + {0x800a, 98}, + {0x800f, 98}, + {0x8018, 98}, + {0x801f, 98}, + {0x8029, 98}, + {0xc038, 98}, + }, + /* 28 */ + { + {0x8002, 100}, + {0x8009, 100}, + {0x8017, 100}, + {0xc028, 100}, + {0x8002, 102}, + {0x8009, 102}, + {0x8017, 102}, + {0xc028, 102}, + {0x8002, 103}, + {0x8009, 103}, + {0x8017, 103}, + {0xc028, 103}, + {0x8002, 104}, + {0x8009, 104}, + {0x8017, 104}, + {0xc028, 104}, + }, + /* 29 */ + { + {0x8003, 100}, + {0x8006, 100}, + {0x800a, 100}, + {0x800f, 100}, + {0x8018, 100}, + {0x801f, 100}, + {0x8029, 100}, + {0xc038, 100}, + {0x8003, 102}, + {0x8006, 102}, + {0x800a, 102}, + {0x800f, 102}, + {0x8018, 102}, + {0x801f, 102}, + {0x8029, 102}, + {0xc038, 102}, + }, + /* 30 */ + { + {0x8003, 103}, + {0x8006, 103}, + {0x800a, 103}, + {0x800f, 103}, + {0x8018, 103}, + {0x801f, 103}, + {0x8029, 103}, + {0xc038, 103}, + {0x8003, 104}, + {0x8006, 104}, + {0x800a, 104}, + {0x800f, 104}, + {0x8018, 104}, + {0x801f, 104}, + {0x8029, 104}, + {0xc038, 104}, + }, + /* 31 */ + { + {0x8001, 108}, + {0xc016, 108}, + {0x8001, 109}, + {0xc016, 109}, + {0x8001, 110}, + {0xc016, 110}, + {0x8001, 112}, + {0xc016, 112}, + {0x8001, 114}, + {0xc016, 114}, + {0x8001, 117}, + {0xc016, 117}, + {0xc000, 58}, + {0xc000, 66}, + {0xc000, 67}, + {0xc000, 68}, + }, + /* 32 */ + { + {0x8002, 108}, + {0x8009, 108}, + {0x8017, 108}, + {0xc028, 108}, + {0x8002, 109}, + {0x8009, 109}, + {0x8017, 109}, + {0xc028, 109}, + {0x8002, 110}, + {0x8009, 110}, + {0x8017, 110}, + {0xc028, 110}, + {0x8002, 112}, + {0x8009, 112}, + {0x8017, 112}, + {0xc028, 112}, + }, + /* 33 */ + { + {0x8003, 108}, + {0x8006, 108}, + {0x800a, 108}, + {0x800f, 108}, + {0x8018, 108}, + {0x801f, 108}, + {0x8029, 108}, + {0xc038, 108}, + {0x8003, 109}, + {0x8006, 109}, + {0x800a, 109}, + {0x800f, 109}, + {0x8018, 109}, + {0x801f, 109}, + {0x8029, 109}, + {0xc038, 109}, + }, + /* 34 */ + { + {0x8003, 110}, + {0x8006, 110}, + {0x800a, 110}, + {0x800f, 110}, + {0x8018, 110}, + {0x801f, 110}, + {0x8029, 110}, + {0xc038, 110}, + {0x8003, 112}, + {0x8006, 112}, + {0x800a, 112}, + {0x800f, 112}, + {0x8018, 112}, + {0x801f, 112}, + {0x8029, 112}, + {0xc038, 112}, + }, + /* 35 */ + { + {0x8002, 114}, + {0x8009, 114}, + {0x8017, 114}, + {0xc028, 114}, + {0x8002, 117}, + {0x8009, 117}, + {0x8017, 117}, + {0xc028, 117}, + {0x8001, 58}, + {0xc016, 58}, + {0x8001, 66}, + {0xc016, 66}, + {0x8001, 67}, + {0xc016, 67}, + {0x8001, 68}, + {0xc016, 68}, + }, + /* 36 */ + { + {0x8003, 114}, + {0x8006, 114}, + {0x800a, 114}, + {0x800f, 114}, + {0x8018, 114}, + {0x801f, 114}, + {0x8029, 114}, + {0xc038, 114}, + {0x8003, 117}, + {0x8006, 117}, + {0x800a, 117}, + {0x800f, 117}, + {0x8018, 117}, + {0x801f, 117}, + {0x8029, 117}, + {0xc038, 117}, + }, + /* 37 */ + { + {0x8002, 58}, + {0x8009, 58}, + {0x8017, 58}, + {0xc028, 58}, + {0x8002, 66}, + {0x8009, 66}, + {0x8017, 66}, + {0xc028, 66}, + {0x8002, 67}, + {0x8009, 67}, + {0x8017, 67}, + {0xc028, 67}, + {0x8002, 68}, + {0x8009, 68}, + {0x8017, 68}, + {0xc028, 68}, + }, + /* 38 */ + { + {0x8003, 58}, + {0x8006, 58}, + {0x800a, 58}, + {0x800f, 58}, + {0x8018, 58}, + {0x801f, 58}, + {0x8029, 58}, + {0xc038, 58}, + {0x8003, 66}, + {0x8006, 66}, + {0x800a, 66}, + {0x800f, 66}, + {0x8018, 66}, + {0x801f, 66}, + {0x8029, 66}, + {0xc038, 66}, + }, + /* 39 */ + { + {0x8003, 67}, + {0x8006, 67}, + {0x800a, 67}, + {0x800f, 67}, + {0x8018, 67}, + {0x801f, 67}, + {0x8029, 67}, + {0xc038, 67}, + {0x8003, 68}, + {0x8006, 68}, + {0x800a, 68}, + {0x800f, 68}, + {0x8018, 68}, + {0x801f, 68}, + {0x8029, 68}, + {0xc038, 68}, + }, + /* 40 */ + { + {0x2c, 0}, + {0x2d, 0}, + {0x2f, 0}, + {0x30, 0}, + {0x33, 0}, + {0x34, 0}, + {0x36, 0}, + {0x37, 0}, + {0x3b, 0}, + {0x3c, 0}, + {0x3e, 0}, + {0x3f, 0}, + {0x42, 0}, + {0x43, 0}, + {0x45, 0}, + {0x4048, 0}, + }, + /* 41 */ + { + {0xc000, 69}, + {0xc000, 70}, + {0xc000, 71}, + {0xc000, 72}, + {0xc000, 73}, + {0xc000, 74}, + {0xc000, 75}, + {0xc000, 76}, + {0xc000, 77}, + {0xc000, 78}, + {0xc000, 79}, + {0xc000, 80}, + {0xc000, 81}, + {0xc000, 82}, + {0xc000, 83}, + {0xc000, 84}, + }, + /* 42 */ + { + {0x8001, 69}, + {0xc016, 69}, + {0x8001, 70}, + {0xc016, 70}, + {0x8001, 71}, + {0xc016, 71}, + {0x8001, 72}, + {0xc016, 72}, + {0x8001, 73}, + {0xc016, 73}, + {0x8001, 74}, + {0xc016, 74}, + {0x8001, 75}, + {0xc016, 75}, + {0x8001, 76}, + {0xc016, 76}, + }, + /* 43 */ + { + {0x8002, 69}, + {0x8009, 69}, + {0x8017, 69}, + {0xc028, 69}, + {0x8002, 70}, + {0x8009, 70}, + {0x8017, 70}, + {0xc028, 70}, + {0x8002, 71}, + {0x8009, 71}, + {0x8017, 71}, + {0xc028, 71}, + {0x8002, 72}, + {0x8009, 72}, + {0x8017, 72}, + {0xc028, 72}, + }, + /* 44 */ + { + {0x8003, 69}, + {0x8006, 69}, + {0x800a, 69}, + {0x800f, 69}, + {0x8018, 69}, + {0x801f, 69}, + {0x8029, 69}, + {0xc038, 69}, + {0x8003, 70}, + {0x8006, 70}, + {0x800a, 70}, + {0x800f, 70}, + {0x8018, 70}, + {0x801f, 70}, + {0x8029, 70}, + {0xc038, 70}, + }, + /* 45 */ + { + {0x8003, 71}, + {0x8006, 71}, + {0x800a, 71}, + {0x800f, 71}, + {0x8018, 71}, + {0x801f, 71}, + {0x8029, 71}, + {0xc038, 71}, + {0x8003, 72}, + {0x8006, 72}, + {0x800a, 72}, + {0x800f, 72}, + {0x8018, 72}, + {0x801f, 72}, + {0x8029, 72}, + {0xc038, 72}, + }, + /* 46 */ + { + {0x8002, 73}, + {0x8009, 73}, + {0x8017, 73}, + {0xc028, 73}, + {0x8002, 74}, + {0x8009, 74}, + {0x8017, 74}, + {0xc028, 74}, + {0x8002, 75}, + {0x8009, 75}, + {0x8017, 75}, + {0xc028, 75}, + {0x8002, 76}, + {0x8009, 76}, + {0x8017, 76}, + {0xc028, 76}, + }, + /* 47 */ + { + {0x8003, 73}, + {0x8006, 73}, + {0x800a, 73}, + {0x800f, 73}, + {0x8018, 73}, + {0x801f, 73}, + {0x8029, 73}, + {0xc038, 73}, + {0x8003, 74}, + {0x8006, 74}, + {0x800a, 74}, + {0x800f, 74}, + {0x8018, 74}, + {0x801f, 74}, + {0x8029, 74}, + {0xc038, 74}, + }, + /* 48 */ + { + {0x8003, 75}, + {0x8006, 75}, + {0x800a, 75}, + {0x800f, 75}, + {0x8018, 75}, + {0x801f, 75}, + {0x8029, 75}, + {0xc038, 75}, + {0x8003, 76}, + {0x8006, 76}, + {0x800a, 76}, + {0x800f, 76}, + {0x8018, 76}, + {0x801f, 76}, + {0x8029, 76}, + {0xc038, 76}, + }, + /* 49 */ + { + {0x8001, 77}, + {0xc016, 77}, + {0x8001, 78}, + {0xc016, 78}, + {0x8001, 79}, + {0xc016, 79}, + {0x8001, 80}, + {0xc016, 80}, + {0x8001, 81}, + {0xc016, 81}, + {0x8001, 82}, + {0xc016, 82}, + {0x8001, 83}, + {0xc016, 83}, + {0x8001, 84}, + {0xc016, 84}, + }, + /* 50 */ + { + {0x8002, 77}, + {0x8009, 77}, + {0x8017, 77}, + {0xc028, 77}, + {0x8002, 78}, + {0x8009, 78}, + {0x8017, 78}, + {0xc028, 78}, + {0x8002, 79}, + {0x8009, 79}, + {0x8017, 79}, + {0xc028, 79}, + {0x8002, 80}, + {0x8009, 80}, + {0x8017, 80}, + {0xc028, 80}, + }, + /* 51 */ + { + {0x8003, 77}, + {0x8006, 77}, + {0x800a, 77}, + {0x800f, 77}, + {0x8018, 77}, + {0x801f, 77}, + {0x8029, 77}, + {0xc038, 77}, + {0x8003, 78}, + {0x8006, 78}, + {0x800a, 78}, + {0x800f, 78}, + {0x8018, 78}, + {0x801f, 78}, + {0x8029, 78}, + {0xc038, 78}, + }, + /* 52 */ + { + {0x8003, 79}, + {0x8006, 79}, + {0x800a, 79}, + {0x800f, 79}, + {0x8018, 79}, + {0x801f, 79}, + {0x8029, 79}, + {0xc038, 79}, + {0x8003, 80}, + {0x8006, 80}, + {0x800a, 80}, + {0x800f, 80}, + {0x8018, 80}, + {0x801f, 80}, + {0x8029, 80}, + {0xc038, 80}, + }, + /* 53 */ + { + {0x8002, 81}, + {0x8009, 81}, + {0x8017, 81}, + {0xc028, 81}, + {0x8002, 82}, + {0x8009, 82}, + {0x8017, 82}, + {0xc028, 82}, + {0x8002, 83}, + {0x8009, 83}, + {0x8017, 83}, + {0xc028, 83}, + {0x8002, 84}, + {0x8009, 84}, + {0x8017, 84}, + {0xc028, 84}, + }, + /* 54 */ + { + {0x8003, 81}, + {0x8006, 81}, + {0x800a, 81}, + {0x800f, 81}, + {0x8018, 81}, + {0x801f, 81}, + {0x8029, 81}, + {0xc038, 81}, + {0x8003, 82}, + {0x8006, 82}, + {0x800a, 82}, + {0x800f, 82}, + {0x8018, 82}, + {0x801f, 82}, + {0x8029, 82}, + {0xc038, 82}, + }, + /* 55 */ + { + {0x8003, 83}, + {0x8006, 83}, + {0x800a, 83}, + {0x800f, 83}, + {0x8018, 83}, + {0x801f, 83}, + {0x8029, 83}, + {0xc038, 83}, + {0x8003, 84}, + {0x8006, 84}, + {0x800a, 84}, + {0x800f, 84}, + {0x8018, 84}, + {0x801f, 84}, + {0x8029, 84}, + {0xc038, 84}, + }, + /* 56 */ + { + {0xc000, 85}, + {0xc000, 86}, + {0xc000, 87}, + {0xc000, 89}, + {0xc000, 106}, + {0xc000, 107}, + {0xc000, 113}, + {0xc000, 118}, + {0xc000, 119}, + {0xc000, 120}, + {0xc000, 121}, + {0xc000, 122}, + {0x46, 0}, + {0x47, 0}, + {0x49, 0}, + {0x404a, 0}, + }, + /* 57 */ + { + {0x8001, 85}, + {0xc016, 85}, + {0x8001, 86}, + {0xc016, 86}, + {0x8001, 87}, + {0xc016, 87}, + {0x8001, 89}, + {0xc016, 89}, + {0x8001, 106}, + {0xc016, 106}, + {0x8001, 107}, + {0xc016, 107}, + {0x8001, 113}, + {0xc016, 113}, + {0x8001, 118}, + {0xc016, 118}, + }, + /* 58 */ + { + {0x8002, 85}, + {0x8009, 85}, + {0x8017, 85}, + {0xc028, 85}, + {0x8002, 86}, + {0x8009, 86}, + {0x8017, 86}, + {0xc028, 86}, + {0x8002, 87}, + {0x8009, 87}, + {0x8017, 87}, + {0xc028, 87}, + {0x8002, 89}, + {0x8009, 89}, + {0x8017, 89}, + {0xc028, 89}, + }, + /* 59 */ + { + {0x8003, 85}, + {0x8006, 85}, + {0x800a, 85}, + {0x800f, 85}, + {0x8018, 85}, + {0x801f, 85}, + {0x8029, 85}, + {0xc038, 85}, + {0x8003, 86}, + {0x8006, 86}, + {0x800a, 86}, + {0x800f, 86}, + {0x8018, 86}, + {0x801f, 86}, + {0x8029, 86}, + {0xc038, 86}, + }, + /* 60 */ + { + {0x8003, 87}, + {0x8006, 87}, + {0x800a, 87}, + {0x800f, 87}, + {0x8018, 87}, + {0x801f, 87}, + {0x8029, 87}, + {0xc038, 87}, + {0x8003, 89}, + {0x8006, 89}, + {0x800a, 89}, + {0x800f, 89}, + {0x8018, 89}, + {0x801f, 89}, + {0x8029, 89}, + {0xc038, 89}, + }, + /* 61 */ + { + {0x8002, 106}, + {0x8009, 106}, + {0x8017, 106}, + {0xc028, 106}, + {0x8002, 107}, + {0x8009, 107}, + {0x8017, 107}, + {0xc028, 107}, + {0x8002, 113}, + {0x8009, 113}, + {0x8017, 113}, + {0xc028, 113}, + {0x8002, 118}, + {0x8009, 118}, + {0x8017, 118}, + {0xc028, 118}, + }, + /* 62 */ + { + {0x8003, 106}, + {0x8006, 106}, + {0x800a, 106}, + {0x800f, 106}, + {0x8018, 106}, + {0x801f, 106}, + {0x8029, 106}, + {0xc038, 106}, + {0x8003, 107}, + {0x8006, 107}, + {0x800a, 107}, + {0x800f, 107}, + {0x8018, 107}, + {0x801f, 107}, + {0x8029, 107}, + {0xc038, 107}, + }, + /* 63 */ + { + {0x8003, 113}, + {0x8006, 113}, + {0x800a, 113}, + {0x800f, 113}, + {0x8018, 113}, + {0x801f, 113}, + {0x8029, 113}, + {0xc038, 113}, + {0x8003, 118}, + {0x8006, 118}, + {0x800a, 118}, + {0x800f, 118}, + {0x8018, 118}, + {0x801f, 118}, + {0x8029, 118}, + {0xc038, 118}, + }, + /* 64 */ + { + {0x8001, 119}, + {0xc016, 119}, + {0x8001, 120}, + {0xc016, 120}, + {0x8001, 121}, + {0xc016, 121}, + {0x8001, 122}, + {0xc016, 122}, + {0xc000, 38}, + {0xc000, 42}, + {0xc000, 44}, + {0xc000, 59}, + {0xc000, 88}, + {0xc000, 90}, + {0x4b, 0}, + {0x4e, 0}, + }, + /* 65 */ + { + {0x8002, 119}, + {0x8009, 119}, + {0x8017, 119}, + {0xc028, 119}, + {0x8002, 120}, + {0x8009, 120}, + {0x8017, 120}, + {0xc028, 120}, + {0x8002, 121}, + {0x8009, 121}, + {0x8017, 121}, + {0xc028, 121}, + {0x8002, 122}, + {0x8009, 122}, + {0x8017, 122}, + {0xc028, 122}, + }, + /* 66 */ + { + {0x8003, 119}, + {0x8006, 119}, + {0x800a, 119}, + {0x800f, 119}, + {0x8018, 119}, + {0x801f, 119}, + {0x8029, 119}, + {0xc038, 119}, + {0x8003, 120}, + {0x8006, 120}, + {0x800a, 120}, + {0x800f, 120}, + {0x8018, 120}, + {0x801f, 120}, + {0x8029, 120}, + {0xc038, 120}, + }, + /* 67 */ + { + {0x8003, 121}, + {0x8006, 121}, + {0x800a, 121}, + {0x800f, 121}, + {0x8018, 121}, + {0x801f, 121}, + {0x8029, 121}, + {0xc038, 121}, + {0x8003, 122}, + {0x8006, 122}, + {0x800a, 122}, + {0x800f, 122}, + {0x8018, 122}, + {0x801f, 122}, + {0x8029, 122}, + {0xc038, 122}, + }, + /* 68 */ + { + {0x8001, 38}, + {0xc016, 38}, + {0x8001, 42}, + {0xc016, 42}, + {0x8001, 44}, + {0xc016, 44}, + {0x8001, 59}, + {0xc016, 59}, + {0x8001, 88}, + {0xc016, 88}, + {0x8001, 90}, + {0xc016, 90}, + {0x4c, 0}, + {0x4d, 0}, + {0x4f, 0}, + {0x51, 0}, + }, + /* 69 */ + { + {0x8002, 38}, + {0x8009, 38}, + {0x8017, 38}, + {0xc028, 38}, + {0x8002, 42}, + {0x8009, 42}, + {0x8017, 42}, + {0xc028, 42}, + {0x8002, 44}, + {0x8009, 44}, + {0x8017, 44}, + {0xc028, 44}, + {0x8002, 59}, + {0x8009, 59}, + {0x8017, 59}, + {0xc028, 59}, + }, + /* 70 */ + { + {0x8003, 38}, + {0x8006, 38}, + {0x800a, 38}, + {0x800f, 38}, + {0x8018, 38}, + {0x801f, 38}, + {0x8029, 38}, + {0xc038, 38}, + {0x8003, 42}, + {0x8006, 42}, + {0x800a, 42}, + {0x800f, 42}, + {0x8018, 42}, + {0x801f, 42}, + {0x8029, 42}, + {0xc038, 42}, + }, + /* 71 */ + { + {0x8003, 44}, + {0x8006, 44}, + {0x800a, 44}, + {0x800f, 44}, + {0x8018, 44}, + {0x801f, 44}, + {0x8029, 44}, + {0xc038, 44}, + {0x8003, 59}, + {0x8006, 59}, + {0x800a, 59}, + {0x800f, 59}, + {0x8018, 59}, + {0x801f, 59}, + {0x8029, 59}, + {0xc038, 59}, + }, + /* 72 */ + { + {0x8002, 88}, + {0x8009, 88}, + {0x8017, 88}, + {0xc028, 88}, + {0x8002, 90}, + {0x8009, 90}, + {0x8017, 90}, + {0xc028, 90}, + {0xc000, 33}, + {0xc000, 34}, + {0xc000, 40}, + {0xc000, 41}, + {0xc000, 63}, + {0x50, 0}, + {0x52, 0}, + {0x54, 0}, + }, + /* 73 */ + { + {0x8003, 88}, + {0x8006, 88}, + {0x800a, 88}, + {0x800f, 88}, + {0x8018, 88}, + {0x801f, 88}, + {0x8029, 88}, + {0xc038, 88}, + {0x8003, 90}, + {0x8006, 90}, + {0x800a, 90}, + {0x800f, 90}, + {0x8018, 90}, + {0x801f, 90}, + {0x8029, 90}, + {0xc038, 90}, + }, + /* 74 */ + { + {0x8001, 33}, + {0xc016, 33}, + {0x8001, 34}, + {0xc016, 34}, + {0x8001, 40}, + {0xc016, 40}, + {0x8001, 41}, + {0xc016, 41}, + {0x8001, 63}, + {0xc016, 63}, + {0xc000, 39}, + {0xc000, 43}, + {0xc000, 124}, + {0x53, 0}, + {0x55, 0}, + {0x58, 0}, + }, + /* 75 */ + { + {0x8002, 33}, + {0x8009, 33}, + {0x8017, 33}, + {0xc028, 33}, + {0x8002, 34}, + {0x8009, 34}, + {0x8017, 34}, + {0xc028, 34}, + {0x8002, 40}, + {0x8009, 40}, + {0x8017, 40}, + {0xc028, 40}, + {0x8002, 41}, + {0x8009, 41}, + {0x8017, 41}, + {0xc028, 41}, + }, + /* 76 */ + { + {0x8003, 33}, + {0x8006, 33}, + {0x800a, 33}, + {0x800f, 33}, + {0x8018, 33}, + {0x801f, 33}, + {0x8029, 33}, + {0xc038, 33}, + {0x8003, 34}, + {0x8006, 34}, + {0x800a, 34}, + {0x800f, 34}, + {0x8018, 34}, + {0x801f, 34}, + {0x8029, 34}, + {0xc038, 34}, + }, + /* 77 */ + { + {0x8003, 40}, + {0x8006, 40}, + {0x800a, 40}, + {0x800f, 40}, + {0x8018, 40}, + {0x801f, 40}, + {0x8029, 40}, + {0xc038, 40}, + {0x8003, 41}, + {0x8006, 41}, + {0x800a, 41}, + {0x800f, 41}, + {0x8018, 41}, + {0x801f, 41}, + {0x8029, 41}, + {0xc038, 41}, + }, + /* 78 */ + { + {0x8002, 63}, + {0x8009, 63}, + {0x8017, 63}, + {0xc028, 63}, + {0x8001, 39}, + {0xc016, 39}, + {0x8001, 43}, + {0xc016, 43}, + {0x8001, 124}, + {0xc016, 124}, + {0xc000, 35}, + {0xc000, 62}, + {0x56, 0}, + {0x57, 0}, + {0x59, 0}, + {0x5a, 0}, + }, + /* 79 */ + { + {0x8003, 63}, + {0x8006, 63}, + {0x800a, 63}, + {0x800f, 63}, + {0x8018, 63}, + {0x801f, 63}, + {0x8029, 63}, + {0xc038, 63}, + {0x8002, 39}, + {0x8009, 39}, + {0x8017, 39}, + {0xc028, 39}, + {0x8002, 43}, + {0x8009, 43}, + {0x8017, 43}, + {0xc028, 43}, + }, + /* 80 */ + { + {0x8003, 39}, + {0x8006, 39}, + {0x800a, 39}, + {0x800f, 39}, + {0x8018, 39}, + {0x801f, 39}, + {0x8029, 39}, + {0xc038, 39}, + {0x8003, 43}, + {0x8006, 43}, + {0x800a, 43}, + {0x800f, 43}, + {0x8018, 43}, + {0x801f, 43}, + {0x8029, 43}, + {0xc038, 43}, + }, + /* 81 */ + { + {0x8002, 124}, + {0x8009, 124}, + {0x8017, 124}, + {0xc028, 124}, + {0x8001, 35}, + {0xc016, 35}, + {0x8001, 62}, + {0xc016, 62}, + {0xc000, 0}, + {0xc000, 36}, + {0xc000, 64}, + {0xc000, 91}, + {0xc000, 93}, + {0xc000, 126}, + {0x5b, 0}, + {0x5c, 0}, + }, + /* 82 */ + { + {0x8003, 124}, + {0x8006, 124}, + {0x800a, 124}, + {0x800f, 124}, + {0x8018, 124}, + {0x801f, 124}, + {0x8029, 124}, + {0xc038, 124}, + {0x8002, 35}, + {0x8009, 35}, + {0x8017, 35}, + {0xc028, 35}, + {0x8002, 62}, + {0x8009, 62}, + {0x8017, 62}, + {0xc028, 62}, + }, + /* 83 */ + { + {0x8003, 35}, + {0x8006, 35}, + {0x800a, 35}, + {0x800f, 35}, + {0x8018, 35}, + {0x801f, 35}, + {0x8029, 35}, + {0xc038, 35}, + {0x8003, 62}, + {0x8006, 62}, + {0x800a, 62}, + {0x800f, 62}, + {0x8018, 62}, + {0x801f, 62}, + {0x8029, 62}, + {0xc038, 62}, + }, + /* 84 */ + { + {0x8001, 0}, + {0xc016, 0}, + {0x8001, 36}, + {0xc016, 36}, + {0x8001, 64}, + {0xc016, 64}, + {0x8001, 91}, + {0xc016, 91}, + {0x8001, 93}, + {0xc016, 93}, + {0x8001, 126}, + {0xc016, 126}, + {0xc000, 94}, + {0xc000, 125}, + {0x5d, 0}, + {0x5e, 0}, + }, + /* 85 */ + { + {0x8002, 0}, + {0x8009, 0}, + {0x8017, 0}, + {0xc028, 0}, + {0x8002, 36}, + {0x8009, 36}, + {0x8017, 36}, + {0xc028, 36}, + {0x8002, 64}, + {0x8009, 64}, + {0x8017, 64}, + {0xc028, 64}, + {0x8002, 91}, + {0x8009, 91}, + {0x8017, 91}, + {0xc028, 91}, + }, + /* 86 */ + { + {0x8003, 0}, + {0x8006, 0}, + {0x800a, 0}, + {0x800f, 0}, + {0x8018, 0}, + {0x801f, 0}, + {0x8029, 0}, + {0xc038, 0}, + {0x8003, 36}, + {0x8006, 36}, + {0x800a, 36}, + {0x800f, 36}, + {0x8018, 36}, + {0x801f, 36}, + {0x8029, 36}, + {0xc038, 36}, + }, + /* 87 */ + { + {0x8003, 64}, + {0x8006, 64}, + {0x800a, 64}, + {0x800f, 64}, + {0x8018, 64}, + {0x801f, 64}, + {0x8029, 64}, + {0xc038, 64}, + {0x8003, 91}, + {0x8006, 91}, + {0x800a, 91}, + {0x800f, 91}, + {0x8018, 91}, + {0x801f, 91}, + {0x8029, 91}, + {0xc038, 91}, + }, + /* 88 */ + { + {0x8002, 93}, + {0x8009, 93}, + {0x8017, 93}, + {0xc028, 93}, + {0x8002, 126}, + {0x8009, 126}, + {0x8017, 126}, + {0xc028, 126}, + {0x8001, 94}, + {0xc016, 94}, + {0x8001, 125}, + {0xc016, 125}, + {0xc000, 60}, + {0xc000, 96}, + {0xc000, 123}, + {0x5f, 0}, + }, + /* 89 */ + { + {0x8003, 93}, + {0x8006, 93}, + {0x800a, 93}, + {0x800f, 93}, + {0x8018, 93}, + {0x801f, 93}, + {0x8029, 93}, + {0xc038, 93}, + {0x8003, 126}, + {0x8006, 126}, + {0x800a, 126}, + {0x800f, 126}, + {0x8018, 126}, + {0x801f, 126}, + {0x8029, 126}, + {0xc038, 126}, + }, + /* 90 */ + { + {0x8002, 94}, + {0x8009, 94}, + {0x8017, 94}, + {0xc028, 94}, + {0x8002, 125}, + {0x8009, 125}, + {0x8017, 125}, + {0xc028, 125}, + {0x8001, 60}, + {0xc016, 60}, + {0x8001, 96}, + {0xc016, 96}, + {0x8001, 123}, + {0xc016, 123}, + {0x60, 0}, + {0x6e, 0}, + }, + /* 91 */ + { + {0x8003, 94}, + {0x8006, 94}, + {0x800a, 94}, + {0x800f, 94}, + {0x8018, 94}, + {0x801f, 94}, + {0x8029, 94}, + {0xc038, 94}, + {0x8003, 125}, + {0x8006, 125}, + {0x800a, 125}, + {0x800f, 125}, + {0x8018, 125}, + {0x801f, 125}, + {0x8029, 125}, + {0xc038, 125}, + }, + /* 92 */ + { + {0x8002, 60}, + {0x8009, 60}, + {0x8017, 60}, + {0xc028, 60}, + {0x8002, 96}, + {0x8009, 96}, + {0x8017, 96}, + {0xc028, 96}, + {0x8002, 123}, + {0x8009, 123}, + {0x8017, 123}, + {0xc028, 123}, + {0x61, 0}, + {0x65, 0}, + {0x6f, 0}, + {0x85, 0}, + }, + /* 93 */ + { + {0x8003, 60}, + {0x8006, 60}, + {0x800a, 60}, + {0x800f, 60}, + {0x8018, 60}, + {0x801f, 60}, + {0x8029, 60}, + {0xc038, 60}, + {0x8003, 96}, + {0x8006, 96}, + {0x800a, 96}, + {0x800f, 96}, + {0x8018, 96}, + {0x801f, 96}, + {0x8029, 96}, + {0xc038, 96}, + }, + /* 94 */ + { + {0x8003, 123}, + {0x8006, 123}, + {0x800a, 123}, + {0x800f, 123}, + {0x8018, 123}, + {0x801f, 123}, + {0x8029, 123}, + {0xc038, 123}, + {0x62, 0}, + {0x63, 0}, + {0x66, 0}, + {0x69, 0}, + {0x70, 0}, + {0x77, 0}, + {0x86, 0}, + {0x99, 0}, + }, + /* 95 */ + { + {0xc000, 92}, + {0xc000, 195}, + {0xc000, 208}, + {0x64, 0}, + {0x67, 0}, + {0x68, 0}, + {0x6a, 0}, + {0x6b, 0}, + {0x71, 0}, + {0x74, 0}, + {0x78, 0}, + {0x7e, 0}, + {0x87, 0}, + {0x8e, 0}, + {0x9a, 0}, + {0xa9, 0}, + }, + /* 96 */ + { + {0x8001, 92}, + {0xc016, 92}, + {0x8001, 195}, + {0xc016, 195}, + {0x8001, 208}, + {0xc016, 208}, + {0xc000, 128}, + {0xc000, 130}, + {0xc000, 131}, + {0xc000, 162}, + {0xc000, 184}, + {0xc000, 194}, + {0xc000, 224}, + {0xc000, 226}, + {0x6c, 0}, + {0x6d, 0}, + }, + /* 97 */ + { + {0x8002, 92}, + {0x8009, 92}, + {0x8017, 92}, + {0xc028, 92}, + {0x8002, 195}, + {0x8009, 195}, + {0x8017, 195}, + {0xc028, 195}, + {0x8002, 208}, + {0x8009, 208}, + {0x8017, 208}, + {0xc028, 208}, + {0x8001, 128}, + {0xc016, 128}, + {0x8001, 130}, + {0xc016, 130}, + }, + /* 98 */ + { + {0x8003, 92}, + {0x8006, 92}, + {0x800a, 92}, + {0x800f, 92}, + {0x8018, 92}, + {0x801f, 92}, + {0x8029, 92}, + {0xc038, 92}, + {0x8003, 195}, + {0x8006, 195}, + {0x800a, 195}, + {0x800f, 195}, + {0x8018, 195}, + {0x801f, 195}, + {0x8029, 195}, + {0xc038, 195}, + }, + /* 99 */ + { + {0x8003, 208}, + {0x8006, 208}, + {0x800a, 208}, + {0x800f, 208}, + {0x8018, 208}, + {0x801f, 208}, + {0x8029, 208}, + {0xc038, 208}, + {0x8002, 128}, + {0x8009, 128}, + {0x8017, 128}, + {0xc028, 128}, + {0x8002, 130}, + {0x8009, 130}, + {0x8017, 130}, + {0xc028, 130}, + }, + /* 100 */ + { + {0x8003, 128}, + {0x8006, 128}, + {0x800a, 128}, + {0x800f, 128}, + {0x8018, 128}, + {0x801f, 128}, + {0x8029, 128}, + {0xc038, 128}, + {0x8003, 130}, + {0x8006, 130}, + {0x800a, 130}, + {0x800f, 130}, + {0x8018, 130}, + {0x801f, 130}, + {0x8029, 130}, + {0xc038, 130}, + }, + /* 101 */ + { + {0x8001, 131}, + {0xc016, 131}, + {0x8001, 162}, + {0xc016, 162}, + {0x8001, 184}, + {0xc016, 184}, + {0x8001, 194}, + {0xc016, 194}, + {0x8001, 224}, + {0xc016, 224}, + {0x8001, 226}, + {0xc016, 226}, + {0xc000, 153}, + {0xc000, 161}, + {0xc000, 167}, + {0xc000, 172}, + }, + /* 102 */ + { + {0x8002, 131}, + {0x8009, 131}, + {0x8017, 131}, + {0xc028, 131}, + {0x8002, 162}, + {0x8009, 162}, + {0x8017, 162}, + {0xc028, 162}, + {0x8002, 184}, + {0x8009, 184}, + {0x8017, 184}, + {0xc028, 184}, + {0x8002, 194}, + {0x8009, 194}, + {0x8017, 194}, + {0xc028, 194}, + }, + /* 103 */ + { + {0x8003, 131}, + {0x8006, 131}, + {0x800a, 131}, + {0x800f, 131}, + {0x8018, 131}, + {0x801f, 131}, + {0x8029, 131}, + {0xc038, 131}, + {0x8003, 162}, + {0x8006, 162}, + {0x800a, 162}, + {0x800f, 162}, + {0x8018, 162}, + {0x801f, 162}, + {0x8029, 162}, + {0xc038, 162}, + }, + /* 104 */ + { + {0x8003, 184}, + {0x8006, 184}, + {0x800a, 184}, + {0x800f, 184}, + {0x8018, 184}, + {0x801f, 184}, + {0x8029, 184}, + {0xc038, 184}, + {0x8003, 194}, + {0x8006, 194}, + {0x800a, 194}, + {0x800f, 194}, + {0x8018, 194}, + {0x801f, 194}, + {0x8029, 194}, + {0xc038, 194}, + }, + /* 105 */ + { + {0x8002, 224}, + {0x8009, 224}, + {0x8017, 224}, + {0xc028, 224}, + {0x8002, 226}, + {0x8009, 226}, + {0x8017, 226}, + {0xc028, 226}, + {0x8001, 153}, + {0xc016, 153}, + {0x8001, 161}, + {0xc016, 161}, + {0x8001, 167}, + {0xc016, 167}, + {0x8001, 172}, + {0xc016, 172}, + }, + /* 106 */ + { + {0x8003, 224}, + {0x8006, 224}, + {0x800a, 224}, + {0x800f, 224}, + {0x8018, 224}, + {0x801f, 224}, + {0x8029, 224}, + {0xc038, 224}, + {0x8003, 226}, + {0x8006, 226}, + {0x800a, 226}, + {0x800f, 226}, + {0x8018, 226}, + {0x801f, 226}, + {0x8029, 226}, + {0xc038, 226}, + }, + /* 107 */ + { + {0x8002, 153}, + {0x8009, 153}, + {0x8017, 153}, + {0xc028, 153}, + {0x8002, 161}, + {0x8009, 161}, + {0x8017, 161}, + {0xc028, 161}, + {0x8002, 167}, + {0x8009, 167}, + {0x8017, 167}, + {0xc028, 167}, + {0x8002, 172}, + {0x8009, 172}, + {0x8017, 172}, + {0xc028, 172}, + }, + /* 108 */ + { + {0x8003, 153}, + {0x8006, 153}, + {0x800a, 153}, + {0x800f, 153}, + {0x8018, 153}, + {0x801f, 153}, + {0x8029, 153}, + {0xc038, 153}, + {0x8003, 161}, + {0x8006, 161}, + {0x800a, 161}, + {0x800f, 161}, + {0x8018, 161}, + {0x801f, 161}, + {0x8029, 161}, + {0xc038, 161}, + }, + /* 109 */ + { + {0x8003, 167}, + {0x8006, 167}, + {0x800a, 167}, + {0x800f, 167}, + {0x8018, 167}, + {0x801f, 167}, + {0x8029, 167}, + {0xc038, 167}, + {0x8003, 172}, + {0x8006, 172}, + {0x800a, 172}, + {0x800f, 172}, + {0x8018, 172}, + {0x801f, 172}, + {0x8029, 172}, + {0xc038, 172}, + }, + /* 110 */ + { + {0x72, 0}, + {0x73, 0}, + {0x75, 0}, + {0x76, 0}, + {0x79, 0}, + {0x7b, 0}, + {0x7f, 0}, + {0x82, 0}, + {0x88, 0}, + {0x8b, 0}, + {0x8f, 0}, + {0x92, 0}, + {0x9b, 0}, + {0xa2, 0}, + {0xaa, 0}, + {0xb4, 0}, + }, + /* 111 */ + { + {0xc000, 176}, + {0xc000, 177}, + {0xc000, 179}, + {0xc000, 209}, + {0xc000, 216}, + {0xc000, 217}, + {0xc000, 227}, + {0xc000, 229}, + {0xc000, 230}, + {0x7a, 0}, + {0x7c, 0}, + {0x7d, 0}, + {0x80, 0}, + {0x81, 0}, + {0x83, 0}, + {0x84, 0}, + }, + /* 112 */ + { + {0x8001, 176}, + {0xc016, 176}, + {0x8001, 177}, + {0xc016, 177}, + {0x8001, 179}, + {0xc016, 179}, + {0x8001, 209}, + {0xc016, 209}, + {0x8001, 216}, + {0xc016, 216}, + {0x8001, 217}, + {0xc016, 217}, + {0x8001, 227}, + {0xc016, 227}, + {0x8001, 229}, + {0xc016, 229}, + }, + /* 113 */ + { + {0x8002, 176}, + {0x8009, 176}, + {0x8017, 176}, + {0xc028, 176}, + {0x8002, 177}, + {0x8009, 177}, + {0x8017, 177}, + {0xc028, 177}, + {0x8002, 179}, + {0x8009, 179}, + {0x8017, 179}, + {0xc028, 179}, + {0x8002, 209}, + {0x8009, 209}, + {0x8017, 209}, + {0xc028, 209}, + }, + /* 114 */ + { + {0x8003, 176}, + {0x8006, 176}, + {0x800a, 176}, + {0x800f, 176}, + {0x8018, 176}, + {0x801f, 176}, + {0x8029, 176}, + {0xc038, 176}, + {0x8003, 177}, + {0x8006, 177}, + {0x800a, 177}, + {0x800f, 177}, + {0x8018, 177}, + {0x801f, 177}, + {0x8029, 177}, + {0xc038, 177}, + }, + /* 115 */ + { + {0x8003, 179}, + {0x8006, 179}, + {0x800a, 179}, + {0x800f, 179}, + {0x8018, 179}, + {0x801f, 179}, + {0x8029, 179}, + {0xc038, 179}, + {0x8003, 209}, + {0x8006, 209}, + {0x800a, 209}, + {0x800f, 209}, + {0x8018, 209}, + {0x801f, 209}, + {0x8029, 209}, + {0xc038, 209}, + }, + /* 116 */ + { + {0x8002, 216}, + {0x8009, 216}, + {0x8017, 216}, + {0xc028, 216}, + {0x8002, 217}, + {0x8009, 217}, + {0x8017, 217}, + {0xc028, 217}, + {0x8002, 227}, + {0x8009, 227}, + {0x8017, 227}, + {0xc028, 227}, + {0x8002, 229}, + {0x8009, 229}, + {0x8017, 229}, + {0xc028, 229}, + }, + /* 117 */ + { + {0x8003, 216}, + {0x8006, 216}, + {0x800a, 216}, + {0x800f, 216}, + {0x8018, 216}, + {0x801f, 216}, + {0x8029, 216}, + {0xc038, 216}, + {0x8003, 217}, + {0x8006, 217}, + {0x800a, 217}, + {0x800f, 217}, + {0x8018, 217}, + {0x801f, 217}, + {0x8029, 217}, + {0xc038, 217}, + }, + /* 118 */ + { + {0x8003, 227}, + {0x8006, 227}, + {0x800a, 227}, + {0x800f, 227}, + {0x8018, 227}, + {0x801f, 227}, + {0x8029, 227}, + {0xc038, 227}, + {0x8003, 229}, + {0x8006, 229}, + {0x800a, 229}, + {0x800f, 229}, + {0x8018, 229}, + {0x801f, 229}, + {0x8029, 229}, + {0xc038, 229}, + }, + /* 119 */ + { + {0x8001, 230}, + {0xc016, 230}, + {0xc000, 129}, + {0xc000, 132}, + {0xc000, 133}, + {0xc000, 134}, + {0xc000, 136}, + {0xc000, 146}, + {0xc000, 154}, + {0xc000, 156}, + {0xc000, 160}, + {0xc000, 163}, + {0xc000, 164}, + {0xc000, 169}, + {0xc000, 170}, + {0xc000, 173}, + }, + /* 120 */ + { + {0x8002, 230}, + {0x8009, 230}, + {0x8017, 230}, + {0xc028, 230}, + {0x8001, 129}, + {0xc016, 129}, + {0x8001, 132}, + {0xc016, 132}, + {0x8001, 133}, + {0xc016, 133}, + {0x8001, 134}, + {0xc016, 134}, + {0x8001, 136}, + {0xc016, 136}, + {0x8001, 146}, + {0xc016, 146}, + }, + /* 121 */ + { + {0x8003, 230}, + {0x8006, 230}, + {0x800a, 230}, + {0x800f, 230}, + {0x8018, 230}, + {0x801f, 230}, + {0x8029, 230}, + {0xc038, 230}, + {0x8002, 129}, + {0x8009, 129}, + {0x8017, 129}, + {0xc028, 129}, + {0x8002, 132}, + {0x8009, 132}, + {0x8017, 132}, + {0xc028, 132}, + }, + /* 122 */ + { + {0x8003, 129}, + {0x8006, 129}, + {0x800a, 129}, + {0x800f, 129}, + {0x8018, 129}, + {0x801f, 129}, + {0x8029, 129}, + {0xc038, 129}, + {0x8003, 132}, + {0x8006, 132}, + {0x800a, 132}, + {0x800f, 132}, + {0x8018, 132}, + {0x801f, 132}, + {0x8029, 132}, + {0xc038, 132}, + }, + /* 123 */ + { + {0x8002, 133}, + {0x8009, 133}, + {0x8017, 133}, + {0xc028, 133}, + {0x8002, 134}, + {0x8009, 134}, + {0x8017, 134}, + {0xc028, 134}, + {0x8002, 136}, + {0x8009, 136}, + {0x8017, 136}, + {0xc028, 136}, + {0x8002, 146}, + {0x8009, 146}, + {0x8017, 146}, + {0xc028, 146}, + }, + /* 124 */ + { + {0x8003, 133}, + {0x8006, 133}, + {0x800a, 133}, + {0x800f, 133}, + {0x8018, 133}, + {0x801f, 133}, + {0x8029, 133}, + {0xc038, 133}, + {0x8003, 134}, + {0x8006, 134}, + {0x800a, 134}, + {0x800f, 134}, + {0x8018, 134}, + {0x801f, 134}, + {0x8029, 134}, + {0xc038, 134}, + }, + /* 125 */ + { + {0x8003, 136}, + {0x8006, 136}, + {0x800a, 136}, + {0x800f, 136}, + {0x8018, 136}, + {0x801f, 136}, + {0x8029, 136}, + {0xc038, 136}, + {0x8003, 146}, + {0x8006, 146}, + {0x800a, 146}, + {0x800f, 146}, + {0x8018, 146}, + {0x801f, 146}, + {0x8029, 146}, + {0xc038, 146}, + }, + /* 126 */ + { + {0x8001, 154}, + {0xc016, 154}, + {0x8001, 156}, + {0xc016, 156}, + {0x8001, 160}, + {0xc016, 160}, + {0x8001, 163}, + {0xc016, 163}, + {0x8001, 164}, + {0xc016, 164}, + {0x8001, 169}, + {0xc016, 169}, + {0x8001, 170}, + {0xc016, 170}, + {0x8001, 173}, + {0xc016, 173}, + }, + /* 127 */ + { + {0x8002, 154}, + {0x8009, 154}, + {0x8017, 154}, + {0xc028, 154}, + {0x8002, 156}, + {0x8009, 156}, + {0x8017, 156}, + {0xc028, 156}, + {0x8002, 160}, + {0x8009, 160}, + {0x8017, 160}, + {0xc028, 160}, + {0x8002, 163}, + {0x8009, 163}, + {0x8017, 163}, + {0xc028, 163}, + }, + /* 128 */ + { + {0x8003, 154}, + {0x8006, 154}, + {0x800a, 154}, + {0x800f, 154}, + {0x8018, 154}, + {0x801f, 154}, + {0x8029, 154}, + {0xc038, 154}, + {0x8003, 156}, + {0x8006, 156}, + {0x800a, 156}, + {0x800f, 156}, + {0x8018, 156}, + {0x801f, 156}, + {0x8029, 156}, + {0xc038, 156}, + }, + /* 129 */ + { + {0x8003, 160}, + {0x8006, 160}, + {0x800a, 160}, + {0x800f, 160}, + {0x8018, 160}, + {0x801f, 160}, + {0x8029, 160}, + {0xc038, 160}, + {0x8003, 163}, + {0x8006, 163}, + {0x800a, 163}, + {0x800f, 163}, + {0x8018, 163}, + {0x801f, 163}, + {0x8029, 163}, + {0xc038, 163}, + }, + /* 130 */ + { + {0x8002, 164}, + {0x8009, 164}, + {0x8017, 164}, + {0xc028, 164}, + {0x8002, 169}, + {0x8009, 169}, + {0x8017, 169}, + {0xc028, 169}, + {0x8002, 170}, + {0x8009, 170}, + {0x8017, 170}, + {0xc028, 170}, + {0x8002, 173}, + {0x8009, 173}, + {0x8017, 173}, + {0xc028, 173}, + }, + /* 131 */ + { + {0x8003, 164}, + {0x8006, 164}, + {0x800a, 164}, + {0x800f, 164}, + {0x8018, 164}, + {0x801f, 164}, + {0x8029, 164}, + {0xc038, 164}, + {0x8003, 169}, + {0x8006, 169}, + {0x800a, 169}, + {0x800f, 169}, + {0x8018, 169}, + {0x801f, 169}, + {0x8029, 169}, + {0xc038, 169}, + }, + /* 132 */ + { + {0x8003, 170}, + {0x8006, 170}, + {0x800a, 170}, + {0x800f, 170}, + {0x8018, 170}, + {0x801f, 170}, + {0x8029, 170}, + {0xc038, 170}, + {0x8003, 173}, + {0x8006, 173}, + {0x800a, 173}, + {0x800f, 173}, + {0x8018, 173}, + {0x801f, 173}, + {0x8029, 173}, + {0xc038, 173}, + }, + /* 133 */ + { + {0x89, 0}, + {0x8a, 0}, + {0x8c, 0}, + {0x8d, 0}, + {0x90, 0}, + {0x91, 0}, + {0x93, 0}, + {0x96, 0}, + {0x9c, 0}, + {0x9f, 0}, + {0xa3, 0}, + {0xa6, 0}, + {0xab, 0}, + {0xae, 0}, + {0xb5, 0}, + {0xbe, 0}, + }, + /* 134 */ + { + {0xc000, 178}, + {0xc000, 181}, + {0xc000, 185}, + {0xc000, 186}, + {0xc000, 187}, + {0xc000, 189}, + {0xc000, 190}, + {0xc000, 196}, + {0xc000, 198}, + {0xc000, 228}, + {0xc000, 232}, + {0xc000, 233}, + {0x94, 0}, + {0x95, 0}, + {0x97, 0}, + {0x98, 0}, + }, + /* 135 */ + { + {0x8001, 178}, + {0xc016, 178}, + {0x8001, 181}, + {0xc016, 181}, + {0x8001, 185}, + {0xc016, 185}, + {0x8001, 186}, + {0xc016, 186}, + {0x8001, 187}, + {0xc016, 187}, + {0x8001, 189}, + {0xc016, 189}, + {0x8001, 190}, + {0xc016, 190}, + {0x8001, 196}, + {0xc016, 196}, + }, + /* 136 */ + { + {0x8002, 178}, + {0x8009, 178}, + {0x8017, 178}, + {0xc028, 178}, + {0x8002, 181}, + {0x8009, 181}, + {0x8017, 181}, + {0xc028, 181}, + {0x8002, 185}, + {0x8009, 185}, + {0x8017, 185}, + {0xc028, 185}, + {0x8002, 186}, + {0x8009, 186}, + {0x8017, 186}, + {0xc028, 186}, + }, + /* 137 */ + { + {0x8003, 178}, + {0x8006, 178}, + {0x800a, 178}, + {0x800f, 178}, + {0x8018, 178}, + {0x801f, 178}, + {0x8029, 178}, + {0xc038, 178}, + {0x8003, 181}, + {0x8006, 181}, + {0x800a, 181}, + {0x800f, 181}, + {0x8018, 181}, + {0x801f, 181}, + {0x8029, 181}, + {0xc038, 181}, + }, + /* 138 */ + { + {0x8003, 185}, + {0x8006, 185}, + {0x800a, 185}, + {0x800f, 185}, + {0x8018, 185}, + {0x801f, 185}, + {0x8029, 185}, + {0xc038, 185}, + {0x8003, 186}, + {0x8006, 186}, + {0x800a, 186}, + {0x800f, 186}, + {0x8018, 186}, + {0x801f, 186}, + {0x8029, 186}, + {0xc038, 186}, + }, + /* 139 */ + { + {0x8002, 187}, + {0x8009, 187}, + {0x8017, 187}, + {0xc028, 187}, + {0x8002, 189}, + {0x8009, 189}, + {0x8017, 189}, + {0xc028, 189}, + {0x8002, 190}, + {0x8009, 190}, + {0x8017, 190}, + {0xc028, 190}, + {0x8002, 196}, + {0x8009, 196}, + {0x8017, 196}, + {0xc028, 196}, + }, + /* 140 */ + { + {0x8003, 187}, + {0x8006, 187}, + {0x800a, 187}, + {0x800f, 187}, + {0x8018, 187}, + {0x801f, 187}, + {0x8029, 187}, + {0xc038, 187}, + {0x8003, 189}, + {0x8006, 189}, + {0x800a, 189}, + {0x800f, 189}, + {0x8018, 189}, + {0x801f, 189}, + {0x8029, 189}, + {0xc038, 189}, + }, + /* 141 */ + { + {0x8003, 190}, + {0x8006, 190}, + {0x800a, 190}, + {0x800f, 190}, + {0x8018, 190}, + {0x801f, 190}, + {0x8029, 190}, + {0xc038, 190}, + {0x8003, 196}, + {0x8006, 196}, + {0x800a, 196}, + {0x800f, 196}, + {0x8018, 196}, + {0x801f, 196}, + {0x8029, 196}, + {0xc038, 196}, + }, + /* 142 */ + { + {0x8001, 198}, + {0xc016, 198}, + {0x8001, 228}, + {0xc016, 228}, + {0x8001, 232}, + {0xc016, 232}, + {0x8001, 233}, + {0xc016, 233}, + {0xc000, 1}, + {0xc000, 135}, + {0xc000, 137}, + {0xc000, 138}, + {0xc000, 139}, + {0xc000, 140}, + {0xc000, 141}, + {0xc000, 143}, + }, + /* 143 */ + { + {0x8002, 198}, + {0x8009, 198}, + {0x8017, 198}, + {0xc028, 198}, + {0x8002, 228}, + {0x8009, 228}, + {0x8017, 228}, + {0xc028, 228}, + {0x8002, 232}, + {0x8009, 232}, + {0x8017, 232}, + {0xc028, 232}, + {0x8002, 233}, + {0x8009, 233}, + {0x8017, 233}, + {0xc028, 233}, + }, + /* 144 */ + { + {0x8003, 198}, + {0x8006, 198}, + {0x800a, 198}, + {0x800f, 198}, + {0x8018, 198}, + {0x801f, 198}, + {0x8029, 198}, + {0xc038, 198}, + {0x8003, 228}, + {0x8006, 228}, + {0x800a, 228}, + {0x800f, 228}, + {0x8018, 228}, + {0x801f, 228}, + {0x8029, 228}, + {0xc038, 228}, + }, + /* 145 */ + { + {0x8003, 232}, + {0x8006, 232}, + {0x800a, 232}, + {0x800f, 232}, + {0x8018, 232}, + {0x801f, 232}, + {0x8029, 232}, + {0xc038, 232}, + {0x8003, 233}, + {0x8006, 233}, + {0x800a, 233}, + {0x800f, 233}, + {0x8018, 233}, + {0x801f, 233}, + {0x8029, 233}, + {0xc038, 233}, + }, + /* 146 */ + { + {0x8001, 1}, + {0xc016, 1}, + {0x8001, 135}, + {0xc016, 135}, + {0x8001, 137}, + {0xc016, 137}, + {0x8001, 138}, + {0xc016, 138}, + {0x8001, 139}, + {0xc016, 139}, + {0x8001, 140}, + {0xc016, 140}, + {0x8001, 141}, + {0xc016, 141}, + {0x8001, 143}, + {0xc016, 143}, + }, + /* 147 */ + { + {0x8002, 1}, + {0x8009, 1}, + {0x8017, 1}, + {0xc028, 1}, + {0x8002, 135}, + {0x8009, 135}, + {0x8017, 135}, + {0xc028, 135}, + {0x8002, 137}, + {0x8009, 137}, + {0x8017, 137}, + {0xc028, 137}, + {0x8002, 138}, + {0x8009, 138}, + {0x8017, 138}, + {0xc028, 138}, + }, + /* 148 */ + { + {0x8003, 1}, + {0x8006, 1}, + {0x800a, 1}, + {0x800f, 1}, + {0x8018, 1}, + {0x801f, 1}, + {0x8029, 1}, + {0xc038, 1}, + {0x8003, 135}, + {0x8006, 135}, + {0x800a, 135}, + {0x800f, 135}, + {0x8018, 135}, + {0x801f, 135}, + {0x8029, 135}, + {0xc038, 135}, + }, + /* 149 */ + { + {0x8003, 137}, + {0x8006, 137}, + {0x800a, 137}, + {0x800f, 137}, + {0x8018, 137}, + {0x801f, 137}, + {0x8029, 137}, + {0xc038, 137}, + {0x8003, 138}, + {0x8006, 138}, + {0x800a, 138}, + {0x800f, 138}, + {0x8018, 138}, + {0x801f, 138}, + {0x8029, 138}, + {0xc038, 138}, + }, + /* 150 */ + { + {0x8002, 139}, + {0x8009, 139}, + {0x8017, 139}, + {0xc028, 139}, + {0x8002, 140}, + {0x8009, 140}, + {0x8017, 140}, + {0xc028, 140}, + {0x8002, 141}, + {0x8009, 141}, + {0x8017, 141}, + {0xc028, 141}, + {0x8002, 143}, + {0x8009, 143}, + {0x8017, 143}, + {0xc028, 143}, + }, + /* 151 */ + { + {0x8003, 139}, + {0x8006, 139}, + {0x800a, 139}, + {0x800f, 139}, + {0x8018, 139}, + {0x801f, 139}, + {0x8029, 139}, + {0xc038, 139}, + {0x8003, 140}, + {0x8006, 140}, + {0x800a, 140}, + {0x800f, 140}, + {0x8018, 140}, + {0x801f, 140}, + {0x8029, 140}, + {0xc038, 140}, + }, + /* 152 */ + { + {0x8003, 141}, + {0x8006, 141}, + {0x800a, 141}, + {0x800f, 141}, + {0x8018, 141}, + {0x801f, 141}, + {0x8029, 141}, + {0xc038, 141}, + {0x8003, 143}, + {0x8006, 143}, + {0x800a, 143}, + {0x800f, 143}, + {0x8018, 143}, + {0x801f, 143}, + {0x8029, 143}, + {0xc038, 143}, + }, + /* 153 */ + { + {0x9d, 0}, + {0x9e, 0}, + {0xa0, 0}, + {0xa1, 0}, + {0xa4, 0}, + {0xa5, 0}, + {0xa7, 0}, + {0xa8, 0}, + {0xac, 0}, + {0xad, 0}, + {0xaf, 0}, + {0xb1, 0}, + {0xb6, 0}, + {0xb9, 0}, + {0xbf, 0}, + {0xcf, 0}, + }, + /* 154 */ + { + {0xc000, 147}, + {0xc000, 149}, + {0xc000, 150}, + {0xc000, 151}, + {0xc000, 152}, + {0xc000, 155}, + {0xc000, 157}, + {0xc000, 158}, + {0xc000, 165}, + {0xc000, 166}, + {0xc000, 168}, + {0xc000, 174}, + {0xc000, 175}, + {0xc000, 180}, + {0xc000, 182}, + {0xc000, 183}, + }, + /* 155 */ + { + {0x8001, 147}, + {0xc016, 147}, + {0x8001, 149}, + {0xc016, 149}, + {0x8001, 150}, + {0xc016, 150}, + {0x8001, 151}, + {0xc016, 151}, + {0x8001, 152}, + {0xc016, 152}, + {0x8001, 155}, + {0xc016, 155}, + {0x8001, 157}, + {0xc016, 157}, + {0x8001, 158}, + {0xc016, 158}, + }, + /* 156 */ + { + {0x8002, 147}, + {0x8009, 147}, + {0x8017, 147}, + {0xc028, 147}, + {0x8002, 149}, + {0x8009, 149}, + {0x8017, 149}, + {0xc028, 149}, + {0x8002, 150}, + {0x8009, 150}, + {0x8017, 150}, + {0xc028, 150}, + {0x8002, 151}, + {0x8009, 151}, + {0x8017, 151}, + {0xc028, 151}, + }, + /* 157 */ + { + {0x8003, 147}, + {0x8006, 147}, + {0x800a, 147}, + {0x800f, 147}, + {0x8018, 147}, + {0x801f, 147}, + {0x8029, 147}, + {0xc038, 147}, + {0x8003, 149}, + {0x8006, 149}, + {0x800a, 149}, + {0x800f, 149}, + {0x8018, 149}, + {0x801f, 149}, + {0x8029, 149}, + {0xc038, 149}, + }, + /* 158 */ + { + {0x8003, 150}, + {0x8006, 150}, + {0x800a, 150}, + {0x800f, 150}, + {0x8018, 150}, + {0x801f, 150}, + {0x8029, 150}, + {0xc038, 150}, + {0x8003, 151}, + {0x8006, 151}, + {0x800a, 151}, + {0x800f, 151}, + {0x8018, 151}, + {0x801f, 151}, + {0x8029, 151}, + {0xc038, 151}, + }, + /* 159 */ + { + {0x8002, 152}, + {0x8009, 152}, + {0x8017, 152}, + {0xc028, 152}, + {0x8002, 155}, + {0x8009, 155}, + {0x8017, 155}, + {0xc028, 155}, + {0x8002, 157}, + {0x8009, 157}, + {0x8017, 157}, + {0xc028, 157}, + {0x8002, 158}, + {0x8009, 158}, + {0x8017, 158}, + {0xc028, 158}, + }, + /* 160 */ + { + {0x8003, 152}, + {0x8006, 152}, + {0x800a, 152}, + {0x800f, 152}, + {0x8018, 152}, + {0x801f, 152}, + {0x8029, 152}, + {0xc038, 152}, + {0x8003, 155}, + {0x8006, 155}, + {0x800a, 155}, + {0x800f, 155}, + {0x8018, 155}, + {0x801f, 155}, + {0x8029, 155}, + {0xc038, 155}, + }, + /* 161 */ + { + {0x8003, 157}, + {0x8006, 157}, + {0x800a, 157}, + {0x800f, 157}, + {0x8018, 157}, + {0x801f, 157}, + {0x8029, 157}, + {0xc038, 157}, + {0x8003, 158}, + {0x8006, 158}, + {0x800a, 158}, + {0x800f, 158}, + {0x8018, 158}, + {0x801f, 158}, + {0x8029, 158}, + {0xc038, 158}, + }, + /* 162 */ + { + {0x8001, 165}, + {0xc016, 165}, + {0x8001, 166}, + {0xc016, 166}, + {0x8001, 168}, + {0xc016, 168}, + {0x8001, 174}, + {0xc016, 174}, + {0x8001, 175}, + {0xc016, 175}, + {0x8001, 180}, + {0xc016, 180}, + {0x8001, 182}, + {0xc016, 182}, + {0x8001, 183}, + {0xc016, 183}, + }, + /* 163 */ + { + {0x8002, 165}, + {0x8009, 165}, + {0x8017, 165}, + {0xc028, 165}, + {0x8002, 166}, + {0x8009, 166}, + {0x8017, 166}, + {0xc028, 166}, + {0x8002, 168}, + {0x8009, 168}, + {0x8017, 168}, + {0xc028, 168}, + {0x8002, 174}, + {0x8009, 174}, + {0x8017, 174}, + {0xc028, 174}, + }, + /* 164 */ + { + {0x8003, 165}, + {0x8006, 165}, + {0x800a, 165}, + {0x800f, 165}, + {0x8018, 165}, + {0x801f, 165}, + {0x8029, 165}, + {0xc038, 165}, + {0x8003, 166}, + {0x8006, 166}, + {0x800a, 166}, + {0x800f, 166}, + {0x8018, 166}, + {0x801f, 166}, + {0x8029, 166}, + {0xc038, 166}, + }, + /* 165 */ + { + {0x8003, 168}, + {0x8006, 168}, + {0x800a, 168}, + {0x800f, 168}, + {0x8018, 168}, + {0x801f, 168}, + {0x8029, 168}, + {0xc038, 168}, + {0x8003, 174}, + {0x8006, 174}, + {0x800a, 174}, + {0x800f, 174}, + {0x8018, 174}, + {0x801f, 174}, + {0x8029, 174}, + {0xc038, 174}, + }, + /* 166 */ + { + {0x8002, 175}, + {0x8009, 175}, + {0x8017, 175}, + {0xc028, 175}, + {0x8002, 180}, + {0x8009, 180}, + {0x8017, 180}, + {0xc028, 180}, + {0x8002, 182}, + {0x8009, 182}, + {0x8017, 182}, + {0xc028, 182}, + {0x8002, 183}, + {0x8009, 183}, + {0x8017, 183}, + {0xc028, 183}, + }, + /* 167 */ + { + {0x8003, 175}, + {0x8006, 175}, + {0x800a, 175}, + {0x800f, 175}, + {0x8018, 175}, + {0x801f, 175}, + {0x8029, 175}, + {0xc038, 175}, + {0x8003, 180}, + {0x8006, 180}, + {0x800a, 180}, + {0x800f, 180}, + {0x8018, 180}, + {0x801f, 180}, + {0x8029, 180}, + {0xc038, 180}, + }, + /* 168 */ + { + {0x8003, 182}, + {0x8006, 182}, + {0x800a, 182}, + {0x800f, 182}, + {0x8018, 182}, + {0x801f, 182}, + {0x8029, 182}, + {0xc038, 182}, + {0x8003, 183}, + {0x8006, 183}, + {0x800a, 183}, + {0x800f, 183}, + {0x8018, 183}, + {0x801f, 183}, + {0x8029, 183}, + {0xc038, 183}, + }, + /* 169 */ + { + {0xc000, 188}, + {0xc000, 191}, + {0xc000, 197}, + {0xc000, 231}, + {0xc000, 239}, + {0xb0, 0}, + {0xb2, 0}, + {0xb3, 0}, + {0xb7, 0}, + {0xb8, 0}, + {0xba, 0}, + {0xbb, 0}, + {0xc0, 0}, + {0xc7, 0}, + {0xd0, 0}, + {0xdf, 0}, + }, + /* 170 */ + { + {0x8001, 188}, + {0xc016, 188}, + {0x8001, 191}, + {0xc016, 191}, + {0x8001, 197}, + {0xc016, 197}, + {0x8001, 231}, + {0xc016, 231}, + {0x8001, 239}, + {0xc016, 239}, + {0xc000, 9}, + {0xc000, 142}, + {0xc000, 144}, + {0xc000, 145}, + {0xc000, 148}, + {0xc000, 159}, + }, + /* 171 */ + { + {0x8002, 188}, + {0x8009, 188}, + {0x8017, 188}, + {0xc028, 188}, + {0x8002, 191}, + {0x8009, 191}, + {0x8017, 191}, + {0xc028, 191}, + {0x8002, 197}, + {0x8009, 197}, + {0x8017, 197}, + {0xc028, 197}, + {0x8002, 231}, + {0x8009, 231}, + {0x8017, 231}, + {0xc028, 231}, + }, + /* 172 */ + { + {0x8003, 188}, + {0x8006, 188}, + {0x800a, 188}, + {0x800f, 188}, + {0x8018, 188}, + {0x801f, 188}, + {0x8029, 188}, + {0xc038, 188}, + {0x8003, 191}, + {0x8006, 191}, + {0x800a, 191}, + {0x800f, 191}, + {0x8018, 191}, + {0x801f, 191}, + {0x8029, 191}, + {0xc038, 191}, + }, + /* 173 */ + { + {0x8003, 197}, + {0x8006, 197}, + {0x800a, 197}, + {0x800f, 197}, + {0x8018, 197}, + {0x801f, 197}, + {0x8029, 197}, + {0xc038, 197}, + {0x8003, 231}, + {0x8006, 231}, + {0x800a, 231}, + {0x800f, 231}, + {0x8018, 231}, + {0x801f, 231}, + {0x8029, 231}, + {0xc038, 231}, + }, + /* 174 */ + { + {0x8002, 239}, + {0x8009, 239}, + {0x8017, 239}, + {0xc028, 239}, + {0x8001, 9}, + {0xc016, 9}, + {0x8001, 142}, + {0xc016, 142}, + {0x8001, 144}, + {0xc016, 144}, + {0x8001, 145}, + {0xc016, 145}, + {0x8001, 148}, + {0xc016, 148}, + {0x8001, 159}, + {0xc016, 159}, + }, + /* 175 */ + { + {0x8003, 239}, + {0x8006, 239}, + {0x800a, 239}, + {0x800f, 239}, + {0x8018, 239}, + {0x801f, 239}, + {0x8029, 239}, + {0xc038, 239}, + {0x8002, 9}, + {0x8009, 9}, + {0x8017, 9}, + {0xc028, 9}, + {0x8002, 142}, + {0x8009, 142}, + {0x8017, 142}, + {0xc028, 142}, + }, + /* 176 */ + { + {0x8003, 9}, + {0x8006, 9}, + {0x800a, 9}, + {0x800f, 9}, + {0x8018, 9}, + {0x801f, 9}, + {0x8029, 9}, + {0xc038, 9}, + {0x8003, 142}, + {0x8006, 142}, + {0x800a, 142}, + {0x800f, 142}, + {0x8018, 142}, + {0x801f, 142}, + {0x8029, 142}, + {0xc038, 142}, + }, + /* 177 */ + { + {0x8002, 144}, + {0x8009, 144}, + {0x8017, 144}, + {0xc028, 144}, + {0x8002, 145}, + {0x8009, 145}, + {0x8017, 145}, + {0xc028, 145}, + {0x8002, 148}, + {0x8009, 148}, + {0x8017, 148}, + {0xc028, 148}, + {0x8002, 159}, + {0x8009, 159}, + {0x8017, 159}, + {0xc028, 159}, + }, + /* 178 */ + { + {0x8003, 144}, + {0x8006, 144}, + {0x800a, 144}, + {0x800f, 144}, + {0x8018, 144}, + {0x801f, 144}, + {0x8029, 144}, + {0xc038, 144}, + {0x8003, 145}, + {0x8006, 145}, + {0x800a, 145}, + {0x800f, 145}, + {0x8018, 145}, + {0x801f, 145}, + {0x8029, 145}, + {0xc038, 145}, + }, + /* 179 */ + { + {0x8003, 148}, + {0x8006, 148}, + {0x800a, 148}, + {0x800f, 148}, + {0x8018, 148}, + {0x801f, 148}, + {0x8029, 148}, + {0xc038, 148}, + {0x8003, 159}, + {0x8006, 159}, + {0x800a, 159}, + {0x800f, 159}, + {0x8018, 159}, + {0x801f, 159}, + {0x8029, 159}, + {0xc038, 159}, + }, + /* 180 */ + { + {0xc000, 171}, + {0xc000, 206}, + {0xc000, 215}, + {0xc000, 225}, + {0xc000, 236}, + {0xc000, 237}, + {0xbc, 0}, + {0xbd, 0}, + {0xc1, 0}, + {0xc4, 0}, + {0xc8, 0}, + {0xcb, 0}, + {0xd1, 0}, + {0xd8, 0}, + {0xe0, 0}, + {0xee, 0}, + }, + /* 181 */ + { + {0x8001, 171}, + {0xc016, 171}, + {0x8001, 206}, + {0xc016, 206}, + {0x8001, 215}, + {0xc016, 215}, + {0x8001, 225}, + {0xc016, 225}, + {0x8001, 236}, + {0xc016, 236}, + {0x8001, 237}, + {0xc016, 237}, + {0xc000, 199}, + {0xc000, 207}, + {0xc000, 234}, + {0xc000, 235}, + }, + /* 182 */ + { + {0x8002, 171}, + {0x8009, 171}, + {0x8017, 171}, + {0xc028, 171}, + {0x8002, 206}, + {0x8009, 206}, + {0x8017, 206}, + {0xc028, 206}, + {0x8002, 215}, + {0x8009, 215}, + {0x8017, 215}, + {0xc028, 215}, + {0x8002, 225}, + {0x8009, 225}, + {0x8017, 225}, + {0xc028, 225}, + }, + /* 183 */ + { + {0x8003, 171}, + {0x8006, 171}, + {0x800a, 171}, + {0x800f, 171}, + {0x8018, 171}, + {0x801f, 171}, + {0x8029, 171}, + {0xc038, 171}, + {0x8003, 206}, + {0x8006, 206}, + {0x800a, 206}, + {0x800f, 206}, + {0x8018, 206}, + {0x801f, 206}, + {0x8029, 206}, + {0xc038, 206}, + }, + /* 184 */ + { + {0x8003, 215}, + {0x8006, 215}, + {0x800a, 215}, + {0x800f, 215}, + {0x8018, 215}, + {0x801f, 215}, + {0x8029, 215}, + {0xc038, 215}, + {0x8003, 225}, + {0x8006, 225}, + {0x800a, 225}, + {0x800f, 225}, + {0x8018, 225}, + {0x801f, 225}, + {0x8029, 225}, + {0xc038, 225}, + }, + /* 185 */ + { + {0x8002, 236}, + {0x8009, 236}, + {0x8017, 236}, + {0xc028, 236}, + {0x8002, 237}, + {0x8009, 237}, + {0x8017, 237}, + {0xc028, 237}, + {0x8001, 199}, + {0xc016, 199}, + {0x8001, 207}, + {0xc016, 207}, + {0x8001, 234}, + {0xc016, 234}, + {0x8001, 235}, + {0xc016, 235}, + }, + /* 186 */ + { + {0x8003, 236}, + {0x8006, 236}, + {0x800a, 236}, + {0x800f, 236}, + {0x8018, 236}, + {0x801f, 236}, + {0x8029, 236}, + {0xc038, 236}, + {0x8003, 237}, + {0x8006, 237}, + {0x800a, 237}, + {0x800f, 237}, + {0x8018, 237}, + {0x801f, 237}, + {0x8029, 237}, + {0xc038, 237}, + }, + /* 187 */ + { + {0x8002, 199}, + {0x8009, 199}, + {0x8017, 199}, + {0xc028, 199}, + {0x8002, 207}, + {0x8009, 207}, + {0x8017, 207}, + {0xc028, 207}, + {0x8002, 234}, + {0x8009, 234}, + {0x8017, 234}, + {0xc028, 234}, + {0x8002, 235}, + {0x8009, 235}, + {0x8017, 235}, + {0xc028, 235}, + }, + /* 188 */ + { + {0x8003, 199}, + {0x8006, 199}, + {0x800a, 199}, + {0x800f, 199}, + {0x8018, 199}, + {0x801f, 199}, + {0x8029, 199}, + {0xc038, 199}, + {0x8003, 207}, + {0x8006, 207}, + {0x800a, 207}, + {0x800f, 207}, + {0x8018, 207}, + {0x801f, 207}, + {0x8029, 207}, + {0xc038, 207}, + }, + /* 189 */ + { + {0x8003, 234}, + {0x8006, 234}, + {0x800a, 234}, + {0x800f, 234}, + {0x8018, 234}, + {0x801f, 234}, + {0x8029, 234}, + {0xc038, 234}, + {0x8003, 235}, + {0x8006, 235}, + {0x800a, 235}, + {0x800f, 235}, + {0x8018, 235}, + {0x801f, 235}, + {0x8029, 235}, + {0xc038, 235}, + }, + /* 190 */ + { + {0xc2, 0}, + {0xc3, 0}, + {0xc5, 0}, + {0xc6, 0}, + {0xc9, 0}, + {0xca, 0}, + {0xcc, 0}, + {0xcd, 0}, + {0xd2, 0}, + {0xd5, 0}, + {0xd9, 0}, + {0xdc, 0}, + {0xe1, 0}, + {0xe7, 0}, + {0xef, 0}, + {0xf6, 0}, + }, + /* 191 */ + { + {0xc000, 192}, + {0xc000, 193}, + {0xc000, 200}, + {0xc000, 201}, + {0xc000, 202}, + {0xc000, 205}, + {0xc000, 210}, + {0xc000, 213}, + {0xc000, 218}, + {0xc000, 219}, + {0xc000, 238}, + {0xc000, 240}, + {0xc000, 242}, + {0xc000, 243}, + {0xc000, 255}, + {0xce, 0}, + }, + /* 192 */ + { + {0x8001, 192}, + {0xc016, 192}, + {0x8001, 193}, + {0xc016, 193}, + {0x8001, 200}, + {0xc016, 200}, + {0x8001, 201}, + {0xc016, 201}, + {0x8001, 202}, + {0xc016, 202}, + {0x8001, 205}, + {0xc016, 205}, + {0x8001, 210}, + {0xc016, 210}, + {0x8001, 213}, + {0xc016, 213}, + }, + /* 193 */ + { + {0x8002, 192}, + {0x8009, 192}, + {0x8017, 192}, + {0xc028, 192}, + {0x8002, 193}, + {0x8009, 193}, + {0x8017, 193}, + {0xc028, 193}, + {0x8002, 200}, + {0x8009, 200}, + {0x8017, 200}, + {0xc028, 200}, + {0x8002, 201}, + {0x8009, 201}, + {0x8017, 201}, + {0xc028, 201}, + }, + /* 194 */ + { + {0x8003, 192}, + {0x8006, 192}, + {0x800a, 192}, + {0x800f, 192}, + {0x8018, 192}, + {0x801f, 192}, + {0x8029, 192}, + {0xc038, 192}, + {0x8003, 193}, + {0x8006, 193}, + {0x800a, 193}, + {0x800f, 193}, + {0x8018, 193}, + {0x801f, 193}, + {0x8029, 193}, + {0xc038, 193}, + }, + /* 195 */ + { + {0x8003, 200}, + {0x8006, 200}, + {0x800a, 200}, + {0x800f, 200}, + {0x8018, 200}, + {0x801f, 200}, + {0x8029, 200}, + {0xc038, 200}, + {0x8003, 201}, + {0x8006, 201}, + {0x800a, 201}, + {0x800f, 201}, + {0x8018, 201}, + {0x801f, 201}, + {0x8029, 201}, + {0xc038, 201}, + }, + /* 196 */ + { + {0x8002, 202}, + {0x8009, 202}, + {0x8017, 202}, + {0xc028, 202}, + {0x8002, 205}, + {0x8009, 205}, + {0x8017, 205}, + {0xc028, 205}, + {0x8002, 210}, + {0x8009, 210}, + {0x8017, 210}, + {0xc028, 210}, + {0x8002, 213}, + {0x8009, 213}, + {0x8017, 213}, + {0xc028, 213}, + }, + /* 197 */ + { + {0x8003, 202}, + {0x8006, 202}, + {0x800a, 202}, + {0x800f, 202}, + {0x8018, 202}, + {0x801f, 202}, + {0x8029, 202}, + {0xc038, 202}, + {0x8003, 205}, + {0x8006, 205}, + {0x800a, 205}, + {0x800f, 205}, + {0x8018, 205}, + {0x801f, 205}, + {0x8029, 205}, + {0xc038, 205}, + }, + /* 198 */ + { + {0x8003, 210}, + {0x8006, 210}, + {0x800a, 210}, + {0x800f, 210}, + {0x8018, 210}, + {0x801f, 210}, + {0x8029, 210}, + {0xc038, 210}, + {0x8003, 213}, + {0x8006, 213}, + {0x800a, 213}, + {0x800f, 213}, + {0x8018, 213}, + {0x801f, 213}, + {0x8029, 213}, + {0xc038, 213}, + }, + /* 199 */ + { + {0x8001, 218}, + {0xc016, 218}, + {0x8001, 219}, + {0xc016, 219}, + {0x8001, 238}, + {0xc016, 238}, + {0x8001, 240}, + {0xc016, 240}, + {0x8001, 242}, + {0xc016, 242}, + {0x8001, 243}, + {0xc016, 243}, + {0x8001, 255}, + {0xc016, 255}, + {0xc000, 203}, + {0xc000, 204}, + }, + /* 200 */ + { + {0x8002, 218}, + {0x8009, 218}, + {0x8017, 218}, + {0xc028, 218}, + {0x8002, 219}, + {0x8009, 219}, + {0x8017, 219}, + {0xc028, 219}, + {0x8002, 238}, + {0x8009, 238}, + {0x8017, 238}, + {0xc028, 238}, + {0x8002, 240}, + {0x8009, 240}, + {0x8017, 240}, + {0xc028, 240}, + }, + /* 201 */ + { + {0x8003, 218}, + {0x8006, 218}, + {0x800a, 218}, + {0x800f, 218}, + {0x8018, 218}, + {0x801f, 218}, + {0x8029, 218}, + {0xc038, 218}, + {0x8003, 219}, + {0x8006, 219}, + {0x800a, 219}, + {0x800f, 219}, + {0x8018, 219}, + {0x801f, 219}, + {0x8029, 219}, + {0xc038, 219}, + }, + /* 202 */ + { + {0x8003, 238}, + {0x8006, 238}, + {0x800a, 238}, + {0x800f, 238}, + {0x8018, 238}, + {0x801f, 238}, + {0x8029, 238}, + {0xc038, 238}, + {0x8003, 240}, + {0x8006, 240}, + {0x800a, 240}, + {0x800f, 240}, + {0x8018, 240}, + {0x801f, 240}, + {0x8029, 240}, + {0xc038, 240}, + }, + /* 203 */ + { + {0x8002, 242}, + {0x8009, 242}, + {0x8017, 242}, + {0xc028, 242}, + {0x8002, 243}, + {0x8009, 243}, + {0x8017, 243}, + {0xc028, 243}, + {0x8002, 255}, + {0x8009, 255}, + {0x8017, 255}, + {0xc028, 255}, + {0x8001, 203}, + {0xc016, 203}, + {0x8001, 204}, + {0xc016, 204}, + }, + /* 204 */ + { + {0x8003, 242}, + {0x8006, 242}, + {0x800a, 242}, + {0x800f, 242}, + {0x8018, 242}, + {0x801f, 242}, + {0x8029, 242}, + {0xc038, 242}, + {0x8003, 243}, + {0x8006, 243}, + {0x800a, 243}, + {0x800f, 243}, + {0x8018, 243}, + {0x801f, 243}, + {0x8029, 243}, + {0xc038, 243}, + }, + /* 205 */ + { + {0x8003, 255}, + {0x8006, 255}, + {0x800a, 255}, + {0x800f, 255}, + {0x8018, 255}, + {0x801f, 255}, + {0x8029, 255}, + {0xc038, 255}, + {0x8002, 203}, + {0x8009, 203}, + {0x8017, 203}, + {0xc028, 203}, + {0x8002, 204}, + {0x8009, 204}, + {0x8017, 204}, + {0xc028, 204}, + }, + /* 206 */ + { + {0x8003, 203}, + {0x8006, 203}, + {0x800a, 203}, + {0x800f, 203}, + {0x8018, 203}, + {0x801f, 203}, + {0x8029, 203}, + {0xc038, 203}, + {0x8003, 204}, + {0x8006, 204}, + {0x800a, 204}, + {0x800f, 204}, + {0x8018, 204}, + {0x801f, 204}, + {0x8029, 204}, + {0xc038, 204}, + }, + /* 207 */ + { + {0xd3, 0}, + {0xd4, 0}, + {0xd6, 0}, + {0xd7, 0}, + {0xda, 0}, + {0xdb, 0}, + {0xdd, 0}, + {0xde, 0}, + {0xe2, 0}, + {0xe4, 0}, + {0xe8, 0}, + {0xeb, 0}, + {0xf0, 0}, + {0xf3, 0}, + {0xf7, 0}, + {0xfa, 0}, + }, + /* 208 */ + { + {0xc000, 211}, + {0xc000, 212}, + {0xc000, 214}, + {0xc000, 221}, + {0xc000, 222}, + {0xc000, 223}, + {0xc000, 241}, + {0xc000, 244}, + {0xc000, 245}, + {0xc000, 246}, + {0xc000, 247}, + {0xc000, 248}, + {0xc000, 250}, + {0xc000, 251}, + {0xc000, 252}, + {0xc000, 253}, + }, + /* 209 */ + { + {0x8001, 211}, + {0xc016, 211}, + {0x8001, 212}, + {0xc016, 212}, + {0x8001, 214}, + {0xc016, 214}, + {0x8001, 221}, + {0xc016, 221}, + {0x8001, 222}, + {0xc016, 222}, + {0x8001, 223}, + {0xc016, 223}, + {0x8001, 241}, + {0xc016, 241}, + {0x8001, 244}, + {0xc016, 244}, + }, + /* 210 */ + { + {0x8002, 211}, + {0x8009, 211}, + {0x8017, 211}, + {0xc028, 211}, + {0x8002, 212}, + {0x8009, 212}, + {0x8017, 212}, + {0xc028, 212}, + {0x8002, 214}, + {0x8009, 214}, + {0x8017, 214}, + {0xc028, 214}, + {0x8002, 221}, + {0x8009, 221}, + {0x8017, 221}, + {0xc028, 221}, + }, + /* 211 */ + { + {0x8003, 211}, + {0x8006, 211}, + {0x800a, 211}, + {0x800f, 211}, + {0x8018, 211}, + {0x801f, 211}, + {0x8029, 211}, + {0xc038, 211}, + {0x8003, 212}, + {0x8006, 212}, + {0x800a, 212}, + {0x800f, 212}, + {0x8018, 212}, + {0x801f, 212}, + {0x8029, 212}, + {0xc038, 212}, + }, + /* 212 */ + { + {0x8003, 214}, + {0x8006, 214}, + {0x800a, 214}, + {0x800f, 214}, + {0x8018, 214}, + {0x801f, 214}, + {0x8029, 214}, + {0xc038, 214}, + {0x8003, 221}, + {0x8006, 221}, + {0x800a, 221}, + {0x800f, 221}, + {0x8018, 221}, + {0x801f, 221}, + {0x8029, 221}, + {0xc038, 221}, + }, + /* 213 */ + { + {0x8002, 222}, + {0x8009, 222}, + {0x8017, 222}, + {0xc028, 222}, + {0x8002, 223}, + {0x8009, 223}, + {0x8017, 223}, + {0xc028, 223}, + {0x8002, 241}, + {0x8009, 241}, + {0x8017, 241}, + {0xc028, 241}, + {0x8002, 244}, + {0x8009, 244}, + {0x8017, 244}, + {0xc028, 244}, + }, + /* 214 */ + { + {0x8003, 222}, + {0x8006, 222}, + {0x800a, 222}, + {0x800f, 222}, + {0x8018, 222}, + {0x801f, 222}, + {0x8029, 222}, + {0xc038, 222}, + {0x8003, 223}, + {0x8006, 223}, + {0x800a, 223}, + {0x800f, 223}, + {0x8018, 223}, + {0x801f, 223}, + {0x8029, 223}, + {0xc038, 223}, + }, + /* 215 */ + { + {0x8003, 241}, + {0x8006, 241}, + {0x800a, 241}, + {0x800f, 241}, + {0x8018, 241}, + {0x801f, 241}, + {0x8029, 241}, + {0xc038, 241}, + {0x8003, 244}, + {0x8006, 244}, + {0x800a, 244}, + {0x800f, 244}, + {0x8018, 244}, + {0x801f, 244}, + {0x8029, 244}, + {0xc038, 244}, + }, + /* 216 */ + { + {0x8001, 245}, + {0xc016, 245}, + {0x8001, 246}, + {0xc016, 246}, + {0x8001, 247}, + {0xc016, 247}, + {0x8001, 248}, + {0xc016, 248}, + {0x8001, 250}, + {0xc016, 250}, + {0x8001, 251}, + {0xc016, 251}, + {0x8001, 252}, + {0xc016, 252}, + {0x8001, 253}, + {0xc016, 253}, + }, + /* 217 */ + { + {0x8002, 245}, + {0x8009, 245}, + {0x8017, 245}, + {0xc028, 245}, + {0x8002, 246}, + {0x8009, 246}, + {0x8017, 246}, + {0xc028, 246}, + {0x8002, 247}, + {0x8009, 247}, + {0x8017, 247}, + {0xc028, 247}, + {0x8002, 248}, + {0x8009, 248}, + {0x8017, 248}, + {0xc028, 248}, + }, + /* 218 */ + { + {0x8003, 245}, + {0x8006, 245}, + {0x800a, 245}, + {0x800f, 245}, + {0x8018, 245}, + {0x801f, 245}, + {0x8029, 245}, + {0xc038, 245}, + {0x8003, 246}, + {0x8006, 246}, + {0x800a, 246}, + {0x800f, 246}, + {0x8018, 246}, + {0x801f, 246}, + {0x8029, 246}, + {0xc038, 246}, + }, + /* 219 */ + { + {0x8003, 247}, + {0x8006, 247}, + {0x800a, 247}, + {0x800f, 247}, + {0x8018, 247}, + {0x801f, 247}, + {0x8029, 247}, + {0xc038, 247}, + {0x8003, 248}, + {0x8006, 248}, + {0x800a, 248}, + {0x800f, 248}, + {0x8018, 248}, + {0x801f, 248}, + {0x8029, 248}, + {0xc038, 248}, + }, + /* 220 */ + { + {0x8002, 250}, + {0x8009, 250}, + {0x8017, 250}, + {0xc028, 250}, + {0x8002, 251}, + {0x8009, 251}, + {0x8017, 251}, + {0xc028, 251}, + {0x8002, 252}, + {0x8009, 252}, + {0x8017, 252}, + {0xc028, 252}, + {0x8002, 253}, + {0x8009, 253}, + {0x8017, 253}, + {0xc028, 253}, + }, + /* 221 */ + { + {0x8003, 250}, + {0x8006, 250}, + {0x800a, 250}, + {0x800f, 250}, + {0x8018, 250}, + {0x801f, 250}, + {0x8029, 250}, + {0xc038, 250}, + {0x8003, 251}, + {0x8006, 251}, + {0x800a, 251}, + {0x800f, 251}, + {0x8018, 251}, + {0x801f, 251}, + {0x8029, 251}, + {0xc038, 251}, + }, + /* 222 */ + { + {0x8003, 252}, + {0x8006, 252}, + {0x800a, 252}, + {0x800f, 252}, + {0x8018, 252}, + {0x801f, 252}, + {0x8029, 252}, + {0xc038, 252}, + {0x8003, 253}, + {0x8006, 253}, + {0x800a, 253}, + {0x800f, 253}, + {0x8018, 253}, + {0x801f, 253}, + {0x8029, 253}, + {0xc038, 253}, + }, + /* 223 */ + { + {0xc000, 254}, + {0xe3, 0}, + {0xe5, 0}, + {0xe6, 0}, + {0xe9, 0}, + {0xea, 0}, + {0xec, 0}, + {0xed, 0}, + {0xf1, 0}, + {0xf2, 0}, + {0xf4, 0}, + {0xf5, 0}, + {0xf8, 0}, + {0xf9, 0}, + {0xfb, 0}, + {0xfc, 0}, + }, + /* 224 */ + { + {0x8001, 254}, + {0xc016, 254}, + {0xc000, 2}, + {0xc000, 3}, + {0xc000, 4}, + {0xc000, 5}, + {0xc000, 6}, + {0xc000, 7}, + {0xc000, 8}, + {0xc000, 11}, + {0xc000, 12}, + {0xc000, 14}, + {0xc000, 15}, + {0xc000, 16}, + {0xc000, 17}, + {0xc000, 18}, + }, + /* 225 */ + { + {0x8002, 254}, + {0x8009, 254}, + {0x8017, 254}, + {0xc028, 254}, + {0x8001, 2}, + {0xc016, 2}, + {0x8001, 3}, + {0xc016, 3}, + {0x8001, 4}, + {0xc016, 4}, + {0x8001, 5}, + {0xc016, 5}, + {0x8001, 6}, + {0xc016, 6}, + {0x8001, 7}, + {0xc016, 7}, + }, + /* 226 */ + { + {0x8003, 254}, + {0x8006, 254}, + {0x800a, 254}, + {0x800f, 254}, + {0x8018, 254}, + {0x801f, 254}, + {0x8029, 254}, + {0xc038, 254}, + {0x8002, 2}, + {0x8009, 2}, + {0x8017, 2}, + {0xc028, 2}, + {0x8002, 3}, + {0x8009, 3}, + {0x8017, 3}, + {0xc028, 3}, + }, + /* 227 */ + { + {0x8003, 2}, + {0x8006, 2}, + {0x800a, 2}, + {0x800f, 2}, + {0x8018, 2}, + {0x801f, 2}, + {0x8029, 2}, + {0xc038, 2}, + {0x8003, 3}, + {0x8006, 3}, + {0x800a, 3}, + {0x800f, 3}, + {0x8018, 3}, + {0x801f, 3}, + {0x8029, 3}, + {0xc038, 3}, + }, + /* 228 */ + { + {0x8002, 4}, + {0x8009, 4}, + {0x8017, 4}, + {0xc028, 4}, + {0x8002, 5}, + {0x8009, 5}, + {0x8017, 5}, + {0xc028, 5}, + {0x8002, 6}, + {0x8009, 6}, + {0x8017, 6}, + {0xc028, 6}, + {0x8002, 7}, + {0x8009, 7}, + {0x8017, 7}, + {0xc028, 7}, + }, + /* 229 */ + { + {0x8003, 4}, + {0x8006, 4}, + {0x800a, 4}, + {0x800f, 4}, + {0x8018, 4}, + {0x801f, 4}, + {0x8029, 4}, + {0xc038, 4}, + {0x8003, 5}, + {0x8006, 5}, + {0x800a, 5}, + {0x800f, 5}, + {0x8018, 5}, + {0x801f, 5}, + {0x8029, 5}, + {0xc038, 5}, + }, + /* 230 */ + { + {0x8003, 6}, + {0x8006, 6}, + {0x800a, 6}, + {0x800f, 6}, + {0x8018, 6}, + {0x801f, 6}, + {0x8029, 6}, + {0xc038, 6}, + {0x8003, 7}, + {0x8006, 7}, + {0x800a, 7}, + {0x800f, 7}, + {0x8018, 7}, + {0x801f, 7}, + {0x8029, 7}, + {0xc038, 7}, + }, + /* 231 */ + { + {0x8001, 8}, + {0xc016, 8}, + {0x8001, 11}, + {0xc016, 11}, + {0x8001, 12}, + {0xc016, 12}, + {0x8001, 14}, + {0xc016, 14}, + {0x8001, 15}, + {0xc016, 15}, + {0x8001, 16}, + {0xc016, 16}, + {0x8001, 17}, + {0xc016, 17}, + {0x8001, 18}, + {0xc016, 18}, + }, + /* 232 */ + { + {0x8002, 8}, + {0x8009, 8}, + {0x8017, 8}, + {0xc028, 8}, + {0x8002, 11}, + {0x8009, 11}, + {0x8017, 11}, + {0xc028, 11}, + {0x8002, 12}, + {0x8009, 12}, + {0x8017, 12}, + {0xc028, 12}, + {0x8002, 14}, + {0x8009, 14}, + {0x8017, 14}, + {0xc028, 14}, + }, + /* 233 */ + { + {0x8003, 8}, + {0x8006, 8}, + {0x800a, 8}, + {0x800f, 8}, + {0x8018, 8}, + {0x801f, 8}, + {0x8029, 8}, + {0xc038, 8}, + {0x8003, 11}, + {0x8006, 11}, + {0x800a, 11}, + {0x800f, 11}, + {0x8018, 11}, + {0x801f, 11}, + {0x8029, 11}, + {0xc038, 11}, + }, + /* 234 */ + { + {0x8003, 12}, + {0x8006, 12}, + {0x800a, 12}, + {0x800f, 12}, + {0x8018, 12}, + {0x801f, 12}, + {0x8029, 12}, + {0xc038, 12}, + {0x8003, 14}, + {0x8006, 14}, + {0x800a, 14}, + {0x800f, 14}, + {0x8018, 14}, + {0x801f, 14}, + {0x8029, 14}, + {0xc038, 14}, + }, + /* 235 */ + { + {0x8002, 15}, + {0x8009, 15}, + {0x8017, 15}, + {0xc028, 15}, + {0x8002, 16}, + {0x8009, 16}, + {0x8017, 16}, + {0xc028, 16}, + {0x8002, 17}, + {0x8009, 17}, + {0x8017, 17}, + {0xc028, 17}, + {0x8002, 18}, + {0x8009, 18}, + {0x8017, 18}, + {0xc028, 18}, + }, + /* 236 */ + { + {0x8003, 15}, + {0x8006, 15}, + {0x800a, 15}, + {0x800f, 15}, + {0x8018, 15}, + {0x801f, 15}, + {0x8029, 15}, + {0xc038, 15}, + {0x8003, 16}, + {0x8006, 16}, + {0x800a, 16}, + {0x800f, 16}, + {0x8018, 16}, + {0x801f, 16}, + {0x8029, 16}, + {0xc038, 16}, + }, + /* 237 */ + { + {0x8003, 17}, + {0x8006, 17}, + {0x800a, 17}, + {0x800f, 17}, + {0x8018, 17}, + {0x801f, 17}, + {0x8029, 17}, + {0xc038, 17}, + {0x8003, 18}, + {0x8006, 18}, + {0x800a, 18}, + {0x800f, 18}, + {0x8018, 18}, + {0x801f, 18}, + {0x8029, 18}, + {0xc038, 18}, + }, + /* 238 */ + { + {0xc000, 19}, + {0xc000, 20}, + {0xc000, 21}, + {0xc000, 23}, + {0xc000, 24}, + {0xc000, 25}, + {0xc000, 26}, + {0xc000, 27}, + {0xc000, 28}, + {0xc000, 29}, + {0xc000, 30}, + {0xc000, 31}, + {0xc000, 127}, + {0xc000, 220}, + {0xc000, 249}, + {0xfd, 0}, + }, + /* 239 */ + { + {0x8001, 19}, + {0xc016, 19}, + {0x8001, 20}, + {0xc016, 20}, + {0x8001, 21}, + {0xc016, 21}, + {0x8001, 23}, + {0xc016, 23}, + {0x8001, 24}, + {0xc016, 24}, + {0x8001, 25}, + {0xc016, 25}, + {0x8001, 26}, + {0xc016, 26}, + {0x8001, 27}, + {0xc016, 27}, + }, + /* 240 */ + { + {0x8002, 19}, + {0x8009, 19}, + {0x8017, 19}, + {0xc028, 19}, + {0x8002, 20}, + {0x8009, 20}, + {0x8017, 20}, + {0xc028, 20}, + {0x8002, 21}, + {0x8009, 21}, + {0x8017, 21}, + {0xc028, 21}, + {0x8002, 23}, + {0x8009, 23}, + {0x8017, 23}, + {0xc028, 23}, + }, + /* 241 */ + { + {0x8003, 19}, + {0x8006, 19}, + {0x800a, 19}, + {0x800f, 19}, + {0x8018, 19}, + {0x801f, 19}, + {0x8029, 19}, + {0xc038, 19}, + {0x8003, 20}, + {0x8006, 20}, + {0x800a, 20}, + {0x800f, 20}, + {0x8018, 20}, + {0x801f, 20}, + {0x8029, 20}, + {0xc038, 20}, + }, + /* 242 */ + { + {0x8003, 21}, + {0x8006, 21}, + {0x800a, 21}, + {0x800f, 21}, + {0x8018, 21}, + {0x801f, 21}, + {0x8029, 21}, + {0xc038, 21}, + {0x8003, 23}, + {0x8006, 23}, + {0x800a, 23}, + {0x800f, 23}, + {0x8018, 23}, + {0x801f, 23}, + {0x8029, 23}, + {0xc038, 23}, + }, + /* 243 */ + { + {0x8002, 24}, + {0x8009, 24}, + {0x8017, 24}, + {0xc028, 24}, + {0x8002, 25}, + {0x8009, 25}, + {0x8017, 25}, + {0xc028, 25}, + {0x8002, 26}, + {0x8009, 26}, + {0x8017, 26}, + {0xc028, 26}, + {0x8002, 27}, + {0x8009, 27}, + {0x8017, 27}, + {0xc028, 27}, + }, + /* 244 */ + { + {0x8003, 24}, + {0x8006, 24}, + {0x800a, 24}, + {0x800f, 24}, + {0x8018, 24}, + {0x801f, 24}, + {0x8029, 24}, + {0xc038, 24}, + {0x8003, 25}, + {0x8006, 25}, + {0x800a, 25}, + {0x800f, 25}, + {0x8018, 25}, + {0x801f, 25}, + {0x8029, 25}, + {0xc038, 25}, + }, + /* 245 */ + { + {0x8003, 26}, + {0x8006, 26}, + {0x800a, 26}, + {0x800f, 26}, + {0x8018, 26}, + {0x801f, 26}, + {0x8029, 26}, + {0xc038, 26}, + {0x8003, 27}, + {0x8006, 27}, + {0x800a, 27}, + {0x800f, 27}, + {0x8018, 27}, + {0x801f, 27}, + {0x8029, 27}, + {0xc038, 27}, + }, + /* 246 */ + { + {0x8001, 28}, + {0xc016, 28}, + {0x8001, 29}, + {0xc016, 29}, + {0x8001, 30}, + {0xc016, 30}, + {0x8001, 31}, + {0xc016, 31}, + {0x8001, 127}, + {0xc016, 127}, + {0x8001, 220}, + {0xc016, 220}, + {0x8001, 249}, + {0xc016, 249}, + {0xfe, 0}, + {0xff, 0}, + }, + /* 247 */ + { + {0x8002, 28}, + {0x8009, 28}, + {0x8017, 28}, + {0xc028, 28}, + {0x8002, 29}, + {0x8009, 29}, + {0x8017, 29}, + {0xc028, 29}, + {0x8002, 30}, + {0x8009, 30}, + {0x8017, 30}, + {0xc028, 30}, + {0x8002, 31}, + {0x8009, 31}, + {0x8017, 31}, + {0xc028, 31}, + }, + /* 248 */ + { + {0x8003, 28}, + {0x8006, 28}, + {0x800a, 28}, + {0x800f, 28}, + {0x8018, 28}, + {0x801f, 28}, + {0x8029, 28}, + {0xc038, 28}, + {0x8003, 29}, + {0x8006, 29}, + {0x800a, 29}, + {0x800f, 29}, + {0x8018, 29}, + {0x801f, 29}, + {0x8029, 29}, + {0xc038, 29}, + }, + /* 249 */ + { + {0x8003, 30}, + {0x8006, 30}, + {0x800a, 30}, + {0x800f, 30}, + {0x8018, 30}, + {0x801f, 30}, + {0x8029, 30}, + {0xc038, 30}, + {0x8003, 31}, + {0x8006, 31}, + {0x800a, 31}, + {0x800f, 31}, + {0x8018, 31}, + {0x801f, 31}, + {0x8029, 31}, + {0xc038, 31}, + }, + /* 250 */ + { + {0x8002, 127}, + {0x8009, 127}, + {0x8017, 127}, + {0xc028, 127}, + {0x8002, 220}, + {0x8009, 220}, + {0x8017, 220}, + {0xc028, 220}, + {0x8002, 249}, + {0x8009, 249}, + {0x8017, 249}, + {0xc028, 249}, + {0xc000, 10}, + {0xc000, 13}, + {0xc000, 22}, + {0x100, 0}, + }, + /* 251 */ + { + {0x8003, 127}, + {0x8006, 127}, + {0x800a, 127}, + {0x800f, 127}, + {0x8018, 127}, + {0x801f, 127}, + {0x8029, 127}, + {0xc038, 127}, + {0x8003, 220}, + {0x8006, 220}, + {0x800a, 220}, + {0x800f, 220}, + {0x8018, 220}, + {0x801f, 220}, + {0x8029, 220}, + {0xc038, 220}, + }, + /* 252 */ + { + {0x8003, 249}, + {0x8006, 249}, + {0x800a, 249}, + {0x800f, 249}, + {0x8018, 249}, + {0x801f, 249}, + {0x8029, 249}, + {0xc038, 249}, + {0x8001, 10}, + {0xc016, 10}, + {0x8001, 13}, + {0xc016, 13}, + {0x8001, 22}, + {0xc016, 22}, + {0x100, 0}, + {0x100, 0}, + }, + /* 253 */ + { + {0x8002, 10}, + {0x8009, 10}, + {0x8017, 10}, + {0xc028, 10}, + {0x8002, 13}, + {0x8009, 13}, + {0x8017, 13}, + {0xc028, 13}, + {0x8002, 22}, + {0x8009, 22}, + {0x8017, 22}, + {0xc028, 22}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + }, + /* 254 */ + { + {0x8003, 10}, + {0x8006, 10}, + {0x800a, 10}, + {0x800f, 10}, + {0x8018, 10}, + {0x801f, 10}, + {0x8029, 10}, + {0xc038, 10}, + {0x8003, 13}, + {0x8006, 13}, + {0x800a, 13}, + {0x800f, 13}, + {0x8018, 13}, + {0x801f, 13}, + {0x8029, 13}, + {0xc038, 13}, + }, + /* 255 */ + { + {0x8003, 22}, + {0x8006, 22}, + {0x800a, 22}, + {0x800f, 22}, + {0x8018, 22}, + {0x801f, 22}, + {0x8029, 22}, + {0xc038, 22}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + }, + /* 256 */ + { + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + }, }; diff --git a/deps/nghttp2/lib/nghttp2_helper.c b/deps/nghttp2/lib/nghttp2_helper.c index 9a2407ab6f518f..f54f37c13e2716 100644 --- a/deps/nghttp2/lib/nghttp2_helper.c +++ b/deps/nghttp2/lib/nghttp2_helper.c @@ -53,70 +53,70 @@ uint32_t nghttp2_get_uint32(const uint8_t *data) { /* Generated by gendowncasetbl.py */ static const uint8_t DOWNCASE_TBL[] = { - 0 /* NUL */, 1 /* SOH */, 2 /* STX */, 3 /* ETX */, - 4 /* EOT */, 5 /* ENQ */, 6 /* ACK */, 7 /* BEL */, - 8 /* BS */, 9 /* HT */, 10 /* LF */, 11 /* VT */, - 12 /* FF */, 13 /* CR */, 14 /* SO */, 15 /* SI */, - 16 /* DLE */, 17 /* DC1 */, 18 /* DC2 */, 19 /* DC3 */, - 20 /* DC4 */, 21 /* NAK */, 22 /* SYN */, 23 /* ETB */, - 24 /* CAN */, 25 /* EM */, 26 /* SUB */, 27 /* ESC */, - 28 /* FS */, 29 /* GS */, 30 /* RS */, 31 /* US */, - 32 /* SPC */, 33 /* ! */, 34 /* " */, 35 /* # */, - 36 /* $ */, 37 /* % */, 38 /* & */, 39 /* ' */, - 40 /* ( */, 41 /* ) */, 42 /* * */, 43 /* + */, - 44 /* , */, 45 /* - */, 46 /* . */, 47 /* / */, - 48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */, - 52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */, - 56 /* 8 */, 57 /* 9 */, 58 /* : */, 59 /* ; */, - 60 /* < */, 61 /* = */, 62 /* > */, 63 /* ? */, - 64 /* @ */, 97 /* A */, 98 /* B */, 99 /* C */, - 100 /* D */, 101 /* E */, 102 /* F */, 103 /* G */, - 104 /* H */, 105 /* I */, 106 /* J */, 107 /* K */, - 108 /* L */, 109 /* M */, 110 /* N */, 111 /* O */, - 112 /* P */, 113 /* Q */, 114 /* R */, 115 /* S */, - 116 /* T */, 117 /* U */, 118 /* V */, 119 /* W */, - 120 /* X */, 121 /* Y */, 122 /* Z */, 91 /* [ */, - 92 /* \ */, 93 /* ] */, 94 /* ^ */, 95 /* _ */, - 96 /* ` */, 97 /* a */, 98 /* b */, 99 /* c */, - 100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */, - 104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */, - 108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */, - 112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */, - 116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */, - 120 /* x */, 121 /* y */, 122 /* z */, 123 /* { */, - 124 /* | */, 125 /* } */, 126 /* ~ */, 127 /* DEL */, - 128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */, - 132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */, - 136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */, - 140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */, - 144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */, - 148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */, - 152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */, - 156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */, - 160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */, - 164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */, - 168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */, - 172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */, - 176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */, - 180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */, - 184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */, - 188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */, - 192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */, - 196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */, - 200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */, - 204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */, - 208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */, - 212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */, - 216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */, - 220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */, - 224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */, - 228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */, - 232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */, - 236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */, - 240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */, - 244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */, - 248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */, - 252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */, + 0 /* NUL */, 1 /* SOH */, 2 /* STX */, 3 /* ETX */, + 4 /* EOT */, 5 /* ENQ */, 6 /* ACK */, 7 /* BEL */, + 8 /* BS */, 9 /* HT */, 10 /* LF */, 11 /* VT */, + 12 /* FF */, 13 /* CR */, 14 /* SO */, 15 /* SI */, + 16 /* DLE */, 17 /* DC1 */, 18 /* DC2 */, 19 /* DC3 */, + 20 /* DC4 */, 21 /* NAK */, 22 /* SYN */, 23 /* ETB */, + 24 /* CAN */, 25 /* EM */, 26 /* SUB */, 27 /* ESC */, + 28 /* FS */, 29 /* GS */, 30 /* RS */, 31 /* US */, + 32 /* SPC */, 33 /* ! */, 34 /* " */, 35 /* # */, + 36 /* $ */, 37 /* % */, 38 /* & */, 39 /* ' */, + 40 /* ( */, 41 /* ) */, 42 /* * */, 43 /* + */, + 44 /* , */, 45 /* - */, 46 /* . */, 47 /* / */, + 48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */, + 52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */, + 56 /* 8 */, 57 /* 9 */, 58 /* : */, 59 /* ; */, + 60 /* < */, 61 /* = */, 62 /* > */, 63 /* ? */, + 64 /* @ */, 97 /* A */, 98 /* B */, 99 /* C */, + 100 /* D */, 101 /* E */, 102 /* F */, 103 /* G */, + 104 /* H */, 105 /* I */, 106 /* J */, 107 /* K */, + 108 /* L */, 109 /* M */, 110 /* N */, 111 /* O */, + 112 /* P */, 113 /* Q */, 114 /* R */, 115 /* S */, + 116 /* T */, 117 /* U */, 118 /* V */, 119 /* W */, + 120 /* X */, 121 /* Y */, 122 /* Z */, 91 /* [ */, + 92 /* \ */, 93 /* ] */, 94 /* ^ */, 95 /* _ */, + 96 /* ` */, 97 /* a */, 98 /* b */, 99 /* c */, + 100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */, + 104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */, + 108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */, + 112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */, + 116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */, + 120 /* x */, 121 /* y */, 122 /* z */, 123 /* { */, + 124 /* | */, 125 /* } */, 126 /* ~ */, 127 /* DEL */, + 128 /* 0x80 */, 129 /* 0x81 */, 130 /* 0x82 */, 131 /* 0x83 */, + 132 /* 0x84 */, 133 /* 0x85 */, 134 /* 0x86 */, 135 /* 0x87 */, + 136 /* 0x88 */, 137 /* 0x89 */, 138 /* 0x8a */, 139 /* 0x8b */, + 140 /* 0x8c */, 141 /* 0x8d */, 142 /* 0x8e */, 143 /* 0x8f */, + 144 /* 0x90 */, 145 /* 0x91 */, 146 /* 0x92 */, 147 /* 0x93 */, + 148 /* 0x94 */, 149 /* 0x95 */, 150 /* 0x96 */, 151 /* 0x97 */, + 152 /* 0x98 */, 153 /* 0x99 */, 154 /* 0x9a */, 155 /* 0x9b */, + 156 /* 0x9c */, 157 /* 0x9d */, 158 /* 0x9e */, 159 /* 0x9f */, + 160 /* 0xa0 */, 161 /* 0xa1 */, 162 /* 0xa2 */, 163 /* 0xa3 */, + 164 /* 0xa4 */, 165 /* 0xa5 */, 166 /* 0xa6 */, 167 /* 0xa7 */, + 168 /* 0xa8 */, 169 /* 0xa9 */, 170 /* 0xaa */, 171 /* 0xab */, + 172 /* 0xac */, 173 /* 0xad */, 174 /* 0xae */, 175 /* 0xaf */, + 176 /* 0xb0 */, 177 /* 0xb1 */, 178 /* 0xb2 */, 179 /* 0xb3 */, + 180 /* 0xb4 */, 181 /* 0xb5 */, 182 /* 0xb6 */, 183 /* 0xb7 */, + 184 /* 0xb8 */, 185 /* 0xb9 */, 186 /* 0xba */, 187 /* 0xbb */, + 188 /* 0xbc */, 189 /* 0xbd */, 190 /* 0xbe */, 191 /* 0xbf */, + 192 /* 0xc0 */, 193 /* 0xc1 */, 194 /* 0xc2 */, 195 /* 0xc3 */, + 196 /* 0xc4 */, 197 /* 0xc5 */, 198 /* 0xc6 */, 199 /* 0xc7 */, + 200 /* 0xc8 */, 201 /* 0xc9 */, 202 /* 0xca */, 203 /* 0xcb */, + 204 /* 0xcc */, 205 /* 0xcd */, 206 /* 0xce */, 207 /* 0xcf */, + 208 /* 0xd0 */, 209 /* 0xd1 */, 210 /* 0xd2 */, 211 /* 0xd3 */, + 212 /* 0xd4 */, 213 /* 0xd5 */, 214 /* 0xd6 */, 215 /* 0xd7 */, + 216 /* 0xd8 */, 217 /* 0xd9 */, 218 /* 0xda */, 219 /* 0xdb */, + 220 /* 0xdc */, 221 /* 0xdd */, 222 /* 0xde */, 223 /* 0xdf */, + 224 /* 0xe0 */, 225 /* 0xe1 */, 226 /* 0xe2 */, 227 /* 0xe3 */, + 228 /* 0xe4 */, 229 /* 0xe5 */, 230 /* 0xe6 */, 231 /* 0xe7 */, + 232 /* 0xe8 */, 233 /* 0xe9 */, 234 /* 0xea */, 235 /* 0xeb */, + 236 /* 0xec */, 237 /* 0xed */, 238 /* 0xee */, 239 /* 0xef */, + 240 /* 0xf0 */, 241 /* 0xf1 */, 242 /* 0xf2 */, 243 /* 0xf3 */, + 244 /* 0xf4 */, 245 /* 0xf5 */, 246 /* 0xf6 */, 247 /* 0xf7 */, + 248 /* 0xf8 */, 249 /* 0xf9 */, 250 /* 0xfa */, 251 /* 0xfb */, + 252 /* 0xfc */, 253 /* 0xfd */, 254 /* 0xfe */, 255 /* 0xff */, }; void nghttp2_downcase(uint8_t *s, size_t len) { @@ -160,7 +160,7 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr, int32_t recv_reduction_delta; int32_t delta; int32_t new_recv_window_size = - nghttp2_max_int32(0, *recv_window_size_ptr) - *delta_ptr; + nghttp2_max_int32(0, *recv_window_size_ptr) - *delta_ptr; if (new_recv_window_size >= 0) { *recv_window_size_ptr = new_recv_window_size; @@ -345,70 +345,70 @@ const char *nghttp2_strerror(int error_code) { /* Generated by gennmchartbl.py */ static const int VALID_HD_NAME_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, - 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, - 0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */, - 0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */, - 0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */, - 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */, - 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, - 0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */, - 0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */, - 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, + 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, + 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, + 0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */, + 0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */, + 0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */, + 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */, + 0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, + 0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */, + 0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */, + 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ }; int nghttp2_check_header_name(const uint8_t *name, size_t len) { @@ -433,70 +433,70 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len) { /* Generated by genvchartbl.py */ static const int VALID_HD_VALUE_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, - 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, - 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, - 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, - 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, - 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, - 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, - 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, - 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, - 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, - 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, - 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, - 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, - 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, - 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, - 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, - 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, - 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, - 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, - 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, - 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, - 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, - 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, - 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, - 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, - 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, - 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, - 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, - 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, - 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, - 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, - 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, - 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, - 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, + 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, + 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, + 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, + 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, + 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, + 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, + 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, + 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, + 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, + 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, + 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, + 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, + 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, + 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, + 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, + 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, + 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, + 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, + 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, + 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, + 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, + 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, + 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, + 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, + 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, + 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, + 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, + 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, + 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, + 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, + 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, + 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, + 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ }; int nghttp2_check_header_value(const uint8_t *value, size_t len) { @@ -524,70 +524,70 @@ int nghttp2_check_header_value_rfc9113(const uint8_t *value, size_t len) { /* Generated by genmethodchartbl.py */ static char VALID_METHOD_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, - 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, - 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, - 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */, - 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, + 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, + 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, + 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */, + 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ }; int nghttp2_check_method(const uint8_t *value, size_t len) { @@ -605,70 +605,70 @@ int nghttp2_check_method(const uint8_t *value, size_t len) { /* Generated by genpathchartbl.py */ static char VALID_PATH_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, - 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, - 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, - 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, - 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, - 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, - 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, - 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, - 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, - 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, - 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, - 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, - 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, - 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, - 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, - 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, - 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, - 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, - 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, - 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, - 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, - 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, - 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, - 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, - 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, - 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, - 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, - 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, - 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, - 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, - 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, - 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, - 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, - 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, - 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, + 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, + 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, + 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, + 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, + 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, + 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, + 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, + 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, + 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, + 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, + 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, + 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, + 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, + 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, + 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, + 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, + 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, + 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, + 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, + 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, + 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, + 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, + 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, + 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, + 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, + 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, + 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, + 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, + 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, + 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, + 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, + 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, + 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ }; int nghttp2_check_path(const uint8_t *value, size_t len) { @@ -683,70 +683,70 @@ int nghttp2_check_path(const uint8_t *value, size_t len) { /* Generated by genauthoritychartbl.py */ static char VALID_AUTHORITY_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, - 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, + 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ }; int nghttp2_check_authority(const uint8_t *value, size_t len) { diff --git a/deps/nghttp2/lib/nghttp2_helper.h b/deps/nghttp2/lib/nghttp2_helper.h index 89b0d4f535db79..f5de6290dab0e1 100644 --- a/deps/nghttp2/lib/nghttp2_helper.h +++ b/deps/nghttp2/lib/nghttp2_helper.h @@ -38,28 +38,28 @@ #define nghttp2_max_def(SUFFIX, T) \ static inline T nghttp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; } -nghttp2_max_def(int8, int8_t); -nghttp2_max_def(int16, int16_t); -nghttp2_max_def(int32, int32_t); -nghttp2_max_def(int64, int64_t); -nghttp2_max_def(uint8, uint8_t); -nghttp2_max_def(uint16, uint16_t); -nghttp2_max_def(uint32, uint32_t); -nghttp2_max_def(uint64, uint64_t); -nghttp2_max_def(size, size_t); +nghttp2_max_def(int8, int8_t) +nghttp2_max_def(int16, int16_t) +nghttp2_max_def(int32, int32_t) +nghttp2_max_def(int64, int64_t) +nghttp2_max_def(uint8, uint8_t) +nghttp2_max_def(uint16, uint16_t) +nghttp2_max_def(uint32, uint32_t) +nghttp2_max_def(uint64, uint64_t) +nghttp2_max_def(size, size_t) #define nghttp2_min_def(SUFFIX, T) \ static inline T nghttp2_min_##SUFFIX(T a, T b) { return a < b ? a : b; } -nghttp2_min_def(int8, int8_t); -nghttp2_min_def(int16, int16_t); -nghttp2_min_def(int32, int32_t); -nghttp2_min_def(int64, int64_t); -nghttp2_min_def(uint8, uint8_t); -nghttp2_min_def(uint16, uint16_t); -nghttp2_min_def(uint32, uint32_t); -nghttp2_min_def(uint64, uint64_t); -nghttp2_min_def(size, size_t); +nghttp2_min_def(int8, int8_t) +nghttp2_min_def(int16, int16_t) +nghttp2_min_def(int32, int32_t) +nghttp2_min_def(int64, int64_t) +nghttp2_min_def(uint8, uint8_t) +nghttp2_min_def(uint16, uint16_t) +nghttp2_min_def(uint32, uint32_t) +nghttp2_min_def(uint64, uint64_t) +nghttp2_min_def(size, size_t) #define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0) diff --git a/deps/nghttp2/lib/nghttp2_http.c b/deps/nghttp2/lib/nghttp2_http.c index ecdeb21ddb694c..f222fe5e3fbe3c 100644 --- a/deps/nghttp2/lib/nghttp2_http.c +++ b/deps/nghttp2/lib/nghttp2_http.c @@ -347,6 +347,84 @@ static int lws(const uint8_t *s, size_t n) { return 1; } +/* Generated by genauthoritychartbl.py, but '@' is not allowed */ +static char VALID_AUTHORITY_CHARS[] = { + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, + 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, + 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ +}; + +static int check_authority(const uint8_t *value, size_t len) { + const uint8_t *last; + for (last = value + len; value != last; ++value) { + if (!VALID_AUTHORITY_CHARS[*value]) { + return 0; + } + } + return 1; +} + int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, nghttp2_frame *frame, nghttp2_hd_nv *nv, int trailer) { @@ -388,10 +466,10 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, case NGHTTP2_TOKEN__AUTHORITY: case NGHTTP2_TOKEN_HOST: if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) { - rv = nghttp2_check_authority(nv->value->base, nv->value->len); + rv = check_authority(nv->value->base, nv->value->len); } else if ( - stream->flags & - NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) { + stream->flags & + NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) { rv = nghttp2_check_header_value(nv->value->base, nv->value->len); } else { rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len); @@ -435,7 +513,7 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) { return http_request_on_header(stream, nv, trailer, session->server && - session->pending_enable_connect_protocol); + session->pending_enable_connect_protocol); } return http_response_on_header(stream, nv, trailer); @@ -453,7 +531,7 @@ int nghttp2_http_on_request_headers(nghttp2_stream *stream, stream->content_length = -1; } else { if ((stream->http_flags & NGHTTP2_HTTP_FLAG_REQ_HEADERS) != - NGHTTP2_HTTP_FLAG_REQ_HEADERS || + NGHTTP2_HTTP_FLAG_REQ_HEADERS || (stream->http_flags & (NGHTTP2_HTTP_FLAG__AUTHORITY | NGHTTP2_HTTP_FLAG_HOST)) == 0) { return -1; @@ -493,7 +571,7 @@ int nghttp2_http_on_response_headers(nghttp2_stream *stream) { } stream->http_flags = - stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE; + stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE; if (!expect_response_body(stream)) { stream->content_length = 0; diff --git a/deps/nghttp2/lib/nghttp2_map.c b/deps/nghttp2/lib/nghttp2_map.c index 0aaaf29155cd02..ee6bb1967ec6da 100644 --- a/deps/nghttp2/lib/nghttp2_map.c +++ b/deps/nghttp2/lib/nghttp2_map.c @@ -35,8 +35,7 @@ void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) { map->mem = mem; - map->tablelen = 0; - map->tablelenbits = 0; + map->hashbits = 0; map->table = NULL; map->size = 0; } @@ -49,33 +48,20 @@ void nghttp2_map_free(nghttp2_map *map) { nghttp2_mem_free(map->mem, map->table); } -void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr), - void *ptr) { - uint32_t i; - nghttp2_map_bucket *bkt; - - for (i = 0; i < map->tablelen; ++i) { - bkt = &map->table[i]; - - if (bkt->data == NULL) { - continue; - } - - func(bkt->data, ptr); - } -} - -int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr), +int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr) { int rv; - uint32_t i; + size_t i; nghttp2_map_bucket *bkt; + size_t tablelen; if (map->size == 0) { return 0; } - for (i = 0; i < map->tablelen; ++i) { + tablelen = 1u << map->hashbits; + + for (i = 0; i < tablelen; ++i) { bkt = &map->table[i]; if (bkt->data == NULL) { @@ -91,82 +77,61 @@ int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr), return 0; } -static uint32_t hash(nghttp2_map_key_type key) { - return (uint32_t)key * 2654435769u; -} - -static size_t h2idx(uint32_t hash, uint32_t bits) { - return hash >> (32 - bits); -} - -static size_t distance(uint32_t tablelen, uint32_t tablelenbits, - nghttp2_map_bucket *bkt, size_t idx) { - return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1); +static size_t hash(nghttp2_map_key_type key, size_t bits) { + return (size_t)(((uint32_t)key * 2654435769u) >> (32 - bits)); } -static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash, - nghttp2_map_key_type *pkey, void **pdata) { - uint32_t h = bkt->hash; - nghttp2_map_key_type key = bkt->key; - void *data = bkt->data; - - bkt->hash = *phash; - bkt->key = *pkey; - bkt->data = *pdata; +static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) { + nghttp2_map_bucket c = *a; - *phash = h; - *pkey = key; - *pdata = data; -} - -static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash, - nghttp2_map_key_type key, void *data) { - bkt->hash = hash; - bkt->key = key; - bkt->data = data; + *a = *b; + *b = c; } #ifndef WIN32 -void nghttp2_map_print_distance(nghttp2_map *map) { - uint32_t i; +void nghttp2_map_print_distance(const nghttp2_map *map) { + size_t i; size_t idx; nghttp2_map_bucket *bkt; + size_t tablelen; - for (i = 0; i < map->tablelen; ++i) { + if (map->size == 0) { + return; + } + + tablelen = 1u << map->hashbits; + + for (i = 0; i < tablelen; ++i) { bkt = &map->table[i]; if (bkt->data == NULL) { - fprintf(stderr, "@%u \n", i); + fprintf(stderr, "@%zu \n", i); continue; } - idx = h2idx(bkt->hash, map->tablelenbits); - fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i, - bkt->hash, bkt->key, idx, - distance(map->tablelen, map->tablelenbits, bkt, idx)); + idx = hash(bkt->key, map->hashbits); + fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i, + hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl); } } #endif /* !WIN32 */ -static int insert(nghttp2_map_bucket *table, uint32_t tablelen, - uint32_t tablelenbits, uint32_t hash, +static int insert(nghttp2_map_bucket *table, size_t hashbits, nghttp2_map_key_type key, void *data) { - size_t idx = h2idx(hash, tablelenbits); - size_t d = 0, dd; - nghttp2_map_bucket *bkt; + size_t idx = hash(key, hashbits); + nghttp2_map_bucket b = {0, key, data}, *bkt; + size_t mask = (1u << hashbits) - 1; for (;;) { bkt = &table[idx]; if (bkt->data == NULL) { - map_bucket_set_data(bkt, hash, key, data); + *bkt = b; return 0; } - dd = distance(tablelen, tablelenbits, bkt, idx); - if (d > dd) { - map_bucket_swap(bkt, &hash, &key, &data); - d = dd; + if (b.psl > bkt->psl) { + map_bucket_swap(bkt, &b); } else if (bkt->key == key) { /* TODO This check is just a waste after first swap or if this function is called from map_resize. That said, there is no @@ -175,41 +140,42 @@ static int insert(nghttp2_map_bucket *table, uint32_t tablelen, return NGHTTP2_ERR_INVALID_ARGUMENT; } - ++d; - idx = (idx + 1) & (tablelen - 1); + ++b.psl; + idx = (idx + 1) & mask; } } -/* new_tablelen must be power of 2 and new_tablelen == (1 << - new_tablelenbits) must hold. */ -static int map_resize(nghttp2_map *map, uint32_t new_tablelen, - uint32_t new_tablelenbits) { - uint32_t i; +static int map_resize(nghttp2_map *map, size_t new_hashbits) { + size_t i; nghttp2_map_bucket *new_table; nghttp2_map_bucket *bkt; + size_t tablelen; int rv; (void)rv; - new_table = - nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_bucket)); + new_table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits, + sizeof(nghttp2_map_bucket)); if (new_table == NULL) { return NGHTTP2_ERR_NOMEM; } - for (i = 0; i < map->tablelen; ++i) { - bkt = &map->table[i]; - if (bkt->data == NULL) { - continue; - } - rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key, - bkt->data); + if (map->size) { + tablelen = 1u << map->hashbits; - assert(0 == rv); + for (i = 0; i < tablelen; ++i) { + bkt = &map->table[i]; + if (bkt->data == NULL) { + continue; + } + + rv = insert(new_table, new_hashbits, bkt->key, bkt->data); + + assert(0 == rv); + } } nghttp2_mem_free(map->mem, map->table); - map->tablelen = new_tablelen; - map->tablelenbits = new_tablelenbits; + map->hashbits = new_hashbits; map->table = new_table; return 0; @@ -221,48 +187,49 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) { assert(data); /* Load factor is 0.75 */ - if ((map->size + 1) * 4 > map->tablelen * 3) { - if (map->tablelen) { - rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1); + /* Under the very initial condition, that is map->size == 0 and + map->hashbits == 0, 4 > 3 still holds nicely. */ + if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) { + if (map->hashbits) { + rv = map_resize(map, map->hashbits + 1); if (rv != 0) { return rv; } } else { - rv = map_resize(map, 1 << NGHTTP2_INITIAL_TABLE_LENBITS, - NGHTTP2_INITIAL_TABLE_LENBITS); + rv = map_resize(map, NGHTTP2_INITIAL_TABLE_LENBITS); if (rv != 0) { return rv; } } } - rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key, - data); + rv = insert(map->table, map->hashbits, key, data); if (rv != 0) { return rv; } + ++map->size; + return 0; } -void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) { - uint32_t h; +void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) { size_t idx; nghttp2_map_bucket *bkt; - size_t d = 0; + size_t psl = 0; + size_t mask; if (map->size == 0) { return NULL; } - h = hash(key); - idx = h2idx(h, map->tablelenbits); + idx = hash(key, map->hashbits); + mask = (1u << map->hashbits) - 1; for (;;) { bkt = &map->table[idx]; - if (bkt->data == NULL || - d > distance(map->tablelen, map->tablelenbits, bkt, idx)) { + if (bkt->data == NULL || psl > bkt->psl) { return NULL; } @@ -270,50 +237,47 @@ void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) { return bkt->data; } - ++d; - idx = (idx + 1) & (map->tablelen - 1); + ++psl; + idx = (idx + 1) & mask; } } int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) { - uint32_t h; - size_t idx, didx; - nghttp2_map_bucket *bkt; - size_t d = 0; + size_t idx; + nghttp2_map_bucket *b, *bkt; + size_t psl = 0; + size_t mask; if (map->size == 0) { return NGHTTP2_ERR_INVALID_ARGUMENT; } - h = hash(key); - idx = h2idx(h, map->tablelenbits); + idx = hash(key, map->hashbits); + mask = (1u << map->hashbits) - 1; for (;;) { bkt = &map->table[idx]; - if (bkt->data == NULL || - d > distance(map->tablelen, map->tablelenbits, bkt, idx)) { + if (bkt->data == NULL || psl > bkt->psl) { return NGHTTP2_ERR_INVALID_ARGUMENT; } if (bkt->key == key) { - map_bucket_set_data(bkt, 0, 0, NULL); - - didx = idx; - idx = (idx + 1) & (map->tablelen - 1); + b = bkt; + idx = (idx + 1) & mask; for (;;) { bkt = &map->table[idx]; - if (bkt->data == NULL || - distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) { + if (bkt->data == NULL || bkt->psl == 0) { + b->data = NULL; break; } - map->table[didx] = *bkt; - map_bucket_set_data(bkt, 0, 0, NULL); - didx = idx; + --bkt->psl; + *b = *bkt; + b = bkt; - idx = (idx + 1) & (map->tablelen - 1); + idx = (idx + 1) & mask; } --map->size; @@ -321,18 +285,18 @@ int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) { return 0; } - ++d; - idx = (idx + 1) & (map->tablelen - 1); + ++psl; + idx = (idx + 1) & mask; } } void nghttp2_map_clear(nghttp2_map *map) { - if (map->tablelen == 0) { + if (map->size == 0) { return; } - memset(map->table, 0, sizeof(*map->table) * map->tablelen); + memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits)); map->size = 0; } -size_t nghttp2_map_size(nghttp2_map *map) { return map->size; } +size_t nghttp2_map_size(const nghttp2_map *map) { return map->size; } diff --git a/deps/nghttp2/lib/nghttp2_map.h b/deps/nghttp2/lib/nghttp2_map.h index 236d28296e31da..5adfb78d027679 100644 --- a/deps/nghttp2/lib/nghttp2_map.h +++ b/deps/nghttp2/lib/nghttp2_map.h @@ -39,7 +39,7 @@ typedef int32_t nghttp2_map_key_type; typedef struct nghttp2_map_bucket { - uint32_t hash; + uint32_t psl; nghttp2_map_key_type key; void *data; } nghttp2_map_bucket; @@ -48,33 +48,24 @@ typedef struct nghttp2_map { nghttp2_map_bucket *table; nghttp2_mem *mem; size_t size; - uint32_t tablelen; - uint32_t tablelenbits; + size_t hashbits; } nghttp2_map; /* - * Initializes the map |map|. + * nghttp2_map_init initializes the map |map|. */ void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem); /* - * Deallocates any resources allocated for |map|. The stored entries - * are not freed by this function. Use nghttp2_map_each_free() to free - * each entries. + * nghttp2_map_free deallocates any resources allocated for |map|. + * The stored entries are not freed by this function. Use + * nghttp2_map_each() to free each entry. */ void nghttp2_map_free(nghttp2_map *map); /* - * Deallocates each entries using |func| function and any resources - * allocated for |map|. The |func| function is responsible for freeing - * given the |data| object. The |ptr| will be passed to the |func| as - * send argument. The return value of the |func| will be ignored. - */ -void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr), - void *ptr); - -/* - * Inserts the new |data| with the |key| to the map |map|. + * nghttp2_map_insert inserts the new |data| with the |key| to the map + * |map|. * * This function returns 0 if it succeeds, or one of the following * negative error codes: @@ -82,57 +73,56 @@ void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr), * NGHTTP2_ERR_INVALID_ARGUMENT * The item associated by |key| already exists. * NGHTTP2_ERR_NOMEM - * Out of memory + * Out of memory */ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data); /* - * Returns the data associated by the key |key|. If there is no such - * data, this function returns NULL. + * nghttp2_map_find returns the entry associated by the key |key|. If + * there is no such entry, this function returns NULL. */ -void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key); +void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key); /* - * Removes the data associated by the key |key| from the |map|. The - * removed data is not freed by this function. + * nghttp2_map_remove removes the entry associated by the key |key| + * from the |map|. The removed entry is not freed by this function. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * * NGHTTP2_ERR_INVALID_ARGUMENT - * The data associated by |key| does not exist. + * The entry associated by |key| does not exist. */ int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key); /* - * Removes all entries from |map|. + * nghttp2_map_clear removes all entries from |map|. The removed + * entry is not freed by this function. */ void nghttp2_map_clear(nghttp2_map *map); /* - * Returns the number of items stored in the map |map|. + * nghttp2_map_size returns the number of items stored in the map + * |map|. */ -size_t nghttp2_map_size(nghttp2_map *map); +size_t nghttp2_map_size(const nghttp2_map *map); /* - * Applies the function |func| to each data in the |map| with the - * optional user supplied pointer |ptr|. + * nghttp2_map_each applies the function |func| to each entry in the + * |map| with the optional user supplied pointer |ptr|. * * If the |func| returns 0, this function calls the |func| with the - * next data. If the |func| returns nonzero, it will not call the + * next entry. If the |func| returns nonzero, it will not call the * |func| for further entries and return the return value of the * |func| immediately. Thus, this function returns 0 if all the * invocations of the |func| return 0, or nonzero value which the last * invocation of |func| returns. - * - * Don't use this function to free each data. Use - * nghttp2_map_each_free() instead. */ -int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr), +int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr); #ifndef WIN32 -void nghttp2_map_print_distance(nghttp2_map *map); +void nghttp2_map_print_distance(const nghttp2_map *map); #endif /* !WIN32 */ #endif /* NGHTTP2_MAP_H */ diff --git a/deps/nghttp2/lib/nghttp2_option.c b/deps/nghttp2/lib/nghttp2_option.c index 53144b9b75c289..02a24eee6b2605 100644 --- a/deps/nghttp2/lib/nghttp2_option.c +++ b/deps/nghttp2/lib/nghttp2_option.c @@ -132,15 +132,15 @@ void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) { } void nghttp2_option_set_server_fallback_rfc7540_priorities( - nghttp2_option *option, int val) { + nghttp2_option *option, int val) { option->opt_set_mask |= NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES; option->server_fallback_rfc7540_priorities = val; } void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - nghttp2_option *option, int val) { + nghttp2_option *option, int val) { option->opt_set_mask |= - NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; + NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; option->no_rfc9113_leading_and_trailing_ws_validation = val; } diff --git a/deps/nghttp2/lib/nghttp2_queue.c b/deps/nghttp2/lib/nghttp2_queue.c index 055eb69c7e5535..3b63158524593b 100644 --- a/deps/nghttp2/lib/nghttp2_queue.c +++ b/deps/nghttp2/lib/nghttp2_queue.c @@ -46,7 +46,7 @@ void nghttp2_queue_free(nghttp2_queue *queue) { int nghttp2_queue_push(nghttp2_queue *queue, void *data) { nghttp2_queue_cell *new_cell = - (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell)); + (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell)); if (!new_cell) { return NGHTTP2_ERR_NOMEM; } diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c index 54746fb37b376d..df33a89efdc1d3 100644 --- a/deps/nghttp2/lib/nghttp2_session.c +++ b/deps/nghttp2/lib/nghttp2_session.c @@ -239,9 +239,9 @@ static int session_terminate_session(nghttp2_session *session, debug_datalen = strlen(reason); } - rv = nghttp2_session_add_goaway(session, last_stream_id, error_code, - debug_data, debug_datalen, - NGHTTP2_GOAWAY_AUX_TERM_ON_SEND); + rv = + nghttp2_session_add_goaway(session, last_stream_id, error_code, debug_data, + debug_datalen, NGHTTP2_GOAWAY_AUX_TERM_ON_SEND); if (rv != 0) { return rv; @@ -439,7 +439,7 @@ static int session_new(nghttp2_session **session_ptr, int rv; size_t nbuffer; size_t max_deflate_dynamic_table_size = - NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE; + NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE; size_t i; if (mem == NULL) { @@ -473,7 +473,7 @@ static int session_new(nghttp2_session **session_ptr, (*session_ptr)->remote_last_stream_id = (1u << 31) - 1; (*session_ptr)->pending_local_max_concurrent_stream = - NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; + NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; (*session_ptr)->pending_enable_push = 1; (*session_ptr)->pending_no_rfc7540_priorities = UINT8_MAX; @@ -489,7 +489,7 @@ static int session_new(nghttp2_session **session_ptr, init_settings(&(*session_ptr)->local_settings); (*session_ptr)->max_incoming_reserved_streams = - NGHTTP2_MAX_INCOMING_RESERVED_STREAMS; + NGHTTP2_MAX_INCOMING_RESERVED_STREAMS; /* Limit max outgoing concurrent streams to sensible value */ (*session_ptr)->remote_settings.max_concurrent_streams = 100; @@ -502,31 +502,26 @@ static int session_new(nghttp2_session **session_ptr, if (option) { if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) && option->no_auto_window_update) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE; } if (option->opt_set_mask & NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS) { - (*session_ptr)->remote_settings.max_concurrent_streams = - option->peer_max_concurrent_streams; + option->peer_max_concurrent_streams; } if (option->opt_set_mask & NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS) { - (*session_ptr)->max_incoming_reserved_streams = - option->max_reserved_remote_streams; + option->max_reserved_remote_streams; } if ((option->opt_set_mask & NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC) && option->no_recv_client_magic) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC; } if ((option->opt_set_mask & NGHTTP2_OPT_NO_HTTP_MESSAGING) && option->no_http_messaging) { - (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_HTTP_MESSAGING; } @@ -546,7 +541,7 @@ static int session_new(nghttp2_session **session_ptr, if (option->opt_set_mask & NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH) { (*session_ptr)->max_send_header_block_length = - option->max_send_header_block_length; + option->max_send_header_block_length; } if (option->opt_set_mask & NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE) { @@ -571,14 +566,14 @@ static int session_new(nghttp2_session **session_ptr, NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES) && option->server_fallback_rfc7540_priorities) { (*session_ptr)->opt_flags |= - NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES; + NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES; } if ((option->opt_set_mask & NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) && option->no_rfc9113_leading_and_trailing_ws_validation) { (*session_ptr)->opt_flags |= - NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; + NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; } if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) { @@ -819,7 +814,7 @@ void nghttp2_session_del(nghttp2_session *session) { /* Have to free streams first, so that we can check stream->item->queued */ - nghttp2_map_each_free(&session->streams, free_streams, session); + nghttp2_map_each(&session->streams, free_streams, session); nghttp2_map_free(&session->streams); ob_q_free(&session->ob_urgent, mem); @@ -835,8 +830,8 @@ void nghttp2_session_del(nghttp2_session *session) { } int nghttp2_session_reprioritize_stream( - nghttp2_session *session, nghttp2_stream *stream, - const nghttp2_priority_spec *pri_spec_in) { + nghttp2_session *session, nghttp2_stream *stream, + const nghttp2_priority_spec *pri_spec_in) { int rv; nghttp2_stream *dep_stream = NULL; nghttp2_priority_spec pri_spec_default; @@ -855,12 +850,11 @@ int nghttp2_session_reprioritize_stream( if (!dep_stream && session_detect_idle_stream(session, pri_spec->stream_id)) { - nghttp2_priority_spec_default_init(&pri_spec_default); dep_stream = nghttp2_session_open_stream( - session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, - NGHTTP2_STREAM_IDLE, NULL); + session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, + NGHTTP2_STREAM_IDLE, NULL); if (dep_stream == NULL) { return NGHTTP2_ERR_NOMEM; @@ -1186,9 +1180,9 @@ int nghttp2_session_add_item(nghttp2_session *session, NGHTTP2_DEFAULT_WEIGHT, 0); if (!nghttp2_session_open_stream( - session, frame->push_promise.promised_stream_id, - NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_RESERVED, - aux_data->stream_user_data)) { + session, frame->push_promise.promised_stream_id, + NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_RESERVED, + aux_data->stream_user_data)) { return NGHTTP2_ERR_NOMEM; } @@ -1254,7 +1248,6 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id, assert(headers_frame->hd.type == NGHTTP2_HEADERS); if (headers_frame->hd.stream_id <= stream_id) { - for (item = session->ob_syn.head; item; item = item->qnext) { aux_data = &item->aux_data.headers; @@ -1368,8 +1361,8 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, nghttp2_priority_spec_default_init(&pri_spec_default); dep_stream = nghttp2_session_open_stream( - session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, - NGHTTP2_STREAM_IDLE, NULL); + session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default, + NGHTTP2_STREAM_IDLE, NULL); if (dep_stream == NULL) { if (stream_alloc) { @@ -1494,8 +1487,7 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id, if (session->callbacks.on_stream_close_callback) { if (session->callbacks.on_stream_close_callback( - session, stream_id, error_code, session->user_data) != 0) { - + session, stream_id, error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } @@ -1663,7 +1655,7 @@ int nghttp2_session_adjust_closed_stream(nghttp2_session *session) { while (session->num_closed_streams > 0 && session->num_closed_streams + session->num_incoming_streams > - num_stream_max) { + num_stream_max) { nghttp2_stream *head_stream; nghttp2_stream *next; @@ -1701,10 +1693,10 @@ int nghttp2_session_adjust_idle_stream(nghttp2_session *session) { /* Make minimum number of idle streams 16, and maximum 100, which are arbitrary chosen numbers. */ max = nghttp2_min_uint32( - 100, nghttp2_max_uint32( - 16, nghttp2_min_uint32( - session->local_settings.max_concurrent_streams, - session->pending_local_max_concurrent_stream))); + 100, + nghttp2_max_uint32( + 16, nghttp2_min_uint32(session->local_settings.max_concurrent_streams, + session->pending_local_max_concurrent_stream))); DEBUGF("stream: adjusting kept idle streams num_idle_streams=%zu, max=%zu\n", session->num_idle_streams, max); @@ -2125,18 +2117,18 @@ static int session_predicate_priority_update_send(nghttp2_session *session, /* Take into account settings max frame size and both connection-level flow control here */ static nghttp2_ssize nghttp2_session_enforce_flow_control_limits( - nghttp2_session *session, nghttp2_stream *stream, - nghttp2_ssize requested_window_size) { + nghttp2_session *session, nghttp2_stream *stream, + nghttp2_ssize requested_window_size) { DEBUGF("send: remote windowsize connection=%d, remote maxframsize=%u, " "stream(id %d)=%d\n", session->remote_window_size, session->remote_settings.max_frame_size, stream->stream_id, stream->remote_window_size); return nghttp2_min_int32( - nghttp2_min_int32(nghttp2_min_int32((int32_t)requested_window_size, - stream->remote_window_size), - session->remote_window_size), - (int32_t)session->remote_settings.max_frame_size); + nghttp2_min_int32(nghttp2_min_int32((int32_t)requested_window_size, + stream->remote_window_size), + session->remote_window_size), + (int32_t)session->remote_settings.max_frame_size); } /* @@ -2150,7 +2142,7 @@ static size_t nghttp2_session_next_data_read(nghttp2_session *session, nghttp2_ssize window_size; window_size = nghttp2_session_enforce_flow_control_limits( - session, stream, NGHTTP2_DATA_PAYLOADLEN); + session, stream, NGHTTP2_DATA_PAYLOADLEN); DEBUGF("send: available window=%td\n", window_size); @@ -2220,14 +2212,14 @@ static nghttp2_ssize session_call_select_padding(nghttp2_session *session, } max_paddedlen = - nghttp2_min_size(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen); + nghttp2_min_size(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen); if (session->callbacks.select_padding_callback2) { rv = session->callbacks.select_padding_callback2( - session, frame, max_paddedlen, session->user_data); + session, frame, max_paddedlen, session->user_data); } else { rv = (nghttp2_ssize)session->callbacks.select_padding_callback( - session, frame, max_paddedlen, session->user_data); + session, frame, max_paddedlen, session->user_data); } if (rv < (nghttp2_ssize)frame->hd.length || rv > (nghttp2_ssize)max_paddedlen) { @@ -2254,7 +2246,7 @@ static int session_headers_add_pad(nghttp2_session *session, frame->hd.length + NGHTTP2_MAX_PADLEN); padded_payloadlen = - session_call_select_padding(session, frame, max_payloadlen); + session_call_select_padding(session, frame, max_payloadlen); if (nghttp2_is_fatal((int)padded_payloadlen)) { return (int)padded_payloadlen; @@ -2298,7 +2290,7 @@ static int session_pack_extension(nghttp2_session *session, nghttp2_bufs *bufs, frame, session->user_data); } else { rv = (nghttp2_ssize)session->callbacks.pack_extension_callback( - session, buf->last, buflen, frame, session->user_data); + session, buf->last, buflen, frame, session->user_data); } if (rv == NGHTTP2_ERR_CANCEL) { return (int)rv; @@ -2364,7 +2356,6 @@ static int session_prep_frame(nghttp2_session *session, next_readmax = nghttp2_session_next_data_read(session, stream); if (next_readmax == 0) { - /* This must be true since we only pop DATA frame item from queue when session->remote_window_size > 0 */ assert(session->remote_window_size > 0); @@ -2377,9 +2368,9 @@ static int session_prep_frame(nghttp2_session *session, return NGHTTP2_ERR_DEFERRED; } - rv = nghttp2_session_pack_data(session, &session->aob.framebufs, - next_readmax, frame, &item->aux_data.data, - stream); + rv = + nghttp2_session_pack_data(session, &session->aob.framebufs, next_readmax, + frame, &item->aux_data.data, stream); if (rv == NGHTTP2_ERR_PAUSE) { return rv; } @@ -2419,9 +2410,9 @@ static int session_prep_frame(nghttp2_session *session, nghttp2_stream *stream; stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, - &frame->headers.pri_spec, NGHTTP2_STREAM_INITIAL, - aux_data->stream_user_data); + session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, + &frame->headers.pri_spec, NGHTTP2_STREAM_INITIAL, + aux_data->stream_user_data); if (stream == NULL) { return NGHTTP2_ERR_NOMEM; @@ -2468,8 +2459,8 @@ static int session_prep_frame(nghttp2_session *session, } estimated_payloadlen = session_estimate_headers_payload( - session, frame->headers.nva, frame->headers.nvlen, - NGHTTP2_PRIORITY_SPECLEN); + session, frame->headers.nva, frame->headers.nvlen, + NGHTTP2_PRIORITY_SPECLEN); if (estimated_payloadlen > session->max_send_header_block_length) { return NGHTTP2_ERR_FRAME_SIZE_ERROR; @@ -2557,14 +2548,14 @@ static int session_prep_frame(nghttp2_session *session, assert(stream); estimated_payloadlen = session_estimate_headers_payload( - session, frame->push_promise.nva, frame->push_promise.nvlen, 0); + session, frame->push_promise.nva, frame->push_promise.nvlen, 0); if (estimated_payloadlen > session->max_send_header_block_length) { return NGHTTP2_ERR_FRAME_SIZE_ERROR; } rv = nghttp2_frame_pack_push_promise( - &session->aob.framebufs, &frame->push_promise, &session->hd_deflater); + &session->aob.framebufs, &frame->push_promise, &session->hd_deflater); if (rv != 0) { return rv; } @@ -2920,7 +2911,7 @@ static int session_after_frame_sent1(nghttp2_session *session) { int stream_closed; stream_closed = - (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR; + (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR; nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR); @@ -3041,8 +3032,8 @@ static int session_after_frame_sent1(nghttp2_session *session) { } stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_FLAG_NONE, - &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); + session, frame->hd.stream_id, NGHTTP2_FLAG_NONE, + &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); if (!stream) { return NGHTTP2_ERR_NOMEM; } @@ -3074,7 +3065,6 @@ static int session_after_frame_sent1(nghttp2_session *session) { aux_data = &item->aux_data.goaway; if ((aux_data->flags & NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE) == 0) { - if (aux_data->flags & NGHTTP2_GOAWAY_AUX_TERM_ON_SEND) { session->goaway_flags |= NGHTTP2_GOAWAY_TERM_SENT; } @@ -3124,7 +3114,7 @@ static int session_after_frame_sent1(nghttp2_session *session) { rv = session_update_stream_consumed_size(session, stream, 0); } else { rv = - nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1); + nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1); } if (nghttp2_is_fatal(rv)) { @@ -3154,10 +3144,8 @@ static void session_after_frame_sent2(nghttp2_session *session) { frame = &item->frame; if (frame->hd.type != NGHTTP2_DATA) { - if (frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_PUSH_PROMISE) { - if (nghttp2_bufs_next_present(framebufs)) { framebufs->cur = framebufs->cur->next; @@ -3294,8 +3282,7 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session, it. */ if (frame->hd.type != NGHTTP2_WINDOW_UPDATE && session->callbacks.on_frame_not_send_callback( - session, frame, rv, session->user_data) != 0) { - + session, frame, rv, session->user_data) != 0) { nghttp2_outbound_item_free(item, mem); nghttp2_mem_free(mem, item); @@ -3323,8 +3310,8 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session, } if (opened_stream_id) { /* careful not to override rv */ - rv2 = nghttp2_session_close_stream(session, opened_stream_id, - error_code); + rv2 = + nghttp2_session_close_stream(session, opened_stream_id, error_code); } nghttp2_outbound_item_free(item, mem); @@ -3338,8 +3325,8 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session, if (rv == NGHTTP2_ERR_HEADER_COMP) { /* If header compression error occurred, should terminate connection. */ - rv = nghttp2_session_terminate_session(session, - NGHTTP2_INTERNAL_ERROR); + rv = + nghttp2_session_terminate_session(session, NGHTTP2_INTERNAL_ERROR); } if (nghttp2_is_fatal(rv)) { return rv; @@ -3372,7 +3359,7 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session, if (session->callbacks.on_frame_not_send_callback) { if (session->callbacks.on_frame_not_send_callback( - session, frame, rv, session->user_data) != 0) { + session, frame, rv, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } @@ -3589,10 +3576,10 @@ int nghttp2_session_send(nghttp2_session *session) { } if (session->callbacks.send_callback2) { sentlen = session->callbacks.send_callback2( - session, data, (size_t)datalen, 0, session->user_data); + session, data, (size_t)datalen, 0, session->user_data); } else { sentlen = (nghttp2_ssize)session->callbacks.send_callback( - session, data, (size_t)datalen, 0, session->user_data); + session, data, (size_t)datalen, 0, session->user_data); } if (sentlen < 0) { if (sentlen == NGHTTP2_ERR_WOULDBLOCK) { @@ -3634,7 +3621,6 @@ static int session_call_on_begin_frame(nghttp2_session *session, int rv; if (session->callbacks.on_begin_frame_callback) { - rv = session->callbacks.on_begin_frame_callback(session, hd, session->user_data); @@ -3683,11 +3669,11 @@ static int session_call_on_header(nghttp2_session *session, int rv = 0; if (session->callbacks.on_header_callback2) { rv = session->callbacks.on_header_callback2( - session, frame, nv->name, nv->value, nv->flags, session->user_data); + session, frame, nv->name, nv->value, nv->flags, session->user_data); } else if (session->callbacks.on_header_callback) { rv = session->callbacks.on_header_callback( - session, frame, nv->name->base, nv->name->len, nv->value->base, - nv->value->len, nv->flags, session->user_data); + session, frame, nv->name->base, nv->name->len, nv->value->base, + nv->value->len, nv->flags, session->user_data); } if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { @@ -3706,11 +3692,11 @@ static int session_call_on_invalid_header(nghttp2_session *session, int rv; if (session->callbacks.on_invalid_header_callback2) { rv = session->callbacks.on_invalid_header_callback2( - session, frame, nv->name, nv->value, nv->flags, session->user_data); + session, frame, nv->name, nv->value, nv->flags, session->user_data); } else if (session->callbacks.on_invalid_header_callback) { rv = session->callbacks.on_invalid_header_callback( - session, frame, nv->name->base, nv->name->len, nv->value->base, - nv->value->len, nv->flags, session->user_data); + session, frame, nv->name->base, nv->name->len, nv->value->base, + nv->value->len, nv->flags, session->user_data); } else { return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; } @@ -3734,7 +3720,7 @@ session_call_on_extension_chunk_recv_callback(nghttp2_session *session, if (session->callbacks.on_extension_chunk_recv_callback) { rv = session->callbacks.on_extension_chunk_recv_callback( - session, &frame->hd, data, len, session->user_data); + session, &frame->hd, data, len, session->user_data); if (rv == NGHTTP2_ERR_CANCEL) { return rv; } @@ -3753,7 +3739,7 @@ static int session_call_unpack_extension_callback(nghttp2_session *session) { void *payload = NULL; rv = session->callbacks.unpack_extension_callback( - session, &payload, &frame->hd, session->user_data); + session, &payload, &frame->hd, session->user_data); if (rv == NGHTTP2_ERR_CANCEL) { return rv; } @@ -3816,7 +3802,7 @@ static int session_call_on_invalid_frame_recv_callback(nghttp2_session *session, int lib_error_code) { if (session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { + session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } @@ -3829,13 +3815,13 @@ static int session_handle_invalid_stream2(nghttp2_session *session, int lib_error_code) { int rv; rv = nghttp2_session_add_rst_stream( - session, stream_id, get_error_code_from_lib_error_code(lib_error_code)); + session, stream_id, get_error_code_from_lib_error_code(lib_error_code)); if (rv != 0) { return rv; } if (session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { + session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } @@ -3869,12 +3855,12 @@ static int session_handle_invalid_connection(nghttp2_session *session, const char *reason) { if (session->callbacks.on_invalid_frame_recv_callback) { if (session->callbacks.on_invalid_frame_recv_callback( - session, frame, lib_error_code, session->user_data) != 0) { + session, frame, lib_error_code, session->user_data) != 0) { return NGHTTP2_ERR_CALLBACK_FAILURE; } } return nghttp2_session_terminate_session_with_reason( - session, get_error_code_from_lib_error_code(lib_error_code), reason); + session, get_error_code_from_lib_error_code(lib_error_code), reason); } static int session_inflate_handle_invalid_connection(nghttp2_session *session, @@ -3883,7 +3869,7 @@ static int session_inflate_handle_invalid_connection(nghttp2_session *session, const char *reason) { int rv; rv = - session_handle_invalid_connection(session, frame, lib_error_code, reason); + session_handle_invalid_connection(session, frame, lib_error_code, reason); if (nghttp2_is_fatal(rv)) { return rv; } @@ -3933,7 +3919,7 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, if (frame->hd.type == NGHTTP2_PUSH_PROMISE) { subject_stream = nghttp2_session_get_stream( - session, frame->push_promise.promised_stream_id); + session, frame->push_promise.promised_stream_id); } else { subject_stream = stream; trailer = session_trailer_headers(session, stream, frame); @@ -3954,7 +3940,7 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, from invoking subsequent callbacks for the same stream ID. */ rv = nghttp2_session_add_rst_stream( - session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR); + session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR); if (nghttp2_is_fatal(rv)) { return rv; @@ -3962,7 +3948,7 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, } } rv = - nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR); + nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -4000,11 +3986,11 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, nv.name->base, (int)nv.value->len, nv.value->base); rv2 = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Ignoring received invalid HTTP header field: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); + session, NGHTTP2_ERR_HTTP_HEADER, + "Ignoring received invalid HTTP header field: frame type: " + "%u, stream: %d, name: [%.*s], value: [%.*s]", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); if (nghttp2_is_fatal(rv2)) { return rv2; @@ -4018,19 +4004,19 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame, nv.name->base, (int)nv.value->len, nv.value->base); rv = session_call_error_callback( - session, NGHTTP2_ERR_HTTP_HEADER, - "Invalid HTTP header field was received: frame type: " - "%u, stream: %d, name: [%.*s], value: [%.*s]", - frame->hd.type, frame->hd.stream_id, (int)nv.name->len, - nv.name->base, (int)nv.value->len, nv.value->base); + session, NGHTTP2_ERR_HTTP_HEADER, + "Invalid HTTP header field was received: frame type: " + "%u, stream: %d, name: [%.*s], value: [%.*s]", + frame->hd.type, frame->hd.stream_id, (int)nv.name->len, + nv.name->base, (int)nv.value->len, nv.value->base); if (nghttp2_is_fatal(rv)) { return rv; } - rv = session_handle_invalid_stream2(session, - subject_stream->stream_id, - frame, NGHTTP2_ERR_HTTP_HEADER); + rv = + session_handle_invalid_stream2(session, subject_stream->stream_id, + frame, NGHTTP2_ERR_HTTP_HEADER); if (nghttp2_is_fatal(rv)) { return rv; } @@ -4118,7 +4104,7 @@ static int session_after_header_block_received(nghttp2_session *session) { nghttp2_stream *subject_stream; subject_stream = nghttp2_session_get_stream( - session, frame->push_promise.promised_stream_id); + session, frame->push_promise.promised_stream_id); if (subject_stream) { rv = nghttp2_http_on_request_headers(subject_stream, frame); } @@ -4190,7 +4176,7 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, nghttp2_stream *stream; if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: stream_id == 0"); } /* If client receives idle stream from server, it is invalid @@ -4199,8 +4185,8 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, if (!session->server) { if (session_detect_idle_stream(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: client received request"); + session, frame, NGHTTP2_ERR_PROTO, + "request HEADERS: client received request"); } return NGHTTP2_ERR_IGN_HEADER_BLOCK; @@ -4212,8 +4198,8 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, if (frame->hd.stream_id == 0 || nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: invalid stream_id"); + session, frame, NGHTTP2_ERR_PROTO, + "request HEADERS: invalid stream_id"); } /* RFC 7540 says if an endpoint receives a HEADERS with invalid @@ -4239,7 +4225,7 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id); if (stream && (stream->shut_flags & NGHTTP2_SHUT_RD)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); } return NGHTTP2_ERR_IGN_HEADER_BLOCK; @@ -4248,8 +4234,8 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, if (session_is_incoming_concurrent_streams_max(session)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "request HEADERS: max concurrent streams exceeded"); + session, frame, NGHTTP2_ERR_PROTO, + "request HEADERS: max concurrent streams exceeded"); } if (!session_allow_incoming_new_stream(session)) { @@ -4259,7 +4245,7 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, if (frame->headers.pri_spec.stream_id == frame->hd.stream_id) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: depend on itself"); + session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: depend on itself"); } if (session_is_incoming_concurrent_streams_pending_max(session)) { @@ -4268,8 +4254,8 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session, } stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, - &frame->headers.pri_spec, NGHTTP2_STREAM_OPENING, NULL); + session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, + &frame->headers.pri_spec, NGHTTP2_STREAM_OPENING, NULL); if (!stream) { return NGHTTP2_ERR_NOMEM; } @@ -4298,7 +4284,7 @@ int nghttp2_session_on_response_headers_received(nghttp2_session *session, nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)); if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "response HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "response HEADERS: stream_id == 0"); } if (stream->shut_flags & NGHTTP2_SHUT_RD) { /* half closed (remote): from the spec: @@ -4310,7 +4296,7 @@ int nghttp2_session_on_response_headers_received(nghttp2_session *session, We go further, and make it connection error. */ return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); } stream->state = NGHTTP2_STREAM_OPENED; rv = session_call_on_begin_headers(session, frame); @@ -4327,20 +4313,20 @@ int nghttp2_session_on_push_response_headers_received(nghttp2_session *session, assert(stream->state == NGHTTP2_STREAM_RESERVED); if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "push response HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, + "push response HEADERS: stream_id == 0"); } if (session->server) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "HEADERS: no HEADERS allowed from client in reserved state"); + session, frame, NGHTTP2_ERR_PROTO, + "HEADERS: no HEADERS allowed from client in reserved state"); } if (session_is_incoming_concurrent_streams_max(session)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "push response HEADERS: max concurrent streams exceeded"); + session, frame, NGHTTP2_ERR_PROTO, + "push response HEADERS: max concurrent streams exceeded"); } if (!session_allow_incoming_new_stream(session)) { @@ -4371,7 +4357,7 @@ int nghttp2_session_on_headers_received(nghttp2_session *session, int rv = 0; if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0"); } if ((stream->shut_flags & NGHTTP2_SHUT_RD)) { /* half closed (remote): from the spec: @@ -4383,7 +4369,7 @@ int nghttp2_session_on_headers_received(nghttp2_session *session, we go further, and make it connection error. */ return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed"); } if (nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { if (stream->state == NGHTTP2_STREAM_OPENED) { @@ -4453,7 +4439,7 @@ int nghttp2_session_on_priority_received(nghttp2_session *session, if (frame->priority.pri_spec.stream_id == frame->hd.stream_id) { return nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "depend on itself"); + session, NGHTTP2_PROTOCOL_ERROR, "depend on itself"); } if (!session->server) { @@ -4471,8 +4457,8 @@ int nghttp2_session_on_priority_received(nghttp2_session *session, } stream = nghttp2_session_open_stream( - session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, - &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); + session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE, + &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL); if (stream == NULL) { return NGHTTP2_ERR_NOMEM; @@ -4578,7 +4564,7 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { stream = (nghttp2_stream *)entry; rv = nghttp2_stream_update_remote_initial_window_size( - stream, arg->new_window_size, arg->old_window_size); + stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, NGHTTP2_FLOW_CONTROL_ERROR); @@ -4588,9 +4574,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) { outbound queue. */ if (stream->remote_window_size > 0 && nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = session_resume_deferred_stream_item( - arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); + arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); if (nghttp2_is_fatal(rv)) { return rv; @@ -4629,7 +4614,7 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { arg = (nghttp2_update_window_size_arg *)ptr; stream = (nghttp2_stream *)entry; rv = nghttp2_stream_update_local_initial_window_size( - stream, arg->new_window_size, arg->old_window_size); + stream, arg->new_window_size, arg->old_window_size); if (rv != 0) { return nghttp2_session_add_rst_stream(arg->session, stream->stream_id, NGHTTP2_FLOW_CONTROL_ERROR); @@ -4645,7 +4630,6 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) { if (nghttp2_should_send_window_update(stream->local_window_size, stream->recv_window_size)) { - rv = nghttp2_session_add_window_update(arg->session, NGHTTP2_FLAG_NONE, stream->stream_id, stream->recv_window_size); @@ -4711,7 +4695,7 @@ int nghttp2_session_update_local_settings(nghttp2_session *session, header_table_size_seen = 1; header_table_size = iv[i].value; min_header_table_size = - nghttp2_min_uint32(min_header_table_size, iv[i].value); + nghttp2_min_uint32(min_header_table_size, iv[i].value); break; case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE: new_initial_window_size = (int32_t)iv[i].value; @@ -4735,8 +4719,8 @@ int nghttp2_session_update_local_settings(nghttp2_session *session, } if (new_initial_window_size != -1) { rv = session_update_local_initial_window_size( - session, new_initial_window_size, - (int32_t)session->local_settings.initial_window_size); + session, new_initial_window_size, + (int32_t)session->local_settings.initial_window_size); if (rv != 0) { return rv; } @@ -4790,15 +4774,15 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, if (frame->hd.flags & NGHTTP2_FLAG_ACK) { if (frame->settings.niv != 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FRAME_SIZE_ERROR, - "SETTINGS: ACK and payload != 0"); + session, frame, NGHTTP2_ERR_FRAME_SIZE_ERROR, + "SETTINGS: ACK and payload != 0"); } settings = session->inflight_settings_head; if (!settings) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "SETTINGS: unexpected ACK"); + session, frame, NGHTTP2_ERR_PROTO, "SETTINGS: unexpected ACK"); } rv = nghttp2_session_update_local_settings(session, settings->iv, @@ -4819,7 +4803,7 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, if (!session->remote_settings_received) { session->remote_settings.max_concurrent_streams = - NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; + NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS; session->remote_settings_received = 1; } @@ -4836,7 +4820,7 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, return rv; } else { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_HEADER_COMP, NULL); + session, frame, NGHTTP2_ERR_HEADER_COMP, NULL); } } @@ -4847,14 +4831,14 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, if (entry->value != 0 && entry->value != 1) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_ENBLE_PUSH"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_ENBLE_PUSH"); } if (!session->server && entry->value != 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: server attempted to enable push"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: server attempted to enable push"); } session->remote_settings.enable_push = entry->value; @@ -4871,8 +4855,8 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, /* Check that initial_window_size < (1u << 31) */ if (entry->value > NGHTTP2_MAX_WINDOW_SIZE) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, - "SETTINGS: too large SETTINGS_INITIAL_WINDOW_SIZE"); + session, frame, NGHTTP2_ERR_FLOW_CONTROL, + "SETTINGS: too large SETTINGS_INITIAL_WINDOW_SIZE"); } rv = session_update_remote_initial_window_size(session, @@ -4884,7 +4868,7 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, if (rv != 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL); + session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL); } session->remote_settings.initial_window_size = entry->value; @@ -4895,8 +4879,8 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, if (entry->value < NGHTTP2_MAX_FRAME_SIZE_MIN || entry->value > NGHTTP2_MAX_FRAME_SIZE_MAX) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_MAX_FRAME_SIZE"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_MAX_FRAME_SIZE"); } session->remote_settings.max_frame_size = entry->value; @@ -4911,17 +4895,17 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, if (entry->value != 0 && entry->value != 1) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL"); } if (!session->server && session->remote_settings.enable_connect_protocol && entry->value == 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: server attempted to disable " - "SETTINGS_ENABLE_CONNECT_PROTOCOL"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: server attempted to disable " + "SETTINGS_ENABLE_CONNECT_PROTOCOL"); } session->remote_settings.enable_connect_protocol = entry->value; @@ -4931,15 +4915,15 @@ int nghttp2_session_on_settings_received(nghttp2_session *session, if (entry->value != 0 && entry->value != 1) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES"); } if (session->remote_settings.no_rfc7540_priorities != UINT32_MAX && session->remote_settings.no_rfc7540_priorities != entry->value) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed"); + session, frame, NGHTTP2_ERR_PROTO, + "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed"); } session->remote_settings.no_rfc7540_priorities = entry->value; @@ -5020,16 +5004,16 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, if (frame->hd.stream_id == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream_id == 0"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream_id == 0"); } if (session->server || session->local_settings.enable_push == 0) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: push disabled"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: push disabled"); } if (!nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: invalid stream_id"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: invalid stream_id"); } if (!session_allow_incoming_new_stream(session)) { @@ -5043,13 +5027,13 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, illegal stream ID is subject to a connection error of type PROTOCOL_ERROR. */ return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PUSH_PROMISE: invalid promised_stream_id"); + session, frame, NGHTTP2_ERR_PROTO, + "PUSH_PROMISE: invalid promised_stream_id"); } if (session_detect_idle_stream(session, frame->hd.stream_id)) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle"); + session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle"); } session->last_recv_stream_id = frame->push_promise.promised_stream_id; @@ -5057,12 +5041,12 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, if (!stream || stream->state == NGHTTP2_STREAM_CLOSING || !session->pending_enable_push || session->num_incoming_reserved_streams >= - session->max_incoming_reserved_streams) { + session->max_incoming_reserved_streams) { /* Currently, client does not retain closed stream, so we don't check NGHTTP2_SHUT_RD condition here. */ rv = nghttp2_session_add_rst_stream( - session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); + session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL); if (rv != 0) { return rv; } @@ -5071,16 +5055,15 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session, if (stream->shut_flags & NGHTTP2_SHUT_RD) { return session_inflate_handle_invalid_connection( - session, frame, NGHTTP2_ERR_STREAM_CLOSED, - "PUSH_PROMISE: stream closed"); + session, frame, NGHTTP2_ERR_STREAM_CLOSED, "PUSH_PROMISE: stream closed"); } nghttp2_priority_spec_init(&pri_spec, stream->stream_id, NGHTTP2_DEFAULT_WEIGHT, 0); promised_stream = nghttp2_session_open_stream( - session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE, - &pri_spec, NGHTTP2_STREAM_RESERVED, NULL); + session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE, + &pri_spec, NGHTTP2_STREAM_RESERVED, NULL); if (!promised_stream) { return NGHTTP2_ERR_NOMEM; @@ -5187,8 +5170,8 @@ session_on_connection_window_update_received(nghttp2_session *session, /* Handle connection-level flow control */ if (frame->window_update.window_size_increment == 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "WINDOW_UPDATE: window_size_increment == 0"); + session, frame, NGHTTP2_ERR_PROTO, + "WINDOW_UPDATE: window_size_increment == 0"); } if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < @@ -5217,12 +5200,12 @@ static int session_on_stream_window_update_received(nghttp2_session *session, } if (state_reserved_remote(session, stream)) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPADATE to reserved stream"); + session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPADATE to reserved stream"); } if (frame->window_update.window_size_increment == 0) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "WINDOW_UPDATE: window_size_increment == 0"); + session, frame, NGHTTP2_ERR_PROTO, + "WINDOW_UPDATE: window_size_increment == 0"); } if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment < stream->remote_window_size) { @@ -5233,9 +5216,8 @@ static int session_on_stream_window_update_received(nghttp2_session *session, if (stream->remote_window_size > 0 && nghttp2_stream_check_deferred_by_flow_control(stream)) { - rv = session_resume_deferred_stream_item( - session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); + session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL); if (nghttp2_is_fatal(rv)) { return rv; @@ -5326,8 +5308,8 @@ int nghttp2_session_on_priority_update_received(nghttp2_session *session, if (nghttp2_session_is_my_stream_id(session, priority_update->stream_id)) { if (session_detect_idle_stream(session, priority_update->stream_id)) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY_UPDATE: prioritizing idle push is not allowed"); + session, frame, NGHTTP2_ERR_PROTO, + "PRIORITY_UPDATE: prioritizing idle push is not allowed"); } /* TODO Ignore priority signal to a push stream for now */ @@ -5344,8 +5326,8 @@ int nghttp2_session_on_priority_update_received(nghttp2_session *session, if (session->num_idle_streams + session->num_incoming_streams >= session->local_settings.max_concurrent_streams) { return session_handle_invalid_connection( - session, frame, NGHTTP2_ERR_PROTO, - "PRIORITY_UPDATE: max concurrent streams exceeded"); + session, frame, NGHTTP2_ERR_PROTO, + "PRIORITY_UPDATE: max concurrent streams exceeded"); } nghttp2_priority_spec_default_init(&pri_spec); @@ -5385,8 +5367,8 @@ static int session_process_altsvc_frame(nghttp2_session *session) { nghttp2_frame *frame = &iframe->frame; nghttp2_frame_unpack_altsvc_payload( - &frame->ext, nghttp2_get_uint16(iframe->sbuf.pos), iframe->lbuf.pos, - nghttp2_buf_len(&iframe->lbuf)); + &frame->ext, nghttp2_get_uint16(iframe->sbuf.pos), iframe->lbuf.pos, + nghttp2_buf_len(&iframe->lbuf)); /* nghttp2_frame_unpack_altsvc_payload steals buffer from iframe->lbuf */ @@ -5539,9 +5521,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session, stream->window_update_queued == 0 && nghttp2_should_send_window_update(stream->local_window_size, stream->recv_window_size)) { - rv = nghttp2_session_add_window_update(session, NGHTTP2_FLAG_NONE, - stream->stream_id, - stream->recv_window_size); + rv = nghttp2_session_add_window_update( + session, NGHTTP2_FLAG_NONE, stream->stream_id, stream->recv_window_size); if (rv != 0) { return rv; } @@ -5619,16 +5600,16 @@ static int session_update_stream_consumed_size(nghttp2_session *session, nghttp2_stream *stream, size_t delta_size) { return session_update_consumed_size( - session, &stream->consumed_size, &stream->recv_window_size, - stream->window_update_queued, stream->stream_id, delta_size, - stream->local_window_size); + session, &stream->consumed_size, &stream->recv_window_size, + stream->window_update_queued, stream->stream_id, delta_size, + stream->local_window_size); } static int session_update_connection_consumed_size(nghttp2_session *session, size_t delta_size) { return session_update_consumed_size( - session, &session->consumed_size, &session->recv_window_size, - session->window_update_queued, 0, delta_size, session->local_window_size); + session, &session->consumed_size, &session->recv_window_size, + session->window_update_queued, 0, delta_size, session->local_window_size); } /* @@ -5842,7 +5823,7 @@ static nghttp2_ssize inbound_frame_effective_readlen(nghttp2_inbound_frame *iframe, size_t payloadleft, size_t readlen) { size_t trail_padlen = - nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen); + nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen); if (trail_padlen > payloadleft) { size_t padlen; @@ -5933,17 +5914,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (iframe->sbuf.pos[3] != NGHTTP2_SETTINGS || (iframe->sbuf.pos[4] & NGHTTP2_FLAG_ACK)) { rv = session_call_error_callback( - session, NGHTTP2_ERR_SETTINGS_EXPECTED, - "Remote peer returned unexpected data while we expected " - "SETTINGS frame. Perhaps, peer does not support HTTP/2 " - "properly."); + session, NGHTTP2_ERR_SETTINGS_EXPECTED, + "Remote peer returned unexpected data while we expected " + "SETTINGS frame. Perhaps, peer does not support HTTP/2 " + "properly."); if (nghttp2_is_fatal(rv)) { return rv; } rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected"); + session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected"); if (nghttp2_is_fatal(rv)) { return rv; @@ -5979,7 +5960,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, session->local_settings.max_frame_size); rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size"); + session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size"); if (nghttp2_is_fatal(rv)) { return rv; @@ -5993,7 +5974,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, DEBUGF("recv: DATA\n"); iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PADDED); + (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PADDED); /* Check stream is open. If it is not open or closing, ignore payload. */ busy = 1; @@ -6016,8 +5997,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); if (rv < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "DATA: insufficient padding space"); + session, NGHTTP2_PROTOCOL_ERROR, + "DATA: insufficient padding space"); if (nghttp2_is_fatal(rv)) { return rv; @@ -6038,14 +6019,14 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, DEBUGF("recv: HEADERS\n"); iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS | - NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_PRIORITY); + (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS | + NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_PRIORITY); rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); if (rv < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "HEADERS: insufficient padding space"); + session, NGHTTP2_PROTOCOL_ERROR, + "HEADERS: insufficient padding space"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6097,7 +6078,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); + session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6184,12 +6165,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, /* We allocate iv with additional one entry, to store the minimum header table size. */ iframe->max_niv = - iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1; + iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1; if (iframe->max_niv - 1 > session->max_settings) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_ENHANCE_YOUR_CALM, - "SETTINGS: too many setting entries"); + session, NGHTTP2_ENHANCE_YOUR_CALM, + "SETTINGS: too many setting entries"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6197,7 +6178,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) * - iframe->max_niv); + iframe->max_niv); if (!iframe->iv) { return NGHTTP2_ERR_NOMEM; @@ -6205,7 +6186,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1]; min_header_table_size_entry->settings_id = - NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; + NGHTTP2_SETTINGS_HEADER_TABLE_SIZE; min_header_table_size_entry->value = UINT32_MAX; inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH); @@ -6221,13 +6202,13 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, DEBUGF("recv: PUSH_PROMISE\n"); iframe->frame.hd.flags &= - (NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED); + (NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED); rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); if (rv < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PUSH_PROMISE: insufficient padding space"); + session, NGHTTP2_PROTOCOL_ERROR, + "PUSH_PROMISE: insufficient padding space"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6286,7 +6267,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, /* Receiving CONTINUATION in this state are subject to connection error of type PROTOCOL_ERROR */ rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "CONTINUATION: unexpected"); + session, NGHTTP2_PROTOCOL_ERROR, "CONTINUATION: unexpected"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6393,12 +6374,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, iframe->frame.hd.flags = NGHTTP2_FLAG_NONE; iframe->frame.ext.payload = - &iframe->ext_frame_payload.priority_update; + &iframe->ext_frame_payload.priority_update; if (!session->server) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PRIORITY_UPDATE is received from server"); + session, NGHTTP2_PROTOCOL_ERROR, + "PRIORITY_UPDATE is received from server"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6476,7 +6457,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (padlen < 0 || (size_t)padlen + pri_fieldlen > 1 + iframe->payloadleft) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding"); + session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6512,7 +6493,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); + session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6562,10 +6543,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, (iframe->frame.hd.flags & NGHTTP2_FLAG_PADDED)) { padlen = inbound_frame_compute_pad(iframe); if (padlen < 0 || (size_t)padlen + 4 /* promised stream id */ - > 1 + iframe->payloadleft) { + > 1 + iframe->payloadleft) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "PUSH_PROMISE: invalid padding"); + session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: invalid padding"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6600,8 +6580,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) { rv = nghttp2_session_add_rst_stream( - session, iframe->frame.push_promise.promised_stream_id, - NGHTTP2_INTERNAL_ERROR); + session, iframe->frame.push_promise.promised_stream_id, + NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6680,7 +6660,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (iframe->frame.hd.length > 2) { iframe->raw_lbuf = - nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2); + nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2); if (iframe->raw_lbuf == NULL) { return NGHTTP2_ERR_NOMEM; @@ -6734,7 +6714,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, iframe->payloadleft - readlen); data_readlen = inbound_frame_effective_readlen( - iframe, iframe->payloadleft - readlen, readlen); + iframe, iframe->payloadleft - readlen, readlen); if (data_readlen == -1) { /* everything is padding */ @@ -6752,9 +6732,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, DEBUGF("recv: block final=%d\n", final); rv = - inflate_header_block(session, &iframe->frame, &hd_proclen, - (uint8_t *)in, (size_t)data_readlen, final, - iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK); + inflate_header_block(session, &iframe->frame, &hd_proclen, + (uint8_t *)in, (size_t)data_readlen, final, + iframe->state == NGHTTP2_IB_READ_HEADER_BLOCK); if (nghttp2_is_fatal(rv)) { return rv; @@ -6780,11 +6760,11 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, /* Use promised stream ID for PUSH_PROMISE */ rv = nghttp2_session_add_rst_stream( - session, - iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE - ? iframe->frame.push_promise.promised_stream_id - : iframe->frame.hd.stream_id, - NGHTTP2_INTERNAL_ERROR); + session, + iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE + ? iframe->frame.push_promise.promised_stream_id + : iframe->frame.hd.stream_id, + NGHTTP2_INTERNAL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6816,7 +6796,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if ((iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) == 0) { - inbound_frame_set_mark(iframe, NGHTTP2_FRAME_HDLEN); iframe->padlen = 0; @@ -6981,8 +6960,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, iframe->frame.hd.stream_id, NGHTTP2_CONTINUATION, cont_hd.stream_id, cont_hd.type); rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, - "unexpected non-CONTINUATION frame or stream_id is invalid"); + session, NGHTTP2_PROTOCOL_ERROR, + "unexpected non-CONTINUATION frame or stream_id is invalid"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -6993,8 +6972,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, /* CONTINUATION won't bear NGHTTP2_PADDED flag */ iframe->frame.hd.flags = - (uint8_t)(iframe->frame.hd.flags | - (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS)); + (uint8_t)(iframe->frame.hd.flags | + (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS)); iframe->frame.hd.length += cont_hd.length; busy = 1; @@ -7038,7 +7017,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, /* Pad Length field is consumed immediately */ rv = - nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen); + nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen); if (nghttp2_is_fatal(rv)) { return rv; @@ -7051,9 +7030,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id); if (stream) { rv = nghttp2_session_update_recv_stream_window_size( - session, stream, readlen, - iframe->payloadleft || - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); + session, stream, readlen, + iframe->payloadleft || + (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); if (nghttp2_is_fatal(rv)) { return rv; } @@ -7064,7 +7043,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, padlen = inbound_frame_compute_pad(iframe); if (padlen < 0) { rv = nghttp2_session_terminate_session_with_reason( - session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding"); + session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding"); if (nghttp2_is_fatal(rv)) { return rv; } @@ -7097,8 +7076,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (readlen > 0) { nghttp2_ssize data_readlen; - rv = nghttp2_session_update_recv_connection_window_size(session, - readlen); + rv = + nghttp2_session_update_recv_connection_window_size(session, readlen); if (nghttp2_is_fatal(rv)) { return rv; } @@ -7108,15 +7087,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } rv = nghttp2_session_update_recv_stream_window_size( - session, stream, readlen, - iframe->payloadleft || - (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); + session, stream, readlen, + iframe->payloadleft || + (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0); if (nghttp2_is_fatal(rv)) { return rv; } - data_readlen = inbound_frame_effective_readlen( - iframe, iframe->payloadleft, readlen); + data_readlen = + inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen); if (data_readlen == -1) { /* everything is padding */ @@ -7147,7 +7126,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { /* Consume all data for connection immediately here */ rv = session_update_connection_consumed_size( - session, (size_t)data_readlen); + session, (size_t)data_readlen); if (nghttp2_is_fatal(rv)) { return rv; @@ -7159,7 +7138,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } rv = nghttp2_session_add_rst_stream( - session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR); + session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } @@ -7170,8 +7149,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (session->callbacks.on_data_chunk_recv_callback) { rv = session->callbacks.on_data_chunk_recv_callback( - session, iframe->frame.hd.flags, iframe->frame.hd.stream_id, - in - readlen, (size_t)data_readlen, session->user_data); + session, iframe->frame.hd.flags, iframe->frame.hd.stream_id, + in - readlen, (size_t)data_readlen, session->user_data); if (rv == NGHTTP2_ERR_PAUSE) { return (nghttp2_ssize)(in - first); } @@ -7208,8 +7187,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (readlen > 0) { /* Update connection-level flow control window for ignored DATA frame too */ - rv = nghttp2_session_update_recv_connection_window_size(session, - readlen); + rv = + nghttp2_session_update_recv_connection_window_size(session, readlen); if (nghttp2_is_fatal(rv)) { return rv; } @@ -7219,7 +7198,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, } if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) { - /* Ignored DATA is considered as "consumed" immediately. */ rv = session_update_connection_consumed_size(session, readlen); @@ -7254,7 +7232,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, if (readlen > 0) { rv = session_call_on_extension_chunk_recv_callback( - session, in - readlen, readlen); + session, in - readlen, readlen); if (nghttp2_is_fatal(rv)) { return rv; } @@ -7363,7 +7341,7 @@ int nghttp2_session_recv(nghttp2_session *session) { readlen = session_recv(session, buf, sizeof(buf)); if (readlen > 0) { nghttp2_ssize proclen = - nghttp2_session_mem_recv2(session, buf, (size_t)readlen); + nghttp2_session_mem_recv2(session, buf, (size_t)readlen); if (proclen < 0) { return (int)proclen; } @@ -7513,7 +7491,7 @@ int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id, /* last_stream_id must not be increased from the value previously sent */ last_stream_id = - nghttp2_min_int32(last_stream_id, session->local_last_stream_id); + nghttp2_min_int32(last_stream_id, session->local_last_stream_id); nghttp2_frame_goaway_init(&frame->goaway, last_stream_id, error_code, opaque_data_copy, opaque_data_len); @@ -7719,20 +7697,20 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs, session->callbacks.read_length_callback) { if (session->callbacks.read_length_callback2) { payloadlen = session->callbacks.read_length_callback2( - session, frame->hd.type, stream->stream_id, - session->remote_window_size, stream->remote_window_size, - session->remote_settings.max_frame_size, session->user_data); + session, frame->hd.type, stream->stream_id, session->remote_window_size, + stream->remote_window_size, session->remote_settings.max_frame_size, + session->user_data); } else { payloadlen = (nghttp2_ssize)session->callbacks.read_length_callback( - session, frame->hd.type, stream->stream_id, - session->remote_window_size, stream->remote_window_size, - session->remote_settings.max_frame_size, session->user_data); + session, frame->hd.type, stream->stream_id, session->remote_window_size, + stream->remote_window_size, session->remote_settings.max_frame_size, + session->user_data); } DEBUGF("send: read_length_callback=%td\n", payloadlen); - payloadlen = nghttp2_session_enforce_flow_control_limits(session, stream, - payloadlen); + payloadlen = + nghttp2_session_enforce_flow_control_limits(session, stream, payloadlen); DEBUGF("send: read_length_callback after flow control=%td\n", payloadlen); @@ -7769,14 +7747,14 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs, switch (aux_data->dpw.version) { case NGHTTP2_DATA_PROVIDER_V1: payloadlen = (nghttp2_ssize)aux_data->dpw.data_prd.v1.read_callback( - session, frame->hd.stream_id, buf->pos, datamax, &data_flags, - &aux_data->dpw.data_prd.source, session->user_data); + session, frame->hd.stream_id, buf->pos, datamax, &data_flags, + &aux_data->dpw.data_prd.source, session->user_data); break; case NGHTTP2_DATA_PROVIDER_V2: payloadlen = aux_data->dpw.data_prd.v2.read_callback( - session, frame->hd.stream_id, buf->pos, datamax, &data_flags, - &aux_data->dpw.data_prd.source, session->user_data); + session, frame->hd.stream_id, buf->pos, datamax, &data_flags, + &aux_data->dpw.data_prd.source, session->user_data); break; default: @@ -7828,10 +7806,10 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs, frame->data.padlen = 0; max_payloadlen = - nghttp2_min_size(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN); + nghttp2_min_size(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN); padded_payloadlen = - session_call_select_padding(session, frame, max_payloadlen); + session_call_select_padding(session, frame, max_payloadlen); if (nghttp2_is_fatal((int)padded_payloadlen)) { return (int)padded_payloadlen; @@ -8108,8 +8086,8 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session, nghttp2_priority_spec_default_init(&pri_spec); stream = nghttp2_session_open_stream( - session, 1, NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_OPENING, - session->server ? NULL : stream_user_data); + session, 1, NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_OPENING, + session->server ? NULL : stream_user_data); if (stream == NULL) { return NGHTTP2_ERR_NOMEM; } @@ -8330,8 +8308,8 @@ int nghttp2_session_check_server_session(nghttp2_session *session) { } int nghttp2_session_change_stream_priority( - nghttp2_session *session, int32_t stream_id, - const nghttp2_priority_spec *pri_spec) { + nghttp2_session *session, int32_t stream_id, + const nghttp2_priority_spec *pri_spec) { int rv; nghttp2_stream *stream; nghttp2_priority_spec pri_spec_copy; @@ -8390,8 +8368,8 @@ int nghttp2_session_create_idle_stream(nghttp2_session *session, nghttp2_priority_spec_normalize_weight(&pri_spec_copy); stream = - nghttp2_session_open_stream(session, stream_id, NGHTTP2_STREAM_FLAG_NONE, - &pri_spec_copy, NGHTTP2_STREAM_IDLE, NULL); + nghttp2_session_open_stream(session, stream_id, NGHTTP2_STREAM_FLAG_NONE, + &pri_spec_copy, NGHTTP2_STREAM_IDLE, NULL); if (!stream) { return NGHTTP2_ERR_NOMEM; } @@ -8419,8 +8397,8 @@ void nghttp2_session_set_user_data(nghttp2_session *session, void *user_data) { } int nghttp2_session_change_extpri_stream_priority( - nghttp2_session *session, int32_t stream_id, - const nghttp2_extpri *extpri_in, int ignore_client_signal) { + nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri_in, + int ignore_client_signal) { nghttp2_stream *stream; nghttp2_extpri extpri = *extpri_in; diff --git a/deps/nghttp2/lib/nghttp2_stream.c b/deps/nghttp2/lib/nghttp2_stream.c index bf8b8c39e25acb..f2362447903755 100644 --- a/deps/nghttp2/lib/nghttp2_stream.c +++ b/deps/nghttp2/lib/nghttp2_stream.c @@ -277,9 +277,9 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) { /* Compute old stream->pending_penalty we used to calculate stream->cycle */ stream->pending_penalty = - (uint32_t)((stream->pending_penalty + (uint32_t)old_weight - - (wlen_penalty % (uint32_t)old_weight)) % - (uint32_t)old_weight); + (uint32_t)((stream->pending_penalty + (uint32_t)old_weight - + (wlen_penalty % (uint32_t)old_weight)) % + (uint32_t)old_weight); last_cycle = stream->cycle - (wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight; @@ -571,16 +571,16 @@ static int update_initial_window_size(int32_t *window_size_ptr, } int nghttp2_stream_update_remote_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size) { + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size) { return update_initial_window_size(&stream->remote_window_size, new_initial_window_size, old_initial_window_size); } int nghttp2_stream_update_local_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size) { + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size) { return update_initial_window_size(&stream->local_window_size, new_initial_window_size, old_initial_window_size); diff --git a/deps/nghttp2/lib/nghttp2_stream.h b/deps/nghttp2/lib/nghttp2_stream.h index 71b9fb1140c932..28add165469d94 100644 --- a/deps/nghttp2/lib/nghttp2_stream.h +++ b/deps/nghttp2/lib/nghttp2_stream.h @@ -124,10 +124,9 @@ typedef enum { NGHTTP2_HTTP_FLAG_METH_HEAD = 1 << 8, NGHTTP2_HTTP_FLAG_METH_OPTIONS = 1 << 9, NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND = 1 << 10, - NGHTTP2_HTTP_FLAG_METH_ALL = NGHTTP2_HTTP_FLAG_METH_CONNECT | - NGHTTP2_HTTP_FLAG_METH_HEAD | - NGHTTP2_HTTP_FLAG_METH_OPTIONS | - NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND, + NGHTTP2_HTTP_FLAG_METH_ALL = + NGHTTP2_HTTP_FLAG_METH_CONNECT | NGHTTP2_HTTP_FLAG_METH_HEAD | + NGHTTP2_HTTP_FLAG_METH_OPTIONS | NGHTTP2_HTTP_FLAG_METH_UPGRADE_WORKAROUND, /* :path category */ /* path starts with "/" */ NGHTTP2_HTTP_FLAG_PATH_REGULAR = 1 << 11, @@ -296,8 +295,8 @@ int nghttp2_stream_check_deferred_by_flow_control(nghttp2_stream *stream); * overflow. */ int nghttp2_stream_update_remote_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size); + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size); /* * Updates the local window size with the new value @@ -308,8 +307,8 @@ int nghttp2_stream_update_remote_initial_window_size( * overflow. */ int nghttp2_stream_update_local_initial_window_size( - nghttp2_stream *stream, int32_t new_initial_window_size, - int32_t old_initial_window_size); + nghttp2_stream *stream, int32_t new_initial_window_size, + int32_t old_initial_window_size); /* * Call this function if promised stream |stream| is replied with diff --git a/deps/nghttp2/lib/nghttp2_submit.c b/deps/nghttp2/lib/nghttp2_submit.c index 72e6588ffbe77d..81c1ab7046bc33 100644 --- a/deps/nghttp2/lib/nghttp2_submit.c +++ b/deps/nghttp2/lib/nghttp2_submit.c @@ -94,8 +94,8 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags, item->aux_data.headers.stream_user_data = stream_user_data; flags_copy = - (uint8_t)((flags & (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PRIORITY)) | - NGHTTP2_FLAG_END_HEADERS); + (uint8_t)((flags & (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PRIORITY)) | + NGHTTP2_FLAG_END_HEADERS); if (stream_id == -1) { if (session->next_stream_id > INT32_MAX) { @@ -174,9 +174,8 @@ int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id, return NGHTTP2_ERR_INVALID_ARGUMENT; } - return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM, - stream_id, NULL, nva, nvlen, NULL, - NULL); + return (int)submit_headers_shared_nva( + session, NGHTTP2_FLAG_END_STREAM, stream_id, NULL, nva, nvlen, NULL, NULL); } int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags, @@ -389,8 +388,8 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags, } if (stream_id == 0) { rv = nghttp2_adjust_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); + &session->local_window_size, &session->recv_window_size, + &session->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } @@ -401,8 +400,8 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags, } rv = nghttp2_adjust_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); + &stream->local_window_size, &stream->recv_window_size, + &stream->recv_reduction, &window_size_increment); if (rv != 0) { return rv; } @@ -411,10 +410,10 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags, if (window_size_increment > 0) { if (stream_id == 0) { session->consumed_size = - nghttp2_max_int32(0, session->consumed_size - window_size_increment); + nghttp2_max_int32(0, session->consumed_size - window_size_increment); } else { stream->consumed_size = - nghttp2_max_int32(0, stream->consumed_size - window_size_increment); + nghttp2_max_int32(0, stream->consumed_size - window_size_increment); } return nghttp2_session_add_window_update(session, 0, stream_id, @@ -444,13 +443,13 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session, if (window_size_increment < 0) { return nghttp2_adjust_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); + &session->local_window_size, &session->recv_window_size, + &session->recv_reduction, &window_size_increment); } rv = nghttp2_increase_local_window_size( - &session->local_window_size, &session->recv_window_size, - &session->recv_reduction, &window_size_increment); + &session->local_window_size, &session->recv_window_size, + &session->recv_reduction, &window_size_increment); if (rv != 0) { return rv; @@ -477,13 +476,13 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session, if (window_size_increment < 0) { return nghttp2_adjust_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); + &stream->local_window_size, &stream->recv_window_size, + &stream->recv_reduction, &window_size_increment); } rv = nghttp2_increase_local_window_size( - &stream->local_window_size, &stream->recv_window_size, - &stream->recv_reduction, &window_size_increment); + &stream->local_window_size, &stream->recv_window_size, + &stream->recv_reduction, &window_size_increment); if (rv != 0) { return rv; @@ -614,7 +613,7 @@ int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags, /* The last nov is added for terminal NULL character. */ ov_copy = - nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov); + nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov); if (ov_copy == NULL) { return NGHTTP2_ERR_NOMEM; } @@ -898,7 +897,7 @@ int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, assert(data_prd); return nghttp2_submit_data_shared( - session, flags, stream_id, nghttp2_data_provider_wrap_v1(&dpw, data_prd)); + session, flags, stream_id, nghttp2_data_provider_wrap_v1(&dpw, data_prd)); } int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags, @@ -909,7 +908,7 @@ int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags, assert(data_prd); return nghttp2_submit_data_shared( - session, flags, stream_id, nghttp2_data_provider_wrap_v2(&dpw, data_prd)); + session, flags, stream_id, nghttp2_data_provider_wrap_v2(&dpw, data_prd)); } ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen, diff --git a/deps/nghttp2/lib/nghttp2_time.c b/deps/nghttp2/lib/nghttp2_time.c index 947b5449e5ac6d..148ccfdce81c12 100644 --- a/deps/nghttp2/lib/nghttp2_time.c +++ b/deps/nghttp2/lib/nghttp2_time.c @@ -45,7 +45,7 @@ static uint64_t time_now_sec(void) { #if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__) uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } #elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_DECL_CLOCK_MONOTONIC) && \ - HAVE_DECL_CLOCK_MONOTONIC + HAVE_DECL_CLOCK_MONOTONIC uint64_t nghttp2_time_now_sec(void) { struct timespec tp; int rv = clock_gettime(CLOCK_MONOTONIC, &tp); diff --git a/deps/nghttp2/lib/sfparse.c b/deps/nghttp2/lib/sfparse.c index efa2850c9d661d..b5e94cc281533b 100644 --- a/deps/nghttp2/lib/sfparse.c +++ b/deps/nghttp2/lib/sfparse.c @@ -1075,21 +1075,20 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) { void sf_base64decode(sf_vec *dest, const sf_vec *src) { static const int index_tbl[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1}; + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, + -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1}; uint8_t *o; const uint8_t *p, *end; uint32_t n; From 016baaebbef1787b15ef57dda5359c4b97e0db76 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Tue, 29 Oct 2024 08:10:17 -0400 Subject: [PATCH 22/93] src: do not run IsWindowsBatchFile on non-windows PR-URL: https://github.com/nodejs/node/pull/55560 Reviewed-By: Richard Lau Reviewed-By: Stefan Stojanovic --- src/process_wrap.cc | 2 ++ src/spawn_sync.cc | 2 ++ src/util-inl.h | 30 +++++++++++++----------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 556dea18eca76f..14c9e99934e27b 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -200,8 +200,10 @@ class ProcessWrap : public HandleWrap { // batch files directly but is potentially insecure because arguments // are not escaped (and sometimes cannot be unambiguously escaped), // hence why they are rejected here. +#ifdef _WIN32 if (IsWindowsBatchFile(options.file)) err = UV_EINVAL; +#endif // options.args Local argv_v = diff --git a/src/spawn_sync.cc b/src/spawn_sync.cc index 5f20e9cc0881f9..6d8d5da686d446 100644 --- a/src/spawn_sync.cc +++ b/src/spawn_sync.cc @@ -769,8 +769,10 @@ Maybe SyncProcessRunner::ParseOptions(Local js_value) { // batch files directly but is potentially insecure because arguments // are not escaped (and sometimes cannot be unambiguously escaped), // hence why they are rejected here. +#ifdef _WIN32 if (IsWindowsBatchFile(uv_process_options_.file)) return Just(UV_EINVAL); +#endif Local js_args = js_options->Get(context, env()->args_string()).ToLocalChecked(); diff --git a/src/util-inl.h b/src/util-inl.h index 47d6a73c7927cf..e078c9a11b2fac 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -540,25 +540,21 @@ constexpr std::string_view FastStringKey::as_string_view() const { // Inline so the compiler can fully optimize it away on Unix platforms. bool IsWindowsBatchFile(const char* filename) { #ifdef _WIN32 - static constexpr bool kIsWindows = true; -#else - static constexpr bool kIsWindows = false; -#endif // _WIN32 - if (kIsWindows) { - std::string file_with_extension = filename; - // Regex to match the last extension part after the last dot, ignoring - // trailing spaces and dots - std::regex extension_regex(R"(\.([a-zA-Z0-9]+)\s*[\.\s]*$)"); - std::smatch match; - std::string extension; - - if (std::regex_search(file_with_extension, match, extension_regex)) { - extension = ToLower(match[1].str()); - } - - return !extension.empty() && (extension == "cmd" || extension == "bat"); + std::string file_with_extension = filename; + // Regex to match the last extension part after the last dot, ignoring + // trailing spaces and dots + std::regex extension_regex(R"(\.([a-zA-Z0-9]+)\s*[\.\s]*$)"); + std::smatch match; + std::string extension; + + if (std::regex_search(file_with_extension, match, extension_regex)) { + extension = ToLower(match[1].str()); } + + return !extension.empty() && (extension == "cmd" || extension == "bat"); +#else return false; +#endif // _WIN32 } } // namespace node From b3971bbf133cf4af79de97e3e2a1b84f78021ec1 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 18 Oct 2024 16:48:19 +0200 Subject: [PATCH 23/93] module: trim off internal stack frames for require(esm) warnings Trim off irrelevant internal stack frames for require(esm) warnings so it's easier to locate where the call comes from when --trace-warnings is used. PR-URL: https://github.com/nodejs/node/pull/55496 Reviewed-By: Marco Ippolito Reviewed-By: Paolo Insogna --- lib/internal/modules/cjs/loader.js | 5 ++- lib/internal/util.js | 10 ++++-- test/es-module/test-require-module-warning.js | 35 +++++++++++++++++++ test/fixtures/es-modules/require-module.js | 1 + 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 test/es-module/test-require-module-warning.js create mode 100644 test/fixtures/es-modules/require-module.js diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 20d06d7ebed21a..817da44cfc3c32 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1389,7 +1389,10 @@ function loadESMFromCJS(mod, filename) { messagePrefix = `${from} is loading ES Module ${to} using require().\n`; } } - emitExperimentalWarning('Support for loading ES Module in require()', messagePrefix); + emitExperimentalWarning('Support for loading ES Module in require()', + messagePrefix, + undefined, + parent?.require); const { wrap, namespace, diff --git a/lib/internal/util.js b/lib/internal/util.js index 4d8cf99a3453d9..1c32efaf2c7d63 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -266,14 +266,20 @@ function slowCases(enc) { } } -function emitExperimentalWarning(feature, messagePrefix) { +/** + * @param {string} feature Feature name used in the warning message + * @param {string} messagePrefix Prefix of the warning message + * @param {string} code See documentation of process.emitWarning + * @param {string} ctor See documentation of process.emitWarning + */ +function emitExperimentalWarning(feature, messagePrefix, code, ctor) { if (experimentalWarnings.has(feature)) return; experimentalWarnings.add(feature); let msg = `${feature} is an experimental feature and might change at any time`; if (messagePrefix) { msg = messagePrefix + msg; } - process.emitWarning(msg, 'ExperimentalWarning'); + process.emitWarning(msg, 'ExperimentalWarning', code, ctor); } function filterDuplicateStrings(items, low) { diff --git a/test/es-module/test-require-module-warning.js b/test/es-module/test-require-module-warning.js new file mode 100644 index 00000000000000..d5be2fc6da8755 --- /dev/null +++ b/test/es-module/test-require-module-warning.js @@ -0,0 +1,35 @@ +'use strict'; + +// This checks the warning and the stack trace emitted by the require(esm) +// experimental warning. It can get removed when `require(esm)` becomes stable. + +require('../common'); +const { spawnSyncAndAssert } = require('../common/child_process'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); + +spawnSyncAndAssert(process.execPath, [ + '--trace-warnings', + fixtures.path('es-modules', 'require-module.js'), +], { + trim: true, + stderr(output) { + const lines = output.split('\n'); + assert.match( + lines[0], + /ExperimentalWarning: CommonJS module .*require-module\.js is loading ES Module .*message\.mjs/ + ); + assert.strictEqual( + lines[1], + 'Support for loading ES Module in require() is an experimental feature and might change at any time' + ); + assert.match( + lines[2], + /at require \(.*modules\/helpers:\d+:\d+\)/ + ); + assert.match( + lines[3], + /at Object\. \(.*require-module\.js:1:1\)/ + ); + } +}); diff --git a/test/fixtures/es-modules/require-module.js b/test/fixtures/es-modules/require-module.js new file mode 100644 index 00000000000000..5a36590fc6171f --- /dev/null +++ b/test/fixtures/es-modules/require-module.js @@ -0,0 +1 @@ +require('./message.mjs'); From d3be3da6f8fe506c6c325434f146eac876679342 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 29 Oct 2024 22:15:19 +0100 Subject: [PATCH 24/93] module: fix error thrown from require(esm) hitting TLA repeatedly This tracks the asynchronicity in the ModuleWraps when they turn out to contain TLA after instantiation, and throw the right error (ERR_REQUIRE_ASYNC_MODULE) when it's required again. It removes the freezing of ModuleWraps since it's not meaningful to freeze this when the rest of the module loader is mutable, and we can record the asynchronicity in the ModuleWrap right after compilation after we get a V8 upgrade that contains v8::Module::HasTopLevelAwait() instead of searching through the module graph repeatedly which can be slow. PR-URL: https://github.com/nodejs/node/pull/55520 Fixes: https://github.com/nodejs/node/issues/55516 Refs: https://github.com/nodejs/node/issues/52697 Reviewed-By: Paolo Insogna Reviewed-By: Antoine du Hamel Reviewed-By: Chengzhong Wu Reviewed-By: Jacob Smith --- lib/internal/errors.js | 3 +++ lib/internal/modules/esm/loader.js | 4 ++++ lib/internal/modules/esm/module_job.js | 16 ++++++++++++++-- src/module_wrap.cc | 12 +++--------- .../test-require-module-tla-retry-require.js | 16 ++++++++++++++++ 5 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 test/es-module/test-require-module-tla-retry-require.js diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 8a97384201341f..9045046c100308 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1650,6 +1650,9 @@ E('ERR_PERFORMANCE_MEASURE_INVALID_OPTIONS', '%s', TypeError); E('ERR_QUIC_CONNECTION_FAILED', 'QUIC connection failed', Error); E('ERR_QUIC_ENDPOINT_CLOSED', 'QUIC endpoint closed: %s (%d)', Error); E('ERR_QUIC_OPEN_STREAM_FAILED', 'Failed to open QUIC stream', Error); +E('ERR_REQUIRE_ASYNC_MODULE', 'require() cannot be used on an ESM ' + + 'graph with top-level await. Use import() instead. To see where the' + + ' top-level await comes from, use --experimental-print-required-tla.', Error); E('ERR_REQUIRE_CYCLE_MODULE', '%s', Error); E('ERR_REQUIRE_ESM', function(filename, hasEsmSyntax, parentPath = null, packageJsonPath = null) { diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 262006f8b3a542..c5594e07d667c3 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -23,6 +23,7 @@ const { imported_cjs_symbol } = internalBinding('symbols'); const assert = require('internal/assert'); const { + ERR_REQUIRE_ASYNC_MODULE, ERR_REQUIRE_CYCLE_MODULE, ERR_REQUIRE_ESM, ERR_NETWORK_IMPORT_DISALLOWED, @@ -302,6 +303,9 @@ class ModuleLoader { // evaluated at this point. if (job !== undefined) { mod[kRequiredModuleSymbol] = job.module; + if (job.module.async) { + throw new ERR_REQUIRE_ASYNC_MODULE(); + } if (job.module.getStatus() !== kEvaluated) { const parentFilename = urlToFilename(parent?.filename); let message = `Cannot require() ES Module ${filename} in a cycle.`; diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index ece30c3864d6a7..8fba05e7b8f699 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -37,8 +37,11 @@ const resolvedPromise = PromiseResolve(); const { setHasStartedUserESMExecution, } = require('internal/modules/helpers'); +const { getOptionValue } = require('internal/options'); const noop = FunctionPrototype; - +const { + ERR_REQUIRE_ASYNC_MODULE, +} = require('internal/errors').codes; let hasPausedEntry = false; const CJSGlobalLike = [ @@ -378,7 +381,16 @@ class ModuleJobSync extends ModuleJobBase { runSync() { // TODO(joyeecheung): add the error decoration logic from the async instantiate. - this.module.instantiateSync(); + this.module.async = this.module.instantiateSync(); + // If --experimental-print-required-tla is true, proceeds to evaluation even + // if it's async because we want to search for the TLA and help users locate + // them. + // TODO(joyeecheung): track the asynchroniticy using v8::Module::HasTopLevelAwait() + // and we'll be able to throw right after compilation of the modules, using acron + // to find and print the TLA. + if (this.module.async && !getOptionValue('--experimental-print-required-tla')) { + throw new ERR_REQUIRE_ASYNC_MODULE(); + } setHasStartedUserESMExecution(); const namespace = this.module.evaluateSync(); return { __proto__: null, module: this.module, namespace }; diff --git a/src/module_wrap.cc b/src/module_wrap.cc index e2252639cf4518..6f8c9d10955b88 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -31,7 +31,6 @@ using v8::FunctionTemplate; using v8::HandleScope; using v8::Int32; using v8::Integer; -using v8::IntegrityLevel; using v8::Isolate; using v8::Local; using v8::MaybeLocal; @@ -332,7 +331,6 @@ void ModuleWrap::New(const FunctionCallbackInfo& args) { obj->contextify_context_ = contextify_context; - that->SetIntegrityLevel(context, IntegrityLevel::kFrozen); args.GetReturnValue().Set(that); } @@ -635,13 +633,9 @@ void ModuleWrap::InstantiateSync(const FunctionCallbackInfo& args) { } } - // If --experimental-print-required-tla is true, proceeds to evaluation even - // if it's async because we want to search for the TLA and help users locate - // them. - if (module->IsGraphAsync() && !env->options()->print_required_tla) { - THROW_ERR_REQUIRE_ASYNC_MODULE(env); - return; - } + // TODO(joyeecheung): record Module::HasTopLevelAwait() in every ModuleWrap + // and infer the asynchronicity from a module's children during linking. + args.GetReturnValue().Set(module->IsGraphAsync()); } void ModuleWrap::EvaluateSync(const FunctionCallbackInfo& args) { diff --git a/test/es-module/test-require-module-tla-retry-require.js b/test/es-module/test-require-module-tla-retry-require.js new file mode 100644 index 00000000000000..d440698fc22b52 --- /dev/null +++ b/test/es-module/test-require-module-tla-retry-require.js @@ -0,0 +1,16 @@ +// This tests that after failing to require an ESM that contains TLA, +// retrying with require() still throws, and produces consistent results. +'use strict'; +require('../common'); +const assert = require('assert'); + +assert.throws(() => { + require('../fixtures/es-modules/tla/resolved.mjs'); +}, { + code: 'ERR_REQUIRE_ASYNC_MODULE' +}); +assert.throws(() => { + require('../fixtures/es-modules/tla/resolved.mjs'); +}, { + code: 'ERR_REQUIRE_ASYNC_MODULE' +}); From 6aa797de4e8b87afa5889255904f3fdae227db3e Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Tue, 29 Oct 2024 22:52:09 +0100 Subject: [PATCH 25/93] test: remove unneeded listeners Unhandled `'error'` events will make the process exit with an unclean exit code anyway. PR-URL: https://github.com/nodejs/node/pull/55486 Reviewed-By: Jake Yuesong Li --- test/parallel/test-child-process-dgram-reuseport.js | 2 +- test/parallel/test-child-process-net-reuseport.js | 2 +- test/parallel/test-cluster-dgram-reuseport.js | 4 ++-- test/parallel/test-cluster-net-reuseport.js | 3 --- test/parallel/test-dgram-reuseport.js | 2 -- test/parallel/test-net-reuseport.js | 2 -- 6 files changed, 4 insertions(+), 11 deletions(-) diff --git a/test/parallel/test-child-process-dgram-reuseport.js b/test/parallel/test-child-process-dgram-reuseport.js index 30f04640f6f570..4eea13c525bcb8 100644 --- a/test/parallel/test-child-process-dgram-reuseport.js +++ b/test/parallel/test-child-process-dgram-reuseport.js @@ -32,4 +32,4 @@ const socket = dgram.createSocket(options); socket.bind(+process.env.port, common.mustCall(() => { socket.close(); -})).on('error', common.mustNotCall()); +})); diff --git a/test/parallel/test-child-process-net-reuseport.js b/test/parallel/test-child-process-net-reuseport.js index 575977fc4168ed..52309edd1b3be1 100644 --- a/test/parallel/test-child-process-net-reuseport.js +++ b/test/parallel/test-child-process-net-reuseport.js @@ -32,4 +32,4 @@ const server = net.createServer(); server.listen({ ...options, port: +process.env.port }, common.mustCall(() => { server.close(); -})).on('error', common.mustNotCall()); +})); diff --git a/test/parallel/test-cluster-dgram-reuseport.js b/test/parallel/test-cluster-dgram-reuseport.js index f859721f5d7c76..da7a90337c8ff7 100644 --- a/test/parallel/test-cluster-dgram-reuseport.js +++ b/test/parallel/test-cluster-dgram-reuseport.js @@ -35,5 +35,5 @@ socket1.bind(0, () => { socket2.bind(socket1.address().port, () => { socket1.close(close); socket2.close(close); - }).on('error', common.mustNotCall()); -}).on('error', common.mustNotCall()); + }); +}); diff --git a/test/parallel/test-cluster-net-reuseport.js b/test/parallel/test-cluster-net-reuseport.js index 985bb2193f2c05..b875490d61fab9 100644 --- a/test/parallel/test-cluster-net-reuseport.js +++ b/test/parallel/test-cluster-net-reuseport.js @@ -36,6 +36,3 @@ server1.listen(options, common.mustCall(() => { server2.close(close); })); })); - -server1.on('error', common.mustNotCall()); -server2.on('error', common.mustNotCall()); diff --git a/test/parallel/test-dgram-reuseport.js b/test/parallel/test-dgram-reuseport.js index c9b6f7964ab666..e5fd6965818d4c 100644 --- a/test/parallel/test-dgram-reuseport.js +++ b/test/parallel/test-dgram-reuseport.js @@ -12,8 +12,6 @@ function test() { socket2.close(); })); })); - socket1.on('error', common.mustNotCall()); - socket2.on('error', common.mustNotCall()); } checkSupportReusePort().then(test, () => { diff --git a/test/parallel/test-net-reuseport.js b/test/parallel/test-net-reuseport.js index f04db09d04a99a..3b7fc100be7ddd 100644 --- a/test/parallel/test-net-reuseport.js +++ b/test/parallel/test-net-reuseport.js @@ -13,8 +13,6 @@ function test(host) { server2.close(); })); })); - server1.on('error', common.mustNotCall()); - server2.on('error', common.mustNotCall()); } checkSupportReusePort() From 4887214e23599f2333461754cdd8a4930798db44 Mon Sep 17 00:00:00 2001 From: Michael Cho Date: Tue, 29 Oct 2024 19:24:38 -0400 Subject: [PATCH 26/93] build: fix building with system icu 76 ICU 76 decided to reduce overlinking[^1] thus `icu-i18n` will no longer add `icu-uc` when linking to shared libraries. This results in undefined symbols/references when trying to build with system ICU 76. [^1]: unicode-org/icu@199bc82 PR-URL: https://github.com/nodejs/node/pull/55563 Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index a5f47af1748903..a4e210261e2e76 100755 --- a/configure.py +++ b/configure.py @@ -1879,7 +1879,7 @@ def icu_download(path): elif with_intl == 'system-icu': # ICU from pkg-config. o['variables']['v8_enable_i18n_support'] = 1 - pkgicu = pkg_config('icu-i18n') + pkgicu = pkg_config(['icu-i18n', 'icu-uc']) if not pkgicu[0]: error('''Could not load pkg-config data for "icu-i18n". See above errors or the README.md.''') From 815e2524a63ac3cf87553526fc08bc700855da3e Mon Sep 17 00:00:00 2001 From: Julian Gassner Date: Wed, 30 Oct 2024 03:10:30 +0100 Subject: [PATCH 27/93] test: split up test-runner-mock-timers test PR-URL: https://github.com/nodejs/node/pull/55506 Reviewed-By: Erick Wendel Reviewed-By: Chemi Atlow Reviewed-By: Claudio Wunder --- test/parallel/test-runner-mock-timers-date.js | 120 +++++++++ .../test-runner-mock-timers-scheduler.js | 124 +++++++++ test/parallel/test-runner-mock-timers.js | 240 +----------------- 3 files changed, 248 insertions(+), 236 deletions(-) create mode 100644 test/parallel/test-runner-mock-timers-date.js create mode 100644 test/parallel/test-runner-mock-timers-scheduler.js diff --git a/test/parallel/test-runner-mock-timers-date.js b/test/parallel/test-runner-mock-timers-date.js new file mode 100644 index 00000000000000..ebd1e430be803f --- /dev/null +++ b/test/parallel/test-runner-mock-timers-date.js @@ -0,0 +1,120 @@ +'use strict'; +process.env.NODE_TEST_KNOWN_GLOBALS = 0; +require('../common'); + +const assert = require('node:assert'); +const { it, describe } = require('node:test'); + +describe('Mock Timers Date Test Suite', () => { + it('should return the initial UNIX epoch if not specified', (t) => { + t.mock.timers.enable({ apis: ['Date'] }); + const date = new Date(); + assert.strictEqual(date.getTime(), 0); + assert.strictEqual(Date.now(), 0); + }); + + it('should throw an error if setTime is called without enabling timers', (t) => { + assert.throws( + () => { + t.mock.timers.setTime(100); + }, + { code: 'ERR_INVALID_STATE' } + ); + }); + + it('should throw an error if epoch passed to enable is not valid', (t) => { + assert.throws( + () => { + t.mock.timers.enable({ now: -1 }); + }, + { code: 'ERR_INVALID_ARG_VALUE' } + ); + + assert.throws( + () => { + t.mock.timers.enable({ now: 'string' }); + }, + { code: 'ERR_INVALID_ARG_TYPE' } + ); + + assert.throws( + () => { + t.mock.timers.enable({ now: NaN }); + }, + { code: 'ERR_INVALID_ARG_VALUE' } + ); + }); + + it('should replace the original Date with the mocked one', (t) => { + t.mock.timers.enable({ apis: ['Date'] }); + assert.ok(Date.isMock); + }); + + it('should return the ticked time when calling Date.now after tick', (t) => { + t.mock.timers.enable({ apis: ['Date'] }); + const time = 100; + t.mock.timers.tick(time); + assert.strictEqual(Date.now(), time); + }); + + it('should return the Date as string when calling it as a function', (t) => { + t.mock.timers.enable({ apis: ['Date'] }); + const returned = Date(); + // Matches the format: 'Mon Jan 01 1970 00:00:00' + // We don't care about the date, just the format + assert.ok(/\w{3}\s\w{3}\s\d{1,2}\s\d{2,4}\s\d{1,2}:\d{2}:\d{2}/.test(returned)); + }); + + it('should return the date with different argument calls', (t) => { + t.mock.timers.enable({ apis: ['Date'] }); + assert.strictEqual(new Date(0).getTime(), 0); + assert.strictEqual(new Date(100).getTime(), 100); + assert.strictEqual(new Date('1970-01-01T00:00:00.000Z').getTime(), 0); + assert.strictEqual(new Date(1970, 0).getFullYear(), 1970); + assert.strictEqual(new Date(1970, 0).getMonth(), 0); + assert.strictEqual(new Date(1970, 0, 1).getDate(), 1); + assert.strictEqual(new Date(1970, 0, 1, 11).getHours(), 11); + assert.strictEqual(new Date(1970, 0, 1, 11, 10).getMinutes(), 10); + assert.strictEqual(new Date(1970, 0, 1, 11, 10, 45).getSeconds(), 45); + assert.strictEqual(new Date(1970, 0, 1, 11, 10, 45, 898).getMilliseconds(), 898); + assert.strictEqual(new Date(1970, 0, 1, 11, 10, 45, 898).toDateString(), 'Thu Jan 01 1970'); + }); + + it('should return native code when calling Date.toString', (t) => { + t.mock.timers.enable({ apis: ['Date'] }); + assert.strictEqual(Date.toString(), 'function Date() { [native code] }'); + }); + + it('should start with a custom epoch if the second argument is specified', (t) => { + t.mock.timers.enable({ apis: ['Date'], now: 100 }); + const date1 = new Date(); + assert.strictEqual(date1.getTime(), 100); + + t.mock.timers.reset(); + t.mock.timers.enable({ apis: ['Date'], now: new Date(200) }); + const date2 = new Date(); + assert.strictEqual(date2.getTime(), 200); + }); + + it('should replace epoch if setTime is lesser than now and not tick', (t) => { + t.mock.timers.enable(); + const fn = t.mock.fn(); + const id = setTimeout(fn, 1000); + t.mock.timers.setTime(800); + assert.strictEqual(Date.now(), 800); + t.mock.timers.setTime(500); + assert.strictEqual(Date.now(), 500); + assert.strictEqual(fn.mock.callCount(), 0); + clearTimeout(id); + }); + + it('should not tick time when setTime is called', (t) => { + t.mock.timers.enable(); + const fn = t.mock.fn(); + const id = setTimeout(fn, 1000); + t.mock.timers.setTime(1200); + assert.strictEqual(Date.now(), 1200); + assert.strictEqual(fn.mock.callCount(), 0); + clearTimeout(id); + }); +}); diff --git a/test/parallel/test-runner-mock-timers-scheduler.js b/test/parallel/test-runner-mock-timers-scheduler.js new file mode 100644 index 00000000000000..6a83056e70eda2 --- /dev/null +++ b/test/parallel/test-runner-mock-timers-scheduler.js @@ -0,0 +1,124 @@ +'use strict'; +process.env.NODE_TEST_KNOWN_GLOBALS = 0; +const common = require('../common'); + +const assert = require('node:assert'); +const { it, describe } = require('node:test'); +const nodeTimersPromises = require('node:timers/promises'); + +describe('Mock Timers Scheduler Test Suite', () => { + it('should advance in time and trigger timers when calling the .tick function', (t) => { + t.mock.timers.enable({ apis: ['scheduler.wait'] }); + + const now = Date.now(); + const durationAtMost = 100; + + const p = nodeTimersPromises.scheduler.wait(4000); + t.mock.timers.tick(4000); + + return p.then(common.mustCall((result) => { + assert.strictEqual(result, undefined); + assert.ok( + Date.now() - now < durationAtMost, + `time should be advanced less than the ${durationAtMost}ms` + ); + })); + }); + + it('should advance in time and trigger timers when calling the .tick function multiple times', async (t) => { + t.mock.timers.enable({ apis: ['scheduler.wait'] }); + + const fn = t.mock.fn(); + + nodeTimersPromises.scheduler.wait(9999).then(fn); + + t.mock.timers.tick(8999); + assert.strictEqual(fn.mock.callCount(), 0); + t.mock.timers.tick(500); + + await nodeTimersPromises.setImmediate(); + + assert.strictEqual(fn.mock.callCount(), 0); + t.mock.timers.tick(500); + + await nodeTimersPromises.setImmediate(); + assert.strictEqual(fn.mock.callCount(), 1); + }); + + it('should work with the same params as the original timers/promises/scheduler.wait', async (t) => { + t.mock.timers.enable({ apis: ['scheduler.wait'] }); + const controller = new AbortController(); + const p = nodeTimersPromises.scheduler.wait(2000, { + ref: true, + signal: controller.signal, + }); + + t.mock.timers.tick(1000); + t.mock.timers.tick(500); + t.mock.timers.tick(500); + t.mock.timers.tick(500); + + const result = await p; + assert.strictEqual(result, undefined); + }); + + it('should abort operation if timers/promises/scheduler.wait received an aborted signal', async (t) => { + t.mock.timers.enable({ apis: ['scheduler.wait'] }); + const controller = new AbortController(); + const p = nodeTimersPromises.scheduler.wait(2000, { + ref: true, + signal: controller.signal, + }); + + t.mock.timers.tick(1000); + controller.abort(); + t.mock.timers.tick(500); + t.mock.timers.tick(500); + t.mock.timers.tick(500); + + await assert.rejects(() => p, { + name: 'AbortError', + }); + }); + it('should abort operation even if the .tick was not called', async (t) => { + t.mock.timers.enable({ apis: ['scheduler.wait'] }); + const controller = new AbortController(); + const p = nodeTimersPromises.scheduler.wait(2000, { + ref: true, + signal: controller.signal, + }); + + controller.abort(); + + await assert.rejects(() => p, { + name: 'AbortError', + }); + }); + + it('should abort operation when .abort is called before calling setInterval', async (t) => { + t.mock.timers.enable({ apis: ['scheduler.wait'] }); + const controller = new AbortController(); + controller.abort(); + const p = nodeTimersPromises.scheduler.wait(2000, { + ref: true, + signal: controller.signal, + }); + + await assert.rejects(() => p, { + name: 'AbortError', + }); + }); + + it('should reject given an an invalid signal instance', async (t) => { + t.mock.timers.enable({ apis: ['scheduler.wait'] }); + const p = nodeTimersPromises.scheduler.wait(2000, { + ref: true, + signal: {}, + }); + + await assert.rejects(() => p, { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + }); + }); +}); diff --git a/test/parallel/test-runner-mock-timers.js b/test/parallel/test-runner-mock-timers.js index e438b2636b832a..87b8ba7e3784d2 100644 --- a/test/parallel/test-runner-mock-timers.js +++ b/test/parallel/test-runner-mock-timers.js @@ -1,3 +1,4 @@ +// Flags: --expose-internals 'use strict'; process.env.NODE_TEST_KNOWN_GLOBALS = 0; const common = require('../common'); @@ -6,6 +7,7 @@ const assert = require('node:assert'); const { it, mock, describe } = require('node:test'); const nodeTimers = require('node:timers'); const nodeTimersPromises = require('node:timers/promises'); +const { TIMEOUT_MAX } = require('internal/timers'); describe('Mock Timers Test Suite', () => { describe('MockTimers API', () => { @@ -252,10 +254,10 @@ describe('Mock Timers Test Suite', () => { }), timeout); }); - it('should change timeout to 1ms when it is >= 2 ** 31', (t) => { + it('should change timeout to 1ms when it is > TIMEOUT_MAX', (t) => { t.mock.timers.enable({ apis: ['setTimeout'] }); const fn = t.mock.fn(); - global.setTimeout(fn, 2 ** 31); + global.setTimeout(fn, TIMEOUT_MAX + 1); t.mock.timers.tick(1); assert.strictEqual(fn.mock.callCount(), 1); }); @@ -791,240 +793,6 @@ describe('Mock Timers Test Suite', () => { }); }); - describe('scheduler Suite', () => { - describe('scheduler.wait', () => { - it('should advance in time and trigger timers when calling the .tick function', (t) => { - t.mock.timers.enable({ apis: ['scheduler.wait'] }); - - const now = Date.now(); - const durationAtMost = 100; - - const p = nodeTimersPromises.scheduler.wait(4000); - t.mock.timers.tick(4000); - - return p.then(common.mustCall((result) => { - assert.strictEqual(result, undefined); - assert.ok( - Date.now() - now < durationAtMost, - `time should be advanced less than the ${durationAtMost}ms` - ); - })); - }); - - it('should advance in time and trigger timers when calling the .tick function multiple times', async (t) => { - t.mock.timers.enable({ apis: ['scheduler.wait'] }); - - const fn = t.mock.fn(); - - nodeTimersPromises.scheduler.wait(9999).then(fn); - - t.mock.timers.tick(8999); - assert.strictEqual(fn.mock.callCount(), 0); - t.mock.timers.tick(500); - - await nodeTimersPromises.setImmediate(); - - assert.strictEqual(fn.mock.callCount(), 0); - t.mock.timers.tick(500); - - await nodeTimersPromises.setImmediate(); - assert.strictEqual(fn.mock.callCount(), 1); - }); - - it('should work with the same params as the original timers/promises/scheduler.wait', async (t) => { - t.mock.timers.enable({ apis: ['scheduler.wait'] }); - const controller = new AbortController(); - const p = nodeTimersPromises.scheduler.wait(2000, { - ref: true, - signal: controller.signal, - }); - - t.mock.timers.tick(1000); - t.mock.timers.tick(500); - t.mock.timers.tick(500); - t.mock.timers.tick(500); - - const result = await p; - assert.strictEqual(result, undefined); - }); - - it('should abort operation if timers/promises/scheduler.wait received an aborted signal', async (t) => { - t.mock.timers.enable({ apis: ['scheduler.wait'] }); - const controller = new AbortController(); - const p = nodeTimersPromises.scheduler.wait(2000, { - ref: true, - signal: controller.signal, - }); - - t.mock.timers.tick(1000); - controller.abort(); - t.mock.timers.tick(500); - t.mock.timers.tick(500); - t.mock.timers.tick(500); - - await assert.rejects(() => p, { - name: 'AbortError', - }); - }); - it('should abort operation even if the .tick was not called', async (t) => { - t.mock.timers.enable({ apis: ['scheduler.wait'] }); - const controller = new AbortController(); - const p = nodeTimersPromises.scheduler.wait(2000, { - ref: true, - signal: controller.signal, - }); - - controller.abort(); - - await assert.rejects(() => p, { - name: 'AbortError', - }); - }); - - it('should abort operation when .abort is called before calling setInterval', async (t) => { - t.mock.timers.enable({ apis: ['scheduler.wait'] }); - const controller = new AbortController(); - controller.abort(); - const p = nodeTimersPromises.scheduler.wait(2000, { - ref: true, - signal: controller.signal, - }); - - await assert.rejects(() => p, { - name: 'AbortError', - }); - }); - - it('should reject given an an invalid signal instance', async (t) => { - t.mock.timers.enable({ apis: ['scheduler.wait'] }); - const p = nodeTimersPromises.scheduler.wait(2000, { - ref: true, - signal: {}, - }); - - await assert.rejects(() => p, { - name: 'TypeError', - code: 'ERR_INVALID_ARG_TYPE', - }); - }); - - }); - }); - - describe('Date Suite', () => { - it('should return the initial UNIX epoch if not specified', (t) => { - t.mock.timers.enable({ apis: ['Date'] }); - const date = new Date(); - assert.strictEqual(date.getTime(), 0); - assert.strictEqual(Date.now(), 0); - }); - - it('should throw an error if setTime is called without enabling timers', (t) => { - assert.throws( - () => { - t.mock.timers.setTime(100); - }, - { code: 'ERR_INVALID_STATE' } - ); - }); - - it('should throw an error if epoch passed to enable is not valid', (t) => { - assert.throws( - () => { - t.mock.timers.enable({ now: -1 }); - }, - { code: 'ERR_INVALID_ARG_VALUE' } - ); - - assert.throws( - () => { - t.mock.timers.enable({ now: 'string' }); - }, - { code: 'ERR_INVALID_ARG_TYPE' } - ); - - assert.throws( - () => { - t.mock.timers.enable({ now: NaN }); - }, - { code: 'ERR_INVALID_ARG_VALUE' } - ); - }); - - it('should replace the original Date with the mocked one', (t) => { - t.mock.timers.enable({ apis: ['Date'] }); - assert.ok(Date.isMock); - }); - - it('should return the ticked time when calling Date.now after tick', (t) => { - t.mock.timers.enable({ apis: ['Date'] }); - const time = 100; - t.mock.timers.tick(time); - assert.strictEqual(Date.now(), time); - }); - - it('should return the Date as string when calling it as a function', (t) => { - t.mock.timers.enable({ apis: ['Date'] }); - const returned = Date(); - // Matches the format: 'Mon Jan 01 1970 00:00:00' - // We don't care about the date, just the format - assert.ok(/\w{3}\s\w{3}\s\d{1,2}\s\d{2,4}\s\d{1,2}:\d{2}:\d{2}/.test(returned)); - }); - - it('should return the date with different argument calls', (t) => { - t.mock.timers.enable({ apis: ['Date'] }); - assert.strictEqual(new Date(0).getTime(), 0); - assert.strictEqual(new Date(100).getTime(), 100); - assert.strictEqual(new Date('1970-01-01T00:00:00.000Z').getTime(), 0); - assert.strictEqual(new Date(1970, 0).getFullYear(), 1970); - assert.strictEqual(new Date(1970, 0).getMonth(), 0); - assert.strictEqual(new Date(1970, 0, 1).getDate(), 1); - assert.strictEqual(new Date(1970, 0, 1, 11).getHours(), 11); - assert.strictEqual(new Date(1970, 0, 1, 11, 10).getMinutes(), 10); - assert.strictEqual(new Date(1970, 0, 1, 11, 10, 45).getSeconds(), 45); - assert.strictEqual(new Date(1970, 0, 1, 11, 10, 45, 898).getMilliseconds(), 898); - assert.strictEqual(new Date(1970, 0, 1, 11, 10, 45, 898).toDateString(), 'Thu Jan 01 1970'); - }); - - it('should return native code when calling Date.toString', (t) => { - t.mock.timers.enable({ apis: ['Date'] }); - assert.strictEqual(Date.toString(), 'function Date() { [native code] }'); - }); - - it('should start with a custom epoch if the second argument is specified', (t) => { - t.mock.timers.enable({ apis: ['Date'], now: 100 }); - const date1 = new Date(); - assert.strictEqual(date1.getTime(), 100); - - t.mock.timers.reset(); - t.mock.timers.enable({ apis: ['Date'], now: new Date(200) }); - const date2 = new Date(); - assert.strictEqual(date2.getTime(), 200); - }); - - it('should replace epoch if setTime is lesser than now and not tick', (t) => { - t.mock.timers.enable(); - const fn = t.mock.fn(); - const id = setTimeout(fn, 1000); - t.mock.timers.setTime(800); - assert.strictEqual(Date.now(), 800); - t.mock.timers.setTime(500); - assert.strictEqual(Date.now(), 500); - assert.strictEqual(fn.mock.callCount(), 0); - clearTimeout(id); - }); - - it('should not tick time when setTime is called', (t) => { - t.mock.timers.enable(); - const fn = t.mock.fn(); - const id = setTimeout(fn, 1000); - t.mock.timers.setTime(1200); - assert.strictEqual(Date.now(), 1200); - assert.strictEqual(fn.mock.callCount(), 0); - clearTimeout(id); - }); - }); - describe('Api should have same public properties as original', () => { it('should have hasRef', (t) => { t.mock.timers.enable(); From f355054ec768e8746bb9872ffe3e702ab8fda8d0 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Wed, 30 Oct 2024 09:33:04 -0400 Subject: [PATCH 28/93] doc: capitalize "MIT License" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55575 Reviewed-By: Ulises Gascón Reviewed-By: Luigi Pinca Reviewed-By: Marco Ippolito --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f51b1487f86589..8f01a50eb370d7 100644 --- a/README.md +++ b/README.md @@ -877,7 +877,7 @@ releases on a rotation basis as outlined in the ## License Node.js is available under the -[MIT license](https://opensource.org/licenses/MIT). Node.js also includes +[MIT License](https://opensource.org/licenses/MIT). Node.js also includes external libraries that are available under a variety of licenses. See [LICENSE](https://github.com/nodejs/node/blob/HEAD/LICENSE) for the full license text. From 09060045b1ac892ebf7abd5ddf98ba13655e02da Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Wed, 30 Oct 2024 10:10:28 -0400 Subject: [PATCH 29/93] dns: stop using deprecated `ares_query` PR-URL: https://github.com/nodejs/node/pull/55430 Refs: https://github.com/nodejs/node/issues/52464 Reviewed-By: Luigi Pinca Reviewed-By: Matteo Collina --- src/cares_wrap.cc | 24 ++++++++++++------------ src/cares_wrap.h | 35 +++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index ac79eeaaf7b150..84d2ab2b065e5d 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -830,62 +830,62 @@ void ChannelWrap::EnsureServers() { } int AnyTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_any); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_ANY); return ARES_SUCCESS; } int ATraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_a); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_A); return ARES_SUCCESS; } int AaaaTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_aaaa); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_AAAA); return ARES_SUCCESS; } int CaaTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, T_CAA); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_CAA); return ARES_SUCCESS; } int CnameTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_cname); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_CNAME); return ARES_SUCCESS; } int MxTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_mx); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_MX); return ARES_SUCCESS; } int NsTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_ns); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_NS); return ARES_SUCCESS; } int TxtTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_txt); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_TXT); return ARES_SUCCESS; } int SrvTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_srv); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_SRV); return ARES_SUCCESS; } int PtrTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_ptr); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_PTR); return ARES_SUCCESS; } int NaptrTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_naptr); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_NAPTR); return ARES_SUCCESS; } int SoaTraits::Send(QueryWrap* wrap, const char* name) { - wrap->AresQuery(name, ns_c_in, ns_t_soa); + wrap->AresQuery(name, ARES_CLASS_IN, ARES_REC_TYPE_SOA); return ARES_SUCCESS; } diff --git a/src/cares_wrap.h b/src/cares_wrap.h index 021ef1c9de518e..4a5d22c0ef085f 100644 --- a/src/cares_wrap.h +++ b/src/cares_wrap.h @@ -246,18 +246,20 @@ class QueryWrap final : public AsyncWrap { return Traits::Send(this, name); } - void AresQuery(const char* name, int dnsclass, int type) { + void AresQuery(const char* name, + ares_dns_class_t dnsclass, + ares_dns_rec_type_t type) { channel_->EnsureServers(); TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( TRACING_CATEGORY_NODE2(dns, native), trace_name_, this, "name", TRACE_STR_COPY(name)); - ares_query( - channel_->cares_channel(), - name, - dnsclass, - type, - Callback, - MakeCallbackPointer()); + ares_query_dnsrec(channel_->cares_channel(), + name, + dnsclass, + type, + Callback, + MakeCallbackPointer(), + nullptr); } void ParseError(int status) { @@ -304,19 +306,20 @@ class QueryWrap final : public AsyncWrap { return wrap; } - static void Callback( - void* arg, - int status, - int timeouts, - unsigned char* answer_buf, - int answer_len) { + static void Callback(void* arg, + ares_status_t status, + size_t timeouts, + const ares_dns_record_t* dnsrec) { QueryWrap* wrap = FromCallbackPointer(arg); if (wrap == nullptr) return; unsigned char* buf_copy = nullptr; + size_t answer_len = 0; if (status == ARES_SUCCESS) { - buf_copy = node::Malloc(answer_len); - memcpy(buf_copy, answer_buf, answer_len); + // No need to explicitly call ares_free_string here, + // as it is a wrapper around free, which is already + // invoked when MallocedBuffer is destructed. + ares_dns_write(dnsrec, &buf_copy, &answer_len); } wrap->response_data_ = std::make_unique(); From 467618418a187c075633c05198f3e431a61b9143 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 30 Oct 2024 23:48:58 -0500 Subject: [PATCH 30/93] src: use NewFromUtf8Literal in NODE_DEFINE_CONSTANT Small efficiency improvement over NewFromUtf8(): the literal's length is known at compile time, so V8 doesn't have to call strlen() or ToLocalChecked(). PR-URL: https://github.com/nodejs/node/pull/55581 Reviewed-By: Yagiz Nizipli Reviewed-By: Richard Lau --- src/node.h | 70 +++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/src/node.h b/src/node.h index b447d4bf5a4eb4..32d346fc4f89f3 100644 --- a/src/node.h +++ b/src/node.h @@ -1023,44 +1023,38 @@ NODE_DEPRECATED("Use v8::Date::ValueOf() directly", }) #define NODE_V8_UNIXTIME node::NODE_V8_UNIXTIME -#define NODE_DEFINE_CONSTANT(target, constant) \ - do { \ - v8::Isolate* isolate = target->GetIsolate(); \ - v8::Local context = isolate->GetCurrentContext(); \ - v8::Local constant_name = \ - v8::String::NewFromUtf8(isolate, #constant, \ - v8::NewStringType::kInternalized).ToLocalChecked(); \ - v8::Local constant_value = \ - v8::Number::New(isolate, static_cast(constant)); \ - v8::PropertyAttribute constant_attributes = \ - static_cast(v8::ReadOnly | v8::DontDelete); \ - (target)->DefineOwnProperty(context, \ - constant_name, \ - constant_value, \ - constant_attributes).Check(); \ - } \ - while (0) - -#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \ - do { \ - v8::Isolate* isolate = target->GetIsolate(); \ - v8::Local context = isolate->GetCurrentContext(); \ - v8::Local constant_name = \ - v8::String::NewFromUtf8(isolate, #constant, \ - v8::NewStringType::kInternalized) \ - .ToLocalChecked(); \ - v8::Local constant_value = \ - v8::Number::New(isolate, static_cast(constant)); \ - v8::PropertyAttribute constant_attributes = \ - static_cast(v8::ReadOnly | \ - v8::DontDelete | \ - v8::DontEnum); \ - (target)->DefineOwnProperty(context, \ - constant_name, \ - constant_value, \ - constant_attributes).Check(); \ - } \ - while (0) +#define NODE_DEFINE_CONSTANT(target, constant) \ + do { \ + v8::Isolate* isolate = target->GetIsolate(); \ + v8::Local context = isolate->GetCurrentContext(); \ + v8::Local constant_name = v8::String::NewFromUtf8Literal( \ + isolate, #constant, v8::NewStringType::kInternalized); \ + v8::Local constant_value = \ + v8::Number::New(isolate, static_cast(constant)); \ + v8::PropertyAttribute constant_attributes = \ + static_cast(v8::ReadOnly | v8::DontDelete); \ + (target) \ + ->DefineOwnProperty( \ + context, constant_name, constant_value, constant_attributes) \ + .Check(); \ + } while (0) + +#define NODE_DEFINE_HIDDEN_CONSTANT(target, constant) \ + do { \ + v8::Isolate* isolate = target->GetIsolate(); \ + v8::Local context = isolate->GetCurrentContext(); \ + v8::Local constant_name = v8::String::NewFromUtf8Literal( \ + isolate, #constant, v8::NewStringType::kInternalized); \ + v8::Local constant_value = \ + v8::Number::New(isolate, static_cast(constant)); \ + v8::PropertyAttribute constant_attributes = \ + static_cast(v8::ReadOnly | v8::DontDelete | \ + v8::DontEnum); \ + (target) \ + ->DefineOwnProperty( \ + context, constant_name, constant_value, constant_attributes) \ + .Check(); \ + } while (0) // Used to be a macro, hence the uppercase name. inline void NODE_SET_METHOD(v8::Local recv, From 2ec4ae7c16f30c6050bcdb4effee033f480d56ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Thu, 31 Oct 2024 12:41:14 +0100 Subject: [PATCH 31/93] sqlite: add readOnly option Allow opening existing SQLite databases with SQLITE_OPEN_READONLY set. PR-URL: https://github.com/nodejs/node/pull/55567 Reviewed-By: Colin Ihrig Reviewed-By: Rafael Gonzaga --- doc/api/sqlite.md | 2 ++ src/node_sqlite.cc | 20 ++++++++++++- src/node_sqlite.h | 5 ++++ test/parallel/test-sqlite-database-sync.js | 33 ++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/doc/api/sqlite.md b/doc/api/sqlite.md index cfb3f48d70a42c..34dfdaf1b11365 100644 --- a/doc/api/sqlite.md +++ b/doc/api/sqlite.md @@ -107,6 +107,8 @@ added: v22.5.0 * `open` {boolean} If `true`, the database is opened by the constructor. When this value is `false`, the database must be opened via the `open()` method. **Default:** `true`. + * `readOnly` {boolean} If `true`, the database is opened in read-only mode. + If the database does not exist, opening it will fail. **Default:** `false`. * `enableForeignKeyConstraints` {boolean} If `true`, foreign key constraints are enabled. This is recommended but can be disabled for compatibility with legacy database schemas. The enforcement of foreign key constraints can be diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index af9e77e1362bc3..742c15233ccd13 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -126,7 +126,9 @@ bool DatabaseSync::Open() { } // TODO(cjihrig): Support additional flags. - int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + int flags = open_config_.get_read_only() + ? SQLITE_OPEN_READONLY + : SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; int r = sqlite3_open_v2( open_config_.location().c_str(), &connection_, flags, nullptr); CHECK_ERROR_OR_THROW(env()->isolate(), connection_, r, SQLITE_OK, false); @@ -219,6 +221,22 @@ void DatabaseSync::New(const FunctionCallbackInfo& args) { open = open_v.As()->Value(); } + Local read_only_string = + FIXED_ONE_BYTE_STRING(env->isolate(), "readOnly"); + Local read_only_v; + if (!options->Get(env->context(), read_only_string).ToLocal(&read_only_v)) { + return; + } + if (!read_only_v->IsUndefined()) { + if (!read_only_v->IsBoolean()) { + node::THROW_ERR_INVALID_ARG_TYPE( + env->isolate(), + "The \"options.readOnly\" argument must be a boolean."); + return; + } + open_config.set_read_only(read_only_v.As()->Value()); + } + Local enable_foreign_keys_string = FIXED_ONE_BYTE_STRING(env->isolate(), "enableForeignKeyConstraints"); Local enable_foreign_keys_v; diff --git a/src/node_sqlite.h b/src/node_sqlite.h index 933d0b65a3ba08..6d06eb551a469e 100644 --- a/src/node_sqlite.h +++ b/src/node_sqlite.h @@ -21,6 +21,10 @@ class DatabaseOpenConfiguration { inline const std::string& location() const { return location_; } + inline bool get_read_only() const { return read_only_; } + + inline void set_read_only(bool flag) { read_only_ = flag; } + inline bool get_enable_foreign_keys() const { return enable_foreign_keys_; } inline void set_enable_foreign_keys(bool flag) { @@ -33,6 +37,7 @@ class DatabaseOpenConfiguration { private: std::string location_; + bool read_only_ = false; bool enable_foreign_keys_ = true; bool enable_dqs_ = false; }; diff --git a/test/parallel/test-sqlite-database-sync.js b/test/parallel/test-sqlite-database-sync.js index 7979d01b568aa1..0bf5b2c139ca03 100644 --- a/test/parallel/test-sqlite-database-sync.js +++ b/test/parallel/test-sqlite-database-sync.js @@ -51,6 +51,39 @@ suite('DatabaseSync() constructor', () => { }); }); + test('throws if options.readOnly is provided but is not a boolean', (t) => { + t.assert.throws(() => { + new DatabaseSync('foo', { readOnly: 5 }); + }, { + code: 'ERR_INVALID_ARG_TYPE', + message: /The "options\.readOnly" argument must be a boolean/, + }); + }); + + test('is not read-only by default', (t) => { + const dbPath = nextDb(); + const db = new DatabaseSync(dbPath); + db.exec('CREATE TABLE foo (id INTEGER PRIMARY KEY)'); + }); + + test('is read-only if readOnly is set', (t) => { + const dbPath = nextDb(); + { + const db = new DatabaseSync(dbPath); + db.exec('CREATE TABLE foo (id INTEGER PRIMARY KEY)'); + db.close(); + } + { + const db = new DatabaseSync(dbPath, { readOnly: true }); + t.assert.throws(() => { + db.exec('CREATE TABLE bar (id INTEGER PRIMARY KEY)'); + }, { + code: 'ERR_SQLITE_ERROR', + message: /attempt to write a readonly database/, + }); + } + }); + test('throws if options.enableForeignKeyConstraints is provided but is not a boolean', (t) => { t.assert.throws(() => { new DatabaseSync('foo', { enableForeignKeyConstraints: 5 }); From 25b1422337d30029e0ff7c97c606a85bb095e972 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Thu, 31 Oct 2024 08:04:25 -0500 Subject: [PATCH 32/93] http: add diagnostic channel `http.client.request.created` PR-URL: https://github.com/nodejs/node/pull/55586 Fixes: https://github.com/nodejs/node/issues/55352 Reviewed-By: Paolo Insogna Reviewed-By: Jake Yuesong Li Reviewed-By: theanarkh --- doc/api/diagnostics_channel.md | 7 ++++ lib/_http_client.js | 6 +++ ...diagnostic-channel-http-request-created.js | 39 +++++++++++++++++++ .../parallel/test-diagnostics-channel-http.js | 5 +++ 4 files changed, 57 insertions(+) create mode 100644 test/parallel/test-diagnostic-channel-http-request-created.js diff --git a/doc/api/diagnostics_channel.md b/doc/api/diagnostics_channel.md index 66f395fa70319e..2467329c7729a2 100644 --- a/doc/api/diagnostics_channel.md +++ b/doc/api/diagnostics_channel.md @@ -1123,6 +1123,13 @@ independently. #### HTTP +`http.client.request.created` + +* `request` {http.ClientRequest} + +Emitted when client creates a request object. +Unlike `http.client.request.start`, this event is emitted before the request has been sent. + `http.client.request.start` * `request` {http.ClientRequest} diff --git a/lib/_http_client.js b/lib/_http_client.js index a0009cfb8f432b..91ba264339fa4f 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -89,6 +89,7 @@ const { const kClientRequestStatistics = Symbol('ClientRequestStatistics'); const dc = require('diagnostics_channel'); +const onClientRequestCreatedChannel = dc.channel('http.client.request.created'); const onClientRequestStartChannel = dc.channel('http.client.request.start'); const onClientRequestErrorChannel = dc.channel('http.client.request.error'); const onClientResponseFinishChannel = dc.channel('http.client.response.finish'); @@ -373,6 +374,11 @@ function ClientRequest(input, options, cb) { this.onSocket(net.createConnection(opts)); } } + if (onClientRequestCreatedChannel.hasSubscribers) { + onClientRequestCreatedChannel.publish({ + request: this, + }); + } } ObjectSetPrototypeOf(ClientRequest.prototype, OutgoingMessage.prototype); ObjectSetPrototypeOf(ClientRequest, OutgoingMessage); diff --git a/test/parallel/test-diagnostic-channel-http-request-created.js b/test/parallel/test-diagnostic-channel-http-request-created.js new file mode 100644 index 00000000000000..bbadfabcd9704f --- /dev/null +++ b/test/parallel/test-diagnostic-channel-http-request-created.js @@ -0,0 +1,39 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const dc = require('diagnostics_channel'); + +const isHTTPServer = (server) => server instanceof http.Server; +const isOutgoingMessage = (object) => object instanceof http.OutgoingMessage; + +dc.subscribe('http.client.request.created', common.mustCall(({ request }) => { + assert.strictEqual(request.getHeader('foo'), 'bar'); + assert.strictEqual(request.getHeader('baz'), undefined); + assert.strictEqual(isOutgoingMessage(request), true); + assert.strictEqual(isHTTPServer(server), true); +})); + +dc.subscribe('http.client.request.start', common.mustCall(({ request }) => { + assert.strictEqual(request.getHeader('foo'), 'bar'); + assert.strictEqual(request.getHeader('baz'), 'bar'); + assert.strictEqual(isOutgoingMessage(request), true); +})); + +const server = http.createServer(common.mustCall((_, res) => { + res.end('done'); +})); + +server.listen(async () => { + const { port } = server.address(); + const req = http.request({ + port, + headers: { + 'foo': 'bar', + } + }, common.mustCall(() => { + server.close(); + })); + req.setHeader('baz', 'bar'); + req.end(); +}); diff --git a/test/parallel/test-diagnostics-channel-http.js b/test/parallel/test-diagnostics-channel-http.js index e134b9ac05a85d..cc212e3f6207f5 100644 --- a/test/parallel/test-diagnostics-channel-http.js +++ b/test/parallel/test-diagnostics-channel-http.js @@ -53,6 +53,11 @@ dc.subscribe('http.server.response.finish', common.mustCall(({ assert.strictEqual(isHTTPServer(server), true); })); +dc.subscribe('http.client.request.created', common.mustCall(({ request }) => { + assert.strictEqual(isOutgoingMessage(request), true); + assert.strictEqual(isHTTPServer(server), true); +}, 2)); + const server = http.createServer(common.mustCall((req, res) => { res.end('done'); })); From 56c46ab686157796f1d1cf719f57fda1a5b43ad0 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Thu, 31 Oct 2024 16:43:57 +0100 Subject: [PATCH 33/93] module: unify TypeScript and .mjs handling in CommonJS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This refactors the CommonJS loading a bit to create a center point that handles source loading (`loadSource`) and make format detection more consistent to pave the way for future synchronous hooks. - Handle .mjs in the .js handler, similar to how .cjs has been handled. - Generate the legacy ERR_REQUIRE_ESM in a getRequireESMError() for both .mts and require(esm) handling (when it's disabled). PR-URL: https://github.com/nodejs/node/pull/55590 Refs: https://github.com/nodejs/loaders/pull/198 Reviewed-By: Antoine du Hamel Reviewed-By: Matteo Collina Reviewed-By: Marco Ippolito Reviewed-By: Juan José Arboleda --- lib/internal/modules/cjs/loader.js | 234 ++++++++++++++++------------- 1 file changed, 129 insertions(+), 105 deletions(-) diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 817da44cfc3c32..da948167e7fdd6 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -100,6 +100,9 @@ const kIsMainSymbol = Symbol('kIsMainSymbol'); const kIsCachedByESMLoader = Symbol('kIsCachedByESMLoader'); const kRequiredModuleSymbol = Symbol('kRequiredModuleSymbol'); const kIsExecuting = Symbol('kIsExecuting'); + +const kFormat = Symbol('kFormat'); + // Set first due to cycle with ESM loader functions. module.exports = { kModuleSource, @@ -436,9 +439,8 @@ function initializeCJS() { Module._extensions['.ts'] = loadTS; } if (getOptionValue('--experimental-require-module')) { - Module._extensions['.mjs'] = loadESMFromCJS; if (tsEnabled) { - Module._extensions['.mts'] = loadESMFromCJS; + Module._extensions['.mts'] = loadMTS; } } } @@ -653,8 +655,6 @@ function getDefaultExtensions() { if (tsEnabled) { // remove .ts and .cts from the default extensions // to avoid extensionless require of .ts and .cts files. - // it behaves similarly to how .mjs is handled when --experimental-require-module - // is enabled. extensions = ArrayPrototypeFilter(extensions, (ext) => (ext !== '.ts' || Module._extensions['.ts'] !== loadTS) && (ext !== '.cts' || Module._extensions['.cts'] !== loadCTS), @@ -667,14 +667,10 @@ function getDefaultExtensions() { if (tsEnabled) { extensions = ArrayPrototypeFilter(extensions, (ext) => - ext !== '.mts' || Module._extensions['.mts'] !== loadESMFromCJS, + ext !== '.mts' || Module._extensions['.mts'] !== loadMTS, ); } - // If the .mjs extension is added by --experimental-require-module, - // remove it from the supported default extensions to maintain - // compatibility. - // TODO(joyeecheung): allow both .mjs and .cjs? - return ArrayPrototypeFilter(extensions, (ext) => ext !== '.mjs' || Module._extensions['.mjs'] !== loadESMFromCJS); + return extensions; } /** @@ -1301,10 +1297,6 @@ Module.prototype.load = function(filename) { this.paths = Module._nodeModulePaths(path.dirname(filename)); const extension = findLongestRegisteredExtension(filename); - // allow .mjs to be overridden - if (StringPrototypeEndsWith(filename, '.mjs') && !Module._extensions['.mjs']) { - throw new ERR_REQUIRE_ESM(filename, true); - } if (getOptionValue('--experimental-strip-types')) { if (StringPrototypeEndsWith(filename, '.mts') && !Module._extensions['.mts']) { @@ -1353,12 +1345,10 @@ let hasPausedEntry = false; * Resolve and evaluate it synchronously as ESM if it's ESM. * @param {Module} mod CJS module instance * @param {string} filename Absolute path of the file. + * @param {string} format Format of the module. If it had types, this would be what it is after type-stripping. + * @param {string} source Source the module. If it had types, this would have the type stripped. */ -function loadESMFromCJS(mod, filename) { - let source = getMaybeCachedSource(mod, filename); - if (getOptionValue('--experimental-strip-types') && path.extname(filename) === '.mts') { - source = stripTypeScriptModuleTypes(source, filename); - } +function loadESMFromCJS(mod, filename, format, source) { const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader(); const isMain = mod[kIsMainSymbol]; if (isMain) { @@ -1512,9 +1502,30 @@ function wrapSafe(filename, content, cjsModuleInstance, format) { * `exports`) to the file. Returns exception, if any. * @param {string} content The source code of the module * @param {string} filename The file path of the module - * @param {'module'|'commonjs'|undefined} format Intended format of the module. + * @param { + * 'module'|'commonjs'|'commonjs-typescript'|'module-typescript' + * } format Intended format of the module. */ Module.prototype._compile = function(content, filename, format) { + if (format === 'commonjs-typescript' || format === 'module-typescript' || format === 'typescript') { + content = stripTypeScriptModuleTypes(content, filename); + switch (format) { + case 'commonjs-typescript': { + format = 'commonjs'; + break; + } + case 'module-typescript': { + format = 'module'; + break; + } + // If the format is still unknown i.e. 'typescript', detect it in + // wrapSafe using the type-stripped source. + default: + format = undefined; + break; + } + } + let redirects; let compiledWrapper; @@ -1527,9 +1538,7 @@ Module.prototype._compile = function(content, filename, format) { } if (format === 'module') { - // Pass the source into the .mjs extension handler indirectly through the cache. - this[kModuleSource] = content; - loadESMFromCJS(this, filename); + loadESMFromCJS(this, filename, format, content); return; } @@ -1582,72 +1591,76 @@ Module.prototype._compile = function(content, filename, format) { /** * Get the source code of a module, using cached ones if it's cached. + * After this returns, mod[kFormat], mod[kModuleSource] and mod[kURL] will be set. * @param {Module} mod Module instance whose source is potentially already cached. * @param {string} filename Absolute path to the file of the module. - * @returns {string} + * @returns {{source: string, format?: string}} */ -function getMaybeCachedSource(mod, filename) { - // If already analyzed the source, then it will be cached. - let content; - if (mod[kModuleSource] !== undefined) { - content = mod[kModuleSource]; +function loadSource(mod, filename, formatFromNode) { + if (formatFromNode !== undefined) { + mod[kFormat] = formatFromNode; + } + const format = mod[kFormat]; + + let source = mod[kModuleSource]; + if (source !== undefined) { mod[kModuleSource] = undefined; } else { // TODO(joyeecheung): we can read a buffer instead to speed up // compilation. - content = fs.readFileSync(filename, 'utf8'); + source = fs.readFileSync(filename, 'utf8'); } - return content; + return { source, format }; +} + +/** + * Built-in handler for `.mts` files. + * @param {Module} mod CJS module instance + * @param {string} filename The file path of the module + */ +function loadMTS(mod, filename) { + const loadResult = loadSource(mod, filename, 'module-typescript'); + mod._compile(loadResult.source, filename, loadResult.format); } +/** + * Built-in handler for `.cts` files. + * @param {Module} module CJS module instance + * @param {string} filename The file path of the module + */ + function loadCTS(module, filename) { - const source = getMaybeCachedSource(module, filename); - const code = stripTypeScriptModuleTypes(source, filename); - module._compile(code, filename, 'commonjs'); + const loadResult = loadSource(module, filename, 'commonjs-typescript'); + module._compile(loadResult.source, filename, loadResult.format); } /** * Built-in handler for `.ts` files. - * @param {Module} module The module to compile + * @param {Module} module CJS module instance * @param {string} filename The file path of the module */ function loadTS(module, filename) { - // If already analyzed the source, then it will be cached. - const source = getMaybeCachedSource(module, filename); - const content = stripTypeScriptModuleTypes(source, filename); - let format; const pkg = packageJsonReader.getNearestParentPackageJSON(filename); - // Function require shouldn't be used in ES modules. - if (pkg?.data.type === 'module') { - if (getOptionValue('--experimental-require-module')) { - module._compile(content, filename, 'module'); - return; - } + const typeFromPjson = pkg?.data.type; - const parent = module[kModuleParent]; - const parentPath = parent?.filename; - const packageJsonPath = pkg.path; - const usesEsm = containsModuleSyntax(content, filename); - const err = new ERR_REQUIRE_ESM(filename, usesEsm, parentPath, - packageJsonPath); - // Attempt to reconstruct the parent require frame. - if (Module._cache[parentPath]) { - let parentSource; - try { - parentSource = stripTypeScriptModuleTypes(fs.readFileSync(parentPath, 'utf8'), parentPath); - } catch { - // Continue regardless of error. - } - if (parentSource) { - reconstructErrorStack(err, parentPath, parentSource); - } - } + let format; + if (typeFromPjson === 'module') { + format = 'module-typescript'; + } else if (typeFromPjson === 'commonjs') { + format = 'commonjs-typescript'; + } else { + format = 'typescript'; + } + const loadResult = loadSource(module, filename, format); + + // Function require shouldn't be used in ES modules when require(esm) is disabled. + if (typeFromPjson === 'module' && !getOptionValue('--experimental-require-module')) { + const err = getRequireESMError(module, pkg, loadResult.source, filename); throw err; - } else if (pkg?.data.type === 'commonjs') { - format = 'commonjs'; } - module._compile(content, filename, format); + module[kFormat] = loadResult.format; + module._compile(loadResult.source, filename, loadResult.format); }; function reconstructErrorStack(err, parentPath, parentSource) { @@ -1663,53 +1676,64 @@ function reconstructErrorStack(err, parentPath, parentSource) { } } +/** + * Generate the legacy ERR_REQUIRE_ESM for the cases where require(esm) is disabled. + * @param {Module} mod The module being required. + * @param {undefined|object} pkg Data of the nearest package.json of the module. + * @param {string} content Source code of the module. + * @param {string} filename Filename of the module + * @returns {Error} + */ +function getRequireESMError(mod, pkg, content, filename) { + // This is an error path because `require` of a `.js` file in a `"type": "module"` scope is not allowed. + const parent = mod[kModuleParent]; + const parentPath = parent?.filename; + const packageJsonPath = pkg?.path; + const usesEsm = containsModuleSyntax(content, filename); + const err = new ERR_REQUIRE_ESM(filename, usesEsm, parentPath, + packageJsonPath); + // Attempt to reconstruct the parent require frame. + const parentModule = Module._cache[parentPath]; + if (parentModule) { + let parentSource; + try { + ({ source: parentSource } = loadSource(parentModule, parentPath)); + } catch { + // Continue regardless of error. + } + if (parentSource) { + // TODO(joyeecheung): trim off internal frames from the stack. + reconstructErrorStack(err, parentPath, parentSource); + } + } + return err; +} + /** * Built-in handler for `.js` files. * @param {Module} module The module to compile * @param {string} filename The file path of the module */ Module._extensions['.js'] = function(module, filename) { - // If already analyzed the source, then it will be cached. - const content = getMaybeCachedSource(module, filename); - - let format; - if (StringPrototypeEndsWith(filename, '.js')) { - const pkg = packageJsonReader.getNearestParentPackageJSON(filename); - // Function require shouldn't be used in ES modules. - if (pkg?.data.type === 'module') { - if (getOptionValue('--experimental-require-module')) { - module._compile(content, filename, 'module'); - return; - } - - // This is an error path because `require` of a `.js` file in a `"type": "module"` scope is not allowed. - const parent = module[kModuleParent]; - const parentPath = parent?.filename; - const packageJsonPath = pkg.path; - const usesEsm = containsModuleSyntax(content, filename); - const err = new ERR_REQUIRE_ESM(filename, usesEsm, parentPath, - packageJsonPath); - // Attempt to reconstruct the parent require frame. - if (Module._cache[parentPath]) { - let parentSource; - try { - parentSource = fs.readFileSync(parentPath, 'utf8'); - } catch { - // Continue regardless of error. - } - if (parentSource) { - reconstructErrorStack(err, parentPath, parentSource); - } - } - throw err; - } else if (pkg?.data.type === 'commonjs') { - format = 'commonjs'; - } - } else if (StringPrototypeEndsWith(filename, '.cjs')) { + let format, pkg; + if (StringPrototypeEndsWith(filename, '.cjs')) { format = 'commonjs'; + } else if (StringPrototypeEndsWith(filename, '.mjs')) { + format = 'module'; + } else if (StringPrototypeEndsWith(filename, '.js')) { + pkg = packageJsonReader.getNearestParentPackageJSON(filename); + const typeFromPjson = pkg?.data.type; + if (typeFromPjson === 'module' || typeFromPjson === 'commonjs' || !typeFromPjson) { + format = typeFromPjson; + } } - - module._compile(content, filename, format); + const { source, format: loadedFormat } = loadSource(module, filename, format); + // Function require shouldn't be used in ES modules when require(esm) is disabled. + if (loadedFormat === 'module' && !getOptionValue('--experimental-require-module')) { + const err = getRequireESMError(module, pkg, source, filename); + throw err; + } + module._compile(source, filename, loadedFormat); }; /** From 137aa5c9f665d1d560f20517c88bf8aee7989bfa Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 31 Oct 2024 19:08:45 +0200 Subject: [PATCH 34/93] http2: fix client async storage persistence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create and store an AsyncResource for each stream, following a similar approach as used in HttpAgent. Fixes: https://github.com/nodejs/node/issues/55376 PR-URL: https://github.com/nodejs/node/pull/55460 Reviewed-By: James M Snell Reviewed-By: Stephen Belanger Reviewed-By: Matteo Collina Reviewed-By: Gerhard Stöbich --- lib/internal/http2/core.js | 13 ++++- .../test-http2-async-local-storage.js | 55 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-http2-async-local-storage.js diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index c2ade7942951bb..6ce633092bca4b 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -60,6 +60,8 @@ const { owner_symbol, }, } = require('internal/async_hooks'); +const { AsyncResource } = require('async_hooks'); + const { AbortError, aggregateTwoErrors, @@ -241,6 +243,7 @@ const kPendingRequestCalls = Symbol('kPendingRequestCalls'); const kProceed = Symbol('proceed'); const kProtocol = Symbol('protocol'); const kRemoteSettings = Symbol('remote-settings'); +const kRequestAsyncResource = Symbol('requestAsyncResource'); const kSelectPadding = Symbol('select-padding'); const kSentHeaders = Symbol('sent-headers'); const kSentTrailers = Symbol('sent-trailers'); @@ -408,7 +411,11 @@ function onSessionHeaders(handle, id, cat, flags, headers, sensitiveHeaders) { originSet.delete(stream[kOrigin]); } debugStream(id, type, "emitting stream '%s' event", event); - process.nextTick(emit, stream, event, obj, flags, headers); + const reqAsync = stream[kRequestAsyncResource]; + if (reqAsync) + reqAsync.runInAsyncScope(process.nextTick, null, emit, stream, event, obj, flags, headers); + else + process.nextTick(emit, stream, event, obj, flags, headers); } if (endOfStream) { stream.push(null); @@ -1797,6 +1804,8 @@ class ClientHttp2Session extends Http2Session { stream[kSentHeaders] = headers; stream[kOrigin] = `${headers[HTTP2_HEADER_SCHEME]}://` + `${getAuthority(headers)}`; + const reqAsync = new AsyncResource('PendingRequest'); + stream[kRequestAsyncResource] = reqAsync; // Close the writable side of the stream if options.endStream is set. if (options.endStream) @@ -1819,7 +1828,7 @@ class ClientHttp2Session extends Http2Session { } } - const onConnect = requestOnConnect.bind(stream, headersList, options); + const onConnect = reqAsync.bind(requestOnConnect.bind(stream, headersList, options)); if (this.connecting) { if (this[kPendingRequestCalls] !== null) { this[kPendingRequestCalls].push(onConnect); diff --git a/test/parallel/test-http2-async-local-storage.js b/test/parallel/test-http2-async-local-storage.js new file mode 100644 index 00000000000000..699285221f847e --- /dev/null +++ b/test/parallel/test-http2-async-local-storage.js @@ -0,0 +1,55 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); +const async_hooks = require('async_hooks'); + +const storage = new async_hooks.AsyncLocalStorage(); + +const { + HTTP2_HEADER_CONTENT_TYPE, + HTTP2_HEADER_PATH, + HTTP2_HEADER_STATUS, +} = http2.constants; + +const server = http2.createServer(); +server.on('stream', (stream) => { + stream.respond({ + [HTTP2_HEADER_CONTENT_TYPE]: 'text/plain; charset=utf-8', + [HTTP2_HEADER_STATUS]: 200 + }); + stream.on('error', common.mustNotCall()); + stream.end('data'); +}); + +server.listen(0, async () => { + const client = storage.run({ id: 0 }, () => http2.connect(`http://localhost:${server.address().port}`)); + + async function doReq(id) { + const req = client.request({ [HTTP2_HEADER_PATH]: '/' }); + + req.on('response', common.mustCall((headers) => { + assert.strictEqual(headers[HTTP2_HEADER_STATUS], 200); + assert.strictEqual(id, storage.getStore().id); + })); + req.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), 'data'); + assert.strictEqual(id, storage.getStore().id); + })); + req.on('end', common.mustCall(() => { + assert.strictEqual(id, storage.getStore().id); + server.close(); + client.close(); + })); + } + + function doReqWith(id) { + storage.run({ id }, () => doReq(id)); + } + + doReqWith(1); + doReqWith(2); +}); From 2b9928561dd5d83e8d7332a09c3a77ead5f43a95 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 31 Oct 2024 22:11:27 +0100 Subject: [PATCH 35/93] url: refactor `pathToFileURL` to native PR-URL: https://github.com/nodejs/node/pull/55476 Reviewed-By: Yagiz Nizipli --- lib/internal/url.js | 92 +++++++-------------------------------- src/node_url.cc | 104 ++++++++++++++++++++++++++++++++++++++++++++ src/node_url.h | 1 + 3 files changed, 120 insertions(+), 77 deletions(-) diff --git a/lib/internal/url.js b/lib/internal/url.js index 64f1b0b6cc0ac6..14b0ef61d2f91c 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -16,7 +16,6 @@ const { ObjectSetPrototypeOf, ReflectGetOwnPropertyDescriptor, ReflectOwnKeys, - RegExpPrototypeSymbolReplace, SafeMap, SafeSet, StringPrototypeCharAt, @@ -779,6 +778,8 @@ function isURL(self) { * for invalid URL inputs. */ const kParseURLSymbol = Symbol('kParseURL'); +const kCreateURLFromPosixPathSymbol = Symbol('kCreateURLFromPosixPath'); +const kCreateURLFromWindowsPathSymbol = Symbol('kCreateURLFromWindowsPath'); class URL { #context = new URLContext(); @@ -812,8 +813,17 @@ class URL { base = `${base}`; } - const raiseException = parseSymbol !== kParseURLSymbol; - const href = bindingUrl.parse(input, base, raiseException); + let href; + if (arguments.length < 3) { + href = bindingUrl.parse(input, base, true); + } else { + const raiseException = parseSymbol !== kParseURLSymbol; + const interpretAsWindowsPath = parseSymbol === kCreateURLFromWindowsPathSymbol; + const pathToFileURL = interpretAsWindowsPath || (parseSymbol === kCreateURLFromPosixPathSymbol); + href = pathToFileURL ? + bindingUrl.pathToFileURL(input, interpretAsWindowsPath, base) : + bindingUrl.parse(input, base, raiseException); + } if (href) { this.#updateContext(href); } @@ -1500,76 +1510,9 @@ function fileURLToPath(path, options = kEmptyObject) { return (windows ?? isWindows) ? getPathFromURLWin32(path) : getPathFromURLPosix(path); } -// RFC1738 defines the following chars as "unsafe" for URLs -// @see https://www.ietf.org/rfc/rfc1738.txt 2.2. URL Character Encoding Issues -const percentRegEx = /%/g; -const newlineRegEx = /\n/g; -const carriageReturnRegEx = /\r/g; -const tabRegEx = /\t/g; -const quoteRegEx = /"/g; -const hashRegex = /#/g; -const spaceRegEx = / /g; -const questionMarkRegex = /\?/g; -const openSquareBracketRegEx = /\[/g; -const backslashRegEx = /\\/g; -const closeSquareBracketRegEx = /]/g; -const caretRegEx = /\^/g; -const verticalBarRegEx = /\|/g; -const tildeRegEx = /~/g; - -function encodePathChars(filepath, options = kEmptyObject) { - if (StringPrototypeIncludes(filepath, '%')) { - filepath = RegExpPrototypeSymbolReplace(percentRegEx, filepath, '%25'); - } - - if (StringPrototypeIncludes(filepath, '\t')) { - filepath = RegExpPrototypeSymbolReplace(tabRegEx, filepath, '%09'); - } - if (StringPrototypeIncludes(filepath, '\n')) { - filepath = RegExpPrototypeSymbolReplace(newlineRegEx, filepath, '%0A'); - } - if (StringPrototypeIncludes(filepath, '\r')) { - filepath = RegExpPrototypeSymbolReplace(carriageReturnRegEx, filepath, '%0D'); - } - if (StringPrototypeIncludes(filepath, ' ')) { - filepath = RegExpPrototypeSymbolReplace(spaceRegEx, filepath, '%20'); - } - if (StringPrototypeIncludes(filepath, '"')) { - filepath = RegExpPrototypeSymbolReplace(quoteRegEx, filepath, '%22'); - } - if (StringPrototypeIncludes(filepath, '#')) { - filepath = RegExpPrototypeSymbolReplace(hashRegex, filepath, '%23'); - } - if (StringPrototypeIncludes(filepath, '?')) { - filepath = RegExpPrototypeSymbolReplace(questionMarkRegex, filepath, '%3F'); - } - if (StringPrototypeIncludes(filepath, '[')) { - filepath = RegExpPrototypeSymbolReplace(openSquareBracketRegEx, filepath, '%5B'); - } - // Back-slashes must be special-cased on Windows, where they are treated as path separator. - if (!options.windows && StringPrototypeIncludes(filepath, '\\')) { - filepath = RegExpPrototypeSymbolReplace(backslashRegEx, filepath, '%5C'); - } - if (StringPrototypeIncludes(filepath, ']')) { - filepath = RegExpPrototypeSymbolReplace(closeSquareBracketRegEx, filepath, '%5D'); - } - if (StringPrototypeIncludes(filepath, '^')) { - filepath = RegExpPrototypeSymbolReplace(caretRegEx, filepath, '%5E'); - } - if (StringPrototypeIncludes(filepath, '|')) { - filepath = RegExpPrototypeSymbolReplace(verticalBarRegEx, filepath, '%7C'); - } - if (StringPrototypeIncludes(filepath, '~')) { - filepath = RegExpPrototypeSymbolReplace(tildeRegEx, filepath, '%7E'); - } - - return filepath; -} - function pathToFileURL(filepath, options = kEmptyObject) { const windows = options?.windows ?? isWindows; if (windows && StringPrototypeStartsWith(filepath, '\\\\')) { - const outURL = new URL('file://'); // UNC path format: \\server\share\resource // Handle extended UNC path and standard UNC path // "\\?\UNC\" path prefix should be ignored. @@ -1592,12 +1535,7 @@ function pathToFileURL(filepath, options = kEmptyObject) { ); } const hostname = StringPrototypeSlice(filepath, prefixLength, hostnameEndIndex); - outURL.hostname = domainToASCII(hostname); - outURL.pathname = encodePathChars( - RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/'), - { windows }, - ); - return outURL; + return new URL(StringPrototypeSlice(filepath, hostnameEndIndex), hostname, kCreateURLFromWindowsPathSymbol); } let resolved = windows ? path.win32.resolve(filepath) : path.posix.resolve(filepath); // path.resolve strips trailing slashes so we must add them back @@ -1608,7 +1546,7 @@ function pathToFileURL(filepath, options = kEmptyObject) { resolved[resolved.length - 1] !== path.sep) resolved += '/'; - return new URL(`file://${encodePathChars(resolved, { windows })}`); + return new URL(resolved, undefined, windows ? kCreateURLFromWindowsPathSymbol : kCreateURLFromPosixPathSymbol); } function toPathIfFileURL(fileURLOrPath) { diff --git a/src/node_url.cc b/src/node_url.cc index d49229f2b1f536..5b854cd9aeaa8b 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -75,6 +75,108 @@ void BindingData::Deserialize(v8::Local context, CHECK_NOT_NULL(binding); } +#ifndef LARGEST_ASCII_CHAR_CODE_TO_ENCODE +#define LARGEST_ASCII_CHAR_CODE_TO_ENCODE '~' +#endif + +// RFC1738 defines the following chars as "unsafe" for URLs +// @see https://www.ietf.org/rfc/rfc1738.txt 2.2. URL Character Encoding Issues +constexpr auto lookup_table = []() consteval { + // Each entry is an array that can hold up to 3 chars + null terminator + std::array, LARGEST_ASCII_CHAR_CODE_TO_ENCODE + 1> + result{}; + + for (uint8_t i = 0; i <= LARGEST_ASCII_CHAR_CODE_TO_ENCODE; i++) { + switch (i) { +#define ENCODE_CHAR(CHAR, HEX_DIGIT_2, HEX_DIGIT_1) \ + case CHAR: \ + result[i] = {{'%', HEX_DIGIT_2, HEX_DIGIT_1, 0}}; \ + break; + + ENCODE_CHAR('\0', '0', '0') // '\0' == 0x00 + ENCODE_CHAR('\t', '0', '9') // '\t' == 0x09 + ENCODE_CHAR('\n', '0', 'A') // '\n' == 0x0A + ENCODE_CHAR('\r', '0', 'D') // '\r' == 0x0D + ENCODE_CHAR(' ', '2', '0') // ' ' == 0x20 + ENCODE_CHAR('"', '2', '2') // '"' == 0x22 + ENCODE_CHAR('#', '2', '3') // '#' == 0x23 + ENCODE_CHAR('%', '2', '5') // '%' == 0x25 + ENCODE_CHAR('?', '3', 'F') // '?' == 0x3F + ENCODE_CHAR('[', '5', 'B') // '[' == 0x5B + ENCODE_CHAR('\\', '5', 'C') // '\\' == 0x5C + ENCODE_CHAR(']', '5', 'D') // ']' == 0x5D + ENCODE_CHAR('^', '5', 'E') // '^' == 0x5E + ENCODE_CHAR('|', '7', 'C') // '|' == 0x7C + ENCODE_CHAR('~', '7', 'E') // '~' == 0x7E +#undef ENCODE_CHAR + + default: + result[i] = {{static_cast(i), '\0', '\0', '\0'}}; + break; + } + } + + return result; +} +(); + +enum class OS { WINDOWS, POSIX }; + +std::string EncodePathChars(std::string_view input_str, OS operating_system) { + std::string encoded = "file://"; + encoded.reserve(input_str.size() + + 7); // Reserve space for "file://" and input_str + for (size_t i : input_str) { + if (i > LARGEST_ASCII_CHAR_CODE_TO_ENCODE) [[unlikely]] { + encoded.push_back(i); + continue; + } + if (operating_system == OS::WINDOWS) { + if (i == '\\') { + encoded.push_back('/'); + continue; + } + } + encoded.append(lookup_table[i].data()); + } + + return encoded; +} + +void BindingData::PathToFileURL(const FunctionCallbackInfo& args) { + CHECK_GE(args.Length(), 2); // input + CHECK(args[0]->IsString()); + CHECK(args[1]->IsBoolean()); + + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Isolate* isolate = realm->isolate(); + OS os = args[1]->IsTrue() ? OS::WINDOWS : OS::POSIX; + + Utf8Value input(isolate, args[0]); + auto input_str = input.ToStringView(); + CHECK(!input_str.empty()); + + auto out = + ada::parse(EncodePathChars(input_str, os), nullptr); + + if (!out) { + return ThrowInvalidURL(realm->env(), input.ToStringView(), nullptr); + } + + if (os == OS::WINDOWS && args.Length() > 2 && !args[2]->IsUndefined()) + [[unlikely]] { + CHECK(args[2]->IsString()); + Utf8Value hostname(isolate, args[2]); + CHECK(out->set_hostname(hostname.ToStringView())); + } + + binding_data->UpdateComponents(out->get_components(), out->type); + + args.GetReturnValue().Set( + ToV8Value(realm->context(), out->get_href(), isolate).ToLocalChecked()); +} + void BindingData::DomainToASCII(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK_GE(args.Length(), 1); // input @@ -371,6 +473,7 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data, SetMethodNoSideEffect(isolate, target, "format", Format); SetMethodNoSideEffect(isolate, target, "getOrigin", GetOrigin); SetMethod(isolate, target, "parse", Parse); + SetMethod(isolate, target, "pathToFileURL", PathToFileURL); SetMethod(isolate, target, "update", Update); SetFastMethodNoSideEffect( isolate, target, "canParse", CanParse, {fast_can_parse_methods_, 2}); @@ -391,6 +494,7 @@ void BindingData::RegisterExternalReferences( registry->Register(Format); registry->Register(GetOrigin); registry->Register(Parse); + registry->Register(PathToFileURL); registry->Register(Update); registry->Register(CanParse); registry->Register(FastCanParse); diff --git a/src/node_url.h b/src/node_url.h index 39fe9c9c8506e9..74f8a49955ce46 100644 --- a/src/node_url.h +++ b/src/node_url.h @@ -59,6 +59,7 @@ class BindingData : public SnapshotableObject { static void Format(const v8::FunctionCallbackInfo& args); static void GetOrigin(const v8::FunctionCallbackInfo& args); static void Parse(const v8::FunctionCallbackInfo& args); + static void PathToFileURL(const v8::FunctionCallbackInfo& args); static void Update(const v8::FunctionCallbackInfo& args); static void CreatePerIsolateProperties(IsolateData* isolate_data, From 4c34891454513e5608a8a75ec964eb71c5365251 Mon Sep 17 00:00:00 2001 From: theanarkh Date: Fri, 1 Nov 2024 11:28:03 +0800 Subject: [PATCH 36/93] src: fix dns crash when failed to create NodeAresTask PR-URL: https://github.com/nodejs/node/pull/55521 Fixes: https://github.com/nodejs/node/issues/52439 Reviewed-By: Luigi Pinca --- src/cares_wrap.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 84d2ab2b065e5d..00fe28d746d61c 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -145,14 +145,10 @@ void ares_sockstate_cb(void* data, ares_socket_t sock, int read, int write) { ares_poll_cb); } else { - /* read == 0 and write == 0 this is c-ares's way of notifying us that */ - /* the socket is now closed. We must free the data associated with */ - /* socket. */ - CHECK(task && - "When an ares socket is closed we should have a handle for it"); - - channel->task_list()->erase(it); - channel->env()->CloseHandle(&task->poll_watcher, ares_poll_close_cb); + if (task != nullptr) { + channel->task_list()->erase(it); + channel->env()->CloseHandle(&task->poll_watcher, ares_poll_close_cb); + } if (channel->task_list()->empty()) { channel->CloseTimer(); @@ -683,7 +679,6 @@ GetNameInfoReqWrap::GetNameInfoReqWrap( void ChannelWrap::AresTimeout(uv_timer_t* handle) { ChannelWrap* channel = static_cast(handle->data); CHECK_EQ(channel->timer_handle(), handle); - CHECK_EQ(false, channel->task_list()->empty()); ares_process_fd(channel->cares_channel(), ARES_SOCKET_BAD, ARES_SOCKET_BAD); } From 5de25676445ff6c12c8e34a7d8f560d5d3ae972a Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Fri, 1 Nov 2024 09:13:53 +0530 Subject: [PATCH 37/93] doc: improve c++ embedder API doc normalise the headers, fixup bullet points and expand `node::IsolateData` scope for clarity. PR-URL: https://github.com/nodejs/node/pull/55597 Reviewed-By: Akhil Marsonya Reviewed-By: Luigi Pinca --- doc/api/embedding.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/api/embedding.md b/doc/api/embedding.md index d4ae090c255f97..114f1128af0a42 100644 --- a/doc/api/embedding.md +++ b/doc/api/embedding.md @@ -23,7 +23,7 @@ a Node.js-specific environment. The full code can be found [in the Node.js source tree][embedtest.cc]. -### Setting up per-process state +### Setting up a per-process state Node.js requires some per-process state management in order to run: @@ -72,7 +72,7 @@ int main(int argc, char** argv) { } ``` -### Per-instance state +### Setting up a per-instance state \n\n' - } - } - return '\n\n' -} - -const eol$1 = /\r?\n|\r/g; -function indentLines(value, map) { - const result = []; - let start = 0; - let line = 0; - let match; - while ((match = eol$1.exec(value))) { - one(value.slice(start, match.index)); - result.push(match[0]); - start = match.index + match[0].length; - line++; - } - one(value.slice(start)); - return result.join('') - function one(value) { - result.push(map(value, line, !value)); - } -} - -function safe(state, input, config) { - const value = (config.before || '') + (input || '') + (config.after || ''); - const positions = []; - const result = []; - const infos = {}; - let index = -1; - while (++index < state.unsafe.length) { - const pattern = state.unsafe[index]; - if (!patternInScope(state.stack, pattern)) { - continue - } - const expression = state.compilePattern(pattern); - let match; - while ((match = expression.exec(value))) { - const before = 'before' in pattern || Boolean(pattern.atBreak); - const after = 'after' in pattern; - const position = match.index + (before ? match[1].length : 0); - if (positions.includes(position)) { - if (infos[position].before && !before) { - infos[position].before = false; - } - if (infos[position].after && !after) { - infos[position].after = false; - } - } else { - positions.push(position); - infos[position] = {before, after}; - } - } - } - positions.sort(numerical); - let start = config.before ? config.before.length : 0; - const end = value.length - (config.after ? config.after.length : 0); - index = -1; - while (++index < positions.length) { - const position = positions[index]; - if (position < start || position >= end) { - continue - } - if ( - (position + 1 < end && - positions[index + 1] === position + 1 && - infos[position].after && - !infos[position + 1].before && - !infos[position + 1].after) || - (positions[index - 1] === position - 1 && - infos[position].before && - !infos[position - 1].before && - !infos[position - 1].after) - ) { - continue - } - if (start !== position) { - result.push(escapeBackslashes(value.slice(start, position), '\\')); - } - start = position; - if ( - /[!-/:-@[-`{-~]/.test(value.charAt(position)) && - (!config.encode || !config.encode.includes(value.charAt(position))) - ) { - result.push('\\'); - } else { - result.push( - '&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';' - ); - start++; - } - } - result.push(escapeBackslashes(value.slice(start, end), config.after)); - return result.join('') -} -function numerical(a, b) { - return a - b -} -function escapeBackslashes(value, after) { - const expression = /\\(?=[!-/:-@[-`{-~])/g; - const positions = []; - const results = []; - const whole = value + after; - let index = -1; - let start = 0; - let match; - while ((match = expression.exec(whole))) { - positions.push(match.index); - } - while (++index < positions.length) { - if (start !== positions[index]) { - results.push(value.slice(start, positions[index])); - } - results.push('\\'); - start = positions[index]; - } - results.push(value.slice(start)); - return results.join('') -} - -function track(config) { - const options = config || {}; - const now = options.now || {}; - let lineShift = options.lineShift || 0; - let line = now.line || 1; - let column = now.column || 1; - return {move, current, shift} - function current() { - return {now: {line, column}, lineShift} - } - function shift(value) { - lineShift += value; - } - function move(input) { - const value = input || ''; - const chunks = value.split(/\r?\n|\r/g); - const tail = chunks[chunks.length - 1]; - line += chunks.length - 1; - column = - chunks.length === 1 ? column + tail.length : 1 + tail.length + lineShift; - return value - } -} - -function toMarkdown(tree, options = {}) { - const state = { - enter, - indentLines, - associationId: association, - containerPhrasing: containerPhrasingBound, - containerFlow: containerFlowBound, - createTracker: track, - compilePattern, - safe: safeBound, - stack: [], - unsafe: [...unsafe], - join: [...join], - handlers: {...handle}, - options: {}, - indexStack: [], - handle: undefined - }; - configure(state, options); - if (state.options.tightDefinitions) { - state.join.push(joinDefinition); - } - state.handle = zwitch('type', { - invalid, - unknown, - handlers: state.handlers - }); - let result = state.handle(tree, undefined, state, { - before: '\n', - after: '\n', - now: {line: 1, column: 1}, - lineShift: 0 - }); - if ( - result && - result.charCodeAt(result.length - 1) !== 10 && - result.charCodeAt(result.length - 1) !== 13 - ) { - result += '\n'; - } - return result - function enter(name) { - state.stack.push(name); - return exit - function exit() { - state.stack.pop(); - } - } -} -function invalid(value) { - throw new Error('Cannot handle value `' + value + '`, expected node') -} -function unknown(value) { - const node = (value); - throw new Error('Cannot handle unknown node `' + node.type + '`') -} -function joinDefinition(left, right) { - if (left.type === 'definition' && left.type === right.type) { - return 0 - } -} -function containerPhrasingBound(parent, info) { - return containerPhrasing(parent, this, info) -} -function containerFlowBound(parent, info) { - return containerFlow(parent, this, info) -} -function safeBound(value, config) { - return safe(this, value, config) -} - -function remarkStringify(options) { - const self = this; - self.compiler = compiler; - function compiler(tree) { - return toMarkdown(tree, { - ...self.data('settings'), - ...options, - extensions: self.data('toMarkdownExtensions') || [] - }) - } -} - -function ccount(value, character) { - const source = String(value); - if (typeof character !== 'string') { - throw new TypeError('Expected character') - } - let count = 0; - let index = source.indexOf(character); - while (index !== -1) { - count++; - index = source.indexOf(character, index + character.length); - } - return count -} - -function escapeStringRegexp(string) { - if (typeof string !== 'string') { - throw new TypeError('Expected a string'); - } - return string - .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - .replace(/-/g, '\\x2d'); -} - -function findAndReplace(tree, list, options) { - const settings = options || {}; - const ignored = convert(settings.ignore || []); - const pairs = toPairs(list); - let pairIndex = -1; - while (++pairIndex < pairs.length) { - visitParents(tree, 'text', visitor); - } - function visitor(node, parents) { - let index = -1; - let grandparent; - while (++index < parents.length) { - const parent = parents[index]; - const siblings = grandparent ? grandparent.children : undefined; - if ( - ignored( - parent, - siblings ? siblings.indexOf(parent) : undefined, - grandparent - ) - ) { - return - } - grandparent = parent; - } - if (grandparent) { - return handler(node, parents) - } - } - function handler(node, parents) { - const parent = parents[parents.length - 1]; - const find = pairs[pairIndex][0]; - const replace = pairs[pairIndex][1]; - let start = 0; - const siblings = parent.children; - const index = siblings.indexOf(node); - let change = false; - let nodes = []; - find.lastIndex = 0; - let match = find.exec(node.value); - while (match) { - const position = match.index; - const matchObject = { - index: match.index, - input: match.input, - stack: [...parents, node] - }; - let value = replace(...match, matchObject); - if (typeof value === 'string') { - value = value.length > 0 ? {type: 'text', value} : undefined; - } - if (value === false) { - find.lastIndex = position + 1; - } else { - if (start !== position) { - nodes.push({ - type: 'text', - value: node.value.slice(start, position) - }); - } - if (Array.isArray(value)) { - nodes.push(...value); - } else if (value) { - nodes.push(value); - } - start = position + match[0].length; - change = true; - } - if (!find.global) { - break - } - match = find.exec(node.value); - } - if (change) { - if (start < node.value.length) { - nodes.push({type: 'text', value: node.value.slice(start)}); - } - parent.children.splice(index, 1, ...nodes); - } else { - nodes = [node]; - } - return index + nodes.length - } -} -function toPairs(tupleOrList) { - const result = []; - if (!Array.isArray(tupleOrList)) { - throw new TypeError('Expected find and replace tuple or list of tuples') - } - const list = - !tupleOrList[0] || Array.isArray(tupleOrList[0]) - ? tupleOrList - : [tupleOrList]; - let index = -1; - while (++index < list.length) { - const tuple = list[index]; - result.push([toExpression(tuple[0]), toFunction(tuple[1])]); - } - return result -} -function toExpression(find) { - return typeof find === 'string' ? new RegExp(escapeStringRegexp(find), 'g') : find -} -function toFunction(replace) { - return typeof replace === 'function' - ? replace - : function () { - return replace - } -} - -const inConstruct = 'phrasing'; -const notInConstruct = ['autolink', 'link', 'image', 'label']; -function gfmAutolinkLiteralFromMarkdown() { - return { - transforms: [transformGfmAutolinkLiterals], - enter: { - literalAutolink: enterLiteralAutolink, - literalAutolinkEmail: enterLiteralAutolinkValue, - literalAutolinkHttp: enterLiteralAutolinkValue, - literalAutolinkWww: enterLiteralAutolinkValue - }, - exit: { - literalAutolink: exitLiteralAutolink, - literalAutolinkEmail: exitLiteralAutolinkEmail, - literalAutolinkHttp: exitLiteralAutolinkHttp, - literalAutolinkWww: exitLiteralAutolinkWww - } - } -} -function gfmAutolinkLiteralToMarkdown() { - return { - unsafe: [ - { - character: '@', - before: '[+\\-.\\w]', - after: '[\\-.\\w]', - inConstruct, - notInConstruct - }, - { - character: '.', - before: '[Ww]', - after: '[\\-.\\w]', - inConstruct, - notInConstruct - }, - { - character: ':', - before: '[ps]', - after: '\\/', - inConstruct, - notInConstruct - } - ] - } -} -function enterLiteralAutolink(token) { - this.enter({type: 'link', title: null, url: '', children: []}, token); -} -function enterLiteralAutolinkValue(token) { - this.config.enter.autolinkProtocol.call(this, token); -} -function exitLiteralAutolinkHttp(token) { - this.config.exit.autolinkProtocol.call(this, token); -} -function exitLiteralAutolinkWww(token) { - this.config.exit.data.call(this, token); - const node = this.stack[this.stack.length - 1]; - ok$1(node.type === 'link'); - node.url = 'http://' + this.sliceSerialize(token); -} -function exitLiteralAutolinkEmail(token) { - this.config.exit.autolinkEmail.call(this, token); -} -function exitLiteralAutolink(token) { - this.exit(token); -} -function transformGfmAutolinkLiterals(tree) { - findAndReplace( - tree, - [ - [/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi, findUrl], - [/(?<=^|\s|\p{P}|\p{S})([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/gu, findEmail] - ], - {ignore: ['link', 'linkReference']} - ); -} -function findUrl(_, protocol, domain, path, match) { - let prefix = ''; - if (!previous(match)) { - return false - } - if (/^w/i.test(protocol)) { - domain = protocol + domain; - protocol = ''; - prefix = 'http://'; - } - if (!isCorrectDomain(domain)) { - return false - } - const parts = splitUrl(domain + path); - if (!parts[0]) return false - const result = { - type: 'link', - title: null, - url: prefix + protocol + parts[0], - children: [{type: 'text', value: protocol + parts[0]}] - }; - if (parts[1]) { - return [result, {type: 'text', value: parts[1]}] - } - return result -} -function findEmail(_, atext, label, match) { - if ( - !previous(match, true) || - /[-\d_]$/.test(label) - ) { - return false - } - return { - type: 'link', - title: null, - url: 'mailto:' + atext + '@' + label, - children: [{type: 'text', value: atext + '@' + label}] - } -} -function isCorrectDomain(domain) { - const parts = domain.split('.'); - if ( - parts.length < 2 || - (parts[parts.length - 1] && - (/_/.test(parts[parts.length - 1]) || - !/[a-zA-Z\d]/.test(parts[parts.length - 1]))) || - (parts[parts.length - 2] && - (/_/.test(parts[parts.length - 2]) || - !/[a-zA-Z\d]/.test(parts[parts.length - 2]))) - ) { - return false - } - return true -} -function splitUrl(url) { - const trailExec = /[!"&'),.:;<>?\]}]+$/.exec(url); - if (!trailExec) { - return [url, undefined] - } - url = url.slice(0, trailExec.index); - let trail = trailExec[0]; - let closingParenIndex = trail.indexOf(')'); - const openingParens = ccount(url, '('); - let closingParens = ccount(url, ')'); - while (closingParenIndex !== -1 && openingParens > closingParens) { - url += trail.slice(0, closingParenIndex + 1); - trail = trail.slice(closingParenIndex + 1); - closingParenIndex = trail.indexOf(')'); - closingParens++; - } - return [url, trail] -} -function previous(match, email) { - const code = match.input.charCodeAt(match.index - 1); - return ( - (match.index === 0 || - unicodeWhitespace(code) || - unicodePunctuation(code)) && - (!email || code !== 47) - ) -} - -footnoteReference.peek = footnoteReferencePeek; -function gfmFootnoteFromMarkdown() { - return { - enter: { - gfmFootnoteDefinition: enterFootnoteDefinition, - gfmFootnoteDefinitionLabelString: enterFootnoteDefinitionLabelString, - gfmFootnoteCall: enterFootnoteCall, - gfmFootnoteCallString: enterFootnoteCallString - }, - exit: { - gfmFootnoteDefinition: exitFootnoteDefinition, - gfmFootnoteDefinitionLabelString: exitFootnoteDefinitionLabelString, - gfmFootnoteCall: exitFootnoteCall, - gfmFootnoteCallString: exitFootnoteCallString - } - } -} -function gfmFootnoteToMarkdown() { - return { - unsafe: [{character: '[', inConstruct: ['phrasing', 'label', 'reference']}], - handlers: {footnoteDefinition, footnoteReference} - } -} -function enterFootnoteDefinition(token) { - this.enter( - {type: 'footnoteDefinition', identifier: '', label: '', children: []}, - token - ); -} -function enterFootnoteDefinitionLabelString() { - this.buffer(); -} -function exitFootnoteDefinitionLabelString(token) { - const label = this.resume(); - const node = this.stack[this.stack.length - 1]; - ok$1(node.type === 'footnoteDefinition'); - node.label = label; - node.identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); -} -function exitFootnoteDefinition(token) { - this.exit(token); -} -function enterFootnoteCall(token) { - this.enter({type: 'footnoteReference', identifier: '', label: ''}, token); -} -function enterFootnoteCallString() { - this.buffer(); -} -function exitFootnoteCallString(token) { - const label = this.resume(); - const node = this.stack[this.stack.length - 1]; - ok$1(node.type === 'footnoteReference'); - node.label = label; - node.identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); -} -function exitFootnoteCall(token) { - this.exit(token); -} -function footnoteReference(node, _, state, info) { - const tracker = state.createTracker(info); - let value = tracker.move('[^'); - const exit = state.enter('footnoteReference'); - const subexit = state.enter('reference'); - value += tracker.move( - state.safe(state.associationId(node), { - ...tracker.current(), - before: value, - after: ']' - }) - ); - subexit(); - exit(); - value += tracker.move(']'); - return value -} -function footnoteReferencePeek() { - return '[' -} -function footnoteDefinition(node, _, state, info) { - const tracker = state.createTracker(info); - let value = tracker.move('[^'); - const exit = state.enter('footnoteDefinition'); - const subexit = state.enter('label'); - value += tracker.move( - state.safe(state.associationId(node), { - ...tracker.current(), - before: value, - after: ']' - }) - ); - subexit(); - value += tracker.move( - ']:' + (node.children && node.children.length > 0 ? ' ' : '') - ); - tracker.shift(4); - value += tracker.move( - state.indentLines(state.containerFlow(node, tracker.current()), map$1) - ); - exit(); - return value -} -function map$1(line, index, blank) { - if (index === 0) { - return line - } - return (blank ? '' : ' ') + line -} - -const constructsWithoutStrikethrough = [ - 'autolink', - 'destinationLiteral', - 'destinationRaw', - 'reference', - 'titleQuote', - 'titleApostrophe' -]; -handleDelete.peek = peekDelete; -function gfmStrikethroughFromMarkdown() { - return { - canContainEols: ['delete'], - enter: {strikethrough: enterStrikethrough}, - exit: {strikethrough: exitStrikethrough} - } -} -function gfmStrikethroughToMarkdown() { - return { - unsafe: [ - { - character: '~', - inConstruct: 'phrasing', - notInConstruct: constructsWithoutStrikethrough - } - ], - handlers: {delete: handleDelete} - } -} -function enterStrikethrough(token) { - this.enter({type: 'delete', children: []}, token); -} -function exitStrikethrough(token) { - this.exit(token); -} -function handleDelete(node, _, state, info) { - const tracker = state.createTracker(info); - const exit = state.enter('strikethrough'); - let value = tracker.move('~~'); - value += state.containerPhrasing(node, { - ...tracker.current(), - before: value, - after: '~' - }); - value += tracker.move('~~'); - exit(); - return value -} -function peekDelete() { - return '~' -} - -function markdownTable(table, options = {}) { - const align = (options.align || []).concat(); - const stringLength = options.stringLength || defaultStringLength; - const alignments = []; - const cellMatrix = []; - const sizeMatrix = []; - const longestCellByColumn = []; - let mostCellsPerRow = 0; - let rowIndex = -1; - while (++rowIndex < table.length) { - const row = []; - const sizes = []; - let columnIndex = -1; - if (table[rowIndex].length > mostCellsPerRow) { - mostCellsPerRow = table[rowIndex].length; - } - while (++columnIndex < table[rowIndex].length) { - const cell = serialize(table[rowIndex][columnIndex]); - if (options.alignDelimiters !== false) { - const size = stringLength(cell); - sizes[columnIndex] = size; - if ( - longestCellByColumn[columnIndex] === undefined || - size > longestCellByColumn[columnIndex] - ) { - longestCellByColumn[columnIndex] = size; - } - } - row.push(cell); - } - cellMatrix[rowIndex] = row; - sizeMatrix[rowIndex] = sizes; - } - let columnIndex = -1; - if (typeof align === 'object' && 'length' in align) { - while (++columnIndex < mostCellsPerRow) { - alignments[columnIndex] = toAlignment(align[columnIndex]); - } - } else { - const code = toAlignment(align); - while (++columnIndex < mostCellsPerRow) { - alignments[columnIndex] = code; - } - } - columnIndex = -1; - const row = []; - const sizes = []; - while (++columnIndex < mostCellsPerRow) { - const code = alignments[columnIndex]; - let before = ''; - let after = ''; - if (code === 99 ) { - before = ':'; - after = ':'; - } else if (code === 108 ) { - before = ':'; - } else if (code === 114 ) { - after = ':'; - } - let size = - options.alignDelimiters === false - ? 1 - : Math.max( - 1, - longestCellByColumn[columnIndex] - before.length - after.length - ); - const cell = before + '-'.repeat(size) + after; - if (options.alignDelimiters !== false) { - size = before.length + size + after.length; - if (size > longestCellByColumn[columnIndex]) { - longestCellByColumn[columnIndex] = size; - } - sizes[columnIndex] = size; - } - row[columnIndex] = cell; - } - cellMatrix.splice(1, 0, row); - sizeMatrix.splice(1, 0, sizes); - rowIndex = -1; - const lines = []; - while (++rowIndex < cellMatrix.length) { - const row = cellMatrix[rowIndex]; - const sizes = sizeMatrix[rowIndex]; - columnIndex = -1; - const line = []; - while (++columnIndex < mostCellsPerRow) { - const cell = row[columnIndex] || ''; - let before = ''; - let after = ''; - if (options.alignDelimiters !== false) { - const size = - longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0); - const code = alignments[columnIndex]; - if (code === 114 ) { - before = ' '.repeat(size); - } else if (code === 99 ) { - if (size % 2) { - before = ' '.repeat(size / 2 + 0.5); - after = ' '.repeat(size / 2 - 0.5); - } else { - before = ' '.repeat(size / 2); - after = before; - } - } else { - after = ' '.repeat(size); - } - } - if (options.delimiterStart !== false && !columnIndex) { - line.push('|'); - } - if ( - options.padding !== false && - !(options.alignDelimiters === false && cell === '') && - (options.delimiterStart !== false || columnIndex) - ) { - line.push(' '); - } - if (options.alignDelimiters !== false) { - line.push(before); - } - line.push(cell); - if (options.alignDelimiters !== false) { - line.push(after); - } - if (options.padding !== false) { - line.push(' '); - } - if ( - options.delimiterEnd !== false || - columnIndex !== mostCellsPerRow - 1 - ) { - line.push('|'); - } - } - lines.push( - options.delimiterEnd === false - ? line.join('').replace(/ +$/, '') - : line.join('') - ); - } - return lines.join('\n') -} -function serialize(value) { - return value === null || value === undefined ? '' : String(value) -} -function defaultStringLength(value) { - return value.length -} -function toAlignment(value) { - const code = typeof value === 'string' ? value.codePointAt(0) : 0; - return code === 67 || code === 99 - ? 99 - : code === 76 || code === 108 - ? 108 - : code === 82 || code === 114 - ? 114 - : 0 -} - -function gfmTableFromMarkdown() { - return { - enter: { - table: enterTable, - tableData: enterCell, - tableHeader: enterCell, - tableRow: enterRow - }, - exit: { - codeText: exitCodeText, - table: exitTable, - tableData: exit, - tableHeader: exit, - tableRow: exit - } - } -} -function enterTable(token) { - const align = token._align; - this.enter( - { - type: 'table', - align: align.map(function (d) { - return d === 'none' ? null : d - }), - children: [] - }, - token - ); - this.data.inTable = true; -} -function exitTable(token) { - this.exit(token); - this.data.inTable = undefined; -} -function enterRow(token) { - this.enter({type: 'tableRow', children: []}, token); -} -function exit(token) { - this.exit(token); -} -function enterCell(token) { - this.enter({type: 'tableCell', children: []}, token); -} -function exitCodeText(token) { - let value = this.resume(); - if (this.data.inTable) { - value = value.replace(/\\([\\|])/g, replace); - } - const node = this.stack[this.stack.length - 1]; - ok$1(node.type === 'inlineCode'); - node.value = value; - this.exit(token); -} -function replace($0, $1) { - return $1 === '|' ? $1 : $0 -} -function gfmTableToMarkdown(options) { - const settings = options || {}; - const padding = settings.tableCellPadding; - const alignDelimiters = settings.tablePipeAlign; - const stringLength = settings.stringLength; - const around = padding ? ' ' : '|'; - return { - unsafe: [ - {character: '\r', inConstruct: 'tableCell'}, - {character: '\n', inConstruct: 'tableCell'}, - {atBreak: true, character: '|', after: '[\t :-]'}, - {character: '|', inConstruct: 'tableCell'}, - {atBreak: true, character: ':', after: '-'}, - {atBreak: true, character: '-', after: '[:|-]'} - ], - handlers: { - inlineCode: inlineCodeWithTable, - table: handleTable, - tableCell: handleTableCell, - tableRow: handleTableRow - } - } - function handleTable(node, _, state, info) { - return serializeData(handleTableAsData(node, state, info), node.align) - } - function handleTableRow(node, _, state, info) { - const row = handleTableRowAsData(node, state, info); - const value = serializeData([row]); - return value.slice(0, value.indexOf('\n')) - } - function handleTableCell(node, _, state, info) { - const exit = state.enter('tableCell'); - const subexit = state.enter('phrasing'); - const value = state.containerPhrasing(node, { - ...info, - before: around, - after: around - }); - subexit(); - exit(); - return value - } - function serializeData(matrix, align) { - return markdownTable(matrix, { - align, - alignDelimiters, - padding, - stringLength - }) - } - function handleTableAsData(node, state, info) { - const children = node.children; - let index = -1; - const result = []; - const subexit = state.enter('table'); - while (++index < children.length) { - result[index] = handleTableRowAsData(children[index], state, info); - } - subexit(); - return result - } - function handleTableRowAsData(node, state, info) { - const children = node.children; - let index = -1; - const result = []; - const subexit = state.enter('tableRow'); - while (++index < children.length) { - result[index] = handleTableCell(children[index], node, state, info); - } - subexit(); - return result - } - function inlineCodeWithTable(node, parent, state) { - let value = handle.inlineCode(node, parent, state); - if (state.stack.includes('tableCell')) { - value = value.replace(/\|/g, '\\$&'); - } - return value - } -} - -function gfmTaskListItemFromMarkdown() { - return { - exit: { - taskListCheckValueChecked: exitCheck, - taskListCheckValueUnchecked: exitCheck, - paragraph: exitParagraphWithTaskListItem - } - } -} -function gfmTaskListItemToMarkdown() { - return { - unsafe: [{atBreak: true, character: '-', after: '[:|-]'}], - handlers: {listItem: listItemWithTaskListItem} - } -} -function exitCheck(token) { - const node = this.stack[this.stack.length - 2]; - ok$1(node.type === 'listItem'); - node.checked = token.type === 'taskListCheckValueChecked'; -} -function exitParagraphWithTaskListItem(token) { - const parent = this.stack[this.stack.length - 2]; - if ( - parent && - parent.type === 'listItem' && - typeof parent.checked === 'boolean' - ) { - const node = this.stack[this.stack.length - 1]; - ok$1(node.type === 'paragraph'); - const head = node.children[0]; - if (head && head.type === 'text') { - const siblings = parent.children; - let index = -1; - let firstParaghraph; - while (++index < siblings.length) { - const sibling = siblings[index]; - if (sibling.type === 'paragraph') { - firstParaghraph = sibling; - break - } - } - if (firstParaghraph === node) { - head.value = head.value.slice(1); - if (head.value.length === 0) { - node.children.shift(); - } else if ( - node.position && - head.position && - typeof head.position.start.offset === 'number' - ) { - head.position.start.column++; - head.position.start.offset++; - node.position.start = Object.assign({}, head.position.start); - } - } - } - } - this.exit(token); -} -function listItemWithTaskListItem(node, parent, state, info) { - const head = node.children[0]; - const checkable = - typeof node.checked === 'boolean' && head && head.type === 'paragraph'; - const checkbox = '[' + (node.checked ? 'x' : ' ') + '] '; - const tracker = state.createTracker(info); - if (checkable) { - tracker.move(checkbox); - } - let value = handle.listItem(node, parent, state, { - ...info, - ...tracker.current() - }); - if (checkable) { - value = value.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/, check); - } - return value - function check($0) { - return $0 + checkbox - } -} - -function gfmFromMarkdown() { - return [ - gfmAutolinkLiteralFromMarkdown(), - gfmFootnoteFromMarkdown(), - gfmStrikethroughFromMarkdown(), - gfmTableFromMarkdown(), - gfmTaskListItemFromMarkdown() - ] -} -function gfmToMarkdown(options) { - return { - extensions: [ - gfmAutolinkLiteralToMarkdown(), - gfmFootnoteToMarkdown(), - gfmStrikethroughToMarkdown(), - gfmTableToMarkdown(options), - gfmTaskListItemToMarkdown() - ] - } -} - -const wwwPrefix = { - tokenize: tokenizeWwwPrefix, - partial: true -}; -const domain = { - tokenize: tokenizeDomain, - partial: true -}; -const path = { - tokenize: tokenizePath, - partial: true -}; -const trail = { - tokenize: tokenizeTrail, - partial: true -}; -const emailDomainDotTrail = { - tokenize: tokenizeEmailDomainDotTrail, - partial: true -}; -const wwwAutolink = { - name: 'wwwAutolink', - tokenize: tokenizeWwwAutolink, - previous: previousWww -}; -const protocolAutolink = { - name: 'protocolAutolink', - tokenize: tokenizeProtocolAutolink, - previous: previousProtocol -}; -const emailAutolink = { - name: 'emailAutolink', - tokenize: tokenizeEmailAutolink, - previous: previousEmail -}; -const text = {}; -function gfmAutolinkLiteral() { - return { - text - }; -} -let code = 48; -while (code < 123) { - text[code] = emailAutolink; - code++; - if (code === 58) code = 65;else if (code === 91) code = 97; -} -text[43] = emailAutolink; -text[45] = emailAutolink; -text[46] = emailAutolink; -text[95] = emailAutolink; -text[72] = [emailAutolink, protocolAutolink]; -text[104] = [emailAutolink, protocolAutolink]; -text[87] = [emailAutolink, wwwAutolink]; -text[119] = [emailAutolink, wwwAutolink]; -function tokenizeEmailAutolink(effects, ok, nok) { - const self = this; - let dot; - let data; - return start; - function start(code) { - if (!gfmAtext(code) || !previousEmail.call(self, self.previous) || previousUnbalanced(self.events)) { - return nok(code); - } - effects.enter('literalAutolink'); - effects.enter('literalAutolinkEmail'); - return atext(code); - } - function atext(code) { - if (gfmAtext(code)) { - effects.consume(code); - return atext; - } - if (code === 64) { - effects.consume(code); - return emailDomain; - } - return nok(code); - } - function emailDomain(code) { - if (code === 46) { - return effects.check(emailDomainDotTrail, emailDomainAfter, emailDomainDot)(code); - } - if (code === 45 || code === 95 || asciiAlphanumeric(code)) { - data = true; - effects.consume(code); - return emailDomain; - } - return emailDomainAfter(code); - } - function emailDomainDot(code) { - effects.consume(code); - dot = true; - return emailDomain; - } - function emailDomainAfter(code) { - if (data && dot && asciiAlpha(self.previous)) { - effects.exit('literalAutolinkEmail'); - effects.exit('literalAutolink'); - return ok(code); - } - return nok(code); - } -} -function tokenizeWwwAutolink(effects, ok, nok) { - const self = this; - return wwwStart; - function wwwStart(code) { - if (code !== 87 && code !== 119 || !previousWww.call(self, self.previous) || previousUnbalanced(self.events)) { - return nok(code); - } - effects.enter('literalAutolink'); - effects.enter('literalAutolinkWww'); - return effects.check(wwwPrefix, effects.attempt(domain, effects.attempt(path, wwwAfter), nok), nok)(code); - } - function wwwAfter(code) { - effects.exit('literalAutolinkWww'); - effects.exit('literalAutolink'); - return ok(code); - } -} -function tokenizeProtocolAutolink(effects, ok, nok) { - const self = this; - let buffer = ''; - let seen = false; - return protocolStart; - function protocolStart(code) { - if ((code === 72 || code === 104) && previousProtocol.call(self, self.previous) && !previousUnbalanced(self.events)) { - effects.enter('literalAutolink'); - effects.enter('literalAutolinkHttp'); - buffer += String.fromCodePoint(code); - effects.consume(code); - return protocolPrefixInside; - } - return nok(code); - } - function protocolPrefixInside(code) { - if (asciiAlpha(code) && buffer.length < 5) { - buffer += String.fromCodePoint(code); - effects.consume(code); - return protocolPrefixInside; - } - if (code === 58) { - const protocol = buffer.toLowerCase(); - if (protocol === 'http' || protocol === 'https') { - effects.consume(code); - return protocolSlashesInside; - } - } - return nok(code); - } - function protocolSlashesInside(code) { - if (code === 47) { - effects.consume(code); - if (seen) { - return afterProtocol; - } - seen = true; - return protocolSlashesInside; - } - return nok(code); - } - function afterProtocol(code) { - return code === null || asciiControl(code) || markdownLineEndingOrSpace(code) || unicodeWhitespace(code) || unicodePunctuation(code) ? nok(code) : effects.attempt(domain, effects.attempt(path, protocolAfter), nok)(code); - } - function protocolAfter(code) { - effects.exit('literalAutolinkHttp'); - effects.exit('literalAutolink'); - return ok(code); - } -} -function tokenizeWwwPrefix(effects, ok, nok) { - let size = 0; - return wwwPrefixInside; - function wwwPrefixInside(code) { - if ((code === 87 || code === 119) && size < 3) { - size++; - effects.consume(code); - return wwwPrefixInside; - } - if (code === 46 && size === 3) { - effects.consume(code); - return wwwPrefixAfter; - } - return nok(code); - } - function wwwPrefixAfter(code) { - return code === null ? nok(code) : ok(code); - } -} -function tokenizeDomain(effects, ok, nok) { - let underscoreInLastSegment; - let underscoreInLastLastSegment; - let seen; - return domainInside; - function domainInside(code) { - if (code === 46 || code === 95) { - return effects.check(trail, domainAfter, domainAtPunctuation)(code); - } - if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code) || code !== 45 && unicodePunctuation(code)) { - return domainAfter(code); - } - seen = true; - effects.consume(code); - return domainInside; - } - function domainAtPunctuation(code) { - if (code === 95) { - underscoreInLastSegment = true; - } - else { - underscoreInLastLastSegment = underscoreInLastSegment; - underscoreInLastSegment = undefined; - } - effects.consume(code); - return domainInside; - } - function domainAfter(code) { - if (underscoreInLastLastSegment || underscoreInLastSegment || !seen) { - return nok(code); - } - return ok(code); - } -} -function tokenizePath(effects, ok) { - let sizeOpen = 0; - let sizeClose = 0; - return pathInside; - function pathInside(code) { - if (code === 40) { - sizeOpen++; - effects.consume(code); - return pathInside; - } - if (code === 41 && sizeClose < sizeOpen) { - return pathAtPunctuation(code); - } - if (code === 33 || code === 34 || code === 38 || code === 39 || code === 41 || code === 42 || code === 44 || code === 46 || code === 58 || code === 59 || code === 60 || code === 63 || code === 93 || code === 95 || code === 126) { - return effects.check(trail, ok, pathAtPunctuation)(code); - } - if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) { - return ok(code); - } - effects.consume(code); - return pathInside; - } - function pathAtPunctuation(code) { - if (code === 41) { - sizeClose++; - } - effects.consume(code); - return pathInside; - } -} -function tokenizeTrail(effects, ok, nok) { - return trail; - function trail(code) { - if (code === 33 || code === 34 || code === 39 || code === 41 || code === 42 || code === 44 || code === 46 || code === 58 || code === 59 || code === 63 || code === 95 || code === 126) { - effects.consume(code); - return trail; - } - if (code === 38) { - effects.consume(code); - return trailCharacterReferenceStart; - } - if (code === 93) { - effects.consume(code); - return trailBracketAfter; - } - if ( - code === 60 || - code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) { - return ok(code); - } - return nok(code); - } - function trailBracketAfter(code) { - if (code === null || code === 40 || code === 91 || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) { - return ok(code); - } - return trail(code); - } - function trailCharacterReferenceStart(code) { - return asciiAlpha(code) ? trailCharacterReferenceInside(code) : nok(code); - } - function trailCharacterReferenceInside(code) { - if (code === 59) { - effects.consume(code); - return trail; - } - if (asciiAlpha(code)) { - effects.consume(code); - return trailCharacterReferenceInside; - } - return nok(code); - } -} -function tokenizeEmailDomainDotTrail(effects, ok, nok) { - return start; - function start(code) { - effects.consume(code); - return after; - } - function after(code) { - return asciiAlphanumeric(code) ? nok(code) : ok(code); - } -} -function previousWww(code) { - return code === null || code === 40 || code === 42 || code === 95 || code === 91 || code === 93 || code === 126 || markdownLineEndingOrSpace(code); -} -function previousProtocol(code) { - return !asciiAlpha(code); -} -function previousEmail(code) { - return !(code === 47 || gfmAtext(code)); -} -function gfmAtext(code) { - return code === 43 || code === 45 || code === 46 || code === 95 || asciiAlphanumeric(code); -} -function previousUnbalanced(events) { - let index = events.length; - let result = false; - while (index--) { - const token = events[index][1]; - if ((token.type === 'labelLink' || token.type === 'labelImage') && !token._balanced) { - result = true; - break; - } - if (token._gfmAutolinkLiteralWalkedInto) { - result = false; - break; - } - } - if (events.length > 0 && !result) { - events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true; - } - return result; -} - -const indent = { - tokenize: tokenizeIndent, - partial: true -}; -function gfmFootnote() { - return { - document: { - [91]: { - name: 'gfmFootnoteDefinition', - tokenize: tokenizeDefinitionStart, - continuation: { - tokenize: tokenizeDefinitionContinuation - }, - exit: gfmFootnoteDefinitionEnd - } - }, - text: { - [91]: { - name: 'gfmFootnoteCall', - tokenize: tokenizeGfmFootnoteCall - }, - [93]: { - name: 'gfmPotentialFootnoteCall', - add: 'after', - tokenize: tokenizePotentialGfmFootnoteCall, - resolveTo: resolveToPotentialGfmFootnoteCall - } - } - }; -} -function tokenizePotentialGfmFootnoteCall(effects, ok, nok) { - const self = this; - let index = self.events.length; - const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []); - let labelStart; - while (index--) { - const token = self.events[index][1]; - if (token.type === "labelImage") { - labelStart = token; - break; - } - if (token.type === 'gfmFootnoteCall' || token.type === "labelLink" || token.type === "label" || token.type === "image" || token.type === "link") { - break; - } - } - return start; - function start(code) { - if (!labelStart || !labelStart._balanced) { - return nok(code); - } - const id = normalizeIdentifier(self.sliceSerialize({ - start: labelStart.end, - end: self.now() - })); - if (id.codePointAt(0) !== 94 || !defined.includes(id.slice(1))) { - return nok(code); - } - effects.enter('gfmFootnoteCallLabelMarker'); - effects.consume(code); - effects.exit('gfmFootnoteCallLabelMarker'); - return ok(code); - } -} -function resolveToPotentialGfmFootnoteCall(events, context) { - let index = events.length; - while (index--) { - if (events[index][1].type === "labelImage" && events[index][0] === 'enter') { - events[index][1]; - break; - } - } - events[index + 1][1].type = "data"; - events[index + 3][1].type = 'gfmFootnoteCallLabelMarker'; - const call = { - type: 'gfmFootnoteCall', - start: Object.assign({}, events[index + 3][1].start), - end: Object.assign({}, events[events.length - 1][1].end) - }; - const marker = { - type: 'gfmFootnoteCallMarker', - start: Object.assign({}, events[index + 3][1].end), - end: Object.assign({}, events[index + 3][1].end) - }; - marker.end.column++; - marker.end.offset++; - marker.end._bufferIndex++; - const string = { - type: 'gfmFootnoteCallString', - start: Object.assign({}, marker.end), - end: Object.assign({}, events[events.length - 1][1].start) - }; - const chunk = { - type: "chunkString", - contentType: 'string', - start: Object.assign({}, string.start), - end: Object.assign({}, string.end) - }; - const replacement = [ - events[index + 1], events[index + 2], ['enter', call, context], - events[index + 3], events[index + 4], - ['enter', marker, context], ['exit', marker, context], - ['enter', string, context], ['enter', chunk, context], ['exit', chunk, context], ['exit', string, context], - events[events.length - 2], events[events.length - 1], ['exit', call, context]]; - events.splice(index, events.length - index + 1, ...replacement); - return events; -} -function tokenizeGfmFootnoteCall(effects, ok, nok) { - const self = this; - const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []); - let size = 0; - let data; - return start; - function start(code) { - effects.enter('gfmFootnoteCall'); - effects.enter('gfmFootnoteCallLabelMarker'); - effects.consume(code); - effects.exit('gfmFootnoteCallLabelMarker'); - return callStart; - } - function callStart(code) { - if (code !== 94) return nok(code); - effects.enter('gfmFootnoteCallMarker'); - effects.consume(code); - effects.exit('gfmFootnoteCallMarker'); - effects.enter('gfmFootnoteCallString'); - effects.enter('chunkString').contentType = 'string'; - return callData; - } - function callData(code) { - if ( - size > 999 || - code === 93 && !data || - code === null || code === 91 || markdownLineEndingOrSpace(code)) { - return nok(code); - } - if (code === 93) { - effects.exit('chunkString'); - const token = effects.exit('gfmFootnoteCallString'); - if (!defined.includes(normalizeIdentifier(self.sliceSerialize(token)))) { - return nok(code); - } - effects.enter('gfmFootnoteCallLabelMarker'); - effects.consume(code); - effects.exit('gfmFootnoteCallLabelMarker'); - effects.exit('gfmFootnoteCall'); - return ok; - } - if (!markdownLineEndingOrSpace(code)) { - data = true; - } - size++; - effects.consume(code); - return code === 92 ? callEscape : callData; - } - function callEscape(code) { - if (code === 91 || code === 92 || code === 93) { - effects.consume(code); - size++; - return callData; - } - return callData(code); - } -} -function tokenizeDefinitionStart(effects, ok, nok) { - const self = this; - const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []); - let identifier; - let size = 0; - let data; - return start; - function start(code) { - effects.enter('gfmFootnoteDefinition')._container = true; - effects.enter('gfmFootnoteDefinitionLabel'); - effects.enter('gfmFootnoteDefinitionLabelMarker'); - effects.consume(code); - effects.exit('gfmFootnoteDefinitionLabelMarker'); - return labelAtMarker; - } - function labelAtMarker(code) { - if (code === 94) { - effects.enter('gfmFootnoteDefinitionMarker'); - effects.consume(code); - effects.exit('gfmFootnoteDefinitionMarker'); - effects.enter('gfmFootnoteDefinitionLabelString'); - effects.enter('chunkString').contentType = 'string'; - return labelInside; - } - return nok(code); - } - function labelInside(code) { - if ( - size > 999 || - code === 93 && !data || - code === null || code === 91 || markdownLineEndingOrSpace(code)) { - return nok(code); - } - if (code === 93) { - effects.exit('chunkString'); - const token = effects.exit('gfmFootnoteDefinitionLabelString'); - identifier = normalizeIdentifier(self.sliceSerialize(token)); - effects.enter('gfmFootnoteDefinitionLabelMarker'); - effects.consume(code); - effects.exit('gfmFootnoteDefinitionLabelMarker'); - effects.exit('gfmFootnoteDefinitionLabel'); - return labelAfter; - } - if (!markdownLineEndingOrSpace(code)) { - data = true; - } - size++; - effects.consume(code); - return code === 92 ? labelEscape : labelInside; - } - function labelEscape(code) { - if (code === 91 || code === 92 || code === 93) { - effects.consume(code); - size++; - return labelInside; - } - return labelInside(code); - } - function labelAfter(code) { - if (code === 58) { - effects.enter('definitionMarker'); - effects.consume(code); - effects.exit('definitionMarker'); - if (!defined.includes(identifier)) { - defined.push(identifier); - } - return factorySpace(effects, whitespaceAfter, 'gfmFootnoteDefinitionWhitespace'); - } - return nok(code); - } - function whitespaceAfter(code) { - return ok(code); - } -} -function tokenizeDefinitionContinuation(effects, ok, nok) { - return effects.check(blankLine, ok, effects.attempt(indent, ok, nok)); -} -function gfmFootnoteDefinitionEnd(effects) { - effects.exit('gfmFootnoteDefinition'); -} -function tokenizeIndent(effects, ok, nok) { - const self = this; - return factorySpace(effects, afterPrefix, 'gfmFootnoteDefinitionIndent', 4 + 1); - function afterPrefix(code) { - const tail = self.events[self.events.length - 1]; - return tail && tail[1].type === 'gfmFootnoteDefinitionIndent' && tail[2].sliceSerialize(tail[1], true).length === 4 ? ok(code) : nok(code); - } -} - -function gfmStrikethrough(options) { - const options_ = options || {}; - let single = options_.singleTilde; - const tokenizer = { - name: 'strikethrough', - tokenize: tokenizeStrikethrough, - resolveAll: resolveAllStrikethrough - }; - if (single === null || single === undefined) { - single = true; - } - return { - text: { - [126]: tokenizer - }, - insideSpan: { - null: [tokenizer] - }, - attentionMarkers: { - null: [126] - } - }; - function resolveAllStrikethrough(events, context) { - let index = -1; - while (++index < events.length) { - if (events[index][0] === 'enter' && events[index][1].type === 'strikethroughSequenceTemporary' && events[index][1]._close) { - let open = index; - while (open--) { - if (events[open][0] === 'exit' && events[open][1].type === 'strikethroughSequenceTemporary' && events[open][1]._open && - events[index][1].end.offset - events[index][1].start.offset === events[open][1].end.offset - events[open][1].start.offset) { - events[index][1].type = 'strikethroughSequence'; - events[open][1].type = 'strikethroughSequence'; - const strikethrough = { - type: 'strikethrough', - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[index][1].end) - }; - const text = { - type: 'strikethroughText', - start: Object.assign({}, events[open][1].end), - end: Object.assign({}, events[index][1].start) - }; - const nextEvents = [['enter', strikethrough, context], ['enter', events[open][1], context], ['exit', events[open][1], context], ['enter', text, context]]; - const insideSpan = context.parser.constructs.insideSpan.null; - if (insideSpan) { - splice(nextEvents, nextEvents.length, 0, resolveAll(insideSpan, events.slice(open + 1, index), context)); - } - splice(nextEvents, nextEvents.length, 0, [['exit', text, context], ['enter', events[index][1], context], ['exit', events[index][1], context], ['exit', strikethrough, context]]); - splice(events, open - 1, index - open + 3, nextEvents); - index = open + nextEvents.length - 2; - break; - } - } - } - } - index = -1; - while (++index < events.length) { - if (events[index][1].type === 'strikethroughSequenceTemporary') { - events[index][1].type = "data"; - } - } - return events; - } - function tokenizeStrikethrough(effects, ok, nok) { - const previous = this.previous; - const events = this.events; - let size = 0; - return start; - function start(code) { - if (previous === 126 && events[events.length - 1][1].type !== "characterEscape") { - return nok(code); - } - effects.enter('strikethroughSequenceTemporary'); - return more(code); - } - function more(code) { - const before = classifyCharacter(previous); - if (code === 126) { - if (size > 1) return nok(code); - effects.consume(code); - size++; - return more; - } - if (size < 2 && !single) return nok(code); - const token = effects.exit('strikethroughSequenceTemporary'); - const after = classifyCharacter(code); - token._open = !after || after === 2 && Boolean(before); - token._close = !before || before === 2 && Boolean(after); - return ok(code); - } - } -} - -class EditMap { - constructor() { - this.map = []; - } - add(index, remove, add) { - addImplementation(this, index, remove, add); - } - consume(events) { - this.map.sort(function (a, b) { - return a[0] - b[0]; - }); - if (this.map.length === 0) { - return; - } - let index = this.map.length; - const vecs = []; - while (index > 0) { - index -= 1; - vecs.push(events.slice(this.map[index][0] + this.map[index][1]), this.map[index][2]); - events.length = this.map[index][0]; - } - vecs.push([...events]); - events.length = 0; - let slice = vecs.pop(); - while (slice) { - events.push(...slice); - slice = vecs.pop(); - } - this.map.length = 0; - } -} -function addImplementation(editMap, at, remove, add) { - let index = 0; - if (remove === 0 && add.length === 0) { - return; - } - while (index < editMap.map.length) { - if (editMap.map[index][0] === at) { - editMap.map[index][1] += remove; - editMap.map[index][2].push(...add); - return; - } - index += 1; - } - editMap.map.push([at, remove, add]); -} - -function gfmTableAlign(events, index) { - let inDelimiterRow = false; - const align = []; - while (index < events.length) { - const event = events[index]; - if (inDelimiterRow) { - if (event[0] === 'enter') { - if (event[1].type === 'tableContent') { - align.push(events[index + 1][1].type === 'tableDelimiterMarker' ? 'left' : 'none'); - } - } - else if (event[1].type === 'tableContent') { - if (events[index - 1][1].type === 'tableDelimiterMarker') { - const alignIndex = align.length - 1; - align[alignIndex] = align[alignIndex] === 'left' ? 'center' : 'right'; - } - } - else if (event[1].type === 'tableDelimiterRow') { - break; - } - } else if (event[0] === 'enter' && event[1].type === 'tableDelimiterRow') { - inDelimiterRow = true; - } - index += 1; - } - return align; -} - -function gfmTable() { - return { - flow: { - null: { - name: 'table', - tokenize: tokenizeTable, - resolveAll: resolveTable - } - } - }; -} -function tokenizeTable(effects, ok, nok) { - const self = this; - let size = 0; - let sizeB = 0; - let seen; - return start; - function start(code) { - let index = self.events.length - 1; - while (index > -1) { - const type = self.events[index][1].type; - if (type === "lineEnding" || - type === "linePrefix") index--;else break; - } - const tail = index > -1 ? self.events[index][1].type : null; - const next = tail === 'tableHead' || tail === 'tableRow' ? bodyRowStart : headRowBefore; - if (next === bodyRowStart && self.parser.lazy[self.now().line]) { - return nok(code); - } - return next(code); - } - function headRowBefore(code) { - effects.enter('tableHead'); - effects.enter('tableRow'); - return headRowStart(code); - } - function headRowStart(code) { - if (code === 124) { - return headRowBreak(code); - } - seen = true; - sizeB += 1; - return headRowBreak(code); - } - function headRowBreak(code) { - if (code === null) { - return nok(code); - } - if (markdownLineEnding(code)) { - if (sizeB > 1) { - sizeB = 0; - self.interrupt = true; - effects.exit('tableRow'); - effects.enter("lineEnding"); - effects.consume(code); - effects.exit("lineEnding"); - return headDelimiterStart; - } - return nok(code); - } - if (markdownSpace(code)) { - return factorySpace(effects, headRowBreak, "whitespace")(code); - } - sizeB += 1; - if (seen) { - seen = false; - size += 1; - } - if (code === 124) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - seen = true; - return headRowBreak; - } - effects.enter("data"); - return headRowData(code); - } - function headRowData(code) { - if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { - effects.exit("data"); - return headRowBreak(code); - } - effects.consume(code); - return code === 92 ? headRowEscape : headRowData; - } - function headRowEscape(code) { - if (code === 92 || code === 124) { - effects.consume(code); - return headRowData; - } - return headRowData(code); - } - function headDelimiterStart(code) { - self.interrupt = false; - if (self.parser.lazy[self.now().line]) { - return nok(code); - } - effects.enter('tableDelimiterRow'); - seen = false; - if (markdownSpace(code)) { - return factorySpace(effects, headDelimiterBefore, "linePrefix", self.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4)(code); - } - return headDelimiterBefore(code); - } - function headDelimiterBefore(code) { - if (code === 45 || code === 58) { - return headDelimiterValueBefore(code); - } - if (code === 124) { - seen = true; - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return headDelimiterCellBefore; - } - return headDelimiterNok(code); - } - function headDelimiterCellBefore(code) { - if (markdownSpace(code)) { - return factorySpace(effects, headDelimiterValueBefore, "whitespace")(code); - } - return headDelimiterValueBefore(code); - } - function headDelimiterValueBefore(code) { - if (code === 58) { - sizeB += 1; - seen = true; - effects.enter('tableDelimiterMarker'); - effects.consume(code); - effects.exit('tableDelimiterMarker'); - return headDelimiterLeftAlignmentAfter; - } - if (code === 45) { - sizeB += 1; - return headDelimiterLeftAlignmentAfter(code); - } - if (code === null || markdownLineEnding(code)) { - return headDelimiterCellAfter(code); - } - return headDelimiterNok(code); - } - function headDelimiterLeftAlignmentAfter(code) { - if (code === 45) { - effects.enter('tableDelimiterFiller'); - return headDelimiterFiller(code); - } - return headDelimiterNok(code); - } - function headDelimiterFiller(code) { - if (code === 45) { - effects.consume(code); - return headDelimiterFiller; - } - if (code === 58) { - seen = true; - effects.exit('tableDelimiterFiller'); - effects.enter('tableDelimiterMarker'); - effects.consume(code); - effects.exit('tableDelimiterMarker'); - return headDelimiterRightAlignmentAfter; - } - effects.exit('tableDelimiterFiller'); - return headDelimiterRightAlignmentAfter(code); - } - function headDelimiterRightAlignmentAfter(code) { - if (markdownSpace(code)) { - return factorySpace(effects, headDelimiterCellAfter, "whitespace")(code); - } - return headDelimiterCellAfter(code); - } - function headDelimiterCellAfter(code) { - if (code === 124) { - return headDelimiterBefore(code); - } - if (code === null || markdownLineEnding(code)) { - if (!seen || size !== sizeB) { - return headDelimiterNok(code); - } - effects.exit('tableDelimiterRow'); - effects.exit('tableHead'); - return ok(code); - } - return headDelimiterNok(code); - } - function headDelimiterNok(code) { - return nok(code); - } - function bodyRowStart(code) { - effects.enter('tableRow'); - return bodyRowBreak(code); - } - function bodyRowBreak(code) { - if (code === 124) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return bodyRowBreak; - } - if (code === null || markdownLineEnding(code)) { - effects.exit('tableRow'); - return ok(code); - } - if (markdownSpace(code)) { - return factorySpace(effects, bodyRowBreak, "whitespace")(code); - } - effects.enter("data"); - return bodyRowData(code); - } - function bodyRowData(code) { - if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { - effects.exit("data"); - return bodyRowBreak(code); - } - effects.consume(code); - return code === 92 ? bodyRowEscape : bodyRowData; - } - function bodyRowEscape(code) { - if (code === 92 || code === 124) { - effects.consume(code); - return bodyRowData; - } - return bodyRowData(code); - } -} -function resolveTable(events, context) { - let index = -1; - let inFirstCellAwaitingPipe = true; - let rowKind = 0; - let lastCell = [0, 0, 0, 0]; - let cell = [0, 0, 0, 0]; - let afterHeadAwaitingFirstBodyRow = false; - let lastTableEnd = 0; - let currentTable; - let currentBody; - let currentCell; - const map = new EditMap(); - while (++index < events.length) { - const event = events[index]; - const token = event[1]; - if (event[0] === 'enter') { - if (token.type === 'tableHead') { - afterHeadAwaitingFirstBodyRow = false; - if (lastTableEnd !== 0) { - flushTableEnd(map, context, lastTableEnd, currentTable, currentBody); - currentBody = undefined; - lastTableEnd = 0; - } - currentTable = { - type: 'table', - start: Object.assign({}, token.start), - end: Object.assign({}, token.end) - }; - map.add(index, 0, [['enter', currentTable, context]]); - } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') { - inFirstCellAwaitingPipe = true; - currentCell = undefined; - lastCell = [0, 0, 0, 0]; - cell = [0, index + 1, 0, 0]; - if (afterHeadAwaitingFirstBodyRow) { - afterHeadAwaitingFirstBodyRow = false; - currentBody = { - type: 'tableBody', - start: Object.assign({}, token.start), - end: Object.assign({}, token.end) - }; - map.add(index, 0, [['enter', currentBody, context]]); - } - rowKind = token.type === 'tableDelimiterRow' ? 2 : currentBody ? 3 : 1; - } - else if (rowKind && (token.type === "data" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) { - inFirstCellAwaitingPipe = false; - if (cell[2] === 0) { - if (lastCell[1] !== 0) { - cell[0] = cell[1]; - currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell); - lastCell = [0, 0, 0, 0]; - } - cell[2] = index; - } - } else if (token.type === 'tableCellDivider') { - if (inFirstCellAwaitingPipe) { - inFirstCellAwaitingPipe = false; - } else { - if (lastCell[1] !== 0) { - cell[0] = cell[1]; - currentCell = flushCell(map, context, lastCell, rowKind, undefined, currentCell); - } - lastCell = cell; - cell = [lastCell[1], index, 0, 0]; - } - } - } - else if (token.type === 'tableHead') { - afterHeadAwaitingFirstBodyRow = true; - lastTableEnd = index; - } else if (token.type === 'tableRow' || token.type === 'tableDelimiterRow') { - lastTableEnd = index; - if (lastCell[1] !== 0) { - cell[0] = cell[1]; - currentCell = flushCell(map, context, lastCell, rowKind, index, currentCell); - } else if (cell[1] !== 0) { - currentCell = flushCell(map, context, cell, rowKind, index, currentCell); - } - rowKind = 0; - } else if (rowKind && (token.type === "data" || token.type === 'tableDelimiterMarker' || token.type === 'tableDelimiterFiller')) { - cell[3] = index; - } - } - if (lastTableEnd !== 0) { - flushTableEnd(map, context, lastTableEnd, currentTable, currentBody); - } - map.consume(context.events); - index = -1; - while (++index < context.events.length) { - const event = context.events[index]; - if (event[0] === 'enter' && event[1].type === 'table') { - event[1]._align = gfmTableAlign(context.events, index); - } - } - return events; -} -function flushCell(map, context, range, rowKind, rowEnd, previousCell) { - const groupName = rowKind === 1 ? 'tableHeader' : rowKind === 2 ? 'tableDelimiter' : 'tableData'; - const valueName = 'tableContent'; - if (range[0] !== 0) { - previousCell.end = Object.assign({}, getPoint(context.events, range[0])); - map.add(range[0], 0, [['exit', previousCell, context]]); - } - const now = getPoint(context.events, range[1]); - previousCell = { - type: groupName, - start: Object.assign({}, now), - end: Object.assign({}, now) - }; - map.add(range[1], 0, [['enter', previousCell, context]]); - if (range[2] !== 0) { - const relatedStart = getPoint(context.events, range[2]); - const relatedEnd = getPoint(context.events, range[3]); - const valueToken = { - type: valueName, - start: Object.assign({}, relatedStart), - end: Object.assign({}, relatedEnd) - }; - map.add(range[2], 0, [['enter', valueToken, context]]); - if (rowKind !== 2) { - const start = context.events[range[2]]; - const end = context.events[range[3]]; - start[1].end = Object.assign({}, end[1].end); - start[1].type = "chunkText"; - start[1].contentType = "text"; - if (range[3] > range[2] + 1) { - const a = range[2] + 1; - const b = range[3] - range[2] - 1; - map.add(a, b, []); - } - } - map.add(range[3] + 1, 0, [['exit', valueToken, context]]); - } - if (rowEnd !== undefined) { - previousCell.end = Object.assign({}, getPoint(context.events, rowEnd)); - map.add(rowEnd, 0, [['exit', previousCell, context]]); - previousCell = undefined; - } - return previousCell; -} -function flushTableEnd(map, context, index, table, tableBody) { - const exits = []; - const related = getPoint(context.events, index); - if (tableBody) { - tableBody.end = Object.assign({}, related); - exits.push(['exit', tableBody, context]); - } - table.end = Object.assign({}, related); - exits.push(['exit', table, context]); - map.add(index + 1, 0, exits); -} -function getPoint(events, index) { - const event = events[index]; - const side = event[0] === 'enter' ? 'start' : 'end'; - return event[1][side]; -} - -const tasklistCheck = { - name: 'tasklistCheck', - tokenize: tokenizeTasklistCheck -}; -function gfmTaskListItem() { - return { - text: { - [91]: tasklistCheck - } - }; -} -function tokenizeTasklistCheck(effects, ok, nok) { - const self = this; - return open; - function open(code) { - if ( - self.previous !== null || - !self._gfmTasklistFirstContentOfListItem) { - return nok(code); - } - effects.enter('taskListCheck'); - effects.enter('taskListCheckMarker'); - effects.consume(code); - effects.exit('taskListCheckMarker'); - return inside; - } - function inside(code) { - if (markdownLineEndingOrSpace(code)) { - effects.enter('taskListCheckValueUnchecked'); - effects.consume(code); - effects.exit('taskListCheckValueUnchecked'); - return close; - } - if (code === 88 || code === 120) { - effects.enter('taskListCheckValueChecked'); - effects.consume(code); - effects.exit('taskListCheckValueChecked'); - return close; - } - return nok(code); - } - function close(code) { - if (code === 93) { - effects.enter('taskListCheckMarker'); - effects.consume(code); - effects.exit('taskListCheckMarker'); - effects.exit('taskListCheck'); - return after; - } - return nok(code); - } - function after(code) { - if (markdownLineEnding(code)) { - return ok(code); - } - if (markdownSpace(code)) { - return effects.check({ - tokenize: spaceThenNonSpace - }, ok, nok)(code); - } - return nok(code); - } -} -function spaceThenNonSpace(effects, ok, nok) { - return factorySpace(effects, after, "whitespace"); - function after(code) { - return code === null ? nok(code) : ok(code); - } -} - -function gfm(options) { - return combineExtensions([ - gfmAutolinkLiteral(), - gfmFootnote(), - gfmStrikethrough(options), - gfmTable(), - gfmTaskListItem() - ]) -} - -const emptyOptions$1 = {}; -function remarkGfm(options) { - const self = (this); - const settings = options || emptyOptions$1; - const data = self.data(); - const micromarkExtensions = - data.micromarkExtensions || (data.micromarkExtensions = []); - const fromMarkdownExtensions = - data.fromMarkdownExtensions || (data.fromMarkdownExtensions = []); - const toMarkdownExtensions = - data.toMarkdownExtensions || (data.toMarkdownExtensions = []); - micromarkExtensions.push(gfm(settings)); - fromMarkdownExtensions.push(gfmFromMarkdown()); - toMarkdownExtensions.push(gfmToMarkdown(settings)); -} - -const commentExpression = /\s*([a-zA-Z\d-]+)(\s+([\s\S]*))?\s*/; -const esCommentExpression = new RegExp( - '(\\s*\\/\\*' + commentExpression.source + '\\*\\/\\s*)' -); -const markerExpression = new RegExp( - '(\\s*\\s*)' -); -function commentMarker(value) { - if ( - isNode(value) && - (value.type === 'html' || - value.type === 'mdxFlowExpression' || - value.type === 'mdxTextExpression') - ) { - const match = value.value.match( - value.type === 'html' ? markerExpression : esCommentExpression - ); - if (match && match[0].length === value.value.length) { - const parameters = parseParameters(match[3] || ''); - if (parameters) { - return { - name: match[2], - attributes: (match[4] || '').trim(), - parameters, - node: value - } - } - } - } -} -function parseParameters(value) { - const parameters = {}; - return value - .replace( - /\s+([-\w]+)(?:=(?:"((?:\\[\s\S]|[^"])*)"|'((?:\\[\s\S]|[^'])*)'|((?:\\[\s\S]|[^"'\s])+)))?/gi, - replacer - ) - .replace(/\s+/g, '') - ? undefined - : parameters - function replacer(_, $1, $2, $3, $4) { - let value = $2 === undefined ? ($3 === undefined ? $4 : $3) : $2; - const number = Number(value); - if (value === 'true' || value === undefined) { - value = true; - } else if (value === 'false') { - value = false; - } else if (value.trim() && !Number.isNaN(number)) { - value = number; - } - parameters[$1] = value; - return '' - } -} -function isNode(value) { - return Boolean(value && typeof value === 'object' && 'type' in value) -} - -function parse(value) { - const input = String(value || '').trim(); - return input ? input.split(/[ \t\n\r\f]+/g) : [] -} - -function location(file) { - const value = String(file); - const indices = []; - return {toOffset, toPoint} - function toPoint(offset) { - if (typeof offset === 'number' && offset > -1 && offset <= value.length) { - let index = 0; - while (true) { - let end = indices[index]; - if (end === undefined) { - const eol = next(value, indices[index - 1]); - end = eol === -1 ? value.length + 1 : eol + 1; - indices[index] = end; - } - if (end > offset) { - return { - line: index + 1, - column: offset - (index > 0 ? indices[index - 1] : 0) + 1, - offset - } - } - index++; - } - } - } - function toOffset(point) { - if ( - point && - typeof point.line === 'number' && - typeof point.column === 'number' && - !Number.isNaN(point.line) && - !Number.isNaN(point.column) - ) { - while (indices.length < point.line) { - const from = indices[indices.length - 1]; - const eol = next(value, from); - const end = eol === -1 ? value.length + 1 : eol + 1; - if (from === end) break - indices.push(end); - } - const offset = - (point.line > 1 ? indices[point.line - 2] : 0) + point.column - 1; - if (offset < indices[point.line - 1]) return offset - } - } -} -function next(value, from) { - const cr = value.indexOf('\r', from); - const lf = value.indexOf('\n', from); - if (lf === -1) return cr - if (cr === -1 || cr + 1 === lf) return lf - return cr < lf ? cr : lf -} - -const own = {}.hasOwnProperty; -function messageControl(tree, options) { - if (!options || typeof options !== 'object') { - throw new Error('Expected `options`') - } - const {file, marker, name, test} = options; - let {enable, disable, known, reset, source} = options; - if (!enable) enable = []; - if (!disable) disable = []; - if (!file) { - throw new Error('Expected `file` in `options`') - } - if (!marker) { - throw new Error('Expected `marker` in `options`') - } - if (!name) { - throw new Error('Expected `name` in `options`') - } - const sources = typeof source === 'string' ? [source] : source || [name]; - const toOffset = location(file).toOffset; - const initial = !reset; - const gaps = detectGaps(tree); - const scope = {}; - const globals = []; - visit(tree, test, visitor); - file.messages = file.messages.filter(function (m) { - return filter(m) - }); - function visitor(node, position, parent) { - const point = node.position && node.position.start; - const mark = marker(node); - if (!point || !mark || mark.name !== name) { - return - } - const ruleIds = parse(mark.attributes); - const verb = ruleIds.shift(); - const fn = - verb === 'enable' - ? doEnable - : verb === 'disable' - ? doDisable - : verb === 'ignore' - ? doIgnore - : undefined; - if (!fn) { - file.fail( - 'Unknown keyword `' + - verb + - '`: expected ' + - "`'enable'`, `'disable'`, or `'ignore'`", - node - ); - } - const next = - (parent && position !== undefined && parent.children[position + 1]) || - undefined; - const tail = next && next.position && next.position.end; - if (ruleIds.length === 0) { - fn(point, undefined, tail); - } else { - let index = -1; - while (++index < ruleIds.length) { - const ruleId = ruleIds[index]; - if (isKnown(ruleId, verb, node)) { - fn(point, ruleId, tail); - } - } - } - } - function doIgnore(point, ruleId, tail) { - if (tail) { - toggle(point, false, ruleId); - toggle(tail, true, ruleId); - } - } - function doDisable(point, ruleId) { - toggle(point, false, ruleId); - if (!ruleId) reset = true; - } - function doEnable(point, ruleId) { - toggle(point, true, ruleId); - if (!ruleId) reset = false; - } - function filter(message) { - let gapIndex = gaps.length; - if (!message.source || !sources.includes(message.source)) { - return true - } - if (!message.line) message.line = 1; - if (!message.column) message.column = 1; - const offset = toOffset(message); - while (gapIndex--) { - if (gaps[gapIndex][0] <= offset && gaps[gapIndex][1] > offset) { - return false - } - } - return ( - (!message.ruleId || check(message, scope[message.ruleId], true)) && - check(message, globals, false) - ) - } - function isKnown(ruleId, verb, node) { - const result = known ? known.includes(ruleId) : true; - if (!result) { - file.message('Cannot ' + verb + " `'" + ruleId + "'`, it’s not known", { - ancestors: [node], - place: node.position, - ruleId: 'known', - source: 'unified-message-control' - }); - } - return result - } - function getState(ruleId) { - const ranges = ruleId ? scope[ruleId] : globals; - if (ranges && ranges.length > 0) { - return ranges[ranges.length - 1].state - } - return ruleId - ? reset - ? enable.includes(ruleId) - : !disable.includes(ruleId) - : !reset - } - function toggle(point, state, ruleId) { - const markers = ruleId ? scope[ruleId] || (scope[ruleId] = []) : globals; - const current = getState(ruleId); - if (current !== state) { - markers.push({state, point}); - } - if (!ruleId) { - for (ruleId in scope) { - if (own.call(scope, ruleId)) { - toggle(point, state, ruleId); - } - } - } - } - function check(message, marks, local) { - if (message.line && message.column && marks && marks.length > 0) { - let index = marks.length; - while (index--) { - const mark = marks[index]; - if ( - mark.point && - (mark.point.line < message.line || - (mark.point.line === message.line && - mark.point.column <= message.column)) - ) { - return mark.state === true - } - } - } - if (local) { - ok$1(message.ruleId); - return reset - ? enable.includes(message.ruleId) - : !disable.includes(message.ruleId) - } - return Boolean(initial || reset) - } -} -function detectGaps(tree) { - const end = - tree && tree.position && tree.position.end && tree.position.end.offset; - let offset = 0; - let gap = false; - const gaps = []; - visit(tree, one); - if (typeof end === 'number' && offset !== end) { - update(); - update(end); - } - return gaps - function one(node) { - update(node.position && node.position.start && node.position.start.offset); - if (!('children' in node)) { - update(node.position && node.position.end && node.position.end.offset); - } - } - function update(latest) { - if (latest === null || latest === undefined) { - gap = true; - } else if (offset < latest) { - if (gap) { - gaps.push([offset, latest]); - gap = false; - } - offset = latest; - } - } -} - -const test = [ - 'comment', - 'html', - 'mdxFlowExpression', - 'mdxTextExpression' -]; -function remarkMessageControl(options) { - return function (tree, file) { - messageControl(tree, {...options, file, marker: commentMarker, test}); - } -} - -function remarkLint() { - this.use(lintMessageControl); -} -function lintMessageControl() { - return remarkMessageControl({name: 'lint', source: 'remark-lint'}) -} - -function lintRule$1(meta, rule) { - const id = typeof meta === 'string' ? meta : meta.origin; - const url = typeof meta === 'string' ? undefined : meta.url; - const parts = id.split(':'); - const source = parts[1] ? parts[0] : undefined; - const ruleId = parts[1]; - Object.defineProperty(plugin, 'name', {value: id}); - return plugin - function plugin(config) { - const [severity, options] = coerce$1(ruleId, config); - const fatal = severity === 2; - if (!severity) return - return function (tree, file, next) { - let index = file.messages.length - 1; - wrap(rule, function (error) { - const messages = file.messages; - if (error && !messages.includes(error)) { - try { - file.fail(error); - } catch {} - } - while (++index < messages.length) { - Object.assign(messages[index], {fatal, ruleId, source, url}); - } - next(); - })(tree, file, options); - } - } -} -function coerce$1(name, config) { - if (!Array.isArray(config)) { - return [1, config] - } - const [severity, ...options] = config; - switch (severity) { - case false: - case 0: - case 'off': { - return [0, ...options] - } - case true: - case 1: - case 'on': - case 'warn': { - return [1, ...options] - } - case 2: - case 'error': { - return [2, ...options] - } - default: { - if (typeof severity !== 'number') { - return [1, config] - } - throw new Error( - 'Incorrect severity `' + - severity + - '` for `' + - name + - '`, ' + - 'expected 0, 1, or 2' - ) - } - } -} - -/** - * remark-lint rule to warn when a final line ending is missing. - * - * ## What is this? - * - * This package checks the final line ending. - * - * ## When should I use this? - * - * You can use this package to check final line endings. - * - * ## API - * - * ### `unified().use(remarkLintFinalNewline)` - * - * Warn when a final line ending is missing. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * Turn this rule on. - * See [StackExchange][] for more info. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/main/packages/remark-stringify) - * always adds final line endings. - * - * [api-remark-lint-final-newline]: #unifieduseremarklintfinalnewline - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * [stackexchange]: https://unix.stackexchange.com/questions/18743 - * - * ## Examples - * - * ##### `ok.md` - * - * ###### In - * - * ```markdown - * Mercury␊ - * ``` - * - * ###### Out - * - * No messages. - * - * ##### `not-ok.md` - * - * ###### In - * - * ```markdown - * Mercury␀ - * ``` - * - * ###### Out - * - * ```text - * 1:8: Unexpected missing final newline character, expected line feed (`\n`) at end of file - * ``` - * - * @module final-newline - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - */ -const remarkLintFinalNewline = lintRule$1( - { - origin: 'remark-lint:final-newline', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-final-newline#readme' - }, - function (_, file) { - const value = String(file); - const end = location(file).toPoint(value.length); - const last = value.length - 1; - if ( - last !== -1 && - value.charAt(last) !== '\n' - ) { - file.message( - 'Unexpected missing final newline character, expected line feed (`\\n`) at end of file', - end - ); - } - } -); - -const pointEnd = point('end'); -const pointStart = point('start'); -function point(type) { - return point - function point(node) { - const point = (node && node.position && node.position[type]) || {}; - if ( - typeof point.line === 'number' && - point.line > 0 && - typeof point.column === 'number' && - point.column > 0 - ) { - return { - line: point.line, - column: point.column, - offset: - typeof point.offset === 'number' && point.offset > -1 - ? point.offset - : undefined - } - } - } -} -function position(node) { - const start = pointStart(node); - const end = pointEnd(node); - if (start && end) { - return {start, end} - } -} - -/** - * remark-lint rule to warn when more spaces are used than needed - * for hard breaks. - * - * ## What is this? - * - * This package checks the whitespace of hard breaks. - * - * ## When should I use this? - * - * You can use this package to check that the number of spaces in hard breaks - * are consistent. - * - * ## API - * - * ### `unified().use(remarkLintHardBreakSpaces)` - * - * Warn when more spaces are used than needed for hard breaks. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * Less than two spaces do not create a hard breaks and more than two spaces - * have no effect. - * Due to this, it’s recommended to turn this rule on. - * - * [api-remark-lint-hard-break-spaces]: #unifieduseremarklinthardbreakspaces - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module hard-break-spaces - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @example - * {"name": "ok.md"} - * - * **Mercury** is the first planet from the Sun␠␠ - * and the smallest in the Solar System. - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * **Mercury** is the first planet from the Sun␠␠␠ - * and the smallest in the Solar System. - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 1:45-2:1: Unexpected `3` spaces for hard break, expected `2` spaces - * - * @example - * {"gfm": true, "label": "input", "name": "containers.md"} - * - * [^mercury]: - * > * > * **Mercury** is the first planet from the Sun␠␠␠ - * > > and the smallest in the Solar System. - * @example - * {"gfm": true, "label": "output", "name": "containers.md"} - * - * 2:57-3:1: Unexpected `3` spaces for hard break, expected `2` spaces - */ -const remarkLintHardBreakSpaces = lintRule$1( - { - origin: 'remark-lint:hard-break-spaces', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-hard-break-spaces#readme' - }, - function (tree, file) { - const value = String(file); - visit(tree, 'break', function (node) { - const end = pointEnd(node); - const start = pointStart(node); - if ( - end && - start && - typeof end.offset === 'number' && - typeof start.offset === 'number' - ) { - const slice = value.slice(start.offset, end.offset); - let actual = 0; - while (slice.charCodeAt(actual) === 32) actual++; - if (actual > 2) { - file.message( - 'Unexpected `' + - actual + - '` spaces for hard break, expected `2` spaces', - node - ); - } - } - }); - } -); - -function commonjsRequire(path) { - throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); -} - -var pluralize$2 = {exports: {}}; - -var pluralize$1 = pluralize$2.exports; -var hasRequiredPluralize; -function requirePluralize () { - if (hasRequiredPluralize) return pluralize$2.exports; - hasRequiredPluralize = 1; - (function (module, exports) { - (function (root, pluralize) { - if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { - module.exports = pluralize(); - } else { - root.pluralize = pluralize(); - } - })(pluralize$1, function () { - var pluralRules = []; - var singularRules = []; - var uncountables = {}; - var irregularPlurals = {}; - var irregularSingles = {}; - function sanitizeRule (rule) { - if (typeof rule === 'string') { - return new RegExp('^' + rule + '$', 'i'); - } - return rule; - } - function restoreCase (word, token) { - if (word === token) return token; - if (word === word.toLowerCase()) return token.toLowerCase(); - if (word === word.toUpperCase()) return token.toUpperCase(); - if (word[0] === word[0].toUpperCase()) { - return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase(); - } - return token.toLowerCase(); - } - function interpolate (str, args) { - return str.replace(/\$(\d{1,2})/g, function (match, index) { - return args[index] || ''; - }); - } - function replace (word, rule) { - return word.replace(rule[0], function (match, index) { - var result = interpolate(rule[1], arguments); - if (match === '') { - return restoreCase(word[index - 1], result); - } - return restoreCase(match, result); - }); - } - function sanitizeWord (token, word, rules) { - if (!token.length || uncountables.hasOwnProperty(token)) { - return word; - } - var len = rules.length; - while (len--) { - var rule = rules[len]; - if (rule[0].test(word)) return replace(word, rule); - } - return word; - } - function replaceWord (replaceMap, keepMap, rules) { - return function (word) { - var token = word.toLowerCase(); - if (keepMap.hasOwnProperty(token)) { - return restoreCase(word, token); - } - if (replaceMap.hasOwnProperty(token)) { - return restoreCase(word, replaceMap[token]); - } - return sanitizeWord(token, word, rules); - }; - } - function checkWord (replaceMap, keepMap, rules, bool) { - return function (word) { - var token = word.toLowerCase(); - if (keepMap.hasOwnProperty(token)) return true; - if (replaceMap.hasOwnProperty(token)) return false; - return sanitizeWord(token, token, rules) === token; - }; - } - function pluralize (word, count, inclusive) { - var pluralized = count === 1 - ? pluralize.singular(word) : pluralize.plural(word); - return (inclusive ? count + ' ' : '') + pluralized; - } - pluralize.plural = replaceWord( - irregularSingles, irregularPlurals, pluralRules - ); - pluralize.isPlural = checkWord( - irregularSingles, irregularPlurals, pluralRules - ); - pluralize.singular = replaceWord( - irregularPlurals, irregularSingles, singularRules - ); - pluralize.isSingular = checkWord( - irregularPlurals, irregularSingles, singularRules - ); - pluralize.addPluralRule = function (rule, replacement) { - pluralRules.push([sanitizeRule(rule), replacement]); - }; - pluralize.addSingularRule = function (rule, replacement) { - singularRules.push([sanitizeRule(rule), replacement]); - }; - pluralize.addUncountableRule = function (word) { - if (typeof word === 'string') { - uncountables[word.toLowerCase()] = true; - return; - } - pluralize.addPluralRule(word, '$0'); - pluralize.addSingularRule(word, '$0'); - }; - pluralize.addIrregularRule = function (single, plural) { - plural = plural.toLowerCase(); - single = single.toLowerCase(); - irregularSingles[single] = plural; - irregularPlurals[plural] = single; - }; - [ - ['I', 'we'], - ['me', 'us'], - ['he', 'they'], - ['she', 'they'], - ['them', 'them'], - ['myself', 'ourselves'], - ['yourself', 'yourselves'], - ['itself', 'themselves'], - ['herself', 'themselves'], - ['himself', 'themselves'], - ['themself', 'themselves'], - ['is', 'are'], - ['was', 'were'], - ['has', 'have'], - ['this', 'these'], - ['that', 'those'], - ['echo', 'echoes'], - ['dingo', 'dingoes'], - ['volcano', 'volcanoes'], - ['tornado', 'tornadoes'], - ['torpedo', 'torpedoes'], - ['genus', 'genera'], - ['viscus', 'viscera'], - ['stigma', 'stigmata'], - ['stoma', 'stomata'], - ['dogma', 'dogmata'], - ['lemma', 'lemmata'], - ['schema', 'schemata'], - ['anathema', 'anathemata'], - ['ox', 'oxen'], - ['axe', 'axes'], - ['die', 'dice'], - ['yes', 'yeses'], - ['foot', 'feet'], - ['eave', 'eaves'], - ['goose', 'geese'], - ['tooth', 'teeth'], - ['quiz', 'quizzes'], - ['human', 'humans'], - ['proof', 'proofs'], - ['carve', 'carves'], - ['valve', 'valves'], - ['looey', 'looies'], - ['thief', 'thieves'], - ['groove', 'grooves'], - ['pickaxe', 'pickaxes'], - ['passerby', 'passersby'] - ].forEach(function (rule) { - return pluralize.addIrregularRule(rule[0], rule[1]); - }); - [ - [/s?$/i, 's'], - [/[^\u0000-\u007F]$/i, '$0'], - [/([^aeiou]ese)$/i, '$1'], - [/(ax|test)is$/i, '$1es'], - [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'], - [/(e[mn]u)s?$/i, '$1s'], - [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'], - [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'], - [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'], - [/(seraph|cherub)(?:im)?$/i, '$1im'], - [/(her|at|gr)o$/i, '$1oes'], - [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'], - [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'], - [/sis$/i, 'ses'], - [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'], - [/([^aeiouy]|qu)y$/i, '$1ies'], - [/([^ch][ieo][ln])ey$/i, '$1ies'], - [/(x|ch|ss|sh|zz)$/i, '$1es'], - [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'], - [/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'], - [/(pe)(?:rson|ople)$/i, '$1ople'], - [/(child)(?:ren)?$/i, '$1ren'], - [/eaux$/i, '$0'], - [/m[ae]n$/i, 'men'], - ['thou', 'you'] - ].forEach(function (rule) { - return pluralize.addPluralRule(rule[0], rule[1]); - }); - [ - [/s$/i, ''], - [/(ss)$/i, '$1'], - [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'], - [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'], - [/ies$/i, 'y'], - [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'], - [/\b(mon|smil)ies$/i, '$1ey'], - [/\b((?:tit)?m|l)ice$/i, '$1ouse'], - [/(seraph|cherub)im$/i, '$1'], - [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'], - [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'], - [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'], - [/(test)(?:is|es)$/i, '$1is'], - [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'], - [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'], - [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'], - [/(alumn|alg|vertebr)ae$/i, '$1a'], - [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'], - [/(matr|append)ices$/i, '$1ix'], - [/(pe)(rson|ople)$/i, '$1rson'], - [/(child)ren$/i, '$1'], - [/(eau)x?$/i, '$1'], - [/men$/i, 'man'] - ].forEach(function (rule) { - return pluralize.addSingularRule(rule[0], rule[1]); - }); - [ - 'adulthood', - 'advice', - 'agenda', - 'aid', - 'aircraft', - 'alcohol', - 'ammo', - 'analytics', - 'anime', - 'athletics', - 'audio', - 'bison', - 'blood', - 'bream', - 'buffalo', - 'butter', - 'carp', - 'cash', - 'chassis', - 'chess', - 'clothing', - 'cod', - 'commerce', - 'cooperation', - 'corps', - 'debris', - 'diabetes', - 'digestion', - 'elk', - 'energy', - 'equipment', - 'excretion', - 'expertise', - 'firmware', - 'flounder', - 'fun', - 'gallows', - 'garbage', - 'graffiti', - 'hardware', - 'headquarters', - 'health', - 'herpes', - 'highjinks', - 'homework', - 'housework', - 'information', - 'jeans', - 'justice', - 'kudos', - 'labour', - 'literature', - 'machinery', - 'mackerel', - 'mail', - 'media', - 'mews', - 'moose', - 'music', - 'mud', - 'manga', - 'news', - 'only', - 'personnel', - 'pike', - 'plankton', - 'pliers', - 'police', - 'pollution', - 'premises', - 'rain', - 'research', - 'rice', - 'salmon', - 'scissors', - 'series', - 'sewage', - 'shambles', - 'shrimp', - 'software', - 'species', - 'staff', - 'swine', - 'tennis', - 'traffic', - 'transportation', - 'trout', - 'tuna', - 'wealth', - 'welfare', - 'whiting', - 'wildebeest', - 'wildlife', - 'you', - /pok[eé]mon$/i, - /[^aeiou]ese$/i, - /deer$/i, - /fish$/i, - /measles$/i, - /o[iu]s$/i, - /pox$/i, - /sheep$/i - ].forEach(pluralize.addUncountableRule); - return pluralize; - }); - } (pluralize$2)); - return pluralize$2.exports; -} - -var pluralizeExports = requirePluralize(); -var pluralize = /*@__PURE__*/getDefaultExportFromCjs(pluralizeExports); - -/** - * remark-lint rule to warn when list item markers are indented. - * - * ## What is this? - * - * This package checks indentation before list item markers. - * - * ## When should I use this? - * - * You can use this package to check that the style of list items is - * consistent. - * - * ## API - * - * ### `unified().use(remarkLintListItemBulletIndent)` - * - * Warn when list item markers are indented. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * There is no specific handling of indented list items in markdown. - * While it is possible to use an indent to align ordered lists on their marker: - * - * ```markdown - * 1. Mercury - * 10. Venus - * 100. Earth - * ``` - * - * …such a style is uncommon and hard to maintain as adding a 10th item - * means 9 other items have to change (more arduous while unlikely would be - * the 100th item). - * So it is recommended to not indent items and to turn this rule on. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats all items without - * indent. - * - * [api-remark-lint-list-item-bullet-indent]: #unifieduseremarklintlistitembulletindent - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module list-item-bullet-indent - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @example - * {"name": "ok.md"} - * - * Mercury. - * - * * Venus. - * * Earth. - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * Mercury. - * - * ␠* Venus. - * ␠* Earth. - * - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 3:2: Unexpected `1` space before list item, expected `0` spaces, remove them - * 4:2: Unexpected `1` space before list item, expected `0` spaces, remove them - */ -const remarkLintListItemBulletIndent = lintRule$1( - { - origin: 'remark-lint:list-item-bullet-indent', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-list-item-bullet-indent#readme' - }, - function (tree, file) { - const treeStart = pointStart(tree); - if (!tree || tree.type !== 'root' || !treeStart) return - for (const child of tree.children) { - if (child.type !== 'list') continue - const list = child; - for (const item of list.children) { - const place = pointStart(item); - if (!place) continue - const actual = place.column - treeStart.column; - if (actual) { - file.message( - 'Unexpected `' + - actual + - '` ' + - pluralize('space', actual) + - ' before list item, expected `0` spaces, remove them', - {ancestors: [tree, list, item], place} - ); - } - } - } - } -); - -/** - * remark-lint rule to warn when the whitespace after list item markers violate - * a given style. - * - * ## What is this? - * - * This package checks the style of whitespace after list item markers. - * - * ## When should I use this? - * - * You can use this package to check that the style of whitespace after list - * item markers and before content is consistent. - * - * ## API - * - * ### `unified().use(remarkLintListItemIndent[, options])` - * - * Warn when the whitespace after list item markers violate a given style. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'one'`) - * — preferred style - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * * `'mixed'` - * — prefer `'one'` for tight lists and `'tab'` for loose lists - * * `'one'` - * — prefer the size of the bullet and a single space - * * `'tab'` - * — prefer the size of the bullet and a single space to the next tab stop - * - * ###### Type - * - * ```ts - * type Options = 'mixed' | 'one' | 'tab' - * ``` - * - * ## Recommendation - * - * First some background. - * The number of spaces that occur after list markers (`*`, `-`, and `+` for - * unordered lists and `.` and `)` for unordered lists) and before the content - * on the first line, - * defines how much indentation can be used for further lines. - * At least one space is required and up to 4 spaces are allowed. - * If there is no further content after the marker then it’s a blank line which - * is handled as if there was one space. - * If there are 5 or more spaces and then content then it’s also seen as one - * space and the rest is seen as indented code. - * - * Regardless of ordered and unordered, - * there are two kinds of lists in markdown, - * tight and loose. - * Lists are tight by default but if there is a blank line between two list - * items or between two blocks inside an item, - * that turns the whole list into a loose list. - * When turning markdown into HTML, - * paragraphs in tight lists are not wrapped in `

` tags. - * - * How indentation of lists works in markdown has historically been a mess, - * especially with how they interact with indented code. - * CommonMark made that a *lot* better, - * but there remain (documented but complex) edge cases and some behavior - * intuitive. - * Due to this, `'tab'` works the best in most markdown parsers *and* in - * CommonMark. - * Currently the situation between markdown parsers is better, - * so the default `'one'`, - * which seems to be the most common style used by authors, - * is okay. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] uses `listItemIndent: 'one'` - * by default. - * `listItemIndent: 'mixed'` or `listItemIndent: 'tab'` is also supported. - * - * [api-options]: #options - * [api-remark-lint-list-item-indent]: #unifieduseremarklintlistitemindent-options - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module list-item-indent - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * *␠Mercury. - * *␠Venus. - * - * 111.␠Earth - * ␠␠␠␠␠and Mars. - * - * *␠**Jupiter**. - * - * ␠␠Jupiter is the fifth planet from the Sun and the largest in the Solar - * ␠␠System. - * - * *␠Saturn. - * - * ␠␠Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. - * - * @example - * {"config": "mixed", "name": "ok.md"} - * - * *␠Mercury. - * *␠Venus. - * - * 111.␠Earth - * ␠␠␠␠␠and Mars. - * - * *␠␠␠**Jupiter**. - * - * ␠␠␠␠Jupiter is the fifth planet from the Sun and the largest in the Solar - * ␠␠␠␠System. - * - * *␠␠␠Saturn. - * - * ␠␠␠␠Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. - * - * @example - * {"config": "mixed", "label": "input", "name": "not-ok.md"} - * - * *␠␠␠Mercury. - * *␠␠␠Venus. - * - * 111.␠␠␠␠Earth - * ␠␠␠␠␠␠␠␠and Mars. - * - * *␠**Jupiter**. - * - * ␠␠Jupiter is the fifth planet from the Sun and the largest in the Solar - * ␠␠System. - * - * *␠Saturn. - * - * ␠␠Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. - * @example - * {"config": "mixed", "label": "output", "name": "not-ok.md"} - * - * 1:5: Unexpected `3` spaces between list item marker and content in tight list, expected `1` space, remove `2` spaces - * 2:5: Unexpected `3` spaces between list item marker and content in tight list, expected `1` space, remove `2` spaces - * 4:9: Unexpected `4` spaces between list item marker and content in tight list, expected `1` space, remove `3` spaces - * 7:3: Unexpected `1` space between list item marker and content in loose list, expected `3` spaces, add `2` spaces - * 12:3: Unexpected `1` space between list item marker and content in loose list, expected `3` spaces, add `2` spaces - * - * @example - * {"config": "one", "name": "ok.md"} - * - * *␠Mercury. - * *␠Venus. - * - * 111.␠Earth - * ␠␠␠␠␠and Mars. - * - * *␠**Jupiter**. - * - * ␠␠Jupiter is the fifth planet from the Sun and the largest in the Solar - * ␠␠System. - * - * *␠Saturn. - * - * ␠␠Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. - * - * @example - * {"config": "one", "label": "input", "name": "not-ok.md"} - * - * *␠␠␠Mercury. - * *␠␠␠Venus. - * - * 111.␠␠␠␠Earth - * ␠␠␠␠␠␠␠␠and Mars. - * - * *␠␠␠**Jupiter**. - * - * ␠␠␠␠Jupiter is the fifth planet from the Sun and the largest in the Solar - * ␠␠␠␠System. - * - * *␠␠␠Saturn. - * - * ␠␠␠␠Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. - * @example - * {"config": "one", "label": "output", "name": "not-ok.md"} - * - * 1:5: Unexpected `3` spaces between list item marker and content, expected `1` space, remove `2` spaces - * 2:5: Unexpected `3` spaces between list item marker and content, expected `1` space, remove `2` spaces - * 4:9: Unexpected `4` spaces between list item marker and content, expected `1` space, remove `3` spaces - * 7:5: Unexpected `3` spaces between list item marker and content, expected `1` space, remove `2` spaces - * 12:5: Unexpected `3` spaces between list item marker and content, expected `1` space, remove `2` spaces - * - * @example - * {"config": "tab", "name": "ok.md"} - * - * *␠␠␠Mercury. - * *␠␠␠Venus. - * - * 111.␠␠␠␠Earth - * ␠␠␠␠␠␠␠␠and Mars. - * - * *␠␠␠**Jupiter**. - * - * ␠␠␠␠Jupiter is the fifth planet from the Sun and the largest in the Solar - * ␠␠␠␠System. - * - * *␠␠␠Saturn. - * - * ␠␠␠␠Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. - * - * @example - * {"config": "tab", "label": "input", "name": "not-ok.md"} - * - * *␠Mercury. - * *␠Venus. - * - * 111.␠Earth - * ␠␠␠␠␠and Mars. - * - * *␠**Jupiter**. - * - * ␠␠Jupiter is the fifth planet from the Sun and the largest in the Solar - * ␠␠System. - * - * *␠Saturn. - * - * ␠␠Saturn is the sixth planet from the Sun and the second-largest in the Solar System, after Jupiter. - * @example - * {"config": "tab", "label": "output", "name": "not-ok.md"} - * - * 1:3: Unexpected `1` space between list item marker and content, expected `3` spaces, add `2` spaces - * 2:3: Unexpected `1` space between list item marker and content, expected `3` spaces, add `2` spaces - * 4:6: Unexpected `1` space between list item marker and content, expected `4` spaces, add `3` spaces - * 7:3: Unexpected `1` space between list item marker and content, expected `3` spaces, add `2` spaces - * 12:3: Unexpected `1` space between list item marker and content, expected `3` spaces, add `2` spaces - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected `'mixed'`, `'one'`, or `'tab'` - * - * @example - * {"config": "mixed", "gfm": true, "label": "input", "name": "gfm.md"} - * - * *␠[x] Mercury. - * - * 1.␠␠[ ] Venus. - * - * 2.␠␠[ ] Earth. - * - * @example - * {"config": "one", "gfm": true, "name": "gfm.md"} - * - * *␠[x] Mercury. - * - * 1.␠[ ] Venus. - * - * 2.␠[ ] Earth. - * - * @example - * {"config": "tab", "gfm": true, "name": "gfm.md"} - * - * *␠␠␠[x] Mercury. - * - * 1.␠␠[ ] Venus. - * - * 2.␠␠[ ] Earth. - * - * @example - * {"config": "mixed", "name": "loose-tight.md"} - * - * Loose lists have blank lines between items: - * - * *␠␠␠Mercury. - * - * *␠␠␠Venus. - * - * …or between children of items: - * - * 1.␠␠Earth. - * - * ␠␠␠␠Earth is the third planet from the Sun and the only astronomical - * ␠␠␠␠object known to harbor life. - */ -const remarkLintListItemIndent = lintRule$1( - { - origin: 'remark-lint:list-item-indent', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-list-item-indent#readme' - }, - function (tree, file, options) { - const value = String(file); - let expected; - if (options === null || options === undefined) { - expected = 'one'; - } else if (options === 'space') { - file.fail( - 'Unexpected value `' + options + "` for `options`, expected `'one'`" - ); - } else if (options === 'tab-size') { - file.fail( - 'Unexpected value `' + options + "` for `options`, expected `'tab'`" - ); - } else if (options === 'mixed' || options === 'one' || options === 'tab') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected `'mixed'`, `'one'`, or `'tab'`" - ); - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'list') return - let loose = node.spread; - if (!loose) { - for (const child of node.children) { - if (child.spread) { - loose = true; - break - } - } - } - for (const child of node.children) { - const head = child.children[0]; - const itemStart = pointStart(child); - const headStart = pointStart(head); - if ( - itemStart && - headStart && - typeof itemStart.offset === 'number' && - typeof headStart.offset === 'number' - ) { - let slice = value.slice(itemStart.offset, headStart.offset); - const checkboxIndex = slice.indexOf('['); - if (checkboxIndex !== -1) slice = slice.slice(0, checkboxIndex); - const actualIndent = slice.length; - let end = actualIndent; - let previous = slice.charCodeAt(end - 1); - while (previous === 9 || previous === 32) { - end--; - previous = slice.charCodeAt(end - 1); - } - let expectedIndent = end + 1; - if (expected === 'tab' || (expected === 'mixed' && loose)) { - expectedIndent = Math.ceil(expectedIndent / 4) * 4; - } - const expectedSpaces = expectedIndent - end; - const actualSpaces = actualIndent - end; - if (actualSpaces !== expectedSpaces) { - const difference = expectedSpaces - actualSpaces; - const differenceAbsolute = Math.abs(difference); - file.message( - 'Unexpected `' + - actualSpaces + - '` ' + - pluralize('space', actualSpaces) + - ' between list item marker and content' + - (expected === 'mixed' - ? ' in ' + (loose ? 'loose' : 'tight') + ' list' - : '') + - ', expected `' + - expectedSpaces + - '` ' + - pluralize('space', expectedSpaces) + - ', ' + - (difference > 0 ? 'add' : 'remove') + - ' `' + - differenceAbsolute + - '` ' + - pluralize('space', differenceAbsolute), - {ancestors: [...parents, node, child], place: headStart} - ); - } - } - } - }); - } -); - -/** - * remark-lint rule to warn for lazy lines in block quotes. - * - * ## What is this? - * - * This package checks the style of block quotes. - * - * ## When should I use this? - * - * You can use this package to check that the style of block quotes is - * consistent. - * - * ## API - * - * ### `unified().use(remarkLintNoBlockquoteWithoutMarker)` - * - * Warn for lazy lines in block quotes. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * Rules around lazy lines are not straightforward and visually confusing, - * so it’s recommended to start each line with a `>`. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] adds `>` markers to every line - * in a block quote. - * - * [api-remark-lint-no-blockquote-without-marker]: #unifieduseremarklintnoblockquotewithoutmarker - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-blockquote-without-marker - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @example - * {"name": "ok.md"} - * - * > Mercury, - * > Venus, - * > and Earth. - * - * Mars. - * - * @example - * {"name": "ok-tabs.md"} - * - * >␉Mercury, - * >␉Venus, - * >␉and Earth. - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * > Mercury, - * Venus, - * > and Earth. - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 2:1: Unexpected `0` block quote markers before paragraph line, expected `1` marker, add `1` marker - * - * @example - * {"label": "input", "name": "not-ok-tabs.md"} - * - * >␉Mercury, - * ␉Venus, - * and Earth. - * @example - * {"label": "output", "name": "not-ok-tabs.md"} - * - * 2:2: Unexpected `0` block quote markers before paragraph line, expected `1` marker, add `1` marker - * 3:1: Unexpected `0` block quote markers before paragraph line, expected `1` marker, add `1` marker - * - * @example - * {"label": "input", "name": "containers.md"} - * - * * > Mercury and - * Venus. - * - * > * Mercury and - * Venus. - * - * * > * Mercury and - * Venus. - * - * > * > Mercury and - * Venus. - * - * *** - * - * > * > Mercury and - * > Venus. - * @example - * {"label": "output", "name": "containers.md"} - * - * 2:1: Unexpected `0` block quote markers before paragraph line, expected `1` marker, add `1` marker - * 5:3: Unexpected `0` block quote markers before paragraph line, expected `1` marker, add `1` marker - * 8:5: Unexpected `0` block quote markers before paragraph line, expected `1` marker, add `1` marker - * 11:7: Unexpected `0` block quote markers before paragraph line, expected `2` markers, add `2` markers - * 16:7: Unexpected `1` block quote marker before paragraph line, expected `2` markers, add `1` marker - */ -const remarkLintNoBlockquoteWithoutMarker = lintRule$1( - { - origin: 'remark-lint:no-blockquote-without-marker', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-blockquote-without-marker#readme' - }, - function (tree, file) { - const value = String(file); - const loc = location(file); - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'paragraph') return - let expected = 0; - for (const parent of parents) { - if (parent.type === 'blockquote') { - expected++; - } - else if ( - parent.type === 'containerDirective' || - parent.type === 'footnoteDefinition' || - parent.type === 'list' || - parent.type === 'listItem' || - parent.type === 'root' - ) ; else { - return SKIP - } - } - if (!expected) return SKIP - const end = pointEnd(node); - const start = pointStart(node); - if (!end || !start) return SKIP - let line = start.line; - while (++line <= end.line) { - const lineStart = loc.toOffset({line, column: 1}); - let actual = 0; - let index = lineStart; - while (index < value.length) { - const code = value.charCodeAt(index); - if (code === 9 || code === 32) ; else if (code === 62 ) { - actual++; - } else { - break - } - index++; - } - const point = loc.toPoint(index); - const difference = expected - actual; - if (difference) { - file.message( - 'Unexpected `' + - actual + - '` block quote ' + - pluralize('marker', actual) + - ' before paragraph line, expected `' + - expected + - '` ' + - pluralize('marker', expected) + - ', add `' + - difference + - '` ' + - pluralize('marker', difference), - {ancestors: [...parents, node], place: point} - ); - } - } - }); - } -); - -/** - * remark-lint rule to warn when identifiers are defined multiple times. - * - * ## What is this? - * - * This package checks that defined identifiers are unique. - * - * ## When should I use this? - * - * You can use this package to check that definitions are useful. - * - * ## API - * - * ### `unified().use(remarkLintNoDuplicateDefinitions)` - * - * Warn when identifiers are defined multiple times. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * It’s a mistake when the same identifier is defined multiple times. - * - * [api-remark-lint-no-duplicate-definitions]: #unifieduseremarklintnoduplicatedefinitions - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-duplicate-definitions - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * [mercury]: https://example.com/mercury/ - * [venus]: https://example.com/venus/ - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * [mercury]: https://example.com/mercury/ - * [mercury]: https://example.com/venus/ - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 2:1-2:38: Unexpected definition with an already defined identifier (`mercury`), expected unique identifiers - * - * @example - * {"gfm": true, "label": "input", "name": "gfm.md"} - * - * Mercury[^mercury]. - * - * [^mercury]: - * Mercury is the first planet from the Sun and the smallest in the Solar - * System. - * - * [^mercury]: - * Venus is the second planet from the Sun. - * - * @example - * {"gfm": true, "label": "output", "name": "gfm.md"} - * - * 7:1-7:12: Unexpected footnote definition with an already defined identifier (`mercury`), expected unique identifiers - */ -const empty = []; -const remarkLintNoDuplicateDefinitions = lintRule$1( - { - origin: 'remark-lint:no-duplicate-definitions', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-duplicate-definitions#readme' - }, - function (tree, file) { - const definitions = new Map(); - const footnoteDefinitions = new Map(); - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - const [map, identifier] = - node.type === 'definition' - ? [definitions, node.identifier] - : node.type === 'footnoteDefinition' - ? [footnoteDefinitions, node.identifier] - : empty; - if (map && identifier && node.position) { - const ancestors = [...parents, node]; - const duplicateAncestors = map.get(identifier); - if (duplicateAncestors) { - const duplicate = duplicateAncestors.at(-1); - file.message( - 'Unexpected ' + - (node.type === 'footnoteDefinition' ? 'footnote ' : '') + - 'definition with an already defined identifier (`' + - identifier + - '`), expected unique identifiers', - { - ancestors, - cause: new VFileMessage('Identifier already defined here', { - ancestors: duplicateAncestors, - place: duplicate.position, - source: 'remark-lint', - ruleId: 'no-duplicate-definitions' - }), - place: node.position - } - ); - } - map.set(identifier, ancestors); - } - }); - } -); - -/** - * remark-lint rule to warn when extra whitespace is used between hashes and - * content in headings. - * - * ## What is this? - * - * This package checks whitespace between hashes and content. - * - * ## When should I use this? - * - * You can use this package to check that headings are consistent. - * - * ## API - * - * ### `unified().use(remarkLintNoHeadingContentIndent)` - * - * Warn when extra whitespace is used between hashes and content in headings. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * One space is required and more than one space has no effect. - * Due to this, it’s recommended to turn this rule on. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats headings with one space. - * - * [api-remark-lint-no-heading-content-indent]: #unifieduseremarklintnoheadingcontentindent - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-heading-content-indent - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * #␠Mercury - * - * ##␠Venus␠## - * - * ␠␠##␠Earth - * - * Setext headings are not affected: - * - * ␠Mars - * ===== - * - * ␠Jupiter - * -------- - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * #␠␠Mercury - * - * ##␠Venus␠␠## - * - * ␠␠##␠␠␠Earth - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 1:4: Unexpected `2` spaces between hashes and content, expected `1` space, remove `1` space - * 3:11: Unexpected `2` spaces between content and hashes, expected `1` space, remove `1` space - * 5:8: Unexpected `3` spaces between hashes and content, expected `1` space, remove `2` spaces - * - * @example - * {"label": "input", "name": "empty-heading.md"} - * - * #␠␠ - * @example - * {"label": "output", "name": "empty-heading.md"} - * - * 1:4: Unexpected `2` spaces between hashes and content, expected `1` space, remove `1` space - */ -const remarkLintNoHeadingContentIndent = lintRule$1( - { - origin: 'remark-lint:no-heading-content-indent', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-heading-content-indent#readme' - }, - function (tree, file) { - const value = String(file); - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'heading') return - const start = pointStart(node); - const end = pointEnd(node); - if ( - !end || - !start || - typeof end.offset !== 'number' || - typeof start.offset !== 'number' - ) { - return - } - let index = start.offset; - let code = value.charCodeAt(index); - let found = false; - while (value.charCodeAt(index) === 35 ) { - index++; - found = true; - continue - } - const from = index; - code = value.charCodeAt(index); - while (code === 9 || code === 32 ) { - code = value.charCodeAt(++index); - continue - } - const size = index - from; - if (found && size > 1) { - file.message( - 'Unexpected `' + - size + - '` ' + - pluralize('space', size) + - ' between hashes and content, expected `1` space, remove `' + - (size - 1) + - '` ' + - pluralize('space', size - 1), - { - ancestors: [...parents, node], - place: { - line: start.line, - column: start.column + (index - start.offset), - offset: start.offset + (index - start.offset) - } - } - ); - } - const contentStart = index; - index = end.offset; - code = value.charCodeAt(index - 1); - while (code === 9 || code === 32 ) { - index--; - code = value.charCodeAt(index - 1); - continue - } - let endFound = false; - while (value.charCodeAt(index - 1) === 35 ) { - index--; - endFound = true; - continue - } - const endFrom = index; - code = value.charCodeAt(index - 1); - while (code === 9 || code === 32 ) { - index--; - code = value.charCodeAt(index - 1); - continue - } - const endSize = endFrom - index; - if (endFound && index > contentStart && endSize > 1) { - file.message( - 'Unexpected `' + - endSize + - '` ' + - pluralize('space', endSize) + - ' between content and hashes, expected `1` space, remove `' + - (endSize - 1) + - '` ' + - pluralize('space', endSize - 1), - { - ancestors: [...parents, node], - place: { - line: end.line, - column: end.column - (end.offset - endFrom), - offset: end.offset - (end.offset - endFrom) - } - } - ); - } - }); - } -); - -/** - * remark-lint rule to warn when GFM autolink literals are used. - * - * ## What is this? - * - * This package checks that regular autolinks or full links are used. - * Literal autolinks is a GFM feature enabled with - * [`remark-gfm`][github-remark-gfm]. - * - * ## When should I use this? - * - * You can use this package to check that links are consistent. - * - * ## API - * - * ### `unified().use(remarkLintNoLiteralUrls)` - * - * Warn when GFM autolink literals are used. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * GFM autolink literals (just a raw URL) are a feature enabled by GFM. - * They don’t work everywhere. - * So, - * it’s recommended to instead use regular autolinks (``) or full - * links (`[text](url)`). - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] never generates GFM autolink - * literals. - * It always generates regular autolinks or full links. - * - * [api-remark-lint-no-literal-urls]: #unifieduseremarklintnoliteralurls - * [github-remark-gfm]: https://github.com/remarkjs/remark-gfm - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-literal-urls - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md", "gfm": true} - * - * - * - * ![Venus](http://example.com/venus/). - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * https://example.com/mercury/ - * - * www.example.com/venus/ - * - * earth@mars.planets - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 1:1-1:29: Unexpected GFM autolink literal, expected regular autolink, add `<` before and `>` after - * 3:1-3:23: Unexpected GFM autolink literal, expected regular autolink, add `` after - * 5:1-5:19: Unexpected GFM autolink literal, expected regular autolink, add `` after - */ -const defaultHttp = 'http://'; -const defaultMailto = 'mailto:'; -const remarkLintNoLiteralUrls = lintRule$1( - { - origin: 'remark-lint:no-literal-urls', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-literal-urls#readme' - }, - function (tree, file) { - const value = String(file); - visitParents(tree, 'link', function (node, parents) { - const start = pointStart(node); - if (!start || typeof start.offset !== 'number') return - const raw = toString(node); - let protocol; - let otherwiseFine = false; - if (raw === node.url) { - otherwiseFine = true; - } else if (defaultHttp + raw === node.url) { - protocol = defaultHttp; - } else if (defaultMailto + raw === node.url) { - protocol = defaultMailto; - } - if ( - (protocol || otherwiseFine) && - !asciiPunctuation(value.charCodeAt(start.offset)) - ) { - file.message( - 'Unexpected GFM autolink literal, expected regular autolink, add ' + - (protocol ? '`<' + protocol + '`' : '`<`') + - ' before and `>` after', - {ancestors: [...parents, node], place: node.position} - ); - } - }); - } -); - -/** - * remark-lint rule to warn when shortcut reference images are used. - * - * ## What is this? - * - * This package checks that collapsed or full reference images are used. - * - * ## When should I use this? - * - * You can use this package to check that references are consistent. - * - * ## API - * - * ### `unified().use(remarkLintNoShortcutReferenceImage)` - * - * Warn when shortcut reference images are used. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * Shortcut references use an implicit style that looks a lot like something - * that could occur as plain text instead of syntax. - * In some cases, - * plain text is intended instead of an image. - * So it’s recommended to use collapsed or full references instead. - * - * [api-remark-lint-no-shortcut-reference-image]: #unifieduseremarklintnoshortcutreferenceimage - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-shortcut-reference-image - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * ![Mercury][] - * - * [mercury]: /mercury.png - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * ![Mercury] - * - * [mercury]: /mercury.png - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 1:1-1:11: Unexpected shortcut reference image (`![text]`), expected collapsed reference (`![text][]`) - */ -const remarkLintNoShortcutReferenceImage = lintRule$1( - { - origin: 'remark-lint:no-shortcut-reference-image', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-shortcut-reference-image#readme' - }, - function (tree, file) { - visitParents(tree, 'imageReference', function (node, parents) { - if (node.position && node.referenceType === 'shortcut') { - file.message( - 'Unexpected shortcut reference image (`![text]`), expected collapsed reference (`![text][]`)', - {ancestors: [...parents, node], place: node.position} - ); - } - }); - } -); - -/** - * remark-lint rule to warn when shortcut reference links are used. - * - * ## What is this? - * - * This package checks that collapsed or full reference links are used. - * - * ## When should I use this? - * - * You can use this package to check that references are consistent. - * - * ## API - * - * ### `unified().use(remarkLintNoShortcutReferenceLink)` - * - * Warn when shortcut reference links are used. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * Shortcut references use an implicit style that looks a lot like something - * that could occur as plain text instead of syntax. - * In some cases, - * plain text is intended instead of a link. - * So it’s recommended to use collapsed or full references instead. - * - * [api-remark-lint-no-shortcut-reference-link]: #unifieduseremarklintnoshortcutreferencelink - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-shortcut-reference-link - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * [Mercury][] - * - * [mercury]: http://example.com/mercury/ - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * [Mercury] - * - * [mercury]: http://example.com/mercury/ - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 1:1-1:10: Unexpected shortcut reference link (`[text]`), expected collapsed reference (`[text][]`) - */ -const remarkLintNoShortcutReferenceLink = lintRule$1( - { - origin: 'remark-lint:no-shortcut-reference-link', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-shortcut-reference-link#readme' - }, - function (tree, file) { - visitParents(tree, 'linkReference', function (node, parents) { - if (node.position && node.referenceType === 'shortcut') { - file.message( - 'Unexpected shortcut reference link (`[text]`), expected collapsed reference (`[text][]`)', - {ancestors: [...parents, node], place: node.position} - ); - } - }); - } -); - -const js = /\s+/g; -const html = /[\t\n\v\f\r ]+/g; -function collapseWhiteSpace(value, options) { - if (!options) { - options = {}; - } else if (typeof options === 'string') { - options = {style: options}; - } - const replace = options.preserveLineEndings ? replaceLineEnding : replaceSpace; - return String(value).replace( - options.style === 'html' ? html : js, - options.trim ? trimFactory(replace) : replace - ) -} -function replaceLineEnding(value) { - const match = /\r?\n|\r/.exec(value); - return match ? match[0] : ' ' -} -function replaceSpace() { - return ' ' -} -function trimFactory(replace) { - return dropOrReplace - function dropOrReplace(value, index, all) { - return index === 0 || index + value.length === all.length - ? '' - : replace(value) - } -} - -/** - * remark-lint rule to warn when undefined definitions are referenced. - * - * ## What is this? - * - * This package checks that referenced definitions are defined. - * - * ## When should I use this? - * - * You can use this package to check for broken references. - * - * ## API - * - * ### `unified().use(remarkLintNoUndefinedReferences[, options])` - * - * Warn when undefined definitions are referenced. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], optional) - * — configuration - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Fields - * - * * `allow` (`Array`, optional) - * — list of values to allow between `[` and `]` - * * `allowShortcutLink` (`boolean`, default: `false`) - * — allow shortcut references, which are just brackets such as `[text]` - * - * ## Recommendation - * - * Shortcut references use an implicit syntax that could also occur as plain - * text. - * To illustrate, - * it is reasonable to expect an author adding `[…]` to abbreviate some text - * somewhere in a document: - * - * ```markdown - * > Some […] quote. - * ``` - * - * This isn’t a problem, - * but it might become one when an author later adds a definition: - * - * ```markdown - * Some new text […][]. - * - * […]: #read-more - * ``` - * - * The second author might expect only their newly added text to form a link, - * but their changes also result in a link for the text by the first author. - * - * [api-options]: #options - * [api-remark-lint-no-undefined-references]: #unifieduseremarklintnoundefinedreferences-options - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-undefined-references - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * [Mercury][] is the first planet from the Sun and the smallest in the Solar - * System. - * - * Venus is the second planet from the [Sun. - * - * Earth is the third planet from the \[Sun] and the only astronomical object - * known to harbor life\. - * - * Mars is the fourth planet from the Sun: []. - * - * [mercury]: https://example.com/mercury/ - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * [Mercury] is the first planet from the Sun and the smallest in the Solar - * System. - * - * [Venus][] is the second planet from the Sun. - * - * [Earth][earth] is the third planet from the Sun and the only astronomical - * object known to harbor life. - * - * ![Mars] is the fourth planet from the Sun in the [Solar - * System]. - * - * > Jupiter is the fifth planet from the Sun and the largest in the [Solar - * > System][]. - * - * [Saturn][ is the sixth planet from the Sun and the second-largest - * in the Solar System, after Jupiter. - * - * [*Uranus*][] is the seventh planet from the Sun. - * - * [Neptune][neptune][more] is the eighth and farthest planet from the Sun. - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 1:1-1:10: Unexpected reference to undefined definition, expected corresponding definition (`mercury`) for a link or escaped opening bracket (`\[`) for regular text - * 4:1-4:10: Unexpected reference to undefined definition, expected corresponding definition (`venus`) for a link or escaped opening bracket (`\[`) for regular text - * 6:1-6:15: Unexpected reference to undefined definition, expected corresponding definition (`earth`) for a link or escaped opening bracket (`\[`) for regular text - * 9:2-9:8: Unexpected reference to undefined definition, expected corresponding definition (`mars`) for an image or escaped opening bracket (`\[`) for regular text - * 9:50-10:8: Unexpected reference to undefined definition, expected corresponding definition (`solar system`) for a link or escaped opening bracket (`\[`) for regular text - * 12:67-13:12: Unexpected reference to undefined definition, expected corresponding definition (`solar > system`) for a link or escaped opening bracket (`\[`) for regular text - * 15:1-15:9: Unexpected reference to undefined definition, expected corresponding definition (`saturn`) for a link or escaped opening bracket (`\[`) for regular text - * 18:1-18:13: Unexpected reference to undefined definition, expected corresponding definition (`*uranus*`) for a link or escaped opening bracket (`\[`) for regular text - * 20:1-20:19: Unexpected reference to undefined definition, expected corresponding definition (`neptune`) for a link or escaped opening bracket (`\[`) for regular text - * 20:19-20:25: Unexpected reference to undefined definition, expected corresponding definition (`more`) for a link or escaped opening bracket (`\[`) for regular text - * - * @example - * {"config": {"allow": ["…"]}, "name": "ok-allow.md"} - * - * Mercury is the first planet from the Sun and the smallest in the Solar - * System. […] - * - * @example - * {"config": {"allow": [{"source": "^mer"}, "venus"]}, "name": "source.md"} - * - * [Mercury][] is the first planet from the Sun and the smallest in the Solar - * System. - * - * [Venus][] is the second planet from the Sun. - * - * @example - * {"gfm": true, "label": "input", "name": "gfm.md"} - * - * Mercury[^mercury] is the first planet from the Sun and the smallest in the - * Solar System. - * - * [^venus]: - * **Venus** is the second planet from the Sun. - * @example - * {"gfm": true, "label": "output", "name": "gfm.md"} - * - * 1:8-1:18: Unexpected reference to undefined definition, expected corresponding definition (`mercury`) for a footnote or escaped opening bracket (`\[`) for regular text - * - * @example - * {"config": {"allowShortcutLink": true}, "label": "input", "name": "allow-shortcut-link.md"} - * - * [Mercury] is the first planet from the Sun and the smallest in the Solar - * System. - * - * [Venus][] is the second planet from the Sun. - * - * [Earth][earth] is the third planet from the Sun and the only astronomical object - * known to harbor life. - * @example - * {"config": {"allowShortcutLink": true}, "label": "output", "name": "allow-shortcut-link.md"} - * - * 4:1-4:10: Unexpected reference to undefined definition, expected corresponding definition (`venus`) for a link or escaped opening bracket (`\[`) for regular text - * 6:1-6:15: Unexpected reference to undefined definition, expected corresponding definition (`earth`) for a link or escaped opening bracket (`\[`) for regular text - */ -const emptyOptions = {}; -const emptyAllow = []; -const lineEndingExpression = /(\r?\n|\r)[\t ]*(>[\t ]*)*/g; -const remarkLintNoUndefinedReferences = lintRule$1( - { - origin: 'remark-lint:no-undefined-references', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-undefined-references#readme' - }, - function (tree, file, options) { - const settings = options || emptyOptions; - const allow = settings.allow || emptyAllow; - const allowShortcutLink = settings.allowShortcutLink || false; - const value = String(file); - const toPoint = location(file).toPoint; - const definitionIdentifiers = new Set(); - const footnoteDefinitionIdentifiers = new Set(); - const regexes = []; - const strings = new Set(); - const phrasingStacks = []; - let index = -1; - while (++index < allow.length) { - const value = allow[index]; - if (typeof value === 'string') { - strings.add(normalizeIdentifier(value)); - } else if (typeof value === 'object' && 'source' in value) { - regexes.push(new RegExp(value.source, value.flags ?? 'i')); - } - } - visitParents(tree, function (node, parents) { - if (node.type === 'definition') { - definitionIdentifiers.add(normalizeIdentifier(node.identifier)); - } - if (node.type === 'footnoteDefinition') { - footnoteDefinitionIdentifiers.add(normalizeIdentifier(node.identifier)); - } - if (node.type === 'heading' || node.type === 'paragraph') { - phrasingStacks.push([...parents, node]); - } - }); - for (const ancestors of phrasingStacks) { - findInPhrasingContainer(ancestors); - } - function findInPhrasingContainer(ancestors) { - const bracketRanges = []; - const node = ancestors.at(-1); - for (const child of node.children) { - if (child.type === 'text') { - findRangesInText(bracketRanges, [...ancestors, child]); - } else if ('children' in child) { - findInPhrasingContainer([...ancestors, child]); - } - } - for (const range of bracketRanges) { - handleRange(range); - } - } - function findRangesInText(ranges, ancestors) { - const node = ancestors.at(-1); - const end = pointEnd(node); - const start = pointStart(node); - if ( - !end || - !start || - typeof start.offset !== 'number' || - typeof end.offset !== 'number' - ) { - return - } - const source = value.slice(start.offset, end.offset); - const lines = [[start.offset, '']]; - let last = 0; - lineEndingExpression.lastIndex = 0; - let match = lineEndingExpression.exec(source); - while (match) { - const index = match.index; - const lineTuple = lines.at(-1); - lineTuple[1] = source.slice(last, index); - last = index + match[0].length; - lines.push([start.offset + last, '']); - match = lineEndingExpression.exec(source); - } - const lineTuple = lines.at(-1); - lineTuple[1] = source.slice(last); - for (const lineTuple of lines) { - const [lineStart, line] = lineTuple; - let index = 0; - while (index < line.length) { - const code = line.charCodeAt(index); - if (code === 91 ) { - ranges.push([ancestors, [lineStart + index]]); - index++; - } - else if (code === 92 ) { - const next = line.charCodeAt(index + 1); - index++; - if (next === 91 || next === 93 ) { - index++; - } - } - else if (code === 93 ) { - const bracketInfo = ranges.at(-1); - if (!bracketInfo) { - index++; - } - else if ( - line.charCodeAt(index + 1) === 91 && - bracketInfo[1].length !== 3 - ) { - index++; - bracketInfo[1].push(lineStart + index, lineStart + index); - index++; - } - else { - index++; - bracketInfo[1].push(lineStart + index); - handleRange(bracketInfo); - ranges.pop(); - } - } - else { - index++; - } - } - } - } - function handleRange(bracketRange) { - const [ancestors, range] = bracketRange; - if (range.length === 1) return - if (range.length === 3) range.length = 2; - if (range.length === 2 && range[0] + 2 === range[1]) return - const label = - value.charCodeAt(range[0] - 1) === 33 - ? 'image' - : value.charCodeAt(range[0] + 1) === 94 - ? 'footnote' - : 'link'; - const offset = range.length === 4 && range[2] + 2 !== range[3] ? 2 : 0; - let id = normalizeIdentifier( - collapseWhiteSpace( - value.slice(range[0 + offset] + 1, range[1 + offset] - 1), - {style: 'html', trim: true} - ) - ); - let defined = definitionIdentifiers; - if (label === 'footnote') { - if (id.includes(' ')) return - defined = footnoteDefinitionIdentifiers; - id = id.slice(1); - } - if ( - (allowShortcutLink && range.length === 2) || - defined.has(id) || - strings.has(id) || - regexes.some(function (regex) { - return regex.test(id) - }) - ) { - return - } - const start = toPoint(range[0]); - const end = toPoint(range[range.length - 1]); - if (end && start) { - file.message( - 'Unexpected reference to undefined definition, expected corresponding definition (`' + - id.toLowerCase() + - '`) for ' + - (label === 'image' ? 'an' : 'a') + - ' ' + - label + - ' or escaped opening bracket (`\\[`) for regular text', - { - ancestors, - place: {start, end} - } - ); - } - } - } -); - -/** - * remark-lint rule to warn when unreferenced definitions are used. - * - * ## What is this? - * - * This package checks that definitions are referenced. - * - * ## When should I use this? - * - * You can use this package to check definitions. - * - * ## API - * - * ### `unified().use(remarkLintNoUnusedDefinitions)` - * - * Warn when unreferenced definitions are used. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * Unused definitions do not contribute anything, so they can be removed. - * - * [api-remark-lint-no-unused-definitions]: #unifieduseremarklintnounuseddefinitions - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module no-unused-definitions - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * @example - * {"name": "ok.md"} - * - * [Mercury][] - * - * [mercury]: https://example.com/mercury/ - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * [mercury]: https://example.com/mercury/ - * - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 1:1-1:40: Unexpected unused definition, expected no definition or one or more references to `mercury` - * - * @example - * {"gfm": true, "label": "input", "name": "gfm.md"} - * - * Mercury[^mercury] is a planet. - * - * [^Mercury]: - * **Mercury** is the first planet from the Sun and the smallest - * in the Solar System. - * [^Venus]: - * **Venus** is the second planet from - * the Sun. - * @example - * {"gfm": true, "label": "output", "name": "gfm.md"} - * - * 6:1-8:13: Unexpected unused footnote definition, expected no definition or one or more footnote references to `venus` - */ -const remarkLintNoUnusedDefinitions = lintRule$1( - { - origin: 'remark-lint:no-unused-definitions', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-unused-definitions#readme' - }, - function (tree, file) { - const footnoteDefinitions = new Map(); - const definitions = new Map(); - visitParents(tree, function (node, parents) { - if ('identifier' in node) { - const map = - node.type === 'footnoteDefinition' || - node.type === 'footnoteReference' - ? footnoteDefinitions - : definitions; - let entry = map.get(node.identifier); - if (!entry) { - entry = {ancestors: undefined, used: false}; - map.set(node.identifier, entry); - } - if (node.type === 'definition' || node.type === 'footnoteDefinition') { - entry.ancestors = [...parents, node]; - } else if ( - node.type === 'imageReference' || - node.type === 'linkReference' || - node.type === 'footnoteReference' - ) { - entry.used = true; - } - } - }); - const entries = [...footnoteDefinitions.values(), ...definitions.values()]; - for (const entry of entries) { - if (!entry.used) { - ok$1(entry.ancestors); - const node = entry.ancestors.at(-1); - ok$1(node.type === 'footnoteDefinition' || node.type === 'definition'); - if (node.position) { - const prefix = node.type === 'footnoteDefinition' ? 'footnote ' : ''; - file.message( - 'Unexpected unused ' + - prefix + - 'definition, expected no definition or one or more ' + - prefix + - 'references to `' + - node.identifier + - '`', - {ancestors: entry.ancestors, place: node.position} - ); - } - } - } - } -); - -/** - * remark-lint rule to warn when ordered list markers are inconsistent. - * - * ## What is this? - * - * This package checks ordered list markers. - * - * ## When should I use this? - * - * You can use this package to check ordered lists. - * - * ## API - * - * ### `unified().use(remarkLintOrderedListMarkerStyle[, options])` - * - * Warn when ordered list markers are inconsistent. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — preferred style or whether to detect the first style and warn for - * further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = Style | 'consistent' - * ``` - * - * ### `Style` - * - * Style (TypeScript type). - * - * ###### Type - * - * ```ts - * type Style = '.' | ')' - * ``` - * - * ## Recommendation - * - * Parens for list markers were not supported in markdown before CommonMark. - * While they should work in most places now, - * not all markdown parsers follow CommonMark. - * So it’s recommended to prefer dots. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats ordered lists with - * dots by default. - * Pass `bulletOrdered: ')'` to always use parens. - * - * [api-style]: #style - * [api-options]: #options - * [api-remark-lint-ordered-list-marker-style]: #unifieduseremarklintorderedlistmarkerstyle-options - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module ordered-list-marker-style - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * 1. Mercury - * - * * Venus - * - * 1. Earth - * - * @example - * {"name": "ok.md", "config": "."} - * - * 1. Mercury - * - * @example - * {"name": "ok.md", "config": ")"} - * - * 1) Mercury - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * 1. Mercury - * - * 1) Venus - * - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 3:2: Unexpected ordered list marker `)`, expected `.` - * - * @example - * {"name": "not-ok.md", "label": "output", "config": "🌍", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected `'.'`, `')'`, or `'consistent'` - */ -const remarkLintOrderedListMarkerStyle = lintRule$1( - { - origin: 'remark-lint:ordered-list-marker-style', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-ordered-list-marker-style#readme' - }, - function (tree, file, options) { - const value = String(file); - let expected; - let cause; - if (options === null || options === undefined || options === 'consistent') ; else if (options === '.' || options === ')') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected `'.'`, `')'`, or `'consistent'`" - ); - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'listItem') return - const parent = parents.at(-1); - if (!parent || parent.type !== 'list' || !parent.ordered) return - const start = pointStart(node); - if (start && typeof start.offset === 'number') { - let index = start.offset; - let code = value.charCodeAt(index); - while (asciiDigit(code)) { - index++; - code = value.charCodeAt(index); - } - const actual = - code === 41 ? ')' : code === 46 ? '.' : undefined; - if (!actual) return - const place = { - line: start.line, - column: start.column + (index - start.offset), - offset: start.offset + (index - start.offset) - }; - if (expected) { - if (actual !== expected) { - file.message( - 'Unexpected ordered list marker `' + - actual + - '`, expected `' + - expected + - '`', - {ancestors: [...parents, node], cause, place} - ); - } - } else { - expected = actual; - cause = new VFileMessage( - 'Ordered list marker style `' + - expected + - "` first defined for `'consistent'` here", - { - ancestors: [...parents, node], - place, - ruleId: 'ordered-list-marker-style', - source: 'remark-lint' - } - ); - } - } - }); - } -); - -const remarkPresetLintRecommended = { - plugins: [ - remarkLint, - remarkLintFinalNewline, - remarkLintListItemBulletIndent, - [remarkLintListItemIndent, 'one'], - remarkLintNoBlockquoteWithoutMarker, - remarkLintNoLiteralUrls, - [remarkLintOrderedListMarkerStyle, '.'], - remarkLintHardBreakSpaces, - remarkLintNoDuplicateDefinitions, - remarkLintNoHeadingContentIndent, - remarkLintNoShortcutReferenceImage, - remarkLintNoShortcutReferenceLink, - remarkLintNoUndefinedReferences, - remarkLintNoUnusedDefinitions - ] -}; - -/** - * remark-lint rule to warn when block quotes are indented too much or - * too little. - * - * ## What is this? - * - * This package checks the “indent” of block quotes: the `>` (greater than) - * marker *and* the spaces before content. - * - * ## When should I use this? - * - * You can use this rule to check markdown code style. - * - * ## API - * - * ### `unified().use(remarkLintBlockquoteIndentation[, options])` - * - * Warn when block quotes are indented too much or too little. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — either a preferred indent or whether to detect the first style - * and warn for further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = number | 'consistent' - * ``` - * - * ## Recommendation - * - * CommonMark specifies that when block quotes are used the `>` markers can be - * followed by an optional space. - * No space at all arguably looks rather ugly: - * - * ```markdown - * >Mars and - * >Venus. - * ``` - * - * There is no specific handling of more that one space, so if 5 spaces were - * used after `>`, then indented code kicks in: - * - * ```markdown - * > neptune() - * ``` - * - * Due to this, it’s recommended to configure this rule with `2`. - * - * [api-options]: #options - * [api-remark-lint-blockquote-indentation]: #unifieduseremarklintblockquoteindentation-options - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module blockquote-indentation - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"config": 2, "name": "ok-2.md"} - * - * > Mercury. - * - * Venus. - * - * > Earth. - * - * @example - * {"config": 4, "name": "ok-4.md"} - * - * > Mercury. - * - * Venus. - * - * > Earth. - * - * @example - * { "name": "ok-tab.md"} - * - * >␉Mercury. - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * > Mercury. - * - * Venus. - * - * > Earth. - * - * Mars. - * - * > Jupiter - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 5:5: Unexpected `4` spaces between block quote marker and content, expected `3` spaces, remove `1` space - * 9:3: Unexpected `2` spaces between block quote marker and content, expected `3` spaces, add `1` space - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok-options.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected `number` or `'consistent'` - */ -const remarkLintBlockquoteIndentation = lintRule$1( - { - origin: 'remark-lint:blockquote-indentation', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-blockquote-indentation#readme' - }, - function (tree, file, options) { - let expected; - if (options === null || options === undefined || options === 'consistent') ; else if (typeof options === 'number') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected `number` or `'consistent'`" - ); - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'blockquote') return - const start = pointStart(node); - const headStart = pointStart(node.children[0]); - if (headStart && start) { - const actual = headStart.column - start.column; - if (expected) { - const difference = expected - actual; - const differenceAbsolute = Math.abs(difference); - if (difference !== 0) { - file.message( - 'Unexpected `' + - actual + - '` ' + - pluralize('space', actual) + - ' between block quote marker and content, expected `' + - expected + - '` ' + - pluralize('space', expected) + - ', ' + - (difference > 0 ? 'add' : 'remove') + - ' `' + - differenceAbsolute + - '` ' + - pluralize('space', differenceAbsolute), - {ancestors: [...parents, node], place: headStart} - ); - } - } else { - expected = actual; - } - } - }); - } -); - -/** - * remark-lint rule to warn when list item checkboxes violate a given - * style. - * - * ## What is this? - * - * This package checks the character used in checkboxes. - * - * ## When should I use this? - * - * You can use this package to check that the style of GFM tasklists is - * consistent. - * Task lists are a GFM feature enabled with - * [`remark-gfm`][github-remark-gfm]. - * - * ## API - * - * ### `unified().use(remarkLintCheckboxCharacterStyle[, options])` - * - * Warn when list item checkboxes violate a given style. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — either preferred values or whether to detect the first styles - * and warn for further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = Styles | 'consistent' - * ``` - * - * ### `Styles` - * - * Styles (TypeScript type). - * - * ###### Fields - * - * * `checked` (`'X'`, `'x'`, or `'consistent'`, default: `'consistent'`) - * — preferred style to use for checked checkboxes - * * `unchecked` (`'␉'` (a tab), `'␠'` (a space), or `'consistent'`, default: - * `'consistent'`) - * — preferred style to use for unchecked checkboxes - * - * ## Recommendation - * - * It’s recommended to set `options.checked` to `'x'` (a lowercase X) as it - * prevents an extra keyboard press and `options.unchecked` to `'␠'` (a space) - * to make all checkboxes align. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats checked checkboxes - * using `'x'` (lowercase X) and unchecked checkboxes using `'␠'` (a space). - * - * [api-options]: #options - * [api-remark-lint-checkbox-character-style]: #unifieduseremarklintcheckboxcharacterstyle-options - * [api-styles]: #styles - * [github-remark-gfm]: https://github.com/remarkjs/remark-gfm - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module checkbox-character-style - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"config": {"checked": "x"}, "gfm": true, "name": "ok-x.md"} - * - * - [x] Mercury. - * - [x] Venus. - * - * @example - * {"config": {"checked": "X"}, "gfm": true, "name": "ok-x-upper.md"} - * - * - [X] Mercury. - * - [X] Venus. - * - * @example - * {"config": {"unchecked": " "}, "gfm": true, "name": "ok-space.md"} - * - * - [ ] Mercury. - * - [ ] Venus. - * - [ ]␠␠ - * - [ ] - * - * @example - * {"config": {"unchecked": "\t"}, "gfm": true, "name": "ok-tab.md"} - * - * - [␉] Mercury. - * - [␉] Venus. - * - * @example - * {"label": "input", "gfm": true, "name": "not-ok-default.md"} - * - * - [x] Mercury. - * - [X] Venus. - * - [ ] Earth. - * - [␉] Mars. - * @example - * {"label": "output", "gfm": true, "name": "not-ok-default.md"} - * - * 2:5: Unexpected checked checkbox value `X`, expected `x` - * 4:5: Unexpected unchecked checkbox value `\t`, expected ` ` - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok-option.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected an object or `'consistent'` - * - * @example - * {"config": {"unchecked": "🌍"}, "label": "output", "name": "not-ok-option-unchecked.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options.unchecked`, expected `'\t'`, `' '`, or `'consistent'` - * - * @example - * {"config": {"checked": "🌍"}, "label": "output", "name": "not-ok-option-checked.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options.checked`, expected `'X'`, `'x'`, or `'consistent'` - */ -const remarkLintCheckboxCharacterStyle = lintRule$1( - { - origin: 'remark-lint:checkbox-character-style', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-character-style#readme' - }, - function (tree, file, options) { - const value = String(file); - let checkedExpected; - let checkedConsistentCause; - let uncheckedExpected; - let uncheckedConsistentCause; - if (options === null || options === undefined || options === 'consistent') ; else if (typeof options === 'object') { - if (options.checked === 'X' || options.checked === 'x') { - checkedExpected = options.checked; - } else if (options.checked && options.checked !== 'consistent') { - file.fail( - 'Unexpected value `' + - options.checked + - "` for `options.checked`, expected `'X'`, `'x'`, or `'consistent'`" - ); - } - if (options.unchecked === '\t' || options.unchecked === ' ') { - uncheckedExpected = options.unchecked; - } else if (options.unchecked && options.unchecked !== 'consistent') { - file.fail( - 'Unexpected value `' + - options.unchecked + - "` for `options.unchecked`, expected `'\\t'`, `' '`, or `'consistent'`" - ); - } - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected an object or `'consistent'`" - ); - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'listItem') return - const head = node.children[0]; - const headStart = pointStart(head); - if ( - !head || - !headStart || - typeof node.checked !== 'boolean' || - typeof headStart.offset !== 'number' - ) { - return - } - headStart.offset -= 2; - headStart.column -= 2; - const match = /\[([\t Xx])]/.exec( - value.slice(headStart.offset - 2, headStart.offset + 1) - ); - if (!match) return - const actual = match[1]; - const actualDisplay = actual === '\t' ? '\\t' : actual; - const expected = node.checked ? checkedExpected : uncheckedExpected; - const expectedDisplay = expected === '\t' ? '\\t' : expected; - if (!expected) { - const cause = new VFileMessage( - (node.checked ? 'C' : 'Unc') + - "hecked checkbox style `'" + - actualDisplay + - "'` first defined for `'consistent'` here", - { - ancestors: [...parents, node], - place: headStart, - ruleId: 'checkbox-character-style', - source: 'remark-lint' - } - ); - if (node.checked) { - checkedExpected = (actual); - checkedConsistentCause = cause; - } else { - uncheckedExpected = (actual); - uncheckedConsistentCause = cause; - } - } else if (actual !== expected) { - file.message( - 'Unexpected ' + - (node.checked ? '' : 'un') + - 'checked checkbox value `' + - actualDisplay + - '`, expected `' + - expectedDisplay + - '`', - { - ancestors: [...parents, node], - cause: node.checked - ? checkedConsistentCause - : uncheckedConsistentCause, - place: headStart - } - ); - } - }); - } -); - -/** - * remark-lint rule to warn when GFM tasklist checkboxes are followed by - * more than one space. - * - * ## What is this? - * - * This package checks the space after checkboxes. - * - * ## When should I use this? - * - * You can use this package to check that the style of GFM tasklists is - * a single space. - * - * ## API - * - * ### `unified().use(remarkLintCheckboxContentIndent)` - * - * Warn when GFM tasklist checkboxes are followed by more than one space. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * GFM allows zero or more spaces and tabs after checkboxes. - * No space at all arguably looks rather ugly: - * - * ```markdown - * * [x]Pluto - * ``` - * - * More that one space is superfluous: - * - * ```markdown - * * [x] Jupiter - * ``` - * - * Due to this, it’s recommended to turn this rule on. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats checkboxes and the - * content after them with a single space between. - * - * [api-remark-lint-checkbox-content-indent]: #unifieduseremarklintcheckboxcontentindent - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module checkbox-content-indent - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"gfm": true, "name": "ok.md"} - * - * - [ ] Mercury. - * + [x] Venus. - * * [X] Earth. - * - [ ] Mars. - * - * @example - * {"gfm": true, "label": "input", "name": "not-ok.md"} - * - * - [ ] Mercury. - * + [x] Venus. - * * [X] Earth. - * - [ ] Mars. - * @example - * {"gfm": true, "label": "output", "name": "not-ok.md"} - * - * 2:8: Unexpected `2` spaces between checkbox and content, expected `1` space, remove `1` space - * 3:9: Unexpected `3` spaces between checkbox and content, expected `1` space, remove `2` spaces - * 4:10: Unexpected `4` spaces between checkbox and content, expected `1` space, remove `3` spaces - * - * @example - * {"gfm": true, "label": "input", "name": "tab.md"} - * - * - [ ]␉Mercury. - * + [x]␉␉Venus. - * @example - * {"gfm": true, "label": "output", "name": "tab.md"} - * - * 2:8: Unexpected `2` spaces between checkbox and content, expected `1` space, remove `1` space - */ -const remarkLintCheckboxContentIndent = lintRule$1( - { - origin: 'remark-lint:checkbox-content-indent', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-content-indent#readme' - }, - function (tree, file) { - const value = String(file); - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'listItem') return - const head = node.children[0]; - const headStart = pointStart(head); - if ( - !head || - !headStart || - typeof node.checked !== 'boolean' || - typeof headStart.offset !== 'number' - ) { - return - } - const match = /\[([\t xX])]/.exec( - value.slice(headStart.offset - 4, headStart.offset + 1) - ); - if (!match) return - let final = headStart.offset; - let code = value.charCodeAt(final); - while (code === 9 || code === 32) { - final++; - code = value.charCodeAt(final); - } - const size = final - headStart.offset; - if (size) { - file.message( - 'Unexpected `' + - (size + 1) + - '` ' + - pluralize('space', size + 1) + - ' between checkbox and content, expected `1` space, remove `' + - size + - '` ' + - pluralize('space', size), - { - ancestors: [...parents, node], - place: { - line: headStart.line, - column: headStart.column + size, - offset: headStart.offset + size - } - } - ); - } - }); - } -); - -/** - * remark-lint rule to warn when code blocks violate a given style. - * - * ## What is this? - * - * This package checks the style of code blocks. - * - * ## When should I use this? - * - * You can use this package to check that the style of code blocks is - * consistent. - * - * ## API - * - * ### `unified().use(remarkLintCodeBlockStyle[, options])` - * - * Warn when code blocks violate a given style. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — preferred style or whether to detect the first style and warn for - * further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = Style | 'consistent' - * ``` - * - * ### `Style` - * - * Style (TypeScript type). - * - * ###### Type - * - * ```ts - * type Style = 'indented' | 'fenced' - * ``` - * - * ## Recommendation - * - * Indentation in markdown is complex as lists and indented code interfere in - * unexpected ways. - * Fenced code has more features than indented code: it can specify a - * programming language. - * Since CommonMark took the idea of fenced code from GFM, - * fenced code became widely supported. - * Due to this, it’s recommended to configure this rule with `'fenced'`. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] always formats code blocks as - * fenced. - * Pass `fences: false` to only use fenced code blocks when they have a - * language and as indented code otherwise. - * - * [api-options]: #options - * [api-remark-lint-code-block-style]: #unifieduseremarklintcodeblockstyle-options - * [api-style]: #style - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module code-block-style - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"config": "indented", "name": "ok-indented.md"} - * - * venus() - * - * Mercury. - * - * earth() - * - * @example - * {"config": "fenced", "name": "ok-fenced.md"} - * - * ``` - * venus() - * ``` - * - * Mercury. - * - * ``` - * earth() - * ``` - * - * @example - * {"label": "input", "name": "not-ok-consistent.md"} - * - * venus() - * - * Mercury. - * - * ``` - * earth() - * ``` - * @example - * {"label": "output", "name": "not-ok-consistent.md"} - * - * 5:1-7:4: Unexpected fenced code block, expected indented code blocks - * - * @example - * {"config": "indented", "label": "input", "name": "not-ok-indented.md"} - * - * ``` - * venus() - * ``` - * - * Mercury. - * - * ``` - * earth() - * ``` - * @example - * {"config": "indented", "label": "output", "name": "not-ok-indented.md"} - * - * 1:1-3:4: Unexpected fenced code block, expected indented code blocks - * 7:1-9:4: Unexpected fenced code block, expected indented code blocks - * - * @example - * {"config": "fenced", "label": "input", "name": "not-ok-fenced.md"} - * - * venus() - * - * Mercury. - * - * earth() - * - * @example - * {"config": "fenced", "label": "output", "name": "not-ok-fenced.md"} - * - * 1:1-1:12: Unexpected indented code block, expected fenced code blocks - * 5:1-5:12: Unexpected indented code block, expected fenced code blocks - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok-options.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected `'fenced'`, `'indented'`, or `'consistent'` - */ -const remarkLintCodeBlockStyle = lintRule$1( - { - origin: 'remark-lint:code-block-style', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-code-block-style#readme' - }, - function (tree, file, options) { - const value = String(file); - let cause; - let expected; - if (options === null || options === undefined || options === 'consistent') ; else if (options === 'indented' || options === 'fenced') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected `'fenced'`, `'indented'`, or `'consistent'`" - ); - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'code') return - const end = pointEnd(node); - const start = pointStart(node); - if ( - !start || - !end || - typeof start.offset !== 'number' || - typeof end.offset !== 'number' - ) { - return - } - const actual = - node.lang || /^ {0,3}([`~])/.test(value.slice(start.offset, end.offset)) - ? 'fenced' - : 'indented'; - if (expected) { - if (expected !== actual) { - file.message( - 'Unexpected ' + - actual + - ' code block, expected ' + - expected + - ' code blocks', - {ancestors: [...parents, node], cause, place: {start, end}} - ); - } - } else { - expected = actual; - cause = new VFileMessage( - "Code block style `'" + - actual + - "'` first defined for `'consistent'` here", - { - ancestors: [...parents, node], - place: {start, end}, - source: 'remark-lint', - ruleId: 'code-block-style' - } - ); - } - }); - } -); - -/** - * remark-lint rule to warn when consecutive whitespace is used in - * a definition label. - * - * ## What is this? - * - * This package checks the whitepsace in definition labels. - * - * GFM footnotes are not affected by this rule as footnote labels cannot - * contain whitespace. - * - * ## When should I use this? - * - * You can use this package to check that definition labels are consistent. - * - * ## API - * - * ### `unified().use(remarkLintDefinitionSpacing)` - * - * Warn when consecutive whitespace is used in a definition label. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * Definitions and references are matched together by collapsing whitespace. - * Using more whitespace in labels might incorrectly indicate that they are of - * importance. - * Due to this, it’s recommended to use one space and turn this rule on. - * - * [api-remark-lint-definition-spacing]: #unifieduseremarklintdefinitionspacing - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module definition-spacing - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * The first planet is [planet mercury][]. - * - * [planet mercury]: http://example.com - * - * @example - * {"label": "input", "name": "not-ok-consecutive.md"} - * - * [planet␠␠␠␠mercury]: http://example.com - * @example - * {"label": "output", "name": "not-ok-consecutive.md"} - * - * 1:1-1:40: Unexpected `4` consecutive spaces in definition label, expected `1` space, remove `3` spaces - * - * @example - * {"label": "input", "name": "not-ok-non-space.md"} - * - * [pla␉net␊mer␍cury]: http://e.com - * @example - * {"label": "output", "name": "not-ok-non-space.md"} - * - * 1:1-3:20: Unexpected non-space whitespace character `\t` in definition label, expected `1` space, replace it - * 1:1-3:20: Unexpected non-space whitespace character `\n` in definition label, expected `1` space, replace it - * 1:1-3:20: Unexpected non-space whitespace character `\r` in definition label, expected `1` space, replace it - */ -const remarkLintDefinitionSpacing = lintRule$1( - { - origin: 'remark-lint:definition-spacing', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-definition-spacing#readme' - }, - function (tree, file) { - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type === 'definition' && node.position && node.label) { - const size = longestStreak(node.label, ' '); - if (size > 1) { - file.message( - 'Unexpected `' + - size + - '` consecutive spaces in definition label, expected `1` space, remove `' + - (size - 1) + - '` ' + - pluralize('space', size - 1), - {ancestors: [...parents, node], place: node.position} - ); - } - const disallowed = []; - if (node.label.includes('\t')) disallowed.push('\\t'); - if (node.label.includes('\n')) disallowed.push('\\n'); - if (node.label.includes('\r')) disallowed.push('\\r'); - for (const disallow of disallowed) { - file.message( - 'Unexpected non-space whitespace character `' + - disallow + - '` in definition label, expected `1` space, replace it', - {ancestors: [...parents, node], place: node.position} - ); - } - } - }); - } -); - -const quotation = - ( - function (value, open, close) { - const start = open; - const end = start; - let index = -1; - if (Array.isArray(value)) { - const list = (value); - const result = []; - while (++index < list.length) { - result[index] = start + list[index] + end; - } - return result - } - if (typeof value === 'string') { - return start + value + end - } - throw new TypeError('Expected string or array of strings') - } - ); - -/** - * remark-lint rule to warn when language flags of fenced code - * are not used. - * - * ## What is this? - * - * This package checks the language flags of fenced code blocks, - * whether they exist, - * and optionally what values they hold. - * - * ## When should I use this? - * - * You can use this package to check that the style of language flags of fenced - * code blocks is consistent. - * - * ## API - * - * ### `unified().use(remarkLintFencedCodeFlag[, options])` - * - * Warn when language flags of fenced code are not used. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options] or `Array`, optional) - * — configuration or flags to allow - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Fields - * - * * `allowEmpty` (`boolean`, default: `false`) - * — allow language flags to be omitted - * * `flags` (`Array`, optional) - * — flags to allow, - * other flags will result in a warning - * - * ## Recommendation - * - * While omitting language flags is fine to signal that code is plain text, - * it *could* point to a mistake. - * It’s recommended to instead use a certain flag for plain text (such as - * `txt`) and to turn this rule on. - * - * [api-options]: #options - * [api-remark-lint-fenced-code-flag]: #unifieduseremarklintfencedcodeflag-options - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module fenced-code-flag - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * Some markdown: - * - * ```markdown - * # Mercury - * ``` - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * ``` - * mercury() - * ``` - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 1:1-3:4: Unexpected missing fenced code language flag in info string, expected keyword - * - * @example - * {"config": {"allowEmpty": true}, "name": "ok-allow-empty.md"} - * - * ``` - * mercury() - * ``` - * - * @example - * {"config": {"allowEmpty": false}, "label": "input", "name": "not-ok-allow-empty.md"} - * - * ``` - * mercury() - * ``` - * @example - * {"config": {"allowEmpty": false}, "label": "output", "name": "not-ok-allow-empty.md"} - * - * 1:1-3:4: Unexpected missing fenced code language flag in info string, expected keyword - * - * @example - * {"config": ["markdown"], "name": "ok-array.md"} - * - * ```markdown - * # Mercury - * ``` - * - * @example - * {"config": {"flags":["markdown"]}, "name": "ok-options.md"} - * - * ```markdown - * # Mercury - * ``` - * - * @example - * {"config": ["markdown"], "label": "input", "name": "not-ok-array.md"} - * - * ```javascript - * mercury() - * ``` - * @example - * {"config": ["markdown"], "label": "output", "name": "not-ok-array.md"} - * - * 1:1-3:4: Unexpected fenced code language flag `javascript` in info string, expected `markdown` - * - * @example - * {"config": ["javascript", "markdown", "mdx", "typescript"], "label": "input", "name": "not-ok-long-array.md"} - * - * ```html - *

Mercury

- * ``` - * @example - * {"config": ["javascript", "markdown", "mdx", "typescript"], "label": "output", "name": "not-ok-long-array.md"} - * - * 1:1-3:4: Unexpected fenced code language flag `html` in info string, expected `javascript`, `markdown`, `mdx`, … - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok-options.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected array or object - */ -const fence = /^ {0,3}([~`])\1{2,}/; -const listFormat$1 = new Intl.ListFormat('en', {type: 'disjunction'}); -const listFormatUnit$1 = new Intl.ListFormat('en', {type: 'unit'}); -const remarkLintFencedCodeFlag = lintRule$1( - { - origin: 'remark-lint:fenced-code-flag', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-flag#readme' - }, - function (tree, file, options) { - const value = String(file); - let allowEmpty = false; - let allowed; - if (options === null || options === undefined) ; else if (typeof options === 'object') { - if (Array.isArray(options)) { - const flags = (options); - allowed = flags; - } else { - const settings = (options); - allowEmpty = settings.allowEmpty === true; - if (settings.flags) { - allowed = settings.flags; - } - } - } else { - file.fail( - 'Unexpected value `' + - options + - '` for `options`, expected array or object' - ); - } - let allowedDisplay; - if (allowed) { - allowedDisplay = - allowed.length > 3 - ? listFormatUnit$1.format([...quotation(allowed.slice(0, 3), '`'), '…']) - : listFormat$1.format(quotation(allowed, '`')); - } else { - allowedDisplay = 'keyword'; - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'code') return - const end = pointEnd(node); - const start = pointStart(node); - if ( - end && - start && - typeof end.offset === 'number' && - typeof start.offset === 'number' - ) { - if (node.lang) { - if (allowed && !allowed.includes(node.lang)) { - file.message( - 'Unexpected fenced code language flag `' + - node.lang + - '` in info string, expected ' + - allowedDisplay, - {ancestors: [...parents, node], place: node.position} - ); - } - } else if (!allowEmpty) { - const slice = value.slice(start.offset, end.offset); - if (fence.test(slice)) { - file.message( - 'Unexpected missing fenced code language flag in info string, expected ' + - allowedDisplay, - {ancestors: [...parents, node], place: node.position} - ); - } - } - } - }); - } -); - -/** - * remark-lint rule to warn when fenced code markers are - * inconsistent. - * - * ## What is this? - * - * This package checks fenced code block markers. - * - * ## When should I use this? - * - * You can use this package to check that fenced code block markers are - * consistent. - * - * ## API - * - * ### `unified().use(remarkLintFencedCodeMarker[, options])` - * - * Warn when fenced code markers are inconsistent. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — preferred style or whether to detect the first style and warn for - * further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Marker` - * - * Marker (TypeScript type). - * - * ###### Type - * - * ```ts - * type Marker = '`' | '~' - * ``` - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = Marker | 'consistent' - * ``` - * - * ## Recommendation - * - * Tildes are uncommon. - * So it’s recommended to configure this rule with ``'`'``. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats fenced code with grave - * accents by default. - * Pass `fence: '~'` to always use tildes. - * - * [api-marker]: #marker - * [api-options]: #options - * [api-remark-lint-fenced-code-marker]: #unifieduseremarklintfencedcodemarker-options - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module fenced-code-marker - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok-indented.md"} - * - * Indented code blocks are not affected by this rule: - * - * mercury() - * - * @example - * {"config": "`", "name": "ok-tick.md"} - * - * ```javascript - * mercury() - * ``` - * - * ``` - * venus() - * ``` - * - * @example - * {"config": "~", "name": "ok-tilde.md"} - * - * ~~~javascript - * mercury() - * ~~~ - * - * ~~~ - * venus() - * ~~~ - * - * @example - * {"label": "input", "name": "not-ok-consistent-tick.md"} - * - * ```javascript - * mercury() - * ``` - * - * ~~~ - * venus() - * ~~~ - * @example - * {"label": "output", "name": "not-ok-consistent-tick.md"} - * - * 5:1-7:4: Unexpected fenced code marker `~`, expected `` ` `` - * - * @example - * {"label": "input", "name": "not-ok-consistent-tilde.md"} - * - * ~~~javascript - * mercury() - * ~~~ - * - * ``` - * venus() - * ``` - * @example - * {"label": "output", "name": "not-ok-consistent-tilde.md"} - * - * 5:1-7:4: Unexpected fenced code marker `` ` ``, expected `~` - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok-incorrect.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected ``'`'``, `'~'`, or `'consistent'` - */ -const remarkLintFencedCodeMarker = lintRule$1( - { - origin: 'remark-lint:fenced-code-marker', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-marker#readme' - }, - function (tree, file, options) { - const value = String(file); - let cause; - let expected; - if (options === null || options === undefined || options === 'consistent') ; else if (options === '`' || options === '~') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected ``'`'``, `'~'`, or `'consistent'`" - ); - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'code') return - const start = pointStart(node); - if (start && typeof start.offset === 'number') { - const actual = value - .slice(start.offset, start.offset + 4) - .replace(/^\s+/, '') - .charAt(0); - if (actual !== '`' && actual !== '~') return - if (expected) { - if (actual !== expected) { - file.message( - 'Unexpected fenced code marker ' + - (actual === '~' ? '`~`' : '`` ` ``') + - ', expected ' + - (expected === '~' ? '`~`' : '`` ` ``'), - {ancestors: [...parents, node], cause, place: node.position} - ); - } - } else { - expected = actual; - cause = new VFileMessage( - 'Fenced code marker style ' + - (actual === '~' ? "`'~'`" : "``'`'``") + - " first defined for `'consistent'` here", - { - ancestors: [...parents, node], - place: node.position, - ruleId: 'fenced-code-marker', - source: 'remark-lint' - } - ); - } - } - }); - } -); - -/** - * remark-lint rule to warn for unexpected file extensions. - * - * ## What is this? - * - * This package checks the file extension. - * - * ## When should I use this? - * - * You can use this package to check that file extensions are consistent. - * - * ## API - * - * ### `unified().use(remarkLintFileExtension[, options])` - * - * Warn for unexpected extensions. - * - * ###### Parameters - * - * * `options` ([`Extensions`][api-extensions] or [`Options`][api-options], - * optional) - * — configuration - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Extensions` - * - * File extension(s) (TypeScript type). - * - * ###### Type - * - * ```ts - * type Extensions = Array | string - * ``` - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Fields - * - * * `allowExtensionless` (`boolean`, default: `true`) - * — allow no file extension such as `AUTHORS` or `LICENSE` - * * `extensions` ([`Extensions`][api-extensions], default: `['mdx', 'md']`) - * — allowed file extension(s) - * - * ## Recommendation - * - * Use `md` as it’s the most common. - * Also use `md` when your markdown contains common syntax extensions (such as - * GFM, frontmatter, or math). - * Do not use `md` for MDX: use `mdx` instead. - * - * [api-extensions]: #extensions - * [api-options]: #options - * [api-remark-lint-file-extension]: #unifieduseremarklintfileextension-options - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module file-extension - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "readme.md"} - * - * @example - * {"name": "readme.mdx"} - * - * @example - * {"name": "readme"} - * - * @example - * {"config": {"allowExtensionless": false}, "label": "output", "name": "readme", "positionless": true} - * - * 1:1: Unexpected missing file extension, expected `mdx` or `md` - * - * @example - * {"label": "output", "name": "readme.mkd", "positionless": true} - * - * 1:1: Unexpected file extension `mkd`, expected `mdx` or `md` - * - * @example - * {"config": "mkd", "name": "readme.mkd"} - * - * @example - * {"config": ["markdown", "md", "mdown", "mdwn", "mdx", "mkd", "mkdn", "mkdown", "ron"], "label": "input", "name": "readme.css", "positionless": true} - * - * @example - * {"config": ["markdown", "md", "mdown", "mdwn", "mdx", "mkd", "mkdn", "mkdown", "ron"], "label": "output", "name": "readme.css"} - * - * 1:1: Unexpected file extension `css`, expected `markdown`, `md`, `mdown`, … - */ -const defaultExtensions = ['mdx', 'md']; -const listFormat = new Intl.ListFormat('en', {type: 'disjunction'}); -const listFormatUnit = new Intl.ListFormat('en', {type: 'unit'}); -const remarkLintFileExtension = lintRule$1( - { - origin: 'remark-lint:file-extension', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-file-extension#readme' - }, - function (_, file, options) { - let expected = defaultExtensions; - let allowExtensionless = true; - let extensionsValue; - if (Array.isArray(options)) { - extensionsValue = (options); - } else if (typeof options === 'string') { - extensionsValue = options; - } else if (options) { - const settings = (options); - extensionsValue = settings.extensions; - if (settings.allowExtensionless === false) { - allowExtensionless = false; - } - } - if (Array.isArray(extensionsValue)) { - expected = (extensionsValue); - } else if (typeof extensionsValue === 'string') { - expected = [extensionsValue]; - } - const extname = file.extname; - const actual = extname ? extname.slice(1) : undefined; - const expectedDisplay = - expected.length > 3 - ? listFormatUnit.format([...quotation(expected.slice(0, 3), '`'), '…']) - : listFormat.format(quotation(expected, '`')); - if (actual ? !expected.includes(actual) : !allowExtensionless) { - file.message( - (actual - ? 'Unexpected file extension `' + actual + '`' - : 'Unexpected missing file extension') + - ', expected ' + - expectedDisplay - ); - } - } -); - -/** - * remark-lint rule to warn when definitions are used *in* the - * document instead of at the end. - * - * ## What is this? - * - * This package checks where definitions are placed. - * - * ## When should I use this? - * - * You can use this package to check that definitions are consistently at the - * end of the document. - * - * ## API - * - * ### `unified().use(remarkLintFinalDefinition)` - * - * Warn when definitions are used *in* the document instead of at the end. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * There are different strategies for placing definitions. - * The simplest is perhaps to place them all at the bottem of documents. - * If you prefer that, turn on this rule. - * - * [api-remark-lint-final-definition]: #unifieduseremarklintfinaldefinition - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module final-definition - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * Mercury. - * - * [venus]: http://example.com - * - * @example - * {"name": "ok.md"} - * - * [mercury]: http://example.com/mercury/ - * [venus]: http://example.com/venus/ - * - * @example - * {"name": "ok-html-comments.md"} - * - * Mercury. - * - * [venus]: http://example.com/venus/ - * - * - * - * [earth]: http://example.com/earth/ - * - * @example - * {"name": "ok-mdx-comments.mdx", "mdx": true} - * - * Mercury. - * - * [venus]: http://example.com/venus/ - * - * {/* Comments in expressions in MDX are ignored. *␀/} - * - * [earth]: http://example.com/earth/ - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * Mercury. - * - * [venus]: https://example.com/venus/ - * - * Earth. - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 3:1-3:36: Unexpected definition before last content, expected definitions after line `5` - * - * @example - * {"gfm": true, "label": "input", "name": "gfm-nok.md"} - * - * Mercury. - * - * [^venus]: - * **Venus** is the second planet from - * the Sun. - * - * Earth. - * @example - * {"gfm": true, "label": "output", "name": "gfm-nok.md"} - * - * 3:1-5:13: Unexpected footnote definition before last content, expected definitions after line `7` - * - * @example - * {"gfm": true, "name": "gfm-ok.md"} - * - * Mercury. - * - * Earth. - * - * [^venus]: - * **Venus** is the second planet from - * the Sun. - */ -const remarkLintFinalDefinition = lintRule$1( - { - origin: 'remark-lint:final-definition', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-final-definition#readme' - }, - function (tree, file) { - const definitionStacks = []; - let contentAncestors; - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type === 'definition' || node.type === 'footnoteDefinition') { - definitionStacks.push([...parents, node]); - return SKIP - } - if ( - node.type === 'root' || - (node.type === 'html' && /^[\t ]*".length)); - validateMeta(node, file, meta); - } catch (e) { - file.message(e, node); - } - }); -} -const remarkLintNodejsYamlComments = lintRule$1( - "remark-lint:nodejs-yaml-comments", - validateYAMLComments, -); - -function lintRule(meta, rule) { - const id = meta ; - const url = undefined ; - const parts = id.split(':'); - const source = parts[1] ? parts[0] : undefined; - const ruleId = parts[1]; - Object.defineProperty(plugin, 'name', {value: id}); - return plugin - function plugin(config) { - const [severity, options] = coerce(ruleId, config); - if (!severity) return - const fatal = severity === 2; - return (tree, file, next) => { - let index = file.messages.length - 1; - wrap(rule, (error) => { - const messages = file.messages; - if (error && !messages.includes(error)) { - try { - file.fail(error); - } catch {} - } - while (++index < messages.length) { - Object.assign(messages[index], {ruleId, source, fatal, url}); - } - next(); - })(tree, file, options); - } - } -} -function coerce(name, config) { - if (!Array.isArray(config)) return [1, config] - const [severity, ...options] = config; - switch (severity) { - case false: - case 'off': - case 0: { - return [0, ...options] - } - case true: - case 'on': - case 'warn': - case 1: { - return [1, ...options] - } - case 'error': - case 2: { - return [2, ...options] - } - default: { - if (typeof severity !== 'number') return [1, config] - throw new Error( - 'Incorrect severity `' + - severity + - '` for `' + - name + - '`, ' + - 'expected 0, 1, or 2' - ) - } - } -} - -const remarkLintProhibitedStrings = lintRule('remark-lint:prohibited-strings', prohibitedStrings); -function testProhibited (val, content) { - let regexpFlags = 'g'; - let no = val.no; - if (!no) { - no = escapeStringRegexp(val.yes); - regexpFlags += 'i'; - } - let regexpString = '(? escapeStringRegexp(a)).join('|'); - ignoreNextTo = `(?:${parts})`; - } else { - ignoreNextTo = escapeStringRegexp(val.ignoreNextTo); - } - } else { - ignoreNextTo = ''; - } - const replaceCaptureGroups = !!val.replaceCaptureGroups; - if (/^\b/.test(no)) { - regexpString += '\\b'; - } - if (ignoreNextTo) { - regexpString += `(? { - const results = testProhibited(val, content); - if (results.length) { - results.forEach(({ result, index, yes }) => { - const message = val.yes ? `Use "${yes}" instead of "${result}"` : `Do not use "${result}"`; - file.message(message, { - start: myLocation.toPoint(initial + index), - end: myLocation.toPoint(initial + index + [...result].length) - }); - }); - } - }); - } -} - -/** - * remark-lint rule to warn when thematic breaks (horizontal rules) are - * inconsistent. - * - * ## What is this? - * - * This package checks markers and whitespace of thematic rules. - * - * ## When should I use this? - * - * You can use this package to check that thematic breaks are consistent. - * - * ## API - * - * ### `unified().use(remarkLintRuleStyle[, options])` - * - * Warn when thematic breaks (horizontal rules) are inconsistent. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — preferred style or whether to detect the first style and warn for - * further differences - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * * `'consistent'` - * — detect the first used style and warn when further rules differ - * * `string` (example: `'** * **'`, `'___'`) - * — thematic break to prefer - * - * ###### Type - * - * ```ts - * type Options = string | 'consistent' - * ``` - * - * ## Recommendation - * - * Rules consist of a `*`, `-`, or `_` character, - * which occurs at least three times with nothing else except for arbitrary - * spaces or tabs on a single line. - * Using spaces, tabs, or more than three markers is unnecessary work to type - * out. - * As asterisks can be used as a marker for more markdown constructs, - * it’s recommended to use that for rules (and lists, emphasis, strong) too. - * So it’s recommended to pass `'***'`. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats rules with `***` by - * default. - * There are three settings to control rules: - * - * * `rule` (default: `'*'`) — marker - * * `ruleRepetition` (default: `3`) — repetitions - * * `ruleSpaces` (default: `false`) — use spaces between markers - * - * [api-options]: #options - * [api-remark-lint-rule-style]: #unifieduseremarklintrulestyle-options - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module rule-style - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md"} - * - * Two rules: - * - * * * * - * - * * * * - * - * @example - * {"config": "_______", "name": "ok.md"} - * - * _______ - * - * _______ - * - * @example - * {"label": "input", "name": "not-ok.md"} - * - * *** - * - * * * * - * @example - * {"label": "output", "name": "not-ok.md"} - * - * 3:1-3:6: Unexpected thematic rule `* * *`, expected `***` - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected thematic rule or `'consistent'` - */ -const remarkLintRuleStyle = lintRule$1( - { - origin: 'remark-lint:rule-style', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-rule-style#readme' - }, - function (tree, file, options) { - const value = String(file); - let expected; - let cause; - if (options === null || options === undefined || options === 'consistent') ; else if ( - /[^-_* ]/.test(options) || - options.at(0) === ' ' || - options.at(-1) === ' ' || - options.replaceAll(' ', '').length < 3 - ) { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected thematic rule or `'consistent'`" - ); - } else { - expected = options; - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'thematicBreak') return - const end = pointEnd(node); - const start = pointStart(node); - if ( - start && - end && - typeof start.offset === 'number' && - typeof end.offset === 'number' - ) { - const place = {start, end}; - const actual = value.slice(start.offset, end.offset); - if (expected) { - if (actual !== expected) { - file.message( - 'Unexpected thematic rule `' + - actual + - '`, expected `' + - expected + - '`', - {ancestors: [...parents, node], cause, place} - ); - } - } else { - expected = actual; - cause = new VFileMessage( - 'Thematic rule style `' + - expected + - "` first defined for `'consistent'` here", - { - ancestors: [...parents, node], - place, - ruleId: 'rule-style', - source: 'remark-lint' - } - ); - } - } - }); - } -); - -/** - * remark-lint rule to warn when strong markers are inconsistent. - * - * ## What is this? - * - * This package checks the style of strong markers. - * - * ## When should I use this? - * - * You can use this package to check that strong is consistent. - * - * ## API - * - * ### `unified().use(remarkLintStrongMarker[, options])` - * - * Warn when strong markers are inconsistent. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — preferred style or whether to detect the first style and warn for - * further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Marker` - * - * Marker (TypeScript type). - * - * ###### Type - * - * ```ts - * type Marker = '*' | '_' - * ``` - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = Marker | 'consistent' - * ``` - * - * ## Recommendation - * - * Whether asterisks or underscores are used affects how and whether strong - * works. - * Underscores are sometimes used to represent normal underscores inside words, - * so there are extra rules in markdown to support that. - * Asterisks are not used in natural language, - * so they don’t need these rules, - * and thus can form strong in more cases. - * Asterisks can also be used as the marker of more constructs than underscores: - * lists. - * Due to having simpler parsing rules, - * looking more like syntax, - * and that they can be used for more constructs, - * it’s recommended to prefer asterisks. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats strong with asterisks - * by default. - * Pass `strong: '_'` to always use underscores. - * - * [api-marker]: #marker - * [api-options]: #options - * [api-remark-lint-strong-marker]: #unifieduseremarklintstrongmarker-options - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module strong-marker - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"config": "*", "name": "ok-asterisk.md"} - * - * **Mercury**. - * - * @example - * {"config": "*", "label": "input", "name": "not-ok-asterisk.md"} - * - * __Mercury__. - * - * @example - * {"config": "*", "label": "output", "name": "not-ok-asterisk.md"} - * - * 1:1-1:12: Unexpected strong marker `_`, expected `*` - * - * @example - * {"config": "_", "name": "ok-underscore.md"} - * - * __Mercury__. - * - * @example - * {"config": "_", "label": "input", "name": "not-ok-underscore.md"} - * - * **Mercury**. - * - * @example - * {"config": "_", "label": "output", "name": "not-ok-underscore.md"} - * - * 1:1-1:12: Unexpected strong marker `*`, expected `_` - * - * @example - * {"label": "input", "name": "not-ok-consistent.md"} - * - * **Mercury** and __Venus__. - * - * @example - * {"label": "output", "name": "not-ok-consistent.md"} - * - * 1:17-1:26: Unexpected strong marker `_`, expected `*` - * - * @example - * {"config": "🌍", "label": "output", "name": "not-ok.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected `'*'`, `'_'`, or `'consistent'` - */ -const remarkLintStrongMarker = lintRule$1( - { - origin: 'remark-lint:strong-marker', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-strong-marker#readme' - }, - function (tree, file, options) { - const value = String(file); - let cause; - let expected; - if (options === null || options === undefined || options === 'consistent') ; else if (options === '*' || options === '_') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected `'*'`, `'_'`, or `'consistent'`" - ); - } - visitParents(tree, 'strong', function (node, parents) { - const start = pointStart(node); - if (start && typeof start.offset === 'number') { - const actual = value.charAt(start.offset); - if (actual !== '*' && actual !== '_') return - if (expected) { - if (actual !== expected) { - file.message( - 'Unexpected strong marker `' + - actual + - '`, expected `' + - expected + - '`', - {ancestors: [...parents, node], cause, place: node.position} - ); - } - } else { - expected = actual; - cause = new VFileMessage( - "Strong marker style `'" + - actual + - "'` first defined for `'consistent'` here", - { - ancestors: [...parents, node], - place: node.position, - ruleId: 'strong-marker', - source: 'remark-lint' - } - ); - } - } - }); - } -); - -/** - * remark-lint rule to warn when GFM table cells are padded inconsistently. - * - * ## What is this? - * - * This package checks table cell padding. - * Tables are a GFM feature enabled with [`remark-gfm`][github-remark-gfm]. - * - * ## When should I use this? - * - * You can use this package to check that tables are consistent. - * - * ## API - * - * ### `unified().use(remarkLintTableCellPadding[, options])` - * - * Warn when GFM table cells are padded inconsistently. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], optional) - * — preferred style or whether to detect the first style and warn for - * further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Style` - * - * Style (TypeScript type). - * - * * `'compact'` - * — prefer zero spaces between pipes and content - * * `'padded'` - * — prefer at least one space between pipes and content - * - * ###### Type - * - * ```ts - * type Style = 'compact' | 'padded' - * ``` - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = Style | 'consistent' - * ``` - * - * ## Recommendation - * - * It’s recommended to use at least one space between pipes and content for - * legibility of the markup (`'padded'`). - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] with - * [`remark-gfm`][github-remark-gfm] formats all table cells as padded by - * default. - * Pass `tableCellPadding: false` to use a more compact style. - * - * [api-options]: #options - * [api-style]: #style - * [api-remark-lint-table-cell-padding]: #unifieduseremarklinttablecellpadding-options - * [github-remark-gfm]: https://github.com/remarkjs/remark-gfm - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module table-cell-padding - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"config": "padded", "gfm": true, "name": "ok.md"} - * - * | Planet | Symbol | Satellites | Mean anomaly (°) | - * | ------- | :----- | :--------: | ---------------: | - * | Mercury | ☿ | None | 174 796 | - * - * | Planet | Symbol | Satellites | Mean anomaly (°) | - * | - | :- | :-: | -: | - * | Venus | ♀ | None | 50 115 | - * - * @example - * {"config": "padded", "gfm": true, "label": "input", "name": "not-ok.md"} - * - * | Planet | - * | -------| - * | Mercury| - * - * |Planet | - * |------ | - * |Venus | - * - * | Planet | - * | ------ | - * | Venus | - * @example - * {"config": "padded", "gfm": true, "label": "output", "name": "not-ok.md"} - * - * 2:10: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 3:10: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 5:2: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 6:2: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 7:2: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 9:4: Unexpected `2` spaces between cell edge and content, expected `1` space, remove `1` space - * 9:12: Unexpected `2` spaces between cell content and edge, expected `1` space, remove `1` space - * 10:4: Unexpected `2` spaces between cell edge and content, expected `1` space, remove `1` space - * 10:12: Unexpected `2` spaces between cell content and edge, expected `1` space, remove `1` space - * 11:4: Unexpected `2` spaces between cell edge and content, expected `1` space, remove `1` space - * 11:12: Unexpected `3` spaces between cell content and edge, expected between `1` (unaligned) and `2` (aligned) spaces, remove between `1` and `2` spaces - * - * @example - * {"config": "compact", "gfm": true, "name": "ok.md"} - * - * |Planet |Symbol|Satellites|Mean anomaly (°)| - * |-------|:-----|:--------:|---------------:| - * |Mercury|☿ | None | 174 796| - * - * |Planet|Symbol|Satellites|Mean anomaly (°)| - * |-|:-|:-:|-:| - * |Venus|♀|None|50 115| - * - * @example - * {"config": "compact", "gfm": true, "label": "input", "name": "not-ok.md"} - * - * | Planet | - * | -------| - * | Mercury| - * - * |Planet | - * |------ | - * |Venus | - * - * | Planet | - * | ------ | - * | Venus | - * @example - * {"config": "compact", "gfm": true, "label": "output", "name": "not-ok.md"} - * - * 1:3: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 2:3: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 3:3: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 5:9: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 6:9: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 7:9: Unexpected `2` spaces between cell content and edge, expected between `0` (unaligned) and `1` (aligned) space, remove between `1` and `2` spaces - * 9:4: Unexpected `2` spaces between cell edge and content, expected `0` spaces, remove `2` spaces - * 9:12: Unexpected `2` spaces between cell content and edge, expected `0` spaces, remove `2` spaces - * 10:4: Unexpected `2` spaces between cell edge and content, expected `0` spaces, remove `2` spaces - * 10:12: Unexpected `2` spaces between cell content and edge, expected `0` spaces, remove `2` spaces - * 11:4: Unexpected `2` spaces between cell edge and content, expected `0` spaces, remove `2` spaces - * 11:12: Unexpected `3` spaces between cell content and edge, expected between `0` (unaligned) and `1` (aligned) space, remove between `2` and `3` spaces - * - * @example - * {"gfm": true, "name": "consistent-padded-ok.md"} - * - * | Planet | - * | - | - * - * @example - * {"gfm": true, "label": "input", "name": "consistent-padded-nok.md"} - * - * | Planet| - * | - | - * @example - * {"gfm": true, "label": "output", "name": "consistent-padded-nok.md"} - * - * 1:9: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * - * @example - * {"gfm": true, "name": "consistent-compact-ok.md"} - * - * |Planet| - * |-| - * - * @example - * {"gfm": true, "label": "input", "name": "consistent-compact-nok.md"} - * - * |Planet | - * |-| - * @example - * {"gfm": true, "label": "output", "name": "consistent-compact-nok.md"} - * - * 1:9: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * - * @example - * {"gfm": true, "name": "empty.md"} - * - * | | Satellites | - * | - | - | - * | Mercury | | - * - * @example - * {"gfm": true, "name": "missing-cells.md"} - * - * | Planet | Symbol | Satellites | - * | - | - | - | - * | Mercury | - * | Venus | ♀ | - * | Earth | 🜨 and ♁ | 1 | - * | Mars | ♂ | 2 | 19 412 | - * - * @example - * {"config": "padded", "gfm": true, "label": "input", "name": "missing-fences.md"} - * - * ␠Planet|Symbol|Satellites - * ------:|:-----|---------- - * Mercury|☿ |0 - * - * Planet|Symbol - * -----:|------ - * ␠Venus|♀ - * @example - * {"config": "padded", "gfm": true, "label": "output", "name": "missing-fences.md"} - * - * 1:8: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 1:9: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 1:15: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 1:16: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 2:8: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 2:9: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 2:15: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 2:16: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 3:8: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 3:9: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 3:16: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 5:7: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 5:8: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 6:7: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 6:8: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 7:7: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 7:8: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * - * @example - * {"config": "compact", "gfm": true, "label": "input", "name": "missing-fences.md"} - * - * Planet | Symbol | Satellites - * -: | - | - - * Mercury | ☿ | 0 - * - * Planet | Symbol - * -----: | ------ - * ␠Venus | ♀ - * @example - * {"config": "compact", "gfm": true, "label": "output", "name": "missing-fences.md"} - * - * 1:8: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 1:10: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 1:17: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 1:19: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 2:4: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 2:6: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 2:10: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 3:9: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 3:11: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 3:15: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 5:8: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 5:10: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 6:8: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 6:10: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 7:8: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 7:10: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * - * @example - * {"config": "compact", "gfm": true, "label": "input", "name": "trailing-spaces.md"} - * - * Planet | Symbol␠ - * -: | -␠ - * Mercury | ☿␠␠ - * - * | Planet | Symbol |␠ - * | ------ | ------ |␠ - * | Venus | ♀ |␠␠ - * @example - * {"config": "compact", "gfm": true, "label": "output", "name": "trailing-spaces.md"} - * - * 1:8: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 1:10: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 2:4: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 2:6: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 3:9: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 3:11: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 5:3: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 5:10: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 5:12: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 5:19: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 6:3: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 6:10: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 6:12: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 6:19: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 7:3: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 7:10: Unexpected `2` spaces between cell content and edge, expected between `0` (unaligned) and `1` (aligned) space, remove between `1` and `2` spaces - * 7:12: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 7:19: Unexpected `6` spaces between cell content and edge, expected between `0` (unaligned) and `5` (aligned) spaces, remove between `1` and `6` spaces - * - * @example - * {"config": "compact", "gfm": true, "label": "input", "name": "nothing.md"} - * - * | | | | - * | - | - | - | - * | | | | - * @example - * {"config": "compact", "gfm": true, "label": "output", "name": "nothing.md"} - * - * 1:5: Unexpected `3` spaces between cell edge and content, expected between `0` (unaligned) and `1` (aligned) space, remove between `2` and `3` spaces - * 1:9: Unexpected `3` spaces between cell edge and content, expected between `0` (unaligned) and `1` (aligned) space, remove between `2` and `3` spaces - * 1:13: Unexpected `3` spaces between cell edge and content, expected between `0` (unaligned) and `1` (aligned) space, remove between `2` and `3` spaces - * 2:3: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 2:5: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 2:7: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 2:9: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 2:11: Unexpected `1` space between cell edge and content, expected `0` spaces, remove `1` space - * 2:13: Unexpected `1` space between cell content and edge, expected `0` spaces, remove `1` space - * 3:5: Unexpected `3` spaces between cell edge and content, expected between `0` (unaligned) and `1` (aligned) space, remove between `2` and `3` spaces - * 3:9: Unexpected `3` spaces between cell edge and content, expected between `0` (unaligned) and `1` (aligned) space, remove between `2` and `3` spaces - * 3:13: Unexpected `3` spaces between cell edge and content, expected between `0` (unaligned) and `1` (aligned) space, remove between `2` and `3` spaces - * - * @example - * {"config": "padded", "gfm": true, "label": "input", "name": "nothing.md"} - * - * |||| - * |-|-|-| - * |||| - * @example - * {"config": "padded", "gfm": true, "label": "output", "name": "nothing.md"} - * - * 1:2: Unexpected `0` spaces between cell edge and content, expected between `1` (unaligned) and `3` (aligned) spaces, add between `3` and `1` space - * 1:3: Unexpected `0` spaces between cell edge and content, expected between `1` (unaligned) and `3` (aligned) spaces, add between `3` and `1` space - * 1:4: Unexpected `0` spaces between cell edge and content, expected between `1` (unaligned) and `3` (aligned) spaces, add between `3` and `1` space - * 2:2: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 2:3: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 2:4: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 2:5: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 2:6: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 2:7: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 3:2: Unexpected `0` spaces between cell edge and content, expected between `1` (unaligned) and `3` (aligned) spaces, add between `3` and `1` space - * 3:3: Unexpected `0` spaces between cell edge and content, expected between `1` (unaligned) and `3` (aligned) spaces, add between `3` and `1` space - * 3:4: Unexpected `0` spaces between cell edge and content, expected between `1` (unaligned) and `3` (aligned) spaces, add between `3` and `1` space - * - * @example - * {"config": "padded", "gfm": true, "label": "input", "name": "more-weirdness.md"} - * - * Mercury - * |- - * - * Venus - * -| - * @example - * {"config": "padded", "gfm": true, "label": "output", "name": "more-weirdness.md"} - * - * 2:2: Unexpected `0` spaces between cell edge and content, expected `1` space, add `1` space - * 5:2: Unexpected `0` spaces between cell content and edge, expected between `1` (unaligned) and `5` (aligned) spaces, add between `5` and `1` space - * - * @example - * {"config": "padded", "gfm": true, "label": "input", "name": "containers.md"} - * - * > | Mercury| - * > | - | - * - * * | Venus| - * | - | - * - * > * > | Earth| - * > > | - | - * @example - * {"config": "padded", "gfm": true, "label": "output", "name": "containers.md"} - * - * 1:12: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 4:10: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * 7:14: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * - * @example - * {"config": "padded", "gfm": true, "label": "input", "name": "windows.md"} - * - * | Mercury|␍␊| --- |␍␊| None | - * @example - * {"config": "padded", "gfm": true, "label": "output", "name": "windows.md"} - * - * 1:10: Unexpected `0` spaces between cell content and edge, expected `1` space, add `1` space - * - * @example - * {"config": "🌍", "gfm": true, "label": "output", "name": "not-ok.md", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected `'compact'`, `'padded'`, or `'consistent'` - */ -const remarkLintTableCellPadding = lintRule$1( - { - origin: 'remark-lint:table-cell-padding', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-table-cell-padding#readme' - }, - function (tree, file, options) { - const value = String(file); - let expected; - let cause; - if (options === null || options === undefined || options === 'consistent') ; else if (options === 'compact' || options === 'padded') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected `'compact'`, `'padded'`, or `'consistent'`" - ); - } - visitParents(tree, function (table, parents) { - if (phrasing(table)) { - return SKIP - } - if (table.type !== 'table') return - const entries = inferTable([...parents, table]); - const sizes = []; - for (const entry of entries) { - if ( - entry.size && - (sizes[entry.column] === undefined || - entry.size.middle > sizes[entry.column]) - ) { - sizes[entry.column] = entry.size.middle; - } - } - if (!expected) { - for (const info of entries) { - if ( - info.size && - info.size.middle && - info.size.middle === sizes[info.column] - ) { - const node = info.ancestors.at(-1); - expected = info.size.left ? 'padded' : 'compact'; - cause = new VFileMessage( - "Cell padding style `'" + - expected + - "'` first defined for `'consistent'` here", - { - ancestors: info.ancestors, - place: node.position, - ruleId: 'table-cell-padding', - source: 'remark-lint' - } - ); - } - } - } - if (!expected) return - for (const info of entries) { - checkSide('left', info, sizes); - checkSide('right', info, sizes); - } - return SKIP - }); - function checkSide(side, info, sizes) { - if (!info.size) { - return - } - const actual = info.size[side]; - if (actual === undefined) { - return - } - const alignSpaces = sizes[info.column] - info.size.middle; - const min = expected === 'compact' ? 0 : 1; - let max = min; - if (info.align === 'center') { - max += Math.ceil(alignSpaces / 2); - } else if (info.align === 'right' ? side === 'left' : side === 'right') { - max += alignSpaces; - } - if (info.size.middle === 0) { - if (side === 'right') return - max = Math.max(max, sizes[info.column] + 2 * min); - } - if (actual < min || actual > max) { - const differenceMin = min - actual; - const differenceMinAbsolute = Math.abs(differenceMin); - const differenceMax = max - actual; - const differenceMaxAbsolute = Math.abs(differenceMax); - file.message( - 'Unexpected `' + - actual + - '` ' + - pluralize('space', actual) + - ' between cell ' + - (side === 'left' ? 'edge' : 'content') + - ' and ' + - (side === 'left' ? 'content' : 'edge') + - ', expected ' + - (min === max ? '' : 'between `' + min + '` (unaligned) and ') + - '`' + - max + - '` ' + - (min === max ? '' : '(aligned) ') + - pluralize('space', max) + - ', ' + - (differenceMin < 0 ? 'remove' : 'add') + - (differenceMin === differenceMax - ? '' - : ' between `' + differenceMaxAbsolute + '` and') + - ' `' + - differenceMinAbsolute + - '` ' + - pluralize('space', differenceMinAbsolute), - { - ancestors: info.ancestors, - cause, - place: side === 'left' ? info.size.leftPoint : info.size.rightPoint - } - ); - } - } - function inferTable(ancestors) { - const node = ancestors.at(-1); - ok$1(node.type === 'table'); - const align = node.align || []; - const result = []; - let rowIndex = -1; - while (++rowIndex < node.children.length) { - const row = node.children[rowIndex]; - let column = -1; - while (++column < row.children.length) { - const node = row.children[column]; - result.push({ - align: align[column], - ancestors: [...ancestors, row, node], - column, - size: inferSize( - pointStart(node), - pointEnd(node), - column === row.children.length - 1 - ) - }); - } - if (rowIndex === 0) { - const alignRow = inferAlignRow(ancestors, align); - if (alignRow) result.push(...alignRow); - } - } - return result - } - function inferAlignRow(ancestors, align) { - const node = ancestors.at(-1); - ok$1(node.type === 'table'); - const headEnd = pointEnd(node.children[0]); - if (!headEnd || typeof headEnd.offset !== 'number') return - let index = headEnd.offset; - if (value.charCodeAt(index) === 13 ) index++; - if (value.charCodeAt(index) !== 10 ) return - index++; - const result = []; - const line = headEnd.line + 1; - let code = value.charCodeAt(index); - while ( - code === 9 || - code === 32 || - code === 62 - ) { - index++; - code = value.charCodeAt(index); - } - if ( - code !== 45 && - code !== 58 && - code !== 124 - ) { - return - } - let lineEndOffset = value.indexOf('\n', index); - if (lineEndOffset === -1) lineEndOffset = value.length; - if (value.charCodeAt(lineEndOffset - 1) === 13 ) lineEndOffset--; - let column = 0; - let cellStart = index; - let cellEnd = value.indexOf('|', index + (code === 124 ? 1 : 0)); - if (cellEnd === -1 || cellEnd > lineEndOffset) { - cellEnd = lineEndOffset; - } - while (cellStart !== cellEnd) { - let nextCellEnd = value.indexOf('|', cellEnd + 1); - if (nextCellEnd === -1 || nextCellEnd > lineEndOffset) { - nextCellEnd = lineEndOffset; - } - if (nextCellEnd === lineEndOffset) { - let maybeEnd = lineEndOffset; - let code = value.charCodeAt(maybeEnd - 1); - while (code === 9 || code === 32 ) { - maybeEnd--; - code = value.charCodeAt(maybeEnd - 1); - } - if (cellEnd + 1 === maybeEnd) { - cellEnd = lineEndOffset; - } - } - result.push({ - align: align[column], - ancestors, - column, - size: inferSize( - { - line, - column: cellStart - index + 1, - offset: cellStart - }, - {line, column: cellEnd - index + 1, offset: cellEnd}, - cellEnd === lineEndOffset - ) - }); - cellStart = cellEnd; - cellEnd = nextCellEnd; - column++; - } - return result - } - function inferSize(start, end, tailCell) { - if ( - end && - start && - typeof end.offset === 'number' && - typeof start.offset === 'number' - ) { - let leftIndex = start.offset; - let left; - let right; - if (value.charCodeAt(leftIndex) === 124 ) { - left = 0; - leftIndex++; - while (value.charCodeAt(leftIndex) === 32) { - left++; - leftIndex++; - } - } - let rightIndex = end.offset; - if (tailCell) { - while (value.charCodeAt(rightIndex - 1) === 32) { - rightIndex--; - } - if ( - rightIndex > leftIndex && - value.charCodeAt(rightIndex - 1) === 124 - ) { - rightIndex--; - } - else { - rightIndex = end.offset; - } - } - const rightEdgeIndex = rightIndex; - if (value.charCodeAt(rightIndex) === 124 ) { - right = 0; - while ( - rightIndex - 1 > leftIndex && - value.charCodeAt(rightIndex - 1) === 32 - ) { - right++; - rightIndex--; - } - } - return { - left, - leftPoint: { - line: start.line, - column: start.column + (leftIndex - start.offset), - offset: leftIndex - }, - middle: rightIndex - leftIndex, - right, - rightPoint: { - line: end.line, - column: end.column - (end.offset - rightEdgeIndex), - offset: rightEdgeIndex - } - } - } - } - } -); - -/** - * remark-lint rule to warn when GFM table rows have no initial or - * final cell delimiter. - * - * ## What is this? - * - * This package checks that table rows have initial and final delimiters. - * Tables are a GFM feature enabled with [`remark-gfm`][github-remark-gfm]. - * - * ## When should I use this? - * - * You can use this package to check that tables are consistent. - * - * ## API - * - * ### `unified().use(remarkLintTablePipes)` - * - * Warn when GFM table rows have no initial or final cell delimiter. - * - * ###### Parameters - * - * There are no options. - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ## Recommendation - * - * While tables don’t require initial or final delimiters (the pipes before the - * first and after the last cells in a row), - * it arguably does look weird without. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] with - * [`remark-gfm`][github-remark-gfm] formats all tables with initial and final - * delimiters. - * - * [api-remark-lint-table-pipes]: #unifieduseremarklinttablepipes - * [github-remark-gfm]: https://github.com/remarkjs/remark-gfm - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module table-pipes - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * - * @example - * {"name": "ok.md", "gfm": true} - * - * Small table: - * - * | Planet | Mean anomaly (°) | - * | :- | -: | - * | Mercury | 174 796 | - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * Planet | Mean anomaly (°) - * :- | -: - * Mercury | 174 796 - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 1:1: Unexpected missing closing pipe in row, expected `|` - * 1:26: Unexpected missing opening pipe in row, expected `|` - * 2:1: Unexpected missing closing pipe in row, expected `|` - * 2:8: Unexpected missing opening pipe in row, expected `|` - * 3:1: Unexpected missing closing pipe in row, expected `|` - * 3:18: Unexpected missing opening pipe in row, expected `|` - * - * @example - * {"gfm": true, "label": "input", "name": "missing-cells.md"} - * - * Planet | Symbol | Satellites - * :- | - | - - * Mercury - * Venus | ♀ - * Earth | ♁ | 1 - * Mars | ♂ | 2 | 19 412 - * @example - * {"gfm": true, "label": "output", "name": "missing-cells.md"} - * - * 1:1: Unexpected missing closing pipe in row, expected `|` - * 1:29: Unexpected missing opening pipe in row, expected `|` - * 2:1: Unexpected missing closing pipe in row, expected `|` - * 2:11: Unexpected missing opening pipe in row, expected `|` - * 3:1: Unexpected missing closing pipe in row, expected `|` - * 3:8: Unexpected missing opening pipe in row, expected `|` - * 4:1: Unexpected missing closing pipe in row, expected `|` - * 4:10: Unexpected missing opening pipe in row, expected `|` - * 5:1: Unexpected missing closing pipe in row, expected `|` - * 5:14: Unexpected missing opening pipe in row, expected `|` - * 6:1: Unexpected missing closing pipe in row, expected `|` - * 6:22: Unexpected missing opening pipe in row, expected `|` - * - * @example - * {"gfm": true, "label": "input", "name": "trailing-spaces.md"} - * - * ␠␠Planet␠␠ - * ␠-:␠ - * - * ␠␠| Planet |␠␠ - * ␠| -: |␠ - * @example - * {"gfm": true, "label": "output", "name": "trailing-spaces.md"} - * - * 1:3: Unexpected missing closing pipe in row, expected `|` - * 1:11: Unexpected missing opening pipe in row, expected `|` - * 2:2: Unexpected missing closing pipe in row, expected `|` - * 2:5: Unexpected missing opening pipe in row, expected `|` - * - * @example - * {"gfm": true, "label": "input", "name": "windows.md"} - * - * Mercury␍␊:-␍␊None - * @example - * {"gfm": true, "label": "output", "name": "windows.md"} - * - * 1:1: Unexpected missing closing pipe in row, expected `|` - * 1:8: Unexpected missing opening pipe in row, expected `|` - * 2:1: Unexpected missing closing pipe in row, expected `|` - * 2:3: Unexpected missing opening pipe in row, expected `|` - * 3:1: Unexpected missing closing pipe in row, expected `|` - * 3:5: Unexpected missing opening pipe in row, expected `|` - */ -const remarkLintTablePipes = lintRule$1( - { - origin: 'remark-lint:table-pipes', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-table-pipes#readme' - }, - function (tree, file) { - const value = String(file); - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'table') return - let index = -1; - while (++index < node.children.length) { - const row = node.children[index]; - const start = pointStart(row); - const end = pointEnd(row); - if (start && typeof start.offset === 'number') { - checkStart(start.offset, start, [...parents, node, row]); - } - if (end && typeof end.offset === 'number') { - checkEnd(end.offset, end, [...parents, node, row]); - if (index === 0) { - let index = end.offset; - if (value.charCodeAt(index) === 13 ) index++; - if (value.charCodeAt(index) !== 10 ) continue - index++; - const lineStart = index; - let code = value.charCodeAt(index); - while ( - code === 9 || - code === 32 || - code === 62 - ) { - index++; - code = value.charCodeAt(index); - } - checkStart( - index, - { - line: end.line + 1, - column: index - lineStart + 1, - offset: index - }, - [...parents, node] - ); - index = value.indexOf('\n', index); - if (index === -1) index = value.length; - if (value.charCodeAt(index - 1) === 13 ) index--; - checkEnd( - index, - { - line: end.line + 1, - column: index - lineStart + 1, - offset: index - }, - [...parents, node] - ); - } - } - } - return SKIP - }); - function checkStart(index, place, ancestors) { - let code = value.charCodeAt(index); - while (code === 9 || code === 32 ) { - code = value.charCodeAt(++index); - } - if (code !== 124 ) { - file.message('Unexpected missing closing pipe in row, expected `|`', { - ancestors, - place - }); - } - } - function checkEnd(index, place, ancestors) { - let code = value.charCodeAt(index - 1); - while (code === 9 || code === 32 ) { - index--; - code = value.charCodeAt(index - 1); - } - if (code !== 124 ) { - file.message('Unexpected missing opening pipe in row, expected `|`', { - ancestors, - place - }); - } - } - } -); - -/** - * remark-lint rule to warn when unordered list markers are inconsistent. - * - * ## What is this? - * - * This package checks unordered list markers. - * - * ## When should I use this? - * - * You can use this package to check unordered lists. - * - * ## API - * - * ### `unified().use(remarkLintUnorderedListMarkerStyle[, options])` - * - * Warn when unordered list markers are inconsistent. - * - * ###### Parameters - * - * * `options` ([`Options`][api-options], default: `'consistent'`) - * — preferred style or whether to detect the first style and warn for - * further differences - * - * ###### Returns - * - * Transform ([`Transformer` from `unified`][github-unified-transformer]). - * - * ### `Options` - * - * Configuration (TypeScript type). - * - * ###### Type - * - * ```ts - * type Options = Style | 'consistent' - * ``` - * - * ### `Style` - * - * Style (TypeScript type). - * - * ###### Type - * - * ```ts - * type Style = '*' | '+' | '-' - * ``` - * - * ## Recommendation - * - * Because asterisks can be used as a marker for more markdown constructs, - * it’s recommended to use that for lists (and thematic breaks, emphasis, - * strong) too. - * - * ## Fix - * - * [`remark-stringify`][github-remark-stringify] formats unordered lists with - * asterisks by default. - * Pass `bullet: '+'` or `bullet: '-'` to use a different marker. - * - * [api-options]: #options - * [api-style]: #style - * [api-remark-lint-unordered-list-marker-style]: #unifieduseremarklintunorderedlistmarkerstyle-options - * [github-remark-stringify]: https://github.com/remarkjs/remark/tree/main/packages/remark-stringify - * [github-unified-transformer]: https://github.com/unifiedjs/unified#transformer - * - * @module unordered-list-marker-style - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @example - * {"name": "ok.md"} - * - * * Mercury - * - * 1. Venus - * - * * Earth - * - * @example - * {"name": "ok.md", "config": "*"} - * - * * Mercury - * - * @example - * {"name": "ok.md", "config": "-"} - * - * - Mercury - * - * @example - * {"name": "ok.md", "config": "+"} - * - * + Mercury - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * * Mercury - * - * - Venus - * - * + Earth - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:1: Unexpected unordered list marker `-`, expected `*` - * 5:1: Unexpected unordered list marker `+`, expected `*` - * - * @example - * {"name": "not-ok.md", "label": "output", "config": "🌍", "positionless": true} - * - * 1:1: Unexpected value `🌍` for `options`, expected `'*'`, `'+'`, `'-'`, or `'consistent'` - */ -const remarkLintUnorderedListMarkerStyle = lintRule$1( - { - origin: 'remark-lint:unordered-list-marker-style', - url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-unordered-list-marker-style#readme' - }, - function (tree, file, options) { - const value = String(file); - let expected; - let cause; - if (options === null || options === undefined || options === 'consistent') ; else if (options === '*' || options === '+' || options === '-') { - expected = options; - } else { - file.fail( - 'Unexpected value `' + - options + - "` for `options`, expected `'*'`, `'+'`, `'-'`, or `'consistent'`" - ); - } - visitParents(tree, function (node, parents) { - if (phrasing(node)) { - return SKIP - } - if (node.type !== 'listItem') return - const parent = parents.at(-1); - if (!parent || parent.type !== 'list' || parent.ordered) return - const place = pointStart(node); - if (!place || typeof place.offset !== 'number') return - const code = value.charCodeAt(place.offset); - const actual = - code === 42 - ? '*' - : code === 43 - ? '+' - : code === 45 - ? '-' - : - undefined; - if (!actual) return - if (expected) { - if (actual !== expected) { - file.message( - 'Unexpected unordered list marker `' + - actual + - '`, expected `' + - expected + - '`', - {ancestors: [...parents, node], cause, place} - ); - } - } else { - expected = actual; - cause = new VFileMessage( - 'Unordered list marker style `' + - expected + - "` first defined for `'consistent'` here", - { - ancestors: [...parents, node], - place, - ruleId: 'unordered-list-marker-style', - source: 'remark-lint' - } - ); - } - }); - } -); - -const plugins = [ - remarkGfm, - remarkPresetLintRecommended, - [remarkLintBlockquoteIndentation, 2], - [remarkLintCheckboxCharacterStyle, { checked: "x", unchecked: " " }], - remarkLintCheckboxContentIndent, - [remarkLintCodeBlockStyle, "fenced"], - remarkLintDefinitionSpacing, - [ - remarkLintFencedCodeFlag, - { - flags: [ - "bash", - "c", - "cjs", - "coffee", - "console", - "cpp", - "diff", - "http", - "js", - "json", - "markdown", - "mjs", - "powershell", - "r", - "text", - "ts", - ], - }, - ], - [remarkLintFencedCodeMarker, "`"], - [remarkLintFileExtension, "md"], - remarkLintFinalDefinition, - [remarkLintFirstHeadingLevel, 1], - [remarkLintHeadingStyle, "atx"], - [remarkLintMaximumLineLength, 120], - remarkLintNoConsecutiveBlankLines, - remarkLintNoFileNameArticles, - remarkLintNoFileNameConsecutiveDashes, - remarkLintNofileNameOuterDashes, - remarkLintNoHeadingIndent, - remarkLintNoMultipleToplevelHeadings, - remarkLintNoShellDollars, - remarkLintNoTableIndentation, - remarkLintNoTabs, - rule, - remarkLintNodejsLinks, - remarkLintNodejsYamlComments, - [ - remarkLintProhibitedStrings, - [ - { yes: "End-of-Life" }, - { no: "filesystem", yes: "file system" }, - { yes: "GitHub" }, - { no: "hostname", yes: "host name" }, - { yes: "JavaScript" }, - { no: "[Ll]ong[ -][Tt]erm [Ss]upport", yes: "Long Term Support" }, - { no: "Node", yes: "Node.js", ignoreNextTo: "-API" }, - { yes: "Node.js" }, - { no: "Node[Jj][Ss]", yes: "Node.js" }, - { no: "Node\\.js's?", yes: "the Node.js" }, - { no: "[Nn]ote that", yes: "" }, - { yes: "RFC" }, - { no: "[Rr][Ff][Cc]\\d+", yes: "RFC " }, - { yes: "TypeScript" }, - { yes: "Unix" }, - { yes: "Valgrind" }, - { yes: "V8" }, - ], - ], - remarkLintRuleStyle, - [remarkLintStrongMarker, "*"], - [remarkLintTableCellPadding, "padded"], - remarkLintTablePipes, - [remarkLintUnorderedListMarkerStyle, "*"], -]; -const settings = { - emphasis: "_", - tightDefinitions: true, -}; -const remarkPresetLintNode = { plugins, settings }; - -function read(description, options, callback) { - const file = toVFile(description); - { - return new Promise(executor) - } - function executor(resolve, reject) { - let fp; - try { - fp = minpath.resolve(file.cwd, file.path); - } catch (error) { - const exception = (error); - return reject(exception) - } - fs$1.readFile(fp, options, done); - function done(error, result) { - if (error) { - reject(error); - } else { - file.value = result; - resolve(file); - } - } - } -} -function toVFile(description) { - if (typeof description === 'string' || description instanceof URL) { - description = {path: description}; - } else if (isUint8Array(description)) { - description = {path: new TextDecoder().decode(description)}; - } - return looksLikeAVFile(description) ? description : new VFile(description) -} -function looksLikeAVFile(value) { - return Boolean( - value && - typeof value === 'object' && - 'message' in value && - 'messages' in value - ) -} -function isUint8Array(value) { - return Boolean( - value && - typeof value === 'object' && - 'byteLength' in value && - 'byteOffset' in value - ) -} - -function ansiRegex({onlyFirst = false} = {}) { - const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)'; - const pattern = [ - `[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`, - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))', - ].join('|'); - return new RegExp(pattern, onlyFirst ? undefined : 'g'); -} - -const regex = ansiRegex(); -function stripAnsi(string) { - if (typeof string !== 'string') { - throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); - } - return string.replace(regex, ''); -} - -var eastasianwidth = {exports: {}}; - -var hasRequiredEastasianwidth; -function requireEastasianwidth () { - if (hasRequiredEastasianwidth) return eastasianwidth.exports; - hasRequiredEastasianwidth = 1; - (function (module) { - var eaw = {}; - { - module.exports = eaw; - } - eaw.eastAsianWidth = function(character) { - var x = character.charCodeAt(0); - var y = (character.length == 2) ? character.charCodeAt(1) : 0; - var codePoint = x; - if ((0xD800 <= x && x <= 0xDBFF) && (0xDC00 <= y && y <= 0xDFFF)) { - x &= 0x3FF; - y &= 0x3FF; - codePoint = (x << 10) | y; - codePoint += 0x10000; - } - if ((0x3000 == codePoint) || - (0xFF01 <= codePoint && codePoint <= 0xFF60) || - (0xFFE0 <= codePoint && codePoint <= 0xFFE6)) { - return 'F'; - } - if ((0x20A9 == codePoint) || - (0xFF61 <= codePoint && codePoint <= 0xFFBE) || - (0xFFC2 <= codePoint && codePoint <= 0xFFC7) || - (0xFFCA <= codePoint && codePoint <= 0xFFCF) || - (0xFFD2 <= codePoint && codePoint <= 0xFFD7) || - (0xFFDA <= codePoint && codePoint <= 0xFFDC) || - (0xFFE8 <= codePoint && codePoint <= 0xFFEE)) { - return 'H'; - } - if ((0x1100 <= codePoint && codePoint <= 0x115F) || - (0x11A3 <= codePoint && codePoint <= 0x11A7) || - (0x11FA <= codePoint && codePoint <= 0x11FF) || - (0x2329 <= codePoint && codePoint <= 0x232A) || - (0x2E80 <= codePoint && codePoint <= 0x2E99) || - (0x2E9B <= codePoint && codePoint <= 0x2EF3) || - (0x2F00 <= codePoint && codePoint <= 0x2FD5) || - (0x2FF0 <= codePoint && codePoint <= 0x2FFB) || - (0x3001 <= codePoint && codePoint <= 0x303E) || - (0x3041 <= codePoint && codePoint <= 0x3096) || - (0x3099 <= codePoint && codePoint <= 0x30FF) || - (0x3105 <= codePoint && codePoint <= 0x312D) || - (0x3131 <= codePoint && codePoint <= 0x318E) || - (0x3190 <= codePoint && codePoint <= 0x31BA) || - (0x31C0 <= codePoint && codePoint <= 0x31E3) || - (0x31F0 <= codePoint && codePoint <= 0x321E) || - (0x3220 <= codePoint && codePoint <= 0x3247) || - (0x3250 <= codePoint && codePoint <= 0x32FE) || - (0x3300 <= codePoint && codePoint <= 0x4DBF) || - (0x4E00 <= codePoint && codePoint <= 0xA48C) || - (0xA490 <= codePoint && codePoint <= 0xA4C6) || - (0xA960 <= codePoint && codePoint <= 0xA97C) || - (0xAC00 <= codePoint && codePoint <= 0xD7A3) || - (0xD7B0 <= codePoint && codePoint <= 0xD7C6) || - (0xD7CB <= codePoint && codePoint <= 0xD7FB) || - (0xF900 <= codePoint && codePoint <= 0xFAFF) || - (0xFE10 <= codePoint && codePoint <= 0xFE19) || - (0xFE30 <= codePoint && codePoint <= 0xFE52) || - (0xFE54 <= codePoint && codePoint <= 0xFE66) || - (0xFE68 <= codePoint && codePoint <= 0xFE6B) || - (0x1B000 <= codePoint && codePoint <= 0x1B001) || - (0x1F200 <= codePoint && codePoint <= 0x1F202) || - (0x1F210 <= codePoint && codePoint <= 0x1F23A) || - (0x1F240 <= codePoint && codePoint <= 0x1F248) || - (0x1F250 <= codePoint && codePoint <= 0x1F251) || - (0x20000 <= codePoint && codePoint <= 0x2F73F) || - (0x2B740 <= codePoint && codePoint <= 0x2FFFD) || - (0x30000 <= codePoint && codePoint <= 0x3FFFD)) { - return 'W'; - } - if ((0x0020 <= codePoint && codePoint <= 0x007E) || - (0x00A2 <= codePoint && codePoint <= 0x00A3) || - (0x00A5 <= codePoint && codePoint <= 0x00A6) || - (0x00AC == codePoint) || - (0x00AF == codePoint) || - (0x27E6 <= codePoint && codePoint <= 0x27ED) || - (0x2985 <= codePoint && codePoint <= 0x2986)) { - return 'Na'; - } - if ((0x00A1 == codePoint) || - (0x00A4 == codePoint) || - (0x00A7 <= codePoint && codePoint <= 0x00A8) || - (0x00AA == codePoint) || - (0x00AD <= codePoint && codePoint <= 0x00AE) || - (0x00B0 <= codePoint && codePoint <= 0x00B4) || - (0x00B6 <= codePoint && codePoint <= 0x00BA) || - (0x00BC <= codePoint && codePoint <= 0x00BF) || - (0x00C6 == codePoint) || - (0x00D0 == codePoint) || - (0x00D7 <= codePoint && codePoint <= 0x00D8) || - (0x00DE <= codePoint && codePoint <= 0x00E1) || - (0x00E6 == codePoint) || - (0x00E8 <= codePoint && codePoint <= 0x00EA) || - (0x00EC <= codePoint && codePoint <= 0x00ED) || - (0x00F0 == codePoint) || - (0x00F2 <= codePoint && codePoint <= 0x00F3) || - (0x00F7 <= codePoint && codePoint <= 0x00FA) || - (0x00FC == codePoint) || - (0x00FE == codePoint) || - (0x0101 == codePoint) || - (0x0111 == codePoint) || - (0x0113 == codePoint) || - (0x011B == codePoint) || - (0x0126 <= codePoint && codePoint <= 0x0127) || - (0x012B == codePoint) || - (0x0131 <= codePoint && codePoint <= 0x0133) || - (0x0138 == codePoint) || - (0x013F <= codePoint && codePoint <= 0x0142) || - (0x0144 == codePoint) || - (0x0148 <= codePoint && codePoint <= 0x014B) || - (0x014D == codePoint) || - (0x0152 <= codePoint && codePoint <= 0x0153) || - (0x0166 <= codePoint && codePoint <= 0x0167) || - (0x016B == codePoint) || - (0x01CE == codePoint) || - (0x01D0 == codePoint) || - (0x01D2 == codePoint) || - (0x01D4 == codePoint) || - (0x01D6 == codePoint) || - (0x01D8 == codePoint) || - (0x01DA == codePoint) || - (0x01DC == codePoint) || - (0x0251 == codePoint) || - (0x0261 == codePoint) || - (0x02C4 == codePoint) || - (0x02C7 == codePoint) || - (0x02C9 <= codePoint && codePoint <= 0x02CB) || - (0x02CD == codePoint) || - (0x02D0 == codePoint) || - (0x02D8 <= codePoint && codePoint <= 0x02DB) || - (0x02DD == codePoint) || - (0x02DF == codePoint) || - (0x0300 <= codePoint && codePoint <= 0x036F) || - (0x0391 <= codePoint && codePoint <= 0x03A1) || - (0x03A3 <= codePoint && codePoint <= 0x03A9) || - (0x03B1 <= codePoint && codePoint <= 0x03C1) || - (0x03C3 <= codePoint && codePoint <= 0x03C9) || - (0x0401 == codePoint) || - (0x0410 <= codePoint && codePoint <= 0x044F) || - (0x0451 == codePoint) || - (0x2010 == codePoint) || - (0x2013 <= codePoint && codePoint <= 0x2016) || - (0x2018 <= codePoint && codePoint <= 0x2019) || - (0x201C <= codePoint && codePoint <= 0x201D) || - (0x2020 <= codePoint && codePoint <= 0x2022) || - (0x2024 <= codePoint && codePoint <= 0x2027) || - (0x2030 == codePoint) || - (0x2032 <= codePoint && codePoint <= 0x2033) || - (0x2035 == codePoint) || - (0x203B == codePoint) || - (0x203E == codePoint) || - (0x2074 == codePoint) || - (0x207F == codePoint) || - (0x2081 <= codePoint && codePoint <= 0x2084) || - (0x20AC == codePoint) || - (0x2103 == codePoint) || - (0x2105 == codePoint) || - (0x2109 == codePoint) || - (0x2113 == codePoint) || - (0x2116 == codePoint) || - (0x2121 <= codePoint && codePoint <= 0x2122) || - (0x2126 == codePoint) || - (0x212B == codePoint) || - (0x2153 <= codePoint && codePoint <= 0x2154) || - (0x215B <= codePoint && codePoint <= 0x215E) || - (0x2160 <= codePoint && codePoint <= 0x216B) || - (0x2170 <= codePoint && codePoint <= 0x2179) || - (0x2189 == codePoint) || - (0x2190 <= codePoint && codePoint <= 0x2199) || - (0x21B8 <= codePoint && codePoint <= 0x21B9) || - (0x21D2 == codePoint) || - (0x21D4 == codePoint) || - (0x21E7 == codePoint) || - (0x2200 == codePoint) || - (0x2202 <= codePoint && codePoint <= 0x2203) || - (0x2207 <= codePoint && codePoint <= 0x2208) || - (0x220B == codePoint) || - (0x220F == codePoint) || - (0x2211 == codePoint) || - (0x2215 == codePoint) || - (0x221A == codePoint) || - (0x221D <= codePoint && codePoint <= 0x2220) || - (0x2223 == codePoint) || - (0x2225 == codePoint) || - (0x2227 <= codePoint && codePoint <= 0x222C) || - (0x222E == codePoint) || - (0x2234 <= codePoint && codePoint <= 0x2237) || - (0x223C <= codePoint && codePoint <= 0x223D) || - (0x2248 == codePoint) || - (0x224C == codePoint) || - (0x2252 == codePoint) || - (0x2260 <= codePoint && codePoint <= 0x2261) || - (0x2264 <= codePoint && codePoint <= 0x2267) || - (0x226A <= codePoint && codePoint <= 0x226B) || - (0x226E <= codePoint && codePoint <= 0x226F) || - (0x2282 <= codePoint && codePoint <= 0x2283) || - (0x2286 <= codePoint && codePoint <= 0x2287) || - (0x2295 == codePoint) || - (0x2299 == codePoint) || - (0x22A5 == codePoint) || - (0x22BF == codePoint) || - (0x2312 == codePoint) || - (0x2460 <= codePoint && codePoint <= 0x24E9) || - (0x24EB <= codePoint && codePoint <= 0x254B) || - (0x2550 <= codePoint && codePoint <= 0x2573) || - (0x2580 <= codePoint && codePoint <= 0x258F) || - (0x2592 <= codePoint && codePoint <= 0x2595) || - (0x25A0 <= codePoint && codePoint <= 0x25A1) || - (0x25A3 <= codePoint && codePoint <= 0x25A9) || - (0x25B2 <= codePoint && codePoint <= 0x25B3) || - (0x25B6 <= codePoint && codePoint <= 0x25B7) || - (0x25BC <= codePoint && codePoint <= 0x25BD) || - (0x25C0 <= codePoint && codePoint <= 0x25C1) || - (0x25C6 <= codePoint && codePoint <= 0x25C8) || - (0x25CB == codePoint) || - (0x25CE <= codePoint && codePoint <= 0x25D1) || - (0x25E2 <= codePoint && codePoint <= 0x25E5) || - (0x25EF == codePoint) || - (0x2605 <= codePoint && codePoint <= 0x2606) || - (0x2609 == codePoint) || - (0x260E <= codePoint && codePoint <= 0x260F) || - (0x2614 <= codePoint && codePoint <= 0x2615) || - (0x261C == codePoint) || - (0x261E == codePoint) || - (0x2640 == codePoint) || - (0x2642 == codePoint) || - (0x2660 <= codePoint && codePoint <= 0x2661) || - (0x2663 <= codePoint && codePoint <= 0x2665) || - (0x2667 <= codePoint && codePoint <= 0x266A) || - (0x266C <= codePoint && codePoint <= 0x266D) || - (0x266F == codePoint) || - (0x269E <= codePoint && codePoint <= 0x269F) || - (0x26BE <= codePoint && codePoint <= 0x26BF) || - (0x26C4 <= codePoint && codePoint <= 0x26CD) || - (0x26CF <= codePoint && codePoint <= 0x26E1) || - (0x26E3 == codePoint) || - (0x26E8 <= codePoint && codePoint <= 0x26FF) || - (0x273D == codePoint) || - (0x2757 == codePoint) || - (0x2776 <= codePoint && codePoint <= 0x277F) || - (0x2B55 <= codePoint && codePoint <= 0x2B59) || - (0x3248 <= codePoint && codePoint <= 0x324F) || - (0xE000 <= codePoint && codePoint <= 0xF8FF) || - (0xFE00 <= codePoint && codePoint <= 0xFE0F) || - (0xFFFD == codePoint) || - (0x1F100 <= codePoint && codePoint <= 0x1F10A) || - (0x1F110 <= codePoint && codePoint <= 0x1F12D) || - (0x1F130 <= codePoint && codePoint <= 0x1F169) || - (0x1F170 <= codePoint && codePoint <= 0x1F19A) || - (0xE0100 <= codePoint && codePoint <= 0xE01EF) || - (0xF0000 <= codePoint && codePoint <= 0xFFFFD) || - (0x100000 <= codePoint && codePoint <= 0x10FFFD)) { - return 'A'; - } - return 'N'; - }; - eaw.characterLength = function(character) { - var code = this.eastAsianWidth(character); - if (code == 'F' || code == 'W' || code == 'A') { - return 2; - } else { - return 1; - } - }; - function stringToArray(string) { - return string.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || []; - } - eaw.length = function(string) { - var characters = stringToArray(string); - var len = 0; - for (var i = 0; i < characters.length; i++) { - len = len + this.characterLength(characters[i]); - } - return len; - }; - eaw.slice = function(text, start, end) { - textLen = eaw.length(text); - start = start ? start : 0; - end = end ? end : 1; - if (start < 0) { - start = textLen + start; - } - if (end < 0) { - end = textLen + end; - } - var result = ''; - var eawLen = 0; - var chars = stringToArray(text); - for (var i = 0; i < chars.length; i++) { - var char = chars[i]; - var charLen = eaw.length(char); - if (eawLen >= start - (charLen == 2 ? 1 : 0)) { - if (eawLen + charLen <= end) { - result += char; - } else { - break; - } - } - eawLen += charLen; - } - return result; - }; - } (eastasianwidth)); - return eastasianwidth.exports; -} - -var eastasianwidthExports = requireEastasianwidth(); -var eastAsianWidth = /*@__PURE__*/getDefaultExportFromCjs(eastasianwidthExports); - -var emojiRegex = () => { - return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE89\uDE8F-\uDEC2\uDEC6\uDECE-\uDEDC\uDEDF-\uDEE9]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g; -}; - -function stringWidth(string, options) { - if (typeof string !== 'string' || string.length === 0) { - return 0; - } - options = { - ambiguousIsNarrow: true, - countAnsiEscapeCodes: false, - ...options, - }; - if (!options.countAnsiEscapeCodes) { - string = stripAnsi(string); - } - if (string.length === 0) { - return 0; - } - const ambiguousCharacterWidth = options.ambiguousIsNarrow ? 1 : 2; - let width = 0; - for (const {segment: character} of new Intl.Segmenter().segment(string)) { - const codePoint = character.codePointAt(0); - if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) { - continue; - } - if (codePoint >= 0x3_00 && codePoint <= 0x3_6F) { - continue; - } - if (emojiRegex().test(character)) { - width += 2; - continue; - } - const code = eastAsianWidth.eastAsianWidth(character); - switch (code) { - case 'F': - case 'W': { - width += 2; - break; - } - case 'A': { - width += ambiguousCharacterWidth; - break; - } - default: { - width += 1; - } - } - } - return width; -} - -function compareFile(a, b) { - return compareString(a, b, 'path') -} -function compareMessage(a, b) { - return ( - compareNumber(a, b, 'line') || - compareNumber(a, b, 'column') || - compareBoolean(a, b, 'fatal') || - compareString(a, b, 'source') || - compareString(a, b, 'ruleId') || - compareString(a, b, 'reason') - ) -} -function compareBoolean(a, b, field) { - return scoreNullableBoolean(a[field]) - scoreNullableBoolean(b[field]) -} -function compareNumber(a, b, field) { - return (a[field] || 0) - (b[field] || 0) -} -function compareString(a, b, field) { - return String(a[field] || '').localeCompare(String(b[field] || '')) -} -function scoreNullableBoolean(value) { - return value ? 0 : value === false ? 1 : 2 -} - -function statistics(value) { - const result = {fatal: 0, warn: 0, info: 0}; - if (!value) { - throw new TypeError( - 'Expected file or message for `value`, not `' + value + '`' - ) - } - if (Array.isArray(value)) { - list(value); - } else { - one(value); - } - return { - fatal: result.fatal, - nonfatal: result.warn + result.info, - warn: result.warn, - info: result.info, - total: result.fatal + result.warn + result.info - } - function list(value) { - let index = -1; - while (++index < value.length) { - one(value[index]); - } - } - function one(value) { - if ('messages' in value) return list(value.messages) - result[value.fatal ? 'fatal' : value.fatal === false ? 'warn' : 'info']++; - } -} - -function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -} -const {env} = process$1; -let flagForceColor; -if ( - hasFlag('no-color') - || hasFlag('no-colors') - || hasFlag('color=false') - || hasFlag('color=never') -) { - flagForceColor = 0; -} else if ( - hasFlag('color') - || hasFlag('colors') - || hasFlag('color=true') - || hasFlag('color=always') -) { - flagForceColor = 1; -} -function envForceColor() { - if ('FORCE_COLOR' in env) { - if (env.FORCE_COLOR === 'true') { - return 1; - } - if (env.FORCE_COLOR === 'false') { - return 0; - } - return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); - } -} -function translateLevel(level) { - if (level === 0) { - return false; - } - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3, - }; -} -function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { - const noFlagForceColor = envForceColor(); - if (noFlagForceColor !== undefined) { - flagForceColor = noFlagForceColor; - } - const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; - if (forceColor === 0) { - return 0; - } - if (sniffFlags) { - if (hasFlag('color=16m') - || hasFlag('color=full') - || hasFlag('color=truecolor')) { - return 3; - } - if (hasFlag('color=256')) { - return 2; - } - } - if ('TF_BUILD' in env && 'AGENT_NAME' in env) { - return 1; - } - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } - const min = forceColor || 0; - if (env.TERM === 'dumb') { - return min; - } - if (process$1.platform === 'win32') { - const osRelease = os.release().split('.'); - if ( - Number(osRelease[0]) >= 10 - && Number(osRelease[2]) >= 10_586 - ) { - return Number(osRelease[2]) >= 14_931 ? 3 : 2; - } - return 1; - } - if ('CI' in env) { - if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) { - return 3; - } - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - return min; - } - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - if (env.COLORTERM === 'truecolor') { - return 3; - } - if (env.TERM === 'xterm-kitty') { - return 3; - } - if ('TERM_PROGRAM' in env) { - const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - switch (env.TERM_PROGRAM) { - case 'iTerm.app': { - return version >= 3 ? 3 : 2; - } - case 'Apple_Terminal': { - return 2; - } - } - } - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - if ('COLORTERM' in env) { - return 1; - } - return min; -} -function createSupportsColor(stream, options = {}) { - const level = _supportsColor(stream, { - streamIsTTY: stream && stream.isTTY, - ...options, - }); - return translateLevel(level); -} -const supportsColor = { - stdout: createSupportsColor({isTTY: tty.isatty(1)}), - stderr: createSupportsColor({isTTY: tty.isatty(2)}), -}; - -const color = supportsColor.stderr.hasBasic; - -const eol = /\r?\n|\r/; -function reporter(files, options) { - if ( - !files || - ('name' in files && 'message' in files) - ) { - throw new TypeError( - 'Unexpected value for `files`, expected one or more `VFile`s' - ) - } - const settings = {}; - const colorEnabled = - typeof settings.color === 'boolean' ? settings.color : color; - let oneFileMode = false; - if (Array.isArray(files)) ; else { - oneFileMode = true; - files = [files]; - } - return serializeRows( - createRows( - { - defaultName: settings.defaultName || undefined, - oneFileMode, - quiet: settings.quiet || false, - silent: settings.silent || false, - traceLimit: - typeof settings.traceLimit === 'number' ? settings.traceLimit : 10, - verbose: settings.verbose || false, - bold: colorEnabled ? '\u001B[1m' : '', - underline: colorEnabled ? '\u001B[4m' : '', - normalIntensity: colorEnabled ? '\u001B[22m' : '', - noUnderline: colorEnabled ? '\u001B[24m' : '', - red: colorEnabled ? '\u001B[31m' : '', - cyan: colorEnabled ? '\u001B[36m' : '', - green: colorEnabled ? '\u001B[32m' : '', - yellow: colorEnabled ? '\u001B[33m' : '', - defaultColor: colorEnabled ? '\u001B[39m' : '' - }, - files - ) - ) -} -function createAncestorsLines(state, ancestors) { - const min = - ancestors.length > state.traceLimit - ? ancestors.length - state.traceLimit - : 0; - let index = ancestors.length; - const lines = []; - if (index > min) { - lines.unshift(' ' + state.bold + '[trace]' + state.normalIntensity + ':'); - } - while (index-- > min) { - const node = ancestors[index]; - const value = node; - const name = - typeof value.tagName === 'string' - ? value.tagName - : - typeof value.name === 'string' - ? value.name - : undefined; - const position = stringifyPosition(node.position); - lines.push( - ' at ' + - state.yellow + - node.type + - (name ? '<' + name + '>' : '') + - state.defaultColor + - (position ? ' (' + position + ')' : '') - ); - } - return lines -} -function createByline(state, stats) { - let result = ''; - if (stats.fatal) { - result = - state.red + - '✖' + - state.defaultColor + - ' ' + - stats.fatal + - ' ' + - (fatalToLabel(true) + (stats.fatal === 1 ? '' : 's')); - } - if (stats.warn) { - result = - (result ? result + ', ' : '') + - (state.yellow + '⚠' + state.defaultColor) + - ' ' + - stats.warn + - ' ' + - (fatalToLabel(false) + (stats.warn === 1 ? '' : 's')); - } - if (stats.total !== stats.fatal && stats.total !== stats.warn) { - result = stats.total + ' messages (' + result + ')'; - } - return result -} -function createCauseLines(state, cause) { - const lines = [' ' + state.bold + '[cause]' + state.normalIntensity + ':']; - let foundReasonableCause = false; - if (cause !== null && typeof cause === 'object') { - const stackValue = - ('stack' in cause ? String(cause.stack) : undefined) || - ('message' in cause ? String(cause.message) : undefined); - if (typeof stackValue === 'string') { - foundReasonableCause = true; - let causeLines; - if ('file' in cause && 'fatal' in cause) { - causeLines = createMessageLine( - state, - (cause) - ); - } - else { - causeLines = stackValue.split(eol); - if ('cause' in cause && cause.cause) { - causeLines.push(...createCauseLines(state, cause.cause)); - } - } - const head = causeLines[0]; - if (typeof head === 'string') { - causeLines[0] = ' ' + head; - } else { - head[0] = ' ' + head[0]; - } - lines.push(...causeLines); - } - } - if (!foundReasonableCause) { - lines.push(' ' + cause); - } - return lines -} -function createFileLine(state, file) { - const stats = statistics(file.messages); - const fromPath = file.history[0]; - const toPath = file.path; - let left = ''; - let right = ''; - if (!state.oneFileMode || state.defaultName || fromPath) { - const name = fromPath || state.defaultName || ''; - left = - state.underline + - (stats.fatal ? state.red : stats.total ? state.yellow : state.green) + - name + - state.defaultColor + - state.noUnderline + - (file.stored && name !== toPath ? ' > ' + toPath : ''); - } - if (file.stored) { - right = state.yellow + 'written' + state.defaultColor; - } else if (!stats.total) { - right = 'no issues found'; - } - return left && right ? left + ': ' + right : left + right -} -function createNoteLines(state, note) { - const noteLines = note.split(eol); - let index = -1; - while (++index < noteLines.length) { - noteLines[index] = ' ' + noteLines[index]; - } - return [ - ' ' + state.bold + '[note]' + state.normalIntensity + ':', - ...noteLines - ] -} -function createMessageLine(state, message) { - const label = fatalToLabel(message.fatal); - let reason = message.stack || message.message; - const match = eol.exec(reason); - let rest = []; - if (match) { - rest = reason.slice(match.index + 1).split(eol); - reason = reason.slice(0, match.index); - } - const place = message.place || message.position; - const row = [ - stringifyPosition(place), - (label === 'error' ? state.red : state.yellow) + label + state.defaultColor, - formatReason(state, reason), - message.ruleId || '', - message.source || '' - ]; - if (message.cause) { - rest.push(...createCauseLines(state, message.cause)); - } - if (state.verbose && message.url) { - rest.push(...createUrlLines(state, message.url)); - } - if (state.verbose && message.note) { - rest.push(...createNoteLines(state, message.note)); - } - if (state.verbose && message.ancestors) { - rest.push(...createAncestorsLines(state, message.ancestors)); - } - return [row, ...rest] -} -function createRows(state, files) { - const sortedFiles = [...files].sort(compareFile); - const all = []; - let index = -1; - const rows = []; - let lastWasMessage = false; - while (++index < sortedFiles.length) { - const file = sortedFiles[index]; - const messages = [...file.messages].sort(compareMessage); - const messageRows = []; - let offset = -1; - while (++offset < messages.length) { - const message = messages[offset]; - if (!state.silent || message.fatal) { - all.push(message); - messageRows.push(...createMessageLine(state, message)); - } - } - if ((!state.quiet && !state.silent) || messageRows.length > 0) { - const line = createFileLine(state, file); - if (lastWasMessage && line) rows.push(''); - if (line) rows.push(line); - if (messageRows.length > 0) rows.push(...messageRows); - lastWasMessage = messageRows.length > 0; - } - } - const stats = statistics(all); - if (stats.fatal || stats.warn) { - rows.push('', createByline(state, stats)); - } - return rows -} -function createUrlLines(state, url) { - return [ - ' ' + state.bold + '[url]' + state.normalIntensity + ':', - ' ' + url - ] -} -function formatReason(state, reason) { - const result = []; - const splits = []; - let index = reason.indexOf('`'); - while (index !== -1) { - const split = {index, size: 1}; - splits.push(split); - while (reason.codePointAt(index + 1) === 96) { - split.size++; - index++; - } - index = reason.indexOf('`', index + 1); - } - index = -1; - let textStart = 0; - while (++index < splits.length) { - let closeIndex = index; - let close; - while (++closeIndex < splits.length) { - if (splits[index].size === splits[closeIndex].size) { - close = splits[closeIndex]; - break - } - } - if (close) { - const codeStart = splits[index].index; - const codeEnd = close.index + close.size; - result.push( - reason.slice(textStart, codeStart) + - state.cyan + - reason.slice(codeStart, codeEnd) + - state.defaultColor - ); - textStart = codeEnd; - index = closeIndex; - } - } - result.push(reason.slice(textStart)); - return state.bold + result.join('') + state.normalIntensity -} -function fatalToLabel(value) { - return value ? 'error' : value === false ? 'warning' : 'info' -} -function serializeRows(rows) { - const sizes = []; - let index = -1; - while (++index < rows.length) { - const row = rows[index]; - if (typeof row === 'string') ; else { - let cellIndex = -1; - while (++cellIndex < row.length) { - const current = sizes[cellIndex] || 0; - const size = stringWidth(row[cellIndex]); - if (size > current) { - sizes[cellIndex] = size; - } - } - } - } - const lines = []; - index = -1; - while (++index < rows.length) { - const row = rows[index]; - let line = ''; - if (typeof row === 'string') { - line = row; - } else { - let cellIndex = -1; - while (++cellIndex < row.length) { - const cell = row[cellIndex] || ''; - const max = (sizes[cellIndex] || 0) + 1; - line += cell + ' '.repeat(max - stringWidth(cell)); - } - } - lines.push(line.trimEnd()); - } - return lines.join('\n') -} +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkStringify from 'remark-stringify'; +import presetLintNode from 'remark-preset-lint-node'; +import { read } from 'to-vfile'; +import { reporter } from 'vfile-reporter'; const paths = process.argv.slice(2); + if (!paths.length) { console.error('Usage: lint-md.mjs [ ...]'); process.exit(1); } + let format = false; + if (paths[0] === '--format') { paths.shift(); format = true; } + const linter = unified() .use(remarkParse) - .use(remarkPresetLintNode) + .use(presetLintNode) .use(remarkStringify); + paths.forEach(async (path) => { const file = await read(path); + // We need to calculate `fileContents` before running `linter.process(files)` + // because `linter.process(files)` mutates `file` and returns it as `result`. + // So we won't be able to use `file` after that to see if its contents have + // changed as they will have been altered to the changed version. const fileContents = file.toString(); const result = await linter.process(file); const isDifferent = fileContents !== result.toString(); diff --git a/tools/lint-md/lint-md.src.mjs b/tools/lint-md/lint-md.src.mjs deleted file mode 100644 index 4116d7e803b64e..00000000000000 --- a/tools/lint-md/lint-md.src.mjs +++ /dev/null @@ -1,53 +0,0 @@ -import fs from 'fs'; - -import { unified } from 'unified'; -import remarkParse from 'remark-parse'; -import remarkStringify from 'remark-stringify'; -import presetLintNode from 'remark-preset-lint-node'; -import { read } from 'to-vfile'; -import { reporter } from 'vfile-reporter'; - -const paths = process.argv.slice(2); - -if (!paths.length) { - console.error('Usage: lint-md.mjs [ ...]'); - process.exit(1); -} - -let format = false; - -if (paths[0] === '--format') { - paths.shift(); - format = true; -} - -const linter = unified() - .use(remarkParse) - .use(presetLintNode) - .use(remarkStringify); - -paths.forEach(async (path) => { - const file = await read(path); - // We need to calculate `fileContents` before running `linter.process(files)` - // because `linter.process(files)` mutates `file` and returns it as `result`. - // So we won't be able to use `file` after that to see if its contents have - // changed as they will have been altered to the changed version. - const fileContents = file.toString(); - const result = await linter.process(file); - const isDifferent = fileContents !== result.toString(); - if (format) { - if (isDifferent) { - fs.writeFileSync(path, result.toString()); - } - } else { - if (isDifferent) { - process.exitCode = 1; - const cmd = process.platform === 'win32' ? 'vcbuild' : 'make'; - console.error(`${path} is not formatted. Please run '${cmd} format-md'.`); - } - if (result.messages.length) { - process.exitCode = 1; - console.error(reporter(result)); - } - } -}); diff --git a/tools/lint-md/package-lock.json b/tools/lint-md/package-lock.json index 0958904e2d0218..75355b8c78c6c7 100644 --- a/tools/lint-md/package-lock.json +++ b/tools/lint-md/package-lock.json @@ -14,316 +14,13 @@ "to-vfile": "^8.0.0", "unified": "^11.0.5", "vfile-reporter": "^8.1.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.1", - "@rollup/plugin-node-resolve": "^15.3.0", - "rollup": "^4.24.0", - "rollup-plugin-cleanup": "^3.2.1" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", - "integrity": "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.2.0", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } } }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", - "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", - "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", "dependencies": { "@types/ms": "*" } @@ -331,12 +28,14 @@ "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", "dependencies": { "@types/estree": "*" } @@ -345,6 +44,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -353,6 +53,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -360,28 +61,26 @@ "node_modules/@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "license": "MIT" }, "node_modules/@types/supports-color": { "version": "8.1.3", "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.3.tgz", - "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==" + "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==", + "license": "MIT" }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -392,12 +91,14 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -407,6 +108,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -416,6 +118,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -425,6 +128,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -434,6 +138,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -443,6 +148,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -452,21 +158,17 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -483,6 +185,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "license": "MIT", "dependencies": { "character-entities": "^2.0.0" }, @@ -491,19 +194,11 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -512,6 +207,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", "dependencies": { "dequal": "^2.0.0" }, @@ -523,17 +219,20 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" }, "node_modules/emoji-regex": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==" + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -541,70 +240,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/fdir": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" }, "node_modules/is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -614,6 +260,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" @@ -641,29 +288,16 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-decimal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -673,21 +307,17 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -695,42 +325,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/js-cleanup": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.2.0.tgz", - "integrity": "sha512-JeDD0yiiSt80fXzAVa/crrS0JDPQljyBG/RpOtaSbyDq03VHa9szJWMaWOYU/bcTn412uMN2MxApXq8v79cUiQ==", - "dev": true, - "dependencies": { - "magic-string": "^0.25.7", - "perf-regexes": "^1.0.1", - "skip-regex": "^1.0.2" - }, - "engines": { - "node": "^10.14.2 || >=12.0.0" - } - }, - "node_modules/js-cleanup/node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -742,24 +341,17 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -769,6 +361,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-3.0.0.tgz", "integrity": "sha512-bt08sLmTNg00/UtVDiqZKocxqvQqqyQZAg1uaRuO/4ysXV5motg7RolF5o5yy/sY1rG0v2XgZEqFWho1+2UquA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-mdx-expression": "^2.0.0" @@ -782,6 +375,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -801,6 +395,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", @@ -816,6 +411,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -839,6 +435,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", @@ -857,6 +454,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", @@ -873,6 +471,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", @@ -889,6 +488,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", @@ -903,6 +503,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -919,6 +520,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -934,6 +536,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-3.0.0.tgz", "integrity": "sha512-tsUfM9Kj9msjlemA/38Z3pvraQay880E3zP2NgIthMoGcpU9bcPX9oSM6QC/+eFXGGB4ba+VCB1dKAPHB7Veug==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" }, @@ -946,6 +549,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx-expression": "^2.0.0", @@ -962,6 +566,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -979,6 +584,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -1002,6 +608,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -1019,6 +626,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" @@ -1032,6 +640,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -1051,6 +660,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" }, @@ -1073,6 +683,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", @@ -1107,6 +718,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", @@ -1130,6 +742,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", @@ -1149,6 +762,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", @@ -1164,6 +778,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", @@ -1183,6 +798,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", @@ -1200,6 +816,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -1216,6 +833,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" }, @@ -1228,6 +846,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -1254,6 +873,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -1274,6 +894,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", @@ -1295,6 +916,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -1314,6 +936,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -1335,6 +958,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -1356,6 +980,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -1375,6 +1000,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } @@ -1393,6 +1019,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -1413,6 +1040,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -1432,6 +1060,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } @@ -1450,6 +1079,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", @@ -1470,7 +1100,8 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-html-tag-name": { "version": "2.0.0", @@ -1485,7 +1116,8 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-normalize-identifier": { "version": "2.0.0", @@ -1501,6 +1133,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } @@ -1519,6 +1152,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" } @@ -1537,6 +1171,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", @@ -1557,6 +1192,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", @@ -1577,7 +1213,8 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-types": { "version": "2.0.0", @@ -1592,17 +1229,20 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/parse-entities": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "character-entities": "^2.0.0", @@ -1621,39 +1261,14 @@ "node_modules/parse-entities/node_modules/@types/unist": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/perf-regexes": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", - "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==", - "dev": true, - "engines": { - "node": ">=6.14" - } - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "license": "MIT", "engines": { "node": ">=4" } @@ -1662,6 +1277,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/quotation/-/quotation-2.0.3.tgz", "integrity": "sha512-yEc24TEgCFLXx7D4JHJJkK4JFVtatO8fziwUxY4nB/Jbea9o9CVS3gt22mA0W7rPYAGW2fWzYDSOtD94PwOyqA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1671,6 +1287,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", @@ -1688,6 +1305,7 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-10.0.0.tgz", "integrity": "sha512-E8yHHDOJ8b+qI0G49BRu24pe8t0fNNBWv8ENQJpCGNrVeTeyBIGEbaUe1yuF7OG8faA6PVpcN/pqWjzW9fcBWQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "remark-message-control": "^8.0.0", @@ -1702,6 +1320,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-4.0.0.tgz", "integrity": "sha512-hdUvn+KsJbBKpY9jLY01PmfpJ/WGhLu9GJMXQGU8ADXJc+F5DWSgKAr6GQ1IUKqvGYdEML/KZ61WomWFUuecVA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -1719,6 +1338,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-5.0.0.tgz", "integrity": "sha512-K0G/Nok59fb2q5KUxcemBVt+ymnhTkDVLJAatZ4PAh9At8y0DGctHdU27jWsuvO0Fs7Zy62Usk7IJE2VO89p1w==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -1736,6 +1356,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-5.0.0.tgz", "integrity": "sha512-7L25a7TEfdogFSh4HDOnB+GTTTEiXJDMlceUPft9bzIjElI8Hm2+a2D8jUQn4ahj+j/3LmdZW4GjAeyfdPuqTA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -1753,6 +1374,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-4.0.0.tgz", "integrity": "sha512-LKBKMVruEO0tzDnnnqi1TfUcnwY6Mo7cVtZM4E4pKt3KMhtvgU2wD68/MxDOEJd0pmnLrEgIadv74bY0gWhZpg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -1770,6 +1392,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-4.0.0.tgz", "integrity": "sha512-t6nP8unz6z/DLBTWeOmDFHPFbX3E2PbNgt2fTazRbVnMC6z3o25hBzg5hI6DL0MPt2ZTRX++rJsGRjb+vgh/tQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "longest-streak": "^3.0.0", @@ -1787,6 +1410,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-4.0.0.tgz", "integrity": "sha512-Zs0wJd4nRvBo/9NWQVfWg5Ykapbo0Zzw/SyZc3f0h73S1gTZZcfeU+bA5oDivlBdcUgLBsyHRE0QaoaVvN3/Wg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -1804,6 +1428,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-4.0.0.tgz", "integrity": "sha512-WFN88Rx78m4/HSbW3Kx2XAYbVfzYns4bJd9qpwDD90DA3nc59zciYd01xi6Bk3n9vSs5gIlmG7xkwxVHHJ8KCA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -1821,6 +1446,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-3.0.0.tgz", "integrity": "sha512-wrOKiGvcl/ftB7FkeX2/l13ALvhKXV77HGR8AXo86cVY2pD+K0WdOC52DV3ldgpUXpWzE9kcgF8bbkxwzKpFFg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "quotation": "^2.0.0", @@ -1835,6 +1461,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-4.0.1.tgz", "integrity": "sha512-51T9oSdA7wuhjSdgGo0snO1BY39Igt9cJQi7XpgtgFsbfQk8zSSAUAc/rLabY6+YCTpcPs6qmwvLXZ4mPX6Qlg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -1854,6 +1481,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-3.0.0.tgz", "integrity": "sha512-NaPyn6FiOn3IV/6gIcwWfJmgraPT2IaVLjhakfPglZkKVfn/FrOfETyY8Bp+HLoSRI9967OH0yRDnK7/pPIWeQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -1869,6 +1497,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-4.0.0.tgz", "integrity": "sha512-CAMSDt03MwzGD1bgOZ+UaE0lN1xZXtJZGRXwMg7OmGazLVDtTsRkMEK0YY2LUyozdHBUFoq6FQt5pKyYdt/Tmw==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-mdx": "^3.0.0", @@ -1884,6 +1513,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-4.0.0.tgz", "integrity": "sha512-zCTq7/xfM0ZL3bMopXse9DH2nk38wE1LrxmYwnTrqASBLnEAJWE2U2//tRGVMEBfSAnNvmIo96twz6zkLWjbGA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0", @@ -1899,6 +1529,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-4.0.0.tgz", "integrity": "sha512-dQ6Jul5K0+aNUvrq4W7H0+osSoC9hsmwHZqBFq000+eMP/hWJqI8tuudw1rap8HHYuOsKLRbB5q+Fr7G+3Vw+Q==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-heading-style": "^3.0.0", @@ -1917,6 +1548,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-5.0.0.tgz", "integrity": "sha512-qq22QaxsDjfsL7aWGIPmP3P0N99CJBQQW1+iSrhYAMCDzqVlw6I3wPNAeR6s8mcoeHT8YlT6eQH3V8xJ0SlW6w==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "pluralize": "^8.0.0", @@ -1932,6 +1564,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-4.0.0.tgz", "integrity": "sha512-Yd6/g8CH9e4vlPAPNgl7F575uKhP+pTo/qwGkE61GOcgEVNJ/529hjumUhyQ4sOAX0YAPAjxvq6fJvb4AhVOOA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -1949,6 +1582,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-4.0.1.tgz", "integrity": "sha512-hQlh8UrRfhkO4FU7z7t1Bu5ethj1y2iBncO5AOWF38RAmlHaZdB2lQxNA8IvUZITGJYpT1aThdFTEf+58lv08Q==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-mdx": "^3.0.0", @@ -1966,6 +1600,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-6.0.0.tgz", "integrity": "sha512-fBhoTpkWcl5tG4FdwPdJIyb8XLrdr6MdLk1+K2BQ6Rom3rRsIYvuox4ohxOunNrXuth8xyw8kC6wDmODR44oFw==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -1986,6 +1621,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-5.0.0.tgz", "integrity": "sha512-HsDZbFlelBVO3mEJDXd9v4z0HLB8pqxWnsV+I4ILYFp5lKYf6NxJaLBWFtP1gAg1+95WxityGLkGtYqmicDjpg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", @@ -2005,6 +1641,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-4.0.0.tgz", "integrity": "sha512-21fcOACkCyhNsHkedKlpvqIywYx+5zGR507bW8e59gzdGhTbnBwQ9du4ACmN9jxPTfIBhUVMz0bWezkGrHE7Bg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -2022,6 +1659,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-3.0.0.tgz", "integrity": "sha512-il4IseupahbV2TVfFjfDVL/EQw7jBWVlMVsv4K2cgl5uPIjiCjFGQypqKnWl6pZDN0oNOs/DE8gBdyuDjldJaA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0" @@ -2035,6 +1673,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-3.0.0.tgz", "integrity": "sha512-3vSI1LOQlu8NSCpWLsKELa8dS9HU+YVZE0U43/DNkdEcnZmlJLpTHQjBTMZUHQipRgoOO+TOSyXFyN/H+2lbuQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0" @@ -2048,6 +1687,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-3.0.0.tgz", "integrity": "sha512-3kgamCp39mdlCtqF/+JLwwS4VpSj5wvVwRythUfrpW7993I9kF67dBsaU545aEzWSK+UJZqjb40i0m2VfnBRfQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0" @@ -2061,6 +1701,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-5.0.0.tgz", "integrity": "sha512-psYSlD2BjcVkgpeXOLwPcYFBrbtJWp8E8JX1J4vSfoHPeY6aIxgYxXkf57cjGTApfRL8xawBmMDiF1FgQvpZYg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -2078,6 +1719,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-5.0.0.tgz", "integrity": "sha512-JWGIWhaEzH00HywI0DHex92tJ5Mw7l11shQ6/MGhRjYsHMRWcwWcVeOuktVMe/BiQbg0hRoE4+g0z2VgUD6Cqw==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -2095,6 +1737,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-4.0.0.tgz", "integrity": "sha512-rl/3Ai4Ax9IH/fRpOJZuXk1HgYX6oFTauhmBOilpqbq/YT2kN3FuXaneXdRfKv1bgMdHaLKxHWxGj/mDyA2n8w==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-string": "^4.0.0", @@ -2112,6 +1755,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-4.0.0.tgz", "integrity": "sha512-JW11iYxza7asDdhQuKfr8SH1u4NBOCQ4U7Ru0HrKCPcT4y/AB1C1il5uMQzbcervgYPBq69xzyQ24+AJeL0t3A==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -2129,6 +1773,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-4.0.0.tgz", "integrity": "sha512-ye2h8FzjsgqqQV0HHN2g9N4FqI3eD9Gpgu7tU5ADIJyQ3mUJdwBoFn7IlGnpmumR1fb/l6u/AhRavIZxXYqG+Q==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "collapse-white-space": "^2.0.0", @@ -2145,6 +1790,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-4.0.0.tgz", "integrity": "sha512-YEiCpW5F/8/LZyxlOuVK2L/n0NJ1AB0AJK7oP39OVyEk3Xl7w+JQi6nZ3KiH6REh+PWGqKn6M0KEPL9cT/iAOw==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0", @@ -2159,6 +1805,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-4.0.0.tgz", "integrity": "sha512-6jka2Zz3I6G2MvDcKrwADYhTOxHMFMK854u1cfBEIH5/XnCCXROtoqiiDtbZw+NJqbmwsBKvGL4t2gnmEJUmgg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0", @@ -2173,6 +1820,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-5.0.0.tgz", "integrity": "sha512-MaLmnzgirpnRiRjWwrsyOX0RmP2eG4YAv169MtsxTVa6O3CpUDwTuTzivudE9L0kVvTlyF9DXEmdyjm85LDyVA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -2192,6 +1840,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-4.0.0.tgz", "integrity": "sha512-rQR7LDdcw047ajB3D+v9uzdB8aZfZtEdlUJvQXKkcVDteWiuXGC3PcIrmM/8n3J/wlFMuwoAaW2IcdlJf8HzXQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0", @@ -2206,6 +1855,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/remark-lint-no-trailing-spaces/-/remark-lint-no-trailing-spaces-3.0.2.tgz", "integrity": "sha512-4KxOdzZ+BlCZDu9yYsKGOfB8fknukxYD+9VhI1I5l7Ns7TgqdYq4k/qwUfTHpQ4TF9aokL/tOpsEGOc4PGKTKw==", + "license": "MIT", "dependencies": { "unified-lint-rule": "^3.0.0", "vfile-location": "^5.0.3" @@ -2215,6 +1865,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-5.0.0.tgz", "integrity": "sha512-O0q8bHpRHK1T85oqO+uep4BkvQnZZp3y+wahDeeLLq9dCJfF56sq6Tt5OOTt1BAOZlpobS3OPQHUiJWYP6hX1w==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "collapse-white-space": "^2.0.0", @@ -2234,6 +1885,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-4.0.0.tgz", "integrity": "sha512-YCZ6k575NCTx7mnN+9ls0G6YgMsZHi0LYQqfLW8MNVHBtbpTBvfmk8I39bmsvuKWeBD98weZoXSDqIiIGg+Q/g==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -2249,6 +1901,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-4.0.0.tgz", "integrity": "sha512-xZ7Xppy5fzACH4b9h1b4lTzVtNY2AlUkNTfl1Oe6cIKN8tk3juFxN0wL2RpktPtSZ7iRIabzFmg6l8WPhlASJA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -2267,6 +1920,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-4.0.0.tgz", "integrity": "sha512-dfLF4da5v3klRAdkHBLpNIC7WpvNdN7Eylgf+p19HPJn53CaxqlGjFvAQDAJU83xXEPWAmdonlx04GIS5ryLow==", + "license": "MIT", "dependencies": { "escape-string-regexp": "^5.0.0", "unified-lint-rule": "^2.0.0", @@ -2278,12 +1932,14 @@ "node_modules/remark-lint-prohibited-strings/node_modules/@types/unist": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" }, "node_modules/remark-lint-prohibited-strings/node_modules/unified": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "bail": "^2.0.0", @@ -2302,6 +1958,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.1.2.tgz", "integrity": "sha512-JWudPtRN7TLFHVLEVZ+Rm8FUb6kCAtHxEXFgBGDxRSdNMnGyTU5zyYvduHSF/liExlFB3vdFvsAHnNVE/UjAwA==", + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "trough": "^2.0.0", @@ -2317,6 +1974,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0" }, @@ -2329,6 +1987,7 @@ "version": "5.3.7", "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -2344,6 +2003,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" @@ -2357,6 +2017,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-4.0.0.tgz", "integrity": "sha512-Kt7IHMB5IbLgRFKaFUmB895sV3PTD0MBgN9CvXKxr1wHFF43S6tabjFIBSoQqyJRlhH0S3rK6Lvopofa009gLg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -2374,6 +2035,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-4.0.0.tgz", "integrity": "sha512-YcvuzakYhQWdCH+1E30sUY+wyvq+PNa77NZAMAYO/cS/pZczFB+q4Ccttw4Q+No/chX8oMfe0GYtm8dDWLei/g==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unified-lint-rule": "^3.0.0", @@ -2390,6 +2052,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-5.0.0.tgz", "integrity": "sha512-LNyiHDQZBIOqcQGG1tYsZHW7g0v8OyRmRgDrD5WEsMaAYfM6EiECUokN/Q4py9h4oM/2KUSrdZbtfuZmy87/kA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -2410,6 +2073,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-5.0.0.tgz", "integrity": "sha512-e7jzAScDrt5+eMomh099TZJBN2K9ldDxBu9iYhNu5C0YsdAvnckJkgilsuClxFpmx4LCVYaX0EGbt/hQ3LB3xg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -2427,6 +2091,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-4.0.0.tgz", "integrity": "sha512-XlP4Wr4KJNovyWVv0H5axfUlF23iE9Kt2SxaVq4+ieum5YcMmKE6KsL+aqt3kiJb60SH1u6a0bxKFvdM/9riOA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-phrasing": "^4.0.0", @@ -2444,6 +2109,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-8.0.0.tgz", "integrity": "sha512-brpzOO+jdyE/mLqvqqvbogmhGxKygjpCUCG/PwSCU43+JZQ+RM+sSzkCWBcYvgF3KIAVNIoPsvXjBkzO7EdsYQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-comment-marker": "^3.0.0", @@ -2459,6 +2125,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", @@ -2474,6 +2141,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-5.1.2.tgz", "integrity": "sha512-ukBPfLqD05AomGL+Z3tbmBCKTaEM+9Dv8Pn0r/0vok8F95Z0wj/AY70cFhm038ID1vKBD07anky11dvigDAHlw==", + "license": "MIT", "dependencies": { "js-yaml": "^4.1.0", "remark-gfm": "^4.0.0", @@ -2518,6 +2186,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-7.0.0.tgz", "integrity": "sha512-A9aPDL78OO12xG2a83DVd+M2QzdBMjn545fbXj40BFJdpt9t//MADkPAwRfpMCBkKi+iECPUTFCb3Jm8SsFG2w==", + "license": "MIT", "dependencies": { "remark-lint": "^10.0.0", "remark-lint-final-newline": "^3.0.0", @@ -2544,6 +2213,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", @@ -2554,93 +2224,11 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-cleanup": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.2.1.tgz", - "integrity": "sha512-zuv8EhoO3TpnrU8MX8W7YxSbO4gmOR0ny06Lm3nkFfq0IVKdBUtHwhVzY1OAJyNCIAdLiyPnOrU0KnO0Fri1GQ==", - "dev": true, - "dependencies": { - "js-cleanup": "^1.2.0", - "rollup-pluginutils": "^2.8.2" - }, - "engines": { - "node": "^10.14.2 || >=12.0.0" - }, - "peerDependencies": { - "rollup": ">=2.0" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, "node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -2648,26 +2236,11 @@ "node": ">=10" } }, - "node_modules/skip-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", - "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==", - "dev": true, - "engines": { - "node": ">=4.2" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead", - "dev": true - }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2677,6 +2250,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^10.2.1", @@ -2693,6 +2267,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -2706,6 +2281,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2720,6 +2296,7 @@ "version": "9.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -2727,22 +2304,11 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/to-vfile": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-8.0.0.tgz", "integrity": "sha512-IcmH1xB5576MJc9qcfEC/m/nQCFt3fzMHz45sSlgJyTWjRbKW1HAkJpuf3DgE57YzIlZcwcBZA5ENQbBo4aLkg==", + "license": "MIT", "dependencies": { "vfile": "^6.0.0" }, @@ -2755,6 +2321,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2764,6 +2331,7 @@ "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", @@ -2782,6 +2350,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-3.0.0.tgz", "integrity": "sha512-Sz96ILLsTy3djsG3H44zFb2b77MFf9CQVYnV3PWkxgRX8/n31fFrr+JnzUaJ6cbOHTtZnL1A71+YodsTjzwAew==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "trough": "^2.0.0", @@ -2797,6 +2366,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-5.0.0.tgz", "integrity": "sha512-B2cSAkpuMVVmPP90KCfKdBhm1e9KYJ+zK3x5BCa0N65zpq1Ybkc9C77+M5qwR8FWO7RF3LM5QRRPZtgjW6DUCw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "devlop": "^1.0.0", @@ -2816,6 +2386,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -2828,6 +2399,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -2840,6 +2412,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -2852,6 +2425,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -2866,6 +2440,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -2879,6 +2454,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" @@ -2892,6 +2468,7 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" @@ -2905,6 +2482,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -2918,6 +2496,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-8.1.1.tgz", "integrity": "sha512-qxRZcnFSQt6pWKn3PAk81yLK2rO2i7CDXpy8v8ZquiEOMLSnPw6BMSi9Y1sUCwGGl7a9b3CJT1CKpnRF7pp66g==", + "license": "MIT", "dependencies": { "@types/supports-color": "^8.0.0", "string-width": "^6.0.0", @@ -2937,6 +2516,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-4.0.0.tgz", "integrity": "sha512-lffPI1JrbHDTToJwcq0rl6rBmkjQmMuXkAxsZPRS9DXbaJQvc642eCg6EGxcX2i1L+esbuhq+2l9tBll5v8AeQ==", + "license": "MIT", "dependencies": { "vfile": "^6.0.0", "vfile-message": "^4.0.0" @@ -2950,6 +2530,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-3.0.0.tgz", "integrity": "sha512-/qlwqwWBWFOmpXujL/20P+Iuydil0rZZNglR+VNm6J0gpLHwuVM5s7g2TfVoswbXjZ4HuIhLMySEyIw5i7/D8w==", + "license": "MIT", "dependencies": { "vfile": "^6.0.0", "vfile-message": "^4.0.0" @@ -2963,6 +2544,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" diff --git a/tools/lint-md/package.json b/tools/lint-md/package.json index dbc662730253f6..f7272f493d67a7 100644 --- a/tools/lint-md/package.json +++ b/tools/lint-md/package.json @@ -2,9 +2,6 @@ "name": "lint-md", "description": "markdown linting", "version": "1.0.0", - "scripts": { - "build": "rollup -f es -p '@rollup/plugin-node-resolve={exportConditions: [\"node\"]}' -p @rollup/plugin-commonjs -p rollup-plugin-cleanup lint-md.src.mjs --file lint-md.mjs" - }, "dependencies": { "remark-parse": "^11.0.0", "remark-preset-lint-node": "^5.1.2", @@ -12,11 +9,5 @@ "to-vfile": "^8.0.0", "unified": "^11.0.5", "vfile-reporter": "^8.1.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.1", - "@rollup/plugin-node-resolve": "^15.3.0", - "rollup": "^4.24.0", - "rollup-plugin-cleanup": "^3.2.1" } } diff --git a/vcbuild.bat b/vcbuild.bat index 6bd6b6a2e9854a..8b53e7f0675e41 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -122,7 +122,6 @@ if /i "%1"=="lint-js-build" set lint_js_build=1&goto arg-ok if /i "%1"=="lint-js-fix" set lint_js_fix=1&goto arg-ok if /i "%1"=="jslint" set lint_js=1&echo Please use lint-js instead of jslint&goto arg-ok if /i "%1"=="lint-md" set lint_md=1&goto arg-ok -if /i "%1"=="lint-md-build" set lint_md_build=1&goto arg-ok if /i "%1"=="lint" set lint_cpp=1&set lint_js=1&set lint_md=1&goto arg-ok if /i "%1"=="lint-ci" set lint_cpp=1&set lint_js_ci=1&goto arg-ok if /i "%1"=="format-md" set format_md=1&goto arg-ok @@ -750,24 +749,21 @@ echo running lint-js goto lint-js-fix :lint-js-fix -if not defined lint_js_fix goto lint-md-build +if not defined lint_js_fix goto lint-md if not exist tools\eslint\node_modules\eslint goto no-lint echo running lint-js-fix %node_exe% tools\eslint\node_modules\eslint\bin\eslint.js --cache --max-warnings=0 --report-unused-disable-directives --rule "@stylistic/js/linebreak-style: 0" eslint.config.mjs benchmark doc lib test tools --fix goto lint-md-build -:no-lint -echo Linting is not available through the source tarball. -echo Use the git repo instead: $ git clone https://github.com/nodejs/node.git -goto lint-md-build - :lint-md-build -if not defined lint_md_build goto lint-md -echo "Deprecated no-op target 'lint_md_build'" -goto lint-md +if not defined lint_md if not defined format_md goto lint-md +cd tools\lint-md +%npm_exe% ci +cd ..\.. :lint-md if not defined lint_md goto format-md +if not exist tools\lint-md\node_modules goto no-lint echo Running Markdown linter on docs... SETLOCAL ENABLEDELAYEDEXPANSION set lint_md_files= @@ -782,6 +778,7 @@ goto format-md :format-md if not defined format_md goto exit +if not exist tools\lint-md\node_modules goto no-lint echo Running Markdown formatter on docs... SETLOCAL ENABLEDELAYEDEXPANSION set lint_md_files= @@ -792,6 +789,10 @@ for /D %%D IN (doc\*) do ( ) %node_exe% tools\lint-md\lint-md.mjs --format %lint_md_files% ENDLOCAL + +:no-lint +echo Linting is not available through the source tarball. +echo Use the git repo instead: $ git clone https://github.com/nodejs/node.git goto exit :create-msvs-files-failed From b79e4835ab0dd58ea571ba4302e689a0dd74cce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sat, 2 Nov 2024 09:00:53 +0100 Subject: [PATCH 44/93] build: use rclone instead of aws CLI Use rclone to upload assets to Cloudflare as it is more reliable. Refs: https://github.com/nodejs/build/issues/3508 PR-URL: https://github.com/nodejs/node/pull/55617 Reviewed-By: Richard Lau Reviewed-By: Moshe Atlow --- Makefile | 20 +++++++++----------- tools/release.sh | 8 +++----- vcbuild.bat | 18 ++++++++---------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index b6cd644e2865ec..c9400f2f793cf1 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,7 @@ PREFIX ?= /usr/local FLAKY_TESTS ?= run TEST_CI_ARGS ?= STAGINGSERVER ?= node-www -CLOUDFLARE_ENDPOINT ?= https://07be8d2fbc940503ca1be344714cb0d1.r2.cloudflarestorage.com -CLOUDFLARE_BUCKET ?= dist-staging -CLOUDFLARE_PROFILE ?= worker +CLOUDFLARE_BUCKET ?= r2:dist-staging LOGLEVEL ?= silent OSTYPE := $(shell uname -s | tr '[:upper:]' '[:lower:]') ifeq ($(findstring os/390,$OSTYPE),os/390) @@ -1170,7 +1168,7 @@ pkg-upload: pkg ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" chmod 664 $(TARNAME).pkg scp -p $(TARNAME).pkg $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg - ssh $(STAGINGSERVER) "aws s3 cp nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg.done" $(TARBALL): release-only doc-only @@ -1221,12 +1219,12 @@ tar-upload: tar ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" chmod 664 $(TARNAME).tar.gz scp -p $(TARNAME).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz - ssh $(STAGINGSERVER) "aws s3 cp nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz.done" ifeq ($(XZ), 1) chmod 664 $(TARNAME).tar.xz scp -p $(TARNAME).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz - ssh $(STAGINGSERVER) "aws s3 cp nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz.done" endif @@ -1236,7 +1234,7 @@ doc-upload: doc ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/" chmod -R ug=rw-x+X,o=r+X out/doc/ scp -pr out/doc/* $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/ - ssh $(STAGINGSERVER) "aws s3 cp --recursive nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/ --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copy nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/ $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs.done" .PHONY: $(TARBALL)-headers @@ -1265,12 +1263,12 @@ tar-headers-upload: tar-headers ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" chmod 664 $(TARNAME)-headers.tar.gz scp -p $(TARNAME)-headers.tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz - ssh $(STAGINGSERVER) "aws s3 cp nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz.done" ifeq ($(XZ), 1) chmod 664 $(TARNAME)-headers.tar.xz scp -p $(TARNAME)-headers.tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz - ssh $(STAGINGSERVER) "aws s3 cp nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz.done" endif @@ -1312,12 +1310,12 @@ binary-upload: binary ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz - ssh $(STAGINGSERVER) "aws s3 cp nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz.done" ifeq ($(XZ), 1) chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz - ssh $(STAGINGSERVER) "aws s3 cp nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz s3://$(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz --endpoint=$(CLOUDFLARE_ENDPOINT) --profile=$(CLOUDFLARE_PROFILE)" + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz" ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz.done" endif diff --git a/tools/release.sh b/tools/release.sh index 136eb87a0f1167..fca6e30a6308f2 100755 --- a/tools/release.sh +++ b/tools/release.sh @@ -17,9 +17,7 @@ promotecmd=dist-promote signcmd=dist-sign customsshkey="" # let ssh and scp use default key signversion="" -cloudflare_bucket="dist-prod" -cloudflare_endpoint=https://07be8d2fbc940503ca1be344714cb0d1.r2.cloudflarestorage.com # Node.js Cloudflare account -cloudflare_profile="worker" +cloudflare_bucket="r2:dist-prod" while getopts ":i:s:" option; do case "${option}" in @@ -162,11 +160,11 @@ sign() { # Copy SHASUMS256.txt.asc # shellcheck disable=SC2086,SC2029 - ssh ${customsshkey} "${webuser}@${webhost}" aws s3 cp "${shadir}/${shafile}.asc" "s3://${cloudflare_bucket}/${r2dir}/${shafile}.asc" --endpoint="${cloudflare_endpoint}" --profile=${cloudflare_profile} + ssh ${customsshkey} "${webuser}@${webhost}" rclone copyto "${shadir}/${shafile}.asc" "${cloudflare_bucket}/${r2dir}/${shafile}.asc" # Copy SHASUMS256.txt.sig # shellcheck disable=SC2086,SC2029 - ssh ${customsshkey} "${webuser}@${webhost}" aws s3 cp "${shadir}/${shafile}.sig" "s3://${cloudflare_bucket}/${r2dir}/${shafile}.sig" --endpoint="${cloudflare_endpoint}" --profile=${cloudflare_profile} + ssh ${customsshkey} "${webuser}@${webhost}" rclone copyto "${shadir}/${shafile}.sig" "${cloudflare_bucket}/${r2dir}/${shafile}.sig" break fi done diff --git a/vcbuild.bat b/vcbuild.bat index 8b53e7f0675e41..f93998d2b14901 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -547,38 +547,36 @@ if not defined SSHCONFIG ( ) if not defined STAGINGSERVER set STAGINGSERVER=node-www -if not defined CLOUDFLARE_ENDPOINT set CLOUDFLARE_ENDPOINT=https://07be8d2fbc940503ca1be344714cb0d1.r2.cloudflarestorage.com -if not defined CLOUDFLARE_BUCKET set CLOUDFLARE_BUCKET=dist-staging -if not defined CLOUDFLARE_PROFILE set CLOUDFLARE_PROFILE=worker +if not defined CLOUDFLARE_BUCKET set CLOUDFLARE_BUCKET=r2:dist-staging ssh -F %SSHCONFIG% %STAGINGSERVER% "mkdir -p nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%" if errorlevel 1 goto exit scp -F %SSHCONFIG% Release\node.exe %STAGINGSERVER%:nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.exe if errorlevel 1 goto exit -ssh -F %SSHCONFIG% %STAGINGSERVER% "aws s3 cp nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.exe s3://%CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.exe --endpoint=%CLOUDFLARE_ENDPOINT% --profile=%CLOUDFLARE_PROFILE%" +ssh -F %SSHCONFIG% %STAGINGSERVER% "rclone copyto nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.exe %CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.exe" if errorlevel 1 goto exit scp -F %SSHCONFIG% Release\node.lib %STAGINGSERVER%:nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.lib if errorlevel 1 goto exit -ssh -F %SSHCONFIG% %STAGINGSERVER% "aws s3 cp nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.lib s3://%CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.lib --endpoint=%CLOUDFLARE_ENDPOINT% --profile=%CLOUDFLARE_PROFILE%" +ssh -F %SSHCONFIG% %STAGINGSERVER% "rclone copyto nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.lib %CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node.lib" if errorlevel 1 goto exit scp -F %SSHCONFIG% Release\node_pdb.zip %STAGINGSERVER%:nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.zip if errorlevel 1 goto exit -ssh -F %SSHCONFIG% %STAGINGSERVER% "aws s3 cp nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.zip s3://%CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.zip --endpoint=%CLOUDFLARE_ENDPOINT% --profile=%CLOUDFLARE_PROFILE%" +ssh -F %SSHCONFIG% %STAGINGSERVER% "rclone copyto nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.zip %CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.zip" if errorlevel 1 goto exit scp -F %SSHCONFIG% Release\node_pdb.7z %STAGINGSERVER%:nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.7z if errorlevel 1 goto exit -ssh -F %SSHCONFIG% %STAGINGSERVER% "aws s3 cp nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.7z s3://%CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.7z --endpoint=%CLOUDFLARE_ENDPOINT% --profile=%CLOUDFLARE_PROFILE%" +ssh -F %SSHCONFIG% %STAGINGSERVER% "rclone copyto nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.7z %CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%/node_pdb.7z" if errorlevel 1 goto exit scp -F %SSHCONFIG% Release\%TARGET_NAME%.7z %STAGINGSERVER%:nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.7z if errorlevel 1 goto exit -ssh -F %SSHCONFIG% %STAGINGSERVER% "aws s3 cp nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.7z s3://%CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.7z --endpoint=%CLOUDFLARE_ENDPOINT% --profile=%CLOUDFLARE_PROFILE%" +ssh -F %SSHCONFIG% %STAGINGSERVER% "rclone copyto nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.7z %CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.7z" if errorlevel 1 goto exit scp -F %SSHCONFIG% Release\%TARGET_NAME%.zip %STAGINGSERVER%:nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.zip if errorlevel 1 goto exit -ssh -F %SSHCONFIG% %STAGINGSERVER% "aws s3 cp nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.zip s3://%CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.zip --endpoint=%CLOUDFLARE_ENDPOINT% --profile=%CLOUDFLARE_PROFILE%" +ssh -F %SSHCONFIG% %STAGINGSERVER% "rclone copyto nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.zip %CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.zip" if errorlevel 1 goto exit scp -F %SSHCONFIG% node-v%FULLVERSION%-%target_arch%.msi %STAGINGSERVER%:nodejs/%DISTTYPEDIR%/v%FULLVERSION%/ if errorlevel 1 goto exit -ssh -F %SSHCONFIG% %STAGINGSERVER% "aws s3 cp nodejs/%DISTTYPEDIR%/v%FULLVERSION%/node-v%FULLVERSION%-%target_arch%.msi s3://%CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/node-v%FULLVERSION%-%target_arch%.msi --endpoint=%CLOUDFLARE_ENDPOINT% --profile=%CLOUDFLARE_PROFILE%" +ssh -F %SSHCONFIG% %STAGINGSERVER% "rclone copyto nodejs/%DISTTYPEDIR%/v%FULLVERSION%/node-v%FULLVERSION%-%target_arch%.msi %CLOUDFLARE_BUCKET%/nodejs/%DISTTYPEDIR%/v%FULLVERSION%/node-v%FULLVERSION%-%target_arch%.msi" if errorlevel 1 goto exit ssh -F %SSHCONFIG% %STAGINGSERVER% "touch nodejs/%DISTTYPEDIR%/v%FULLVERSION%/node-v%FULLVERSION%-%target_arch%.msi.done nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.zip.done nodejs/%DISTTYPEDIR%/v%FULLVERSION%/%TARGET_NAME%.7z.done nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%.done && chmod -R ug=rw-x+X,o=r+X nodejs/%DISTTYPEDIR%/v%FULLVERSION%/node-v%FULLVERSION%-%target_arch%.* nodejs/%DISTTYPEDIR%/v%FULLVERSION%/win-%target_arch%*" if errorlevel 1 goto exit From d26dedf41da40c4426cdfbd29e808b25bb08ae8f Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 2 Nov 2024 12:36:09 +0000 Subject: [PATCH 45/93] src: refactor ECDHBitsJob signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55610 Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen --- lib/internal/crypto/diffiehellman.js | 1 - src/crypto/crypto_ec.cc | 30 +++++----------------------- src/crypto/crypto_ec.h | 1 - src/crypto/crypto_keys.cc | 16 +++++++++++++++ src/crypto/crypto_keys.h | 2 ++ 5 files changed, 23 insertions(+), 27 deletions(-) diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index 59bbf8ff71233c..410759414f635d 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -332,7 +332,6 @@ async function ecdhDeriveBits(algorithm, baseKey, length) { const bits = await jobPromise(() => new ECDHBitsJob( kCryptoJobAsync, - key.algorithm.name === 'ECDH' ? baseKey.algorithm.namedCurve : baseKey.algorithm.name, key[kKeyObject][kHandle], baseKey[kKeyObject][kHandle])); diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc index 3942a52c142226..a42a336baedf09 100644 --- a/src/crypto/crypto_ec.cc +++ b/src/crypto/crypto_ec.cc @@ -45,22 +45,6 @@ int GetCurveFromName(const char* name) { return nid; } -int GetOKPCurveFromName(const char* name) { - int nid; - if (strcmp(name, "Ed25519") == 0) { - nid = EVP_PKEY_ED25519; - } else if (strcmp(name, "Ed448") == 0) { - nid = EVP_PKEY_ED448; - } else if (strcmp(name, "X25519") == 0) { - nid = EVP_PKEY_X25519; - } else if (strcmp(name, "X448") == 0) { - nid = EVP_PKEY_X448; - } else { - nid = NID_undef; - } - return nid; -} - void ECDH::Initialize(Environment* env, Local target) { Isolate* isolate = env->isolate(); Local context = env->context(); @@ -450,17 +434,14 @@ Maybe ECDHBitsTraits::AdditionalConfig( ECDHBitsConfig* params) { Environment* env = Environment::GetCurrent(args); - CHECK(args[offset]->IsString()); // curve name - CHECK(args[offset + 1]->IsObject()); // public key - CHECK(args[offset + 2]->IsObject()); // private key + CHECK(args[offset]->IsObject()); // public key + CHECK(args[offset + 1]->IsObject()); // private key KeyObjectHandle* private_key; KeyObjectHandle* public_key; - Utf8Value name(env->isolate(), args[offset]); - - ASSIGN_OR_RETURN_UNWRAP(&public_key, args[offset + 1], Nothing()); - ASSIGN_OR_RETURN_UNWRAP(&private_key, args[offset + 2], Nothing()); + ASSIGN_OR_RETURN_UNWRAP(&public_key, args[offset], Nothing()); + ASSIGN_OR_RETURN_UNWRAP(&private_key, args[offset + 1], Nothing()); if (private_key->Data().GetKeyType() != kKeyTypePrivate || public_key->Data().GetKeyType() != kKeyTypePublic) { @@ -468,7 +449,6 @@ Maybe ECDHBitsTraits::AdditionalConfig( return Nothing(); } - params->id_ = GetOKPCurveFromName(*name); params->private_ = private_key->Data().addRef(); params->public_ = public_key->Data().addRef(); @@ -482,7 +462,7 @@ bool ECDHBitsTraits::DeriveBits(Environment* env, const auto& m_privkey = params.private_.GetAsymmetricKey(); const auto& m_pubkey = params.public_.GetAsymmetricKey(); - switch (params.id_) { + switch (m_privkey.id()) { case EVP_PKEY_X25519: // Fall through case EVP_PKEY_X448: { diff --git a/src/crypto/crypto_ec.h b/src/crypto/crypto_ec.h index 49a87d1663e7ee..b5de681fbe1516 100644 --- a/src/crypto/crypto_ec.h +++ b/src/crypto/crypto_ec.h @@ -16,7 +16,6 @@ namespace node { namespace crypto { int GetCurveFromName(const char* name); -int GetOKPCurveFromName(const char* name); class ECDH final : public BaseObject { public: diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 784180e90a8702..efd20cdb9452e3 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -909,6 +909,22 @@ void KeyObjectHandle::InitECRaw(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(true); } +int GetOKPCurveFromName(const char* name) { + int nid; + if (strcmp(name, "Ed25519") == 0) { + nid = EVP_PKEY_ED25519; + } else if (strcmp(name, "Ed448") == 0) { + nid = EVP_PKEY_ED448; + } else if (strcmp(name, "X25519") == 0) { + nid = EVP_PKEY_X25519; + } else if (strcmp(name, "X448") == 0) { + nid = EVP_PKEY_X448; + } else { + nid = NID_undef; + } + return nid; +} + void KeyObjectHandle::InitEDRaw(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); KeyObjectHandle* key; diff --git a/src/crypto/crypto_keys.h b/src/crypto/crypto_keys.h index fd7ff00b21c8e2..6d794b439b51ba 100644 --- a/src/crypto/crypto_keys.h +++ b/src/crypto/crypto_keys.h @@ -408,6 +408,8 @@ WebCryptoKeyExportStatus PKEY_SPKI_Export(const KeyObjectData& key_data, WebCryptoKeyExportStatus PKEY_PKCS8_Export(const KeyObjectData& key_data, ByteSource* out); +int GetOKPCurveFromName(const char* name); + namespace Keys { void Initialize(Environment* env, v8::Local target); void RegisterExternalReferences(ExternalReferenceRegistry* registry); From 9743fa44edf471ae9aea3c5486ee32711d57ec73 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 2 Nov 2024 12:36:25 +0000 Subject: [PATCH 46/93] doc: remove mention of ECDH-ES in crypto.diffieHellman MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55611 Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen --- doc/api/crypto.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 81d3e0cf95f639..788c52d8864660 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3557,7 +3557,7 @@ added: Computes the Diffie-Hellman secret based on a `privateKey` and a `publicKey`. Both keys must have the same `asymmetricKeyType`, which must be one of `'dh'` -(for Diffie-Hellman), `'ec'` (for ECDH), `'x448'`, or `'x25519'` (for ECDH-ES). +(for Diffie-Hellman), `'ec'`, `'x448'`, or `'x25519'` (for ECDH). ### `crypto.hash(algorithm, data[, outputEncoding])` From 6662752b6267b8ea40952f001a497075c98e3e4e Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Sat, 2 Nov 2024 18:07:09 +0530 Subject: [PATCH 47/93] doc: add a note on console stream behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many user reported issues show poor awareness of the nature of console streams. explicitly document that. PR-URL: https://github.com/nodejs/node/pull/55616 Reviewed-By: Ulises Gascón Reviewed-By: Luigi Pinca --- doc/api/console.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/api/console.md b/doc/api/console.md index 147a45eadb1203..1c966d094d1472 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -19,7 +19,11 @@ The module exports two specific components: _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently -asynchronous like all other Node.js streams. See the [note on process I/O][] for +asynchronous like all other Node.js streams. Programs that desire to depend +on the synchronous / asynchronous behavior of the console functions should +first figure out the nature of console's backing stream. This is because the +stream is dependent on the underlying platform and standard stream +configuration of the current process. See the [note on process I/O][] for more information. Example using the global `console`: From 8d0526f1f427f22288d7fcc982e806d2eec80ed8 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Sat, 2 Nov 2024 08:46:20 -0500 Subject: [PATCH 48/93] http: add diagnostic channel `http.server.response.created` PR-URL: https://github.com/nodejs/node/pull/55622 Reviewed-By: Matteo Collina Reviewed-By: Paolo Insogna --- doc/api/diagnostics_channel.md | 8 ++++ lib/_http_server.js | 7 +++ ...iagnostic-channel-http-response-created.js | 45 +++++++++++++++++++ .../parallel/test-diagnostics-channel-http.js | 8 ++++ 4 files changed, 68 insertions(+) create mode 100644 test/parallel/test-diagnostic-channel-http-response-created.js diff --git a/doc/api/diagnostics_channel.md b/doc/api/diagnostics_channel.md index 2467329c7729a2..6fa1a57f3eeb60 100644 --- a/doc/api/diagnostics_channel.md +++ b/doc/api/diagnostics_channel.md @@ -1159,6 +1159,14 @@ Emitted when client receives a response. Emitted when server receives a request. +`http.server.response.created` + +* `request` {http.IncomingMessage} +* `response` {http.ServerResponse} + +Emitted when server creates a response. +The event is emitted before the response is sent. + `http.server.response.finish` * `request` {http.IncomingMessage} diff --git a/lib/_http_server.js b/lib/_http_server.js index c8b388669232d9..e00d3cac0490e5 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -97,6 +97,7 @@ let debug = require('internal/util/debuglog').debuglog('http', (fn) => { const dc = require('diagnostics_channel'); const onRequestStartChannel = dc.channel('http.server.request.start'); +const onResponseCreatedChannel = dc.channel('http.server.response.created'); const onResponseFinishChannel = dc.channel('http.server.response.finish'); const kServerResponse = Symbol('ServerResponse'); @@ -224,6 +225,12 @@ function ServerResponse(req, options) { this._traceEventId = getNextTraceEventId(); traceBegin(HTTP_SERVER_TRACE_EVENT_NAME, this._traceEventId); } + if (onResponseCreatedChannel.hasSubscribers) { + onResponseCreatedChannel.publish({ + request: req, + response: this, + }); + } } ObjectSetPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype); ObjectSetPrototypeOf(ServerResponse, OutgoingMessage); diff --git a/test/parallel/test-diagnostic-channel-http-response-created.js b/test/parallel/test-diagnostic-channel-http-response-created.js new file mode 100644 index 00000000000000..5dac865a50d692 --- /dev/null +++ b/test/parallel/test-diagnostic-channel-http-response-created.js @@ -0,0 +1,45 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const dc = require('diagnostics_channel'); + +const isOutgoingMessage = (object) => object instanceof http.OutgoingMessage; +const isIncomingMessage = (object) => object instanceof http.IncomingMessage; + +dc.subscribe('http.server.response.created', common.mustCall(({ + request, + response, +}) => { + assert.strictEqual(request.headers.foo, 'bar'); + assert.strictEqual(response.getHeader('baz'), undefined); + assert.strictEqual(isIncomingMessage(request), true); + assert.strictEqual(isOutgoingMessage(response), true); +})); + +dc.subscribe('http.server.response.finish', common.mustCall(({ + request, + response, +}) => { + assert.strictEqual(request.headers.foo, 'bar'); + assert.strictEqual(response.getHeader('baz'), 'bar'); + assert.strictEqual(isIncomingMessage(request), true); + assert.strictEqual(isOutgoingMessage(response), true); +})); + +const server = http.createServer(common.mustCall((_, res) => { + res.setHeader('baz', 'bar'); + res.end('done'); +})); + +server.listen(() => { + const { port } = server.address(); + http.get({ + port, + headers: { + 'foo': 'bar', + } + }, common.mustCall(() => { + server.close(); + })); +}); diff --git a/test/parallel/test-diagnostics-channel-http.js b/test/parallel/test-diagnostics-channel-http.js index cc212e3f6207f5..fd371a5d259f0b 100644 --- a/test/parallel/test-diagnostics-channel-http.js +++ b/test/parallel/test-diagnostics-channel-http.js @@ -53,6 +53,14 @@ dc.subscribe('http.server.response.finish', common.mustCall(({ assert.strictEqual(isHTTPServer(server), true); })); +dc.subscribe('http.server.response.created', common.mustCall(({ + request, + response, +}) => { + assert.strictEqual(isIncomingMessage(request), true); + assert.strictEqual(isOutgoingMessage(response), true); +})); + dc.subscribe('http.client.request.created', common.mustCall(({ request }) => { assert.strictEqual(isOutgoingMessage(request), true); assert.strictEqual(isHTTPServer(server), true); From 7ce7eab32445a5387f20540e4aac7cd7da20930f Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 2 Nov 2024 15:14:40 +0100 Subject: [PATCH 49/93] tools: lint README lists more strictly PR-URL: https://github.com/nodejs/node/pull/55625 Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca Reviewed-By: Rafael Gonzaga --- README.md | 6 +++--- tools/lint-readme-lists.mjs | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8f01a50eb370d7..69777ccb2dad40 100644 --- a/README.md +++ b/README.md @@ -409,7 +409,7 @@ For information about the governance of the Node.js project, see **Filip Skokan** <> (he/him) * [pimterry](https://github.com/pimterry) - **Tim Perry** <> (he/him) -* [pmarchini](https://github.com/pmarchini) +* [pmarchini](https://github.com/pmarchini) - **Pietro Marchini** <> (he/him) * [Qard](https://github.com/Qard) - **Stephen Belanger** <> (he/him) @@ -515,7 +515,7 @@ For information about the governance of the Node.js project, see **Hitesh Kanwathirtha** <> (he/him) * [dmabupt](https://github.com/dmabupt) - **Xu Meng** <> (he/him) -* [dnlup](https://github.com/dnlup) +* [dnlup](https://github.com/dnlup) - **dnlup** <> * [eljefedelrodeodeljefe](https://github.com/eljefedelrodeodeljefe) - **Robert Jefe Lindstaedt** <> @@ -757,7 +757,7 @@ maintaining the Node.js project. **Mert Can Altin** <> * [preveen-stack](https://github.com/preveen-stack) - **Preveen Padmanabhan** <> (he/him) -* [RedYetiDev](https://github.com/redyetidev) - +* [RedYetiDev](https://github.com/RedYetiDev) - **Aviv Keller** <> (they/them) * [VoltrexKeyva](https://github.com/VoltrexKeyva) - **Mohammed Keyvanzadeh** <> (he/him) diff --git a/tools/lint-readme-lists.mjs b/tools/lint-readme-lists.mjs index f6c05b46bdf20f..97992b79b1e32e 100755 --- a/tools/lint-readme-lists.mjs +++ b/tools/lint-readme-lists.mjs @@ -6,6 +6,9 @@ import assert from 'node:assert'; import { open } from 'node:fs/promises'; import { argv } from 'node:process'; +const ghHandleLine = /^\* \[(.+)\]\(https:\/\/github\.com\/\1\) -$/; +const memberInfoLine = /^ {2}\*\*[^*]+\*\* <<[^@]+@.+\.[a-z]+>>( \(\w+(\/[^)/]+)+\))?( - \[Support me\]\(.+\))?$/; + const lists = { '__proto__': null, @@ -26,12 +29,19 @@ const tscMembers = new Set(); const readme = await open(new URL('../README.md', import.meta.url), 'r'); let currentList = null; +let previousGithubHandleInfoRequired; let previousGithubHandle; let lineNumber = 0; for await (const line of readme.readLines()) { lineNumber++; - if (line.startsWith('### ')) { + if (previousGithubHandleInfoRequired) { + if (!memberInfoLine.test(line)) { + throw new Error(`${previousGithubHandleInfoRequired} info are not formatted correctly (README.md:${lineNumber})`); + } + previousGithubHandle = previousGithubHandleInfoRequired; + previousGithubHandleInfoRequired = null; + } else if (line.startsWith('### ')) { currentList = line.slice(4); previousGithubHandle = null; } else if (line.startsWith('#### ')) { @@ -49,6 +59,10 @@ for await (const line of readme.readLines()) { ); } + if (!ghHandleLine.test(line)) { + throw new Error(`${currentGithubHandle} is not formatted correctly (README.md:${lineNumber})`); + } + if ( currentList === 'TSC voting members' || currentList === 'TSC regular members' @@ -60,7 +74,7 @@ for await (const line of readme.readLines()) { if (lists[currentList]) { (actualMembers[lists[currentList]] ??= new Set()).add(currentGithubHandle); } - previousGithubHandle = currentGithubHandleLowerCase; + previousGithubHandleInfoRequired = currentGithubHandleLowerCase; } } console.info('Lists are in the alphabetical order.'); From 0302efe4b2e1a21b3b1d9b82b263383e36e9b9bc Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sat, 2 Nov 2024 08:11:28 -0700 Subject: [PATCH 50/93] src: move more key related stuff to ncrypto PR-URL: https://github.com/nodejs/node/pull/55368 Reviewed-By: Yagiz Nizipli --- deps/ncrypto/ncrypto.cc | 252 ++++++++++++++++++-- deps/ncrypto/ncrypto.h | 36 ++- src/crypto/crypto_keygen.cc | 3 +- src/crypto/crypto_keygen.h | 28 ++- src/crypto/crypto_keys.cc | 443 ++++++++++++++---------------------- src/crypto/crypto_keys.h | 68 ++---- src/crypto/crypto_util.h | 12 +- 7 files changed, 467 insertions(+), 375 deletions(-) diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index a38b4a280a3263..3319957baf13e2 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -80,7 +80,7 @@ std::optional CryptoErrorList::pop_front() { // ============================================================================ DataPointer DataPointer::Alloc(size_t len) { - return DataPointer(OPENSSL_malloc(len), len); + return DataPointer(OPENSSL_zalloc(len), len); } DataPointer::DataPointer(void* data, size_t length) @@ -1428,6 +1428,33 @@ DataPointer pbkdf2(const EVP_MD* md, // ============================================================================ +EVPKeyPointer::PrivateKeyEncodingConfig::PrivateKeyEncodingConfig( + const PrivateKeyEncodingConfig& other) + : PrivateKeyEncodingConfig(other.output_key_object, other.format, other.type) { + cipher = other.cipher; + if (other.passphrase.has_value()) { + auto& otherPassphrase = other.passphrase.value(); + auto newPassphrase = DataPointer::Alloc(otherPassphrase.size()); + memcpy(newPassphrase.get(), otherPassphrase.get(), otherPassphrase.size()); + passphrase = std::move(newPassphrase); + } +} + +EVPKeyPointer::AsymmetricKeyEncodingConfig::AsymmetricKeyEncodingConfig( + bool output_key_object, + PKFormatType format, + PKEncodingType type) + : output_key_object(output_key_object), + format(format), + type(type) {} + +EVPKeyPointer::PrivateKeyEncodingConfig& EVPKeyPointer::PrivateKeyEncodingConfig::operator=( + const PrivateKeyEncodingConfig& other) { + if (this == &other) return *this; + this->~PrivateKeyEncodingConfig(); + return *new (this) PrivateKeyEncodingConfig(other); +} + EVPKeyPointer EVPKeyPointer::New() { return EVPKeyPointer(EVP_PKEY_new()); } @@ -1661,14 +1688,13 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePublicKeyPEM( } EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePublicKey( - PKFormatType format, - PKEncodingType encoding, + const PublicKeyEncodingConfig& config, const Buffer& buffer) { - if (format == PKFormatType::PEM) { + if (config.format == PKFormatType::PEM) { return TryParsePublicKeyPEM(buffer); } - if (format != PKFormatType::DER) { + if (config.format != PKFormatType::DER) { return ParseKeyResult(PKParseError::FAILED); } @@ -1676,12 +1702,12 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePublicKey( EVP_PKEY* key = nullptr; - if (encoding == PKEncodingType::PKCS1 && + if (config.type == PKEncodingType::PKCS1 && (key = d2i_PublicKey(EVP_PKEY_RSA, nullptr, &start, buffer.len))) { return EVPKeyPointer::ParseKeyResult(EVPKeyPointer(key)); } - if (encoding == PKEncodingType::SPKI && + if (config.type == PKEncodingType::SPKI && (key = d2i_PUBKEY(nullptr, &start, buffer.len))) { return EVPKeyPointer::ParseKeyResult(EVPKeyPointer(key)); } @@ -1689,13 +1715,34 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePublicKey( return ParseKeyResult(PKParseError::FAILED); } +namespace { +Buffer GetPassphrase(const EVPKeyPointer::PrivateKeyEncodingConfig& config) { + Buffer pass { + // OpenSSL will not actually dereference this pointer, so it can be any + // non-null pointer. We cannot assert that directly, which is why we + // intentionally use a pointer that will likely cause a segmentation fault + // when dereferenced. + .data = reinterpret_cast(-1), + .len = 0, + }; + if (config.passphrase.has_value()) { + auto& passphrase = config.passphrase.value(); + // The pass.data can't be a nullptr, even if the len is zero or else + // openssl will prompt for a password and we really don't want that. + if (passphrase.get() != nullptr) { + pass.data = static_cast(passphrase.get()); + } + pass.len = passphrase.size(); + } + return pass; +} +} // namespace + EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey( - PKFormatType format, - PKEncodingType encoding, - std::optional> maybe_passphrase, + const PrivateKeyEncodingConfig& config, const Buffer& buffer) { - static auto keyOrError = [&](EVPKeyPointer pkey, bool had_passphrase = false) { + static constexpr auto keyOrError = [](EVPKeyPointer pkey, bool had_passphrase = false) { if (int err = ERR_peek_error()) { if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_BAD_PASSWORD_READ && @@ -1708,24 +1755,23 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey( return ParseKeyResult(std::move(pkey)); }; - Buffer* passphrase = nullptr; - if (maybe_passphrase.has_value()) { - passphrase = &maybe_passphrase.value(); - } auto bio = BIOPointer::New(buffer); if (!bio) return ParseKeyResult(PKParseError::FAILED); - if (format == PKFormatType::PEM) { - auto key = PEM_read_bio_PrivateKey(bio.get(), nullptr, PasswordCallback, passphrase); - return keyOrError(EVPKeyPointer(key), maybe_passphrase.has_value()); + auto passphrase = GetPassphrase(config); + + if (config.format == PKFormatType::PEM) { + auto key = PEM_read_bio_PrivateKey(bio.get(), nullptr, PasswordCallback, + config.passphrase.has_value() ? &passphrase : nullptr); + return keyOrError(EVPKeyPointer(key), config.passphrase.has_value()); } - if (format != PKFormatType::DER) { + if (config.format != PKFormatType::DER) { return ParseKeyResult(PKParseError::FAILED); } - switch (encoding) { + switch (config.type) { case PKEncodingType::PKCS1: { auto key = d2i_PrivateKey_bio(bio.get(), nullptr); return keyOrError(EVPKeyPointer(key)); @@ -1735,8 +1781,8 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey( auto key = d2i_PKCS8PrivateKey_bio(bio.get(), nullptr, PasswordCallback, - passphrase); - return keyOrError(EVPKeyPointer(key), maybe_passphrase.has_value()); + config.passphrase.has_value() ? &passphrase : nullptr); + return keyOrError(EVPKeyPointer(key), config.passphrase.has_value()); } PKCS8Pointer p8inf(d2i_PKCS8_PRIV_KEY_INFO_bio(bio.get(), nullptr)); @@ -1755,4 +1801,166 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryParsePrivateKey( }; } +Result EVPKeyPointer::writePrivateKey( + const PrivateKeyEncodingConfig& config) const { + if (config.format == PKFormatType::JWK) { + return Result(false); + } + + auto bio = BIOPointer::NewMem(); + if (!bio) { + return Result(false); + } + + auto passphrase = GetPassphrase(config); + MarkPopErrorOnReturn mark_pop_error_on_return; + bool err; + + switch (config.type) { + case PKEncodingType::PKCS1: { + // PKCS1 is only permitted for RSA keys. + if (id() != EVP_PKEY_RSA) return Result(false); + +#if OPENSSL_VERSION_MAJOR >= 3 + const RSA* rsa = EVP_PKEY_get0_RSA(get()); +#else + RSA* rsa = EVP_PKEY_get0_RSA(get()); +#endif + switch (config.format) { + case PKFormatType::PEM: { + err = PEM_write_bio_RSAPrivateKey(bio.get(), rsa, config.cipher, + reinterpret_cast(passphrase.data), + passphrase.len, nullptr, nullptr) != 1; + break; + } + case PKFormatType::DER: { + // Encoding PKCS1 as DER. This variation does not permit encryption. + err = i2d_RSAPrivateKey_bio(bio.get(), rsa) != 1; + break; + } + default: { + // Should never get here. + return Result(false); + } + } + break; + } + case PKEncodingType::PKCS8: { + switch (config.format) { + case PKFormatType::PEM: { + // Encode PKCS#8 as PEM. + err = PEM_write_bio_PKCS8PrivateKey( + bio.get(), get(), + config.cipher, + passphrase.data, + passphrase.len, + nullptr, nullptr) != 1; + break; + } + case PKFormatType::DER: { + err = i2d_PKCS8PrivateKey_bio( + bio.get(), get(), + config.cipher, + passphrase.data, + passphrase.len, + nullptr, nullptr) != 1; + break; + } + default: { + // Should never get here. + return Result(false); + } + } + break; + } + case PKEncodingType::SEC1: { + // SEC1 is only permitted for EC keys + if (id() != EVP_PKEY_EC) return Result(false); + +#if OPENSSL_VERSION_MAJOR >= 3 + const EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get()); +#else + EC_KEY* ec = EVP_PKEY_get0_EC_KEY(get()); +#endif + switch (config.format) { + case PKFormatType::PEM: { + err = PEM_write_bio_ECPrivateKey(bio.get(), + ec, + config.cipher, + reinterpret_cast(passphrase.data), + passphrase.len, + nullptr, + nullptr) != 1; + break; + } + case PKFormatType::DER: { + // Encoding SEC1 as DER. This variation does not permit encryption. + err = i2d_ECPrivateKey_bio(bio.get(), ec) != 1; + break; + } + default: { + // Should never get here. + return Result(false); + } + } + break; + } + default: { + // Not a valid private key encoding + return Result(false); + } + } + + if (err) { + // Failed to encode the private key. + return Result(false, mark_pop_error_on_return.peekError()); + } + + return bio; +} + +Result EVPKeyPointer::writePublicKey( + const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config) const { + auto bio = BIOPointer::NewMem(); + if (!bio) return Result(false); + + MarkPopErrorOnReturn mark_pop_error_on_return; + + if (config.type == ncrypto::EVPKeyPointer::PKEncodingType::PKCS1) { + // PKCS#1 is only valid for RSA keys. +#if OPENSSL_VERSION_MAJOR >= 3 + const RSA* rsa = EVP_PKEY_get0_RSA(get()); +#else + RSA* rsa = EVP_PKEY_get0_RSA(get()); +#endif + if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { + // Encode PKCS#1 as PEM. + if (PEM_write_bio_RSAPublicKey(bio.get(), rsa) != 1) { + return Result(false, mark_pop_error_on_return.peekError()); + } + return bio; + } + + // Encode PKCS#1 as DER. + if (i2d_RSAPublicKey_bio(bio.get(), rsa) != 1) { + return Result(false, mark_pop_error_on_return.peekError()); + } + return bio; + } + + if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { + // Encode SPKI as PEM. + if (PEM_write_bio_PUBKEY(bio.get(), get()) != 1) { + return Result(false, mark_pop_error_on_return.peekError()); + } + return bio; + } + + // Encode SPKI as DER. + if (i2d_PUBKEY_bio(bio.get(), get()) != 1) { + return Result(false, mark_pop_error_on_return.peekError()); + } + return bio; +} + } // namespace ncrypto diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 20b69dc67b13fd..08eeb5be556136 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -386,13 +386,13 @@ class EVPKeyPointer final { // SubjectPublicKeyInfo according to X.509. SPKI, // ECPrivateKey according to SEC1. - SEC1 + SEC1, }; enum class PKFormatType { DER, PEM, - JWK + JWK, }; enum class PKParseError { @@ -402,18 +402,36 @@ class EVPKeyPointer final { }; using ParseKeyResult = Result; + struct AsymmetricKeyEncodingConfig { + bool output_key_object = false; + PKFormatType format = PKFormatType::DER; + PKEncodingType type = PKEncodingType::PKCS8; + AsymmetricKeyEncodingConfig() = default; + AsymmetricKeyEncodingConfig(bool output_key_object, PKFormatType format, PKEncodingType type); + AsymmetricKeyEncodingConfig(const AsymmetricKeyEncodingConfig&) = default; + AsymmetricKeyEncodingConfig& operator=(const AsymmetricKeyEncodingConfig&) = default; + }; + using PublicKeyEncodingConfig = AsymmetricKeyEncodingConfig; + + struct PrivateKeyEncodingConfig: public AsymmetricKeyEncodingConfig { + const EVP_CIPHER* cipher = nullptr; + std::optional passphrase = std::nullopt; + PrivateKeyEncodingConfig() = default; + PrivateKeyEncodingConfig(bool output_key_object, PKFormatType format, PKEncodingType type) + : AsymmetricKeyEncodingConfig(output_key_object, format, type) {} + PrivateKeyEncodingConfig(const PrivateKeyEncodingConfig&); + PrivateKeyEncodingConfig& operator=(const PrivateKeyEncodingConfig&); + }; + static ParseKeyResult TryParsePublicKey( - PKFormatType format, - PKEncodingType encoding, + const PublicKeyEncodingConfig& config, const Buffer& buffer); static ParseKeyResult TryParsePublicKeyPEM( const Buffer& buffer); static ParseKeyResult TryParsePrivateKey( - PKFormatType format, - PKEncodingType encoding, - std::optional> passphrase, + const PrivateKeyEncodingConfig& config, const Buffer& buffer); EVPKeyPointer() = default; @@ -441,9 +459,11 @@ class EVPKeyPointer final { size_t rawPrivateKeySize() const; DataPointer rawPublicKey() const; DataPointer rawPrivateKey() const; - BIOPointer derPublicKey() const; + Result writePrivateKey(const PrivateKeyEncodingConfig& config) const; + Result writePublicKey(const PublicKeyEncodingConfig& config) const; + EVPKeyCtxPointer newCtx() const; static bool IsRSAPrivateKey(const Buffer& buffer); diff --git a/src/crypto/crypto_keygen.cc b/src/crypto/crypto_keygen.cc index 8a17cde8b9cac5..c13acd63886673 100644 --- a/src/crypto/crypto_keygen.cc +++ b/src/crypto/crypto_keygen.cc @@ -48,8 +48,7 @@ Maybe NidKeyPairGenTraits::AdditionalConfig( EVPKeyCtxPointer NidKeyPairGenTraits::Setup(NidKeyPairGenConfig* params) { EVPKeyCtxPointer ctx = EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(params->params.id, nullptr)); - if (!ctx || EVP_PKEY_keygen_init(ctx.get()) <= 0) - return EVPKeyCtxPointer(); + if (!ctx || EVP_PKEY_keygen_init(ctx.get()) <= 0) return {}; return ctx; } diff --git a/src/crypto/crypto_keygen.h b/src/crypto/crypto_keygen.h index 2707cb8b41dc53..f1e92c69cb4065 100644 --- a/src/crypto/crypto_keygen.h +++ b/src/crypto/crypto_keygen.h @@ -147,19 +147,16 @@ struct KeyPairGenTraits final { // process input parameters. This allows each job to have a variable // number of input parameters specific to each job type. if (KeyPairAlgorithmTraits::AdditionalConfig(mode, args, offset, params) - .IsNothing()) { + .IsNothing() || + !KeyObjectData::GetPublicKeyEncodingFromJs( + args, offset, kKeyContextGenerate) + .To(¶ms->public_key_encoding) || + !KeyObjectData::GetPrivateKeyEncodingFromJs( + args, offset, kKeyContextGenerate) + .To(¶ms->private_key_encoding)) { return v8::Nothing(); } - params->public_key_encoding = KeyObjectData::GetPublicKeyEncodingFromJs( - args, offset, kKeyContextGenerate); - - auto private_key_encoding = KeyObjectData::GetPrivateKeyEncodingFromJs( - args, offset, kKeyContextGenerate); - - if (!private_key_encoding.IsEmpty()) - params->private_key_encoding = private_key_encoding.Release(); - return v8::JustVoid(); } @@ -230,8 +227,8 @@ struct SecretKeyGenTraits final { template struct KeyPairGenConfig final : public MemoryRetainer { - PublicKeyEncodingConfig public_key_encoding; - PrivateKeyEncodingConfig private_key_encoding; + ncrypto::EVPKeyPointer::PublicKeyEncodingConfig public_key_encoding; + ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig private_key_encoding; KeyObjectData key; AlgorithmParams params; @@ -245,7 +242,7 @@ struct KeyPairGenConfig final : public MemoryRetainer { explicit KeyPairGenConfig(KeyPairGenConfig&& other) noexcept : public_key_encoding(other.public_key_encoding), private_key_encoding( - std::forward( + std::forward( other.private_key_encoding)), key(std::move(other.key)), params(std::move(other.params)) {} @@ -258,9 +255,10 @@ struct KeyPairGenConfig final : public MemoryRetainer { void MemoryInfo(MemoryTracker* tracker) const override { tracker->TrackField("key", key); - if (!private_key_encoding.passphrase_.IsEmpty()) { + if (private_key_encoding.passphrase.has_value()) { + auto& passphrase = private_key_encoding.passphrase.value(); tracker->TrackFieldWithSize("private_key_encoding.passphrase", - private_key_encoding.passphrase_->size()); + passphrase.size()); } tracker->TrackField("params", params); } diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index efd20cdb9452e3..4a686a77b2a0ac 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -25,6 +25,7 @@ using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Int32; using v8::Isolate; +using v8::Just; using v8::JustVoid; using v8::Local; using v8::Maybe; @@ -40,199 +41,86 @@ using v8::Value; namespace crypto { namespace { -void GetKeyFormatAndTypeFromJs( - AsymmetricKeyEncodingConfig* config, - const FunctionCallbackInfo& args, - unsigned int* offset, - KeyEncodingContext context) { +Maybe +GetKeyFormatAndTypeFromJs(const FunctionCallbackInfo& args, + unsigned int* offset, + KeyEncodingContext context) { + ncrypto::EVPKeyPointer::AsymmetricKeyEncodingConfig config; // During key pair generation, it is possible not to specify a key encoding, // which will lead to a key object being returned. if (args[*offset]->IsUndefined()) { CHECK_EQ(context, kKeyContextGenerate); CHECK(args[*offset + 1]->IsUndefined()); - config->output_key_object_ = true; + config.output_key_object = true; } else { - config->output_key_object_ = false; + config.output_key_object = false; CHECK(args[*offset]->IsInt32()); - config->format_ = static_cast( + config.format = static_cast( args[*offset].As()->Value()); if (args[*offset + 1]->IsInt32()) { - config->type_ = - static_cast(args[*offset + 1].As()->Value()); + config.type = static_cast( + args[*offset + 1].As()->Value()); } else { - CHECK( - (context == kKeyContextInput && - config->format_ == kKeyFormatPEM) || - (context == kKeyContextGenerate && - config->format_ == kKeyFormatJWK)); + CHECK((context == kKeyContextInput && + config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) || + (context == kKeyContextGenerate && + config.format == ncrypto::EVPKeyPointer::PKFormatType::JWK)); CHECK(args[*offset + 1]->IsNullOrUndefined()); - config->type_ = std::nullopt; + config.type = ncrypto::EVPKeyPointer::PKEncodingType::PKCS1; } } *offset += 2; + return Just(config); } -MaybeLocal BIOToStringOrBuffer(Environment* env, - const BIOPointer& bio, - PKFormatType format) { +MaybeLocal BIOToStringOrBuffer( + Environment* env, + const BIOPointer& bio, + const ncrypto::EVPKeyPointer::AsymmetricKeyEncodingConfig& config) { BUF_MEM* bptr = bio; - if (format == kKeyFormatPEM) { + if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { // PEM is an ASCII format, so we will return it as a string. - return String::NewFromUtf8(env->isolate(), bptr->data, - NewStringType::kNormal, - bptr->length).FromMaybe(Local()); - } else { - CHECK_EQ(format, kKeyFormatDER); - // DER is binary, return it as a buffer. - return Buffer::Copy(env, bptr->data, bptr->length) + return String::NewFromUtf8( + env->isolate(), bptr->data, NewStringType::kNormal, bptr->length) .FromMaybe(Local()); } -} - -MaybeLocal WritePrivateKey(Environment* env, - OSSL3_CONST EVP_PKEY* pkey, - const PrivateKeyEncodingConfig& config) { - auto bio = BIOPointer::NewMem(); - CHECK(bio); - // If an empty string was passed as the passphrase, the ByteSource might - // contain a null pointer, which OpenSSL will ignore, causing it to invoke its - // default passphrase callback, which would block the thread until the user - // manually enters a passphrase. We could supply our own passphrase callback - // to handle this special case, but it is easier to avoid passing a null - // pointer to OpenSSL. - char* pass = nullptr; - size_t pass_len = 0; - if (!config.passphrase_.IsEmpty()) { - pass = const_cast(config.passphrase_->data()); - pass_len = config.passphrase_->size(); - if (pass == nullptr) { - // OpenSSL will not actually dereference this pointer, so it can be any - // non-null pointer. We cannot assert that directly, which is why we - // intentionally use a pointer that will likely cause a segmentation fault - // when dereferenced. - CHECK_EQ(pass_len, 0); - pass = reinterpret_cast(-1); - CHECK_NE(pass, nullptr); - } - } + CHECK_EQ(config.format, ncrypto::EVPKeyPointer::PKFormatType::DER); + // DER is binary, return it as a buffer. + return Buffer::Copy(env, bptr->data, bptr->length).FromMaybe(Local()); +} - MarkPopErrorOnReturn mark_pop_error_on_return; - bool err; - - PKEncodingType encoding_type = config.type_.value(); - if (encoding_type == kKeyEncodingPKCS1) { - // PKCS#1 is only permitted for RSA keys. - CHECK_EQ(EVPKeyPointer::id(pkey), EVP_PKEY_RSA); - - OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(pkey); - if (config.format_ == kKeyFormatPEM) { - // Encode PKCS#1 as PEM. - err = PEM_write_bio_RSAPrivateKey(bio.get(), - rsa, - config.cipher_, - reinterpret_cast(pass), - pass_len, - nullptr, - nullptr) != 1; - } else { - // Encode PKCS#1 as DER. This does not permit encryption. - CHECK_EQ(config.format_, kKeyFormatDER); - CHECK_NULL(config.cipher_); - err = i2d_RSAPrivateKey_bio(bio.get(), rsa) != 1; - } - } else if (encoding_type == kKeyEncodingPKCS8) { - if (config.format_ == kKeyFormatPEM) { - // Encode PKCS#8 as PEM. - err = PEM_write_bio_PKCS8PrivateKey( - bio.get(), pkey, - config.cipher_, - pass, - pass_len, - nullptr, nullptr) != 1; - } else { - // Encode PKCS#8 as DER. - CHECK_EQ(config.format_, kKeyFormatDER); - err = i2d_PKCS8PrivateKey_bio( - bio.get(), pkey, - config.cipher_, - pass, - pass_len, - nullptr, nullptr) != 1; - } - } else { - CHECK_EQ(encoding_type, kKeyEncodingSEC1); - - // SEC1 is only permitted for EC keys. - CHECK_EQ(EVPKeyPointer::id(pkey), EVP_PKEY_EC); - - OSSL3_CONST EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey); - if (config.format_ == kKeyFormatPEM) { - // Encode SEC1 as PEM. - err = PEM_write_bio_ECPrivateKey(bio.get(), - ec_key, - config.cipher_, - reinterpret_cast(pass), - pass_len, - nullptr, - nullptr) != 1; - } else { - // Encode SEC1 as DER. This does not permit encryption. - CHECK_EQ(config.format_, kKeyFormatDER); - CHECK_NULL(config.cipher_); - err = i2d_ECPrivateKey_bio(bio.get(), ec_key) != 1; - } +MaybeLocal WritePrivateKey( + Environment* env, + const EVPKeyPointer& pkey, + const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config) { + CHECK(pkey); + auto res = pkey.writePrivateKey(config); + if (res) { + return BIOToStringOrBuffer(env, std::move(res.value), config); } - if (err) { - ThrowCryptoError(env, ERR_get_error(), "Failed to encode private key"); - return MaybeLocal(); - } - return BIOToStringOrBuffer(env, bio, config.format_); + ThrowCryptoError( + env, res.openssl_error.value_or(0), "Failed to encode private key"); + return MaybeLocal(); } -bool WritePublicKeyInner(OSSL3_CONST EVP_PKEY* pkey, - const BIOPointer& bio, - const PublicKeyEncodingConfig& config) { - if (config.type_.value() == kKeyEncodingPKCS1) { - // PKCS#1 is only valid for RSA keys. - CHECK_EQ(EVPKeyPointer::id(pkey), EVP_PKEY_RSA); - OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(pkey); - if (config.format_ == kKeyFormatPEM) { - // Encode PKCS#1 as PEM. - return PEM_write_bio_RSAPublicKey(bio.get(), rsa) == 1; - } else { - // Encode PKCS#1 as DER. - CHECK_EQ(config.format_, kKeyFormatDER); - return i2d_RSAPublicKey_bio(bio.get(), rsa) == 1; - } - } else { - CHECK_EQ(config.type_.value(), kKeyEncodingSPKI); - if (config.format_ == kKeyFormatPEM) { - // Encode SPKI as PEM. - return PEM_write_bio_PUBKEY(bio.get(), pkey) == 1; - } else { - // Encode SPKI as DER. - CHECK_EQ(config.format_, kKeyFormatDER); - return i2d_PUBKEY_bio(bio.get(), pkey) == 1; - } +MaybeLocal WritePublicKey( + Environment* env, + const EVPKeyPointer& pkey, + const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config) { + CHECK(pkey); + auto res = pkey.writePublicKey(config); + if (res) { + return BIOToStringOrBuffer(env, res.value, config); } -} -MaybeLocal WritePublicKey(Environment* env, - OSSL3_CONST EVP_PKEY* pkey, - const PublicKeyEncodingConfig& config) { - auto bio = BIOPointer::NewMem(); - CHECK(bio); - - if (!WritePublicKeyInner(pkey, bio, config)) { - ThrowCryptoError(env, ERR_get_error(), "Failed to encode public key"); - return MaybeLocal(); - } - return BIOToStringOrBuffer(env, bio, config.format_); + ThrowCryptoError( + env, res.openssl_error.value_or(0), "Failed to encode public key"); + return MaybeLocal(); } Maybe ExportJWKSecretKey(Environment* env, @@ -247,12 +135,11 @@ Maybe ExportJWKSecretKey(Environment* env, key.GetSymmetricKeySize(), BASE64URL, &error); - if (key_data.IsEmpty()) { + if (!key_data.ToLocal(&raw)) { CHECK(!error.IsEmpty()); env->isolate()->ThrowException(error); return Nothing(); } - if (!key_data.ToLocal(&raw)) return Nothing(); if (target->Set( env->context(), @@ -277,8 +164,8 @@ KeyObjectData ImportJWKSecretKey(Environment* env, Local jwk) { } static_assert(String::kMaxLength <= INT_MAX); - auto key_data = ByteSource::FromEncodedString(env, key.As()); - return KeyObjectData::CreateSecret(std::move(key_data)); + return KeyObjectData::CreateSecret( + ByteSource::FromEncodedString(env, key.As())); } Maybe ExportJWKAsymmetricKey(Environment* env, @@ -290,7 +177,8 @@ Maybe ExportJWKAsymmetricKey(Environment* env, if (handleRsaPss) return ExportJWKRsaKey(env, key, target); break; } - case EVP_PKEY_RSA: return ExportJWKRsaKey(env, key, target); + case EVP_PKEY_RSA: + return ExportJWKRsaKey(env, key, target); case EVP_PKEY_EC: return ExportJWKEcKey(env, key, target); case EVP_PKEY_ED25519: @@ -299,7 +187,8 @@ Maybe ExportJWKAsymmetricKey(Environment* env, // Fall through case EVP_PKEY_X25519: // Fall through - case EVP_PKEY_X448: return ExportJWKEdKey(env, key, target); + case EVP_PKEY_X448: + return ExportJWKEdKey(env, key, target); } THROW_ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE(env); return Nothing(); @@ -354,38 +243,22 @@ Maybe GetAsymmetricKeyDetail(Environment* env, KeyObjectData TryParsePrivateKey( Environment* env, - const PrivateKeyEncodingConfig& config, + const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config, const ncrypto::Buffer& buffer) { - std::optional> maybePassphrase = std::nullopt; - if (config.passphrase_.get() != nullptr) { - maybePassphrase = ncrypto::Buffer{ - .data = const_cast(config.passphrase_->data()), - .len = config.passphrase_->size(), - }; + auto res = EVPKeyPointer::TryParsePrivateKey(config, buffer); + if (res) { + return KeyObjectData::CreateAsymmetric(KeyType::kKeyTypePrivate, + std::move(res.value)); } - auto res = EVPKeyPointer::TryParsePrivateKey( - static_cast(config.format_), - static_cast( - config.type_.value_or(kKeyEncodingPKCS8)), - std::move(maybePassphrase), - buffer); - - if (!res) { - if (res.error.value() == EVPKeyPointer::PKParseError::NEED_PASSPHRASE) { - THROW_ERR_MISSING_PASSPHRASE(env, - "Passphrase required for encrypted key"); - return {}; - } + if (res.error.value() == EVPKeyPointer::PKParseError::NEED_PASSPHRASE) { + THROW_ERR_MISSING_PASSPHRASE(env, "Passphrase required for encrypted key"); + } else { ThrowCryptoError( env, res.openssl_error.value_or(0), "Failed to read private key"); - return {}; } - - return KeyObjectData::CreateAsymmetric(KeyType::kKeyTypePrivate, - std::move(res.value)); + return {}; } -} // namespace // This maps true to JustVoid and false to Nothing(). static inline Maybe NothingIfFalse(bool b) { @@ -408,58 +281,61 @@ Maybe ExportJWKInner(Environment* env, UNREACHABLE(); } } +} // namespace Maybe KeyObjectData::ToEncodedPublicKey( Environment* env, - const PublicKeyEncodingConfig& config, + const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config, Local* out) { CHECK(key_type_ != KeyType::kKeyTypeSecret); - if (config.output_key_object_) { + if (config.output_key_object) { // Note that this has the downside of containing sensitive data of the // private key. return NothingIfFalse( KeyObjectHandle::Create(env, addRefWithType(KeyType::kKeyTypePublic)) .ToLocal(out)); - } else if (config.format_ == kKeyFormatJWK) { + } else if (config.format == ncrypto::EVPKeyPointer::PKFormatType::JWK) { *out = Object::New(env->isolate()); return ExportJWKInner( env, addRefWithType(KeyType::kKeyTypePublic), *out, false); } return NothingIfFalse( - WritePublicKey(env, GetAsymmetricKey().get(), config).ToLocal(out)); + WritePublicKey(env, GetAsymmetricKey(), config).ToLocal(out)); } Maybe KeyObjectData::ToEncodedPrivateKey( Environment* env, - const PrivateKeyEncodingConfig& config, + const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config, Local* out) { CHECK(key_type_ != KeyType::kKeyTypeSecret); - if (config.output_key_object_) { + if (config.output_key_object) { return NothingIfFalse( KeyObjectHandle::Create(env, addRefWithType(KeyType::kKeyTypePrivate)) .ToLocal(out)); - } else if (config.format_ == kKeyFormatJWK) { + } else if (config.format == ncrypto::EVPKeyPointer::PKFormatType::JWK) { *out = Object::New(env->isolate()); return ExportJWKInner( env, addRefWithType(KeyType::kKeyTypePrivate), *out, false); } return NothingIfFalse( - WritePrivateKey(env, GetAsymmetricKey().get(), config).ToLocal(out)); + WritePrivateKey(env, GetAsymmetricKey(), config).ToLocal(out)); } -NonCopyableMaybe +Maybe KeyObjectData::GetPrivateKeyEncodingFromJs( const FunctionCallbackInfo& args, unsigned int* offset, KeyEncodingContext context) { Environment* env = Environment::GetCurrent(args); - PrivateKeyEncodingConfig result; - GetKeyFormatAndTypeFromJs(&result, args, offset, context); + ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + if (!GetKeyFormatAndTypeFromJs(args, offset, context).To(&config)) { + return Nothing(); + } - if (result.output_key_object_) { + if (config.output_key_object) { if (context != kKeyContextInput) (*offset)++; } else { @@ -467,44 +343,43 @@ KeyObjectData::GetPrivateKeyEncodingFromJs( if (context != kKeyContextInput) { if (args[*offset]->IsString()) { Utf8Value cipher_name(env->isolate(), args[*offset]); - result.cipher_ = EVP_get_cipherbyname(*cipher_name); - if (result.cipher_ == nullptr) { + config.cipher = EVP_get_cipherbyname(*cipher_name); + if (config.cipher == nullptr) { THROW_ERR_CRYPTO_UNKNOWN_CIPHER(env); - return NonCopyableMaybe(); + return Nothing(); } needs_passphrase = true; } else { CHECK(args[*offset]->IsNullOrUndefined()); - result.cipher_ = nullptr; + config.cipher = nullptr; } (*offset)++; } if (IsAnyBufferSource(args[*offset])) { - CHECK_IMPLIES(context != kKeyContextInput, result.cipher_ != nullptr); + CHECK_IMPLIES(context != kKeyContextInput, config.cipher != nullptr); ArrayBufferOrViewContents passphrase(args[*offset]); if (!passphrase.CheckSizeInt32()) [[unlikely]] { THROW_ERR_OUT_OF_RANGE(env, "passphrase is too big"); - return NonCopyableMaybe(); + return Nothing(); } - result.passphrase_ = NonCopyableMaybe( - passphrase.ToNullTerminatedCopy()); + config.passphrase = passphrase.ToDataPointer(); } else { CHECK(args[*offset]->IsNullOrUndefined() && !needs_passphrase); } } (*offset)++; - return NonCopyableMaybe(std::move(result)); + return Just( + std::move(config)); } -PublicKeyEncodingConfig KeyObjectData::GetPublicKeyEncodingFromJs( +Maybe +KeyObjectData::GetPublicKeyEncodingFromJs( const FunctionCallbackInfo& args, unsigned int* offset, KeyEncodingContext context) { - PublicKeyEncodingConfig result; - GetKeyFormatAndTypeFromJs(&result, args, offset, context); - return result; + return GetKeyFormatAndTypeFromJs(args, offset, context); } KeyObjectData KeyObjectData::GetPrivateKeyFromJs( @@ -513,14 +388,17 @@ KeyObjectData KeyObjectData::GetPrivateKeyFromJs( bool allow_key_object) { if (args[*offset]->IsString() || IsAnyBufferSource(args[*offset])) { Environment* env = Environment::GetCurrent(args); - ByteSource key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]); - NonCopyableMaybe config = - GetPrivateKeyEncodingFromJs(args, offset, kKeyContextInput); + auto key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]); + + ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + if (!GetPrivateKeyEncodingFromJs(args, offset, kKeyContextInput) + .To(&config)) { + return {}; + } - if (config.IsEmpty()) return {}; return TryParsePrivateKey( env, - config.Release(), + config, ncrypto::Buffer{ .data = reinterpret_cast(key.data()), .len = key.size(), @@ -544,70 +422,62 @@ KeyObjectData KeyObjectData::GetPublicOrPrivateKeyFromJs( THROW_ERR_OUT_OF_RANGE(env, "keyData is too big"); return {}; } - NonCopyableMaybe config_ = - KeyObjectData::GetPrivateKeyEncodingFromJs( - args, offset, kKeyContextInput); - if (config_.IsEmpty()) return {}; - PrivateKeyEncodingConfig config = config_.Release(); + + ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + if (!KeyObjectData::GetPrivateKeyEncodingFromJs( + args, offset, kKeyContextInput) + .To(&config)) { + return {}; + } ncrypto::Buffer buffer = { .data = reinterpret_cast(data.data()), .len = data.size(), }; - std::optional> maybePassphrase = std::nullopt; - if (config.passphrase_.get() != nullptr) { - maybePassphrase = ncrypto::Buffer{ - .data = const_cast(config.passphrase_->data()), - .len = config.passphrase_->size(), - }; - } - - if (config.format_ == kKeyFormatPEM) { + if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM) { // For PEM, we can easily determine whether it is a public or private key // by looking for the respective PEM tags. auto res = EVPKeyPointer::TryParsePublicKeyPEM(buffer); - if (!res) { - if (res.error.value() == EVPKeyPointer::PKParseError::NOT_RECOGNIZED) { - return TryParsePrivateKey(env, config, buffer); - } - ThrowCryptoError(env, - res.openssl_error.value_or(0), - "Failed to read asymmetric key"); - return {}; + if (res) { + return CreateAsymmetric(kKeyTypePublic, std::move(res.value)); } - return CreateAsymmetric(kKeyTypePublic, std::move(res.value)); + + if (res.error.value() == EVPKeyPointer::PKParseError::NOT_RECOGNIZED) { + return TryParsePrivateKey(env, config, buffer); + } + ThrowCryptoError( + env, res.openssl_error.value_or(0), "Failed to read asymmetric key"); + return {}; } // For DER, the type determines how to parse it. SPKI, PKCS#8 and SEC1 are // easy, but PKCS#1 can be a public key or a private key. - bool is_public = ([&] { - switch (config.type_.value()) { - case kKeyEncodingPKCS1: + static const auto is_public = [](const auto& config, + const auto& buffer) -> bool { + switch (config.type) { + case ncrypto::EVPKeyPointer::PKEncodingType::PKCS1: return !EVPKeyPointer::IsRSAPrivateKey(buffer); - case kKeyEncodingSPKI: + case ncrypto::EVPKeyPointer::PKEncodingType::SPKI: return true; - case kKeyEncodingPKCS8: + case ncrypto::EVPKeyPointer::PKEncodingType::PKCS8: return false; - case kKeyEncodingSEC1: + case ncrypto::EVPKeyPointer::PKEncodingType::SEC1: return false; default: UNREACHABLE("Invalid key encoding type"); } - })(); - - if (is_public) { - auto res = EVPKeyPointer::TryParsePublicKey( - static_cast(config.format_), - static_cast(config.type_.value()), - buffer); - if (!res) { - ThrowCryptoError(env, - res.openssl_error.value_or(0), - "Failed to read asymmetric key"); - return {}; + }; + + if (is_public(config, buffer)) { + auto res = EVPKeyPointer::TryParsePublicKey(config, buffer); + if (res) { + return CreateAsymmetric(KeyType::kKeyTypePublic, std::move(res.value)); } - return CreateAsymmetric(KeyType::kKeyTypePublic, std::move(res.value)); + + ThrowCryptoError( + env, res.openssl_error.value_or(0), "Failed to read asymmetric key"); + return {}; } return TryParsePrivateKey(env, config, buffer); @@ -1120,20 +990,25 @@ void KeyObjectHandle::Export(const FunctionCallbackInfo& args) { result = key->ExportSecretKey(); } else if (type == kKeyTypePublic) { unsigned int offset = 0; - PublicKeyEncodingConfig config = KeyObjectData::GetPublicKeyEncodingFromJs( - args, &offset, kKeyContextExport); + ncrypto::EVPKeyPointer::PublicKeyEncodingConfig config; + if (!KeyObjectData::GetPublicKeyEncodingFromJs( + args, &offset, kKeyContextExport) + .To(&config)) { + return; + } CHECK_EQ(offset, static_cast(args.Length())); result = key->ExportPublicKey(config); } else { CHECK_EQ(type, kKeyTypePrivate); unsigned int offset = 0; - NonCopyableMaybe config = - KeyObjectData::GetPrivateKeyEncodingFromJs( - args, &offset, kKeyContextExport); - if (config.IsEmpty()) + ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig config; + if (!KeyObjectData::GetPrivateKeyEncodingFromJs( + args, &offset, kKeyContextExport) + .To(&config)) { return; + } CHECK_EQ(offset, static_cast(args.Length())); - result = key->ExportPrivateKey(config.Release()); + result = key->ExportPrivateKey(config); } if (!result.IsEmpty()) @@ -1147,13 +1022,13 @@ MaybeLocal KeyObjectHandle::ExportSecretKey() const { } MaybeLocal KeyObjectHandle::ExportPublicKey( - const PublicKeyEncodingConfig& config) const { - return WritePublicKey(env(), data_.GetAsymmetricKey().get(), config); + const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config) const { + return WritePublicKey(env(), data_.GetAsymmetricKey(), config); } MaybeLocal KeyObjectHandle::ExportPrivateKey( - const PrivateKeyEncodingConfig& config) const { - return WritePrivateKey(env(), data_.GetAsymmetricKey().get(), config); + const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config) const { + return WritePrivateKey(env(), data_.GetAsymmetricKey(), config); } void KeyObjectHandle::ExportJWK( @@ -1308,11 +1183,25 @@ void Initialize(Environment* env, Local target) { FIXED_ONE_BYTE_STRING(env->isolate(), "KeyObjectHandle"), KeyObjectHandle::Initialize(env)).Check(); + constexpr int kKeyEncodingPKCS1 = + static_cast(ncrypto::EVPKeyPointer::PKEncodingType::PKCS1); + constexpr int kKeyEncodingPKCS8 = + static_cast(ncrypto::EVPKeyPointer::PKEncodingType::PKCS8); + constexpr int kKeyEncodingSPKI = + static_cast(ncrypto::EVPKeyPointer::PKEncodingType::SPKI); + constexpr int kKeyEncodingSEC1 = + static_cast(ncrypto::EVPKeyPointer::PKEncodingType::SEC1); + constexpr int kKeyFormatDER = + static_cast(ncrypto::EVPKeyPointer::PKFormatType::DER); + constexpr int kKeyFormatPEM = + static_cast(ncrypto::EVPKeyPointer::PKFormatType::PEM); + constexpr int kKeyFormatJWK = + static_cast(ncrypto::EVPKeyPointer::PKFormatType::JWK); + NODE_DEFINE_CONSTANT(target, kWebCryptoKeyFormatRaw); NODE_DEFINE_CONSTANT(target, kWebCryptoKeyFormatPKCS8); NODE_DEFINE_CONSTANT(target, kWebCryptoKeyFormatSPKI); NODE_DEFINE_CONSTANT(target, kWebCryptoKeyFormatJWK); - NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED25519); NODE_DEFINE_CONSTANT(target, EVP_PKEY_ED448); NODE_DEFINE_CONSTANT(target, EVP_PKEY_X25519); diff --git a/src/crypto/crypto_keys.h b/src/crypto/crypto_keys.h index 6d794b439b51ba..32832e87798372 100644 --- a/src/crypto/crypto_keys.h +++ b/src/crypto/crypto_keys.h @@ -18,24 +18,6 @@ namespace node { namespace crypto { -// TODO(@jasnell): These static casts are temporarily while this code -// is being shifted over into ncrypto -enum PKEncodingType { - // RSAPublicKey / RSAPrivateKey according to PKCS#1. - kKeyEncodingPKCS1 = static_cast(EVPKeyPointer::PKEncodingType::PKCS1), - // PrivateKeyInfo or EncryptedPrivateKeyInfo according to PKCS#8. - kKeyEncodingPKCS8 = static_cast(EVPKeyPointer::PKEncodingType::PKCS8), - // SubjectPublicKeyInfo according to X.509. - kKeyEncodingSPKI = static_cast(EVPKeyPointer::PKEncodingType::SPKI), - // ECPrivateKey according to SEC1. - kKeyEncodingSEC1 = static_cast(EVPKeyPointer::PKEncodingType::SEC1), -}; - -enum PKFormatType { - kKeyFormatDER = static_cast(EVPKeyPointer::PKFormatType::DER), - kKeyFormatPEM = static_cast(EVPKeyPointer::PKFormatType::PEM), - kKeyFormatJWK = static_cast(EVPKeyPointer::PKFormatType::JWK), -}; enum KeyType { kKeyTypeSecret, @@ -58,22 +40,6 @@ enum class ParseKeyResult { kParseKeyOk, }; -struct AsymmetricKeyEncodingConfig { - bool output_key_object_ = false; - PKFormatType format_ = kKeyFormatDER; - std::optional type_ = std::nullopt; -}; - -using PublicKeyEncodingConfig = AsymmetricKeyEncodingConfig; - -struct PrivateKeyEncodingConfig : public AsymmetricKeyEncodingConfig { - const EVP_CIPHER* cipher_; - // The ByteSource alone is not enough to distinguish between "no passphrase" - // and a zero-length passphrase (which can be a null pointer), therefore, we - // use a NonCopyableMaybe. - NonCopyableMaybe passphrase_; -}; - // Objects of this class can safely be shared among threads. class KeyObjectData final : public MemoryRetainer { public: @@ -99,10 +65,10 @@ class KeyObjectData final : public MemoryRetainer { Mutex& mutex() const; - static PublicKeyEncodingConfig GetPublicKeyEncodingFromJs( - const v8::FunctionCallbackInfo& args, - unsigned int* offset, - KeyEncodingContext context); + static v8::Maybe + GetPublicKeyEncodingFromJs(const v8::FunctionCallbackInfo& args, + unsigned int* offset, + KeyEncodingContext context); static KeyObjectData GetPrivateKeyFromJs( const v8::FunctionCallbackInfo& args, @@ -112,18 +78,20 @@ class KeyObjectData final : public MemoryRetainer { static KeyObjectData GetPublicOrPrivateKeyFromJs( const v8::FunctionCallbackInfo& args, unsigned int* offset); - static NonCopyableMaybe GetPrivateKeyEncodingFromJs( - const v8::FunctionCallbackInfo& args, - unsigned int* offset, - KeyEncodingContext context); + static v8::Maybe + GetPrivateKeyEncodingFromJs(const v8::FunctionCallbackInfo& args, + unsigned int* offset, + KeyEncodingContext context); - v8::Maybe ToEncodedPublicKey(Environment* env, - const PublicKeyEncodingConfig& config, - v8::Local* out); + v8::Maybe ToEncodedPublicKey( + Environment* env, + const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config, + v8::Local* out); - v8::Maybe ToEncodedPrivateKey(Environment* env, - const PrivateKeyEncodingConfig& config, - v8::Local* out); + v8::Maybe ToEncodedPrivateKey( + Environment* env, + const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config, + v8::Local* out); inline KeyObjectData addRef() const { return KeyObjectData(key_type_, mutex_, data_); @@ -204,9 +172,9 @@ class KeyObjectHandle : public BaseObject { v8::MaybeLocal ExportSecretKey() const; v8::MaybeLocal ExportPublicKey( - const PublicKeyEncodingConfig& config) const; + const ncrypto::EVPKeyPointer::PublicKeyEncodingConfig& config) const; v8::MaybeLocal ExportPrivateKey( - const PrivateKeyEncodingConfig& config) const; + const ncrypto::EVPKeyPointer::PrivateKeyEncodingConfig& config) const; KeyObjectHandle(Environment* env, v8::Local wrap); diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index 922e77091d7217..5c717c6fdb0fc4 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -689,12 +689,22 @@ class ArrayBufferOrViewContents { return std::move(buf).release(size()); } + inline ncrypto::DataPointer ToDataPointer() const { + if (empty()) return {}; + if (auto dp = ncrypto::DataPointer::Alloc(size())) { + memcpy(dp.get(), data(), size()); + return dp; + } + return {}; + } + template void CopyTo(M* dest, size_t len) const { static_assert(sizeof(M) == 1, "sizeof(M) must equal 1"); len = std::min(len, size()); - if (len > 0 && data() != nullptr) + if (len > 0 && data() != nullptr) { memcpy(dest, data(), len); + } } private: From 6ab59c81b6a7f9f4ec63548eccc49a88088fea2f Mon Sep 17 00:00:00 2001 From: Mert Can Altin Date: Sat, 2 Nov 2024 18:11:44 +0300 Subject: [PATCH 51/93] os: improve path check with direct index access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55434 Reviewed-By: Luigi Pinca Reviewed-By: Juan José Arboleda --- lib/os.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/os.js b/lib/os.js index c88ef443b9b4f2..c6e2f220fd223b 100644 --- a/lib/os.js +++ b/lib/os.js @@ -26,7 +26,6 @@ const { Float64Array, NumberParseInt, ObjectDefineProperties, - StringPrototypeEndsWith, StringPrototypeSlice, SymbolToPrimitive, } = primordials; @@ -184,9 +183,9 @@ function tmpdir() { process.env.TMP || (process.env.SystemRoot || process.env.windir) + '\\temp'; - if (path.length > 1 && StringPrototypeEndsWith(path, '\\') && - !StringPrototypeEndsWith(path, ':\\')) + if (path.length > 1 && path[path.length - 1] === '\\' && path[path.length - 2] !== ':') { return StringPrototypeSlice(path, 0, -1); + } return path; } From 7af76ef0b31717c894cb20f499ad754f80b938ff Mon Sep 17 00:00:00 2001 From: Giovanni Bucci Date: Sat, 2 Nov 2024 16:12:12 +0100 Subject: [PATCH 52/93] assert: fix the string length check for printing the simple diff PR-URL: https://github.com/nodejs/node/pull/55474 Reviewed-By: Pietro Marchini Reviewed-By: Ruben Bridgewater --- lib/internal/assert/assertion_error.js | 9 ++++++++- test/parallel/test-assert-deep.js | 20 ++++++++++++++++++++ test/parallel/test-assert.js | 18 +++--------------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/lib/internal/assert/assertion_error.js b/lib/internal/assert/assertion_error.js index ee376899d04d35..dd56811647e5bf 100644 --- a/lib/internal/assert/assertion_error.js +++ b/lib/internal/assert/assertion_error.js @@ -134,7 +134,14 @@ function getStackedDiff(actual, expected) { } function getSimpleDiff(originalActual, actual, originalExpected, expected) { - const stringsLen = actual.length + expected.length; + let stringsLen = actual.length + expected.length; + // Accounting for the quotes wrapping strings + if (typeof originalActual === 'string') { + stringsLen -= 2; + } + if (typeof originalExpected === 'string') { + stringsLen -= 2; + } if (stringsLen <= kMaxShortStringLength && (originalActual !== 0 || originalExpected !== 0)) { return { message: `${actual} !== ${expected}`, header: '' }; } diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index aeacd21a21f029..93cc248160e6a1 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -846,6 +846,26 @@ test('Additional tests', () => { } ); + assert.throws( + () => assert.strictEqual('apple', 'pear'), + { + name: 'AssertionError', + message: 'Expected values to be strictly equal:\n\n\'apple\' !== \'pear\'\n' + } + ); + + assert.throws( + () => assert.strictEqual('ABABABABABAB', 'BABABABABABA'), + { + name: 'AssertionError', + message: 'Expected values to be strictly equal:\n' + + '+ actual - expected\n' + + '\n' + + "+ 'ABABABABABAB'\n" + + "- 'BABABABABABA'\n" + } + ); + assert.notDeepStrictEqual(new Date(), new Date(2000, 3, 14)); assert.throws( diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 4a6420779a845e..e639e7f150a5df 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -919,11 +919,7 @@ test('Additional asserts', () => { { code: 'ERR_ASSERTION', constructor: assert.AssertionError, - message: 'Expected values to be strictly equal:\n' + - '+ actual - expected\n' + - '\n' + - "+ 'string'\n" + - '- false\n' + message: 'Expected values to be strictly equal:\n\n\'string\' !== false\n' } ); @@ -935,11 +931,7 @@ test('Additional asserts', () => { { code: 'ERR_ASSERTION', constructor: assert.AssertionError, - message: 'Expected values to be strictly equal:\n' + - '+ actual - expected\n' + - '\n' + - "+ 'string'\n" + - '- false\n' + message: 'Expected values to be strictly equal:\n\n\'string\' !== false\n' } ); @@ -951,11 +943,7 @@ test('Additional asserts', () => { }, { code: 'ERR_ASSERTION', constructor: assert.AssertionError, - message: 'Expected values to be strictly equal:\n' + - '+ actual - expected\n' + - '\n' + - "+ 'string'\n" + - '- false\n' + message: 'Expected values to be strictly equal:\n\n\'string\' !== false\n' } ); /* eslint-enable @stylistic/js/indent */ From 869e88c6a8ebe780edd70dd81fbebf108e5e817d Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 2 Nov 2024 16:13:23 +0100 Subject: [PATCH 53/93] module: simplify `findPackageJSON` implementation PR-URL: https://github.com/nodejs/node/pull/55543 Reviewed-By: Jacob Smith Reviewed-By: Marco Ippolito --- lib/internal/modules/package_json_reader.js | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/internal/modules/package_json_reader.js b/lib/internal/modules/package_json_reader.js index d55ccbad64d0e6..92f46ed3971341 100644 --- a/lib/internal/modules/package_json_reader.js +++ b/lib/internal/modules/package_json_reader.js @@ -7,7 +7,6 @@ const { RegExpPrototypeExec, StringPrototypeIndexOf, StringPrototypeSlice, - StringPrototypeStartsWith, } = primordials; const { fileURLToPath, @@ -285,22 +284,14 @@ function findPackageJSON(specifier, base = 'data:') { validateString(specifier, 'specifier'); } - let parentURL; - if (isURL(base)) { - parentURL = new URL(base); - } else { + let parentURL = base; + if (!isURL(base)) { validateString(base, 'base'); - if ( - path.isAbsolute(base) || - (URLCanParse(base) && !StringPrototypeStartsWith(base, 'file:')) - ) { - parentURL = pathToFileURL(path.toNamespacedPath(base)); - } else { - parentURL = URL.parse(base) || pathToFileURL(base); - } + parentURL = path.isAbsolute(base) ? pathToFileURL(base) : new URL(base); } if (specifier && specifier[0] !== '.' && specifier[0] !== '/' && !URLCanParse(specifier)) { + // If `specifier` is a bare specifier. const { packageJSONPath } = getPackageJSONURL(specifier, parentURL); return packageJSONPath; } From d0ea9815f693b5c919714077bbd107835effa614 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sat, 2 Nov 2024 11:15:25 -0400 Subject: [PATCH 54/93] meta: make review-wanted message minimal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55607 Reviewed-By: Rafael Gonzaga Reviewed-By: Juan José Arboleda --- .github/workflows/notify-on-review-wanted.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/notify-on-review-wanted.yml b/.github/workflows/notify-on-review-wanted.yml index 6521318a2dce81..1f076a00027766 100644 --- a/.github/workflows/notify-on-review-wanted.yml +++ b/.github/workflows/notify-on-review-wanted.yml @@ -35,6 +35,7 @@ jobs: - name: Slack Notification uses: rtCamp/action-slack-notify@4e5fb42d249be6a45a298f3c9543b111b02f7907 # 2.3.0 env: + MSG_MINIMAL: actions url SLACK_COLOR: '#3d85c6' SLACK_ICON: https://github.com/nodejs.png?size=48 SLACK_TITLE: ${{ steps.define-message.outputs.title }} From dd9b6833c7dcc0aaf8ef04c86c009c4bacd43a0a Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Sun, 3 Nov 2024 03:24:29 +1100 Subject: [PATCH 55/93] Revert "fs,win: fix bug in paths with trailing slashes" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 00b2f07f9ddeb8ffd2fb2108b0ed9ffa81ea000d. PR-URL: https://github.com/nodejs/node/pull/55527 Fixes: https://github.com/nodejs/node/issues/17801 Reviewed-By: Rafael Gonzaga Reviewed-By: Juan José Arboleda Reviewed-By: Marco Ippolito Reviewed-By: Luigi Pinca Reviewed-By: Matteo Collina Reviewed-By: Stefan Stojanovic --- lib/fs.js | 26 ++--- lib/internal/fs/promises.js | 6 +- lib/internal/fs/streams.js | 4 +- lib/internal/fs/utils.js | 47 +------- test/sequential/test-fs-path-dir.js | 174 ---------------------------- 5 files changed, 20 insertions(+), 237 deletions(-) delete mode 100644 test/sequential/test-fs-path-dir.js diff --git a/lib/fs.js b/lib/fs.js index e6ae9855a0ddef..9db60a4f89a3d9 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -385,11 +385,7 @@ function readFile(path, options, callback) { const req = new FSReqCallback(); req.context = context; req.oncomplete = readFileAfterOpen; - binding.open( - getValidatedPath(path, 'path', { expectFile: true, syscall: 'read' }), - flagsNumber, - 0o666, - req); + binding.open(getValidatedPath(path), flagsNumber, 0o666, req); } function tryStatSync(fd, isUserFd) { @@ -441,9 +437,7 @@ function readFileSync(path, options) { if (options.encoding === 'utf8' || options.encoding === 'utf-8') { if (!isInt32(path)) { - path = getValidatedPath(path, - 'path', - { expectFile: true, syscall: 'read' }); + path = getValidatedPath(path); } return binding.readFileUtf8(path, stringToFlags(options.flag)); } @@ -537,7 +531,7 @@ function closeSync(fd) { * @returns {void} */ function open(path, flags, mode, callback) { - path = getValidatedPath(path, 'path', { expectFile: true, syscall: 'open' }); + path = getValidatedPath(path); if (arguments.length < 3) { callback = flags; flags = 'r'; @@ -566,7 +560,7 @@ function open(path, flags, mode, callback) { */ function openSync(path, flags, mode) { return binding.open( - getValidatedPath(path, 'path', { expectFile: true, syscall: 'open' }), + getValidatedPath(path), stringToFlags(flags), parseFileMode(mode, 'mode', 0o666), ); @@ -2345,9 +2339,7 @@ function writeFileSync(path, data, options) { // C++ fast path for string data and UTF8 encoding if (typeof data === 'string' && (options.encoding === 'utf8' || options.encoding === 'utf-8')) { if (!isInt32(path)) { - path = getValidatedPath(path, - 'path', - { expectFile: true, syscall: 'write' }); + path = getValidatedPath(path); } return binding.writeFileUtf8( @@ -2992,8 +2984,8 @@ function copyFile(src, dest, mode, callback) { mode = 0; } - src = getValidatedPath(src, 'src', { expectFile: true, syscall: 'cp' }); - dest = getValidatedPath(dest, 'dest', { expectFile: true, syscall: 'cp' }); + src = getValidatedPath(src, 'src'); + dest = getValidatedPath(dest, 'dest'); callback = makeCallback(callback); const req = new FSReqCallback(); @@ -3011,8 +3003,8 @@ function copyFile(src, dest, mode, callback) { */ function copyFileSync(src, dest, mode) { binding.copyFile( - getValidatedPath(src, 'src', { expectFile: true, syscall: 'cp' }), - getValidatedPath(dest, 'dest', { expectFile: true, syscall: 'cp' }), + getValidatedPath(src, 'src'), + getValidatedPath(dest, 'dest'), mode, ); } diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index f5a9a3a854263b..76460d2957bb0b 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -620,8 +620,8 @@ async function cp(src, dest, options) { async function copyFile(src, dest, mode) { return await PromisePrototypeThen( binding.copyFile( - getValidatedPath(src, 'src', { expectFile: true, syscall: 'cp' }), - getValidatedPath(dest, 'dest', { expectFile: true, syscall: 'cp' }), + getValidatedPath(src, 'src'), + getValidatedPath(dest, 'dest'), mode, kUsePromises, ), @@ -633,7 +633,7 @@ async function copyFile(src, dest, mode) { // Note that unlike fs.open() which uses numeric file descriptors, // fsPromises.open() uses the fs.FileHandle class. async function open(path, flags, mode) { - path = getValidatedPath(path, 'path', { expectFile: true, syscall: 'open' }); + path = getValidatedPath(path); const flagsNumber = stringToFlags(flags); mode = parseFileMode(mode, 'mode', 0o666); return new FileHandle(await PromisePrototypeThen( diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js index 6e7ae9d6804a04..43f06d0104de61 100644 --- a/lib/internal/fs/streams.js +++ b/lib/internal/fs/streams.js @@ -182,7 +182,7 @@ function ReadStream(path, options) { this.flags = options.flags === undefined ? 'r' : options.flags; this.mode = options.mode === undefined ? 0o666 : options.mode; - validatePath(this.path, 'path', { expectFile: true, syscall: 'read' }); + validatePath(this.path); } else { this.fd = getValidatedFd(importFd(this, options)); } @@ -337,7 +337,7 @@ function WriteStream(path, options) { this.flags = options.flags === undefined ? 'w' : options.flags; this.mode = options.mode === undefined ? 0o666 : options.mode; - validatePath(this.path, 'path', { expectFile: true, syscall: 'write' }); + validatePath(this.path); } else { this.fd = getValidatedFd(importFd(this, options)); } diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 5080bbf2580889..d54ab2112461aa 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -710,38 +710,13 @@ const validateOffsetLengthWrite = hideStackFrames( }, ); -/** - * Validates the given path based on the expected type (file or directory). - * @param {string} path - The path to validate. - * @param {string} [propName='path'] - The name of the property being validated. - * @param {object} options - Additional options for validation. - * @param {boolean} [options.expectFile] - If true, expects the path to be a file. - * @param {string} [options.syscall] - The name of the syscall. - * @throws {TypeError} Throws if the path is not a string, Uint8Array, or URL without null bytes. - * @throws {Error} Throws if the path does not meet the expected type (file). - */ -const validatePath = hideStackFrames((path, propName = 'path', options) => { +const validatePath = hideStackFrames((path, propName = 'path') => { if (typeof path !== 'string' && !isUint8Array(path)) { throw new ERR_INVALID_ARG_TYPE.HideStackFramesError(propName, ['string', 'Buffer', 'URL'], path); } const pathIsString = typeof path === 'string'; const pathIsUint8Array = isUint8Array(path); - if (options?.expectFile) { - const lastCharacter = path[path.length - 1]; - if ( - lastCharacter === '/' || lastCharacter === 47 || - (isWindows && (lastCharacter === '\\' || lastCharacter === 92)) - ) { - throw new ERR_FS_EISDIR({ - code: 'ERR_FS_EISDIR', - message: 'is a directory', - path, - syscall: options.syscall, - errno: ERR_FS_EISDIR, - }); - } - } // We can only perform meaningful checks on strings and Uint8Arrays. if ((!pathIsString && !pathIsUint8Array) || @@ -757,21 +732,11 @@ const validatePath = hideStackFrames((path, propName = 'path', options) => { ); }); -/** - * Validates and returns the given file URL or path based on the expected type (file or directory). - * @param {string|URL} fileURLOrPath - The file URL or path to validate. - * @param {string} [propName='path'] - The name of the property being validated. - * @param {object} options - Additional options for validation. - * @param {boolean} [options.expectFile] - If true, expects the path to be a file. - * @param {string} [options.syscall] - The name of the syscall. - * @returns {string} The validated path. - */ -const getValidatedPath = - hideStackFrames((fileURLOrPath, propName = 'path', options) => { - const path = toPathIfFileURL(fileURLOrPath); - validatePath(path, propName, options); - return path; - }); +const getValidatedPath = hideStackFrames((fileURLOrPath, propName = 'path') => { + const path = toPathIfFileURL(fileURLOrPath); + validatePath(path, propName); + return path; +}); const getValidatedFd = hideStackFrames((fd, propName = 'fd') => { if (ObjectIs(fd, -0)) { diff --git a/test/sequential/test-fs-path-dir.js b/test/sequential/test-fs-path-dir.js deleted file mode 100644 index 0926a207574b51..00000000000000 --- a/test/sequential/test-fs-path-dir.js +++ /dev/null @@ -1,174 +0,0 @@ -'use strict'; - -const common = require('../common'); -const tmpdir = require('../common/tmpdir'); -const assert = require('assert'); -const path = require('path'); -const fs = require('fs'); -const { pathToFileURL } = require('url'); - -tmpdir.refresh(); - -let fileCounter = 1; -const nextFile = () => path.join(tmpdir.path, `file${fileCounter++}`); - -const generateStringPath = (file, suffix = '') => file + suffix; - -const generateURLPath = (file, suffix = '') => - pathToFileURL(file + suffix); - -const generateUint8ArrayPath = (file, suffix = '') => - new Uint8Array(Buffer.from(file + suffix)); - -const generatePaths = (file, suffix = '') => [ - generateStringPath(file, suffix), - generateURLPath(file, suffix), - generateUint8ArrayPath(file, suffix), -]; - -const generateNewPaths = (suffix = '') => [ - generateStringPath(nextFile(), suffix), - generateURLPath(nextFile(), suffix), - generateUint8ArrayPath(nextFile(), suffix), -]; - -function checkSyncFn(syncFn, p, args, fail) { - const result = fail ? 'must fail' : 'must succeed'; - const failMsg = `failed testing sync ${p} ${syncFn.name} ${result}`; - if (!fail) { - try { - syncFn(p, ...args); - } catch (e) { - console.log(failMsg, e); - throw e; - } - } else { - assert.throws(() => syncFn(p, ...args), { - code: 'ERR_FS_EISDIR', - }, failMsg); - } -} - -function checkAsyncFn(asyncFn, p, args, fail) { - const result = fail ? 'must fail' : 'must succeed'; - const failMsg = `failed testing async ${p} ${asyncFn.name} ${result}`; - if (!fail) { - try { - asyncFn(p, ...args, common.mustCall()); - } catch (e) { - console.log(failMsg, e); - throw e; - } - } else { - assert.throws( - () => asyncFn(p, ...args, common.mustNotCall()), { - code: 'ERR_FS_EISDIR', - }, - failMsg - ); - } -} - -function checkPromiseFn(promiseFn, p, args, fail) { - const result = fail ? 'must fail' : 'must succeed'; - const failMsg = `failed testing promise ${p} ${promiseFn.name} ${result}`; - if (!fail) { - const r = promiseFn(p, ...args).catch((err) => { - console.log(failMsg, err); - throw err; - }); - r?.close?.(); - } else { - assert.rejects( - promiseFn(p, ...args), { - code: 'ERR_FS_EISDIR', - }, - failMsg - ).then(common.mustCall()); - } -} - -function check(asyncFn, syncFn, promiseFn, - { suffix, fail, args = [] }) { - const file = nextFile(); - fs.writeFile(file, 'data', (e) => { - assert.ifError(e); - const paths = generatePaths(file, suffix); - for (const p of paths) { - if (asyncFn) checkAsyncFn(asyncFn, p, args, fail); - if (promiseFn) checkPromiseFn(promiseFn, p, args, fail); - if (syncFn) checkSyncFn(syncFn, p, args, fail); - } - }); -} - -function checkManyToMany(asyncFn, syncFn, promiseFn, - { suffix, fail, args = [] }) { - const source = nextFile(); - fs.writeFile(source, 'data', (err) => { - assert.ifError(err); - if (asyncFn) { - generateNewPaths(suffix) - .forEach((p) => checkAsyncFn(asyncFn, source, [p, ...args], fail)); - } - if (promiseFn) { - generateNewPaths(suffix) - .forEach((p) => checkPromiseFn(promiseFn, source, [p, ...args], fail)); - } - if (syncFn) { - generateNewPaths(suffix) - .forEach((p) => checkSyncFn(syncFn, source, [p, ...args], fail)); - } - }); -} -check(fs.readFile, fs.readFileSync, fs.promises.readFile, - { suffix: '', fail: false }); -check(fs.readFile, fs.readFileSync, fs.promises.readFile, - { suffix: '/', fail: true }); -check(fs.writeFile, fs.writeFileSync, fs.promises.writeFile, - { suffix: '', fail: false, args: ['data'] }); -check(fs.writeFile, fs.writeFileSync, fs.promises.writeFile, - { suffix: '/', fail: true, args: ['data'] }); -check(fs.appendFile, fs.appendFileSync, fs.promises.appendFile, - { suffix: '', fail: false, args: ['data'] }); -check(fs.appendFile, fs.appendFileSync, fs.promises.appendFile, - { suffix: '/', fail: true, args: ['data'] }); -check(undefined, fs.createReadStream, undefined, - { suffix: '', fail: false }); -check(undefined, fs.createReadStream, undefined, - { suffix: '/', fail: true }); -check(undefined, fs.createWriteStream, undefined, - { suffix: '', fail: false }); -check(undefined, fs.createWriteStream, undefined, - { suffix: '/', fail: true }); -check(fs.truncate, fs.truncateSync, fs.promises.truncate, - { suffix: '', fail: false, args: [42] }); -check(fs.truncate, fs.truncateSync, fs.promises.truncate, - { suffix: '/', fail: true, args: [42] }); - -check(fs.open, fs.openSync, fs.promises.open, { suffix: '', fail: false }); -check(fs.open, fs.openSync, fs.promises.open, { suffix: '/', fail: true }); - -checkManyToMany(fs.copyFile, fs.copyFileSync, fs.promises.copyFile, - { suffix: '', fail: false }); - -checkManyToMany(fs.copyFile, fs.copyFileSync, fs.promises.copyFile, - { suffix: '/', fail: true }); - -if (common.isWindows) { - check(fs.readFile, fs.readFileSync, fs.promises.readFile, - { suffix: '\\', fail: true }); - check(fs.writeFile, fs.writeFileSync, fs.promises.writeFile, - { suffix: '\\', fail: true, args: ['data'] }); - check(fs.appendFile, fs.appendFileSync, fs.promises.appendFile, - { suffix: '\\', fail: true, args: ['data'] }); - check(undefined, fs.createReadStream, undefined, - { suffix: '\\', fail: true }); - check(undefined, fs.createWriteStream, undefined, - { suffix: '\\', fail: true }); - check(fs.truncate, fs.truncateSync, fs.promises.truncate, - { suffix: '\\', fail: true, args: [42] }); - check(fs.open, fs.openSync, fs.promises.open, { suffix: '\\', fail: true }); - checkManyToMany(fs.copyFile, fs.copyFileSync, fs.promises.copyFile, - { suffix: '\\', fail: true }); -} From c2fcda45ca5ce2615bbf493764d6fdf4c8ba1356 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 2 Nov 2024 16:36:49 +0000 Subject: [PATCH 56/93] typings: fix `ModulesBinding` types PR-URL: https://github.com/nodejs/node/pull/55549 Refs: https://github.com/nodejs/node/pull/55412/files#r1817708918 Reviewed-By: Jacob Smith Reviewed-By: Marco Ippolito --- typings/internalBinding/modules.d.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/typings/internalBinding/modules.d.ts b/typings/internalBinding/modules.d.ts index 7d35b864dae356..e19c662ded3379 100644 --- a/typings/internalBinding/modules.d.ts +++ b/typings/internalBinding/modules.d.ts @@ -9,7 +9,7 @@ export type PackageConfig = { export type DeserializedPackageConfig = { data: PackageConfig, exists: boolean, - path: URL['pathname'], + path: string, } export type SerializedPackageConfig = [ PackageConfig['name'], @@ -22,9 +22,10 @@ export type SerializedPackageConfig = [ export interface ModulesBinding { readPackageJSON(path: string): SerializedPackageConfig | undefined; - getNearestParentPackageJSON(path: string): SerializedPackageConfig | undefined - getNearestRawParentPackageJSON(origin: URL['pathname']): [ReturnType, DeserializedPackageConfig['path']] | undefined getNearestParentPackageJSONType(path: string): PackageConfig['type'] + getNearestParentPackageJSON(path: string): SerializedPackageConfig | undefined getPackageScopeConfig(path: string): SerializedPackageConfig | undefined - getPackageJSONScripts(): string | undefined + enableCompileCache(path?: string): { status: number, message?: string, directory?: string } + getCompileCacheDir(): string | undefined + flushCompileCache(keepDeserializedCache?: boolean): void } From b8ca9d89f4885d0279c5c64d860de6c1d159b168 Mon Sep 17 00:00:00 2001 From: robberfree Date: Sun, 3 Nov 2024 00:55:53 +0800 Subject: [PATCH 57/93] doc: add write flag when open file as the demo code's intention PR-URL: https://github.com/nodejs/node/pull/54626 Reviewed-By: James M Snell Reviewed-By: Jake Yuesong Li --- doc/api/stream.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index 9eadee899310e7..8dc5173500e623 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -3731,7 +3731,7 @@ class WriteStream extends Writable { this.fd = null; } _construct(callback) { - fs.open(this.filename, (err, fd) => { + fs.open(this.filename, 'w', (err, fd) => { if (err) { callback(err); } else { From 505ff199b65915c07bf840e636c5c5a14bb82895 Mon Sep 17 00:00:00 2001 From: Dom Harrington Date: Sat, 2 Nov 2024 17:05:24 +0000 Subject: [PATCH 58/93] doc: broken `PerformanceObserver` code sample The code sample at the top of the "Performance measurements API" section of the docs does not run. The code in question: ```js const { PerformanceObserver, performance } = require('node:perf_hooks'); const obs = new PerformanceObserver((items) => { console.log(items.getEntries()[0].duration); performance.clearMarks(); }); obs.observe({ type: 'measure' }); performance.measure('Start to Now'); performance.mark('A'); doSomeLongRunningProcess(() => { performance.measure('A to Now', 'A'); performance.mark('B'); performance.measure('A to B', 'A', 'B'); }); ``` If you replace `doSomeLongRunningProcess` with an IIFE with a sleep() at the top of it, you get this: ```js const { PerformanceObserver, performance } = require('node:perf_hooks'); const obs = new PerformanceObserver((items) => { console.log(items.getEntries()[0].duration); performance.clearMarks(); }); obs.observe({ type: 'measure' }); performance.measure('Start to Now'); performance.mark('A'); (async function doSomeLongRunningProcess() { await new Promise(r => setTimeout(r, 5000)); performance.measure('A to Now', 'A'); performance.mark('B'); performance.measure('A to B', 'A', 'B'); })() ``` When you run this, you get the following output: ```sh $ node performance-test.js 17.873416 node:internal/per_context/domexception:53 ErrorCaptureStackTrace(this); ^ DOMException [SyntaxError]: The "A" performance mark has not been set at new DOMException (node:internal/per_context/domexception:53:5) at __node_internal_ (node:internal/util:695:10) at getMark (node:internal/perf/usertiming:65:11) at calculateStartDuration (node:internal/perf/usertiming:202:13) at measure (node:internal/perf/usertiming:220:7) at Performance.measure (node:internal/perf/performance:135:12) at /private/tmp/performance-test.js:14:15 Node.js v20.11.1 ``` I believe it's due to the call to `performance.clearMarks();` in the PerformanceObserver callback. If you remove that, it works as expected: ```js const { PerformanceObserver, performance } = require('node:perf_hooks'); const obs = new PerformanceObserver((items) => { console.log(items.getEntries()[0].duration); }); obs.observe({ type: 'measure' }); performance.measure('Start to Now'); performance.mark('A'); (async function doSomeLongRunningProcess() { await new Promise(r => setTimeout(r, 5000)); performance.measure('A to Now', 'A'); performance.mark('B'); performance.measure('A to B', 'A', 'B'); })() ``` ```sh $ node performance-test.js 17.761083 5002.468417 ``` PR-URL: https://github.com/nodejs/node/pull/54227 Reviewed-By: Chengzhong Wu --- doc/api/perf_hooks.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/perf_hooks.md b/doc/api/perf_hooks.md index 74f8c115b486d4..7c3144939244b6 100644 --- a/doc/api/perf_hooks.md +++ b/doc/api/perf_hooks.md @@ -22,18 +22,18 @@ const { PerformanceObserver, performance } = require('node:perf_hooks'); const obs = new PerformanceObserver((items) => { console.log(items.getEntries()[0].duration); - performance.clearMarks(); }); obs.observe({ type: 'measure' }); performance.measure('Start to Now'); performance.mark('A'); -doSomeLongRunningProcess(() => { +(async function doSomeLongRunningProcess() { + await new Promise(r => setTimeout(r, 5000)); performance.measure('A to Now', 'A'); performance.mark('B'); performance.measure('A to B', 'A', 'B'); -}); +})(); ``` ## `perf_hooks.performance` From cba05cda38288ad2226250b465986a17abf0b9b7 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 2 Nov 2024 20:24:19 +0000 Subject: [PATCH 59/93] tools: run daily WPT.fyi report on all supported releases PR-URL: https://github.com/nodejs/node/pull/55619 Reviewed-By: Richard Lau Reviewed-By: Yagiz Nizipli --- .github/workflows/daily-wpt-fyi.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index 0cea4b01619b30..35f326365f1865 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -6,11 +6,6 @@ name: Daily WPT report on: workflow_dispatch: - inputs: - node-versions: - description: Node.js versions (as supported by actions/setup-node) to test as JSON array - required: false - default: '["current", "lts/*", "lts/-1"]' schedule: # This is 20 minutes after `epochs/daily` branch is triggered to be created # in WPT repo. @@ -24,11 +19,22 @@ permissions: contents: read jobs: - report: + collect-versions: if: github.repository == 'nodejs/node' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.query.outputs.matrix }} + steps: + - id: query + run: | + matrix=$(curl -s https://raw.githubusercontent.com/nodejs/Release/refs/heads/main/schedule.json | jq --arg now "$(date +%Y-%m-%d)" '[with_entries(select(.value.end > $now and .value.start < $now)) | keys[] | ltrimstr("v") | tonumber] + ["latest-nightly"]') + echo "matrix=$matrix" >> "$GITHUB_OUTPUT" + report: + needs: + - collect-versions strategy: matrix: - node-version: ${{ fromJSON(github.event.inputs.node-versions || '["latest-nightly", "current", "lts/*", "lts/-1"]') }} + node-version: ${{ fromJSON(needs.collect-versions.outputs.matrix) }} fail-fast: false runs-on: ubuntu-latest steps: From d0b2d6be840bbc3006b32ec65f66d02668892599 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Sat, 2 Nov 2024 20:42:06 +0000 Subject: [PATCH 60/93] tools: compact jq output in daily-wpt-fyi.yml action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55695 Reviewed-By: Yagiz Nizipli Reviewed-By: Juan José Arboleda --- .github/workflows/daily-wpt-fyi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index 35f326365f1865..a148f21428170c 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -27,7 +27,7 @@ jobs: steps: - id: query run: | - matrix=$(curl -s https://raw.githubusercontent.com/nodejs/Release/refs/heads/main/schedule.json | jq --arg now "$(date +%Y-%m-%d)" '[with_entries(select(.value.end > $now and .value.start < $now)) | keys[] | ltrimstr("v") | tonumber] + ["latest-nightly"]') + matrix=$(curl -s https://raw.githubusercontent.com/nodejs/Release/refs/heads/main/schedule.json | jq -c --arg now "$(date +%Y-%m-%d)" '[with_entries(select(.value.end > $now and .value.start < $now)) | keys[] | ltrimstr("v") | tonumber] + ["latest-nightly"]') echo "matrix=$matrix" >> "$GITHUB_OUTPUT" report: needs: From dfb764cbc687f894372bdb1c8e9ae0d465b928a1 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sat, 2 Nov 2024 17:39:25 -0400 Subject: [PATCH 61/93] deps: update sqlite to 3.47.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55557 Reviewed-By: Marco Ippolito Reviewed-By: Tobias Nießen Reviewed-By: Rafael Gonzaga --- deps/sqlite/sqlite3.c | 8285 +++++++++++++++++++++++++++-------------- deps/sqlite/sqlite3.h | 193 +- 2 files changed, 5693 insertions(+), 2785 deletions(-) diff --git a/deps/sqlite/sqlite3.c b/deps/sqlite/sqlite3.c index 20752a7ca9ee68..2886d04ae5263b 100644 --- a/deps/sqlite/sqlite3.c +++ b/deps/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.46.1. By combining all the individual C code files into this +** version 3.47.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** c9c2ab54ba1f5f46360f1b4f35d849cd3f08. +** 03a9703e27c44437c39363d0baf82db4ebc9. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -256,10 +256,13 @@ /* ** Macro to disable warnings about missing "break" at the end of a "case". */ -#if GCC_VERSION>=7000000 -# define deliberate_fall_through __attribute__((fallthrough)); -#else -# define deliberate_fall_through +#if defined(__has_attribute) +# if __has_attribute(fallthrough) +# define deliberate_fall_through __attribute__((fallthrough)); +# endif +#endif +#if !defined(deliberate_fall_through) +# define deliberate_fall_through #endif /* @@ -459,9 +462,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.46.1" -#define SQLITE_VERSION_NUMBER 3046001 -#define SQLITE_SOURCE_ID "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33" +#define SQLITE_VERSION "3.47.0" +#define SQLITE_VERSION_NUMBER 3047000 +#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1085,8 +1088,8 @@ struct sqlite3_file { ** to xUnlock() is a no-op. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, -** PENDING, or EXCLUSIVE lock on the file. It returns true -** if such a lock exists and false otherwise. +** PENDING, or EXCLUSIVE lock on the file. It returns, via its output +** pointer parameter, true if such a lock exists and false otherwise. ** ** The xFileControl() method is a generic interface that allows custom ** VFS implementations to directly control an open file using the @@ -3883,8 +3886,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** [[OPEN_EXRESCODE]] ^(
[SQLITE_OPEN_EXRESCODE]
**
The database connection comes up in "extended result code mode". -** In other words, the database behaves has if -** [sqlite3_extended_result_codes(db,1)] where called on the database +** In other words, the database behaves as if +** [sqlite3_extended_result_codes(db,1)] were called on the database ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.
@@ -4535,13 +4538,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the -** first zero terminator. ^If nByte is positive, then it is the -** number of bytes read from zSql. ^If nByte is zero, then no prepared +** first zero terminator. ^If nByte is positive, then it is the maximum +** number of bytes read from zSql. When nByte is positive, zSql is read +** up to the first zero terminator or until the nByte bytes have been read, +** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string including ** the nul-terminator. +** Note that nByte measure the length of the input in bytes, not +** characters, even for the UTF-16 interfaces. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only @@ -5912,7 +5919,7 @@ SQLITE_API int sqlite3_create_window_function( ** This flag instructs SQLite to omit some corner-case optimizations that ** might disrupt the operation of the [sqlite3_value_subtype()] function, ** causing it to return zero rather than the correct subtype(). -** SQL functions that invokes [sqlite3_value_subtype()] should have this +** All SQL functions that invoke [sqlite3_value_subtype()] should have this ** property. If the SQLITE_SUBTYPE property is omitted, then the return ** value from [sqlite3_value_subtype()] might sometimes be zero even though ** a non-zero subtype was specified by the function argument expression. @@ -5928,6 +5935,15 @@ SQLITE_API int sqlite3_create_window_function( ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. +** +** [[SQLITE_SELFORDER1]]
SQLITE_SELFORDER1
+** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate +** that internally orders the values provided to the first argument. The +** ordered-set aggregate SQL notation with a single ORDER BY term can be +** used to invoke this function. If the ordered-set aggregate notation is +** used on a function that lacks this flag, then an error is raised. Note +** that the ordered-set aggregate syntax is only available if SQLite is +** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. **
** */ @@ -5936,6 +5952,7 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 +#define SQLITE_SELFORDER1 0x002000000 /* ** CAPI3REF: Deprecated Functions @@ -6133,7 +6150,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** -** Every [application-defined SQL function] that invoke this interface +** Every [application-defined SQL function] that invokes this interface ** should include the [SQLITE_SUBTYPE] property in the text ** encoding argument when the function is [sqlite3_create_function|registered]. ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() @@ -7740,9 +7757,11 @@ struct sqlite3_module { ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a -** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - -** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite -** assumes that the strategy may visit at most one row. +** mask of SQLITE_INDEX_SCAN_* flags. One such flag is +** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] +** output to show the idxNum has hex instead of as decimal. Another flag is +** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will +** return at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as @@ -7806,7 +7825,9 @@ struct sqlite3_index_info { ** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ -#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ +#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ +#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ + /* in EXPLAIN QUERY PLAN */ /* ** CAPI3REF: Virtual Table Constraint Operator Codes @@ -8643,6 +8664,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ +#define SQLITE_TESTCTRL_GETOPT 16 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 @@ -8662,7 +8684,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 -#define SQLITE_TESTCTRL_USELONGDOUBLE 34 +#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* @@ -9638,6 +9660,16 @@ typedef struct sqlite3_backup sqlite3_backup; ** APIs are not strictly speaking threadsafe. If they are invoked at the ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. +** +** Alternatives To Using The Backup API +** +** Other techniques for safely creating a consistent backup of an SQLite +** database include: +** +**
    +**
  • The [VACUUM INTO] command. +**
  • The [sqlite3_rsync] utility program. +**
*/ SQLITE_API sqlite3_backup *sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ @@ -10837,6 +10869,14 @@ typedef struct sqlite3_snapshot { ** If there is not already a read-transaction open on schema S when ** this function is called, one is opened automatically. ** +** If a read-transaction is opened by this function, then it is guaranteed +** that the returned snapshot object may not be invalidated by a database +** writer or checkpointer until after the read-transaction is closed. This +** is not guaranteed if a read-transaction is already open when this +** function is called. In that case, any subsequent write or checkpoint +** operation on the database may invalidate the returned snapshot handle, +** even while the read-transaction remains open. +** ** The following must be true for this function to succeed. If any of ** the following statements are false when sqlite3_snapshot_get() is ** called, SQLITE_ERROR is returned. The final value of *P is undefined @@ -11145,8 +11185,6 @@ SQLITE_API int sqlite3_deserialize( #if defined(__wasi__) # undef SQLITE_WASI # define SQLITE_WASI 1 -# undef SQLITE_OMIT_WAL -# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ # ifndef SQLITE_OMIT_LOAD_EXTENSION # define SQLITE_OMIT_LOAD_EXTENSION # endif @@ -13349,6 +13387,10 @@ struct Fts5PhraseIter { ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** ** xPhraseNext() ** See xPhraseFirst above. ** @@ -13415,9 +13457,32 @@ struct Fts5PhraseIter { ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. +** +** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the locale associated +** with column iCol of the current row. Usually, there is no associated +** locale, and output parameters (*pzLocale) and (*pnLocale) are set +** to NULL and 0, respectively. However, if the fts5_locale() function +** was used to associate a locale with the value when it was inserted +** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated +** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) +** is set to the size in bytes of the buffer, not including the +** nul-terminator. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an +** SQLite error code is returned. The final value of the output parameters +** is undefined in this case. +** +** xTokenize_v2: +** Tokenize text using the tokenizer belonging to the FTS5 table. This +** API is the same as the xTokenize() API, except that it allows a tokenizer +** locale to be specified. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 3 */ + int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); @@ -13459,6 +13524,15 @@ struct Fts5ExtensionApi { const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); + + /* Below this point are iVersion>=4 only */ + int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xTokenize_v2)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); }; /* @@ -13479,7 +13553,7 @@ struct Fts5ExtensionApi { ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) -** pointer provided by the application when the fts5_tokenizer object +** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the @@ -13503,7 +13577,7 @@ struct Fts5ExtensionApi { ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** -** The second argument indicates the reason that FTS5 is requesting +** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** @@ -13527,6 +13601,13 @@ struct Fts5ExtensionApi { ** on a columnsize=0 database. ** ** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth @@ -13550,6 +13631,30 @@ struct Fts5ExtensionApi { ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +**
    +**
  • There is no "iVersion" field, and +**
  • The xTokenize() method does not take a locale argument. +**
+** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a @@ -13658,6 +13763,33 @@ struct Fts5ExtensionApi { ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); @@ -13677,6 +13809,7 @@ struct fts5_tokenizer { ); }; + /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 @@ -13696,7 +13829,7 @@ struct fts5_tokenizer { */ typedef struct fts5_api fts5_api; struct fts5_api { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( @@ -13723,6 +13856,25 @@ struct fts5_api { fts5_extension_function xFunction, void (*xDestroy)(void*) ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); }; /* @@ -14532,132 +14684,132 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 #define TK_FUNCTION 172 #define TK_UPLUS 173 #define TK_UMINUS 174 @@ -14680,6 +14832,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #include #include #include +#include /* ** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY. @@ -14700,7 +14853,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #ifdef SQLITE_OMIT_FLOATING_POINT # define double sqlite_int64 # define float sqlite_int64 -# define LONGDOUBLE_TYPE sqlite_int64 +# define fabs(X) ((X)<0?-(X):(X)) +# define sqlite3IsOverflow(X) 0 # ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif @@ -14875,9 +15029,6 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); # define INT8_TYPE signed char # endif #endif -#ifndef LONGDOUBLE_TYPE -# define LONGDOUBLE_TYPE long double -#endif typedef sqlite_int64 i64; /* 8-byte signed integer */ typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ @@ -15377,6 +15528,7 @@ typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; +typedef struct Subquery Subquery; typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ @@ -16259,6 +16411,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursor( ); SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor(Btree*,BtCursor*); +#endif SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -16477,6 +16632,19 @@ typedef struct Vdbe Vdbe; */ typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; +typedef struct SubrtnSig SubrtnSig; + +/* +** A signature for a reusable subroutine that materializes the RHS of +** an IN operator. +*/ +struct SubrtnSig { + int selId; /* SELECT-id for the SELECT statement on the RHS */ + char *zAff; /* Affinity of the overall IN expression */ + int iTable; /* Ephemeral table generated by the subroutine */ + int iAddr; /* Subroutine entry address */ + int regReturn; /* Register used to hold return address */ +}; /* ** A single instruction of the virtual machine has an opcode @@ -16505,6 +16673,7 @@ struct VdbeOp { u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ + SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif @@ -16572,6 +16741,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ +#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 @@ -16663,16 +16833,16 @@ typedef struct VdbeOpList VdbeOpList; #define OP_RowSetTest 47 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Program 48 /* jump0 */ #define OP_FkIfZero 49 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ -#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ -#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ -#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ -#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ -#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ -#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ -#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ -#define OP_IfPos 59 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IfPos 50 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IsNull 51 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ +#define OP_NotNull 52 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ +#define OP_Ne 53 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ +#define OP_Eq 54 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */ +#define OP_Gt 55 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */ +#define OP_Le 56 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ +#define OP_Lt 57 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ +#define OP_ElseEq 59 /* jump, same as TK_ESCAPE */ #define OP_IfNotZero 60 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ #define OP_DecrJumpZero 61 /* jump, synopsis: if (--r[P1])==0 goto P2 */ #define OP_IncrVacuum 62 /* jump */ @@ -16715,23 +16885,23 @@ typedef struct VdbeOpList VdbeOpList; #define OP_ReadCookie 99 #define OP_SetCookie 100 #define OP_ReopenIdx 101 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_OpenRead 112 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 102 /* synopsis: root=P2 iDb=P3 */ +#define OP_BitAnd 103 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 104 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 105 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 107 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 108 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 109 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 110 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 111 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 112 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ #define OP_OpenWrite 113 /* synopsis: root=P2 iDb=P3 */ -#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_OpenDup 115 +#define OP_OpenDup 114 +#define OP_BitNot 115 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ #define OP_OpenAutoindex 116 /* synopsis: nColumn=P2 */ -#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */ +#define OP_String8 118 /* same as TK_STRING, synopsis: r[P2]='P4' */ #define OP_SorterOpen 119 #define OP_SequenceTest 120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ #define OP_OpenPseudo 121 /* synopsis: P3 columns in r[P2] */ @@ -16766,8 +16936,8 @@ typedef struct VdbeOpList VdbeOpList; #define OP_LoadAnalysis 150 #define OP_DropTable 151 #define OP_DropIndex 152 -#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_DropTrigger 154 +#define OP_DropTrigger 153 +#define OP_Real 154 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ #define OP_IntegrityCk 155 #define OP_RowSetAdd 156 /* synopsis: rowset(P1)=r[P2] */ #define OP_Param 157 @@ -16823,20 +16993,20 @@ typedef struct VdbeOpList VdbeOpList; /* 24 */ 0xc9, 0x01, 0x49, 0x49, 0x49, 0x49, 0xc9, 0x49,\ /* 32 */ 0xc1, 0x01, 0x41, 0x41, 0xc1, 0x01, 0x41, 0x41,\ /* 40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\ -/* 48 */ 0x81, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\ +/* 48 */ 0x81, 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x41,\ /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\ /* 80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\ /* 88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\ -/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x26, 0x26,\ +/* 96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\ +/* 112 */ 0x26, 0x00, 0x40, 0x12, 0x40, 0x40, 0x10, 0x00,\ /* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\ /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x50,\ /* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\ /* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ +/* 152 */ 0x00, 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ /* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ @@ -17897,6 +18067,7 @@ struct sqlite3 { #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ +#define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -18884,9 +19055,15 @@ struct AggInfo { ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** The assert()s that are part of this macro verify that constraint. */ +#ifndef NDEBUG #define AggInfoColumnReg(A,I) (assert((A)->iFirstReg),(A)->iFirstReg+(I)) #define AggInfoFuncReg(A,I) \ (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I)) +#else +#define AggInfoColumnReg(A,I) ((A)->iFirstReg+(I)) +#define AggInfoFuncReg(A,I) \ + ((A)->iFirstReg+(A)->nColumn+(I)) +#endif /* ** The datatype ynVar is a signed integer, either 16-bit or 32-bit. @@ -19067,7 +19244,7 @@ struct Expr { #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ - /* 0x80000000 // Available */ +#define EP_SubtArg 0x80000000 /* Is argument to SQLITE_SUBTYPE function */ /* The EP_Propagate mask is a set of properties that automatically propagate ** upwards into parent nodes. @@ -19238,6 +19415,16 @@ struct IdList { #define EU4_IDX 1 /* Uses IdList.a.u4.idx */ #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ +/* +** Details of the implementation of a subquery. +*/ +struct Subquery { + Select *pSelect; /* A SELECT statement used in place of a table name */ + int addrFillSub; /* Address of subroutine to initialize a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ +}; + /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. @@ -19250,29 +19437,40 @@ struct IdList { ** In the colUsed field, the high-order bit (bit 63) is set if the table ** contains more than 63 columns and the 64-th or later column is used. ** -** Union member validity: +** Aggressive use of "union" helps keep the size of the object small. This +** has been shown to boost performance, in addition to saving memory. +** Access to union elements is gated by the following rules which should +** always be checked, either by an if-statement or by an assert(). ** -** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc -** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy +** Field Only access if this is true +** --------------- ----------------------------------- +** u1.zIndexedBy fg.isIndexedBy +** u1.pFuncArg fg.isTabFunc ** u1.nRow !fg.isTabFunc && !fg.isIndexedBy ** -** u2.pIBIndex fg.isIndexedBy && !fg.isCte -** u2.pCteUse fg.isCte && !fg.isIndexedBy +** u2.pIBIndex fg.isIndexedBy +** u2.pCteUse fg.isCte +** +** u3.pOn !fg.isUsing +** u3.pUsing fg.isUsing +** +** u4.zDatabase !fg.fixedSchema && !fg.isSubquery +** u4.pSchema fg.fixedSchema +** u4.pSubq fg.isSubquery +** +** See also the sqlite3SrcListDelete() routine for assert() statements that +** check invariants on the fields of this object, especially the flags +** inside the fg struct. */ struct SrcItem { - Schema *pSchema; /* Schema to which this item is fixed */ - char *zDatabase; /* Name of database holding this table */ char *zName; /* Name of the table */ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ - Table *pTab; /* An SQL table corresponding to zName */ - Select *pSelect; /* A SELECT statement used in place of a table name */ - int addrFillSub; /* Address of subroutine to manifest a subquery */ - int regReturn; /* Register holding return address of addrFillSub */ - int regResult; /* Registers holding results of a co-routine */ + Table *pSTab; /* Table object for zName. Mnemonic: Srcitem-TABle */ struct { u8 jointype; /* Type of join between this table and the previous */ unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isSubquery :1; /* True if this term is a subquery */ unsigned isTabFunc :1; /* True if table-valued-function syntax */ unsigned isCorrelated :1; /* True if sub-query is correlated */ unsigned isMaterialized:1; /* This is a materialized view */ @@ -19286,12 +19484,10 @@ struct SrcItem { unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ unsigned rowidUsed :1; /* The ROWID of this table is referenced */ + unsigned fixedSchema :1; /* Uses u4.pSchema, not u4.zDatabase */ + unsigned hadSchema :1; /* Had u4.zDatabase before u4.pSchema */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ - union { - Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ - IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ - } u3; Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */ union { char *zIndexedBy; /* Identifier from "INDEXED BY " clause */ @@ -19302,6 +19498,15 @@ struct SrcItem { Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */ } u2; + union { + Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ + IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ + } u3; + union { + Schema *pSchema; /* Schema to which this item is fixed */ + char *zDatabase; /* Name of database holding this table */ + Subquery *pSubq; /* Description of a subquery */ + } u4; }; /* @@ -19433,7 +19638,7 @@ struct NameContext { #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ #define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ -#define NC_Complex 0x002000 /* True if a function or subquery seen */ +/* 0x002000 // available for reuse */ #define NC_AllowWin 0x004000 /* Window functions are allowed here */ #define NC_HasWin 0x008000 /* One or more window functions seen */ #define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ @@ -19561,8 +19766,10 @@ struct Select { #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ #define SF_Correlated 0x20000000 /* True if references the outer context */ -/* True if S exists and has SF_NestedFrom */ -#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) +/* True if SrcItem X is a subquery that has SF_NestedFrom */ +#define IsNestedFrom(X) \ + ((X)->fg.isSubquery && \ + ((X)->u4.pSubq->pSelect->selFlags&SF_NestedFrom)!=0) /* ** The results of a SELECT can be distributed in several ways, as defined @@ -19592,7 +19799,11 @@ struct Select { ** SRT_Set The result must be a single column. Store each ** row of result as the key in table pDest->iSDParm. ** Apply the affinity pDest->affSdst before storing -** results. Used to implement "IN (SELECT ...)". +** results. if pDest->iSDParm2 is positive, then it is +** a register holding a Bloom filter for the IN operator +** that should be populated in addition to the +** pDest->iSDParm table. This SRT is used to +** implement "IN (SELECT ...)". ** ** SRT_EphemTab Create an temporary table pDest->iSDParm and store ** the result there. The cursor is left open after @@ -19800,6 +20011,7 @@ struct Parse { u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 bHasWith; /* True if statement contains WITH */ + u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif @@ -20095,7 +20307,7 @@ struct Returning { }; /* -** An objected used to accumulate the text of a string where we +** An object used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. */ struct sqlite3_str { @@ -20109,7 +20321,7 @@ struct sqlite3_str { }; #define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ #define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ -#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ +#define SQLITE_PRINTF_MALLOCED 0x04 /* True if zText is allocated space */ #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) @@ -20187,7 +20399,6 @@ struct Sqlite3Config { u8 bUseCis; /* Use covering indices for full-scans */ u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ - u8 bUseLongDouble; /* Make use of long double */ #ifdef SQLITE_DEBUG u8 bJsonSelfcheck; /* Double-check JSON parsing */ #endif @@ -20562,15 +20773,6 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); # define SQLITE_ENABLE_FTS3 1 #endif -/* -** The ctype.h header is needed for non-ASCII systems. It is also -** needed by FTS3 when FTS3 is included in the amalgamation. -*/ -#if !defined(SQLITE_ASCII) || \ - (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION)) -# include -#endif - /* ** The following macros mimic the standard library functions toupper(), ** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The @@ -20949,6 +21151,9 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3*,Subquery*); +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3*,SrcItem*); +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery(Parse*, SrcItem*, Select*, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); @@ -20998,6 +21203,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg); SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); @@ -21060,7 +21266,7 @@ SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int,i #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*, Parse*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); @@ -21188,7 +21394,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*); SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 -SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nByte, int nChar); #endif SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); @@ -22174,6 +22380,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC "ENABLE_OFFSET_SQL_FUNC", #endif +#ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES + "ENABLE_ORDERED_SET_AGGREGATES", +#endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif @@ -22921,7 +23130,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ - sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ #ifdef SQLITE_DEBUG 0, /* bJsonSelfcheck */ #endif @@ -23644,6 +23852,7 @@ struct PreUpdate { Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ + sqlite3_value **apDflt; /* Array of default values, if required */ }; /* @@ -24490,8 +24699,8 @@ static void computeJD(DateTime *p){ Y--; M += 12; } - A = Y/100; - B = 2 - A + (A/4); + A = (Y+4800)/100; + B = 38 - A + (A/4); X1 = 36525*(Y+4716)/100; X2 = 306001*(M+1)/10000; p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); @@ -24675,7 +24884,7 @@ static int validJulianDay(sqlite3_int64 iJD){ ** Compute the Year, Month, and Day from the julian day number. */ static void computeYMD(DateTime *p){ - int Z, A, B, C, D, E, X1; + int Z, alpha, A, B, C, D, E, X1; if( p->validYMD ) return; if( !p->validJD ){ p->Y = 2000; @@ -24686,8 +24895,8 @@ static void computeYMD(DateTime *p){ return; }else{ Z = (int)((p->iJD + 43200000)/86400000); - A = (int)((Z - 1867216.25)/36524.25); - A = Z + 1 + A - (A/4); + alpha = (int)((Z + 32044.75)/36524.25) - 52; + A = Z + 1 + alpha - ((alpha+100)/4) + 25; B = A + 1524; C = (int)((B - 122.1)/365.25); D = (36525*(C&32767))/100; @@ -29089,16 +29298,29 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ /* ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. +** +** Because these routines raise false-positive alerts in TSAN, disable +** them (make them always return 1) when compiling with TSAN. */ SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); } SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ +# if defined(__has_feature) +# if __has_feature(thread_sanitizer) + p = 0; +# endif +# endif assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); } -#endif +#endif /* NDEBUG */ #endif /* !defined(SQLITE_MUTEX_OMIT) */ @@ -31986,16 +32208,19 @@ SQLITE_API void sqlite3_str_vappendf( if( pItem->zAlias && !flag_altform2 ){ sqlite3_str_appendall(pAccum, pItem->zAlias); }else if( pItem->zName ){ - if( pItem->zDatabase ){ - sqlite3_str_appendall(pAccum, pItem->zDatabase); + if( pItem->fg.fixedSchema==0 + && pItem->fg.isSubquery==0 + && pItem->u4.zDatabase!=0 + ){ + sqlite3_str_appendall(pAccum, pItem->u4.zDatabase); sqlite3_str_append(pAccum, ".", 1); } sqlite3_str_appendall(pAccum, pItem->zName); }else if( pItem->zAlias ){ sqlite3_str_appendall(pAccum, pItem->zAlias); - }else{ - Select *pSel = pItem->pSelect; - assert( pSel!=0 ); /* Because of tag-20240424-1 */ + }else if( ALWAYS(pItem->fg.isSubquery) ){/* Because of tag-20240424-1 */ + Select *pSel = pItem->u4.pSubq->pSelect; + assert( pSel!=0 ); if( pSel->selFlags & SF_NestedFrom ){ sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); }else if( pSel->selFlags & SF_MultiValue ){ @@ -32777,9 +33002,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); - if( pItem->pTab ){ + if( pItem->pSTab ){ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx%s", - pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, + pItem->pSTab->zName, pItem->pSTab->nCol, pItem->pSTab, pItem->colUsed, pItem->fg.rowidUsed ? "+rowid" : ""); } @@ -32810,25 +33035,30 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) if( pItem->fg.viaCoroutine ) sqlite3_str_appendf(&x, " viaCoroutine"); if( pItem->fg.notCte ) sqlite3_str_appendf(&x, " notCte"); if( pItem->fg.isNestedFrom ) sqlite3_str_appendf(&x, " isNestedFrom"); + if( pItem->fg.fixedSchema ) sqlite3_str_appendf(&x, " fixedSchema"); + if( pItem->fg.hadSchema ) sqlite3_str_appendf(&x, " hadSchema"); + if( pItem->fg.isSubquery ) sqlite3_str_appendf(&x, " isSubquery"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); n = 0; - if( pItem->pSelect ) n++; + if( pItem->fg.isSubquery ) n++; if( pItem->fg.isTabFunc ) n++; if( pItem->fg.isUsing ) n++; if( pItem->fg.isUsing ){ sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); } - if( pItem->pSelect ){ - sqlite3TreeViewPush(&pView, i+1nSrc); - if( pItem->pTab ){ - Table *pTab = pItem->pTab; + if( pItem->fg.isSubquery ){ + assert( n==1 ); + if( pItem->pSTab ){ + Table *pTab = pItem->pSTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewLine(pView, "SUBQUERY"); sqlite3TreeViewPop(&pView); + sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); @@ -32870,7 +33100,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m n = 1000; }else{ n = 0; - if( p->pSrc && p->pSrc->nSrc ) n++; + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++; if( p->pWhere ) n++; if( p->pGroupBy ) n++; if( p->pHaving ) n++; @@ -32896,7 +33126,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m sqlite3TreeViewPop(&pView); } #endif - if( p->pSrc && p->pSrc->nSrc ){ + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){ sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); @@ -33404,7 +33634,8 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m case OE_Ignore: zType = "ignore"; break; } assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); + sqlite3TreeViewLine(pView, "RAISE %s", zType); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } #endif @@ -33484,9 +33715,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; inExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; + u8 sortFlags = pList->a[i].fg.sortFlags; char *zName = pList->a[i].zEName; int moreToFollow = inExpr - 1; - if( j || zName ){ + if( j || zName || sortFlags ){ sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); @@ -33507,13 +33739,18 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList( } } if( j ){ - fprintf(stdout, "iOrderByCol=%d", j); + fprintf(stdout, "iOrderByCol=%d ", j); + } + if( sortFlags & KEYINFO_ORDER_DESC ){ + fprintf(stdout, "DESC "); + }else if( sortFlags & KEYINFO_ORDER_BIGNULL ){ + fprintf(stdout, "NULLS-LAST"); } fprintf(stdout, "\n"); fflush(stdout); } sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); - if( j || zName ){ + if( j || zName || sortFlags ){ sqlite3TreeViewPop(&pView); } } @@ -34476,7 +34713,7 @@ static const unsigned char sqlite3Utf8Trans1[] = { c = *(zIn++); \ if( c>=0xc0 ){ \ c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + while( zIn=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2; + if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; n++; } return (int)(z-(unsigned char const *)zIn) @@ -35448,6 +35687,8 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en int eValid = 1; /* True exponent is either not used or is well-formed */ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + double rr[2]; + u64 s2; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -35559,68 +35800,41 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en e++; } - if( e==0 ){ - *pResult = s; - }else if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; - if( e>0 ){ - while( e>=100 ){ e-=100; r *= 1.0e+100L; } - while( e>=10 ){ e-=10; r *= 1.0e+10L; } - while( e>=1 ){ e-=1; r *= 1.0e+01L; } - }else{ - while( e<=-100 ){ e+=100; r *= 1.0e-100L; } - while( e<=-10 ){ e+=10; r *= 1.0e-10L; } - while( e<=-1 ){ e+=1; r *= 1.0e-01L; } - } - assert( r>=0.0 ); - if( r>+1.7976931348623157081452742373e+308L ){ -#ifdef INFINITY - *pResult = +INFINITY; -#else - *pResult = 1.0e308*10.0; + rr[0] = (double)s; + s2 = (u64)rr[0]; +#if defined(_MSC_VER) && _MSC_VER<1700 + if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } #endif - }else{ - *pResult = (double)r; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + if( e>0 ){ + while( e>=100 ){ + e -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( e>=10 ){ + e -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( e>=1 ){ + e -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); } }else{ - double rr[2]; - u64 s2; - rr[0] = (double)s; - s2 = (u64)rr[0]; -#if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } -#endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); - if( e>0 ){ - while( e>=100 ){ - e -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( e>=10 ){ - e -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( e>=1 ){ - e -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } - }else{ - while( e<=-100 ){ - e += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( e<=-10 ){ - e += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( e<=-1 ){ - e += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } + while( e<=-100 ){ + e += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( e<=-10 ){ + e += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( e<=-1 ){ + e += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } - *pResult = rr[0]+rr[1]; - if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; } + *pResult = rr[0]+rr[1]; + if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; if( sign<0 ) *pResult = -*pResult; assert( !sqlite3IsNaN(*pResult) ); @@ -35924,10 +36138,13 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){ ** Decode a floating-point value into an approximate decimal ** representation. ** -** Round the decimal representation to n significant digits if -** n is positive. Or round to -n signficant digits after the -** decimal point if n is negative. No rounding is performed if -** n is zero. +** If iRound<=0 then round to -iRound significant digits to the +** the left of the decimal point, or to a maximum of mxRound total +** significant digits. +** +** If iRound>0 round to min(iRound,mxRound) significant digits total. +** +** mxRound must be positive. ** ** The significant digits of the decimal representation are ** stored in p->z[] which is a often (but not always) a pointer @@ -35938,8 +36155,11 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou int i; u64 v; int e, exp = 0; + double rr[2]; + p->isSpecial = 0; p->z = p->zBuf; + assert( mxRound>0 ); /* Convert negative numbers to positive. Deal with Infinity, 0.0, and ** NaN. */ @@ -35966,62 +36186,45 @@ SQLITE_PRIVATE void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRou /* Multiply r by powers of ten until it lands somewhere in between ** 1.0e+19 and 1.0e+17. + ** + ** Use Dekker-style double-double computation to increase the + ** precision. + ** + ** The error terms on constants like 1.0e+100 computed using the + ** decimal extension, for example as follows: + ** + ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); */ - if( sqlite3Config.bUseLongDouble ){ - LONGDOUBLE_TYPE rr = r; - if( rr>=1.0e+19 ){ - while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } - while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } - while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } - }else{ - while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } - while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } - while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } + rr[0] = r; + rr[1] = 0.0; + if( rr[0]>9.223372036854774784e+18 ){ + while( rr[0]>9.223372036854774784e+118 ){ + exp += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( rr[0]>9.223372036854774784e+28 ){ + exp += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( rr[0]>9.223372036854774784e+18 ){ + exp += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } - v = (u64)rr; }else{ - /* If high-precision floating point is not available using "long double", - ** then use Dekker-style double-double computation to increase the - ** precision. - ** - ** The error terms on constants like 1.0e+100 computed using the - ** decimal extension, for example as follows: - ** - ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); - */ - double rr[2]; - rr[0] = r; - rr[1] = 0.0; - if( rr[0]>9.223372036854774784e+18 ){ - while( rr[0]>9.223372036854774784e+118 ){ - exp += 100; - dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); - } - while( rr[0]>9.223372036854774784e+28 ){ - exp += 10; - dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); - } - while( rr[0]>9.223372036854774784e+18 ){ - exp += 1; - dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); - } - }else{ - while( rr[0]<9.223372036854774784e-83 ){ - exp -= 100; - dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); - } - while( rr[0]<9.223372036854774784e+07 ){ - exp -= 10; - dekkerMul2(rr, 1.0e+10, 0.0); - } - while( rr[0]<9.22337203685477478e+17 ){ - exp -= 1; - dekkerMul2(rr, 1.0e+01, 0.0); - } + while( rr[0]<9.223372036854774784e-83 ){ + exp -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( rr[0]<9.223372036854774784e+07 ){ + exp -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( rr[0]<9.22337203685477478e+17 ){ + exp -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); } - v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; } - + v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; /* Extract significant digits. */ i = sizeof(p->zBuf)-1; @@ -36792,104 +36995,6 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam return 0; } -/* -** High-resolution hardware timer used for debugging and testing only. -*/ -#if defined(VDBE_PROFILE) \ - || defined(SQLITE_PERFORMANCE_TRACE) \ - || defined(SQLITE_ENABLE_STMT_SCANSTATUS) -/************** Include hwtime.h in the middle of util.c *********************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 and x86_64 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on Pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - /* - ** asm() is needed for hardware timing support. Without asm(), - ** disable the sqlite3Hwtime() routine. - ** - ** sqlite3Hwtime() is only used for some obscure debugging - ** and analysis configurations, not in any deliverable, so this - ** should not be a great loss. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in util.c ***********************/ -#endif - /************** End of util.c ************************************************/ /************** Begin file hash.c ********************************************/ /* @@ -37227,16 +37332,16 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 47 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 48 */ "Program" OpHelp(""), /* 49 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), - /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), - /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), - /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"), - /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"), - /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), - /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), - /* 58 */ "ElseEq" OpHelp(""), - /* 59 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 50 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 51 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), + /* 52 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), + /* 53 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), + /* 54 */ "Eq" OpHelp("IF r[P3]==r[P1]"), + /* 55 */ "Gt" OpHelp("IF r[P3]>r[P1]"), + /* 56 */ "Le" OpHelp("IF r[P3]<=r[P1]"), + /* 57 */ "Lt" OpHelp("IF r[P3]=r[P1]"), + /* 59 */ "ElseEq" OpHelp(""), /* 60 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), /* 61 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 62 */ "IncrVacuum" OpHelp(""), @@ -37279,23 +37384,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 99 */ "ReadCookie" OpHelp(""), /* 100 */ "SetCookie" OpHelp(""), /* 101 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 112 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 102 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 103 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 104 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 105 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 107 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 108 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 109 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 110 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 111 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 112 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), /* 113 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 115 */ "OpenDup" OpHelp(""), + /* 114 */ "OpenDup" OpHelp(""), + /* 115 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), /* 116 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 117 */ "String8" OpHelp("r[P2]='P4'"), - /* 118 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 118 */ "String8" OpHelp("r[P2]='P4'"), /* 119 */ "SorterOpen" OpHelp(""), /* 120 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), /* 121 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), @@ -37330,8 +37435,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 150 */ "LoadAnalysis" OpHelp(""), /* 151 */ "DropTable" OpHelp(""), /* 152 */ "DropIndex" OpHelp(""), - /* 153 */ "Real" OpHelp("r[P2]=P4"), - /* 154 */ "DropTrigger" OpHelp(""), + /* 153 */ "DropTrigger" OpHelp(""), + /* 154 */ "Real" OpHelp("r[P2]=P4"), /* 155 */ "IntegrityCk" OpHelp(""), /* 156 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), /* 157 */ "Param" OpHelp(""), @@ -38680,7 +38785,7 @@ static pid_t randomnessPid = 0; #define UNIXFILE_EXCL 0x01 /* Connections from one process only */ #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ -#ifndef SQLITE_DISABLE_DIRSYNC +#if !defined(SQLITE_DISABLE_DIRSYNC) && !defined(_AIX) # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ #else # define UNIXFILE_DIRSYNC 0x00 @@ -40637,26 +40742,22 @@ static int nolockClose(sqlite3_file *id) { /* ** This routine checks if there is a RESERVED lock held on the specified -** file by this or any other process. If such a lock is held, set *pResOut -** to a non-zero value otherwise *pResOut is set to zero. The return value -** is set to SQLITE_OK unless an I/O error occurs during lock checking. -** -** In dotfile locking, either a lock exists or it does not. So in this -** variation of CheckReservedLock(), *pResOut is set to true if any lock -** is held on the file and false if the file is unlocked. +** file by this or any other process. If the caller holds a SHARED +** or greater lock when it is called, then it is assumed that no other +** client may hold RESERVED. Or, if the caller holds no lock, then it +** is assumed another client holds RESERVED if the lock-file exists. */ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { - int rc = SQLITE_OK; - int reserved = 0; unixFile *pFile = (unixFile*)id; - SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - assert( pFile ); - reserved = osAccess((const char*)pFile->lockingContext, 0)==0; - OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); - *pResOut = reserved; - return rc; + if( pFile->eFileLock>=SHARED_LOCK ){ + *pResOut = 0; + }else{ + *pResOut = osAccess((const char*)pFile->lockingContext, 0)==0; + } + OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, 0, *pResOut)); + return SQLITE_OK; } /* @@ -40826,54 +40927,33 @@ static int robust_flock(int fd, int op){ ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc = SQLITE_OK; - int reserved = 0; +#ifdef SQLITE_DEBUG unixFile *pFile = (unixFile*)id; +#else + UNUSED_PARAMETER(id); +#endif SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); - /* Check if a thread in this process holds such a lock */ - if( pFile->eFileLock>SHARED_LOCK ){ - reserved = 1; - } - - /* Otherwise see if some other process holds it. */ - if( !reserved ){ - /* attempt to get the lock */ - int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); - if( !lrc ){ - /* got the lock, unlock it */ - lrc = robust_flock(pFile->h, LOCK_UN); - if ( lrc ) { - int tErrno = errno; - /* unlock failed with an error */ - lrc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } else { - int tErrno = errno; - reserved = 1; - /* someone else might have it reserved */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(lrc) ){ - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } - } - OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); + /* The flock VFS only ever takes exclusive locks (see function flockLock). + ** Therefore, if this connection is holding any lock at all, no other + ** connection may be holding a RESERVED lock. So set *pResOut to 0 + ** in this case. + ** + ** Or, this connection may be holding no lock. In that case, set *pResOut to + ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the + ** db in order to roll the hot journal back. If there is another connection + ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to + ** the user. With other VFS, we try to avoid this, in order to allow a reader + ** to proceed while a writer is preparing its transaction. But that won't + ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is + ** not a problem in this case. */ + *pResOut = 0; -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & 0xff) == SQLITE_IOERR ){ - rc = SQLITE_OK; - reserved=1; - } -#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - *pResOut = reserved; - return rc; + return SQLITE_OK; } /* @@ -42345,7 +42425,7 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ /* Forward declaration */ static int unixGetTempname(int nBuf, char *zBuf); -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) static int unixFcntlExternalReader(unixFile*, int*); #endif @@ -42472,7 +42552,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ case SQLITE_FCNTL_EXTERNAL_READER: { -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) return unixFcntlExternalReader((unixFile*)id, (int*)pArg); #else *(int*)pArg = 0; @@ -42561,7 +42641,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; @@ -42569,7 +42649,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ pFile->sectorSize = fsInfo.f_bsize; pFile->deviceCharacteristics = /* full bitset of atomics from max sector size and smaller */ - ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 | + (((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2) | SQLITE_IOCAP_SEQUENTIAL | /* The ram filesystem has no write behind ** so it is ordered */ 0; @@ -42645,7 +42725,7 @@ static int unixGetpagesize(void){ #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */ -#ifndef SQLITE_OMIT_WAL +#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) /* ** Object used to represent an shared memory buffer. @@ -54730,6 +54810,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; memset(pPgHdr->pExtra, 0, 8); + assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) ); pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; @@ -55476,7 +55557,8 @@ static int pcache1InitBulk(PCache1 *pCache){ do{ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; - pX->page.pExtra = &pX[1]; + pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); + assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); pX->isBulkLocal = 1; pX->isAnchor = 0; pX->pNext = pCache->pFree; @@ -55613,7 +55695,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ if( pPg==0 ) return 0; p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; p->page.pBuf = pPg; - p->page.pExtra = &p[1]; + p->page.pExtra = (u8*)p + ROUND8(sizeof(*p)); + assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) ); p->isBulkLocal = 0; p->isAnchor = 0; p->pLruPrev = 0; /* Initializing this saves a valgrind error */ @@ -61172,6 +61255,7 @@ static int pagerAcquireMapPage( return SQLITE_NOMEM_BKPT; } p->pExtra = (void *)&p[1]; + assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) ); p->flags = PGHDR_MMAP; p->nRef = 1; p->pPager = pPager; @@ -64955,7 +65039,7 @@ SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ ** 28: Checksum-2 (second part of checksum for first 24 bytes of header). ** ** Immediately following the wal-header are zero or more frames. Each -** frame consists of a 24-byte frame-header followed by a bytes +** frame consists of a 24-byte frame-header followed by bytes ** of page data. The frame-header is six big-endian 32-bit unsigned ** integer values, as follows: ** @@ -65452,6 +65536,7 @@ struct Wal { #endif #ifdef SQLITE_ENABLE_SNAPSHOT WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */ + int bGetSnapshot; /* Transaction opened for sqlite3_get_snapshot() */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT sqlite3 *db; @@ -67344,7 +67429,7 @@ static int walHandleException(Wal *pWal){ /* ** Assert that the Wal.lockMask mask, which indicates the locks held -** by the connenction, is consistent with the Wal.readLock, Wal.writeLock +** by the connection, is consistent with the Wal.readLock, Wal.writeLock ** and Wal.ckptLock variables. To be used as: ** ** assert( walAssertLockmask(pWal) ); @@ -68008,7 +68093,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ SEH_INJECT_FAULT; if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT - && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) + && ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0) #endif ){ /* The WAL has been completely backfilled (or it is empty). @@ -69408,7 +69493,20 @@ SQLITE_PRIVATE void sqlite3WalSnapshotOpen( Wal *pWal, sqlite3_snapshot *pSnapshot ){ - pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + if( pSnapshot && ((WalIndexHdr*)pSnapshot)->iVersion==0 ){ + /* iVersion==0 means that this is a call to sqlite3_snapshot_get(). In + ** this case set the bGetSnapshot flag so that if the call to + ** sqlite3_snapshot_get() is about to read transaction on this wal + ** file, it does not take read-lock 0 if the wal file has been completely + ** checkpointed. Taking read-lock 0 would work, but then it would be + ** possible for a subsequent writer to destroy the snapshot even while + ** this connection is holding its read-transaction open. This is contrary + ** to user expectations, so we avoid it by not taking read-lock 0. */ + pWal->bGetSnapshot = 1; + }else{ + pWal->pSnapshot = (WalIndexHdr*)pSnapshot; + pWal->bGetSnapshot = 0; + } } /* @@ -75289,6 +75387,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ return ROUND8(sizeof(BtCursor)); } +#ifdef SQLITE_DEBUG +/* +** Return true if and only if the Btree object will be automatically +** closed with the BtCursor closes. This is used within assert() statements +** only. +*/ +SQLITE_PRIVATE int sqlite3BtreeClosesWithCursor( + Btree *pBtree, /* the btree object */ + BtCursor *pCur /* Corresponding cursor */ +){ + BtShared *pBt = pBtree->pBt; + if( (pBt->openFlags & BTREE_SINGLE)==0 ) return 0; + if( pBt->pCursor!=pCur ) return 0; + if( pCur->pNext!=0 ) return 0; + if( pCur->pBtree!=pBtree ) return 0; + return 1; +} +#endif + /* ** Initialize memory that will be converted into a BtCursor object. ** @@ -76532,7 +76649,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 && pIdxKey->errCode==SQLITE_OK ){ - pCur->curFlags &= ~BTCF_ValidOvfl; + pCur->curFlags &= ~(BTCF_ValidOvfl|BTCF_AtLast); if( !pCur->pPage->isInit ){ return SQLITE_CORRUPT_BKPT; } @@ -78110,7 +78227,8 @@ static int rebuildPage( if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); - for(k=0; ALWAYS(kixNx[k]<=i; k++){} + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i; k++){} pSrcEnd = pCArray->apEnd[k]; pData = pEnd; @@ -78193,7 +78311,8 @@ static int pageInsertArray( u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; - for(k=0; ALWAYS(kixNx[k]<=i ; k++){} + assert( pCArray->ixNx[NB*2-1]>i ); + for(k=0; pCArray->ixNx[k]<=i ; k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; @@ -78478,6 +78597,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ b.szCell = &szCell; b.apEnd[0] = pPage->aDataEnd; b.ixNx[0] = 2; + b.ixNx[NB*2-1] = 0x7fffffff; rc = rebuildPage(&b, 0, 1, pNew); if( NEVER(rc) ){ releasePage(pNew); @@ -78713,7 +78833,9 @@ static int balance_nonroot( CellArray b; /* Parsed information on cells being balanced */ memset(abDone, 0, sizeof(abDone)); - memset(&b, 0, sizeof(b)); + assert( sizeof(b) - sizeof(b.ixNx) == offsetof(CellArray,ixNx) ); + memset(&b, 0, sizeof(b)-sizeof(b.ixNx[0])); + b.ixNx[NB*2-1] = 0x7fffffff; pBt = pParent->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); @@ -79304,7 +79426,8 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; ALWAYS(kj ); + for(k=0; b.ixNx[k]<=j; k++){} pSrcEnd = b.apEnd[k]; if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){ rc = SQLITE_CORRUPT_BKPT; @@ -84316,7 +84439,8 @@ static int valueFromFunction( goto value_from_function_out; } for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); + rc = sqlite3Stat4ValueFromExpr(pCtx->pParse, pList->a[i].pExpr, aff, + &apVal[i]); if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; } } @@ -86250,6 +86374,12 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); break; } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = (SubrtnSig*)p4; + sqlite3DbFree(db, pSig->zAff); + sqlite3DbFree(db, pSig); + break; + } } } @@ -86829,6 +86959,11 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ zP4 = pOp->p4.pTab->zName; break; } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = pOp->p4.pSubrtnSig; + sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); + break; + } default: { zP4 = pOp->p4.z; } @@ -89338,7 +89473,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem ** We must use separate SQLITE_NOINLINE functions here, since otherwise ** optimizer code movement causes gcov to become very confused. */ -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) static int SQLITE_NOINLINE doubleLt(double a, double b){ return ar ); - testcase( x==r ); - return (xr); }else{ i64 y; if( r<-9223372036854775808.0 ) return +1; @@ -90369,6 +90497,13 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( } sqlite3DbNNFreeNN(db, preupdate.aNew); } + if( preupdate.apDflt ){ + int i; + for(i=0; inCol; i++){ + sqlite3ValueFree(preupdate.apDflt[i]); + } + sqlite3DbFree(db, preupdate.apDflt); + } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -91997,6 +92132,17 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ ** ** The error code stored in database p->db is overwritten with the return ** value in any case. +** +** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK, +** that means all of the the following will be true: +** +** p!=0 +** p->pVar!=0 +** i>0 +** i<=p->nVar +** +** An assert() is normally added after vdbeUnbind() to help static analyzers +** realize this. */ static int vdbeUnbind(Vdbe *p, unsigned int i){ Mem *pVar; @@ -92054,6 +92200,7 @@ static int bindText( rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ if( zData!=0 ){ pVar = &p->aVar[i-1]; rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); @@ -92103,6 +92250,7 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); sqlite3_mutex_leave(p->db->mutex); } @@ -92116,6 +92264,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); sqlite3_mutex_leave(p->db->mutex); } @@ -92126,6 +92275,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3_mutex_leave(p->db->mutex); } return rc; @@ -92141,6 +92291,7 @@ SQLITE_API int sqlite3_bind_pointer( Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ @@ -92222,6 +92373,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, (u32)(i-1)); if( rc==SQLITE_OK ){ + assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */ #ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); #else @@ -92581,7 +92733,30 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa if( iIdx==p->pTab->iPKey ){ sqlite3VdbeMemSetInt64(pMem, p->iKey1); }else if( iIdx>=p->pUnpacked->nField ){ - *ppValue = (sqlite3_value *)columnNullValue(); + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; + } + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ if( pMem->flags & (MEM_Int|MEM_IntReal) ){ testcase( pMem->flags & MEM_Int ); @@ -93134,6 +93309,104 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ +/* +** High-resolution hardware timer used for debugging and testing only. +*/ +#if defined(VDBE_PROFILE) \ + || defined(SQLITE_PERFORMANCE_TRACE) \ + || defined(SQLITE_ENABLE_STMT_SCANSTATUS) +/************** Include hwtime.h in the middle of vdbe.c *********************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains inline asm code for retrieving "high-performance" +** counters for x86 and x86_64 class CPUs. +*/ +#ifndef SQLITE_HWTIME_H +#define SQLITE_HWTIME_H + +/* +** The following routine only works on Pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if !defined(__STRICT_ANSI__) && \ + (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + /* + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(SQLITE_HWTIME_H) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in vdbe.c ***********************/ +#endif + /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are @@ -94327,7 +94600,7 @@ case OP_HaltIfNull: { /* in3 */ /* no break */ deliberate_fall_through } -/* Opcode: Halt P1 P2 * P4 P5 +/* Opcode: Halt P1 P2 P3 P4 P5 ** ** Exit immediately. All open cursors, etc are closed ** automatically. @@ -94340,18 +94613,22 @@ case OP_HaltIfNull: { /* in3 */ ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** -** If P4 is not null then it is an error message string. +** If P3 is not zero and P4 is NULL, then P3 is a register that holds the +** text of an error message. ** -** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. +** If P3 is zero and P4 is not null then the error message string is held +** in P4. +** +** P5 is a value between 1 and 4, inclusive, then the P4 error message +** string is modified as follows: ** -** 0: (no change) ** 1: NOT NULL constraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 ** -** If P5 is not zero and P4 is NULL, then everything after the ":" is -** omitted. +** If P3 is zero and P5 is not zero and P4 is NULL, then everything after +** the ":" is omitted. ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program @@ -94364,6 +94641,9 @@ case OP_Halt: { #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif + assert( pOp->p4type==P4_NOTUSED + || pOp->p4type==P4_STATIC + || pOp->p4type==P4_DYNAMIC ); /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates ** something is wrong with the code generator. Raise an assertion in order @@ -94394,7 +94674,12 @@ case OP_Halt: { p->errorAction = (u8)pOp->p2; assert( pOp->p5<=4 ); if( p->rc ){ - if( pOp->p5 ){ + if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){ + const char *zErr; + assert( pOp->p3<=(p->nMem + 1 - p->nCursor) ); + zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8); + sqlite3VdbeError(p, "%s", zErr); + }else if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", "FOREIGN KEY" }; testcase( pOp->p5==1 ); @@ -95197,7 +95482,7 @@ case OP_RealAffinity: { /* in1 */ } #endif -#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_ANALYZE) +#if !defined(SQLITE_OMIT_CAST) || !defined(SQLITE_OMIT_ANALYZE) /* Opcode: Cast P1 P2 * * * ** Synopsis: affinity(r[P1]) ** @@ -97437,23 +97722,23 @@ case OP_OpenWrite: if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; } + if( pOp->p5 & OPFLAG_P2ISREG ){ + assert( p2>0 ); + assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); + pIn2 = &aMem[p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); + sqlite3VdbeMemIntegerify(pIn2); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateBtree opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + assert( p2>=2 ); + } }else{ wrFlag = 0; - } - if( pOp->p5 & OPFLAG_P2ISREG ){ - assert( p2>0 ); - assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); - assert( pOp->opcode==OP_OpenWrite ); - pIn2 = &aMem[p2]; - assert( memIsValid(pIn2) ); - assert( (pIn2->flags & MEM_Int)!=0 ); - sqlite3VdbeMemIntegerify(pIn2); - p2 = (int)pIn2->u.i; - /* The p2 value always comes from a prior OP_CreateBtree opcode and - ** that opcode will always set the p2 value to 2 or more or else fail. - ** If there were a failure, the prepared statement would have halted - ** before reaching this instruction. */ - assert( p2>=2 ); + assert( (pOp->p5 & OPFLAG_P2ISREG)==0 ); } if( pOp->p4type==P4_KEYINFO ){ pKeyInfo = pOp->p4.pKeyInfo; @@ -97631,7 +97916,10 @@ case OP_OpenEphemeral: { /* ncycle */ } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); if( rc ){ + assert( !sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); sqlite3BtreeClose(pCx->ub.pBtx); + }else{ + assert( sqlite3BtreeClosesWithCursor(pCx->ub.pBtx, pCx->uc.pCursor) ); } } } @@ -98409,6 +98697,7 @@ case OP_Found: { /* jump, in3, ncycle */ r.pKeyInfo = pC->pKeyInfo; r.default_rc = 0; #ifdef SQLITE_DEBUG + (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */ for(ii=0; iip4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + - (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); + + /* Allocate space for (a) the context object and (n-1) extra pointers + ** to append to the sqlite3_context.argv[1] array, and (b) a memory + ** cell in which to store the accumulation. Be careful that the memory + ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. + ** + ** Note: We could avoid this by using a regular memory cell from aMem[] for + ** the accumulator, instead of allocating one here. */ + nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); + pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); if( pCtx==0 ) goto no_mem; - pCtx->pMem = 0; - pCtx->pOut = (Mem*)&(pCtx->argv[n]); + pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); + assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); + pCtx->pMem = 0; pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; @@ -102116,14 +102416,29 @@ case OP_ReleaseReg: { /* Opcode: Noop * * * * * ** -** Do nothing. This instruction is often useful as a jump -** destination. +** Do nothing. Continue downward to the next opcode. */ -/* -** The magic Explain opcode are only inserted when explain==2 (which -** is to say when the EXPLAIN QUERY PLAN syntax is used.) -** This opcode records information from the optimizer. It is the -** the same as a no-op. This opcodesnever appears in a real VM program. +/* Opcode: Explain P1 P2 P3 P4 * +** +** This is the same as OP_Noop during normal query execution. The +** purpose of this opcode is to hold information about the query +** plan for the purpose of EXPLAIN QUERY PLAN output. +** +** The P4 value is human-readable text that describes the query plan +** element. Something like "SCAN t1" or "SEARCH t2 USING INDEX t2x1". +** +** The P1 value is the ID of the current element and P2 is the parent +** element for the case of nested query plan elements. If P2 is zero +** then this element is a top-level element. +** +** For loop elements, P3 is the estimated code of each invocation of this +** element. +** +** As with all opcodes, the meanings of the parameters for OP_Explain +** are subject to change from one release to the next. Applications +** should not attempt to interpret or use any of the information +** contained in the OP_Explain opcode. The information provided by this +** opcode is intended for testing and debugging use only. */ default: { /* This is really OP_Noop, OP_Explain */ assert( pOp->opcode==OP_Noop || pOp->opcode==OP_Explain ); @@ -102450,6 +102765,11 @@ SQLITE_API int sqlite3_blob_open( pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } + if( pTab && (pTab->tabFlags&TF_HasGenerated)!=0 ){ + pTab = 0; + sqlite3ErrorMsg(&sParse, "cannot open table with generated columns: %s", + zTable); + } #ifndef SQLITE_OMIT_VIEW if( pTab && IsView(pTab) ){ pTab = 0; @@ -103357,13 +103677,14 @@ static int vdbePmaReadBlob( while( nRem>0 ){ int rc; /* vdbePmaReadBlob() return code */ int nCopy; /* Number of bytes to copy */ - u8 *aNext; /* Pointer to buffer to copy data from */ + u8 *aNext = 0; /* Pointer to buffer to copy data from */ nCopy = nRem; if( nRem>p->nBuffer ) nCopy = p->nBuffer; rc = vdbePmaReadBlob(p, nCopy, &aNext); if( rc!=SQLITE_OK ) return rc; assert( aNext!=p->aAlloc ); + assert( aNext!=0 ); memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); nRem -= nCopy; } @@ -106633,7 +106954,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ pSrc = p->pSrc; if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ + if( pItem->fg.isSubquery + && sqlite3WalkSelect(pWalker, pItem->u4.pSubq->pSelect) + ){ return WRC_Abort; } if( pItem->fg.isTabFunc @@ -106939,7 +107262,7 @@ static void extendFJMatch( if( pNew ){ pNew->iTable = pMatch->iCursor; pNew->iColumn = iColumn; - pNew->y.pTab = pMatch->pTab; + pNew->y.pTab = pMatch->pSTab; assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); ExprSetProperty(pNew, EP_CanBeNull); *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); @@ -107070,10 +107393,10 @@ static int lookupName( if( pSrcList ){ for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ u8 hCol; - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem)); if( pItem->fg.isNestedFrom ){ /* In this case, pItem is a subquery that has been formed from a ** parenthesized subset of the FROM clause terms. Example: @@ -107082,8 +107405,12 @@ static int lookupName( ** This pItem -------------^ */ int hit = 0; - assert( pItem->pSelect!=0 ); - pEList = pItem->pSelect->pEList; + Select *pSel; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + pSel = pItem->u4.pSubq->pSelect; + assert( pSel!=0 ); + pEList = pSel->pEList; assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ @@ -107206,9 +107533,9 @@ static int lookupName( */ if( cntTab==0 || (cntTab==1 - && ALWAYS(pMatch!=0) - && ALWAYS(pMatch->pTab!=0) - && (pMatch->pTab->tabFlags & TF_Ephemeral)!=0 + && pMatch!=0 + && ALWAYS(pMatch->pSTab!=0) + && (pMatch->pSTab->tabFlags & TF_Ephemeral)!=0 && (pTab->tabFlags & TF_Ephemeral)==0) ){ cntTab = 1; @@ -107229,7 +107556,7 @@ static int lookupName( if( pMatch ){ pExpr->iTable = pMatch->iCursor; assert( ExprUseYTab(pExpr) ); - pExpr->y.pTab = pMatch->pTab; + pExpr->y.pTab = pMatch->pSTab; if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } @@ -107271,7 +107598,7 @@ static int lookupName( if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ - pTab = pUpsert->pUpsertSrc->a[0].pTab; + pTab = pUpsert->pUpsertSrc->a[0].pSTab; pExpr->iTable = EXCLUDED_TABLE_NUMBER; } } @@ -107354,11 +107681,11 @@ static int lookupName( && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) + && ALWAYS(VisibleRowid(pMatch->pSTab) || pMatch->fg.isNestedFrom) ){ cnt = cntTab; #if SQLITE_ALLOW_ROWID_IN_VIEW+0==2 - if( pMatch->pTab!=0 && IsView(pMatch->pTab) ){ + if( pMatch->pSTab!=0 && IsView(pMatch->pSTab) ){ eNewExprOp = TK_NULL; } #endif @@ -107595,7 +107922,7 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab; assert( ExprUseYTab(p) ); - pTab = p->y.pTab = pItem->pTab; + pTab = p->y.pTab = pItem->pSTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; @@ -107714,7 +108041,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pItem = pSrcList->a; pExpr->op = TK_COLUMN; assert( ExprUseYTab(pExpr) ); - pExpr->y.pTab = pItem->pTab; + pExpr->y.pTab = pItem->pSTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn--; pExpr->affExpr = SQLITE_AFF_INTEGER; @@ -107839,8 +108166,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* Resolve function names */ case TK_FUNCTION: { - ExprList *pList = pExpr->x.pList; /* The argument list */ - int n = pList ? pList->nExpr : 0; /* Number of arguments */ + ExprList *pList; /* The argument list */ + int n; /* Number of arguments */ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ @@ -107853,6 +108180,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); + pList = pExpr->x.pList; + n = pList ? pList->nExpr : 0; zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ @@ -107901,6 +108230,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } } #endif + + /* If the function may call sqlite3_value_subtype(), then set the + ** EP_SubtArg flag on all of its argument expressions. This prevents + ** where.c from replacing the expression with a value read from an + ** index on the same expression, which will not have the correct + ** subtype. Also set the flag if the function expression itself is + ** an EP_SubtArg expression. In this case subtypes are required as + ** the function may return a value with a subtype back to its + ** caller using sqlite3_result_value(). */ + if( (pDef->funcFlags & SQLITE_SUBTYPE) + || ExprHasProperty(pExpr, EP_SubtArg) + ){ + int ii; + for(ii=0; iia[ii].pExpr, EP_SubtArg); + } + } + if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){ /* For the purposes of the EP_ConstFunc flag, date and time ** functions and other functions that change slowly are considered @@ -108020,9 +108367,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC - if( pWin ){ + if( pWin && pParse->nErr==0 ){ Select *pSel = pNC->pWinSelect; - assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) ); + assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); if( pParse->db->mallocFailed ) break; @@ -108229,7 +108576,7 @@ static int resolveOrderByTermToExprList( int rc; /* Return code from subprocedures */ u8 savedSuppErr; /* Saved value of db->suppressErr */ - assert( sqlite3ExprIsInteger(pE, &i)==0 ); + assert( sqlite3ExprIsInteger(pE, &i, 0)==0 ); pEList = pSelect->pEList; /* Resolve all names in the ORDER BY term expression @@ -108328,7 +108675,7 @@ static int resolveCompoundOrderBy( if( pItem->fg.done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; - if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( sqlite3ExprIsInteger(pE, &iCol, 0) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); return 1; @@ -108513,7 +108860,7 @@ static int resolveOrderGroupBy( continue; } } - if( sqlite3ExprIsInteger(pE2, &iCol) ){ + if( sqlite3ExprIsInteger(pE2, &iCol, 0) ){ /* The ORDER BY term is an integer constant. Again, set the column ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ @@ -108604,7 +108951,11 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** moves the pOrderBy down to the sub-query. It will be moved back ** after the names have been resolved. */ if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + assert( p->pSrc->a[0].u4.pSubq!=0 ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); assert( p->pSrc->nSrc==1 && p->pOrderBy ); assert( pSub->pPrior && pSub->pOrderBy==0 ); pSub->pOrderBy = p->pOrderBy; @@ -108616,13 +108967,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( pOuterNC ) pOuterNC->nNestedSelect++; for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; - assert( pItem->zName!=0 || pItem->pSelect!=0 );/* Test of tag-20240424-1*/ - if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ + assert( pItem->zName!=0 + || pItem->fg.isSubquery ); /* Test of tag-20240424-1*/ + if( pItem->fg.isSubquery + && (pItem->u4.pSubq->pSelect->selFlags & SF_Resolved)==0 + ){ int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; if( pItem->zName ) pParse->zAuthContext = pItem->zName; - sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); + sqlite3ResolveSelectNames(pParse, pItem->u4.pSubq->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr ) return WRC_Abort; assert( db->mallocFailed==0 ); @@ -108724,7 +109078,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** These integers will be replaced by copies of the corresponding result ** set expressions by the call to resolveOrderGroupBy() below. */ if( p->selFlags & SF_Converted ){ - Select *pSub = p->pSrc->a[0].pSelect; + Select *pSub; + assert( p->pSrc->a[0].fg.isSubquery ); + pSub = p->pSrc->a[0].u4.pSubq->pSelect; + assert( pSub!=0 ); p->pOrderBy = pSub->pOrderBy; pSub->pOrderBy = 0; } @@ -108991,7 +109348,7 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference( if( pTab ){ sSrc.nSrc = 1; sSrc.a[0].zName = pTab->zName; - sSrc.a[0].pTab = pTab; + sSrc.a[0].pSTab = pTab; sSrc.a[0].iCursor = -1; if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP @@ -109096,7 +109453,9 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ op = pExpr->op; continue; } - if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; + if( op!=TK_REGISTER ) break; + op = pExpr->op2; + if( NEVER( op==TK_REGISTER ) ) break; } return pExpr->affExpr; } @@ -110886,15 +111245,30 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla SrcItem *pNewItem = &pNew->a[i]; const SrcItem *pOldItem = &p->a[i]; Table *pTab; - pNewItem->pSchema = pOldItem->pSchema; - pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); + pNewItem->fg = pOldItem->fg; + if( pOldItem->fg.isSubquery ){ + Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery)); + if( pNewSubq==0 ){ + assert( db->mallocFailed ); + pNewItem->fg.isSubquery = 0; + }else{ + memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq)); + pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags); + if( pNewSubq->pSelect==0 ){ + sqlite3DbFree(db, pNewSubq); + pNewSubq = 0; + pNewItem->fg.isSubquery = 0; + } + } + pNewItem->u4.pSubq = pNewSubq; + }else if( pOldItem->fg.fixedSchema ){ + pNewItem->u4.pSchema = pOldItem->u4.pSchema; + }else{ + pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase); + } pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); - pNewItem->fg = pOldItem->fg; pNewItem->iCursor = pOldItem->iCursor; - pNewItem->addrFillSub = pOldItem->addrFillSub; - pNewItem->regReturn = pOldItem->regReturn; - pNewItem->regResult = pOldItem->regResult; if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); }else if( pNewItem->fg.isTabFunc ){ @@ -110907,11 +111281,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla if( pNewItem->fg.isCte ){ pNewItem->u2.pCteUse->nUse++; } - pTab = pNewItem->pTab = pOldItem->pTab; + pTab = pNewItem->pSTab = pOldItem->pSTab; if( pTab ){ pTab->nTabRef++; } - pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); if( pOldItem->fg.isUsing ){ assert( pNewItem->fg.isUsing ); pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); @@ -110985,7 +111358,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int fla pp = &pNew->pPrior; pNext = pNew; } - return pRet; } #else @@ -111800,8 +112172,12 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. +** +** If the pParse pointer is provided, then allow the expression p to be +** a parameter (TK_VARIABLE) that is bound to an integer. +** But if pParse is NULL, then p must be a pure integer literal. */ -SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue, Parse *pParse){ int rc = 0; if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ @@ -111816,18 +112192,38 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ } switch( p->op ){ case TK_UPLUS: { - rc = sqlite3ExprIsInteger(p->pLeft, pValue); + rc = sqlite3ExprIsInteger(p->pLeft, pValue, 0); break; } case TK_UMINUS: { int v = 0; - if( sqlite3ExprIsInteger(p->pLeft, &v) ){ + if( sqlite3ExprIsInteger(p->pLeft, &v, 0) ){ assert( ((unsigned int)v)!=0x80000000 ); *pValue = -v; rc = 1; } break; } + case TK_VARIABLE: { + sqlite3_value *pVal; + if( pParse==0 ) break; + if( NEVER(pParse->pVdbe==0) ) break; + if( (pParse->db->flags & SQLITE_EnableQPSG)!=0 ) break; + sqlite3VdbeSetVarmask(pParse->pVdbe, p->iColumn); + pVal = sqlite3VdbeGetBoundValue(pParse->pReprepare, p->iColumn, + SQLITE_AFF_BLOB); + if( pVal ){ + if( sqlite3_value_type(pVal)==SQLITE_INTEGER ){ + sqlite3_int64 vv = sqlite3_value_int64(pVal); + if( vv == (vv & 0x7fffffff) ){ /* non-negative numbers only */ + *pValue = (int)vv; + rc = 1; + } + } + sqlite3ValueFree(pVal); + } + break; + } default: break; } return rc; @@ -111981,8 +112377,8 @@ static Select *isCandidateForInOpt(const Expr *pX){ pSrc = p->pSrc; assert( pSrc!=0 ); if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */ - if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ - pTab = pSrc->a[0].pTab; + if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */ + pTab = pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ @@ -112165,7 +112561,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */ assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */ - pTab = p->pSrc->a[0].pTab; + pTab = p->pSrc->a[0].pSTab; /* Code an OP_Transaction and OP_TableLock for . */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -112405,6 +112801,49 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ } } +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Scan all previously generated bytecode looking for an OP_BeginSubrtn +** that is compatible with pExpr. If found, add the y.sub values +** to pExpr and return true. If not found, return false. +*/ +static int findCompatibleInRhsSubrtn( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* IN operator with RHS that we want to reuse */ + SubrtnSig *pNewSig /* Signature for the IN operator */ +){ + VdbeOp *pOp, *pEnd; + SubrtnSig *pSig; + Vdbe *v; + + if( pNewSig==0 ) return 0; + if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0; + assert( pExpr->op==TK_IN ); + assert( !ExprUseYSub(pExpr) ); + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( (pExpr->x.pSelect->selFlags & SF_All)==0 ); + v = pParse->pVdbe; + assert( v!=0 ); + pOp = sqlite3VdbeGetOp(v, 1); + pEnd = sqlite3VdbeGetLastOp(v); + for(; pOpp4type!=P4_SUBRTNSIG ) continue; + assert( pOp->opcode==OP_BeginSubrtn ); + pSig = pOp->p4.pSubrtnSig; + assert( pSig!=0 ); + if( pNewSig->selId!=pSig->selId ) continue; + if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; + pExpr->y.sub.iAddr = pSig->iAddr; + pExpr->y.sub.regReturn = pSig->regReturn; + pExpr->iTable = pSig->iTable; + ExprSetProperty(pExpr, EP_Subrtn); + return 1; + } + return 0; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that will construct an ephemeral table containing all terms @@ -112454,11 +112893,28 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ - /* Reuse of the RHS is allowed */ - /* If this routine has already been coded, but the previous code - ** might not have been invoked yet, so invoke it now as a subroutine. + /* Reuse of the RHS is allowed + ** + ** Compute a signature for the RHS of the IN operator to facility + ** finding and reusing prior instances of the same IN operator. */ - if( ExprHasProperty(pExpr, EP_Subrtn) ){ + SubrtnSig *pSig = 0; + assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); + if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ + pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); + if( pSig ){ + pSig->selId = pExpr->x.pSelect->selId; + pSig->zAff = exprINAffinity(pParse, pExpr); + } + } + + /* Check to see if there is a prior materialization of the RHS of + ** this IN operator. If there is, then make use of that prior + ** materialization rather than recomputing it. + */ + if( ExprHasProperty(pExpr, EP_Subrtn) + || findCompatibleInRhsSubrtn(pParse, pExpr, pSig) + ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); if( ExprUseXSelect(pExpr) ){ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", @@ -112470,6 +112926,10 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( assert( iTab!=pExpr->iTable ); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); sqlite3VdbeJumpHere(v, addrOnce); + if( pSig ){ + sqlite3DbFree(pParse->db, pSig->zAff); + sqlite3DbFree(pParse->db, pSig); + } return; } @@ -112480,7 +112940,13 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; - + if( pSig ){ + pSig->iAddr = pExpr->y.sub.iAddr; + pSig->regReturn = pExpr->y.sub.regReturn; + pSig->iTable = iTab; + pParse->mSubrtnSig = 1 << (pSig->selId&7); + sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); + } addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } @@ -112521,15 +112987,30 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( SelectDest dest; int i; int rc; + int addrBloom = 0; sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; + if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ + int regBloom = ++pParse->nMem; + addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); + VdbeComment((v, "Bloom filter")); + dest.iSDParm2 = regBloom; + } testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); + if( addrBloom ){ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + if( dest.iSDParm2==0 ){ + sqlite3VdbeChangeToNoop(v, addrBloom); + }else{ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + } + } if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; @@ -112827,9 +113308,7 @@ static void sqlite3ExprCodeIN( if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); - aiMap = (int*)sqlite3DbMallocZero( - pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 - ); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int)); if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than @@ -112972,6 +113451,15 @@ static void sqlite3ExprCodeIN( sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); + assert( pOp->opcode==OP_Once || pParse->nErr ); + if( pOp->opcode==OP_Once && pOp->p3>0 ){ + assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); + sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + } + } sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); goto sqlite3ExprCodeIN_finished; @@ -113254,13 +113742,17 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n ** register iReg. The caller must ensure that iReg already contains ** the correct value for the expression. */ -static void exprToRegister(Expr *pExpr, int iReg){ +SQLITE_PRIVATE void sqlite3ExprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); if( NEVER(p==0) ) return; - p->op2 = p->op; - p->op = TK_REGISTER; - p->iTable = iReg; - ExprClearProperty(p, EP_Skip); + if( p->op==TK_REGISTER ){ + assert( p->iTable==iReg ); + }else{ + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); + } } /* @@ -113430,6 +113922,59 @@ static int exprCodeInlineFunction( return target; } +/* +** Expression Node callback for sqlite3ExprCanReturnSubtype(). +** +** Only a function call is able to return a subtype. So if the node +** is not a function call, return WRC_Prune immediately. +** +** A function call is able to return a subtype if it has the +** SQLITE_RESULT_SUBTYPE property. +** +** Assume that every function is able to pass-through a subtype from +** one of its argument (using sqlite3_result_value()). Most functions +** are not this way, but we don't have a mechanism to distinguish those +** that are from those that are not, so assume they all work this way. +** That means that if one of its arguments is another function and that +** other function is able to return a subtype, then this function is +** able to return a subtype. +*/ +static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ + int n; + FuncDef *pDef; + sqlite3 *db; + if( pExpr->op!=TK_FUNCTION ){ + return WRC_Prune; + } + assert( ExprUseXList(pExpr) ); + db = pWalker->pParse->db; + n = ALWAYS(pExpr->x.pList) ? pExpr->x.pList->nExpr : 0; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); + if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ + pWalker->eCode = 1; + return WRC_Prune; + } + return WRC_Continue; +} + +/* +** Return TRUE if expression pExpr is able to return a subtype. +** +** A TRUE return does not guarantee that a subtype will be returned. +** It only indicates that a subtype return is possible. False positives +** are acceptable as they only disable an optimization. False negatives, +** on the other hand, can lead to incorrect answers. +*/ +static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ + Walker w; + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = exprNodeCanReturnSubtype; + sqlite3WalkExpr(&w, pExpr); + return w.eCode; +} + + /* ** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr. ** If it is, then resolve the expression by reading from the index and @@ -113462,6 +114007,17 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup( continue; } + + /* Functions that might set a subtype should not be replaced by the + ** value taken from an expression index if they are themselves an + ** argument to another scalar function or aggregate. + ** https://sqlite.org/forum/forumpost/68d284c86b082c3e */ + if( ExprHasProperty(pExpr, EP_SubtArg) + && sqlite3ExprCanReturnSubtype(pParse, pExpr) + ){ + continue; + } + v = pParse->pVdbe; assert( v!=0 ); if( p->bMaybeNullRow ){ @@ -114263,7 +114819,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) break; } testcase( pX->op==TK_COLUMN ); - exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); testcase( regFree1==0 ); memset(&opCompare, 0, sizeof(opCompare)); opCompare.op = TK_EQ; @@ -114317,15 +114873,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ - sqlite3VdbeAddOp4( - v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore); VdbeCoverage(v); }else{ - sqlite3HaltConstraint(pParse, + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp3(v, OP_Halt, pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, - pExpr->affExpr, pExpr->u.zToken, 0, 0); + pExpr->affExpr, r1); } - break; } #endif @@ -114614,7 +115169,7 @@ static void exprCodeBetween( compRight.op = TK_LE; compRight.pLeft = pDel; compRight.pRight = pExpr->x.pList->a[1].pExpr; - exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); + sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1)); if( xJump ){ xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ @@ -117508,8 +118063,9 @@ static int renameResolveTrigger(Parse *pParse){ int i; for(i=0; ipFrom->nSrc && rc==SQLITE_OK; i++){ SrcItem *p = &pStep->pFrom->a[i]; - if( p->pSelect ){ - sqlite3SelectPrep(pParse, p->pSelect, 0); + if( p->fg.isSubquery ){ + assert( p->u4.pSubq!=0 ); + sqlite3SelectPrep(pParse, p->u4.pSubq->pSelect, 0); } } } @@ -117577,8 +118133,12 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ } if( pStep->pFrom ){ int i; - for(i=0; ipFrom->nSrc; i++){ - sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect); + SrcList *pFrom = pStep->pFrom; + for(i=0; inSrc; i++){ + if( pFrom->a[i].fg.isSubquery ){ + assert( pFrom->a[i].u4.pSubq!=0 ); + sqlite3WalkSelect(pWalker, pFrom->a[i].u4.pSubq->pSelect); + } } } } @@ -117825,7 +118385,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ } for(i=0; inSrc; i++){ SrcItem *pItem = &pSrc->a[i]; - if( pItem->pTab==p->pTab ){ + if( pItem->pSTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } } @@ -120253,12 +120813,13 @@ static int loadStatTbl( while( sqlite3_step(pStmt)==SQLITE_ROW ){ int nIdxCol = 1; /* Number of columns in stat4 records */ - char *zIndex; /* Index name */ - Index *pIdx; /* Pointer to the index object */ - int nSample; /* Number of samples */ - int nByte; /* Bytes of space required */ - int i; /* Bytes of space required */ - tRowcnt *pSpace; + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + i64 nByte; /* Bytes of space required */ + i64 i; /* Bytes of space required */ + tRowcnt *pSpace; /* Available allocated memory space */ + u8 *pPtr; /* Available memory as a u8 for easier manipulation */ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; @@ -120278,7 +120839,7 @@ static int loadStatTbl( } pIdx->nSampleCol = nIdxCol; pIdx->mxSample = nSample; - nByte = sizeof(IndexSample) * nSample; + nByte = ROUND8(sizeof(IndexSample) * nSample); nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ @@ -120287,7 +120848,10 @@ static int loadStatTbl( sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } - pSpace = (tRowcnt*)&pIdx->aSample[nSample]; + pPtr = (u8*)pIdx->aSample; + pPtr += ROUND8(nSample*sizeof(pIdx->aSample[0])); + pSpace = (tRowcnt*)pPtr; + assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); pIdx->aAvgEq = pSpace; pSpace += nIdxCol; pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; ia; inSrc; i++, pItem++){ - if( pFix->bTemp==0 ){ - if( pItem->zDatabase ){ - if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + if( pFix->bTemp==0 && pItem->fg.isSubquery==0 ){ + if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + if( iDb!=sqlite3FindDbName(db, pItem->u4.zDatabase) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); + pFix->zType, pFix->pName, pItem->u4.zDatabase); return WRC_Abort; } - sqlite3DbFree(db, pItem->zDatabase); - pItem->zDatabase = 0; + sqlite3DbFree(db, pItem->u4.zDatabase); pItem->fg.notCte = 1; + pItem->fg.hadSchema = 1; } - pItem->pSchema = pFix->pSchema; + pItem->u4.pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; + pItem->fg.fixedSchema = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( pList->a[i].fg.isUsing==0 @@ -121261,7 +121826,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( assert( pTabList ); for(iSrc=0; iSrcnSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ - pTab = pTabList->a[iSrc].pTab; + pTab = pTabList->a[iSrc].pSTab; break; } } @@ -121864,12 +122429,12 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem( SrcItem *p ){ const char *zDb; - assert( p->pSchema==0 || p->zDatabase==0 ); - if( p->pSchema ){ - int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); + if( p->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, p->u4.pSchema); zDb = pParse->db->aDb[iDb].zDbSName; }else{ - zDb = p->zDatabase; + assert( !p->fg.isSubquery ); + zDb = p->u4.zDatabase; } return sqlite3LocateTable(pParse, flags, p->zName, zDb); } @@ -124854,6 +125419,8 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); @@ -124862,7 +125429,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, if( pTab==0 ){ if( noErr ){ - sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } goto exit_drop_table; @@ -125953,15 +126520,17 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists } assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ assert( pName->nSrc==1 ); + assert( pName->a[0].fg.fixedSchema==0 ); + assert( pName->a[0].fg.isSubquery==0 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } - pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); + pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].u4.zDatabase); if( pIndex==0 ){ if( !ifExists ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); }else{ - sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].u4.zDatabase); sqlite3ForceNotReadOnly(pParse); } pParse->checkSchema = 1; @@ -126258,12 +126827,14 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( if( pDatabase && pDatabase->z==0 ){ pDatabase = 0; } + assert( pItem->fg.fixedSchema==0 ); + assert( pItem->fg.isSubquery==0 ); if( pDatabase ){ pItem->zName = sqlite3NameFromToken(db, pDatabase); - pItem->zDatabase = sqlite3NameFromToken(db, pTable); + pItem->u4.zDatabase = sqlite3NameFromToken(db, pTable); }else{ pItem->zName = sqlite3NameFromToken(db, pTable); - pItem->zDatabase = 0; + pItem->u4.zDatabase = 0; } return pList; } @@ -126279,13 +126850,40 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ if( pItem->iCursor>=0 ) continue; pItem->iCursor = pParse->nTab++; - if( pItem->pSelect ){ - sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); + if( pItem->fg.isSubquery ){ + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + assert( pItem->u4.pSubq->pSelect->pSrc!=0 ); + sqlite3SrcListAssignCursors(pParse, pItem->u4.pSubq->pSelect->pSrc); } } } } +/* +** Delete a Subquery object and its substructure. +*/ +SQLITE_PRIVATE void sqlite3SubqueryDelete(sqlite3 *db, Subquery *pSubq){ + assert( pSubq!=0 && pSubq->pSelect!=0 ); + sqlite3SelectDelete(db, pSubq->pSelect); + sqlite3DbFree(db, pSubq); +} + +/* +** Remove a Subquery from a SrcItem. Return the associated Select object. +** The returned Select becomes the responsibility of the caller. +*/ +SQLITE_PRIVATE Select *sqlite3SubqueryDetach(sqlite3 *db, SrcItem *pItem){ + Select *pSel; + assert( pItem!=0 ); + assert( pItem->fg.isSubquery ); + pSel = pItem->u4.pSubq->pSelect; + sqlite3DbFree(db, pItem->u4.pSubq); + pItem->u4.pSubq = 0; + pItem->fg.isSubquery = 0; + return pSel; +} + /* ** Delete an entire SrcList including all its substructure. */ @@ -126295,13 +126893,24 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ assert( db!=0 ); if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - if( pItem->zDatabase ) sqlite3DbNNFreeNN(db, pItem->zDatabase); + + /* Check invariants on SrcItem */ + assert( !pItem->fg.isIndexedBy || !pItem->fg.isTabFunc ); + assert( !pItem->fg.isCte || !pItem->fg.isIndexedBy ); + assert( !pItem->fg.fixedSchema || !pItem->fg.isSubquery ); + assert( !pItem->fg.isSubquery || (pItem->u4.pSubq!=0 && + pItem->u4.pSubq->pSelect!=0) ); + if( pItem->zName ) sqlite3DbNNFreeNN(db, pItem->zName); if( pItem->zAlias ) sqlite3DbNNFreeNN(db, pItem->zAlias); + if( pItem->fg.isSubquery ){ + sqlite3SubqueryDelete(db, pItem->u4.pSubq); + }else if( pItem->fg.fixedSchema==0 && pItem->u4.zDatabase!=0 ){ + sqlite3DbNNFreeNN(db, pItem->u4.zDatabase); + } if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); - sqlite3DeleteTable(db, pItem->pTab); - if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); + sqlite3DeleteTable(db, pItem->pSTab); if( pItem->fg.isUsing ){ sqlite3IdListDelete(db, pItem->u3.pUsing); }else if( pItem->u3.pOn ){ @@ -126311,6 +126920,54 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ sqlite3DbNNFreeNN(db, pList); } +/* +** Attach a Subquery object to pItem->uv.pSubq. Set the +** pSelect value but leave all the other values initialized +** to zero. +** +** A copy of the Select object is made if dupSelect is true, and the +** SrcItem takes responsibility for deleting the copy. If dupSelect is +** false, ownership of the Select passes to the SrcItem. Either way, +** the SrcItem will take responsibility for deleting the Select. +** +** When dupSelect is zero, that means the Select might get deleted right +** away if there is an OOM error. Beware. +** +** Return non-zero on success. Return zero on an OOM error. +*/ +SQLITE_PRIVATE int sqlite3SrcItemAttachSubquery( + Parse *pParse, /* Parsing context */ + SrcItem *pItem, /* Item to which the subquery is to be attached */ + Select *pSelect, /* The subquery SELECT. Must be non-NULL */ + int dupSelect /* If true, attach a copy of pSelect, not pSelect itself.*/ +){ + Subquery *p; + assert( pSelect!=0 ); + assert( pItem->fg.isSubquery==0 ); + if( pItem->fg.fixedSchema ){ + pItem->u4.pSchema = 0; + pItem->fg.fixedSchema = 0; + }else if( pItem->u4.zDatabase!=0 ){ + sqlite3DbFree(pParse->db, pItem->u4.zDatabase); + pItem->u4.zDatabase = 0; + } + if( dupSelect ){ + pSelect = sqlite3SelectDup(pParse->db, pSelect, 0); + if( pSelect==0 ) return 0; + } + p = pItem->u4.pSubq = sqlite3DbMallocRawNN(pParse->db, sizeof(Subquery)); + if( p==0 ){ + sqlite3SelectDelete(pParse->db, pSelect); + return 0; + } + pItem->fg.isSubquery = 1; + p->pSelect = pSelect; + assert( offsetof(Subquery, pSelect)==0 ); + memset(((char*)p)+sizeof(p->pSelect), 0, sizeof(*p)-sizeof(p->pSelect)); + return 1; +} + + /* ** This routine is called by the parser to add a new term to the ** end of a growing FROM clause. The "p" parameter is the part of @@ -126360,10 +127017,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } + assert( pSubquery==0 || pDatabase==0 ); if( pSubquery ){ - pItem->pSelect = pSubquery; - if( pSubquery->selFlags & SF_NestedFrom ){ - pItem->fg.isNestedFrom = 1; + if( sqlite3SrcItemAttachSubquery(pParse, pItem, pSubquery, 0) ){ + if( pSubquery->selFlags & SF_NestedFrom ){ + pItem->fg.isNestedFrom = 1; + } } } assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); @@ -127641,8 +128300,8 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ ** ** The following fields are initialized appropriate in pSrc: ** -** pSrc->a[0].pTab Pointer to the Table object -** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one +** pSrc->a[0].spTab Pointer to the Table object +** pSrc->a[0].u2.pIBIndex Pointer to the INDEXED BY index, if there is one ** */ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ @@ -127650,8 +128309,8 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); - if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); - pItem->pTab = pTab; + if( pItem->pSTab ) sqlite3DeleteTable(pParse->db, pItem->pSTab); + pItem->pSTab = pTab; pItem->fg.notCte = 1; if( pTab ){ pTab->nTabRef++; @@ -127692,6 +128351,7 @@ SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char * ** is for a top-level SQL statement. */ static int vtabIsReadOnly(Parse *pParse, Table *pTab){ + assert( IsVirtual(pTab) ); if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){ return 1; } @@ -127773,7 +128433,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView( if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); - pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pFrom->a[0].fg.fixedSchema==0 && pFrom->a[0].fg.isSubquery==0 ); + pFrom->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); assert( pFrom->a[0].fg.isUsing==0 ); assert( pFrom->a[0].u3.pOn==0 ); } @@ -127835,7 +128496,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( ** ); */ - pTab = pSrc->a[0].pTab; + pTab = pSrc->a[0].pSTab; if( HasRowid(pTab) ){ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); pEList = sqlite3ExprListAppend( @@ -127868,9 +128529,9 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ - pSrc->a[0].pTab = 0; + pSrc->a[0].pSTab = 0; pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); - pSrc->a[0].pTab = pTab; + pSrc->a[0].pSTab = pTab; if( pSrc->a[0].fg.isIndexedBy ){ assert( pSrc->a[0].fg.isCte==0 ); pSrc->a[0].u2.pIBIndex = 0; @@ -130697,7 +131358,11 @@ static void minMaxFinalize(sqlite3_context *context){ ** group_concat(EXPR, ?SEPARATOR?) ** string_agg(EXPR, SEPARATOR) ** -** The SEPARATOR goes before the EXPR string. This is tragic. The +** Content is accumulated in GroupConcatCtx.str with the SEPARATOR +** coming before the EXPR value, except for the first entry which +** omits the SEPARATOR. +** +** It is tragic that the SEPARATOR goes before the EXPR string. The ** groupConcatInverse() implementation would have been easier if the ** SEPARATOR were appended after EXPR. And the order is undocumented, ** so we could change it, in theory. But the old behavior has been @@ -130801,7 +131466,7 @@ static void groupConcatInverse( /* pGCC is always non-NULL since groupConcatStep() will have always ** run first to initialize it */ if( ALWAYS(pGCC) ){ - int nVS; + int nVS; /* Number of characters to remove */ /* Must call sqlite3_value_text() to convert the argument into text prior ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ (void)sqlite3_value_text(argv[0]); @@ -131179,7 +131844,13 @@ static void signFunc( ** Implementation of fpdecode(x,y,z) function. ** ** x is a real number that is to be decoded. y is the precision. -** z is the maximum real precision. +** z is the maximum real precision. Return a string that shows the +** results of the sqlite3FpDecode() function. +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3FpDecode() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. */ static void fpdecodeFunc( sqlite3_context *context, @@ -131195,6 +131866,7 @@ static void fpdecodeFunc( x = sqlite3_value_double(argv[0]); y = sqlite3_value_int(argv[1]); z = sqlite3_value_int(argv[2]); + if( z<=0 ) z = 1; sqlite3FpDecode(&s, x, y, z); if( s.isSpecial==2 ){ sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); @@ -131205,6 +131877,82 @@ static void fpdecodeFunc( } #endif /* SQLITE_DEBUG */ +#ifdef SQLITE_DEBUG +/* +** Implementation of parseuri(uri,flags) function. +** +** Required Arguments: +** "uri" The URI to parse. +** "flags" Bitmask of flags, as if to sqlite3_open_v2(). +** +** Additional arguments beyond the first two make calls to +** sqlite3_uri_key() for integers and sqlite3_uri_parameter for +** anything else. +** +** The result is a string showing the results of calling sqlite3ParseUri(). +** +** Used for testing and debugging only, specifically testing and debugging +** of the sqlite3ParseUri() function. This SQL function does not appear +** in production builds. This function is not an API and is subject to +** modification or removal in future versions of SQLite. +*/ +static void parseuriFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + sqlite3_str *pResult; + const char *zVfs; + const char *zUri; + unsigned int flgs; + int rc; + sqlite3_vfs *pVfs = 0; + char *zFile = 0; + char *zErr = 0; + + if( argc<2 ) return; + pVfs = sqlite3_vfs_find(0); + assert( pVfs ); + zVfs = pVfs->zName; + zUri = (const char*)sqlite3_value_text(argv[0]); + if( zUri==0 ) return; + flgs = (unsigned int)sqlite3_value_int(argv[1]); + rc = sqlite3ParseUri(zVfs, zUri, &flgs, &pVfs, &zFile, &zErr); + pResult = sqlite3_str_new(0); + if( pResult ){ + int i; + sqlite3_str_appendf(pResult, "rc=%d", rc); + sqlite3_str_appendf(pResult, ", flags=0x%x", flgs); + sqlite3_str_appendf(pResult, ", vfs=%Q", pVfs ? pVfs->zName: 0); + sqlite3_str_appendf(pResult, ", err=%Q", zErr); + sqlite3_str_appendf(pResult, ", file=%Q", zFile); + if( zFile ){ + const char *z = zFile; + z += sqlite3Strlen30(z)+1; + while( z[0] ){ + sqlite3_str_appendf(pResult, ", %Q", z); + z += sqlite3Strlen30(z)+1; + } + for(i=2; ia; - pItem->pTab = pFKey->pFrom; + pItem->pSTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; - pItem->pTab->nTabRef++; + pItem->pSTab->nTabRef++; pItem->iCursor = pParse->nTab++; if( regNew!=0 ){ @@ -132736,7 +133486,8 @@ static Trigger *fkActionTrigger( SrcList *pSrc; Expr *pRaise; - pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); + pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"), + pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0); if( pRaise ){ pRaise->affExpr = OE_Abort; } @@ -132744,7 +133495,8 @@ static Trigger *fkActionTrigger( if( pSrc ){ assert( pSrc->nSrc==1 ); pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom); - pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + assert( pSrc->a[0].fg.fixedSchema==0 && pSrc->a[0].fg.isSubquery==0 ); + pSrc->a[0].u4.zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), @@ -133478,8 +134230,11 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ SQLITE_PRIVATE void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){ if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){ SrcItem *pItem = &pVal->pSrc->a[0]; - sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn); - sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1); + assert( (pItem->fg.isSubquery && pItem->u4.pSubq!=0) || pParse->nErr ); + if( pItem->fg.isSubquery ){ + sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->u4.pSubq->regReturn); + sqlite3VdbeJumpHere(pParse->pVdbe, pItem->u4.pSubq->addrFillSub - 1); + } } } @@ -133607,6 +134362,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList if( pRet ){ SelectDest dest; + Subquery *pSubq; pRet->pSrc->nSrc = 1; pRet->pPrior = pLeft->pPrior; pRet->op = pLeft->op; @@ -133616,28 +134372,32 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList assert( pLeft->pNext==0 ); assert( pRet->pNext==0 ); p = &pRet->pSrc->a[0]; - p->pSelect = pLeft; p->fg.viaCoroutine = 1; - p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; - p->regReturn = ++pParse->nMem; p->iCursor = -1; + assert( !p->fg.isIndexedBy && !p->fg.isTabFunc ); p->u1.nRow = 2; - sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub); - sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn); - - /* Allocate registers for the output of the co-routine. Do so so - ** that there are two unused registers immediately before those - ** used by the co-routine. This allows the code in sqlite3Insert() - ** to use these registers directly, instead of copying the output - ** of the co-routine to a separate array for processing. */ - dest.iSdst = pParse->nMem + 3; - dest.nSdst = pLeft->pEList->nExpr; - pParse->nMem += 2 + dest.nSdst; - - pLeft->selFlags |= SF_MultiValue; - sqlite3Select(pParse, pLeft, &dest); - p->regResult = dest.iSdst; - assert( pParse->nErr || dest.iSdst>0 ); + if( sqlite3SrcItemAttachSubquery(pParse, p, pLeft, 0) ){ + pSubq = p->u4.pSubq; + pSubq->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1; + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, + pSubq->regReturn, 0, pSubq->addrFillSub); + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); + + /* Allocate registers for the output of the co-routine. Do so so + ** that there are two unused registers immediately before those + ** used by the co-routine. This allows the code in sqlite3Insert() + ** to use these registers directly, instead of copying the output + ** of the co-routine to a separate array for processing. */ + dest.iSdst = pParse->nMem + 3; + dest.nSdst = pLeft->pEList->nExpr; + pParse->nMem += 2 + dest.nSdst; + + pLeft->selFlags |= SF_MultiValue; + sqlite3Select(pParse, pLeft, &dest); + pSubq->regResult = dest.iSdst; + assert( pParse->nErr || dest.iSdst>0 ); + } pLeft = pRet; } }else{ @@ -133647,12 +134407,18 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList } if( pParse->nErr==0 ){ + Subquery *pSubq; assert( p!=0 ); - if( p->pSelect->pEList->nExpr!=pRow->nExpr ){ - sqlite3SelectWrongNumTermsError(pParse, p->pSelect); + assert( p->fg.isSubquery ); + pSubq = p->u4.pSubq; + assert( pSubq!=0 ); + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + if( pSubq->pSelect->pEList->nExpr!=pRow->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, pSubq->pSelect); }else{ - sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0); - sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn); + sqlite3ExprCodeExprList(pParse, pRow, pSubq->regResult, 0, 0); + sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, pSubq->regReturn); } } sqlite3ExprListDelete(pParse->db, pRow); @@ -134003,9 +134769,14 @@ SQLITE_PRIVATE void sqlite3Insert( && pSelect->pPrior==0 ){ SrcItem *pItem = &pSelect->pSrc->a[0]; - dest.iSDParm = pItem->regReturn; - regFromSelect = pItem->regResult; - nColumn = pItem->pSelect->pEList->nExpr; + Subquery *pSubq; + assert( pItem->fg.isSubquery ); + pSubq = pItem->u4.pSubq; + dest.iSDParm = pSubq->regReturn; + regFromSelect = pSubq->regResult; + assert( pSubq->pSelect!=0 ); + assert( pSubq->pSelect->pEList!=0 ); + nColumn = pSubq->pSelect->pEList->nExpr; ExplainQueryPlan((pParse, 0, "SCAN %S", pItem)); if( bIdListInOrder && nColumn==pTab->nCol ){ regData = regFromSelect; @@ -135925,7 +136696,7 @@ static int xferOptimization( if( pSelect->pSrc->nSrc!=1 ){ return 0; /* FROM clause must have exactly one term */ } - if( pSelect->pSrc->a[0].pSelect ){ + if( pSelect->pSrc->a[0].fg.isSubquery ){ return 0; /* FROM clause cannot contain a subquery */ } if( pSelect->pWhere ){ @@ -140485,6 +141256,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Make sure sufficient number of registers have been allocated */ sqlite3TouchRegister(pParse, 8+cnt); + sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt); sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ @@ -142810,12 +143582,24 @@ static int sqlite3Prepare16( if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; } + + /* Make sure nBytes is non-negative and correct. It should be the + ** number of bytes until the end of the input buffer or until the first + ** U+0000 character. If the input nBytes is odd, convert it into + ** an even number. If the input nBytes is negative, then the input + ** must be terminated by at least one U+0000 character */ if( nBytes>=0 ){ int sz; const char *z = (const char*)zSql; for(sz=0; szmutex); zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 ){ @@ -142829,7 +143613,7 @@ static int sqlite3Prepare16( ** the same number of characters into the UTF-16 string. */ int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); - *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, nBytes, chars_parsed); } sqlite3DbFree(db, zSql8); rc = sqlite3ApiExit(db, rc); @@ -143223,11 +144007,13 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ */ SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ assert( pItem!=0 ); - assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) ); if( pItem->fg.isNestedFrom ){ ExprList *pResults; - assert( pItem->pSelect!=0 ); - pResults = pItem->pSelect->pEList; + assert( pItem->fg.isSubquery ); + assert( pItem->u4.pSubq!=0 ); + assert( pItem->u4.pSubq->pSelect!=0 ); + pResults = pItem->u4.pSubq->pSelect->pEList; assert( pResults!=0 ); assert( iCol>=0 && iColnExpr ); pResults->a[iCol].fg.bUsed = 1; @@ -143261,9 +144047,9 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=iStart; i<=iEnd; i++){ - iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pSTab, zCol); if( iCol>=0 - && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) + && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pSTab->aCol[iCol])==0) ){ if( piTab ){ sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); @@ -143392,10 +144178,10 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ pLeft = &pSrc->a[0]; pRight = &pLeft[1]; for(i=0; inSrc-1; i++, pRight++, pLeft++){ - Table *pRightTab = pRight->pTab; + Table *pRightTab = pRight->pSTab; u32 joinType; - if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; + if( NEVER(pLeft->pSTab==0 || pRightTab==0) ) continue; joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; /* If this is a NATURAL join, synthesize an appropriate USING clause @@ -144268,12 +145054,18 @@ static void selectInnerLoop( ** case the order does matter */ pushOntoSorter( pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */ }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + if( pDest->iSDParm2 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + regResult, nResultCol); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); } break; @@ -144815,8 +145607,12 @@ static const char *columnTypeImpl( SrcList *pTabList = pNC->pSrcList; for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); if( jnSrc ){ - pTab = pTabList->a[j].pTab; - pS = pTabList->a[j].pSelect; + pTab = pTabList->a[j].pSTab; + if( pTabList->a[j].fg.isSubquery ){ + pS = pTabList->a[j].u4.pSubq->pSelect; + }else{ + pS = 0; + } }else{ pNC = pNC->pNext; } @@ -145383,7 +146179,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); assert( v!=0 ); - if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ + if( sqlite3ExprIsInteger(pLimit->pLeft, &n, pParse) ){ sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ @@ -145863,7 +146659,7 @@ static int multiSelect( p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( p->pLimit - && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse) && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); @@ -146207,6 +147003,11 @@ static int generateOutputSubroutine( r1, pDest->zAffSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); + if( pDest->iSDParm2>0 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + pIn->iSdst, pIn->nSdst); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); break; } @@ -146863,7 +147664,9 @@ static void substSelect( pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - substSelect(pSubst, pItem->pSelect, 1); + if( pItem->fg.isSubquery ){ + substSelect(pSubst, pItem->u4.pSubq->pSelect, 1); + } if( pItem->fg.isTabFunc ){ substExprList(pSubst, pItem->u1.pFuncArg); } @@ -146894,7 +147697,7 @@ static void recomputeColumnsUsed( SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; - if( NEVER(pSrcItem->pTab==0) ) return; + if( NEVER(pSrcItem->pSTab==0) ) return; memset(&w, 0, sizeof(w)); w.xExprCallback = recomputeColumnsUsedExpr; w.xSelectCallback = sqlite3SelectWalkNoop; @@ -146934,8 +147737,10 @@ static void srclistRenumberCursors( aCsrMap[pItem->iCursor+1] = pParse->nTab++; } pItem->iCursor = aCsrMap[pItem->iCursor+1]; - for(p=pItem->pSelect; p; p=p->pPrior){ - srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + if( pItem->fg.isSubquery ){ + for(p=pItem->u4.pSubq->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } } } } @@ -147246,7 +148051,8 @@ static int flattenSubquery( assert( pSrc && iFrom>=0 && iFromnSrc ); pSubitem = &pSrc->a[iFrom]; iParent = pSubitem->iCursor; - pSub = pSubitem->pSelect; + assert( pSubitem->fg.isSubquery ); + pSub = pSubitem->u4.pSubq->pSelect; assert( pSub!=0 ); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -147299,7 +148105,7 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ - || IsVirtual(pSubSrc->a[0].pTab) /* (3b) */ + || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ @@ -147385,14 +148191,18 @@ static int flattenSubquery( pParse->zAuthContext = zSavedAuthContext; /* Delete the transient structures associated with the subquery */ - pSub1 = pSubitem->pSelect; - sqlite3DbFree(db, pSubitem->zDatabase); + + if( ALWAYS(pSubitem->fg.isSubquery) ){ + pSub1 = sqlite3SubqueryDetach(db, pSubitem); + }else{ + pSub1 = 0; + } + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->fg.fixedSchema==0 ); sqlite3DbFree(db, pSubitem->zName); sqlite3DbFree(db, pSubitem->zAlias); - pSubitem->zDatabase = 0; pSubitem->zName = 0; pSubitem->zAlias = 0; - pSubitem->pSelect = 0; assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); /* If the sub-query is a compound SELECT statement, then (by restrictions @@ -147433,8 +148243,8 @@ static int flattenSubquery( ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; - Table *pItemTab = pSubitem->pTab; - pSubitem->pTab = 0; + Table *pItemTab = pSubitem->pSTab; + pSubitem->pSTab = 0; p->pOrderBy = 0; p->pPrior = 0; p->pLimit = 0; @@ -147442,7 +148252,7 @@ static int flattenSubquery( p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->op = TK_ALL; - pSubitem->pTab = pItemTab; + pSubitem->pSTab = pItemTab; if( pNew==0 ){ p->pPrior = pPrior; }else{ @@ -147457,11 +148267,14 @@ static int flattenSubquery( TREETRACE(0x4,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } - assert( pSubitem->pSelect==0 ); + assert( pSubitem->fg.isSubquery==0 ); } sqlite3DbFree(db, aCsrMap); if( db->mallocFailed ){ - pSubitem->pSelect = pSub1; + assert( pSubitem->fg.fixedSchema==0 ); + assert( pSubitem->fg.isSubquery==0 ); + assert( pSubitem->u4.zDatabase==0 ); + sqlite3SrcItemAttachSubquery(pParse, pSubitem, pSub1, 0); return 1; } @@ -147472,8 +148285,8 @@ static int flattenSubquery( ** ** pSubitem->pTab is always non-NULL by test restrictions and tests above. */ - if( ALWAYS(pSubitem->pTab!=0) ){ - Table *pTabToDel = pSubitem->pTab; + if( ALWAYS(pSubitem->pSTab!=0) ){ + Table *pTabToDel = pSubitem->pSTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); @@ -147481,7 +148294,7 @@ static int flattenSubquery( }else{ pTabToDel->nTabRef--; } - pSubitem->pTab = 0; + pSubitem->pSTab = 0; } /* The following loop runs once for each term in a compound-subquery @@ -147537,8 +148350,11 @@ static int flattenSubquery( */ for(i=0; ia[i+iFrom]; - if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); assert( pItem->fg.isTabFunc==0 ); + assert( pItem->fg.isSubquery + || pItem->fg.fixedSchema + || pItem->u4.zDatabase==0 ); + if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); *pItem = pSubSrc->a[i]; pItem->fg.jointype |= ltorj; iNewParent = pSubSrc->a[i].iCursor; @@ -147957,7 +148773,8 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** ** NAME AMBIGUITY ** -** This optimization is called the "WHERE-clause push-down optimization". +** This optimization is called the "WHERE-clause push-down optimization" +** or sometimes the "predicate push-down optimization". ** ** Do not confuse this optimization with another unrelated optimization ** with a similar name: The "MySQL push-down optimization" causes WHERE @@ -148221,10 +149038,10 @@ static int disableUnusedSubqueryResultColumns(SrcItem *pItem){ if( pItem->fg.isCorrelated || pItem->fg.isCte ){ return 0; } - assert( pItem->pTab!=0 ); - pTab = pItem->pTab; - assert( pItem->pSelect!=0 ); - pSub = pItem->pSelect; + assert( pItem->pSTab!=0 ); + pTab = pItem->pSTab; + assert( pItem->fg.isSubquery ); + pSub = pItem->u4.pSubq->pSelect; assert( pSub->pEList->nExpr==pTab->nCol ); for(pX=pSub; pX; pX=pX->pPrior){ if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ @@ -148353,13 +149170,13 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ if( p->pWhere || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 - || p->pSrc->a[0].pSelect + || p->pSrc->a[0].fg.isSubquery || pAggInfo->nFunc!=1 || p->pHaving ){ return 0; } - pTab = p->pSrc->a[0].pTab; + pTab = p->pSrc->a[0].pSTab; assert( pTab!=0 ); assert( !IsView(pTab) ); if( !IsOrdinaryTable(pTab) ) return 0; @@ -148384,7 +149201,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** pFrom->pIndex and return SQLITE_OK. */ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ - Table *pTab = pFrom->pTab; + Table *pTab = pFrom->pSTab; char *zIndexedBy = pFrom->u1.zIndexedBy; Index *pIdx; assert( pTab!=0 ); @@ -148461,7 +149278,11 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); - if( pNewSrc==0 ) return WRC_Abort; + assert( pNewSrc!=0 || pParse->nErr ); + if( pParse->nErr ){ + sqlite3SrcListDelete(db, pNewSrc); + return WRC_Abort; + } *pNew = *p; p->pSrc = pNewSrc; p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); @@ -148516,7 +149337,7 @@ static struct Cte *searchWith( ){ const char *zName = pItem->zName; With *p; - assert( pItem->zDatabase==0 ); + assert( pItem->fg.fixedSchema || pItem->u4.zDatabase==0 ); assert( zName!=0 ); for(p=pWith; p; p=p->pOuter){ int i; @@ -148586,7 +149407,7 @@ static int resolveFromTermToCte( Cte *pCte; /* Matched CTE (or NULL if no match) */ With *pWith; /* The matching WITH */ - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); if( pParse->pWith==0 ){ /* There are no WITH clauses in the stack. No match is possible */ return 0; @@ -148596,7 +149417,8 @@ static int resolveFromTermToCte( ** go no further. */ return 0; } - if( pFrom->zDatabase!=0 ){ + assert( pFrom->fg.hadSchema==0 || pFrom->fg.notCte!=0 ); + if( pFrom->fg.fixedSchema==0 && pFrom->u4.zDatabase!=0 ){ /* The FROM term contains a schema qualifier (ex: main.t1) and so ** it cannot possibly be a CTE reference. */ return 0; @@ -148632,7 +149454,7 @@ static int resolveFromTermToCte( } if( cannotBeFunction(pParse, pFrom) ) return 2; - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 2; pCteUse = pCte->pUse; @@ -148646,26 +149468,29 @@ static int resolveFromTermToCte( } pCteUse->eM10d = pCte->eM10d; } - pFrom->pTab = pTab; + pFrom->pSTab = pTab; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; - pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); + sqlite3SrcItemAttachSubquery(pParse, pFrom, pCte->pSelect, 1); if( db->mallocFailed ) return 2; - pFrom->pSelect->selFlags |= SF_CopyCte; - assert( pFrom->pSelect ); + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + pSel = pFrom->u4.pSubq->pSelect; + assert( pSel!=0 ); + pSel->selFlags |= SF_CopyCte; if( pFrom->fg.isIndexedBy ){ sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); return 2; } + assert( !pFrom->fg.isIndexedBy ); pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; /* Check if this is a recursive CTE. */ - pRecTerm = pSel = pFrom->pSelect; + pRecTerm = pSel; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); while( bMayRecursive && pRecTerm->op==pSel->op ){ int i; @@ -148673,11 +149498,13 @@ static int resolveFromTermToCte( assert( pRecTerm->pPrior!=0 ); for(i=0; inSrc; i++){ SrcItem *pItem = &pSrc->a[i]; - if( pItem->zDatabase==0 - && pItem->zName!=0 + if( pItem->zName!=0 + && !pItem->fg.hadSchema + && ALWAYS( !pItem->fg.isSubquery ) + && (pItem->fg.fixedSchema || pItem->u4.zDatabase==0) && 0==sqlite3StrICmp(pItem->zName, pCte->zName) ){ - pItem->pTab = pTab; + pItem->pSTab = pTab; pTab->nTabRef++; pItem->fg.isRecursive = 1; if( pRecTerm->selFlags & SF_Recursive ){ @@ -148779,11 +149606,14 @@ SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ ** SQLITE_NOMEM. */ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ - Select *pSel = pFrom->pSelect; + Select *pSel; Table *pTab; + assert( pFrom->fg.isSubquery ); + assert( pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; assert( pSel ); - pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); + pFrom->pSTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); if( pTab==0 ) return SQLITE_NOMEM; pTab->nTabRef = 1; if( pFrom->zAlias ){ @@ -148903,33 +149733,35 @@ static int selectExpander(Walker *pWalker, Select *p){ */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab; - assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); - if( pFrom->pTab ) continue; + assert( pFrom->fg.isRecursive==0 || pFrom->pSTab!=0 ); + if( pFrom->pSTab ) continue; assert( pFrom->fg.isRecursive==0 ); if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY - Select *pSel = pFrom->pSelect; + Select *pSel; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq!=0 ); + pSel = pFrom->u4.pSubq->pSelect; /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); - assert( pFrom->pTab==0 ); + assert( pFrom->pSTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; #endif #ifndef SQLITE_OMIT_CTE }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ if( rc>1 ) return WRC_Abort; - pTab = pFrom->pTab; + pTab = pFrom->pSTab; assert( pTab!=0 ); #endif }else{ /* An ordinary table or view name in the FROM clause */ - assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); + assert( pFrom->pSTab==0 ); + pFrom->pSTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; if( pTab->nTabRef>=0xffff ){ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", pTab->zName); - pFrom->pTab = 0; + pFrom->pSTab = 0; return WRC_Abort; } pTab->nTabRef++; @@ -148941,7 +149773,7 @@ static int selectExpander(Walker *pWalker, Select *p){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; - assert( pFrom->pSelect==0 ); + assert( pFrom->fg.isSubquery==0 ); if( IsView(pTab) ){ if( (db->flags & SQLITE_EnableView)==0 && pTab->pSchema!=db->aDb[1].pSchema @@ -148949,7 +149781,7 @@ static int selectExpander(Walker *pWalker, Select *p){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } - pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0); + sqlite3SrcItemAttachSubquery(pParse, pFrom, pTab->u.view.pSelect, 1); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( ALWAYS(IsVirtual(pTab)) @@ -148965,7 +149797,9 @@ static int selectExpander(Walker *pWalker, Select *p){ nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ - sqlite3WalkSelect(pWalker, pFrom->pSelect); + if( pFrom->fg.isSubquery ){ + sqlite3WalkSelect(pWalker, pFrom->u4.pSubq->pSelect); + } pWalker->eCode = eCodeOrig; pTab->nCol = nCol; } @@ -149052,7 +149886,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ int nAdd; /* Number of cols including rowid */ - Table *pTab = pFrom->pTab; /* Table for this data source */ + Table *pTab = pFrom->pSTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ const char *zSchemaName = 0; /* Schema name for this data source */ @@ -149063,10 +149897,11 @@ static int selectExpander(Walker *pWalker, Select *p){ zTabName = pTab->zName; } if( db->mallocFailed ) break; - assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); + assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom) ); if( pFrom->fg.isNestedFrom ){ - assert( pFrom->pSelect!=0 ); - pNestedFrom = pFrom->pSelect->pEList; + assert( pFrom->fg.isSubquery && pFrom->u4.pSubq ); + assert( pFrom->u4.pSubq->pSelect!=0 ); + pNestedFrom = pFrom->u4.pSubq->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid ); @@ -149305,14 +150140,12 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ assert( (p->selFlags & SF_Resolved) ); pTabList = p->pSrc; for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; + Table *pTab = pFrom->pSTab; assert( pTab!=0 ); - if( (pTab->tabFlags & TF_Ephemeral)!=0 ){ + if( (pTab->tabFlags & TF_Ephemeral)!=0 && pFrom->fg.isSubquery ){ /* A sub-query in the FROM clause of a SELECT */ - Select *pSel = pFrom->pSelect; - if( pSel ){ - sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); - } + Select *pSel = pFrom->u4.pSubq->pSelect; + sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE); } } } @@ -149626,6 +150459,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); + if( pParse->nErr ) return; pList = pF->pFExpr->x.pList; if( pF->iOBTab>=0 ){ /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs @@ -149835,6 +150669,7 @@ static void updateAccumulator( if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } + if( pParse->nErr ) return; } if( regHit==0 && pAggInfo->nAccumulator ){ regHit = regAcc; @@ -149844,6 +150679,7 @@ static void updateAccumulator( } for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i)); + if( pParse->nErr ) return; } pAggInfo->directMode = 0; @@ -149959,25 +150795,28 @@ static SrcItem *isSelfJoinView( int iFirst, int iEnd /* Range of FROM-clause entries to search. */ ){ SrcItem *pItem; - assert( pThis->pSelect!=0 ); - if( pThis->pSelect->selFlags & SF_PushDown ) return 0; + Select *pSel; + assert( pThis->fg.isSubquery ); + pSel = pThis->u4.pSubq->pSelect; + assert( pSel!=0 ); + if( pSel->selFlags & SF_PushDown ) return 0; while( iFirsta[iFirst++]; - if( pItem->pSelect==0 ) continue; + if( !pItem->fg.isSubquery ) continue; if( pItem->fg.viaCoroutine ) continue; if( pItem->zName==0 ) continue; - assert( pItem->pTab!=0 ); - assert( pThis->pTab!=0 ); - if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue; + assert( pItem->pSTab!=0 ); + assert( pThis->pSTab!=0 ); + if( pItem->pSTab->pSchema!=pThis->pSTab->pSchema ) continue; if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; - pS1 = pItem->pSelect; - if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){ + pS1 = pItem->u4.pSubq->pSelect; + if( pItem->pSTab->pSchema==0 && pSel->selId!=pS1->selId ){ /* The query flattener left two different CTE tables with identical ** names in the same FROM clause. */ continue; } - if( pItem->pSelect->selFlags & SF_PushDown ){ + if( pS1->selFlags & SF_PushDown ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; @@ -150021,6 +150860,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ Expr *pExpr; Expr *pCount; sqlite3 *db; + SrcItem *pFrom; if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; @@ -150035,8 +150875,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */ - pSub = p->pSrc->a[0].pSelect; - if( pSub==0 ) return 0; /* The FROM is a subquery */ + pFrom = p->pSrc->a; + if( pFrom->fg.isSubquery==0 ) return 0; /* FROM is a subquery */ + pSub = pFrom->u4.pSubq->pSelect; if( pSub->pPrior==0 ) return 0; /* Must be a compound */ if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ do{ @@ -150045,7 +150886,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ assert( pSub->pHaving==0 ); /* Due to the previous */ - pSub = pSub->pPrior; /* Repeat over compound */ + pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); /* If we reach this point then it is OK to perform the transformation */ @@ -150053,8 +150894,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ db = pParse->db; pCount = pExpr; pExpr = 0; - pSub = p->pSrc->a[0].pSelect; - p->pSrc->a[0].pSelect = 0; + pSub = sqlite3SubqueryDetach(db, pFrom); sqlite3SrcListDelete(db, p->pSrc); p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); while( pSub ){ @@ -150099,12 +150939,12 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){ for(i=0; inSrc; i++){ SrcItem *p1 = &pSrc->a[i]; if( p1==p0 ) continue; - if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ + if( p0->pSTab==p1->pSTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ return 1; } - if( p1->pSelect - && (p1->pSelect->selFlags & SF_NestedFrom)!=0 - && sameSrcAlias(p0, p1->pSelect->pSrc) + if( p1->fg.isSubquery + && (p1->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 + && sameSrcAlias(p0, p1->u4.pSubq->pSelect->pSrc) ){ return 1; } @@ -150169,13 +151009,13 @@ static int fromClauseTermCanBeCoroutine( if( i==0 ) break; i--; pItem--; - if( pItem->pSelect!=0 ) return 0; /* (1c-i) */ + if( pItem->fg.isSubquery ) return 0; /* (1c-i) */ } return 1; } /* -** Generate code for the SELECT statement given in the p argument. +** Generate byte-code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. ** See comments in sqliteInt.h for further information. @@ -150186,6 +151026,40 @@ static int fromClauseTermCanBeCoroutine( ** ** This routine does NOT free the Select structure passed in. The ** calling function needs to do that. +** +** This is a long function. The following is an outline of the processing +** steps, with tags referencing various milestones: +** +** * Resolve names and similar preparation tag-select-0100 +** * Scan of the FROM clause tag-select-0200 +** + OUTER JOIN strength reduction tag-select-0220 +** + Sub-query ORDER BY removal tag-select-0230 +** + Query flattening tag-select-0240 +** * Separate subroutine for compound-SELECT tag-select-0300 +** * WHERE-clause constant propagation tag-select-0330 +** * Count()-of-VIEW optimization tag-select-0350 +** * Scan of the FROM clause again tag-select-0400 +** + Authorize unreferenced tables tag-select-0410 +** + Predicate push-down optimization tag-select-0420 +** + Omit unused subquery columns optimization tag-select-0440 +** + Generate code to implement subqueries tag-select-0480 +** - Co-routines tag-select-0482 +** - Reuse previously computed CTE tag-select-0484 +** - REuse previously computed VIEW tag-select-0486 +** - Materialize a VIEW or CTE tag-select-0488 +** * DISTINCT ORDER BY -> GROUP BY optimization tag-select-0500 +** * Set up for ORDER BY tag-select-0600 +** * Create output table tag-select-0630 +** * Prepare registers for LIMIT tag-select-0650 +** * Setup for DISTINCT tag-select-0680 +** * Generate code for non-aggregate and non-GROUP BY tag-select-0700 +** * Generate code for aggregate and/or GROUP BY tag-select-0800 +** + GROUP BY queries tag-select-0810 +** + non-GROUP BY queries tag-select-0820 +** - Special case of count() w/o GROUP BY tag-select-0821 +** - General case of non-GROUP BY aggregates tag-select-0822 +** * Sort results, as needed tag-select-0900 +** * Internal self-checks tag-select-1000 */ SQLITE_PRIVATE int sqlite3Select( Parse *pParse, /* The parser context */ @@ -150229,6 +151103,7 @@ SQLITE_PRIVATE int sqlite3Select( } #endif + /* tag-select-0100 */ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); @@ -150280,7 +151155,7 @@ SQLITE_PRIVATE int sqlite3Select( if( sameSrcAlias(p0, p->pSrc) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", - p0->zAlias ? p0->zAlias : p0->pTab->zName + p0->zAlias ? p0->zAlias : p0->pSTab->zName ); goto select_end; } @@ -150315,12 +151190,13 @@ SQLITE_PRIVATE int sqlite3Select( /* Try to do various optimizations (flattening subqueries, and strength ** reduction of join operators) in the FROM clause up into the main query + ** tag-select-0200 */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && inSrc; i++){ SrcItem *pItem = &pTabList->a[i]; - Select *pSub = pItem->pSelect; - Table *pTab = pItem->pTab; + Select *pSub = pItem->fg.isSubquery ? pItem->u4.pSubq->pSelect : 0; + Table *pTab = pItem->pSTab; /* The expander should have already created transient Table objects ** even for FROM clause elements such as subqueries that do not correspond @@ -150337,6 +151213,7 @@ SQLITE_PRIVATE int sqlite3Select( ** way that the i-th table cannot be the NULL row of a join, then ** perform the appropriate simplification. This is called ** "OUTER JOIN strength reduction" in the SQLite documentation. + ** tag-select-0220 */ if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, @@ -150407,7 +151284,8 @@ SQLITE_PRIVATE int sqlite3Select( if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; assert( pSub->pGroupBy==0 ); - /* If a FROM-clause subquery has an ORDER BY clause that is not + /* tag-select-0230: + ** If a FROM-clause subquery has an ORDER BY clause that is not ** really doing anything, then delete it now so that it does not ** interfere with query flattening. See the discussion at ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a @@ -150426,13 +151304,16 @@ SQLITE_PRIVATE int sqlite3Select( ** (a) The outer query has a different ORDER BY clause ** (b) The subquery is part of a join ** See forum post 062d576715d277c8 + ** (6) The subquery is not a recursive CTE. ORDER BY has a different + ** meaning for recursive CTEs and this optimization does not + ** apply. ** ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. */ if( pSub->pOrderBy!=0 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ && pSub->pLimit==0 /* Condition (1) */ - && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ + && (pSub->selFlags & (SF_OrderByReqd|SF_Recursive))==0 /* (2) and (6) */ && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ && OptimizationEnabled(db, SQLITE_OmitOrderBy) ){ @@ -150470,6 +151351,7 @@ SQLITE_PRIVATE int sqlite3Select( continue; } + /* tag-select-0240 */ if( flattenSubquery(pParse, p, i, isAgg) ){ if( pParse->nErr ) goto select_end; /* This subquery can be absorbed into its parent. */ @@ -150485,7 +151367,7 @@ SQLITE_PRIVATE int sqlite3Select( #ifndef SQLITE_OMIT_COMPOUND_SELECT /* Handle compound SELECT statements using the separate multiSelect() - ** procedure. + ** procedure. tag-select-0300 */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); @@ -150501,9 +151383,9 @@ SQLITE_PRIVATE int sqlite3Select( #endif /* Do the WHERE-clause constant propagation optimization if this is - ** a join. No need to speed time on this operation for non-join queries + ** a join. No need to spend time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in - ** sqlite3WhereBegin(). + ** sqlite3WhereBegin(). tag-select-0330 */ if( p->pWhere!=0 && p->pWhere->op==TK_AND @@ -150520,6 +151402,7 @@ SQLITE_PRIVATE int sqlite3Select( TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n")); } + /* tag-select-0350 */ if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) && countOfViewOptimization(pParse, p) ){ @@ -150527,20 +151410,26 @@ SQLITE_PRIVATE int sqlite3Select( pTabList = p->pSrc; } - /* For each term in the FROM clause, do two things: - ** (1) Authorized unreferenced tables - ** (2) Generate code for all sub-queries + /* Loop over all terms in the FROM clause and do two things for each term: + ** + ** (1) Authorize unreferenced tables + ** (2) Generate code for all sub-queries + ** + ** tag-select-0400 */ for(i=0; inSrc; i++){ SrcItem *pItem = &pTabList->a[i]; SrcItem *pPrior; SelectDest dest; + Subquery *pSubq; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) const char *zSavedAuthContext; #endif - /* Issue SQLITE_READ authorizations with a fake column name for any + /* Authorized unreferenced tables. tag-select-0410 + ** + ** Issue SQLITE_READ authorizations with a fake column name for any ** tables that are referenced but from which no values are extracted. ** Examples of where these kinds of null SQLITE_READ authorizations ** would occur: @@ -150557,17 +151446,28 @@ SQLITE_PRIVATE int sqlite3Select( ** string for the fake column name seems safer. */ if( pItem->colUsed==0 && pItem->zName!=0 ){ - sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); + const char *zDb; + if( pItem->fg.fixedSchema ){ + int iDb = sqlite3SchemaToIndex(pParse->db, pItem->u4.pSchema); + zDb = db->aDb[iDb].zDbSName; + }else if( pItem->fg.isSubquery ){ + zDb = 0; + }else{ + zDb = pItem->u4.zDatabase; + } + sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", zDb); } #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* Generate code for all sub-queries in the FROM clause */ - pSub = pItem->pSelect; - if( pSub==0 || pItem->addrFillSub!=0 ) continue; + if( pItem->fg.isSubquery==0 ) continue; + pSubq = pItem->u4.pSubq; + assert( pSubq!=0 ); + pSub = pSubq->pSelect; /* The code for a subquery should only be generated once. */ - assert( pItem->addrFillSub==0 ); + if( pSubq->addrFillSub!=0 ) continue; /* Increment Parse.nHeight by the height of the largest expression ** tree referred to by this, the parent select. The child select @@ -150580,6 +151480,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Make copies of constant WHERE-clause terms in the outer query down ** inside the subquery. This can help the subquery to run more efficiently. + ** This is the "predicate push-down optimization". tag-select-0420 */ if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 @@ -150593,13 +151494,14 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3TreeViewSelect(0, p, 0); } #endif - assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); + assert( pSubq->pSelect && (pSub->selFlags & SF_PushDown)!=0 ); }else{ TREETRACE(0x4000,pParse,p,("WHERE-lcause push-down not possible\n")); } /* Convert unused result columns of the subquery into simple NULL ** expressions, to avoid unneeded searching and computation. + ** tag-select-0440 */ if( OptimizationEnabled(db, SQLITE_NullUnusedCols) && disableUnusedSubqueryResultColumns(pItem) @@ -150617,32 +151519,33 @@ SQLITE_PRIVATE int sqlite3Select( zSavedAuthContext = pParse->zAuthContext; pParse->zAuthContext = pItem->zName; - /* Generate code to implement the subquery + /* Generate byte-code to implement the subquery tag-select-0480 */ if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){ /* Implement a co-routine that will return a single row of the result - ** set on each invocation. + ** set on each invocation. tag-select-0482 */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; - pItem->regReturn = ++pParse->nMem; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); + pSubq->regReturn = ++pParse->nMem; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pSubq->regReturn, 0, addrTop); VdbeComment((v, "%!S", pItem)); - pItem->addrFillSub = addrTop; - sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); + pSubq->addrFillSub = addrTop; + sqlite3SelectDestInit(&dest, SRT_Coroutine, pSubq->regReturn); ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; + pItem->pSTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; - pItem->regResult = dest.iSdst; - sqlite3VdbeEndCoroutine(v, pItem->regReturn); + pSubq->regResult = dest.iSdst; + sqlite3VdbeEndCoroutine(v, pSubq->regReturn); + VdbeComment((v, "end %!S", pItem)); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ /* This is a CTE for which materialization code has already been ** generated. Invoke the subroutine to compute the materialization, - ** the make the pItem->iCursor be a copy of the ephemeral table that - ** holds the result of the materialization. */ + ** then make the pItem->iCursor be a copy of the ephemeral table that + ** holds the result of the materialization. tag-select-0484 */ CteUse *pCteUse = pItem->u2.pCteUse; sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); if( pItem->iCursor!=pCteUse->iCur ){ @@ -150652,25 +151555,30 @@ SQLITE_PRIVATE int sqlite3Select( pSub->nSelectRow = pCteUse->nRowEst; }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){ /* This view has already been materialized by a prior entry in - ** this same FROM clause. Reuse it. */ - if( pPrior->addrFillSub ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); + ** this same FROM clause. Reuse it. tag-select-0486 */ + Subquery *pPriorSubq; + assert( pPrior->fg.isSubquery ); + pPriorSubq = pPrior->u4.pSubq; + assert( pPriorSubq!=0 ); + if( pPriorSubq->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPriorSubq->regReturn, + pPriorSubq->addrFillSub); } sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); - pSub->nSelectRow = pPrior->pSelect->nSelectRow; + pSub->nSelectRow = pPriorSubq->pSelect->nSelectRow; }else{ /* Materialize the view. If the view is not correlated, generate a ** subroutine to do the materialization so that subsequent uses of - ** the same view can reuse the materialization. */ + ** the same view can reuse the materialization. tag-select-0488 */ int topAddr; int onceAddr = 0; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS int addrExplain; #endif - pItem->regReturn = ++pParse->nMem; + pSubq->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp0(v, OP_Goto); - pItem->addrFillSub = topAddr+1; + pSubq->addrFillSub = topAddr+1; pItem->fg.isMaterialized = 1; if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of @@ -150685,17 +151593,17 @@ SQLITE_PRIVATE int sqlite3Select( ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); - pItem->pTab->nRowLogEst = pSub->nSelectRow; + pItem->pSTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); - sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1); + sqlite3VdbeAddOp2(v, OP_Return, pSubq->regReturn, topAddr+1); VdbeComment((v, "end %!S", pItem)); sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1); sqlite3VdbeJumpHere(v, topAddr); sqlite3ClearTempRegCache(pParse); if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ CteUse *pCteUse = pItem->u2.pCteUse; - pCteUse->addrM9e = pItem->addrFillSub; - pCteUse->regRtn = pItem->regReturn; + pCteUse->addrM9e = pSubq->addrFillSub; + pCteUse->regRtn = pSubq->regReturn; pCteUse->iCur = pItem->iCursor; pCteUse->nRowEst = pSub->nSelectRow; } @@ -150721,7 +151629,9 @@ SQLITE_PRIVATE int sqlite3Select( } #endif - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + /* tag-select-0500 + ** + ** If the query is DISTINCT with an ORDER BY but is not an aggregate, and ** if the select-list is the same as the ORDER BY list, then this query ** can be rewritten as a GROUP BY. In other words, this: ** @@ -150738,12 +151648,18 @@ SQLITE_PRIVATE int sqlite3Select( */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 + && OptimizationEnabled(db, SQLITE_GroupByOrder) #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 #endif ){ p->selFlags &= ~SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); + if( pGroupBy ){ + for(i=0; inExpr; i++){ + pGroupBy->a[i].u.x.iOrderByCol = i+1; + } + } p->selFlags |= SF_Aggregate; /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the @@ -150765,7 +151681,7 @@ SQLITE_PRIVATE int sqlite3Select( ** If that is the case, then the OP_OpenEphemeral instruction will be ** changed to an OP_Noop once we figure out that the sorting index is ** not needed. The sSort.addrSortIndex variable is used to facilitate - ** that change. + ** that change. tag-select-0600 */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; @@ -150782,6 +151698,7 @@ SQLITE_PRIVATE int sqlite3Select( } /* If the output is destined for a temporary table, open that table. + ** tag-select-0630 */ if( pDest->eDest==SRT_EphemTab ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); @@ -150799,7 +151716,7 @@ SQLITE_PRIVATE int sqlite3Select( } } - /* Set the limiter. + /* Set the limiter. tag-select-0650 */ iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ @@ -150811,7 +151728,7 @@ SQLITE_PRIVATE int sqlite3Select( sSort.sortFlags |= SORTFLAG_UseSorter; } - /* Open an ephemeral index to use for the distinct set. + /* Open an ephemeral index to use for the distinct set. tag-select-0680 */ if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; @@ -150826,7 +151743,7 @@ SQLITE_PRIVATE int sqlite3Select( } if( !isAgg && pGroupBy==0 ){ - /* No aggregate functions and no GROUP BY clause */ + /* No aggregate functions and no GROUP BY clause. tag-select-0700 */ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) | (p->selFlags & SF_FixedLimit); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -150899,8 +151816,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3WhereEnd(pWInfo); } }else{ - /* This case when there exist aggregate functions or a GROUP BY clause - ** or both */ + /* This case is for when there exist aggregate functions or a GROUP BY + ** clause or both. tag-select-0800 */ NameContext sNC; /* Name context for processing aggregate information */ int iAMem; /* First Mem address for storing current GROUP BY */ int iBMem; /* First Mem address for previous GROUP BY */ @@ -151019,7 +151936,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Processing for aggregates with GROUP BY is very different and - ** much more complex than aggregates without a GROUP BY. + ** much more complex than aggregates without a GROUP BY. tag-select-0810 */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ @@ -151206,12 +152123,25 @@ SQLITE_PRIVATE int sqlite3Select( sortOut, sortPTab); } for(j=0; jnExpr; j++){ + int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol; + if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); }else{ pAggInfo->directMode = 1; sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } + + if( iOrderByCol ){ + Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; + Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); + if( ALWAYS(pBase!=0) + && pBase->op!=TK_AGG_COLUMN + && pBase->op!=TK_REGISTER + ){ + sqlite3ExprToRegister(pX, iAMem+j); + } + } } sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); @@ -151227,9 +152157,9 @@ SQLITE_PRIVATE int sqlite3Select( ** and resets the aggregate accumulator registers in preparation ** for the next GROUP BY batch. */ - sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output one row")); + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); VdbeComment((v, "check abort flag")); sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); @@ -151303,9 +152233,12 @@ SQLITE_PRIVATE int sqlite3Select( } } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { + /* Aggregate functions without GROUP BY. tag-select-0820 */ Table *pTab; if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){ - /* If isSimpleCount() returns a pointer to a Table structure, then + /* tag-select-0821 + ** + ** If isSimpleCount() returns a pointer to a Table structure, then ** the SQL statement is of the form: ** ** SELECT count(*) FROM @@ -151364,6 +152297,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else{ + /* The general case of an aggregate query without GROUP BY + ** tag-select-0822 */ int regAcc = 0; /* "populate accumulators" flag */ ExprList *pDistinct = 0; u16 distFlag = 0; @@ -151452,7 +152387,7 @@ SQLITE_PRIVATE int sqlite3Select( } /* If there is an ORDER BY clause, then we need to sort the results - ** and send them to the callback one by one. + ** and send them to the callback one by one. tag-select-0900 */ if( sSort.pOrderBy ){ assert( p->pEList==pEList ); @@ -151475,6 +152410,7 @@ SQLITE_PRIVATE int sqlite3Select( assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG + /* Internal self-checks. tag-select-1000 */ if( pAggInfo && !db->mallocFailed ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x20 ){ @@ -151864,8 +152800,10 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( ** name on pTableName if we are reparsing out of the schema table */ if( db->init.busy && iDb!=1 ){ - sqlite3DbFree(db, pTableName->a[0].zDatabase); - pTableName->a[0].zDatabase = 0; + assert( pTableName->a[0].fg.fixedSchema==0 ); + assert( pTableName->a[0].fg.isSubquery==0 ); + sqlite3DbFree(db, pTableName->a[0].u4.zDatabase); + pTableName->a[0].u4.zDatabase = 0; } /* If the trigger name was unqualified, and the table is a temp table, @@ -152343,7 +153281,8 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) } assert( pName->nSrc==1 ); - zDb = pName->a[0].zDatabase; + assert( pName->a[0].fg.fixedSchema==0 && pName->a[0].fg.isSubquery==0 ); + zDb = pName->a[0].u4.zDatabase; zName = pName->a[0].zName; assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; inDb; i++){ @@ -152580,7 +153519,9 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( Schema *pSchema = pStep->pTrig->pSchema; pSrc->a[0].zName = zName; if( pSchema!=db->aDb[1].pSchema ){ - pSrc->a[0].pSchema = pSchema; + assert( pSrc->a[0].fg.fixedSchema || pSrc->a[0].u4.zDatabase==0 ); + pSrc->a[0].u4.pSchema = pSchema; + pSrc->a[0].fg.fixedSchema = 1; } if( pStep->pFrom ){ SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0); @@ -152693,7 +153634,7 @@ static int sqlite3ReturningSubqueryCorrelated(Walker *pWalker, Select *pSelect){ pSrc = pSelect->pSrc; assert( pSrc!=0 ); for(i=0; inSrc; i++){ - if( pSrc->a[i].pTab==pWalker->u.pTab ){ + if( pSrc->a[i].pSTab==pWalker->u.pTab ){ testcase( pSelect->selFlags & SF_Correlated ); pSelect->selFlags |= SF_Correlated; pWalker->eCode = 1; @@ -152764,7 +153705,7 @@ static void codeReturningTrigger( sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); sSelect.pSrc = &sFrom; sFrom.nSrc = 1; - sFrom.a[0].pTab = pTab; + sFrom.a[0].pSTab = pTab; sFrom.a[0].zName = pTab->zName; /* tag-20240424-1 */ sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); @@ -153475,7 +154416,7 @@ static void updateFromSelect( Expr *pLimit2 = 0; ExprList *pOrderBy2 = 0; sqlite3 *db = pParse->db; - Table *pTab = pTabList->a[0].pTab; + Table *pTab = pTabList->a[0].pSTab; SrcList *pSrc; Expr *pWhere2; int eDest; @@ -153499,8 +154440,8 @@ static void updateFromSelect( if( pSrc ){ assert( pSrc->a[0].fg.notCte ); pSrc->a[0].iCursor = -1; - pSrc->a[0].pTab->nTabRef--; - pSrc->a[0].pTab = 0; + pSrc->a[0].pSTab->nTabRef--; + pSrc->a[0].pSTab = 0; } if( pPk ){ for(i=0; inKeyCol; i++){ @@ -154748,7 +155689,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); - assert( pTabList->a[0].pTab!=0 ); + assert( pTabList->a[0].pSTab!=0 ); assert( pUpsert!=0 ); assert( pUpsert->pUpsertTarget!=0 ); @@ -154767,7 +155708,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( if( rc ) return rc; /* Check to see if the conflict target matches the rowid. */ - pTab = pTabList->a[0].pTab; + pTab = pTabList->a[0].pSTab; pTarget = pUpsert->pUpsertTarget; iCursor = pTabList->a[0].iCursor; if( HasRowid(pTab) @@ -155138,6 +156079,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ + u64 iRandom; /* Random value used for zDbVacuum[] */ + char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ + if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); @@ -155178,27 +156122,29 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); - /* Attach the temporary database as 'vacuum_db'. The synchronous pragma + /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** ** An optimization would be to use a non-journaled pager. - ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but + ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially ** empty. Only the journal header is written. Apparently it takes more ** time to parse and run the PRAGMA to turn journalling off than it does ** to write the journal header file. */ + sqlite3_randomness(sizeof(iRandom),&iRandom); + sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); nDb = db->nDb; - rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); db->openFlags = saved_openFlags; if( rc!=SQLITE_OK ) goto end_of_vacuum; assert( (db->nDb-1)==nDb ); pDb = &db->aDb[nDb]; - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); + assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); pTemp = pDb->pBt; if( pOut ){ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); @@ -155275,11 +156221,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** the contents to the temporary database. */ rc = execSqlF(db, pzErrMsg, - "SELECT'INSERT INTO vacuum_db.'||quote(name)" + "SELECT'INSERT INTO %s.'||quote(name)" "||' SELECT*FROM\"%w\".'||quote(name)" - "FROM vacuum_db.sqlite_schema " + "FROM %s.sqlite_schema " "WHERE type='table'AND coalesce(rootpage,1)>0", - zDbMain + zDbVacuum, zDbMain, zDbVacuum ); assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); db->mDbFlags &= ~DBFLAG_Vacuum; @@ -155291,11 +156237,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( ** from the schema table. */ rc = execSqlF(db, pzErrMsg, - "INSERT INTO vacuum_db.sqlite_schema" + "INSERT INTO %s.sqlite_schema" " SELECT*FROM \"%w\".sqlite_schema" " WHERE type IN('view','trigger')" " OR(type='table'AND rootpage=0)", - zDbMain + zDbVacuum, zDbMain ); if( rc ) goto end_of_vacuum; @@ -156259,6 +157205,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; + assert( IsOrdinaryTable(pNew) ); sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); @@ -156933,11 +157880,13 @@ struct WhereLoop { u16 nTop; /* Size of TOP vector */ u16 nDistinctCol; /* Index columns used to sort for DISTINCT */ Index *pIndex; /* Index used, or NULL */ + ExprList *pOrderBy; /* ORDER BY clause if this is really a subquery */ } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ u32 bOmitOffset : 1; /* True to let virtual table handle offset */ + u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ @@ -156950,6 +157899,8 @@ struct WhereLoop { /**** whereLoopXfer() copies fields above ***********************/ # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) u16 nLSlot; /* Number of slots allocated for aLTerm[] */ + LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not + ** initialized unless pWInfo->nOutStarDelta>0 */ WhereTerm **aLTerm; /* WhereTerms used */ WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */ WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */ @@ -157272,6 +158223,7 @@ struct WhereInfo { unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ unsigned sorted :1; /* True if really sorted (not just grouped) */ + LogEst nOutStarDelta; /* Artifical nOut reduction for star-query */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ @@ -157423,7 +158375,8 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ - /* 0x02000000 -- available for reuse */ +#define WHERE_COROUTINE 0x02000000 /* Implemented by co-routine. + ** NB: False-negatives are possible */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -157568,7 +158521,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( assert( pLoop->u.btree.pIndex!=0 ); pIdx = pLoop->u.btree.pIndex; assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) ); - if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){ + if( !HasRowid(pItem->pSTab) && IsPrimaryKeyIndex(pIdx) ){ if( isSearch ){ zFmt = "PRIMARY KEY"; } @@ -157611,7 +158564,9 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ - sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", + sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX "); + sqlite3_str_appendf(&str, + pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif @@ -157629,7 +158584,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( zMsg = sqlite3StrAccumFinish(&str); sqlite3ExplainBreakpoint("",zMsg); ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), - pParse->addrExplain, 0, zMsg,P4_DYNAMIC); + pParse->addrExplain, pLoop->rRun, + zMsg, P4_DYNAMIC); } return ret; } @@ -157664,7 +158620,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); pLoop = pLevel->pWLoop; if( pLoop->wsFlags & WHERE_IPK ){ - const Table *pTab = pItem->pTab; + const Table *pTab = pItem->pSTab; if( pTab->iPKey>=0 ){ sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); }else{ @@ -157727,7 +158683,9 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); } }else{ - int addr = pSrclist->a[pLvl->iFrom].addrFillSub; + int addr; + assert( pSrclist->a[pLvl->iFrom].fg.isSubquery ); + addr = pSrclist->a[pLvl->iFrom].u4.pSubq->addrFillSub; VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); @@ -157871,6 +158829,39 @@ static void updateRangeAffinityStr( } } +/* +** The pOrderBy->a[].u.x.iOrderByCol values might be incorrect because +** columns might have been rearranged in the result set. This routine +** fixes them up. +** +** pEList is the new result set. The pEList->a[].u.x.iOrderByCol values +** contain the *old* locations of each expression. This is a temporary +** use of u.x.iOrderByCol, not its intended use. The caller must reset +** u.x.iOrderByCol back to zero for all entries in pEList before the +** caller returns. +** +** This routine changes pOrderBy->a[].u.x.iOrderByCol values from +** pEList->a[N].u.x.iOrderByCol into N+1. (The "+1" is because of the 1-based +** indexing used by iOrderByCol.) Or if no match, iOrderByCol is set to zero. +*/ +static void adjustOrderByCol(ExprList *pOrderBy, ExprList *pEList){ + int i, j; + if( pOrderBy==0 ) return; + for(i=0; inExpr; i++){ + int t = pOrderBy->a[i].u.x.iOrderByCol; + if( t==0 ) continue; + for(j=0; jnExpr; j++){ + if( pEList->a[j].u.x.iOrderByCol==t ){ + pOrderBy->a[i].u.x.iOrderByCol = j+1; + break; + } + } + if( j>=pEList->nExpr ){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } + } +} + /* ** pX is an expression of the form: (vector) IN (SELECT ...) @@ -157934,6 +158925,7 @@ static Expr *removeUnindexableInClauseTerms( if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; + if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1; if( pOrigLhs ){ assert( pOrigLhs->a[iField].pExpr!=0 ); pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr); @@ -157956,18 +158948,16 @@ static Expr *removeUnindexableInClauseTerms( sqlite3ExprDelete(db, pNew->pLeft); pNew->pLeft = p; } - if( pSelect->pOrderBy ){ - /* If the SELECT statement has an ORDER BY clause, zero the - ** iOrderByCol variables. These are set to non-zero when an - ** ORDER BY term exactly matches one of the terms of the - ** result-set. Since the result-set of the SELECT statement may - ** have been modified or reordered, these variables are no longer - ** set correctly. Since setting them is just an optimization, - ** it's easiest just to zero them here. */ - ExprList *pOrderBy = pSelect->pOrderBy; - for(i=0; inExpr; i++){ - pOrderBy->a[i].u.x.iOrderByCol = 0; - } + + /* If either the ORDER BY clause or the GROUP BY clause contains + ** references to result-set columns, those references might now be + ** obsolete. So fix them up. + */ + assert( pRhs!=0 || db->mallocFailed ); + if( pRhs ){ + adjustOrderByCol(pSelect->pOrderBy, pRhs); + adjustOrderByCol(pSelect->pGroupBy, pRhs); + for(i=0; inExpr; i++) pRhs->a[i].u.x.iOrderByCol = 0; } #if 0 @@ -157982,6 +158972,147 @@ static Expr *removeUnindexableInClauseTerms( } +#ifndef SQLITE_OMIT_SUBQUERY +/* +** Generate code for a single X IN (....) term of the WHERE clause. +** +** This is a special-case of codeEqualityTerm() that works for IN operators +** only. It is broken out into a subroutine because this case is +** uncommon and by splitting it off into a subroutine, the common case +** runs faster. +** +** The current value for the constraint is left in register iTarget. +** This routine sets up a loop that will iterate over all values of X. +*/ +static SQLITE_NOINLINE void codeINTerm( + Parse *pParse, /* The parsing context */ + WhereTerm *pTerm, /* The term of the WHERE clause to be coded */ + WhereLevel *pLevel, /* The level of the FROM clause we are working on */ + int iEq, /* Index of the equality term within this level */ + int bRev, /* True for reverse-order IN operations */ + int iTarget /* Attempt to leave results in this register */ +){ + Expr *pX = pTerm->pExpr; + int eType = IN_INDEX_NOOP; + int iTab; + struct InLoop *pIn; + WhereLoop *pLoop = pLevel->pWLoop; + Vdbe *v = pParse->pVdbe; + int i; + int nEq = 0; + int *aiMap = 0; + + if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && pLoop->u.btree.pIndex!=0 + && pLoop->u.btree.pIndex->aSortOrder[iEq] + ){ + testcase( iEq==0 ); + testcase( bRev ); + bRev = !bRev; + } + assert( pX->op==TK_IN ); + + for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ + disableTerm(pLevel, pTerm); + return; + } + } + for(i=iEq;inLTerm; i++){ + assert( pLoop->aLTerm[i]!=0 ); + if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; + } + + iTab = 0; + if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); + }else{ + Expr *pExpr = pTerm->pExpr; + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3 *db = pParse->db; + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + pExpr->iTable = iTab; + } + sqlite3ExprDelete(db, pX); + }else{ + int n = sqlite3ExprVectorSize(pX->pLeft); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + } + pX = pExpr; + } + + if( eType==IN_INDEX_INDEX_DESC ){ + testcase( bRev ); + bRev = !bRev; + } + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + VdbeCoverageIf(v, bRev); + VdbeCoverageIf(v, !bRev); + + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + pLoop->wsFlags |= WHERE_IN_ABLE; + if( pLevel->u.in.nIn==0 ){ + pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + } + if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + } + + i = pLevel->u.in.nIn; + pLevel->u.in.nIn += nEq; + pLevel->u.in.aInLoop = + sqlite3WhereRealloc(pTerm->pWC->pWInfo, + pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + pIn = pLevel->u.in.aInLoop; + if( pIn ){ + int iMap = 0; /* Index in aiMap[] */ + pIn += i; + for(i=iEq;inLTerm; i++){ + if( pLoop->aLTerm[i]->pExpr==pX ){ + int iOut = iTarget + i - iEq; + if( eType==IN_INDEX_ROWID ){ + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); + }else{ + int iCol = aiMap ? aiMap[iMap++] : 0; + pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); + } + sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); + if( i==iEq ){ + pIn->iCur = iTab; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + if( iEq>0 ){ + pIn->iBase = iTarget - i; + pIn->nPrefix = i; + }else{ + pIn->nPrefix = 0; + } + }else{ + pIn->eEndLoopOp = OP_Noop; + } + pIn++; + } + } + testcase( iEq>0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); + if( iEq>0 + && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 + ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); + } + }else{ + pLevel->u.in.nIn = 0; + } + sqlite3DbFree(pParse->db, aiMap); +} +#endif + + /* ** Generate code for a single equality term of the WHERE clause. An equality ** term can be either X=expr or X IN (...). pTerm is the term to be @@ -158006,7 +159137,6 @@ static int codeEqualityTerm( int iTarget /* Attempt to leave results in this register */ ){ Expr *pX = pTerm->pExpr; - Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); @@ -158015,125 +159145,12 @@ static int codeEqualityTerm( iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; - sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ - int eType = IN_INDEX_NOOP; - int iTab; - struct InLoop *pIn; - WhereLoop *pLoop = pLevel->pWLoop; - int i; - int nEq = 0; - int *aiMap = 0; - - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 - && pLoop->u.btree.pIndex!=0 - && pLoop->u.btree.pIndex->aSortOrder[iEq] - ){ - testcase( iEq==0 ); - testcase( bRev ); - bRev = !bRev; - } assert( pX->op==TK_IN ); iReg = iTarget; - - for(i=0; iaLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){ - disableTerm(pLevel, pTerm); - return iTarget; - } - } - for(i=iEq;inLTerm; i++){ - assert( pLoop->aLTerm[i]!=0 ); - if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; - } - - iTab = 0; - if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); - }else{ - Expr *pExpr = pTerm->pExpr; - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ - sqlite3 *db = pParse->db; - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); - pExpr->iTable = iTab; - } - sqlite3ExprDelete(db, pX); - }else{ - int n = sqlite3ExprVectorSize(pX->pLeft); - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*MAX(nEq,n)); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); - } - pX = pExpr; - } - - if( eType==IN_INDEX_INDEX_DESC ){ - testcase( bRev ); - bRev = !bRev; - } - sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); - VdbeCoverageIf(v, bRev); - VdbeCoverageIf(v, !bRev); - - assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); - pLoop->wsFlags |= WHERE_IN_ABLE; - if( pLevel->u.in.nIn==0 ){ - pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); - } - if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ - pLoop->wsFlags |= WHERE_IN_EARLYOUT; - } - - i = pLevel->u.in.nIn; - pLevel->u.in.nIn += nEq; - pLevel->u.in.aInLoop = - sqlite3WhereRealloc(pTerm->pWC->pWInfo, - pLevel->u.in.aInLoop, - sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); - pIn = pLevel->u.in.aInLoop; - if( pIn ){ - int iMap = 0; /* Index in aiMap[] */ - pIn += i; - for(i=iEq;inLTerm; i++){ - if( pLoop->aLTerm[i]->pExpr==pX ){ - int iOut = iReg + i - iEq; - if( eType==IN_INDEX_ROWID ){ - pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); - }else{ - int iCol = aiMap ? aiMap[iMap++] : 0; - pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); - } - sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); - if( i==iEq ){ - pIn->iCur = iTab; - pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; - if( iEq>0 ){ - pIn->iBase = iReg - i; - pIn->nPrefix = i; - }else{ - pIn->nPrefix = 0; - } - }else{ - pIn->eEndLoopOp = OP_Noop; - } - pIn++; - } - } - testcase( iEq>0 - && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 - && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); - if( iEq>0 - && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 - ){ - sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); - } - }else{ - pLevel->u.in.nIn = 0; - } - sqlite3DbFree(pParse->db, aiMap); + codeINTerm(pParse, pTerm, pLevel, iEq, bRev, iTarget); #endif } @@ -158805,7 +159822,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; - VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); + VdbeModuleComment((v, "Begin WHERE-loop%d: %s", + iLevel, pTabItem->pSTab->zName)); #if WHERETRACE_ENABLED /* 0x4001 */ if( sqlite3WhereTrace & 0x1 ){ sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", @@ -158860,11 +159878,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ - int regYield = pTabItem->regReturn; - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); + int regYield; + Subquery *pSubq; + assert( pTabItem->fg.isSubquery && pTabItem->u4.pSubq!=0 ); + pSubq = pTabItem->u4.pSubq; + regYield = pSubq->regReturn; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeCoverage(v); - VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); + VdbeComment((v, "next row of %s", pTabItem->pSTab->zName)); pLevel->op = OP_Goto; }else @@ -159593,7 +160615,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; pTerm = pLoop->aLTerm[0]; assert( pTerm!=0 ); @@ -160052,7 +161074,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** least once. This is accomplished by storing the PK for the row in ** both the iMatch index and the regBloom Bloom filter. */ - pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; + pTab = pWInfo->pTabList->a[pLevel->iFrom].pSTab; if( HasRowid(pTab) ){ r = sqlite3GetTempRange(pParse, 2); sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); @@ -160159,7 +161181,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( Bitmask mAll = 0; int k; - ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, pRJ->regReturn); for(k=0; kpTabList->a[pWInfo->a[k].iFrom]; mAll |= pWInfo->a[k].pWLoop->maskSelf; if( pRight->fg.viaCoroutine ){ + Subquery *pSubq; + assert( pRight->fg.isSubquery && pRight->u4.pSubq!=0 ); + pSubq = pRight->u4.pSubq; + assert( pSubq->pSelect!=0 && pSubq->pSelect->pEList!=0 ); sqlite3VdbeAddOp3( - v, OP_Null, 0, pRight->regResult, - pRight->regResult + pRight->pSelect->pEList->nExpr-1 + v, OP_Null, 0, pSubq->regResult, + pSubq->regResult + pSubq->pSelect->pEList->nExpr-1 ); } sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); @@ -160209,7 +161235,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( int nPk; int jmp; int addrCont = sqlite3WhereContinueLabel(pSubWInfo); - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; if( HasRowid(pTab) ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); nPk = 1; @@ -160342,7 +161368,12 @@ static int allowedOp(int op){ assert( TK_LT>TK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS; + assert( TK_INTK_GE ) return 0; + if( op>=TK_EQ ) return 1; + return op==TK_IN || op==TK_ISNULL || op==TK_IS; } /* @@ -160375,15 +161406,16 @@ static u16 exprCommute(Parse *pParse, Expr *pExpr){ static u16 operatorMask(int op){ u16 c; assert( allowedOp(op) ); - if( op==TK_IN ){ + if( op>=TK_EQ ){ + assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); + c = (u16)(WO_EQ<<(op-TK_EQ)); + }else if( op==TK_IN ){ c = WO_IN; }else if( op==TK_ISNULL ){ c = WO_ISNULL; - }else if( op==TK_IS ){ - c = WO_IS; }else{ - assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff ); - c = (u16)(WO_EQ<<(op-TK_EQ)); + assert( op==TK_IS ); + c = WO_IS; } assert( op!=TK_ISNULL || c==WO_ISNULL ); assert( op!=TK_IN || c==WO_IN ); @@ -160454,12 +161486,26 @@ static int isLikeOrGlob( z = (u8*)pRight->u.zToken; } if( z ){ - - /* Count the number of prefix characters prior to the first wildcard */ + /* Count the number of prefix bytes prior to the first wildcard. + ** or U+fffd character. If the underlying database has a UTF16LE + ** encoding, then only consider ASCII characters. Note that the + ** encoding of z[] is UTF8 - we are dealing with only UTF8 here in + ** this code, but the database engine itself might be processing + ** content using a different encoding. */ cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; - if( c==wc[3] && z[cnt]!=0 ) cnt++; + if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){ + cnt++; + }else if( c>=0x80 ){ + const u8 *z2 = z+cnt-1; + if( sqlite3Utf8Read(&z2)==0xfffd || ENC(db)==SQLITE_UTF16LE ){ + cnt--; + break; + }else{ + cnt = (int)(z2-z); + } + } } /* The optimization is possible only if (1) the pattern does not begin @@ -160470,11 +161516,11 @@ static int isLikeOrGlob( ** range search. The third is because the caller assumes that the pattern ** consists of at least one character after all escapes have been ** removed. */ - if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ + if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && ALWAYS(255!=(u8)z[cnt-1]) ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ - *pisComplete = c==wc[0] && z[cnt+1]==0; + *pisComplete = c==wc[0] && z[cnt+1]==0 && ENC(db)!=SQLITE_UTF16LE; /* Get the pattern prefix. Remove all escapes from the prefix. */ pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); @@ -160670,6 +161716,13 @@ static int isAuxiliaryVtabOperator( } } } + }else if( pExpr->op>=TK_EQ ){ + /* Comparison operators are a common case. Save a few comparisons for + ** that common case by terminating early. */ + assert( TK_NE < TK_EQ ); + assert( TK_ISNOT < TK_EQ ); + assert( TK_NOTNULL < TK_EQ ); + return 0; }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; @@ -161186,7 +162239,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ if( ALWAYS(pSrc!=0) ){ int i; for(i=0; inSrc; i++){ - mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); + if( pSrc->a[i].fg.isSubquery ){ + mask |= exprSelectUsage(pMaskSet, pSrc->a[i].u4.pSubq->pSelect); + } if( pSrc->a[i].fg.isUsing==0 ){ mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); } @@ -161224,7 +162279,7 @@ static SQLITE_NOINLINE int exprMightBeIndexed2( int iCur; do{ iCur = pFrom->a[j].iCursor; - for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + for(pIdx=pFrom->a[j].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr==0 ) continue; for(i=0; inKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; @@ -161268,7 +162323,7 @@ static int exprMightBeIndexed( for(i=0; inSrc; i++){ Index *pIdx; - for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + for(pIdx=pFrom->a[i].pSTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->aColExpr ){ return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i); } @@ -161811,7 +162866,7 @@ static void whereAddLimitExpr( Expr *pNew; int iVal = 0; - if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){ + if( sqlite3ExprIsInteger(pExpr, &iVal, pParse) && iVal>=0 ){ Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); if( pVal==0 ) return; ExprSetProperty(pVal, EP_IntValue); @@ -161856,7 +162911,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec assert( p!=0 && p->pLimit!=0 ); /* 1 -- checked by caller */ if( p->pGroupBy==0 && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ - && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ + && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pSTab)) /* 3 */ ){ ExprList *pOrderBy = p->pOrderBy; int iCsr = p->pSrc->a[0].iCursor; @@ -162077,7 +163132,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( Expr *pColRef; Expr *pTerm; if( pItem->fg.isTabFunc==0 ) return; - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 ); pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; @@ -162761,7 +163816,7 @@ static int isDistinctRedundant( ** clause is redundant. */ if( pTabList->nSrc!=1 ) return 0; iBase = pTabList->a[0].iCursor; - pTab = pTabList->a[0].pTab; + pTab = pTabList->a[0].pSTab; /* If any of the expressions is an IPK column on table iBase, then return ** true. Note: The (p->iTable==iBase) part of this test may be false if the @@ -162836,6 +163891,12 @@ static void translateColumnToCopy( VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); if( pParse->db->mallocFailed ) return; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("CHECKING for column-to-copy on cursor %d for %d..%d\n", + iTabCur, iStart, iEnd); + } +#endif for(; iStartp1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ @@ -162957,6 +164018,40 @@ static int constraintCompatibleWithOuterJoin( return 1; } +#ifndef SQLITE_OMIT_AUTOMATIC_INDEX +/* +** Return true if column iCol of table pTab seem like it might be a +** good column to use as part of a query-time index. +** +** Current algorithm (subject to improvement!): +** +** 1. If iCol is already the left-most column of some other index, +** then return false. +** +** 2. If iCol is part of an existing index that has an aiRowLogEst of +** more than 20, then return false. +** +** 3. If no disqualifying conditions above are found, return true. +*/ +static SQLITE_NOINLINE int columnIsGoodIndexCandidate( + const Table *pTab, + int iCol +){ + const Index *pIdx; + for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){ + int j; + for(j=0; jnKeyCol; j++){ + if( pIdx->aiColumn[j]==iCol ){ + if( j==0 ) return 0; + if( pIdx->hasStat1 && pIdx->aiRowLogEst[j+1]>20 ) return 0; + break; + } + } + } + return 1; +} +#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ + #ifndef SQLITE_OMIT_AUTOMATIC_INDEX @@ -162971,6 +164066,8 @@ static int termCanDriveIndex( const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; + int leftCol; + if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; assert( (pSrc->fg.jointype & JT_RIGHT)==0 ); @@ -162981,11 +164078,12 @@ static int termCanDriveIndex( } if( (pTerm->prereqRight & notReady)!=0 ) return 0; assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - if( pTerm->u.x.leftColumn<0 ) return 0; - aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; + leftCol = pTerm->u.x.leftColumn; + if( leftCol<0 ) return 0; + aff = pSrc->pSTab->aCol[leftCol].affinity; if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; testcase( pTerm->pExpr->op==TK_IS ); - return 1; + return columnIsGoodIndexCandidate(pSrc->pSTab, leftCol); } #endif @@ -163093,7 +164191,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( nKeyCol = 0; pTabList = pWC->pWInfo->pTabList; pSrc = &pTabList->a[pLevel->iFrom]; - pTable = pSrc->pTab; + pTable = pSrc->pSTab; pWCEnd = &pWC->a[pWC->nTerm]; pLoop = pLevel->pWLoop; idxCols = 0; @@ -163235,12 +164333,17 @@ static SQLITE_NOINLINE void constructAutomaticIndex( /* Fill the automatic index with content */ assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] ); if( pSrc->fg.viaCoroutine ){ - int regYield = pSrc->regReturn; + int regYield; + Subquery *pSubq; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + assert( pSubq!=0 ); + regYield = pSubq->regReturn; addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); - sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSubq->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); - VdbeComment((v, "next row of %s", pSrc->pTab->zName)); + VdbeComment((v, "next row of %s", pSrc->pSTab->zName)); }else{ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } @@ -163262,11 +164365,12 @@ static SQLITE_NOINLINE void constructAutomaticIndex( sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pSrc->fg.viaCoroutine ){ + assert( pSrc->fg.isSubquery && pSrc->u4.pSubq!=0 ); sqlite3VdbeChangeP2(v, addrCounter, regBase+n); testcase( pParse->db->mallocFailed ); assert( pLevel->iIdxCur>0 ); translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, - pSrc->regResult, pLevel->iIdxCur); + pSrc->u4.pSubq->regResult, pLevel->iIdxCur); sqlite3VdbeGoto(v, addrTop); pSrc->fg.viaCoroutine = 0; }else{ @@ -163357,7 +164461,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( iSrc = pLevel->iFrom; pItem = &pTabList->a[iSrc]; assert( pItem!=0 ); - pTab = pItem->pTab; + pTab = pItem->pSTab; assert( pTab!=0 ); sz = sqlite3LogEstToInt(pTab->nRowLogEst); if( sz<10000 ){ @@ -163388,7 +164492,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( int r1 = sqlite3GetTempRange(pParse, n); int jj; for(jj=0; jjpTable==pItem->pTab ); + assert( pIdx->pTable==pItem->pSTab ); sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj); } sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); @@ -163426,6 +164530,20 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( #ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return term iTerm of the WhereClause passed as the first argument. Terms +** are numbered from 0 upwards, starting with the terms in pWC->a[], then +** those in pWC->pOuter->a[] (if any), and so on. +*/ +static WhereTerm *termFromWhereClause(WhereClause *pWC, int iTerm){ + WhereClause *p; + for(p=pWC; p; p=p->pOuter){ + if( iTermnTerm ) return &p->a[iTerm]; + iTerm -= p->nTerm; + } + return 0; +} + /* ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure @@ -163452,9 +164570,10 @@ static sqlite3_index_info *allocateIndexInfo( const Table *pTab; int eDistinct = 0; ExprList *pOrderBy = pWInfo->pOrderBy; + WhereClause *p; assert( pSrc!=0 ); - pTab = pSrc->pTab; + pTab = pSrc->pSTab; assert( pTab!=0 ); assert( IsVirtual(pTab) ); @@ -163462,28 +164581,30 @@ static sqlite3_index_info *allocateIndexInfo( ** Mark each term with the TERM_OK flag. Set nTerm to the number of ** terms found. */ - for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - pTerm->wtFlags &= ~TERM_OK; - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); - testcase( pTerm->eOperator & WO_IN ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; + for(p=pWC, nTerm=0; p; p=p->pOuter){ + for(i=0, pTerm=p->a; inTerm; i++, pTerm++){ + pTerm->wtFlags &= ~TERM_OK; + if( pTerm->leftCursor != pSrc->iCursor ) continue; + if( pTerm->prereqRight & mUnusable ) continue; + assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); + testcase( pTerm->eOperator & WO_IN ); + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IS ); + testcase( pTerm->eOperator & WO_ALL ); + if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; + if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); - assert( pTerm->u.x.leftColumn>=XN_ROWID ); - assert( pTerm->u.x.leftColumnnCol ); - if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 - && !constraintCompatibleWithOuterJoin(pTerm,pSrc) - ){ - continue; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pTerm->u.x.leftColumn>=XN_ROWID ); + assert( pTerm->u.x.leftColumnnCol ); + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 + && !constraintCompatibleWithOuterJoin(pTerm,pSrc) + ){ + continue; + } + nTerm++; + pTerm->wtFlags |= TERM_OK; } - nTerm++; - pTerm->wtFlags |= TERM_OK; } /* If the ORDER BY clause contains only columns in the current @@ -163558,53 +164679,69 @@ static sqlite3_index_info *allocateIndexInfo( pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; + pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; + if( HasRowid(pTab)==0 ){ + /* Ensure that all bits associated with PK columns are set. This is to + ** ensure they are available for cases like RIGHT joins or OR loops. */ + Index *pPk = sqlite3PrimaryKeyIndex((Table*)pTab); + assert( pPk!=0 ); + for(i=0; inKeyCol; i++){ + int iCol = pPk->aiColumn[i]; + assert( iCol>=0 ); + if( iCol>=BMS-1 ) iCol = BMS-1; + pIdxInfo->colUsed |= MASKBIT(iCol); + } + } pHidden->pWC = pWC; pHidden->pParse = pParse; pHidden->eDistinct = eDistinct; pHidden->mIn = 0; - for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - u16 op; - if( (pTerm->wtFlags & TERM_OK)==0 ) continue; - pIdxCons[j].iColumn = pTerm->u.x.leftColumn; - pIdxCons[j].iTermOffset = i; - op = pTerm->eOperator & WO_ALL; - if( op==WO_IN ){ - if( (pTerm->wtFlags & TERM_SLICE)==0 ){ - pHidden->mIn |= SMASKBIT32(j); - } - op = WO_EQ; - } - if( op==WO_AUX ){ - pIdxCons[j].op = pTerm->eMatchOp; - }else if( op & (WO_ISNULL|WO_IS) ){ - if( op==WO_ISNULL ){ - pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; - }else{ - pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; - } - }else{ - pIdxCons[j].op = (u8)op; - /* The direct assignment in the previous line is possible only because - ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The - ** following asserts verify this fact. */ - assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); - assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); - assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); - assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); - assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); - assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); - - if( op & (WO_LT|WO_LE|WO_GT|WO_GE) - && sqlite3ExprIsVector(pTerm->pExpr->pRight) - ){ - testcase( j!=i ); - if( j<16 ) mNoOmit |= (1 << j); - if( op==WO_LT ) pIdxCons[j].op = WO_LE; - if( op==WO_GT ) pIdxCons[j].op = WO_GE; + for(p=pWC, i=j=0; p; p=p->pOuter){ + int nLast = i+p->nTerm;; + for(pTerm=p->a; iwtFlags & TERM_OK)==0 ) continue; + pIdxCons[j].iColumn = pTerm->u.x.leftColumn; + pIdxCons[j].iTermOffset = i; + op = pTerm->eOperator & WO_ALL; + if( op==WO_IN ){ + if( (pTerm->wtFlags & TERM_SLICE)==0 ){ + pHidden->mIn |= SMASKBIT32(j); + } + op = WO_EQ; + } + if( op==WO_AUX ){ + pIdxCons[j].op = pTerm->eMatchOp; + }else if( op & (WO_ISNULL|WO_IS) ){ + if( op==WO_ISNULL ){ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL; + }else{ + pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS; + } + }else{ + pIdxCons[j].op = (u8)op; + /* The direct assignment in the previous line is possible only because + ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The + ** following asserts verify this fact. */ + assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); + assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); + assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); + assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); + assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); + assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); + + if( op & (WO_LT|WO_LE|WO_GT|WO_GE) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) + ){ + testcase( j!=i ); + if( j<16 ) mNoOmit |= (1 << j); + if( op==WO_LT ) pIdxCons[j].op = WO_LE; + if( op==WO_GT ) pIdxCons[j].op = WO_GE; + } } - } - j++; + j++; + } } assert( j==nTerm ); pIdxInfo->nConstraint = j; @@ -163624,6 +164761,17 @@ static sqlite3_index_info *allocateIndexInfo( return pIdxInfo; } +/* +** Free and zero the sqlite3_index_info.idxStr value if needed. +*/ +static void freeIdxStr(sqlite3_index_info *pIdxInfo){ + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->needToFreeIdxStr = 0; + } +} + /* ** Free an sqlite3_index_info structure allocated by allocateIndexInfo() ** and possibly modified by xBestIndex methods. @@ -163639,6 +164787,7 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ pHidden->aRhs[i] = 0; } + freeIdxStr(pIdxInfo); sqlite3DbFree(db, pIdxInfo); } @@ -163659,9 +164808,11 @@ static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ ** that this is required. */ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ - sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; int rc; + sqlite3_vtab *pVtab; + assert( IsVirtual(pTab) ); + pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; whereTraceIndexInfoInputs(p, pTab); pParse->db->nSchemaLock++; rc = pVtab->pModule->xBestIndex(pVtab, p); @@ -164432,7 +165583,7 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; SrcItem *pItem = pWInfo->pTabList->a + p->iTab; - Table *pTab = pItem->pTab; + Table *pTab = pItem->pSTab; Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); @@ -164604,7 +165755,7 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ ** and Y has additional constraints that might speed the search that X lacks ** but the cost of running X is not more than the cost of running Y. ** -** In other words, return true if the cost relationwship between X and Y +** In other words, return true if the cost relationship between X and Y ** is inverted and needs to be adjusted. ** ** Case 1: @@ -164990,7 +166141,7 @@ static void whereLoopOutputAdjust( Expr *pRight = pTerm->pExpr->pRight; int k = 0; testcase( pTerm->pExpr->op==TK_IS ); - if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ + if( sqlite3ExprIsInteger(pRight, &k, 0) && k>=(-1) && k<=1 ){ k = 10; }else{ k = 20; @@ -165287,7 +166438,7 @@ static int whereLoopAddBtreeIndex( || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ if( iCol==XN_ROWID || pProbe->uniqNotNull - || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) + || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ)) ){ pNew->wsFlags |= WHERE_ONEROW; }else{ @@ -165420,7 +166571,7 @@ static int whereLoopAddBtreeIndex( ** 2. Stepping forward in the index pNew->nOut times to find all ** additional matching entries. */ - assert( pSrc->pTab->szTabRow>0 ); + assert( pSrc->pSTab->szTabRow>0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* The pProbe->szIdxRow is low for an IPK table since the interior ** pages are small. Thus szIdxRow gives a good estimate of seek cost. @@ -165428,7 +166579,7 @@ static int whereLoopAddBtreeIndex( ** under-estimate the scanning cost. */ rCostIdx = pNew->nOut + 16; }else{ - rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; + rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pSTab->szTabRow; } rCostIdx = sqlite3LogEstAdd(rLogSize, rCostIdx); @@ -165893,9 +167044,9 @@ static int whereLoopAddBtree( pWInfo = pBuilder->pWInfo; pTabList = pWInfo->pTabList; pSrc = pTabList->a + pNew->iTab; - pTab = pSrc->pTab; + pTab = pSrc->pSTab; pWC = pBuilder->pWC; - assert( !IsVirtual(pSrc->pTab) ); + assert( !IsVirtual(pSrc->pSTab) ); if( pSrc->fg.isIndexedBy ){ assert( pSrc->fg.isCte==0 ); @@ -165920,7 +167071,7 @@ static int whereLoopAddBtree( sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; - pFirst = pSrc->pTab->pIndex; + pFirst = pSrc->pSTab->pIndex; if( pSrc->fg.notIndexed==0 ){ /* The real indices of the table are only considered if the ** NOT INDEXED qualifier is omitted from the FROM clause */ @@ -166010,6 +167161,7 @@ static int whereLoopAddBtree( pNew->prereq = mPrereq; pNew->nOut = rSize; pNew->u.btree.pIndex = pProbe; + pNew->u.btree.pOrderBy = 0; b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ @@ -166039,6 +167191,10 @@ static int whereLoopAddBtree( #endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); + if( pSrc->fg.isSubquery ){ + if( pSrc->fg.viaCoroutine ) pNew->wsFlags |= WHERE_COROUTINE; + pNew->u.btree.pOrderBy = pSrc->u4.pSubq->pSelect->pOrderBy; + } rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; @@ -166241,7 +167397,7 @@ static int whereLoopAddVirtualOne( ** arguments mUsable and mExclude. */ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; ia[pIdxCons->iTermOffset]; + WhereTerm *pTerm = termFromWhereClause(pWC, pIdxCons->iTermOffset); pIdxCons->usable = 0; if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 @@ -166260,11 +167416,10 @@ static int whereLoopAddVirtualOne( pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; - pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ - rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); + rc = vtabBestIndex(pParse, pSrc->pSTab, pIdxInfo); if( rc ){ if( rc==SQLITE_CONSTRAINT ){ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means @@ -166272,6 +167427,7 @@ static int whereLoopAddVirtualOne( ** Make no entries in the loop table. */ WHERETRACE(0xffffffff, (" ^^^^--- non-viable plan rejected!\n")); + freeIdxStr(pIdxInfo); return SQLITE_OK; } return rc; @@ -166289,18 +167445,17 @@ static int whereLoopAddVirtualOne( int j = pIdxCons->iTermOffset; if( iTerm>=nConstraint || j<0 - || j>=pWC->nTerm + || (pTerm = termFromWhereClause(pWC, j))==0 || pNew->aLTerm[iTerm]!=0 || pIdxCons->usable==0 ){ - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - testcase( pIdxInfo->needToFreeIdxStr ); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); return SQLITE_ERROR; } testcase( iTerm==nConstraint-1 ); testcase( j==0 ); testcase( j==pWC->nTerm-1 ); - pTerm = &pWC->a[j]; pNew->prereq |= pTerm->prereqRight; assert( iTermnLSlot ); pNew->aLTerm[iTerm] = pTerm; @@ -166345,11 +167500,7 @@ static int whereLoopAddVirtualOne( ** the plan cannot be used. In these cases set variable *pbRetryLimit ** to true to tell the caller to retry with LIMIT and OFFSET ** disabled. */ - if( pIdxInfo->needToFreeIdxStr ){ - sqlite3_free(pIdxInfo->idxStr); - pIdxInfo->idxStr = 0; - pIdxInfo->needToFreeIdxStr = 0; - } + freeIdxStr(pIdxInfo); *pbRetryLimit = 1; return SQLITE_OK; } @@ -166361,8 +167512,8 @@ static int whereLoopAddVirtualOne( if( pNew->aLTerm[i]==0 ){ /* The non-zero argvIdx values must be contiguous. Raise an ** error if they are not */ - sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); - testcase( pIdxInfo->needToFreeIdxStr ); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pSTab->zName); + freeIdxStr(pIdxInfo); return SQLITE_ERROR; } } @@ -166373,6 +167524,7 @@ static int whereLoopAddVirtualOne( pNew->u.vtab.idxStr = pIdxInfo->idxStr; pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? pIdxInfo->nOrderBy : 0); + pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0; pNew->rSetup = 0; pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); @@ -166417,7 +167569,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int if( iCons>=0 && iConsnConstraint ){ CollSeq *pC = 0; int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; - Expr *pX = pHidden->pWC->a[iTerm].pExpr; + Expr *pX = termFromWhereClause(pHidden->pWC, iTerm)->pExpr; if( pX->pLeft ){ pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); } @@ -166463,7 +167615,9 @@ SQLITE_API int sqlite3_vtab_rhs_value( rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ - WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; + WhereTerm *pTerm = termFromWhereClause( + pH->pWC, pIdxInfo->aConstraint[iCons].iTermOffset + ); rc = sqlite3ValueFromExpr( pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), SQLITE_AFF_BLOB, &pH->aRhs[iCons] @@ -166561,7 +167715,7 @@ static int whereLoopAddVirtual( pWC = pBuilder->pWC; pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; - assert( IsVirtual(pSrc->pTab) ); + assert( IsVirtual(pSrc->pSTab) ); p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); if( p==0 ) return SQLITE_NOMEM_BKPT; pNew->rSetup = 0; @@ -166575,7 +167729,7 @@ static int whereLoopAddVirtual( } /* First call xBestIndex() with all constraints usable. */ - WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); + WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pSTab->zName)); WHERETRACE(0x800, (" VirtualOne: all usable\n")); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry @@ -166619,9 +167773,8 @@ static int whereLoopAddVirtual( Bitmask mNext = ALLBITS; assert( mNext>0 ); for(i=0; ia[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq - ); + int iTerm = p->aConstraint[i].iTermOffset; + Bitmask mThis = termFromWhereClause(pWC, iTerm)->prereqRight & ~mPrereq; if( mThis>mPrev && mThisneedToFreeIdxStr ) sqlite3_free(p->idxStr); freeIndexInfo(pParse->db, p); - WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); + WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pSTab->zName, rc)); return rc; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -166731,7 +167883,7 @@ static int whereLoopAddOr( } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ + if( IsVirtual(pItem->pSTab) ){ rc = whereLoopAddVirtual(&sSubBuild, mPrereq, mUnusable); }else #endif @@ -166845,7 +167997,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ mPrereq = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pItem->pTab) ){ + if( IsVirtual(pItem->pSTab) ){ SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_OUTER|JT_CROSS)) ){ @@ -166877,6 +168029,97 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ return rc; } +/* Implementation of the order-by-subquery optimization: +** +** WhereLoop pLoop, which the iLoop-th term of the nested loop, is really +** a subquery or CTE that has an ORDER BY clause. See if any of the terms +** in the subquery ORDER BY clause will satisfy pOrderBy from the outer +** query. Mark off all satisfied terms (by setting bits in *pOBSat) and +** return TRUE if they do. If not, return false. +** +** Example: +** +** CREATE TABLE t1(a,b,c, PRIMARY KEY(a,b)); +** CREATE TABLE t2(x,y); +** WITH t3(p,q) AS MATERIALIZED (SELECT x+y, x-y FROM t2 ORDER BY x+y) +** SELECT * FROM t3 JOIN t1 ON a=q ORDER BY p, b; +** +** The CTE named "t3" comes out in the natural order of "p", so the first +** first them of "ORDER BY p,b" is satisfied by a sequential scan of "t3" +** and sorting only needs to occur on the second term "b". +** +** Limitations: +** +** (1) The optimization is not applied if the outer ORDER BY contains +** a COLLATE clause. The optimization might be applied if the +** outer ORDER BY uses NULLS FIRST, NULLS LAST, ASC, and/or DESC as +** long as the subquery ORDER BY does the same. But if the +** outer ORDER BY uses COLLATE, even a redundant COLLATE, the +** optimization is bypassed. +** +** (2) The subquery ORDER BY terms must exactly match subquery result +** columns, including any COLLATE annotations. This routine relies +** on iOrderByCol to do matching between order by terms and result +** columns, and iOrderByCol will not be set if the result column +** and ORDER BY collations differ. +** +** (3) The subquery and outer ORDER BY can be in opposite directions as +** long as the subquery is materialized. If the subquery is +** implemented as a co-routine, the sort orders must be in the same +** direction because there is no way to run a co-routine backwards. +*/ +static SQLITE_NOINLINE int wherePathMatchSubqueryOB( + WhereInfo *pWInfo, /* The WHERE clause */ + WhereLoop *pLoop, /* The nested loop term that is a subquery */ + int iLoop, /* Which level of the nested loop. 0==outermost */ + int iCur, /* Cursor used by the this loop */ + ExprList *pOrderBy, /* The ORDER BY clause on the whole query */ + Bitmask *pRevMask, /* When loops need to go in reverse order */ + Bitmask *pOBSat /* Which terms of pOrderBy are satisfied so far */ +){ + int iOB; /* Index into pOrderBy->a[] */ + int jSub; /* Index into pSubOB->a[] */ + u8 rev = 0; /* True if iOB and jSub sort in opposite directions */ + u8 revIdx = 0; /* Sort direction for jSub */ + Expr *pOBExpr; /* Current term of outer ORDER BY */ + ExprList *pSubOB; /* Complete ORDER BY on the subquery */ + + pSubOB = pLoop->u.btree.pOrderBy; + assert( pSubOB!=0 ); + for(iOB=0; (MASKBIT(iOB) & *pOBSat)!=0; iOB++){} + for(jSub=0; jSubnExpr && iOBnExpr; jSub++, iOB++){ + if( pSubOB->a[jSub].u.x.iOrderByCol==0 ) break; + pOBExpr = pOrderBy->a[iOB].pExpr; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) break; + if( pOBExpr->iTable!=iCur ) break; + if( pOBExpr->iColumn!=pSubOB->a[jSub].u.x.iOrderByCol-1 ) break; + if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){ + u8 sfOB = pOrderBy->a[iOB].fg.sortFlags; /* sortFlags for iOB */ + u8 sfSub = pSubOB->a[jSub].fg.sortFlags; /* sortFlags for jSub */ + if( (sfSub & KEYINFO_ORDER_BIGNULL) != (sfOB & KEYINFO_ORDER_BIGNULL) ){ + break; + } + revIdx = sfSub & KEYINFO_ORDER_DESC; + if( jSub>0 ){ + if( (rev^revIdx)!=(sfOB & KEYINFO_ORDER_DESC) ){ + break; + } + }else{ + rev = revIdx ^ (sfOB & KEYINFO_ORDER_DESC); + if( rev ){ + if( (pLoop->wsFlags & WHERE_COROUTINE)!=0 ){ + /* Cannot run a co-routine in reverse order */ + break; + } + *pRevMask |= MASKBIT(iLoop); + } + } + } + *pOBSat |= MASKBIT(iOB); + } + return jSub>0; +} + /* ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** parameters) to see if it outputs rows in the requested ORDER BY @@ -167022,9 +168265,18 @@ static i8 wherePathSatisfiesOrderBy( if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){ if( pLoop->wsFlags & WHERE_IPK ){ + if( pLoop->u.btree.pOrderBy + && OptimizationEnabled(db, SQLITE_OrderBySubq) + && wherePathMatchSubqueryOB(pWInfo,pLoop,iLoop,iCur, + pOrderBy,pRevMask, &obSat) + ){ + nColumn = 0; + isOrderDistinct = 0; + }else{ + nColumn = 1; + } pIndex = 0; nKeyCol = 0; - nColumn = 1; }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){ return 0; }else{ @@ -167034,7 +168286,7 @@ static i8 wherePathSatisfiesOrderBy( assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); /* All relevant terms of the index must also be non-NULL in order - ** for isOrderDistinct to be true. So the isOrderDistint value + ** for isOrderDistinct to be true. So the isOrderDistinct value ** computed here might be a false positive. Corrections will be ** made at tag-20210426-1 below */ isOrderDistinct = IsUniqueIndex(pIndex) @@ -167119,7 +168371,7 @@ static i8 wherePathSatisfiesOrderBy( } /* Find the ORDER BY term that corresponds to the j-th column - ** of the index and mark that ORDER BY term off + ** of the index and mark that ORDER BY term having been satisfied. */ isMatch = 0; for(i=0; bOnce && inOutStarDelta and the cost adjustment +** for each WhereLoop is stored in its rStarDelta field. +*/ +static int computeMxChoice(WhereInfo *pWInfo, LogEst nRowEst){ + int nLoop = pWInfo->nLevel; /* Number of terms in the join */ + if( nRowEst==0 && nLoop>=5 ){ + /* Check to see if we are dealing with a star schema and if so, reduce + ** the cost of fact tables relative to dimension tables, as a heuristic + ** to help keep the fact tables in outer loops. + */ + int iLoop; /* Counter over join terms */ + Bitmask m; /* Bitmask for current loop */ + assert( pWInfo->nOutStarDelta==0 ); + for(iLoop=0, m=1; iLooppLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( (pWLoop->prereq & m)!=0 && (pWLoop->maskSelf & mSeen)==0 ){ + nDep++; + mSeen |= pWLoop->maskSelf; + } + } + if( nDep<=3 ) continue; + rDelta = 15*(nDep-3); +#ifdef WHERETRACE_ENABLED /* 0x4 */ + if( sqlite3WhereTrace&0x4 ){ + SrcItem *pItem = pWInfo->pTabList->a + iLoop; + sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n", + pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName, + nDep, rDelta); + } +#endif + if( pWInfo->nOutStarDelta==0 ){ + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + pWLoop->rStarDelta = 0; + } + } + pWInfo->nOutStarDelta += rDelta; + for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){ + if( pWLoop->maskSelf==m ){ + pWLoop->rRun -= rDelta; + pWLoop->nOut -= rDelta; + pWLoop->rStarDelta = rDelta; + } + } + } + } + return pWInfo->nOutStarDelta>0 ? 18 : 12; +} + /* ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine ** attempts to find the lowest cost path that visits each WhereLoop @@ -167361,13 +168690,25 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pParse = pWInfo->pParse; nLoop = pWInfo->nLevel; - /* TUNING: For simple queries, only the best path is tracked. - ** For 2-way joins, the 5 best paths are followed. - ** For joins of 3 or more tables, track the 10 best paths */ - mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); - assert( nLoop<=pWInfo->pTabList->nSrc ); WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", nRowEst, pParse->nQueryLoop)); + /* TUNING: mxChoice is the maximum number of possible paths to preserve + ** at each step. Based on the number of loops in the FROM clause: + ** + ** nLoop mxChoice + ** ----- -------- + ** 1 1 // the most common case + ** 2 5 + ** 3+ 12 or 18 // see computeMxChoice() + */ + if( nLoop<=1 ){ + mxChoice = 1; + }else if( nLoop==2 ){ + mxChoice = 5; + }else{ + mxChoice = computeMxChoice(pWInfo, nRowEst); + } + assert( nLoop<=pWInfo->pTabList->nSrc ); /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this ** case the purpose of this call is to estimate the number of rows returned @@ -167450,7 +168791,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ - rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); + rUnsorted = pWLoop->rRun + pFrom->nRow; + if( pWLoop->rSetup ){ + rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup, rUnsorted); + } rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); nOut = pFrom->nRow + pWLoop->nOut; maskNew = pFrom->maskLoop | pWLoop->maskSelf; @@ -167495,6 +168839,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range ** of legal values for isOrdered, -1..64. */ + testcase( nTo==0 ); for(jj=0, pTo=aTo; jjmaskLoop==maskNew && ((pTo->isOrdered^isOrdered)&0x80)==0 @@ -167611,16 +168956,28 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ #ifdef WHERETRACE_ENABLED /* >=2 */ if( sqlite3WhereTrace & 0x02 ){ + LogEst rMin, rFloor = 0; + int nDone = 0; sqlite3DebugPrintf("---- after round %d ----\n", iLoop); - for(ii=0, pTo=aTo; iirCost, pTo->nRow, - pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); - if( pTo->isOrdered>0 ){ - sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); - }else{ - sqlite3DebugPrintf("\n"); + while( nDonerCost>rFloor && pTo->rCostrCost; + } + for(ii=0, pTo=aTo; iirCost==rMin ){ + sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c", + wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, + pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); + if( pTo->isOrdered>0 ){ + sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); + }else{ + sqlite3DebugPrintf("\n"); + } + nDone++; + } } + rFloor = rMin; } } #endif @@ -167715,7 +169072,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } } - pWInfo->nRowOut = pFrom->nRow; + pWInfo->nRowOut = pFrom->nRow + pWInfo->nOutStarDelta; /* Free temporary memory and return success */ sqlite3StackFreeNN(pParse->db, pSpace); @@ -167826,7 +169183,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; assert( pWInfo->pTabList->nSrc>=1 ); pItem = pWInfo->pTabList->a; - pTab = pItem->pTab; + pTab = pItem->pSTab; if( IsVirtual(pTab) ) return 0; if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){ testcase( pItem->fg.isIndexedBy ); @@ -168016,6 +169373,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( WhereTerm *pTerm, *pEnd; SrcItem *pItem; WhereLoop *pLoop; + Bitmask m1; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue; @@ -168042,7 +169400,10 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( } } if( pTerm drop loop %c not used\n", pLoop->cId)); + WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId)); + m1 = MASKBIT(i)-1; + testcase( ((pWInfo->revMask>>1) & ~m1)!=0 ); + pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1); notReady &= ~pLoop->maskSelf; for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ @@ -168089,7 +169450,7 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( WhereLoop *pLoop = pWInfo->a[i].pWLoop; const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; - Table *pTab = pItem->pTab; + Table *pTab = pItem->pSTab; if( (pTab->tabFlags & TF_HasStat1)==0 ) break; pTab->tabFlags |= TF_MaybeReanalyze; if( i>=1 @@ -168109,61 +169470,10 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( } } nSearch += pLoop->nOut; + if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta; } } -/* -** Expression Node callback for sqlite3ExprCanReturnSubtype(). -** -** Only a function call is able to return a subtype. So if the node -** is not a function call, return WRC_Prune immediately. -** -** A function call is able to return a subtype if it has the -** SQLITE_RESULT_SUBTYPE property. -** -** Assume that every function is able to pass-through a subtype from -** one of its argument (using sqlite3_result_value()). Most functions -** are not this way, but we don't have a mechanism to distinguish those -** that are from those that are not, so assume they all work this way. -** That means that if one of its arguments is another function and that -** other function is able to return a subtype, then this function is -** able to return a subtype. -*/ -static int exprNodeCanReturnSubtype(Walker *pWalker, Expr *pExpr){ - int n; - FuncDef *pDef; - sqlite3 *db; - if( pExpr->op!=TK_FUNCTION ){ - return WRC_Prune; - } - assert( ExprUseXList(pExpr) ); - db = pWalker->pParse->db; - n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; - pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0); - if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){ - pWalker->eCode = 1; - return WRC_Prune; - } - return WRC_Continue; -} - -/* -** Return TRUE if expression pExpr is able to return a subtype. -** -** A TRUE return does not guarantee that a subtype will be returned. -** It only indicates that a subtype return is possible. False positives -** are acceptable as they only disable an optimization. False negatives, -** on the other hand, can lead to incorrect answers. -*/ -static int sqlite3ExprCanReturnSubtype(Parse *pParse, Expr *pExpr){ - Walker w; - memset(&w, 0, sizeof(w)); - w.pParse = pParse; - w.xExprCallback = exprNodeCanReturnSubtype; - sqlite3WalkExpr(&w, pExpr); - return w.eCode; -} - /* ** The index pIdx is used by a query and contains one or more expressions. ** In other words pIdx is an index on an expression. iIdxCur is the cursor @@ -168197,12 +169507,6 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( continue; } if( sqlite3ExprIsConstant(0,pExpr) ) continue; - if( pExpr->op==TK_FUNCTION && sqlite3ExprCanReturnSubtype(pParse,pExpr) ){ - /* Functions that might set a subtype should not be replaced by the - ** value taken from an expression index since the index omits the - ** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */ - continue; - } p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr)); if( p==0 ) break; p->pIENext = pParse->pIdxEpr; @@ -168245,8 +169549,8 @@ static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ SrcItem *pItem = &pWInfo->pTabList->a[ii]; if( !pItem->fg.isCte || pItem->u2.pCteUse->eM10d!=M10d_Yes - || NEVER(pItem->pSelect==0) - || pItem->pSelect->pOrderBy==0 + || NEVER(pItem->fg.isSubquery==0) + || pItem->u4.pSubq->pSelect->pOrderBy==0 ){ pWInfo->revMask |= MASKBIT(ii); } @@ -168625,7 +169929,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( db->mallocFailed ) goto whereBeginError; if( pWInfo->pOrderBy ){ whereInterstageHeuristic(pWInfo); - wherePathSolver(pWInfo, pWInfo->nRowOut+1); + wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } @@ -168736,15 +170040,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ int wsFlags = pWInfo->a[0].pWLoop->wsFlags; int bOnerow = (wsFlags & WHERE_ONEROW)!=0; - assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) ); + assert( !(wsFlags&WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pSTab) ); if( bOnerow || ( 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) - && !IsVirtual(pTabList->a[0].pTab) + && !IsVirtual(pTabList->a[0].pSTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) && OptimizationEnabled(db, SQLITE_OnePass) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; - if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ + if( HasRowid(pTabList->a[0].pSTab) && (wsFlags & WHERE_IDX_ONLY) ){ if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ bFordelete = OPFLAG_FORDELETE; } @@ -168762,7 +170066,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( SrcItem *pTabItem; pTabItem = &pTabList->a[pLevel->iFrom]; - pTab = pTabItem->pTab; + pTab = pTabItem->pSTab; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ @@ -168833,7 +170137,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( iIndexCur = pLevel->iTabCur; op = 0; }else if( pWInfo->eOnePass!=ONEPASS_OFF ){ - Index *pJ = pTabItem->pTab->pIndex; + Index *pJ = pTabItem->pSTab->pIndex; iIndexCur = iAuxArg; assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); while( ALWAYS(pJ) && pJ!=pIx ){ @@ -168900,7 +170204,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); - assert( pTab==pTabItem->pTab ); + assert( pTab==pTabItem->pSTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); @@ -168939,13 +170243,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( wsFlags = pLevel->pWLoop->wsFlags; pSrc = &pTabList->a[pLevel->iFrom]; if( pSrc->fg.isMaterialized ){ - if( pSrc->fg.isCorrelated ){ - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); + Subquery *pSubq; + int iOnce = 0; + assert( pSrc->fg.isSubquery ); + pSubq = pSrc->u4.pSubq; + if( pSrc->fg.isCorrelated==0 ){ + iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); }else{ - int iOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub); - sqlite3VdbeJumpHere(v, iOnce); + iOnce = 0; } + sqlite3VdbeAddOp2(v, OP_Gosub, pSubq->regReturn, pSubq->addrFillSub); + VdbeComment((v, "materialize %!S", pSrc)); + if( iOnce ) sqlite3VdbeJumpHere(v, iOnce); } assert( pTabList == pWInfo->pTabList ); if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ @@ -169158,9 +170467,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pLevel->iTabCur==pSrc->iCursor ); if( pSrc->fg.viaCoroutine ){ int m, n; - n = pSrc->regResult; - assert( pSrc->pTab!=0 ); - m = pSrc->pTab->nCol; + assert( pSrc->fg.isSubquery ); + n = pSrc->u4.pSubq->regResult; + assert( pSrc->pSTab!=0 ); + m = pSrc->pSTab->nCol; sqlite3VdbeAddOp3(v, OP_Null, 0, n, n+m-1); } sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); @@ -169184,7 +170494,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeJumpHere(v, addr); } VdbeModuleComment((v, "End WHERE-loop%d: %s", i, - pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); + pWInfo->pTabList->a[pLevel->iFrom].pSTab->zName)); } assert( pWInfo->nLevel<=pTabList->nSrc ); @@ -169193,7 +170503,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeOp *pOp, *pLastOp; Index *pIdx = 0; SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; - Table *pTab = pTabItem->pTab; + Table *pTab = pTabItem->pSTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; @@ -169212,9 +170522,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ */ if( pTabItem->fg.viaCoroutine ){ testcase( pParse->db->mallocFailed ); - assert( pTabItem->regResult>=0 ); + assert( pTabItem->fg.isSubquery ); + assert( pTabItem->u4.pSubq->regResult>=0 ); translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur, - pTabItem->regResult, 0); + pTabItem->u4.pSubq->regResult, 0); continue; } @@ -170256,7 +171567,7 @@ static ExprList *exprListAppendList( int iDummy; Expr *pSub; pSub = sqlite3ExprSkipCollateAndLikely(pDup); - if( sqlite3ExprIsInteger(pSub, &iDummy) ){ + if( sqlite3ExprIsInteger(pSub, &iDummy, 0) ){ pSub->op = TK_NULL; pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); pSub->u.zToken = 0; @@ -170424,9 +171735,10 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside ** of sqlite3DbMallocRawNN() called from ** sqlite3SrcListAppend() */ - if( p->pSrc ){ + if( p->pSrc==0 ){ + sqlite3SelectDelete(db, pSub); + }else if( sqlite3SrcItemAttachSubquery(pParse, &p->pSrc->a[0], pSub, 0) ){ Table *pTab2; - p->pSrc->a[0].pSelect = pSub; p->pSrc->a[0].fg.isCorrelated = 1; sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded|SF_OrderByReqd; @@ -170440,7 +171752,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ }else{ memcpy(pTab, pTab2, sizeof(Table)); pTab->tabFlags |= TF_Ephemeral; - p->pSrc->a[0].pTab = pTab; + p->pSrc->a[0].pSTab = pTab; pTab = pTab2; memset(&w, 0, sizeof(w)); w.xExprCallback = sqlite3WindowExtraAggFuncDepth; @@ -170448,8 +171760,6 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ w.xSelectCallback2 = sqlite3WalkerDepthDecrease; sqlite3WalkSelect(&w, pSub); } - }else{ - sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; @@ -170736,10 +172046,15 @@ SQLITE_PRIVATE int sqlite3WindowCompare( ** and initialize registers and cursors used by sqlite3WindowCodeStep(). */ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ - int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr; - Window *pMWin = pSelect->pWin; Window *pWin; - Vdbe *v = sqlite3GetVdbe(pParse); + int nEphExpr; + Window *pMWin; + Vdbe *v; + + assert( pSelect->pSrc->a[0].fg.isSubquery ); + nEphExpr = pSelect->pSrc->a[0].u4.pSubq->pSelect->pEList->nExpr; + pMWin = pSelect->pWin; + v = sqlite3GetVdbe(pParse); sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); @@ -172136,7 +173451,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( Vdbe *v = sqlite3GetVdbe(pParse); int csrWrite; /* Cursor used to write to eph. table */ int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ - int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */ + int nInput = p->pSrc->a[0].pSTab->nCol; /* Number of cols returned by sub */ int iInput; /* To iterate through sub cols */ int addrNe; /* Address of OP_Ne */ int addrGosubFlush = 0; /* Address of OP_Gosub to flush: */ @@ -172733,132 +174048,132 @@ static void updateDeleteLimitError( #define TK_OR 43 #define TK_AND 44 #define TK_IS 45 -#define TK_MATCH 46 -#define TK_LIKE_KW 47 -#define TK_BETWEEN 48 -#define TK_IN 49 -#define TK_ISNULL 50 -#define TK_NOTNULL 51 -#define TK_NE 52 -#define TK_EQ 53 -#define TK_GT 54 -#define TK_LE 55 -#define TK_LT 56 -#define TK_GE 57 -#define TK_ESCAPE 58 -#define TK_ID 59 -#define TK_COLUMNKW 60 -#define TK_DO 61 -#define TK_FOR 62 -#define TK_IGNORE 63 -#define TK_INITIALLY 64 -#define TK_INSTEAD 65 -#define TK_NO 66 -#define TK_KEY 67 -#define TK_OF 68 -#define TK_OFFSET 69 -#define TK_PRAGMA 70 -#define TK_RAISE 71 -#define TK_RECURSIVE 72 -#define TK_REPLACE 73 -#define TK_RESTRICT 74 -#define TK_ROW 75 -#define TK_ROWS 76 -#define TK_TRIGGER 77 -#define TK_VACUUM 78 -#define TK_VIEW 79 -#define TK_VIRTUAL 80 -#define TK_WITH 81 -#define TK_NULLS 82 -#define TK_FIRST 83 -#define TK_LAST 84 -#define TK_CURRENT 85 -#define TK_FOLLOWING 86 -#define TK_PARTITION 87 -#define TK_PRECEDING 88 -#define TK_RANGE 89 -#define TK_UNBOUNDED 90 -#define TK_EXCLUDE 91 -#define TK_GROUPS 92 -#define TK_OTHERS 93 -#define TK_TIES 94 -#define TK_GENERATED 95 -#define TK_ALWAYS 96 -#define TK_MATERIALIZED 97 -#define TK_REINDEX 98 -#define TK_RENAME 99 -#define TK_CTIME_KW 100 -#define TK_ANY 101 -#define TK_BITAND 102 -#define TK_BITOR 103 -#define TK_LSHIFT 104 -#define TK_RSHIFT 105 -#define TK_PLUS 106 -#define TK_MINUS 107 -#define TK_STAR 108 -#define TK_SLASH 109 -#define TK_REM 110 -#define TK_CONCAT 111 -#define TK_PTR 112 -#define TK_COLLATE 113 -#define TK_BITNOT 114 -#define TK_ON 115 -#define TK_INDEXED 116 -#define TK_STRING 117 -#define TK_JOIN_KW 118 -#define TK_CONSTRAINT 119 -#define TK_DEFAULT 120 -#define TK_NULL 121 -#define TK_PRIMARY 122 -#define TK_UNIQUE 123 -#define TK_CHECK 124 -#define TK_REFERENCES 125 -#define TK_AUTOINCR 126 -#define TK_INSERT 127 -#define TK_DELETE 128 -#define TK_UPDATE 129 -#define TK_SET 130 -#define TK_DEFERRABLE 131 -#define TK_FOREIGN 132 -#define TK_DROP 133 -#define TK_UNION 134 -#define TK_ALL 135 -#define TK_EXCEPT 136 -#define TK_INTERSECT 137 -#define TK_SELECT 138 -#define TK_VALUES 139 -#define TK_DISTINCT 140 -#define TK_DOT 141 -#define TK_FROM 142 -#define TK_JOIN 143 -#define TK_USING 144 -#define TK_ORDER 145 -#define TK_GROUP 146 -#define TK_HAVING 147 -#define TK_LIMIT 148 -#define TK_WHERE 149 -#define TK_RETURNING 150 -#define TK_INTO 151 -#define TK_NOTHING 152 -#define TK_FLOAT 153 -#define TK_BLOB 154 -#define TK_INTEGER 155 -#define TK_VARIABLE 156 -#define TK_CASE 157 -#define TK_WHEN 158 -#define TK_THEN 159 -#define TK_ELSE 160 -#define TK_INDEX 161 -#define TK_ALTER 162 -#define TK_ADD 163 -#define TK_WINDOW 164 -#define TK_OVER 165 -#define TK_FILTER 166 -#define TK_COLUMN 167 -#define TK_AGG_FUNCTION 168 -#define TK_AGG_COLUMN 169 -#define TK_TRUEFALSE 170 -#define TK_ISNOT 171 +#define TK_ISNOT 46 +#define TK_MATCH 47 +#define TK_LIKE_KW 48 +#define TK_BETWEEN 49 +#define TK_IN 50 +#define TK_ISNULL 51 +#define TK_NOTNULL 52 +#define TK_NE 53 +#define TK_EQ 54 +#define TK_GT 55 +#define TK_LE 56 +#define TK_LT 57 +#define TK_GE 58 +#define TK_ESCAPE 59 +#define TK_ID 60 +#define TK_COLUMNKW 61 +#define TK_DO 62 +#define TK_FOR 63 +#define TK_IGNORE 64 +#define TK_INITIALLY 65 +#define TK_INSTEAD 66 +#define TK_NO 67 +#define TK_KEY 68 +#define TK_OF 69 +#define TK_OFFSET 70 +#define TK_PRAGMA 71 +#define TK_RAISE 72 +#define TK_RECURSIVE 73 +#define TK_REPLACE 74 +#define TK_RESTRICT 75 +#define TK_ROW 76 +#define TK_ROWS 77 +#define TK_TRIGGER 78 +#define TK_VACUUM 79 +#define TK_VIEW 80 +#define TK_VIRTUAL 81 +#define TK_WITH 82 +#define TK_NULLS 83 +#define TK_FIRST 84 +#define TK_LAST 85 +#define TK_CURRENT 86 +#define TK_FOLLOWING 87 +#define TK_PARTITION 88 +#define TK_PRECEDING 89 +#define TK_RANGE 90 +#define TK_UNBOUNDED 91 +#define TK_EXCLUDE 92 +#define TK_GROUPS 93 +#define TK_OTHERS 94 +#define TK_TIES 95 +#define TK_GENERATED 96 +#define TK_ALWAYS 97 +#define TK_MATERIALIZED 98 +#define TK_REINDEX 99 +#define TK_RENAME 100 +#define TK_CTIME_KW 101 +#define TK_ANY 102 +#define TK_BITAND 103 +#define TK_BITOR 104 +#define TK_LSHIFT 105 +#define TK_RSHIFT 106 +#define TK_PLUS 107 +#define TK_MINUS 108 +#define TK_STAR 109 +#define TK_SLASH 110 +#define TK_REM 111 +#define TK_CONCAT 112 +#define TK_PTR 113 +#define TK_COLLATE 114 +#define TK_BITNOT 115 +#define TK_ON 116 +#define TK_INDEXED 117 +#define TK_STRING 118 +#define TK_JOIN_KW 119 +#define TK_CONSTRAINT 120 +#define TK_DEFAULT 121 +#define TK_NULL 122 +#define TK_PRIMARY 123 +#define TK_UNIQUE 124 +#define TK_CHECK 125 +#define TK_REFERENCES 126 +#define TK_AUTOINCR 127 +#define TK_INSERT 128 +#define TK_DELETE 129 +#define TK_UPDATE 130 +#define TK_SET 131 +#define TK_DEFERRABLE 132 +#define TK_FOREIGN 133 +#define TK_DROP 134 +#define TK_UNION 135 +#define TK_ALL 136 +#define TK_EXCEPT 137 +#define TK_INTERSECT 138 +#define TK_SELECT 139 +#define TK_VALUES 140 +#define TK_DISTINCT 141 +#define TK_DOT 142 +#define TK_FROM 143 +#define TK_JOIN 144 +#define TK_USING 145 +#define TK_ORDER 146 +#define TK_GROUP 147 +#define TK_HAVING 148 +#define TK_LIMIT 149 +#define TK_WHERE 150 +#define TK_RETURNING 151 +#define TK_INTO 152 +#define TK_NOTHING 153 +#define TK_FLOAT 154 +#define TK_BLOB 155 +#define TK_INTEGER 156 +#define TK_VARIABLE 157 +#define TK_CASE 158 +#define TK_WHEN 159 +#define TK_THEN 160 +#define TK_ELSE 161 +#define TK_INDEX 162 +#define TK_ALTER 163 +#define TK_ADD 164 +#define TK_WINDOW 165 +#define TK_OVER 166 +#define TK_FILTER 167 +#define TK_COLUMN 168 +#define TK_AGG_FUNCTION 169 +#define TK_AGG_COLUMN 170 +#define TK_TRUEFALSE 171 #define TK_FUNCTION 172 #define TK_UPLUS 173 #define TK_UMINUS 174 @@ -172939,7 +174254,7 @@ static void updateDeleteLimitError( #define YYCODETYPE unsigned short int #define YYNOCODE 322 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 101 +#define YYWILDCARD 102 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; @@ -173076,446 +174391,452 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2142) +#define YY_ACTTAB_COUNT (2207) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 576, 128, 125, 232, 1622, 549, 576, 1290, 1281, 576, - /* 10 */ 328, 576, 1300, 212, 576, 128, 125, 232, 578, 412, - /* 20 */ 578, 391, 1542, 51, 51, 523, 405, 1293, 529, 51, - /* 30 */ 51, 983, 51, 51, 81, 81, 1107, 61, 61, 984, - /* 40 */ 1107, 1292, 380, 135, 136, 90, 1228, 1228, 1063, 1066, - /* 50 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 1577, 412, - /* 60 */ 287, 287, 7, 287, 287, 422, 1050, 1050, 1064, 1067, - /* 70 */ 289, 556, 492, 573, 524, 561, 573, 497, 561, 482, - /* 80 */ 530, 262, 229, 135, 136, 90, 1228, 1228, 1063, 1066, - /* 90 */ 1053, 1053, 133, 133, 134, 134, 134, 134, 128, 125, - /* 100 */ 232, 1506, 132, 132, 132, 132, 131, 131, 130, 130, - /* 110 */ 130, 129, 126, 450, 1204, 1255, 1, 1, 582, 2, - /* 120 */ 1259, 1571, 420, 1582, 379, 320, 1174, 153, 1174, 1584, - /* 130 */ 412, 378, 1582, 543, 1341, 330, 111, 570, 570, 570, - /* 140 */ 293, 1054, 132, 132, 132, 132, 131, 131, 130, 130, - /* 150 */ 130, 129, 126, 450, 135, 136, 90, 1228, 1228, 1063, - /* 160 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 287, - /* 170 */ 287, 1204, 1205, 1204, 255, 287, 287, 510, 507, 506, - /* 180 */ 137, 455, 573, 212, 561, 447, 446, 505, 573, 1616, - /* 190 */ 561, 134, 134, 134, 134, 127, 400, 243, 132, 132, - /* 200 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, - /* 210 */ 282, 471, 345, 132, 132, 132, 132, 131, 131, 130, - /* 220 */ 130, 130, 129, 126, 450, 574, 155, 936, 936, 454, - /* 230 */ 227, 521, 1236, 412, 1236, 134, 134, 134, 134, 132, - /* 240 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, - /* 250 */ 450, 130, 130, 130, 129, 126, 450, 135, 136, 90, - /* 260 */ 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, - /* 270 */ 134, 134, 128, 125, 232, 450, 576, 412, 397, 1249, - /* 280 */ 180, 92, 93, 132, 132, 132, 132, 131, 131, 130, - /* 290 */ 130, 130, 129, 126, 450, 381, 387, 1204, 383, 81, - /* 300 */ 81, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, - /* 310 */ 133, 133, 134, 134, 134, 134, 132, 132, 132, 132, - /* 320 */ 131, 131, 130, 130, 130, 129, 126, 450, 131, 131, - /* 330 */ 130, 130, 130, 129, 126, 450, 556, 1204, 302, 319, - /* 340 */ 567, 121, 568, 480, 4, 555, 1149, 1657, 1628, 1657, - /* 350 */ 45, 128, 125, 232, 1204, 1205, 1204, 1250, 571, 1169, - /* 360 */ 132, 132, 132, 132, 131, 131, 130, 130, 130, 129, - /* 370 */ 126, 450, 1169, 287, 287, 1169, 1019, 576, 422, 1019, - /* 380 */ 412, 451, 1602, 582, 2, 1259, 573, 44, 561, 95, - /* 390 */ 320, 110, 153, 565, 1204, 1205, 1204, 522, 522, 1341, - /* 400 */ 81, 81, 7, 44, 135, 136, 90, 1228, 1228, 1063, - /* 410 */ 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, 295, - /* 420 */ 1149, 1658, 1040, 1658, 1204, 1147, 319, 567, 119, 119, - /* 430 */ 343, 466, 331, 343, 287, 287, 120, 556, 451, 577, - /* 440 */ 451, 1169, 1169, 1028, 319, 567, 438, 573, 210, 561, - /* 450 */ 1339, 1451, 546, 531, 1169, 1169, 1598, 1169, 1169, 416, - /* 460 */ 319, 567, 243, 132, 132, 132, 132, 131, 131, 130, - /* 470 */ 130, 130, 129, 126, 450, 1028, 1028, 1030, 1031, 35, - /* 480 */ 44, 1204, 1205, 1204, 472, 287, 287, 1328, 412, 1307, - /* 490 */ 372, 1595, 359, 225, 454, 1204, 195, 1328, 573, 1147, - /* 500 */ 561, 1333, 1333, 274, 576, 1188, 576, 340, 46, 196, - /* 510 */ 537, 217, 135, 136, 90, 1228, 1228, 1063, 1066, 1053, - /* 520 */ 1053, 133, 133, 134, 134, 134, 134, 19, 19, 19, - /* 530 */ 19, 412, 581, 1204, 1259, 511, 1204, 319, 567, 320, - /* 540 */ 944, 153, 425, 491, 430, 943, 1204, 488, 1341, 1450, - /* 550 */ 532, 1277, 1204, 1205, 1204, 135, 136, 90, 1228, 1228, - /* 560 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 570 */ 575, 132, 132, 132, 132, 131, 131, 130, 130, 130, - /* 580 */ 129, 126, 450, 287, 287, 528, 287, 287, 372, 1595, - /* 590 */ 1204, 1205, 1204, 1204, 1205, 1204, 573, 486, 561, 573, - /* 600 */ 889, 561, 412, 1204, 1205, 1204, 886, 40, 22, 22, - /* 610 */ 220, 243, 525, 1449, 132, 132, 132, 132, 131, 131, - /* 620 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 630 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 640 */ 134, 412, 180, 454, 1204, 879, 255, 287, 287, 510, - /* 650 */ 507, 506, 372, 1595, 1568, 1331, 1331, 576, 889, 505, - /* 660 */ 573, 44, 561, 559, 1207, 135, 136, 90, 1228, 1228, - /* 670 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 680 */ 81, 81, 422, 576, 377, 132, 132, 132, 132, 131, - /* 690 */ 131, 130, 130, 130, 129, 126, 450, 297, 287, 287, - /* 700 */ 460, 1204, 1205, 1204, 1204, 534, 19, 19, 448, 448, - /* 710 */ 448, 573, 412, 561, 230, 436, 1187, 535, 319, 567, - /* 720 */ 363, 432, 1207, 1435, 132, 132, 132, 132, 131, 131, - /* 730 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 740 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 750 */ 134, 412, 211, 949, 1169, 1041, 1110, 1110, 494, 547, - /* 760 */ 547, 1204, 1205, 1204, 7, 539, 1570, 1169, 376, 576, - /* 770 */ 1169, 5, 1204, 486, 3, 135, 136, 90, 1228, 1228, - /* 780 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 790 */ 576, 513, 19, 19, 427, 132, 132, 132, 132, 131, - /* 800 */ 131, 130, 130, 130, 129, 126, 450, 305, 1204, 433, - /* 810 */ 225, 1204, 385, 19, 19, 273, 290, 371, 516, 366, - /* 820 */ 515, 260, 412, 538, 1568, 549, 1024, 362, 437, 1204, - /* 830 */ 1205, 1204, 902, 1552, 132, 132, 132, 132, 131, 131, - /* 840 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 850 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 860 */ 134, 412, 1435, 514, 1281, 1204, 1205, 1204, 1204, 1205, - /* 870 */ 1204, 903, 48, 342, 1568, 1568, 1279, 1627, 1568, 911, - /* 880 */ 576, 129, 126, 450, 110, 135, 136, 90, 1228, 1228, - /* 890 */ 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, 134, - /* 900 */ 265, 576, 459, 19, 19, 132, 132, 132, 132, 131, - /* 910 */ 131, 130, 130, 130, 129, 126, 450, 1345, 204, 576, - /* 920 */ 459, 458, 50, 47, 19, 19, 49, 434, 1105, 573, - /* 930 */ 497, 561, 412, 428, 108, 1224, 1569, 1554, 376, 205, - /* 940 */ 550, 550, 81, 81, 132, 132, 132, 132, 131, 131, - /* 950 */ 130, 130, 130, 129, 126, 450, 135, 136, 90, 1228, - /* 960 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 970 */ 134, 480, 576, 1204, 576, 1541, 412, 1435, 969, 315, - /* 980 */ 1659, 398, 284, 497, 969, 893, 1569, 1569, 376, 376, - /* 990 */ 1569, 461, 376, 1224, 459, 80, 80, 81, 81, 497, - /* 1000 */ 374, 114, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, - /* 1010 */ 133, 134, 134, 134, 134, 132, 132, 132, 132, 131, - /* 1020 */ 131, 130, 130, 130, 129, 126, 450, 1204, 1505, 576, - /* 1030 */ 1204, 1205, 1204, 1366, 316, 486, 281, 281, 497, 431, - /* 1040 */ 557, 288, 288, 402, 1340, 471, 345, 298, 429, 573, - /* 1050 */ 576, 561, 81, 81, 573, 374, 561, 971, 386, 132, - /* 1060 */ 132, 132, 132, 131, 131, 130, 130, 130, 129, 126, - /* 1070 */ 450, 231, 117, 81, 81, 287, 287, 231, 287, 287, - /* 1080 */ 576, 1511, 576, 1336, 1204, 1205, 1204, 139, 573, 556, - /* 1090 */ 561, 573, 412, 561, 441, 456, 969, 213, 558, 1511, - /* 1100 */ 1513, 1550, 969, 143, 143, 145, 145, 1368, 314, 478, - /* 1110 */ 444, 970, 412, 850, 851, 852, 135, 136, 90, 1228, - /* 1120 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 1130 */ 134, 357, 412, 397, 1148, 304, 135, 136, 90, 1228, - /* 1140 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 1150 */ 134, 1575, 323, 6, 862, 7, 135, 124, 90, 1228, - /* 1160 */ 1228, 1063, 1066, 1053, 1053, 133, 133, 134, 134, 134, - /* 1170 */ 134, 409, 408, 1511, 212, 132, 132, 132, 132, 131, - /* 1180 */ 131, 130, 130, 130, 129, 126, 450, 411, 118, 1204, - /* 1190 */ 116, 10, 352, 265, 355, 132, 132, 132, 132, 131, - /* 1200 */ 131, 130, 130, 130, 129, 126, 450, 576, 324, 306, - /* 1210 */ 576, 306, 1250, 469, 158, 132, 132, 132, 132, 131, - /* 1220 */ 131, 130, 130, 130, 129, 126, 450, 207, 1224, 1126, - /* 1230 */ 65, 65, 470, 66, 66, 412, 447, 446, 882, 531, - /* 1240 */ 335, 258, 257, 256, 1127, 1233, 1204, 1205, 1204, 327, - /* 1250 */ 1235, 874, 159, 576, 16, 480, 1085, 1040, 1234, 1128, - /* 1260 */ 136, 90, 1228, 1228, 1063, 1066, 1053, 1053, 133, 133, - /* 1270 */ 134, 134, 134, 134, 1029, 576, 81, 81, 1028, 1040, - /* 1280 */ 922, 576, 463, 1236, 576, 1236, 1224, 502, 107, 1435, - /* 1290 */ 923, 6, 576, 410, 1498, 882, 1029, 480, 21, 21, - /* 1300 */ 1028, 332, 1380, 334, 53, 53, 497, 81, 81, 874, - /* 1310 */ 1028, 1028, 1030, 445, 259, 19, 19, 533, 132, 132, - /* 1320 */ 132, 132, 131, 131, 130, 130, 130, 129, 126, 450, - /* 1330 */ 551, 301, 1028, 1028, 1030, 107, 532, 545, 121, 568, - /* 1340 */ 1188, 4, 1126, 1576, 449, 576, 462, 7, 1282, 418, - /* 1350 */ 462, 350, 1435, 576, 518, 571, 544, 1127, 121, 568, - /* 1360 */ 442, 4, 1188, 464, 533, 1180, 1223, 9, 67, 67, - /* 1370 */ 487, 576, 1128, 303, 410, 571, 54, 54, 451, 576, - /* 1380 */ 123, 944, 576, 417, 576, 333, 943, 1379, 576, 236, - /* 1390 */ 565, 576, 1574, 564, 68, 68, 7, 576, 451, 362, - /* 1400 */ 419, 182, 69, 69, 541, 70, 70, 71, 71, 540, - /* 1410 */ 565, 72, 72, 484, 55, 55, 473, 1180, 296, 1040, - /* 1420 */ 56, 56, 296, 493, 541, 119, 119, 410, 1573, 542, - /* 1430 */ 569, 418, 7, 120, 1244, 451, 577, 451, 465, 1040, - /* 1440 */ 1028, 576, 1557, 552, 476, 119, 119, 527, 259, 121, - /* 1450 */ 568, 240, 4, 120, 576, 451, 577, 451, 576, 477, - /* 1460 */ 1028, 576, 156, 576, 57, 57, 571, 576, 286, 229, - /* 1470 */ 410, 336, 1028, 1028, 1030, 1031, 35, 59, 59, 219, - /* 1480 */ 983, 60, 60, 220, 73, 73, 74, 74, 984, 451, - /* 1490 */ 75, 75, 1028, 1028, 1030, 1031, 35, 96, 216, 291, - /* 1500 */ 552, 565, 1188, 318, 395, 395, 394, 276, 392, 576, - /* 1510 */ 485, 859, 474, 1311, 410, 541, 576, 417, 1530, 1144, - /* 1520 */ 540, 399, 1188, 292, 237, 1153, 326, 38, 23, 576, - /* 1530 */ 1040, 576, 20, 20, 325, 299, 119, 119, 164, 76, - /* 1540 */ 76, 1529, 121, 568, 120, 4, 451, 577, 451, 203, - /* 1550 */ 576, 1028, 141, 141, 142, 142, 576, 322, 39, 571, - /* 1560 */ 341, 1021, 110, 264, 239, 901, 900, 423, 242, 908, - /* 1570 */ 909, 370, 173, 77, 77, 43, 479, 1310, 264, 62, - /* 1580 */ 62, 369, 451, 1028, 1028, 1030, 1031, 35, 1601, 1192, - /* 1590 */ 453, 1092, 238, 291, 565, 163, 1309, 110, 395, 395, - /* 1600 */ 394, 276, 392, 986, 987, 859, 481, 346, 264, 110, - /* 1610 */ 1032, 489, 576, 1188, 503, 1088, 261, 261, 237, 576, - /* 1620 */ 326, 121, 568, 1040, 4, 347, 1376, 413, 325, 119, - /* 1630 */ 119, 948, 319, 567, 351, 78, 78, 120, 571, 451, - /* 1640 */ 577, 451, 79, 79, 1028, 354, 356, 576, 360, 1092, - /* 1650 */ 110, 576, 974, 942, 264, 123, 457, 358, 239, 576, - /* 1660 */ 519, 451, 939, 1104, 123, 1104, 173, 576, 1032, 43, - /* 1670 */ 63, 63, 1324, 565, 168, 168, 1028, 1028, 1030, 1031, - /* 1680 */ 35, 576, 169, 169, 1308, 872, 238, 157, 1589, 576, - /* 1690 */ 86, 86, 365, 89, 568, 375, 4, 1103, 941, 1103, - /* 1700 */ 123, 576, 1040, 1389, 64, 64, 1188, 1434, 119, 119, - /* 1710 */ 571, 576, 82, 82, 563, 576, 120, 165, 451, 577, - /* 1720 */ 451, 413, 1362, 1028, 144, 144, 319, 567, 576, 1374, - /* 1730 */ 562, 498, 279, 451, 83, 83, 1439, 576, 166, 166, - /* 1740 */ 576, 1289, 554, 576, 1280, 565, 576, 12, 576, 1268, - /* 1750 */ 457, 146, 146, 1267, 576, 1028, 1028, 1030, 1031, 35, - /* 1760 */ 140, 140, 1269, 167, 167, 1609, 160, 160, 1359, 150, - /* 1770 */ 150, 149, 149, 311, 1040, 576, 312, 147, 147, 313, - /* 1780 */ 119, 119, 222, 235, 576, 1188, 396, 576, 120, 576, - /* 1790 */ 451, 577, 451, 1192, 453, 1028, 508, 291, 148, 148, - /* 1800 */ 1421, 1612, 395, 395, 394, 276, 392, 85, 85, 859, - /* 1810 */ 87, 87, 84, 84, 553, 576, 294, 576, 1426, 338, - /* 1820 */ 339, 1425, 237, 300, 326, 1416, 1409, 1028, 1028, 1030, - /* 1830 */ 1031, 35, 325, 344, 403, 483, 226, 1307, 52, 52, - /* 1840 */ 58, 58, 368, 1371, 1502, 566, 1501, 121, 568, 221, - /* 1850 */ 4, 208, 268, 209, 390, 1244, 1549, 1188, 1372, 1370, - /* 1860 */ 1369, 1547, 239, 184, 571, 233, 421, 1241, 95, 218, - /* 1870 */ 173, 1507, 193, 43, 91, 94, 178, 186, 467, 188, - /* 1880 */ 468, 1422, 13, 189, 190, 191, 501, 451, 245, 108, - /* 1890 */ 238, 401, 1428, 1427, 1430, 475, 404, 1496, 197, 565, - /* 1900 */ 14, 490, 249, 101, 1518, 496, 349, 280, 251, 201, - /* 1910 */ 353, 499, 252, 406, 1270, 253, 517, 1327, 1326, 435, - /* 1920 */ 1325, 1318, 103, 893, 1296, 413, 227, 407, 1040, 1626, - /* 1930 */ 319, 567, 1625, 1297, 119, 119, 439, 367, 1317, 1295, - /* 1940 */ 1624, 526, 120, 440, 451, 577, 451, 1594, 309, 1028, - /* 1950 */ 310, 373, 266, 267, 457, 1580, 1579, 443, 138, 1394, - /* 1960 */ 552, 1393, 11, 1483, 384, 115, 317, 1350, 109, 536, - /* 1970 */ 42, 579, 382, 214, 1349, 388, 1198, 389, 275, 277, - /* 1980 */ 278, 1028, 1028, 1030, 1031, 35, 580, 1265, 414, 1260, - /* 1990 */ 170, 415, 183, 1534, 1535, 1533, 171, 154, 307, 1532, - /* 2000 */ 846, 223, 224, 88, 452, 215, 172, 321, 234, 1102, - /* 2010 */ 152, 1188, 1100, 329, 185, 174, 1223, 925, 187, 241, - /* 2020 */ 337, 244, 1116, 192, 175, 176, 424, 426, 97, 194, - /* 2030 */ 98, 99, 100, 177, 1119, 1115, 246, 247, 161, 24, - /* 2040 */ 248, 348, 1238, 264, 1108, 250, 495, 199, 198, 15, - /* 2050 */ 861, 500, 369, 254, 504, 509, 512, 200, 102, 25, - /* 2060 */ 179, 361, 26, 364, 104, 891, 308, 162, 105, 904, - /* 2070 */ 520, 106, 1185, 1069, 1155, 17, 228, 27, 1154, 283, - /* 2080 */ 285, 263, 978, 202, 972, 123, 28, 1175, 29, 30, - /* 2090 */ 1179, 1171, 31, 1173, 1160, 41, 32, 206, 548, 33, - /* 2100 */ 110, 1178, 1083, 8, 112, 1070, 113, 1068, 1072, 34, - /* 2110 */ 1073, 560, 1125, 269, 1124, 270, 36, 18, 1194, 1033, - /* 2120 */ 873, 151, 122, 37, 393, 271, 272, 572, 181, 1193, - /* 2130 */ 1256, 1256, 1256, 935, 1256, 1256, 1256, 1256, 1256, 1256, - /* 2140 */ 1256, 1617, + /* 0 */ 130, 127, 234, 282, 282, 1328, 576, 1307, 460, 289, + /* 10 */ 289, 576, 1622, 381, 576, 1328, 573, 576, 562, 413, + /* 20 */ 1300, 1542, 573, 481, 562, 524, 460, 459, 558, 82, + /* 30 */ 82, 983, 294, 375, 51, 51, 498, 61, 61, 984, + /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063, + /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413, + /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130, + /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290, + /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063, + /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296, + /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132, + /* 110 */ 132, 132, 131, 128, 451, 44, 1050, 1050, 1064, 1067, + /* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174, + /* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 498, 1341, + /* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132, + /* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 1105, 1228, + /* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, + /* 170 */ 136, 1204, 320, 567, 288, 288, 283, 288, 288, 523, + /* 180 */ 523, 1250, 139, 1541, 7, 214, 503, 573, 1169, 562, + /* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 401, 547, + /* 200 */ 487, 1169, 245, 1568, 1169, 245, 133, 133, 132, 132, + /* 210 */ 132, 131, 128, 451, 261, 134, 134, 134, 134, 133, + /* 220 */ 133, 132, 132, 132, 131, 128, 451, 451, 1204, 1205, + /* 230 */ 1204, 130, 127, 234, 455, 413, 182, 455, 130, 127, + /* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132, + /* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 576, 137, + /* 260 */ 138, 91, 261, 1228, 1228, 1063, 1066, 1053, 1053, 135, + /* 270 */ 135, 136, 136, 136, 136, 44, 472, 346, 1204, 472, + /* 280 */ 346, 51, 51, 418, 93, 157, 134, 134, 134, 134, + /* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 166, 363, + /* 300 */ 298, 134, 134, 134, 134, 133, 133, 132, 132, 132, + /* 310 */ 131, 128, 451, 1293, 461, 1570, 423, 377, 275, 134, + /* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128, + /* 330 */ 451, 418, 320, 567, 1292, 1204, 1205, 1204, 257, 413, + /* 340 */ 483, 511, 508, 507, 94, 132, 132, 132, 131, 128, + /* 350 */ 451, 506, 1204, 548, 548, 388, 576, 384, 7, 413, + /* 360 */ 550, 229, 522, 137, 138, 91, 530, 1228, 1228, 1063, + /* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 51, + /* 380 */ 51, 1582, 380, 137, 138, 91, 331, 1228, 1228, 1063, + /* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 320, + /* 400 */ 567, 288, 288, 320, 567, 1602, 582, 2, 1259, 1204, + /* 410 */ 1205, 1204, 1628, 321, 573, 155, 562, 576, 1511, 264, + /* 420 */ 231, 520, 1341, 134, 134, 134, 134, 133, 133, 132, + /* 430 */ 132, 132, 131, 128, 451, 519, 1511, 1513, 1333, 1333, + /* 440 */ 82, 82, 498, 134, 134, 134, 134, 133, 133, 132, + /* 450 */ 132, 132, 131, 128, 451, 1435, 257, 288, 288, 511, + /* 460 */ 508, 507, 944, 1568, 413, 1019, 1204, 943, 360, 506, + /* 470 */ 573, 1598, 562, 44, 575, 551, 551, 557, 1107, 1582, + /* 480 */ 544, 576, 1107, 40, 417, 245, 531, 1505, 137, 138, + /* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, + /* 500 */ 136, 136, 136, 136, 81, 81, 1281, 1204, 413, 553, + /* 510 */ 1511, 48, 512, 448, 447, 493, 578, 455, 578, 344, + /* 520 */ 45, 1204, 1233, 1204, 1205, 1204, 428, 1235, 158, 882, + /* 530 */ 320, 567, 137, 138, 91, 1234, 1228, 1228, 1063, 1066, + /* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134, + /* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, + /* 560 */ 1236, 576, 1236, 329, 1204, 1205, 1204, 387, 492, 403, + /* 570 */ 1040, 382, 489, 123, 568, 1569, 4, 377, 1204, 1205, + /* 580 */ 1204, 570, 570, 570, 82, 82, 882, 1029, 1331, 1331, + /* 590 */ 571, 1028, 134, 134, 134, 134, 133, 133, 132, 132, + /* 600 */ 132, 131, 128, 451, 288, 288, 1281, 1204, 576, 423, + /* 610 */ 576, 1568, 413, 423, 452, 378, 886, 573, 1279, 562, + /* 620 */ 46, 557, 532, 1028, 1028, 1030, 565, 130, 127, 234, + /* 630 */ 556, 82, 82, 82, 82, 479, 137, 138, 91, 462, + /* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 650 */ 136, 136, 1188, 487, 1506, 1040, 413, 6, 1204, 50, + /* 660 */ 879, 121, 121, 948, 1204, 1205, 1204, 358, 557, 122, + /* 670 */ 316, 452, 577, 452, 535, 1204, 1028, 439, 303, 212, + /* 680 */ 137, 138, 91, 213, 1228, 1228, 1063, 1066, 1053, 1053, + /* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134, + /* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028, + /* 710 */ 1030, 1031, 35, 288, 288, 1204, 1205, 1204, 1040, 1339, + /* 720 */ 533, 123, 568, 1569, 4, 377, 573, 1019, 562, 353, + /* 730 */ 1277, 356, 1204, 1205, 1204, 1029, 488, 1188, 571, 1028, + /* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 750 */ 128, 451, 576, 343, 288, 288, 449, 449, 449, 971, + /* 760 */ 413, 1627, 452, 911, 1187, 288, 288, 573, 464, 562, + /* 770 */ 238, 1028, 1028, 1030, 565, 82, 82, 498, 573, 411, + /* 780 */ 562, 344, 467, 332, 137, 138, 91, 197, 1228, 1228, + /* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 800 */ 1188, 528, 1169, 1040, 413, 1110, 1110, 495, 1041, 121, + /* 810 */ 121, 1204, 317, 540, 862, 1169, 1244, 122, 1169, 452, + /* 820 */ 577, 452, 1340, 198, 1028, 1204, 481, 526, 137, 138, + /* 830 */ 91, 560, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, + /* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133, + /* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031, + /* 860 */ 35, 1204, 288, 288, 1204, 477, 288, 288, 1204, 1205, + /* 870 */ 1204, 539, 481, 437, 470, 573, 1451, 562, 364, 573, + /* 880 */ 1153, 562, 1204, 1205, 1204, 1188, 5, 576, 134, 134, + /* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451, + /* 900 */ 221, 214, 302, 96, 1149, 1657, 232, 1657, 413, 392, + /* 910 */ 19, 19, 1024, 949, 406, 373, 1595, 1085, 1204, 1205, + /* 920 */ 1204, 1204, 1205, 1204, 1204, 426, 1149, 1658, 413, 1658, + /* 930 */ 1659, 399, 137, 138, 91, 3, 1228, 1228, 1063, 1066, + /* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 304, 1311, + /* 950 */ 514, 1204, 137, 138, 91, 1498, 1228, 1228, 1063, 1066, + /* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 131, + /* 970 */ 128, 451, 375, 1204, 274, 291, 372, 517, 367, 516, + /* 980 */ 262, 1204, 1205, 1204, 1147, 227, 363, 448, 447, 1435, + /* 990 */ 1568, 1310, 134, 134, 134, 134, 133, 133, 132, 132, + /* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 487, 1204, 1205, + /* 1010 */ 1204, 442, 134, 134, 134, 134, 133, 133, 132, 132, + /* 1020 */ 132, 131, 128, 451, 386, 576, 485, 576, 19, 19, + /* 1030 */ 1204, 1205, 1204, 1345, 1236, 970, 1236, 574, 47, 936, + /* 1040 */ 936, 473, 413, 431, 1552, 573, 1125, 562, 19, 19, + /* 1050 */ 19, 19, 49, 336, 850, 851, 852, 111, 1368, 315, + /* 1060 */ 429, 576, 413, 433, 341, 306, 137, 138, 91, 115, + /* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 1080 */ 136, 136, 576, 1309, 82, 82, 137, 138, 91, 529, + /* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, + /* 1100 */ 136, 136, 1569, 222, 377, 19, 19, 305, 1126, 1169, + /* 1110 */ 398, 1148, 22, 22, 498, 333, 1569, 335, 377, 576, + /* 1120 */ 438, 445, 1169, 1127, 486, 1169, 134, 134, 134, 134, + /* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576, + /* 1140 */ 902, 576, 145, 145, 6, 576, 134, 134, 134, 134, + /* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 214, 1336, + /* 1160 */ 922, 576, 19, 19, 19, 19, 1282, 419, 19, 19, + /* 1170 */ 923, 412, 515, 141, 576, 1169, 413, 206, 465, 207, + /* 1180 */ 903, 215, 1575, 552, 147, 147, 7, 227, 1169, 411, + /* 1190 */ 1250, 1169, 120, 307, 117, 307, 413, 66, 66, 334, + /* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1210 */ 135, 135, 136, 136, 136, 136, 413, 285, 209, 969, + /* 1220 */ 137, 138, 91, 471, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1230 */ 135, 135, 136, 136, 136, 136, 435, 10, 1450, 267, + /* 1240 */ 137, 126, 91, 1435, 1228, 1228, 1063, 1066, 1053, 1053, + /* 1250 */ 135, 135, 136, 136, 136, 136, 1435, 1435, 410, 409, + /* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1270 */ 128, 451, 576, 969, 576, 1224, 498, 373, 1595, 1554, + /* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1290 */ 128, 451, 532, 457, 576, 82, 82, 82, 82, 111, + /* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131, + /* 1310 */ 128, 451, 109, 233, 430, 1576, 546, 67, 67, 7, + /* 1320 */ 413, 351, 550, 1550, 260, 259, 258, 494, 443, 569, + /* 1330 */ 419, 983, 446, 1224, 450, 545, 1207, 576, 969, 984, + /* 1340 */ 413, 475, 1449, 1574, 1180, 138, 91, 7, 1228, 1228, + /* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 1360 */ 21, 21, 267, 576, 300, 1126, 91, 233, 1228, 1228, + /* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, + /* 1380 */ 1127, 373, 1595, 161, 1573, 16, 53, 53, 7, 108, + /* 1390 */ 533, 38, 969, 125, 1207, 1128, 1180, 576, 1224, 123, + /* 1400 */ 568, 893, 4, 324, 134, 134, 134, 134, 133, 133, + /* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 576, + /* 1420 */ 68, 68, 576, 39, 134, 134, 134, 134, 133, 133, + /* 1430 */ 132, 132, 132, 131, 128, 451, 576, 160, 1571, 1223, + /* 1440 */ 452, 576, 54, 54, 576, 69, 69, 576, 1366, 576, + /* 1450 */ 420, 184, 565, 463, 297, 576, 1224, 463, 297, 70, + /* 1460 */ 70, 576, 44, 474, 71, 71, 576, 72, 72, 576, + /* 1470 */ 73, 73, 55, 55, 411, 874, 242, 576, 56, 56, + /* 1480 */ 576, 1040, 576, 478, 57, 57, 576, 121, 121, 59, + /* 1490 */ 59, 23, 60, 60, 411, 122, 319, 452, 577, 452, + /* 1500 */ 74, 74, 1028, 75, 75, 76, 76, 411, 290, 20, + /* 1510 */ 20, 108, 287, 231, 553, 123, 568, 325, 4, 320, + /* 1520 */ 567, 97, 218, 944, 1144, 328, 400, 576, 943, 576, + /* 1530 */ 1380, 424, 571, 874, 1028, 1028, 1030, 1031, 35, 293, + /* 1540 */ 534, 576, 1104, 576, 1104, 9, 576, 342, 576, 111, + /* 1550 */ 77, 77, 143, 143, 576, 205, 452, 222, 1379, 889, + /* 1560 */ 576, 901, 900, 1188, 144, 144, 78, 78, 565, 62, + /* 1570 */ 62, 79, 79, 323, 1021, 576, 266, 63, 63, 908, + /* 1580 */ 909, 1589, 542, 80, 80, 576, 371, 541, 123, 568, + /* 1590 */ 480, 4, 266, 482, 244, 266, 370, 1040, 64, 64, + /* 1600 */ 576, 466, 576, 121, 121, 571, 1557, 576, 170, 170, + /* 1610 */ 576, 122, 576, 452, 577, 452, 576, 889, 1028, 576, + /* 1620 */ 165, 576, 111, 171, 171, 87, 87, 337, 1616, 452, + /* 1630 */ 65, 65, 1530, 83, 83, 146, 146, 986, 987, 84, + /* 1640 */ 84, 565, 168, 168, 148, 148, 1092, 347, 1032, 111, + /* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 1103, 576, 1103, 576, + /* 1660 */ 543, 123, 568, 504, 4, 263, 576, 361, 1529, 111, + /* 1670 */ 1040, 1088, 576, 263, 576, 490, 121, 121, 571, 1188, + /* 1680 */ 142, 142, 169, 169, 122, 576, 452, 577, 452, 162, + /* 1690 */ 162, 1028, 576, 563, 576, 152, 152, 151, 151, 348, + /* 1700 */ 1376, 974, 452, 266, 1092, 942, 1032, 125, 149, 149, + /* 1710 */ 939, 576, 125, 576, 565, 150, 150, 86, 86, 872, + /* 1720 */ 352, 159, 576, 1028, 1028, 1030, 1031, 35, 542, 941, + /* 1730 */ 576, 125, 355, 541, 88, 88, 85, 85, 357, 359, + /* 1740 */ 1324, 1308, 366, 1040, 376, 52, 52, 499, 1389, 121, + /* 1750 */ 121, 1434, 1188, 58, 58, 1362, 1374, 122, 1439, 452, + /* 1760 */ 577, 452, 1289, 167, 1028, 1280, 280, 1268, 1267, 1269, + /* 1770 */ 1609, 1359, 312, 313, 12, 314, 397, 1421, 224, 1416, + /* 1780 */ 295, 237, 1409, 339, 340, 1426, 301, 345, 484, 228, + /* 1790 */ 1371, 1307, 1372, 1370, 1425, 404, 1028, 1028, 1030, 1031, + /* 1800 */ 35, 1601, 1192, 454, 509, 369, 292, 1502, 210, 1501, + /* 1810 */ 1369, 396, 396, 395, 277, 393, 211, 566, 859, 1612, + /* 1820 */ 1244, 123, 568, 391, 4, 1188, 223, 270, 1549, 1547, + /* 1830 */ 1241, 239, 186, 327, 422, 96, 195, 220, 571, 235, + /* 1840 */ 180, 326, 188, 468, 190, 1507, 191, 192, 92, 193, + /* 1850 */ 469, 95, 1422, 13, 502, 247, 1430, 109, 199, 402, + /* 1860 */ 476, 405, 452, 1496, 1428, 1427, 14, 491, 251, 102, + /* 1870 */ 497, 1518, 241, 281, 565, 253, 203, 354, 500, 254, + /* 1880 */ 175, 1270, 407, 43, 350, 518, 1327, 436, 255, 1326, + /* 1890 */ 1325, 1318, 104, 893, 1626, 229, 408, 440, 1625, 441, + /* 1900 */ 240, 310, 1296, 1040, 311, 1317, 527, 1594, 1297, 121, + /* 1910 */ 121, 368, 1295, 1624, 268, 269, 1580, 122, 1579, 452, + /* 1920 */ 577, 452, 374, 444, 1028, 1394, 1393, 140, 553, 90, + /* 1930 */ 568, 11, 4, 1483, 383, 414, 385, 110, 116, 216, + /* 1940 */ 320, 567, 1350, 555, 42, 318, 571, 537, 1349, 389, + /* 1950 */ 390, 579, 1198, 276, 279, 278, 1028, 1028, 1030, 1031, + /* 1960 */ 35, 580, 415, 1265, 458, 1260, 416, 185, 1534, 172, + /* 1970 */ 452, 1535, 173, 156, 308, 846, 1533, 1532, 453, 217, + /* 1980 */ 225, 89, 565, 174, 322, 1188, 226, 236, 1102, 154, + /* 1990 */ 1100, 330, 176, 187, 1223, 189, 925, 338, 243, 1116, + /* 2000 */ 246, 194, 177, 178, 425, 427, 98, 99, 196, 100, + /* 2010 */ 101, 1040, 179, 1119, 248, 1115, 249, 121, 121, 24, + /* 2020 */ 163, 250, 349, 1108, 266, 122, 1238, 452, 577, 452, + /* 2030 */ 1192, 454, 1028, 200, 292, 496, 252, 201, 861, 396, + /* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256, + /* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239, + /* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326, + /* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309, + /* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155, + /* 2090 */ 17, 1154, 284, 1188, 286, 978, 265, 204, 125, 1171, + /* 2100 */ 241, 230, 972, 1175, 28, 1160, 29, 1179, 175, 1173, + /* 2110 */ 30, 43, 31, 1178, 241, 32, 41, 549, 8, 33, + /* 2120 */ 208, 111, 175, 1083, 1070, 43, 113, 1068, 240, 114, + /* 2130 */ 1072, 34, 1073, 561, 1124, 118, 271, 36, 18, 1194, + /* 2140 */ 1033, 873, 240, 935, 124, 37, 272, 273, 1617, 572, + /* 2150 */ 183, 153, 394, 1193, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567, + /* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256, + /* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + /* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 194, 276, 277, 278, 216, 194, 194, 217, 194, 194, - /* 10 */ 194, 194, 224, 194, 194, 276, 277, 278, 204, 19, - /* 20 */ 206, 202, 297, 217, 218, 205, 207, 217, 205, 217, - /* 30 */ 218, 31, 217, 218, 217, 218, 29, 217, 218, 39, - /* 40 */ 33, 217, 220, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 312, 19, - /* 60 */ 240, 241, 316, 240, 241, 194, 46, 47, 48, 49, - /* 70 */ 22, 254, 65, 253, 254, 255, 253, 194, 255, 194, - /* 80 */ 263, 258, 259, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 276, 277, - /* 100 */ 278, 285, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 112, 113, 59, 186, 187, 188, 189, 190, - /* 120 */ 191, 310, 239, 317, 318, 196, 86, 198, 88, 317, - /* 130 */ 19, 319, 317, 318, 205, 264, 25, 211, 212, 213, - /* 140 */ 205, 121, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, - /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 240, - /* 170 */ 241, 116, 117, 118, 119, 240, 241, 122, 123, 124, - /* 180 */ 69, 298, 253, 194, 255, 106, 107, 132, 253, 141, - /* 190 */ 255, 54, 55, 56, 57, 58, 207, 268, 102, 103, - /* 200 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 210 */ 214, 128, 129, 102, 103, 104, 105, 106, 107, 108, - /* 220 */ 109, 110, 111, 112, 113, 134, 25, 136, 137, 300, - /* 230 */ 165, 166, 153, 19, 155, 54, 55, 56, 57, 102, - /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 250 */ 113, 108, 109, 110, 111, 112, 113, 43, 44, 45, - /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 270 */ 56, 57, 276, 277, 278, 113, 194, 19, 22, 23, - /* 280 */ 194, 67, 24, 102, 103, 104, 105, 106, 107, 108, - /* 290 */ 109, 110, 111, 112, 113, 220, 250, 59, 252, 217, - /* 300 */ 218, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, - /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 106, 107, - /* 330 */ 108, 109, 110, 111, 112, 113, 254, 59, 205, 138, - /* 340 */ 139, 19, 20, 194, 22, 263, 22, 23, 231, 25, - /* 350 */ 72, 276, 277, 278, 116, 117, 118, 101, 36, 76, - /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 370 */ 112, 113, 89, 240, 241, 92, 73, 194, 194, 73, - /* 380 */ 19, 59, 188, 189, 190, 191, 253, 81, 255, 151, - /* 390 */ 196, 25, 198, 71, 116, 117, 118, 311, 312, 205, - /* 400 */ 217, 218, 316, 81, 43, 44, 45, 46, 47, 48, - /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 270, - /* 420 */ 22, 23, 100, 25, 59, 101, 138, 139, 106, 107, - /* 430 */ 127, 128, 129, 127, 240, 241, 114, 254, 116, 117, - /* 440 */ 118, 76, 76, 121, 138, 139, 263, 253, 264, 255, - /* 450 */ 205, 275, 87, 19, 89, 89, 194, 92, 92, 199, - /* 460 */ 138, 139, 268, 102, 103, 104, 105, 106, 107, 108, - /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, - /* 480 */ 81, 116, 117, 118, 129, 240, 241, 224, 19, 226, - /* 490 */ 314, 315, 23, 25, 300, 59, 22, 234, 253, 101, - /* 500 */ 255, 236, 237, 26, 194, 183, 194, 152, 72, 22, - /* 510 */ 145, 150, 43, 44, 45, 46, 47, 48, 49, 50, - /* 520 */ 51, 52, 53, 54, 55, 56, 57, 217, 218, 217, - /* 530 */ 218, 19, 189, 59, 191, 23, 59, 138, 139, 196, - /* 540 */ 135, 198, 232, 283, 232, 140, 59, 287, 205, 275, - /* 550 */ 116, 205, 116, 117, 118, 43, 44, 45, 46, 47, - /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 570 */ 194, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 580 */ 111, 112, 113, 240, 241, 194, 240, 241, 314, 315, - /* 590 */ 116, 117, 118, 116, 117, 118, 253, 194, 255, 253, - /* 600 */ 59, 255, 19, 116, 117, 118, 23, 22, 217, 218, - /* 610 */ 142, 268, 205, 275, 102, 103, 104, 105, 106, 107, - /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 640 */ 57, 19, 194, 300, 59, 23, 119, 240, 241, 122, - /* 650 */ 123, 124, 314, 315, 194, 236, 237, 194, 117, 132, - /* 660 */ 253, 81, 255, 205, 59, 43, 44, 45, 46, 47, - /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 680 */ 217, 218, 194, 194, 194, 102, 103, 104, 105, 106, - /* 690 */ 107, 108, 109, 110, 111, 112, 113, 294, 240, 241, - /* 700 */ 120, 116, 117, 118, 59, 194, 217, 218, 211, 212, - /* 710 */ 213, 253, 19, 255, 194, 19, 23, 254, 138, 139, - /* 720 */ 24, 232, 117, 194, 102, 103, 104, 105, 106, 107, - /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 750 */ 57, 19, 264, 108, 76, 23, 127, 128, 129, 311, - /* 760 */ 312, 116, 117, 118, 316, 87, 306, 89, 308, 194, - /* 770 */ 92, 22, 59, 194, 22, 43, 44, 45, 46, 47, - /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 790 */ 194, 95, 217, 218, 265, 102, 103, 104, 105, 106, - /* 800 */ 107, 108, 109, 110, 111, 112, 113, 232, 59, 113, - /* 810 */ 25, 59, 194, 217, 218, 119, 120, 121, 122, 123, - /* 820 */ 124, 125, 19, 145, 194, 194, 23, 131, 232, 116, - /* 830 */ 117, 118, 35, 194, 102, 103, 104, 105, 106, 107, - /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 860 */ 57, 19, 194, 66, 194, 116, 117, 118, 116, 117, - /* 870 */ 118, 74, 242, 294, 194, 194, 206, 23, 194, 25, - /* 880 */ 194, 111, 112, 113, 25, 43, 44, 45, 46, 47, - /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 900 */ 24, 194, 194, 217, 218, 102, 103, 104, 105, 106, - /* 910 */ 107, 108, 109, 110, 111, 112, 113, 241, 232, 194, - /* 920 */ 212, 213, 242, 242, 217, 218, 242, 130, 11, 253, - /* 930 */ 194, 255, 19, 265, 149, 59, 306, 194, 308, 232, - /* 940 */ 309, 310, 217, 218, 102, 103, 104, 105, 106, 107, - /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, - /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 970 */ 57, 194, 194, 59, 194, 239, 19, 194, 25, 254, - /* 980 */ 303, 304, 23, 194, 25, 126, 306, 306, 308, 308, - /* 990 */ 306, 271, 308, 117, 286, 217, 218, 217, 218, 194, - /* 1000 */ 194, 159, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, - /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 59, 239, 194, - /* 1030 */ 116, 117, 118, 260, 254, 194, 240, 241, 194, 233, - /* 1040 */ 205, 240, 241, 205, 239, 128, 129, 270, 265, 253, - /* 1050 */ 194, 255, 217, 218, 253, 194, 255, 143, 280, 102, - /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 1070 */ 113, 118, 159, 217, 218, 240, 241, 118, 240, 241, - /* 1080 */ 194, 194, 194, 239, 116, 117, 118, 22, 253, 254, - /* 1090 */ 255, 253, 19, 255, 233, 194, 143, 24, 263, 212, - /* 1100 */ 213, 194, 143, 217, 218, 217, 218, 261, 262, 271, - /* 1110 */ 254, 143, 19, 7, 8, 9, 43, 44, 45, 46, - /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1130 */ 57, 16, 19, 22, 23, 294, 43, 44, 45, 46, - /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1150 */ 57, 312, 194, 214, 21, 316, 43, 44, 45, 46, - /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 1170 */ 57, 106, 107, 286, 194, 102, 103, 104, 105, 106, - /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 207, 158, 59, - /* 1190 */ 160, 22, 77, 24, 79, 102, 103, 104, 105, 106, - /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 194, 194, 229, - /* 1210 */ 194, 231, 101, 80, 22, 102, 103, 104, 105, 106, - /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 288, 59, 12, - /* 1230 */ 217, 218, 293, 217, 218, 19, 106, 107, 59, 19, - /* 1240 */ 16, 127, 128, 129, 27, 115, 116, 117, 118, 194, - /* 1250 */ 120, 59, 22, 194, 24, 194, 123, 100, 128, 42, - /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1270 */ 54, 55, 56, 57, 117, 194, 217, 218, 121, 100, - /* 1280 */ 63, 194, 245, 153, 194, 155, 117, 19, 115, 194, - /* 1290 */ 73, 214, 194, 256, 161, 116, 117, 194, 217, 218, - /* 1300 */ 121, 77, 194, 79, 217, 218, 194, 217, 218, 117, - /* 1310 */ 153, 154, 155, 254, 46, 217, 218, 144, 102, 103, - /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - /* 1330 */ 232, 270, 153, 154, 155, 115, 116, 66, 19, 20, - /* 1340 */ 183, 22, 12, 312, 254, 194, 262, 316, 209, 210, - /* 1350 */ 266, 239, 194, 194, 108, 36, 85, 27, 19, 20, - /* 1360 */ 265, 22, 183, 245, 144, 94, 25, 48, 217, 218, - /* 1370 */ 293, 194, 42, 270, 256, 36, 217, 218, 59, 194, - /* 1380 */ 25, 135, 194, 115, 194, 161, 140, 194, 194, 15, - /* 1390 */ 71, 194, 312, 63, 217, 218, 316, 194, 59, 131, - /* 1400 */ 301, 302, 217, 218, 85, 217, 218, 217, 218, 90, - /* 1410 */ 71, 217, 218, 19, 217, 218, 245, 146, 262, 100, - /* 1420 */ 217, 218, 266, 265, 85, 106, 107, 256, 312, 90, - /* 1430 */ 209, 210, 316, 114, 60, 116, 117, 118, 194, 100, - /* 1440 */ 121, 194, 194, 145, 115, 106, 107, 19, 46, 19, - /* 1450 */ 20, 24, 22, 114, 194, 116, 117, 118, 194, 245, - /* 1460 */ 121, 194, 164, 194, 217, 218, 36, 194, 258, 259, - /* 1470 */ 256, 194, 153, 154, 155, 156, 157, 217, 218, 150, - /* 1480 */ 31, 217, 218, 142, 217, 218, 217, 218, 39, 59, - /* 1490 */ 217, 218, 153, 154, 155, 156, 157, 149, 150, 5, - /* 1500 */ 145, 71, 183, 245, 10, 11, 12, 13, 14, 194, - /* 1510 */ 116, 17, 129, 227, 256, 85, 194, 115, 194, 23, - /* 1520 */ 90, 25, 183, 99, 30, 97, 32, 22, 22, 194, - /* 1530 */ 100, 194, 217, 218, 40, 152, 106, 107, 23, 217, - /* 1540 */ 218, 194, 19, 20, 114, 22, 116, 117, 118, 257, - /* 1550 */ 194, 121, 217, 218, 217, 218, 194, 133, 53, 36, - /* 1560 */ 23, 23, 25, 25, 70, 120, 121, 61, 141, 7, - /* 1570 */ 8, 121, 78, 217, 218, 81, 23, 227, 25, 217, - /* 1580 */ 218, 131, 59, 153, 154, 155, 156, 157, 0, 1, - /* 1590 */ 2, 59, 98, 5, 71, 23, 227, 25, 10, 11, - /* 1600 */ 12, 13, 14, 83, 84, 17, 23, 23, 25, 25, - /* 1610 */ 59, 194, 194, 183, 23, 23, 25, 25, 30, 194, - /* 1620 */ 32, 19, 20, 100, 22, 194, 194, 133, 40, 106, - /* 1630 */ 107, 108, 138, 139, 194, 217, 218, 114, 36, 116, - /* 1640 */ 117, 118, 217, 218, 121, 194, 194, 194, 23, 117, - /* 1650 */ 25, 194, 23, 23, 25, 25, 162, 194, 70, 194, - /* 1660 */ 145, 59, 23, 153, 25, 155, 78, 194, 117, 81, - /* 1670 */ 217, 218, 194, 71, 217, 218, 153, 154, 155, 156, - /* 1680 */ 157, 194, 217, 218, 194, 23, 98, 25, 321, 194, - /* 1690 */ 217, 218, 194, 19, 20, 194, 22, 153, 23, 155, - /* 1700 */ 25, 194, 100, 194, 217, 218, 183, 194, 106, 107, - /* 1710 */ 36, 194, 217, 218, 237, 194, 114, 243, 116, 117, - /* 1720 */ 118, 133, 194, 121, 217, 218, 138, 139, 194, 194, - /* 1730 */ 194, 290, 289, 59, 217, 218, 194, 194, 217, 218, - /* 1740 */ 194, 194, 140, 194, 194, 71, 194, 244, 194, 194, - /* 1750 */ 162, 217, 218, 194, 194, 153, 154, 155, 156, 157, - /* 1760 */ 217, 218, 194, 217, 218, 194, 217, 218, 257, 217, - /* 1770 */ 218, 217, 218, 257, 100, 194, 257, 217, 218, 257, - /* 1780 */ 106, 107, 215, 299, 194, 183, 192, 194, 114, 194, - /* 1790 */ 116, 117, 118, 1, 2, 121, 221, 5, 217, 218, - /* 1800 */ 273, 197, 10, 11, 12, 13, 14, 217, 218, 17, - /* 1810 */ 217, 218, 217, 218, 140, 194, 246, 194, 273, 295, - /* 1820 */ 247, 273, 30, 247, 32, 269, 269, 153, 154, 155, - /* 1830 */ 156, 157, 40, 246, 273, 295, 230, 226, 217, 218, - /* 1840 */ 217, 218, 220, 261, 220, 282, 220, 19, 20, 244, - /* 1850 */ 22, 250, 141, 250, 246, 60, 201, 183, 261, 261, - /* 1860 */ 261, 201, 70, 299, 36, 299, 201, 38, 151, 150, - /* 1870 */ 78, 285, 22, 81, 296, 296, 43, 235, 18, 238, - /* 1880 */ 201, 274, 272, 238, 238, 238, 18, 59, 200, 149, - /* 1890 */ 98, 247, 274, 274, 235, 247, 247, 247, 235, 71, - /* 1900 */ 272, 201, 200, 158, 292, 62, 291, 201, 200, 22, - /* 1910 */ 201, 222, 200, 222, 201, 200, 115, 219, 219, 64, - /* 1920 */ 219, 228, 22, 126, 221, 133, 165, 222, 100, 225, - /* 1930 */ 138, 139, 225, 219, 106, 107, 24, 219, 228, 219, - /* 1940 */ 219, 307, 114, 113, 116, 117, 118, 315, 284, 121, - /* 1950 */ 284, 222, 201, 91, 162, 320, 320, 82, 148, 267, - /* 1960 */ 145, 267, 22, 279, 201, 158, 281, 251, 147, 146, - /* 1970 */ 25, 203, 250, 249, 251, 248, 13, 247, 195, 195, - /* 1980 */ 6, 153, 154, 155, 156, 157, 193, 193, 305, 193, - /* 1990 */ 208, 305, 302, 214, 214, 214, 208, 223, 223, 214, - /* 2000 */ 4, 215, 215, 214, 3, 22, 208, 163, 15, 23, - /* 2010 */ 16, 183, 23, 139, 151, 130, 25, 20, 142, 24, - /* 2020 */ 16, 144, 1, 142, 130, 130, 61, 37, 53, 151, - /* 2030 */ 53, 53, 53, 130, 116, 1, 34, 141, 5, 22, - /* 2040 */ 115, 161, 75, 25, 68, 141, 41, 115, 68, 24, - /* 2050 */ 20, 19, 131, 125, 67, 67, 96, 22, 22, 22, - /* 2060 */ 37, 23, 22, 24, 22, 59, 67, 23, 149, 28, - /* 2070 */ 22, 25, 23, 23, 23, 22, 141, 34, 97, 23, - /* 2080 */ 23, 34, 116, 22, 143, 25, 34, 75, 34, 34, - /* 2090 */ 75, 88, 34, 86, 23, 22, 34, 25, 24, 34, - /* 2100 */ 25, 93, 23, 44, 142, 23, 142, 23, 23, 22, - /* 2110 */ 11, 25, 23, 25, 23, 22, 22, 22, 1, 23, - /* 2120 */ 23, 23, 22, 22, 15, 141, 141, 25, 25, 1, - /* 2130 */ 322, 322, 322, 135, 322, 322, 322, 322, 322, 322, - /* 2140 */ 322, 141, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2150 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2160 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2180 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2190 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2200 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 0 */ 276, 277, 278, 240, 241, 224, 194, 226, 194, 240, + /* 10 */ 241, 194, 216, 220, 194, 234, 253, 194, 255, 19, + /* 20 */ 224, 297, 253, 194, 255, 205, 212, 213, 205, 217, + /* 30 */ 218, 31, 205, 194, 217, 218, 194, 217, 218, 39, + /* 40 */ 217, 218, 312, 43, 44, 45, 316, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19, + /* 60 */ 240, 241, 194, 240, 241, 194, 254, 240, 241, 276, + /* 70 */ 277, 278, 233, 253, 254, 255, 253, 254, 255, 217, + /* 80 */ 253, 239, 255, 43, 44, 45, 263, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 270, + /* 100 */ 286, 22, 23, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 114, 82, 47, 48, 49, 50, + /* 120 */ 186, 187, 188, 189, 190, 191, 189, 87, 191, 89, + /* 130 */ 196, 19, 198, 196, 317, 198, 319, 25, 194, 205, + /* 140 */ 298, 270, 205, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 11, 47, + /* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 170 */ 58, 60, 139, 140, 240, 241, 214, 240, 241, 311, + /* 180 */ 312, 102, 70, 239, 316, 194, 19, 253, 77, 255, + /* 190 */ 253, 122, 255, 55, 56, 57, 58, 59, 207, 88, + /* 200 */ 194, 90, 268, 194, 93, 268, 107, 108, 109, 110, + /* 210 */ 111, 112, 113, 114, 47, 103, 104, 105, 106, 107, + /* 220 */ 108, 109, 110, 111, 112, 113, 114, 114, 117, 118, + /* 230 */ 119, 276, 277, 278, 300, 19, 194, 300, 276, 277, + /* 240 */ 278, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 194, 43, + /* 260 */ 44, 45, 47, 47, 48, 49, 50, 51, 52, 53, + /* 270 */ 54, 55, 56, 57, 58, 82, 129, 130, 60, 129, + /* 280 */ 130, 217, 218, 116, 68, 25, 103, 104, 105, 106, + /* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 23, 132, + /* 300 */ 294, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 310 */ 112, 113, 114, 217, 121, 306, 194, 308, 26, 103, + /* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 330 */ 114, 116, 139, 140, 217, 117, 118, 119, 120, 19, + /* 340 */ 194, 123, 124, 125, 24, 109, 110, 111, 112, 113, + /* 350 */ 114, 133, 60, 311, 312, 250, 194, 252, 316, 19, + /* 360 */ 194, 166, 167, 43, 44, 45, 205, 47, 48, 49, + /* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 217, + /* 380 */ 218, 317, 318, 43, 44, 45, 264, 47, 48, 49, + /* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 139, + /* 400 */ 140, 240, 241, 139, 140, 188, 189, 190, 191, 117, + /* 410 */ 118, 119, 231, 196, 253, 198, 255, 194, 194, 258, + /* 420 */ 259, 146, 205, 103, 104, 105, 106, 107, 108, 109, + /* 430 */ 110, 111, 112, 113, 114, 109, 212, 213, 236, 237, + /* 440 */ 217, 218, 194, 103, 104, 105, 106, 107, 108, 109, + /* 450 */ 110, 111, 112, 113, 114, 194, 120, 240, 241, 123, + /* 460 */ 124, 125, 136, 194, 19, 74, 60, 141, 23, 133, + /* 470 */ 253, 194, 255, 82, 194, 309, 310, 254, 29, 317, + /* 480 */ 318, 194, 33, 22, 199, 268, 263, 239, 43, 44, + /* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54, + /* 500 */ 55, 56, 57, 58, 217, 218, 194, 60, 19, 146, + /* 510 */ 286, 242, 23, 107, 108, 66, 204, 300, 206, 128, + /* 520 */ 73, 60, 116, 117, 118, 119, 265, 121, 165, 60, + /* 530 */ 139, 140, 43, 44, 45, 129, 47, 48, 49, 50, + /* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104, + /* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 560 */ 154, 194, 156, 194, 117, 118, 119, 280, 283, 205, + /* 570 */ 101, 220, 287, 19, 20, 306, 22, 308, 117, 118, + /* 580 */ 119, 211, 212, 213, 217, 218, 117, 118, 236, 237, + /* 590 */ 36, 122, 103, 104, 105, 106, 107, 108, 109, 110, + /* 600 */ 111, 112, 113, 114, 240, 241, 194, 60, 194, 194, + /* 610 */ 194, 194, 19, 194, 60, 194, 23, 253, 206, 255, + /* 620 */ 73, 254, 19, 154, 155, 156, 72, 276, 277, 278, + /* 630 */ 263, 217, 218, 217, 218, 271, 43, 44, 45, 271, + /* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 650 */ 57, 58, 183, 194, 285, 101, 19, 214, 60, 242, + /* 660 */ 23, 107, 108, 109, 117, 118, 119, 16, 254, 115, + /* 670 */ 254, 117, 118, 119, 194, 60, 122, 263, 205, 264, + /* 680 */ 43, 44, 45, 264, 47, 48, 49, 50, 51, 52, + /* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106, + /* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155, + /* 710 */ 156, 157, 158, 240, 241, 117, 118, 119, 101, 205, + /* 720 */ 117, 19, 20, 306, 22, 308, 253, 74, 255, 78, + /* 730 */ 205, 80, 117, 118, 119, 118, 293, 183, 36, 122, + /* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 750 */ 113, 114, 194, 294, 240, 241, 211, 212, 213, 144, + /* 760 */ 19, 23, 60, 25, 23, 240, 241, 253, 245, 255, + /* 770 */ 15, 154, 155, 156, 72, 217, 218, 194, 253, 256, + /* 780 */ 255, 128, 129, 130, 43, 44, 45, 22, 47, 48, + /* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 800 */ 183, 19, 77, 101, 19, 128, 129, 130, 23, 107, + /* 810 */ 108, 60, 254, 88, 21, 90, 61, 115, 93, 117, + /* 820 */ 118, 119, 239, 22, 122, 60, 194, 205, 43, 44, + /* 830 */ 45, 205, 47, 48, 49, 50, 51, 52, 53, 54, + /* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108, + /* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157, + /* 860 */ 158, 60, 240, 241, 60, 116, 240, 241, 117, 118, + /* 870 */ 119, 146, 194, 19, 81, 253, 275, 255, 24, 253, + /* 880 */ 98, 255, 117, 118, 119, 183, 22, 194, 103, 104, + /* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + /* 900 */ 151, 194, 270, 152, 22, 23, 194, 25, 19, 202, + /* 910 */ 217, 218, 23, 109, 207, 314, 315, 124, 117, 118, + /* 920 */ 119, 117, 118, 119, 60, 232, 22, 23, 19, 25, + /* 930 */ 303, 304, 43, 44, 45, 22, 47, 48, 49, 50, + /* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 270, 227, + /* 950 */ 96, 60, 43, 44, 45, 162, 47, 48, 49, 50, + /* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 112, + /* 970 */ 113, 114, 194, 60, 120, 121, 122, 123, 124, 125, + /* 980 */ 126, 117, 118, 119, 102, 25, 132, 107, 108, 194, + /* 990 */ 194, 227, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1000 */ 111, 112, 113, 114, 194, 194, 102, 194, 117, 118, + /* 1010 */ 119, 233, 103, 104, 105, 106, 107, 108, 109, 110, + /* 1020 */ 111, 112, 113, 114, 194, 194, 19, 194, 217, 218, + /* 1030 */ 117, 118, 119, 241, 154, 144, 156, 135, 242, 137, + /* 1040 */ 138, 130, 19, 232, 194, 253, 23, 255, 217, 218, + /* 1050 */ 217, 218, 242, 16, 7, 8, 9, 25, 261, 262, + /* 1060 */ 265, 194, 19, 232, 153, 232, 43, 44, 45, 160, + /* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1080 */ 57, 58, 194, 227, 217, 218, 43, 44, 45, 194, + /* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1100 */ 57, 58, 306, 143, 308, 217, 218, 294, 12, 77, + /* 1110 */ 22, 23, 217, 218, 194, 78, 306, 80, 308, 194, + /* 1120 */ 232, 254, 90, 27, 117, 93, 103, 104, 105, 106, + /* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 194, + /* 1140 */ 35, 194, 217, 218, 214, 194, 103, 104, 105, 106, + /* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 194, 239, + /* 1160 */ 64, 194, 217, 218, 217, 218, 209, 210, 217, 218, + /* 1170 */ 74, 207, 67, 22, 194, 77, 19, 232, 245, 232, + /* 1180 */ 75, 24, 312, 232, 217, 218, 316, 25, 90, 256, + /* 1190 */ 102, 93, 159, 229, 161, 231, 19, 217, 218, 162, + /* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52, + /* 1210 */ 53, 54, 55, 56, 57, 58, 19, 23, 288, 25, + /* 1220 */ 43, 44, 45, 293, 47, 48, 49, 50, 51, 52, + /* 1230 */ 53, 54, 55, 56, 57, 58, 131, 22, 275, 24, + /* 1240 */ 43, 44, 45, 194, 47, 48, 49, 50, 51, 52, + /* 1250 */ 53, 54, 55, 56, 57, 58, 194, 194, 107, 108, + /* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1270 */ 113, 114, 194, 25, 194, 60, 194, 314, 315, 194, + /* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1290 */ 113, 114, 19, 194, 194, 217, 218, 217, 218, 25, + /* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1310 */ 113, 114, 150, 119, 265, 312, 67, 217, 218, 316, + /* 1320 */ 19, 239, 194, 194, 128, 129, 130, 265, 265, 209, + /* 1330 */ 210, 31, 254, 118, 254, 86, 60, 194, 144, 39, + /* 1340 */ 19, 130, 275, 312, 95, 44, 45, 316, 47, 48, + /* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1360 */ 217, 218, 24, 194, 153, 12, 45, 119, 47, 48, + /* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + /* 1380 */ 27, 314, 315, 22, 312, 24, 217, 218, 316, 116, + /* 1390 */ 117, 22, 144, 25, 118, 42, 147, 194, 60, 19, + /* 1400 */ 20, 127, 22, 194, 103, 104, 105, 106, 107, 108, + /* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 194, + /* 1420 */ 217, 218, 194, 54, 103, 104, 105, 106, 107, 108, + /* 1430 */ 109, 110, 111, 112, 113, 114, 194, 22, 310, 25, + /* 1440 */ 60, 194, 217, 218, 194, 217, 218, 194, 260, 194, + /* 1450 */ 301, 302, 72, 262, 262, 194, 118, 266, 266, 217, + /* 1460 */ 218, 194, 82, 245, 217, 218, 194, 217, 218, 194, + /* 1470 */ 217, 218, 217, 218, 256, 60, 24, 194, 217, 218, + /* 1480 */ 194, 101, 194, 245, 217, 218, 194, 107, 108, 217, + /* 1490 */ 218, 22, 217, 218, 256, 115, 245, 117, 118, 119, + /* 1500 */ 217, 218, 122, 217, 218, 217, 218, 256, 22, 217, + /* 1510 */ 218, 116, 258, 259, 146, 19, 20, 194, 22, 139, + /* 1520 */ 140, 150, 151, 136, 23, 194, 25, 194, 141, 194, + /* 1530 */ 194, 62, 36, 118, 154, 155, 156, 157, 158, 100, + /* 1540 */ 145, 194, 154, 194, 156, 49, 194, 23, 194, 25, + /* 1550 */ 217, 218, 217, 218, 194, 257, 60, 143, 194, 60, + /* 1560 */ 194, 121, 122, 183, 217, 218, 217, 218, 72, 217, + /* 1570 */ 218, 217, 218, 134, 23, 194, 25, 217, 218, 7, + /* 1580 */ 8, 321, 86, 217, 218, 194, 122, 91, 19, 20, + /* 1590 */ 23, 22, 25, 23, 142, 25, 132, 101, 217, 218, + /* 1600 */ 194, 194, 194, 107, 108, 36, 194, 194, 217, 218, + /* 1610 */ 194, 115, 194, 117, 118, 119, 194, 118, 122, 194, + /* 1620 */ 23, 194, 25, 217, 218, 217, 218, 194, 142, 60, + /* 1630 */ 217, 218, 194, 217, 218, 217, 218, 84, 85, 217, + /* 1640 */ 218, 72, 217, 218, 217, 218, 60, 23, 60, 25, + /* 1650 */ 154, 155, 156, 157, 158, 86, 154, 194, 156, 194, + /* 1660 */ 91, 19, 20, 23, 22, 25, 194, 23, 194, 25, + /* 1670 */ 101, 23, 194, 25, 194, 194, 107, 108, 36, 183, + /* 1680 */ 217, 218, 217, 218, 115, 194, 117, 118, 119, 217, + /* 1690 */ 218, 122, 194, 237, 194, 217, 218, 217, 218, 194, + /* 1700 */ 194, 23, 60, 25, 118, 23, 118, 25, 217, 218, + /* 1710 */ 23, 194, 25, 194, 72, 217, 218, 217, 218, 23, + /* 1720 */ 194, 25, 194, 154, 155, 156, 157, 158, 86, 23, + /* 1730 */ 194, 25, 194, 91, 217, 218, 217, 218, 194, 194, + /* 1740 */ 194, 194, 194, 101, 194, 217, 218, 290, 194, 107, + /* 1750 */ 108, 194, 183, 217, 218, 194, 194, 115, 194, 117, + /* 1760 */ 118, 119, 194, 243, 122, 194, 289, 194, 194, 194, + /* 1770 */ 194, 257, 257, 257, 244, 257, 192, 273, 215, 269, + /* 1780 */ 246, 299, 269, 295, 247, 273, 247, 246, 295, 230, + /* 1790 */ 261, 226, 261, 261, 273, 273, 154, 155, 156, 157, + /* 1800 */ 158, 0, 1, 2, 221, 220, 5, 220, 250, 220, + /* 1810 */ 261, 10, 11, 12, 13, 14, 250, 282, 17, 197, + /* 1820 */ 61, 19, 20, 246, 22, 183, 244, 142, 201, 201, + /* 1830 */ 38, 30, 299, 32, 201, 152, 22, 151, 36, 299, + /* 1840 */ 43, 40, 235, 18, 238, 285, 238, 238, 296, 238, + /* 1850 */ 201, 296, 274, 272, 18, 200, 235, 150, 235, 247, + /* 1860 */ 247, 247, 60, 247, 274, 274, 272, 201, 200, 159, + /* 1870 */ 63, 292, 71, 201, 72, 200, 22, 201, 222, 200, + /* 1880 */ 79, 201, 222, 82, 291, 116, 219, 65, 200, 219, + /* 1890 */ 219, 228, 22, 127, 225, 166, 222, 24, 225, 114, + /* 1900 */ 99, 284, 221, 101, 284, 228, 307, 315, 219, 107, + /* 1910 */ 108, 219, 219, 219, 201, 92, 320, 115, 320, 117, + /* 1920 */ 118, 119, 222, 83, 122, 267, 267, 149, 146, 19, + /* 1930 */ 20, 22, 22, 279, 250, 134, 201, 148, 159, 249, + /* 1940 */ 139, 140, 251, 141, 25, 281, 36, 147, 251, 248, + /* 1950 */ 247, 203, 13, 195, 6, 195, 154, 155, 156, 157, + /* 1960 */ 158, 193, 305, 193, 163, 193, 305, 302, 214, 208, + /* 1970 */ 60, 214, 208, 223, 223, 4, 214, 214, 3, 22, + /* 1980 */ 215, 214, 72, 208, 164, 183, 215, 15, 23, 16, + /* 1990 */ 23, 140, 131, 152, 25, 143, 20, 16, 24, 1, + /* 2000 */ 145, 143, 131, 131, 62, 37, 54, 54, 152, 54, + /* 2010 */ 54, 101, 131, 117, 34, 1, 142, 107, 108, 22, + /* 2020 */ 5, 116, 162, 69, 25, 115, 76, 117, 118, 119, + /* 2030 */ 1, 2, 122, 69, 5, 41, 142, 116, 20, 10, + /* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126, + /* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30, + /* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40, + /* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68, + /* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23, + /* 2090 */ 22, 98, 23, 183, 23, 117, 34, 22, 25, 89, + /* 2100 */ 71, 142, 144, 76, 34, 23, 34, 76, 79, 87, + /* 2110 */ 34, 82, 34, 94, 71, 34, 22, 24, 44, 34, + /* 2120 */ 25, 25, 79, 23, 23, 82, 143, 23, 99, 143, + /* 2130 */ 23, 22, 11, 25, 23, 25, 22, 22, 22, 1, + /* 2140 */ 23, 23, 99, 136, 22, 22, 142, 142, 142, 25, + /* 2150 */ 25, 23, 15, 1, 322, 322, 322, 322, 322, 322, + /* 2160 */ 322, 322, 322, 134, 322, 322, 322, 322, 139, 140, + /* 2170 */ 322, 322, 322, 322, 322, 322, 322, 134, 322, 322, + /* 2180 */ 322, 322, 139, 140, 322, 322, 322, 322, 322, 322, + /* 2190 */ 322, 322, 163, 322, 322, 322, 322, 322, 322, 322, + /* 2200 */ 322, 322, 322, 322, 322, 322, 163, 322, 322, 322, /* 2210 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2220 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2230 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, @@ -173527,118 +174848,125 @@ static const YYCODETYPE yy_lookahead[] = { /* 2290 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2300 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, /* 2310 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, + /* 2320 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2330 */ 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, + /* 2340 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2350 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2360 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2370 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2380 */ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + /* 2390 */ 186, 186, 186, }; #define YY_SHIFT_COUNT (582) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2128) +#define YY_SHIFT_MAX (2152) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1792, 1588, 1494, 322, 322, 399, 306, 1319, 1339, 1430, - /* 10 */ 1828, 1828, 1828, 580, 399, 399, 399, 399, 399, 0, - /* 20 */ 0, 214, 1093, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 30 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1130, 1130, - /* 40 */ 365, 365, 55, 278, 436, 713, 713, 201, 201, 201, - /* 50 */ 201, 40, 111, 258, 361, 469, 512, 583, 622, 693, - /* 60 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, - /* 70 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, - /* 80 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1523, 1602, - /* 90 */ 1674, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 100 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 110 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 120 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 130 */ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828, - /* 140 */ 137, 181, 181, 181, 181, 181, 181, 181, 96, 222, - /* 150 */ 143, 477, 713, 1133, 1268, 713, 713, 79, 79, 713, - /* 160 */ 770, 83, 65, 65, 65, 288, 162, 162, 2142, 2142, - /* 170 */ 696, 696, 696, 238, 474, 474, 474, 474, 1217, 1217, - /* 180 */ 678, 477, 324, 398, 713, 713, 713, 713, 713, 713, - /* 190 */ 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, - /* 200 */ 713, 713, 713, 1220, 366, 366, 713, 917, 283, 283, - /* 210 */ 434, 434, 605, 605, 1298, 2142, 2142, 2142, 2142, 2142, - /* 220 */ 2142, 2142, 1179, 1157, 1157, 487, 527, 585, 645, 749, - /* 230 */ 914, 968, 752, 713, 713, 713, 713, 713, 713, 713, - /* 240 */ 713, 713, 713, 303, 713, 713, 713, 713, 713, 713, - /* 250 */ 713, 713, 713, 713, 713, 713, 797, 797, 797, 713, - /* 260 */ 713, 713, 959, 713, 713, 713, 1169, 1271, 713, 713, - /* 270 */ 1330, 713, 713, 713, 713, 713, 713, 713, 713, 629, - /* 280 */ 7, 91, 876, 876, 876, 876, 953, 91, 91, 1246, - /* 290 */ 1065, 1106, 1374, 1329, 1348, 468, 1348, 1394, 785, 1329, - /* 300 */ 1329, 785, 1329, 468, 1394, 859, 854, 1402, 1449, 1449, - /* 310 */ 1449, 1173, 1173, 1173, 1173, 1355, 1355, 1030, 1341, 405, - /* 320 */ 1230, 1795, 1795, 1711, 1711, 1829, 1829, 1711, 1717, 1719, - /* 330 */ 1850, 1833, 1860, 1860, 1860, 1860, 1711, 1868, 1740, 1719, - /* 340 */ 1719, 1740, 1850, 1833, 1740, 1833, 1740, 1711, 1868, 1745, - /* 350 */ 1843, 1711, 1868, 1887, 1711, 1868, 1711, 1868, 1887, 1801, - /* 360 */ 1801, 1801, 1855, 1900, 1900, 1887, 1801, 1797, 1801, 1855, - /* 370 */ 1801, 1801, 1761, 1912, 1830, 1830, 1887, 1711, 1862, 1862, - /* 380 */ 1875, 1875, 1810, 1815, 1940, 1711, 1807, 1810, 1821, 1823, - /* 390 */ 1740, 1945, 1963, 1963, 1974, 1974, 1974, 2142, 2142, 2142, - /* 400 */ 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, 2142, - /* 410 */ 2142, 2142, 20, 1224, 256, 1111, 1115, 1114, 1192, 1496, - /* 420 */ 1424, 1505, 1427, 355, 1383, 1537, 1506, 1538, 1553, 1583, - /* 430 */ 1584, 1591, 1625, 541, 1445, 1562, 1450, 1572, 1515, 1428, - /* 440 */ 1532, 1592, 1629, 1520, 1630, 1639, 1510, 1544, 1662, 1675, - /* 450 */ 1551, 48, 1996, 2001, 1983, 1844, 1993, 1994, 1986, 1989, - /* 460 */ 1874, 1863, 1885, 1991, 1991, 1995, 1876, 1997, 1877, 2004, - /* 470 */ 2021, 1881, 1894, 1991, 1895, 1965, 1990, 1991, 1878, 1975, - /* 480 */ 1977, 1978, 1979, 1903, 1918, 2002, 1896, 2034, 2033, 2017, - /* 490 */ 1925, 1880, 1976, 2018, 1980, 1967, 2005, 1904, 1932, 2025, - /* 500 */ 2030, 2032, 1921, 1928, 2035, 1987, 2036, 2037, 2038, 2040, - /* 510 */ 1988, 2006, 2039, 1960, 2041, 2042, 1999, 2023, 2044, 2043, - /* 520 */ 1919, 2048, 2049, 2050, 2046, 2051, 2053, 1981, 1935, 2056, - /* 530 */ 2057, 1966, 2047, 2061, 1941, 2060, 2052, 2054, 2055, 2058, - /* 540 */ 2003, 2012, 2007, 2059, 2015, 2008, 2062, 2071, 2073, 2074, - /* 550 */ 2072, 2075, 2065, 1962, 1964, 2079, 2060, 2082, 2084, 2085, - /* 560 */ 2087, 2086, 2089, 2088, 2091, 2093, 2099, 2094, 2095, 2096, - /* 570 */ 2097, 2100, 2101, 2102, 1998, 1984, 1985, 2000, 2103, 2098, - /* 580 */ 2109, 2117, 2128, + /* 0 */ 2029, 1801, 2043, 1380, 1380, 33, 391, 1496, 1569, 1642, + /* 10 */ 702, 702, 702, 193, 33, 33, 33, 33, 33, 0, + /* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702, + /* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 406, 406, + /* 40 */ 111, 111, 218, 447, 547, 598, 598, 260, 260, 260, + /* 50 */ 260, 40, 112, 320, 340, 445, 489, 593, 637, 741, + /* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177, + /* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, + /* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554, + /* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702, + /* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, + /* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198, + /* 150 */ 183, 99, 236, 292, 598, 793, 167, 598, 598, 880, + /* 160 */ 880, 598, 857, 150, 195, 195, 195, 264, 113, 113, + /* 170 */ 2207, 2207, 854, 854, 854, 751, 765, 765, 765, 765, + /* 180 */ 1096, 1096, 725, 292, 882, 904, 598, 598, 598, 598, + /* 190 */ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, + /* 200 */ 598, 598, 598, 598, 598, 1273, 1032, 1032, 598, 147, + /* 210 */ 1098, 1098, 603, 603, 1276, 1276, 363, 2207, 2207, 2207, + /* 220 */ 2207, 2207, 2207, 2207, 469, 617, 617, 801, 336, 461, + /* 230 */ 804, 864, 615, 891, 913, 598, 598, 598, 598, 598, + /* 240 */ 598, 598, 598, 598, 598, 653, 598, 598, 598, 598, + /* 250 */ 598, 598, 598, 598, 598, 598, 598, 598, 1105, 1105, + /* 260 */ 1105, 598, 598, 598, 1194, 598, 598, 598, 1215, 1249, + /* 270 */ 598, 1353, 598, 598, 598, 598, 598, 598, 598, 598, + /* 280 */ 677, 449, 902, 1338, 1338, 1338, 1338, 1248, 902, 902, + /* 290 */ 326, 1151, 1047, 755, 749, 1371, 960, 1371, 1007, 1162, + /* 300 */ 749, 749, 1162, 749, 960, 1007, 1274, 738, 215, 1300, + /* 310 */ 1300, 1300, 1395, 1395, 1395, 1395, 1368, 1368, 1033, 1414, + /* 320 */ 1387, 1361, 1759, 1759, 1685, 1685, 1792, 1792, 1685, 1683, + /* 330 */ 1686, 1814, 1797, 1825, 1825, 1825, 1825, 1685, 1836, 1707, + /* 340 */ 1686, 1686, 1707, 1814, 1797, 1707, 1797, 1707, 1685, 1836, + /* 350 */ 1710, 1807, 1685, 1836, 1854, 1685, 1836, 1685, 1836, 1854, + /* 360 */ 1769, 1769, 1769, 1822, 1870, 1870, 1854, 1769, 1766, 1769, + /* 370 */ 1822, 1769, 1769, 1729, 1873, 1785, 1785, 1854, 1685, 1823, + /* 380 */ 1823, 1840, 1840, 1778, 1782, 1909, 1685, 1779, 1778, 1789, + /* 390 */ 1800, 1707, 1919, 1939, 1939, 1948, 1948, 1948, 2207, 2207, + /* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, + /* 410 */ 2207, 2207, 2207, 69, 1037, 79, 1088, 651, 1196, 1415, + /* 420 */ 1501, 1439, 1369, 1452, 911, 1211, 1524, 1469, 1551, 1567, + /* 430 */ 1570, 1624, 1640, 1644, 1499, 1440, 1572, 1464, 1597, 275, + /* 440 */ 782, 1586, 1648, 1678, 1553, 1682, 1687, 1388, 1502, 1696, + /* 450 */ 1706, 1588, 1486, 1971, 1975, 1957, 1820, 1972, 1973, 1965, + /* 460 */ 1967, 1851, 1841, 1861, 1969, 1969, 1974, 1852, 1976, 1855, + /* 470 */ 1981, 1998, 1858, 1871, 1969, 1872, 1942, 1968, 1969, 1856, + /* 480 */ 1952, 1953, 1955, 1956, 1881, 1896, 1980, 1874, 2014, 2015, + /* 490 */ 1997, 1905, 1860, 1954, 1999, 1964, 1950, 1994, 1894, 1921, + /* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047, + /* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057, + /* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1959, + /* 530 */ 2069, 2071, 1978, 2062, 2075, 1958, 2073, 2070, 2072, 2076, + /* 540 */ 2078, 2010, 2027, 2022, 2074, 2031, 2019, 2081, 2082, 2094, + /* 550 */ 2093, 2095, 2096, 2085, 1983, 1986, 2100, 2073, 2101, 2104, + /* 560 */ 2107, 2109, 2108, 2110, 2111, 2114, 2121, 2115, 2116, 2117, + /* 570 */ 2118, 2122, 2123, 2124, 2007, 2004, 2005, 2006, 2125, 2128, + /* 580 */ 2137, 2138, 2152, }; -#define YY_REDUCE_COUNT (411) -#define YY_REDUCE_MIN (-275) -#define YY_REDUCE_MAX (1798) +#define YY_REDUCE_COUNT (412) +#define YY_REDUCE_MIN (-276) +#define YY_REDUCE_MAX (1775) static const short yy_reduce_ofst[] = { - /* 0 */ -71, 194, 343, 835, -180, -177, 838, -194, -188, -185, - /* 10 */ -183, 82, 183, -65, 133, 245, 346, 407, 458, -178, - /* 20 */ 75, -275, -4, 310, 312, 489, 575, 596, 463, 686, - /* 30 */ 707, 725, 780, 1098, 856, 778, 1059, 1090, 708, 887, - /* 40 */ 86, 448, 980, 630, 680, 681, 684, 796, 801, 796, - /* 50 */ 801, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 60 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 70 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 80 */ -261, -261, -261, -261, -261, -261, -261, -261, 391, 886, - /* 90 */ 888, 1013, 1016, 1081, 1087, 1151, 1159, 1177, 1185, 1188, - /* 100 */ 1190, 1194, 1197, 1203, 1247, 1260, 1264, 1267, 1269, 1273, - /* 110 */ 1315, 1322, 1335, 1337, 1356, 1362, 1418, 1425, 1453, 1457, - /* 120 */ 1465, 1473, 1487, 1495, 1507, 1517, 1521, 1534, 1543, 1546, - /* 130 */ 1549, 1552, 1554, 1560, 1581, 1590, 1593, 1595, 1621, 1623, - /* 140 */ -261, -261, -261, -261, -261, -261, -261, -261, -261, -261, - /* 150 */ -261, -186, -117, 260, 263, 460, 631, -74, 497, -181, - /* 160 */ -261, 939, 176, 274, 338, 676, -261, -261, -261, -261, - /* 170 */ -212, -212, -212, -184, 149, 777, 1061, 1103, 265, 419, - /* 180 */ -254, 670, 677, 677, -11, -129, 184, 488, 736, 789, - /* 190 */ 805, 844, 403, 529, 579, 668, 783, 841, 1158, 1112, - /* 200 */ 806, 861, 1095, 846, 839, 1031, -189, 1077, 1080, 1116, - /* 210 */ 1084, 1156, 1139, 1221, 46, 1099, 1037, 1118, 1171, 1214, - /* 220 */ 1210, 1258, -210, -190, -176, -115, 117, 262, 376, 490, - /* 230 */ 511, 520, 618, 639, 743, 901, 907, 958, 1014, 1055, - /* 240 */ 1108, 1193, 1244, 720, 1248, 1277, 1324, 1347, 1417, 1431, - /* 250 */ 1432, 1440, 1451, 1452, 1463, 1478, 1286, 1350, 1369, 1490, - /* 260 */ 1498, 1501, 773, 1509, 1513, 1528, 1292, 1367, 1535, 1536, - /* 270 */ 1477, 1542, 376, 1547, 1550, 1555, 1559, 1568, 1571, 1441, - /* 280 */ 1443, 1474, 1511, 1516, 1519, 1522, 773, 1474, 1474, 1503, - /* 290 */ 1567, 1594, 1484, 1527, 1556, 1570, 1557, 1524, 1573, 1545, - /* 300 */ 1548, 1576, 1561, 1587, 1540, 1575, 1606, 1611, 1622, 1624, - /* 310 */ 1626, 1582, 1597, 1598, 1599, 1601, 1603, 1563, 1608, 1605, - /* 320 */ 1604, 1564, 1566, 1655, 1660, 1578, 1579, 1665, 1586, 1607, - /* 330 */ 1610, 1642, 1641, 1645, 1646, 1647, 1679, 1688, 1644, 1618, - /* 340 */ 1619, 1648, 1628, 1659, 1649, 1663, 1650, 1700, 1702, 1612, - /* 350 */ 1615, 1706, 1708, 1689, 1709, 1712, 1713, 1715, 1691, 1698, - /* 360 */ 1699, 1701, 1693, 1704, 1707, 1705, 1714, 1703, 1718, 1710, - /* 370 */ 1720, 1721, 1632, 1634, 1664, 1666, 1729, 1751, 1635, 1636, - /* 380 */ 1692, 1694, 1716, 1722, 1684, 1763, 1685, 1723, 1724, 1727, - /* 390 */ 1730, 1768, 1783, 1784, 1793, 1794, 1796, 1683, 1686, 1690, - /* 400 */ 1782, 1779, 1780, 1781, 1785, 1788, 1774, 1775, 1786, 1787, - /* 410 */ 1789, 1798, + /* 0 */ -66, 217, -63, -177, -180, 161, 364, 64, -183, 162, + /* 10 */ 223, 367, 414, -173, 473, 514, 525, 622, 626, -207, + /* 20 */ 351, -276, -38, 693, 811, 831, 833, 888, -188, 945, + /* 30 */ 947, 416, 558, 951, 867, 287, 1078, 1080, -186, 224, + /* 40 */ -132, 42, 964, 269, 417, 796, 810, -237, -231, -237, + /* 50 */ -231, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 60 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 70 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + /* 80 */ -45, -45, -45, -45, -45, -45, -45, -45, -45, 895, + /* 90 */ 925, 967, 980, 1100, 1143, 1169, 1203, 1225, 1228, 1242, + /* 100 */ 1247, 1250, 1253, 1255, 1261, 1267, 1272, 1275, 1283, 1286, + /* 110 */ 1288, 1292, 1333, 1335, 1347, 1349, 1352, 1354, 1360, 1366, + /* 120 */ 1381, 1391, 1406, 1408, 1413, 1416, 1418, 1422, 1425, 1427, + /* 130 */ 1463, 1465, 1472, 1478, 1480, 1491, 1498, 1500, 1517, 1519, + /* 140 */ 1528, 1536, -45, -45, -45, -45, -45, -45, -45, -45, + /* 150 */ -45, -45, -45, 312, -158, 285, -219, 9, 166, 370, + /* 160 */ 545, 707, -45, 930, 601, 963, 1067, 792, -45, -45, + /* 170 */ -45, -45, -204, -204, -204, 369, -171, -129, 632, 678, + /* 180 */ 202, 352, -270, 412, 627, 627, -9, 122, 415, 419, + /* 190 */ -56, 248, 583, 920, 6, 261, 459, 795, 1049, 813, + /* 200 */ 1062, 1082, -161, 778, 1063, 797, 870, 1003, 1128, 443, + /* 210 */ 1031, 1072, 1191, 1192, 957, 1120, 105, 1149, 523, 933, + /* 220 */ 1218, 1238, 1254, 1251, -138, 96, 117, 146, 181, 277, + /* 230 */ 280, 421, 480, 712, 830, 850, 1085, 1099, 1129, 1209, + /* 240 */ 1323, 1331, 1336, 1364, 1407, 368, 1412, 1433, 1438, 1474, + /* 250 */ 1481, 1505, 1506, 1526, 1538, 1544, 1545, 1546, 722, 764, + /* 260 */ 856, 1547, 1548, 1550, 1188, 1554, 1557, 1561, 1298, 1260, + /* 270 */ 1562, 1456, 1564, 280, 1568, 1571, 1573, 1574, 1575, 1576, + /* 280 */ 1457, 1477, 1520, 1514, 1515, 1516, 1518, 1188, 1520, 1520, + /* 290 */ 1530, 1563, 1584, 1482, 1504, 1510, 1534, 1513, 1488, 1537, + /* 300 */ 1512, 1521, 1539, 1522, 1541, 1493, 1583, 1559, 1565, 1585, + /* 310 */ 1587, 1589, 1529, 1531, 1532, 1549, 1558, 1566, 1535, 1577, + /* 320 */ 1582, 1622, 1533, 1540, 1627, 1628, 1552, 1555, 1633, 1560, + /* 330 */ 1578, 1581, 1607, 1606, 1608, 1609, 1611, 1649, 1655, 1612, + /* 340 */ 1590, 1591, 1613, 1594, 1621, 1614, 1623, 1616, 1666, 1668, + /* 350 */ 1579, 1593, 1672, 1675, 1656, 1676, 1679, 1680, 1688, 1660, + /* 360 */ 1667, 1670, 1671, 1663, 1669, 1673, 1674, 1689, 1681, 1692, + /* 370 */ 1677, 1693, 1694, 1592, 1599, 1617, 1620, 1700, 1713, 1596, + /* 380 */ 1598, 1658, 1659, 1691, 1684, 1654, 1735, 1664, 1697, 1690, + /* 390 */ 1701, 1703, 1748, 1758, 1760, 1768, 1770, 1772, 1657, 1661, + /* 400 */ 1665, 1761, 1754, 1757, 1762, 1763, 1764, 1750, 1751, 1765, + /* 410 */ 1771, 1767, 1775, }; static const YYACTIONTYPE yy_default[] = { /* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254, @@ -173647,57 +174975,57 @@ static const YYACTIONTYPE yy_default[] = { /* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254, /* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254, /* 50 */ 1254, 1254, 1406, 1254, 1413, 1254, 1254, 1254, 1254, 1254, - /* 60 */ 1492, 1493, 1254, 1254, 1254, 1543, 1545, 1508, 1420, 1419, - /* 70 */ 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, 1486, - /* 80 */ 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, 1254, + /* 60 */ 1492, 1493, 1254, 1254, 1254, 1254, 1543, 1545, 1508, 1420, + /* 70 */ 1419, 1418, 1417, 1526, 1385, 1411, 1404, 1408, 1487, 1488, + /* 80 */ 1486, 1641, 1493, 1492, 1254, 1407, 1455, 1471, 1454, 1254, /* 90 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 100 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 110 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 120 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 130 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 140 */ 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, 1456, 1458, - /* 150 */ 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, 1254, 1254, - /* 160 */ 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, 1473, 1472, - /* 170 */ 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, 1254, 1254, - /* 180 */ 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 140 */ 1254, 1254, 1463, 1470, 1469, 1468, 1477, 1467, 1464, 1457, + /* 150 */ 1456, 1458, 1459, 1278, 1254, 1275, 1329, 1254, 1254, 1254, + /* 160 */ 1254, 1254, 1460, 1287, 1448, 1447, 1446, 1254, 1474, 1461, + /* 170 */ 1473, 1472, 1551, 1615, 1614, 1509, 1254, 1254, 1254, 1254, + /* 180 */ 1254, 1254, 1578, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 190 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 200 */ 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, 1578, 1578, - /* 210 */ 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, 1358, 1358, - /* 220 */ 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, 1546, 1254, - /* 240 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 200 */ 1254, 1254, 1254, 1254, 1254, 1387, 1578, 1578, 1254, 1287, + /* 210 */ 1578, 1578, 1388, 1388, 1283, 1283, 1391, 1558, 1358, 1358, + /* 220 */ 1358, 1358, 1367, 1358, 1254, 1254, 1254, 1254, 1254, 1254, + /* 230 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1548, + /* 240 */ 1546, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 250 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, 1254, 1254, - /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, 1254, - /* 280 */ 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, 1357, - /* 290 */ 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, 1423, - /* 300 */ 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, 1397, - /* 310 */ 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, 1357, - /* 320 */ 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, 1638, - /* 330 */ 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, 1638, - /* 340 */ 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, 1525, - /* 350 */ 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, 1330, - /* 360 */ 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, 1319, - /* 370 */ 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, 1588, - /* 380 */ 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, 1401, - /* 390 */ 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, 1558, - /* 400 */ 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, 1288, - /* 410 */ 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, 1254, - /* 420 */ 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1564, - /* 440 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 450 */ 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, 1254, - /* 460 */ 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, 1254, - /* 470 */ 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, 1254, - /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, 1254, - /* 490 */ 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, 1254, + /* 260 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1363, 1254, + /* 270 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1608, + /* 280 */ 1254, 1521, 1343, 1363, 1363, 1363, 1363, 1365, 1344, 1342, + /* 290 */ 1357, 1288, 1261, 1655, 1423, 1412, 1364, 1412, 1652, 1410, + /* 300 */ 1423, 1423, 1410, 1423, 1364, 1652, 1304, 1630, 1299, 1397, + /* 310 */ 1397, 1397, 1387, 1387, 1387, 1387, 1391, 1391, 1489, 1364, + /* 320 */ 1357, 1254, 1655, 1655, 1373, 1373, 1654, 1654, 1373, 1509, + /* 330 */ 1638, 1432, 1332, 1338, 1338, 1338, 1338, 1373, 1272, 1410, + /* 340 */ 1638, 1638, 1410, 1432, 1332, 1410, 1332, 1410, 1373, 1272, + /* 350 */ 1525, 1649, 1373, 1272, 1499, 1373, 1272, 1373, 1272, 1499, + /* 360 */ 1330, 1330, 1330, 1319, 1254, 1254, 1499, 1330, 1304, 1330, + /* 370 */ 1319, 1330, 1330, 1596, 1254, 1503, 1503, 1499, 1373, 1588, + /* 380 */ 1588, 1400, 1400, 1405, 1391, 1494, 1373, 1254, 1405, 1403, + /* 390 */ 1401, 1410, 1322, 1611, 1611, 1607, 1607, 1607, 1660, 1660, + /* 400 */ 1558, 1623, 1287, 1287, 1287, 1287, 1623, 1306, 1306, 1288, + /* 410 */ 1288, 1287, 1623, 1254, 1254, 1254, 1254, 1254, 1254, 1618, + /* 420 */ 1254, 1553, 1510, 1377, 1254, 1254, 1254, 1254, 1254, 1254, + /* 430 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 440 */ 1564, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 450 */ 1254, 1254, 1437, 1254, 1257, 1555, 1254, 1254, 1254, 1254, + /* 460 */ 1254, 1254, 1254, 1254, 1414, 1415, 1378, 1254, 1254, 1254, + /* 470 */ 1254, 1254, 1254, 1254, 1429, 1254, 1254, 1254, 1424, 1254, + /* 480 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1651, 1254, 1254, + /* 490 */ 1254, 1254, 1254, 1254, 1524, 1523, 1254, 1254, 1375, 1254, /* 500 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 510 */ 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 510 */ 1254, 1254, 1302, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 520 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 530 */ 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, 1254, + /* 530 */ 1254, 1254, 1254, 1254, 1254, 1254, 1402, 1254, 1254, 1254, /* 540 */ 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - /* 550 */ 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, 1254, - /* 560 */ 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, + /* 550 */ 1254, 1593, 1392, 1254, 1254, 1254, 1254, 1642, 1254, 1254, + /* 560 */ 1254, 1254, 1352, 1254, 1254, 1254, 1254, 1254, 1254, 1254, /* 570 */ 1254, 1254, 1254, 1634, 1346, 1438, 1254, 1441, 1276, 1254, /* 580 */ 1266, 1254, 1254, }; @@ -173721,52 +175049,53 @@ static const YYACTIONTYPE yy_default[] = { static const YYCODETYPE yyFallback[] = { 0, /* $ => nothing */ 0, /* SEMI => nothing */ - 59, /* EXPLAIN => ID */ - 59, /* QUERY => ID */ - 59, /* PLAN => ID */ - 59, /* BEGIN => ID */ + 60, /* EXPLAIN => ID */ + 60, /* QUERY => ID */ + 60, /* PLAN => ID */ + 60, /* BEGIN => ID */ 0, /* TRANSACTION => nothing */ - 59, /* DEFERRED => ID */ - 59, /* IMMEDIATE => ID */ - 59, /* EXCLUSIVE => ID */ + 60, /* DEFERRED => ID */ + 60, /* IMMEDIATE => ID */ + 60, /* EXCLUSIVE => ID */ 0, /* COMMIT => nothing */ - 59, /* END => ID */ - 59, /* ROLLBACK => ID */ - 59, /* SAVEPOINT => ID */ - 59, /* RELEASE => ID */ + 60, /* END => ID */ + 60, /* ROLLBACK => ID */ + 60, /* SAVEPOINT => ID */ + 60, /* RELEASE => ID */ 0, /* TO => nothing */ 0, /* TABLE => nothing */ 0, /* CREATE => nothing */ - 59, /* IF => ID */ + 60, /* IF => ID */ 0, /* NOT => nothing */ 0, /* EXISTS => nothing */ - 59, /* TEMP => ID */ + 60, /* TEMP => ID */ 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ 0, /* COMMA => nothing */ - 59, /* WITHOUT => ID */ - 59, /* ABORT => ID */ - 59, /* ACTION => ID */ - 59, /* AFTER => ID */ - 59, /* ANALYZE => ID */ - 59, /* ASC => ID */ - 59, /* ATTACH => ID */ - 59, /* BEFORE => ID */ - 59, /* BY => ID */ - 59, /* CASCADE => ID */ - 59, /* CAST => ID */ - 59, /* CONFLICT => ID */ - 59, /* DATABASE => ID */ - 59, /* DESC => ID */ - 59, /* DETACH => ID */ - 59, /* EACH => ID */ - 59, /* FAIL => ID */ + 60, /* WITHOUT => ID */ + 60, /* ABORT => ID */ + 60, /* ACTION => ID */ + 60, /* AFTER => ID */ + 60, /* ANALYZE => ID */ + 60, /* ASC => ID */ + 60, /* ATTACH => ID */ + 60, /* BEFORE => ID */ + 60, /* BY => ID */ + 60, /* CASCADE => ID */ + 60, /* CAST => ID */ + 60, /* CONFLICT => ID */ + 60, /* DATABASE => ID */ + 60, /* DESC => ID */ + 60, /* DETACH => ID */ + 60, /* EACH => ID */ + 60, /* FAIL => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* IS => nothing */ - 59, /* MATCH => ID */ - 59, /* LIKE_KW => ID */ + 0, /* ISNOT => nothing */ + 60, /* MATCH => ID */ + 60, /* LIKE_KW => ID */ 0, /* BETWEEN => nothing */ 0, /* IN => nothing */ 0, /* ISNULL => nothing */ @@ -173779,47 +175108,47 @@ static const YYCODETYPE yyFallback[] = { 0, /* GE => nothing */ 0, /* ESCAPE => nothing */ 0, /* ID => nothing */ - 59, /* COLUMNKW => ID */ - 59, /* DO => ID */ - 59, /* FOR => ID */ - 59, /* IGNORE => ID */ - 59, /* INITIALLY => ID */ - 59, /* INSTEAD => ID */ - 59, /* NO => ID */ - 59, /* KEY => ID */ - 59, /* OF => ID */ - 59, /* OFFSET => ID */ - 59, /* PRAGMA => ID */ - 59, /* RAISE => ID */ - 59, /* RECURSIVE => ID */ - 59, /* REPLACE => ID */ - 59, /* RESTRICT => ID */ - 59, /* ROW => ID */ - 59, /* ROWS => ID */ - 59, /* TRIGGER => ID */ - 59, /* VACUUM => ID */ - 59, /* VIEW => ID */ - 59, /* VIRTUAL => ID */ - 59, /* WITH => ID */ - 59, /* NULLS => ID */ - 59, /* FIRST => ID */ - 59, /* LAST => ID */ - 59, /* CURRENT => ID */ - 59, /* FOLLOWING => ID */ - 59, /* PARTITION => ID */ - 59, /* PRECEDING => ID */ - 59, /* RANGE => ID */ - 59, /* UNBOUNDED => ID */ - 59, /* EXCLUDE => ID */ - 59, /* GROUPS => ID */ - 59, /* OTHERS => ID */ - 59, /* TIES => ID */ - 59, /* GENERATED => ID */ - 59, /* ALWAYS => ID */ - 59, /* MATERIALIZED => ID */ - 59, /* REINDEX => ID */ - 59, /* RENAME => ID */ - 59, /* CTIME_KW => ID */ + 60, /* COLUMNKW => ID */ + 60, /* DO => ID */ + 60, /* FOR => ID */ + 60, /* IGNORE => ID */ + 60, /* INITIALLY => ID */ + 60, /* INSTEAD => ID */ + 60, /* NO => ID */ + 60, /* KEY => ID */ + 60, /* OF => ID */ + 60, /* OFFSET => ID */ + 60, /* PRAGMA => ID */ + 60, /* RAISE => ID */ + 60, /* RECURSIVE => ID */ + 60, /* REPLACE => ID */ + 60, /* RESTRICT => ID */ + 60, /* ROW => ID */ + 60, /* ROWS => ID */ + 60, /* TRIGGER => ID */ + 60, /* VACUUM => ID */ + 60, /* VIEW => ID */ + 60, /* VIRTUAL => ID */ + 60, /* WITH => ID */ + 60, /* NULLS => ID */ + 60, /* FIRST => ID */ + 60, /* LAST => ID */ + 60, /* CURRENT => ID */ + 60, /* FOLLOWING => ID */ + 60, /* PARTITION => ID */ + 60, /* PRECEDING => ID */ + 60, /* RANGE => ID */ + 60, /* UNBOUNDED => ID */ + 60, /* EXCLUDE => ID */ + 60, /* GROUPS => ID */ + 60, /* OTHERS => ID */ + 60, /* TIES => ID */ + 60, /* GENERATED => ID */ + 60, /* ALWAYS => ID */ + 60, /* MATERIALIZED => ID */ + 60, /* REINDEX => ID */ + 60, /* RENAME => ID */ + 60, /* CTIME_KW => ID */ 0, /* ANY => nothing */ 0, /* BITAND => nothing */ 0, /* BITOR => nothing */ @@ -173890,7 +175219,6 @@ static const YYCODETYPE yyFallback[] = { 0, /* AGG_FUNCTION => nothing */ 0, /* AGG_COLUMN => nothing */ 0, /* TRUEFALSE => nothing */ - 0, /* ISNOT => nothing */ 0, /* FUNCTION => nothing */ 0, /* UPLUS => nothing */ 0, /* UMINUS => nothing */ @@ -174034,132 +175362,132 @@ static const char *const yyTokenName[] = { /* 43 */ "OR", /* 44 */ "AND", /* 45 */ "IS", - /* 46 */ "MATCH", - /* 47 */ "LIKE_KW", - /* 48 */ "BETWEEN", - /* 49 */ "IN", - /* 50 */ "ISNULL", - /* 51 */ "NOTNULL", - /* 52 */ "NE", - /* 53 */ "EQ", - /* 54 */ "GT", - /* 55 */ "LE", - /* 56 */ "LT", - /* 57 */ "GE", - /* 58 */ "ESCAPE", - /* 59 */ "ID", - /* 60 */ "COLUMNKW", - /* 61 */ "DO", - /* 62 */ "FOR", - /* 63 */ "IGNORE", - /* 64 */ "INITIALLY", - /* 65 */ "INSTEAD", - /* 66 */ "NO", - /* 67 */ "KEY", - /* 68 */ "OF", - /* 69 */ "OFFSET", - /* 70 */ "PRAGMA", - /* 71 */ "RAISE", - /* 72 */ "RECURSIVE", - /* 73 */ "REPLACE", - /* 74 */ "RESTRICT", - /* 75 */ "ROW", - /* 76 */ "ROWS", - /* 77 */ "TRIGGER", - /* 78 */ "VACUUM", - /* 79 */ "VIEW", - /* 80 */ "VIRTUAL", - /* 81 */ "WITH", - /* 82 */ "NULLS", - /* 83 */ "FIRST", - /* 84 */ "LAST", - /* 85 */ "CURRENT", - /* 86 */ "FOLLOWING", - /* 87 */ "PARTITION", - /* 88 */ "PRECEDING", - /* 89 */ "RANGE", - /* 90 */ "UNBOUNDED", - /* 91 */ "EXCLUDE", - /* 92 */ "GROUPS", - /* 93 */ "OTHERS", - /* 94 */ "TIES", - /* 95 */ "GENERATED", - /* 96 */ "ALWAYS", - /* 97 */ "MATERIALIZED", - /* 98 */ "REINDEX", - /* 99 */ "RENAME", - /* 100 */ "CTIME_KW", - /* 101 */ "ANY", - /* 102 */ "BITAND", - /* 103 */ "BITOR", - /* 104 */ "LSHIFT", - /* 105 */ "RSHIFT", - /* 106 */ "PLUS", - /* 107 */ "MINUS", - /* 108 */ "STAR", - /* 109 */ "SLASH", - /* 110 */ "REM", - /* 111 */ "CONCAT", - /* 112 */ "PTR", - /* 113 */ "COLLATE", - /* 114 */ "BITNOT", - /* 115 */ "ON", - /* 116 */ "INDEXED", - /* 117 */ "STRING", - /* 118 */ "JOIN_KW", - /* 119 */ "CONSTRAINT", - /* 120 */ "DEFAULT", - /* 121 */ "NULL", - /* 122 */ "PRIMARY", - /* 123 */ "UNIQUE", - /* 124 */ "CHECK", - /* 125 */ "REFERENCES", - /* 126 */ "AUTOINCR", - /* 127 */ "INSERT", - /* 128 */ "DELETE", - /* 129 */ "UPDATE", - /* 130 */ "SET", - /* 131 */ "DEFERRABLE", - /* 132 */ "FOREIGN", - /* 133 */ "DROP", - /* 134 */ "UNION", - /* 135 */ "ALL", - /* 136 */ "EXCEPT", - /* 137 */ "INTERSECT", - /* 138 */ "SELECT", - /* 139 */ "VALUES", - /* 140 */ "DISTINCT", - /* 141 */ "DOT", - /* 142 */ "FROM", - /* 143 */ "JOIN", - /* 144 */ "USING", - /* 145 */ "ORDER", - /* 146 */ "GROUP", - /* 147 */ "HAVING", - /* 148 */ "LIMIT", - /* 149 */ "WHERE", - /* 150 */ "RETURNING", - /* 151 */ "INTO", - /* 152 */ "NOTHING", - /* 153 */ "FLOAT", - /* 154 */ "BLOB", - /* 155 */ "INTEGER", - /* 156 */ "VARIABLE", - /* 157 */ "CASE", - /* 158 */ "WHEN", - /* 159 */ "THEN", - /* 160 */ "ELSE", - /* 161 */ "INDEX", - /* 162 */ "ALTER", - /* 163 */ "ADD", - /* 164 */ "WINDOW", - /* 165 */ "OVER", - /* 166 */ "FILTER", - /* 167 */ "COLUMN", - /* 168 */ "AGG_FUNCTION", - /* 169 */ "AGG_COLUMN", - /* 170 */ "TRUEFALSE", - /* 171 */ "ISNOT", + /* 46 */ "ISNOT", + /* 47 */ "MATCH", + /* 48 */ "LIKE_KW", + /* 49 */ "BETWEEN", + /* 50 */ "IN", + /* 51 */ "ISNULL", + /* 52 */ "NOTNULL", + /* 53 */ "NE", + /* 54 */ "EQ", + /* 55 */ "GT", + /* 56 */ "LE", + /* 57 */ "LT", + /* 58 */ "GE", + /* 59 */ "ESCAPE", + /* 60 */ "ID", + /* 61 */ "COLUMNKW", + /* 62 */ "DO", + /* 63 */ "FOR", + /* 64 */ "IGNORE", + /* 65 */ "INITIALLY", + /* 66 */ "INSTEAD", + /* 67 */ "NO", + /* 68 */ "KEY", + /* 69 */ "OF", + /* 70 */ "OFFSET", + /* 71 */ "PRAGMA", + /* 72 */ "RAISE", + /* 73 */ "RECURSIVE", + /* 74 */ "REPLACE", + /* 75 */ "RESTRICT", + /* 76 */ "ROW", + /* 77 */ "ROWS", + /* 78 */ "TRIGGER", + /* 79 */ "VACUUM", + /* 80 */ "VIEW", + /* 81 */ "VIRTUAL", + /* 82 */ "WITH", + /* 83 */ "NULLS", + /* 84 */ "FIRST", + /* 85 */ "LAST", + /* 86 */ "CURRENT", + /* 87 */ "FOLLOWING", + /* 88 */ "PARTITION", + /* 89 */ "PRECEDING", + /* 90 */ "RANGE", + /* 91 */ "UNBOUNDED", + /* 92 */ "EXCLUDE", + /* 93 */ "GROUPS", + /* 94 */ "OTHERS", + /* 95 */ "TIES", + /* 96 */ "GENERATED", + /* 97 */ "ALWAYS", + /* 98 */ "MATERIALIZED", + /* 99 */ "REINDEX", + /* 100 */ "RENAME", + /* 101 */ "CTIME_KW", + /* 102 */ "ANY", + /* 103 */ "BITAND", + /* 104 */ "BITOR", + /* 105 */ "LSHIFT", + /* 106 */ "RSHIFT", + /* 107 */ "PLUS", + /* 108 */ "MINUS", + /* 109 */ "STAR", + /* 110 */ "SLASH", + /* 111 */ "REM", + /* 112 */ "CONCAT", + /* 113 */ "PTR", + /* 114 */ "COLLATE", + /* 115 */ "BITNOT", + /* 116 */ "ON", + /* 117 */ "INDEXED", + /* 118 */ "STRING", + /* 119 */ "JOIN_KW", + /* 120 */ "CONSTRAINT", + /* 121 */ "DEFAULT", + /* 122 */ "NULL", + /* 123 */ "PRIMARY", + /* 124 */ "UNIQUE", + /* 125 */ "CHECK", + /* 126 */ "REFERENCES", + /* 127 */ "AUTOINCR", + /* 128 */ "INSERT", + /* 129 */ "DELETE", + /* 130 */ "UPDATE", + /* 131 */ "SET", + /* 132 */ "DEFERRABLE", + /* 133 */ "FOREIGN", + /* 134 */ "DROP", + /* 135 */ "UNION", + /* 136 */ "ALL", + /* 137 */ "EXCEPT", + /* 138 */ "INTERSECT", + /* 139 */ "SELECT", + /* 140 */ "VALUES", + /* 141 */ "DISTINCT", + /* 142 */ "DOT", + /* 143 */ "FROM", + /* 144 */ "JOIN", + /* 145 */ "USING", + /* 146 */ "ORDER", + /* 147 */ "GROUP", + /* 148 */ "HAVING", + /* 149 */ "LIMIT", + /* 150 */ "WHERE", + /* 151 */ "RETURNING", + /* 152 */ "INTO", + /* 153 */ "NOTHING", + /* 154 */ "FLOAT", + /* 155 */ "BLOB", + /* 156 */ "INTEGER", + /* 157 */ "VARIABLE", + /* 158 */ "CASE", + /* 159 */ "WHEN", + /* 160 */ "THEN", + /* 161 */ "ELSE", + /* 162 */ "INDEX", + /* 163 */ "ALTER", + /* 164 */ "ADD", + /* 165 */ "WINDOW", + /* 166 */ "OVER", + /* 167 */ "FILTER", + /* 168 */ "COLUMN", + /* 169 */ "AGG_FUNCTION", + /* 170 */ "AGG_COLUMN", + /* 171 */ "TRUEFALSE", /* 172 */ "FUNCTION", /* 173 */ "UPLUS", /* 174 */ "UMINUS", @@ -174597,7 +175925,7 @@ static const char *const yyRuleName[] = { /* 277 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", /* 278 */ "trigger_cmd ::= scanpt select scanpt", /* 279 */ "expr ::= RAISE LP IGNORE RP", - /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 280 */ "expr ::= RAISE LP raisetype COMMA expr RP", /* 281 */ "raisetype ::= ROLLBACK", /* 282 */ "raisetype ::= ABORT", /* 283 */ "raisetype ::= FAIL", @@ -175522,7 +176850,7 @@ static const YYCODETYPE yyRuleInfoLhs[] = { 293, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ 293, /* (278) trigger_cmd ::= scanpt select scanpt */ 218, /* (279) expr ::= RAISE LP IGNORE RP */ - 218, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ + 218, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ 237, /* (281) raisetype ::= ROLLBACK */ 237, /* (282) raisetype ::= ABORT */ 237, /* (283) raisetype ::= FAIL */ @@ -175936,7 +177264,7 @@ static const signed char yyRuleInfoNRhs[] = { -6, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -3, /* (278) trigger_cmd ::= scanpt select scanpt */ -4, /* (279) expr ::= RAISE LP IGNORE RP */ - -6, /* (280) expr ::= RAISE LP raisetype COMMA nm RP */ + -6, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */ -1, /* (281) raisetype ::= ROLLBACK */ -1, /* (282) raisetype ::= ABORT */ -1, /* (283) raisetype ::= FAIL */ @@ -176574,11 +177902,21 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-5].minor.yy203 ){ SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; SrcItem *pOld = yymsp[-3].minor.yy203->a; + assert( pOld->fg.fixedSchema==0 ); pNew->zName = pOld->zName; - pNew->zDatabase = pOld->zDatabase; - pNew->pSelect = pOld->pSelect; - if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){ - pNew->fg.isNestedFrom = 1; + assert( pOld->fg.fixedSchema==0 ); + if( pOld->fg.isSubquery ){ + pNew->fg.isSubquery = 1; + pNew->u4.pSubq = pOld->u4.pSubq; + pOld->u4.pSubq = 0; + pOld->fg.isSubquery = 0; + assert( pNew->u4.pSubq!=0 && pNew->u4.pSubq->pSelect!=0 ); + if( (pNew->u4.pSubq->pSelect->selFlags & SF_NestedFrom)!=0 ){ + pNew->fg.isNestedFrom = 1; + } + }else{ + pNew->u4.zDatabase = pOld->u4.zDatabase; + pOld->u4.zDatabase = 0; } if( pOld->fg.isTabFunc ){ pNew->u1.pFuncArg = pOld->u1.pFuncArg; @@ -176586,8 +177924,7 @@ static YYACTIONTYPE yy_reduce( pOld->fg.isTabFunc = 0; pNew->fg.isTabFunc = 1; } - pOld->zName = pOld->zDatabase = 0; - pOld->pSelect = 0; + pOld->zName = 0; } sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); }else{ @@ -177321,9 +178658,9 @@ static YYACTIONTYPE yy_reduce( } } break; - case 280: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */ { - yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0); if( yymsp[-5].minor.yy454 ) { yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144; } @@ -179914,32 +181251,6 @@ SQLITE_API char *sqlite3_temp_directory = 0; */ SQLITE_API char *sqlite3_data_directory = 0; -/* -** Determine whether or not high-precision (long double) floating point -** math works correctly on CPU currently running. -*/ -static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ - if( sizeof(LONGDOUBLE_TYPE)<=8 ){ - /* If the size of "long double" is not more than 8, then - ** high-precision math is not possible. */ - return 0; - }else{ - /* Just because sizeof(long double)>8 does not mean that the underlying - ** hardware actually supports high-precision floating point. For example, - ** clearing the 0x100 bit in the floating-point control word on Intel - ** processors will make long double work like double, even though long - ** double takes up more space. The only way to determine if long double - ** actually works is to run an experiment. */ - LONGDOUBLE_TYPE a, b, c; - rc++; - a = 1.0+rc*0.1; - b = 1.0e+18+rc*25.0; - c = a+b; - return b!=c; - } -} - - /* ** Initialize SQLite. ** @@ -180134,13 +181445,6 @@ SQLITE_API int sqlite3_initialize(void){ rc = SQLITE_EXTRA_INIT(0); } #endif - - /* Experimentally determine if high-precision floating point is - ** available. */ -#ifndef SQLITE_OMIT_WSD - sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); -#endif - return rc; } @@ -181681,7 +182985,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY| - SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE); + SQLITE_SUBTYPE|SQLITE_INNOCUOUS| + SQLITE_RESULT_SUBTYPE|SQLITE_SELFORDER1); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But @@ -183236,6 +184541,7 @@ static int openDatabase( if( ((1<<(flags&7)) & 0x46)==0 ){ rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */ }else{ + if( zFilename==0 ) zFilename = ":memory:"; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); } if( rc!=SQLITE_OK ){ @@ -184148,6 +185454,18 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, sqlite3 *db, int *N) + ** + ** Write the current optimization settings into *N. A zero bit means that + ** the optimization is on, and a 1 bit means that the optimization is off. + */ + case SQLITE_TESTCTRL_GETOPT: { + sqlite3 *db = va_arg(ap, sqlite3*); + int *pN = va_arg(ap, int*); + *pN = db->dbOptFlags; + break; + } + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); ** ** If parameter onoff is 1, subsequent calls to localtime() fail. @@ -184379,24 +185697,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } -#if !defined(SQLITE_OMIT_WSD) - /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); - ** - ** X<0 Make no changes to the bUseLongDouble. Just report value. - ** X==0 Disable bUseLongDouble - ** X==1 Enable bUseLongDouble - ** X>=2 Set bUseLongDouble to its default value for this platform - */ - case SQLITE_TESTCTRL_USELONGDOUBLE: { - int b = va_arg(ap, int); - if( b>=2 ) b = hasHighPrecisionDouble(b); - if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; - rc = sqlite3Config.bUseLongDouble!=0; - break; - } -#endif - - #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) ** @@ -184704,7 +186004,11 @@ SQLITE_API int sqlite3_snapshot_get( if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ + Pager *pPager = sqlite3BtreePager(pBt); + i64 dummy = 0; + sqlite3PagerSnapshotOpen(pPager, (sqlite3_snapshot*)&dummy); rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); } @@ -195475,11 +196779,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" /* #include */ /* @@ -202706,6 +204006,7 @@ static int fts3SnippetNextCandidate(SnippetIter *pIter){ return 1; } + assert( pIter->nSnippet>=0 ); pIter->iCurrent = iStart = iEnd - pIter->nSnippet + 1; for(i=0; inPhrase; i++){ SnippetPhrase *pPhrase = &pIter->aPhrase[i]; @@ -207699,7 +209000,9 @@ static u32 jsonLookupStep( zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; - for(i=1; zPath[i] && zPath[i]!='"'; i++){} + for(i=1; zPath[i] && zPath[i]!='"'; i++){ + if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++; + } nKey = i-1; if( zPath[i] ){ i++; @@ -208709,10 +210012,16 @@ static void jsonExtractFunc( ** NUMBER ==> $[NUMBER] // PG compatible ** LABEL ==> $.LABEL // PG compatible ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + ** + ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from + ** the right of the array. Hence for negative NUMBER: + ** + ** NUMBER ==> $[#NUMBER] // PG compatible */ jsonStringInit(&jx, ctx); if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){ jsonAppendRawNZ(&jx, "[", 1); + if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1); jsonAppendRaw(&jx, zPath, nPath); jsonAppendRawNZ(&jx, "]", 2); }else if( jsonAllAlphanum(zPath, nPath) ){ @@ -218454,6 +219763,27 @@ struct RbuFrame { u32 iWalFrame; }; +#ifndef UNUSED_PARAMETER +/* +** The following macros are used to suppress compiler warnings and to +** make it clear to human readers when a function parameter is deliberately +** left unused within the body of a function. This usually happens when +** a function is called via a function pointer. For example the +** implementation of an SQL aggregate step callback may not use the +** parameter indicating the number of arguments passed to the aggregate, +** if it knows that this is enforced elsewhere. +** +** When a function parameter is not used at all within the body of a function, +** it is generally named "NotUsed" or "NotUsed2" to make things even clearer. +** However, these macros may also be used to suppress warnings related to +** parameters that may or may not be used depending on compilation options. +** For example those parameters only used in assert() statements. In these +** cases the parameters are named as per the usual conventions. +*/ +#define UNUSED_PARAMETER(x) (void)(x) +#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y) +#endif + /* ** RBU handle. ** @@ -218505,7 +219835,7 @@ struct sqlite3rbu { int rc; /* Value returned by last rbu_step() call */ char *zErrmsg; /* Error message if rc!=SQLITE_OK */ int nStep; /* Rows processed for current object */ - int nProgress; /* Rows processed for all objects */ + sqlite3_int64 nProgress; /* Rows processed for all objects */ RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ @@ -218622,7 +219952,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){ v = (v<<6) + c; } z--; - *pLen -= z - zStart; + *pLen -= (int)(z - zStart); *pz = (char*)z; return v; } @@ -218807,6 +220137,7 @@ static void rbuFossilDeltaFunc( char *aOut; assert( argc==2 ); + UNUSED_PARAMETER(argc); nOrig = sqlite3_value_bytes(argv[0]); aOrig = (const char*)sqlite3_value_blob(argv[0]); @@ -220386,13 +221717,13 @@ static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ else if( c==')' ){ nParen--; if( nParen==0 ){ - int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; i++; break; } }else if( c==',' && nParen==1 ){ - int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan; + int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan); pIter->aIdxCol[iIdxCol++].nSpan = nSpan; pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1]; }else if( c=='"' || c=='\'' || c=='`' ){ @@ -221082,6 +222413,8 @@ static void rbuFileSuffix3(const char *zBase, char *z){ for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4); } +#else + UNUSED_PARAMETER2(zBase,z); #endif } @@ -221666,7 +222999,7 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){ "(%d, %Q), " "(%d, %Q), " "(%d, %d), " - "(%d, %d), " + "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " "(%d, %lld), " @@ -222024,6 +223357,7 @@ static void rbuIndexCntFunc( sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); + UNUSED_PARAMETER(nVal); rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, sqlite3_mprintf("SELECT count(*) FROM sqlite_schema " @@ -222299,7 +223633,7 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( ){ if( zTarget==0 ){ return rbuMisuseError(); } if( zState ){ - int n = strlen(zState); + size_t n = strlen(zState); if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){ return rbuMisuseError(); } @@ -222516,6 +223850,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ */ static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){ int rc = SQLITE_OK; + UNUSED_PARAMETER(pArg); #if defined(_WIN32_WCE) { LPWSTR zWideOld; @@ -223420,6 +224755,9 @@ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ ** No-op. */ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(a); + UNUSED_PARAMETER(b); return 0; } @@ -223818,6 +225156,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ pIdxInfo->orderByConsumed = 1; pIdxInfo->idxNum |= 0x08; } + pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX; return SQLITE_OK; } @@ -224475,7 +225814,13 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; } ** ** The data field of sqlite_dbpage table can be updated. The new ** value must be a BLOB which is the correct page size, otherwise the -** update fails. Rows may not be deleted or inserted. +** update fails. INSERT operations also work, and operate as if they +** where REPLACE. The size of the database can be extended by INSERT-ing +** new pages on the end. +** +** Rows may not be deleted. However, doing an INSERT to page number N +** with NULL page data causes the N-th page and all subsequent pages to be +** deleted and the database to be truncated. */ /* #include "sqliteInt.h" ** Requires access to internal data structures ** */ @@ -224498,6 +225843,8 @@ struct DbpageCursor { struct DbpageTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database */ + int iDbTrunc; /* Database to truncate */ + Pgno pgnoTrunc; /* Size to truncate to */ }; /* Columns */ @@ -224506,7 +225853,6 @@ struct DbpageTable { #define DBPAGE_COLUMN_SCHEMA 2 - /* ** Connect to or create a dbpagevfs virtual table. */ @@ -224768,11 +226114,11 @@ static int dbpageUpdate( DbPage *pDbPage = 0; int rc = SQLITE_OK; char *zErr = 0; - const char *zSchema; int iDb; Btree *pBt; Pager *pPager; int szPage; + int isInsert; (void)pRowid; if( pTab->db->flags & SQLITE_Defensive ){ @@ -224783,21 +226129,29 @@ static int dbpageUpdate( zErr = "cannot delete"; goto update_fail; } - pgno = sqlite3_value_int(argv[0]); - if( sqlite3_value_type(argv[0])==SQLITE_NULL - || (Pgno)sqlite3_value_int(argv[1])!=pgno - ){ - zErr = "cannot insert"; - goto update_fail; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + pgno = (Pgno)sqlite3_value_int(argv[2]); + isInsert = 1; + }else{ + pgno = sqlite3_value_int(argv[0]); + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ + zErr = "cannot insert"; + goto update_fail; + } + isInsert = 0; } - zSchema = (const char*)sqlite3_value_text(argv[4]); - iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1; - if( NEVER(iDb<0) ){ - zErr = "no such schema"; - goto update_fail; + if( sqlite3_value_type(argv[4])==SQLITE_NULL ){ + iDb = 0; + }else{ + const char *zSchema = (const char*)sqlite3_value_text(argv[4]); + iDb = sqlite3FindDbName(pTab->db, zSchema); + if( iDb<0 ){ + zErr = "no such schema"; + goto update_fail; + } } pBt = pTab->db->aDb[iDb].pBt; - if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){ + if( pgno<1 || NEVER(pBt==0) ){ zErr = "bad page number"; goto update_fail; } @@ -224805,18 +226159,25 @@ static int dbpageUpdate( if( sqlite3_value_type(argv[3])!=SQLITE_BLOB || sqlite3_value_bytes(argv[3])!=szPage ){ - zErr = "bad page value"; - goto update_fail; + if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){ + /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and + ** all subsequent pages to be deleted. */ + pTab->iDbTrunc = iDb; + pgno--; + pTab->pgnoTrunc = pgno; + }else{ + zErr = "bad page value"; + goto update_fail; + } } pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ const void *pData = sqlite3_value_blob(argv[3]); - assert( pData!=0 || pTab->db->mallocFailed ); - if( pData - && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK - ){ - memcpy(sqlite3PagerGetData(pDbPage), pData, szPage); + if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){ + unsigned char *aPage = sqlite3PagerGetData(pDbPage); + memcpy(aPage, pData, szPage); + pTab->pgnoTrunc = 0; } } sqlite3PagerUnref(pDbPage); @@ -224840,9 +226201,31 @@ static int dbpageBegin(sqlite3_vtab *pVtab){ Btree *pBt = db->aDb[i].pBt; if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0); } + pTab->pgnoTrunc = 0; return SQLITE_OK; } +/* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT +*/ +static int dbpageSync(sqlite3_vtab *pVtab){ + DbpageTable *pTab = (DbpageTable *)pVtab; + if( pTab->pgnoTrunc>0 ){ + Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc); + } + pTab->pgnoTrunc = 0; + return SQLITE_OK; +} + +/* Cancel any pending truncate. +*/ +static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){ + DbpageTable *pTab = (DbpageTable *)pVtab; + pTab->pgnoTrunc = 0; + (void)notUsed1; + return SQLITE_OK; +} /* ** Invoke this routine to register the "dbpage" virtual table module @@ -224864,14 +226247,14 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ dbpageRowid, /* xRowid - read data */ dbpageUpdate, /* xUpdate */ dbpageBegin, /* xBegin */ - 0, /* xSync */ + dbpageSync, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ - 0, /* xRollbackTo */ + dbpageRollbackTo, /* xRollbackTo */ 0, /* xShadowName */ 0 /* xIntegrity */ }; @@ -224959,6 +226342,10 @@ struct SessionBuffer { ** input data. Input data may be supplied either as a single large buffer ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. ** sqlite3changeset_start_strm()). +** +** bNoDiscard: +** If true, then the only time data is discarded is as a result of explicit +** sessionDiscardData() calls. Not within every sessionInputBuffer() call. */ struct SessionInput { int bNoDiscard; /* If true, do not discard in InputBuffer() */ @@ -226642,16 +228029,19 @@ static void sessionPreupdateOneChange( for(i=0; i<(pTab->nCol-pTab->bRowid); i++){ sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ - TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); - assert( trc==SQLITE_OK ); + /* This may fail if the column has a non-NULL default and was added + ** using ALTER TABLE ADD COLUMN after this record was created. */ + rc = pSession->hook.xOld(pSession->hook.pCtx, i, &p); }else if( pTab->abPK[i] ){ TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &p); assert( trc==SQLITE_OK ); } - /* This may fail if SQLite value p contains a utf-16 string that must - ** be converted to utf-8 and an OOM error occurs while doing so. */ - rc = sessionSerializeValue(0, p, &nByte); + if( rc==SQLITE_OK ){ + /* This may fail if SQLite value p contains a utf-16 string that must + ** be converted to utf-8 and an OOM error occurs while doing so. */ + rc = sessionSerializeValue(0, p, &nByte); + } if( rc!=SQLITE_OK ) goto error_out; } if( pTab->bRowid ){ @@ -230009,15 +231399,21 @@ static int sessionChangesetApply( int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ int bPatchset; + u64 savedFlag = db->flags & SQLITE_FkNoAction; assert( xConflict!=0 ); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ + db->flags |= ((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } + pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP); - sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); } @@ -230179,6 +231575,12 @@ static int sessionChangesetApply( sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); sqlite3_free((char*)sApply.rebase.aBuf); + + if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ + assert( db->flags & SQLITE_FkNoAction ); + db->flags &= ~((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } @@ -230207,12 +231609,6 @@ SQLITE_API int sqlite3changeset_apply_v2( sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); - u64 savedFlag = db->flags & SQLITE_FkNoAction; - - if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ - db->flags |= ((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } if( rc==SQLITE_OK ){ rc = sessionChangesetApply( @@ -230220,11 +231616,6 @@ SQLITE_API int sqlite3changeset_apply_v2( ); } - if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ - assert( db->flags & SQLITE_FkNoAction ); - db->flags &= ~((u64)SQLITE_FkNoAction); - db->aDb[0].pSchema->schema_cookie -= 32; - } return rc; } @@ -230545,6 +231936,9 @@ static int sessionChangesetExtendRecord( sessionAppendBlob(pOut, aRec, nRec, &rc); if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); + if( rc==SQLITE_OK && SQLITE_ROW!=sqlite3_step(pTab->pDfltStmt) ){ + rc = sqlite3_errcode(pGrp->db); + } } for(ii=nCol; rc==SQLITE_OK && iinCol; ii++){ int eType = sqlite3_column_type(pTab->pDfltStmt, ii); @@ -230561,6 +231955,7 @@ static int sessionChangesetExtendRecord( } if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + pOut->nBuf += 8; } break; } @@ -230700,6 +232095,8 @@ static int sessionOneChangeToHash( u8 *aRec = &pIter->in.aData[pIter->in.iCurrent + 2]; int nRec = (pIter->in.iNext - pIter->in.iCurrent) - 2; + assert( nRec>0 ); + /* Ensure that only changesets, or only patchsets, but not a mixture ** of both, are being combined. It is an error to try to combine a ** changeset and a patchset. */ @@ -230777,6 +232174,7 @@ static int sessionChangesetToHash( int nRec; int rc = SQLITE_OK; + pIter->in.bNoDiscard = 1; while( SQLITE_ROW==(sessionChangesetNext(pIter, &aRec, &nRec, 0)) ){ rc = sessionOneChangeToHash(pGrp, pIter, bRebase); if( rc!=SQLITE_OK ) break; @@ -231658,6 +233056,10 @@ struct Fts5PhraseIter { ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** ** xPhraseNext() ** See xPhraseFirst above. ** @@ -231724,9 +233126,32 @@ struct Fts5PhraseIter { ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. +** +** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the locale associated +** with column iCol of the current row. Usually, there is no associated +** locale, and output parameters (*pzLocale) and (*pnLocale) are set +** to NULL and 0, respectively. However, if the fts5_locale() function +** was used to associate a locale with the value when it was inserted +** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated +** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) +** is set to the size in bytes of the buffer, not including the +** nul-terminator. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an +** SQLite error code is returned. The final value of the output parameters +** is undefined in this case. +** +** xTokenize_v2: +** Tokenize text using the tokenizer belonging to the FTS5 table. This +** API is the same as the xTokenize() API, except that it allows a tokenizer +** locale to be specified. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 3 */ + int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); @@ -231768,6 +233193,15 @@ struct Fts5ExtensionApi { const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); + + /* Below this point are iVersion>=4 only */ + int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xTokenize_v2)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); }; /* @@ -231788,7 +233222,7 @@ struct Fts5ExtensionApi { ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) -** pointer provided by the application when the fts5_tokenizer object +** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the @@ -231812,7 +233246,7 @@ struct Fts5ExtensionApi { ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** -** The second argument indicates the reason that FTS5 is requesting +** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** @@ -231836,6 +233270,13 @@ struct Fts5ExtensionApi { ** on a columnsize=0 database. ** ** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth @@ -231859,6 +233300,30 @@ struct Fts5ExtensionApi { ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +**
    +**
  • There is no "iVersion" field, and +**
  • The xTokenize() method does not take a locale argument. +**
+** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a @@ -231967,6 +233432,33 @@ struct Fts5ExtensionApi { ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); @@ -231986,6 +233478,7 @@ struct fts5_tokenizer { ); }; + /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 @@ -232005,7 +233498,7 @@ struct fts5_tokenizer { */ typedef struct fts5_api fts5_api; struct fts5_api { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( @@ -232032,6 +233525,25 @@ struct fts5_api { fts5_extension_function xFunction, void (*xDestroy)(void*) ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); }; /* @@ -232105,6 +233617,22 @@ typedef sqlite3_uint64 u64; # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) +/* The uptr type is an unsigned integer large enough to hold a pointer +*/ +#if defined(HAVE_STDINT_H) + typedef uintptr_t uptr; +#elif SQLITE_PTRSIZE==4 + typedef u32 uptr; +#else + typedef u64 uptr; +#endif + +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) +#endif + #endif /* Truncate very long tokens to this many bytes. Hard limit is @@ -232188,6 +233716,18 @@ struct Fts5Colset { */ typedef struct Fts5Config Fts5Config; +typedef struct Fts5TokenizerConfig Fts5TokenizerConfig; + +struct Fts5TokenizerConfig { + Fts5Tokenizer *pTok; + fts5_tokenizer_v2 *pApi2; + fts5_tokenizer *pApi1; + const char **azArg; + int nArg; + int ePattern; /* FTS_PATTERN_XXX constant */ + const char *pLocale; /* Current locale to use */ + int nLocale; /* Size of pLocale in bytes */ +}; /* ** An instance of the following structure encodes all information that can @@ -232227,9 +233767,12 @@ typedef struct Fts5Config Fts5Config; ** ** INSERT INTO tbl(tbl, rank) VALUES('prefix-index', $bPrefixIndex); ** +** bLocale: +** Set to true if locale=1 was specified when the table was created. */ struct Fts5Config { sqlite3 *db; /* Database handle */ + Fts5Global *pGlobal; /* Global fts5 object for handle db */ char *zDb; /* Database holding FTS index (e.g. "main") */ char *zName; /* Name of FTS index */ int nCol; /* Number of columns */ @@ -232239,16 +233782,17 @@ struct Fts5Config { int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ int eContent; /* An FTS5_CONTENT value */ int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ + int bContentlessUnindexed; /* "contentless_unindexed=" option (dflt=0) */ char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ int bTokendata; /* "tokendata=" option value (dflt==0) */ + int bLocale; /* "locale=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; - Fts5Tokenizer *pTok; - fts5_tokenizer *pTokApi; + Fts5TokenizerConfig t; int bLock; /* True when table is preparing statement */ - int ePattern; /* FTS_PATTERN_XXX constant */ + /* Values loaded from the %_config table */ int iVersion; /* fts5 file format 'version' */ @@ -232277,9 +233821,10 @@ struct Fts5Config { #define FTS5_CURRENT_VERSION 4 #define FTS5_CURRENT_VERSION_SECUREDELETE 5 -#define FTS5_CONTENT_NORMAL 0 -#define FTS5_CONTENT_NONE 1 -#define FTS5_CONTENT_EXTERNAL 2 +#define FTS5_CONTENT_NORMAL 0 +#define FTS5_CONTENT_NONE 1 +#define FTS5_CONTENT_EXTERNAL 2 +#define FTS5_CONTENT_UNINDEXED 3 #define FTS5_DETAIL_FULL 0 #define FTS5_DETAIL_NONE 1 @@ -232314,6 +233859,8 @@ static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, i static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); +static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...); + /* ** End of interface to code in fts5_config.c. **************************************************************************/ @@ -232358,7 +233905,7 @@ static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); static void sqlite3Fts5Put32(u8*, int); static int sqlite3Fts5Get32(const u8*); -#define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32) +#define FTS5_POS2COLUMN(iPos) (int)((iPos >> 32) & 0x7FFFFFFF) #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) typedef struct Fts5PoslistReader Fts5PoslistReader; @@ -232643,18 +234190,20 @@ struct Fts5Table { Fts5Index *pIndex; /* Full-text index */ }; -static int sqlite3Fts5GetTokenizer( - Fts5Global*, - const char **azArg, - int nArg, - Fts5Config*, - char **pzErr -); +static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig); static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); static int sqlite3Fts5FlushToDisk(Fts5Table*); +static void sqlite3Fts5ClearLocale(Fts5Config *pConfig); +static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc); + +static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal); +static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal, + const char **ppText, int *pnText, const char **ppLoc, int *pnLoc +); + /* ** End of interface to code in fts5.c. **************************************************************************/ @@ -232734,8 +234283,8 @@ static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); static int sqlite3Fts5DropAll(Fts5Config*); static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); -static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); -static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); +static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**, int); +static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, int, sqlite3_value**, i64*); static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); @@ -232760,6 +234309,9 @@ static int sqlite3Fts5StorageOptimize(Fts5Storage *p); static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); static int sqlite3Fts5StorageReset(Fts5Storage *p); +static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage*); +static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel); + /* ** End of interface to code in fts5_storage.c. **************************************************************************/ @@ -232912,6 +234464,7 @@ static int sqlite3Fts5TokenizerPattern( int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), Fts5Tokenizer *pTok ); +static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ @@ -234689,6 +236242,7 @@ static int fts5HighlightCb( return rc; } + /* ** Implementation of highlight() function. */ @@ -234719,12 +236273,19 @@ static void fts5HighlightFunction( sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); rc = SQLITE_OK; }else if( ctx.zIn ){ + const char *pLoc = 0; /* Locale of column iCol */ + int nLoc = 0; /* Size of pLoc in bytes */ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); } if( rc==SQLITE_OK ){ - rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); + rc = pApi->xColumnLocale(pFts, iCol, &pLoc, &nLoc); + } + if( rc==SQLITE_OK ){ + rc = pApi->xTokenize_v2( + pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx, fts5HighlightCb + ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); @@ -234921,6 +236482,8 @@ static void fts5SnippetFunction( memset(&sFinder, 0, sizeof(Fts5SFinder)); for(i=0; ixColumnText(pFts, i, &sFinder.zDoc, &nDoc); if( rc!=SQLITE_OK ) break; - rc = pApi->xTokenize(pFts, - sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb + rc = pApi->xColumnLocale(pFts, i, &pLoc, &nLoc); + if( rc!=SQLITE_OK ) break; + rc = pApi->xTokenize_v2(pFts, + sFinder.zDoc, nDoc, pLoc, nLoc, (void*)&sFinder, fts5SentenceFinderCb ); if( rc!=SQLITE_OK ) break; rc = pApi->xColumnSize(pFts, i, &nDocsize); @@ -234987,6 +236552,9 @@ static void fts5SnippetFunction( rc = pApi->xColumnSize(pFts, iBestCol, &nColSize); } if( ctx.zIn ){ + const char *pLoc = 0; /* Locale of column iBestCol */ + int nLoc = 0; /* Bytes in pLoc */ + if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter); } @@ -235005,7 +236573,12 @@ static void fts5SnippetFunction( } if( rc==SQLITE_OK ){ - rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); + rc = pApi->xColumnLocale(pFts, iBestCol, &pLoc, &nLoc); + } + if( rc==SQLITE_OK ){ + rc = pApi->xTokenize_v2( + pFts, ctx.zIn, ctx.nIn, pLoc, nLoc, (void*)&ctx,fts5HighlightCb + ); } if( ctx.bOpen ){ fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); @@ -235189,6 +236762,53 @@ static void fts5Bm25Function( } } +/* +** Implementation of fts5_get_locale() function. +*/ +static void fts5GetLocaleFunction( + const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ + Fts5Context *pFts, /* First arg to pass to pApi functions */ + sqlite3_context *pCtx, /* Context for returning result/error */ + int nVal, /* Number of values in apVal[] array */ + sqlite3_value **apVal /* Array of trailing arguments */ +){ + int iCol = 0; + int eType = 0; + int rc = SQLITE_OK; + const char *zLocale = 0; + int nLocale = 0; + + /* xColumnLocale() must be available */ + assert( pApi->iVersion>=4 ); + + if( nVal!=1 ){ + const char *z = "wrong number of arguments to function fts5_get_locale()"; + sqlite3_result_error(pCtx, z, -1); + return; + } + + eType = sqlite3_value_numeric_type(apVal[0]); + if( eType!=SQLITE_INTEGER ){ + const char *z = "non-integer argument passed to function fts5_get_locale()"; + sqlite3_result_error(pCtx, z, -1); + return; + } + + iCol = sqlite3_value_int(apVal[0]); + if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){ + sqlite3_result_error_code(pCtx, SQLITE_RANGE); + return; + } + + rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale); + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(pCtx, rc); + return; + } + + sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT); +} + static int sqlite3Fts5AuxInit(fts5_api *pApi){ struct Builtin { const char *zFunc; /* Function name (nul-terminated) */ @@ -235196,9 +236816,10 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){ fts5_extension_function xFunc;/* Callback function */ void (*xDestroy)(void*); /* Destructor function */ } aBuiltin [] = { - { "snippet", 0, fts5SnippetFunction, 0 }, - { "highlight", 0, fts5HighlightFunction, 0 }, - { "bm25", 0, fts5Bm25Function, 0 }, + { "snippet", 0, fts5SnippetFunction, 0 }, + { "highlight", 0, fts5HighlightFunction, 0 }, + { "bm25", 0, fts5Bm25Function, 0 }, + { "fts5_get_locale", 0, fts5GetLocaleFunction, 0 }, }; int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ @@ -235863,7 +237484,6 @@ static int fts5ConfigSetEnum( ** eventually free any such error message using sqlite3_free(). */ static int fts5ConfigParseSpecial( - Fts5Global *pGlobal, Fts5Config *pConfig, /* Configuration object to update */ const char *zCmd, /* Special command to parse */ const char *zArg, /* Argument to parse */ @@ -235871,6 +237491,7 @@ static int fts5ConfigParseSpecial( ){ int rc = SQLITE_OK; int nCmd = (int)strlen(zCmd); + if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; const char *p; @@ -235927,12 +237548,11 @@ static int fts5ConfigParseSpecial( if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; sqlite3_int64 nArg = strlen(zArg) + 1; - char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); - char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); - char *pSpace = pDel; + char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg); - if( azArg && pSpace ){ - if( pConfig->pTok ){ + if( azArg ){ + char *pSpace = (char*)&azArg[nArg]; + if( pConfig->t.azArg ){ *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); rc = SQLITE_ERROR; }else{ @@ -235955,16 +237575,14 @@ static int fts5ConfigParseSpecial( *pzErr = sqlite3_mprintf("parse error in tokenize directive"); rc = SQLITE_ERROR; }else{ - rc = sqlite3Fts5GetTokenizer(pGlobal, - (const char**)azArg, (int)nArg, pConfig, - pzErr - ); + pConfig->t.azArg = (const char**)azArg; + pConfig->t.nArg = nArg; + azArg = 0; } } } - sqlite3_free(azArg); - sqlite3_free(pDel); + return rc; } @@ -235993,6 +237611,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("contentless_unindexed", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bContentlessUnindexed = (zArg[0]=='1'); + } + return rc; + } + if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ if( pConfig->zContentRowid ){ *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); @@ -236013,6 +237641,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("locale", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed locale=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bLocale = (zArg[0]=='1'); + } + return rc; + } + if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ const Fts5Enum aDetail[] = { { "none", FTS5_DETAIL_NONE }, @@ -236041,16 +237679,6 @@ static int fts5ConfigParseSpecial( return SQLITE_ERROR; } -/* -** Allocate an instance of the default tokenizer ("simple") at -** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error -** code if an error occurs. -*/ -static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ - assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); - return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0); -} - /* ** Gobble up the first bareword or quoted word from the input buffer zIn. ** Return a pointer to the character immediately following the last in @@ -236110,7 +237738,8 @@ static int fts5ConfigParseColumn( Fts5Config *p, char *zCol, char *zArg, - char **pzErr + char **pzErr, + int *pbUnindexed ){ int rc = SQLITE_OK; if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME) @@ -236121,6 +237750,7 @@ static int fts5ConfigParseColumn( }else if( zArg ){ if( 0==sqlite3_stricmp(zArg, "unindexed") ){ p->abUnindexed[p->nCol] = 1; + *pbUnindexed = 1; }else{ *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg); rc = SQLITE_ERROR; @@ -236141,11 +237771,26 @@ static int fts5ConfigMakeExprlist(Fts5Config *p){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid); if( p->eContent!=FTS5_CONTENT_NONE ){ + assert( p->eContent==FTS5_CONTENT_EXTERNAL + || p->eContent==FTS5_CONTENT_NORMAL + || p->eContent==FTS5_CONTENT_UNINDEXED + ); for(i=0; inCol; i++){ if( p->eContent==FTS5_CONTENT_EXTERNAL ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); - }else{ + }else if( p->eContent==FTS5_CONTENT_NORMAL || p->abUnindexed[i] ){ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); + }else{ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); + } + } + } + if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){ + for(i=0; inCol; i++){ + if( p->abUnindexed[i]==0 ){ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i); + }else{ + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL"); } } } @@ -236179,10 +237824,12 @@ static int sqlite3Fts5ConfigParse( Fts5Config *pRet; /* New object to return */ int i; sqlite3_int64 nByte; + int bUnindexed = 0; /* True if there are one or more UNINDEXED */ *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); + pRet->pGlobal = pGlobal; pRet->db = db; pRet->iCookie = -1; @@ -236231,13 +237878,13 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; }else{ if( bOption ){ - rc = fts5ConfigParseSpecial(pGlobal, pRet, + rc = fts5ConfigParseSpecial(pRet, ALWAYS(zOne)?zOne:"", zTwo?zTwo:"", pzErr ); }else{ - rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr); + rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr, &bUnindexed); zOne = 0; } } @@ -236269,11 +237916,17 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; } - /* If a tokenizer= option was successfully parsed, the tokenizer has - ** already been allocated. Otherwise, allocate an instance of the default - ** tokenizer (unicode61) now. */ - if( rc==SQLITE_OK && pRet->pTok==0 ){ - rc = fts5ConfigDefaultTokenizer(pGlobal, pRet); + /* We only allow contentless_unindexed=1 if the table is actually a + ** contentless one. + */ + if( rc==SQLITE_OK + && pRet->bContentlessUnindexed + && pRet->eContent!=FTS5_CONTENT_NONE + ){ + *pzErr = sqlite3_mprintf( + "contentless_unindexed=1 requires a contentless table" + ); + rc = SQLITE_ERROR; } /* If no zContent option was specified, fill in the default values. */ @@ -236284,6 +237937,9 @@ static int sqlite3Fts5ConfigParse( ); if( pRet->eContent==FTS5_CONTENT_NORMAL ){ zTail = "content"; + }else if( bUnindexed && pRet->bContentlessUnindexed ){ + pRet->eContent = FTS5_CONTENT_UNINDEXED; + zTail = "content"; }else if( pRet->bColumnsize ){ zTail = "docsize"; } @@ -236317,9 +237973,14 @@ static int sqlite3Fts5ConfigParse( static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; - if( pConfig->pTok ){ - pConfig->pTokApi->xDelete(pConfig->pTok); + if( pConfig->t.pTok ){ + if( pConfig->t.pApi1 ){ + pConfig->t.pApi1->xDelete(pConfig->t.pTok); + }else{ + pConfig->t.pApi2->xDelete(pConfig->t.pTok); + } } + sqlite3_free((char*)pConfig->t.azArg); sqlite3_free(pConfig->zDb); sqlite3_free(pConfig->zName); for(i=0; inCol; i++){ @@ -236394,10 +238055,24 @@ static int sqlite3Fts5Tokenize( void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ){ - if( pText==0 ) return SQLITE_OK; - return pConfig->pTokApi->xTokenize( - pConfig->pTok, pCtx, flags, pText, nText, xToken - ); + int rc = SQLITE_OK; + if( pText ){ + if( pConfig->t.pTok==0 ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } + if( rc==SQLITE_OK ){ + if( pConfig->t.pApi1 ){ + rc = pConfig->t.pApi1->xTokenize( + pConfig->t.pTok, pCtx, flags, pText, nText, xToken + ); + }else{ + rc = pConfig->t.pApi2->xTokenize(pConfig->t.pTok, pCtx, flags, + pText, nText, pConfig->t.pLocale, pConfig->t.nLocale, xToken + ); + } + } + } + return rc; } /* @@ -236651,13 +238326,10 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){ rc = SQLITE_ERROR; - if( pConfig->pzErrmsg ){ - assert( 0==*pConfig->pzErrmsg ); - *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format " - "(found %d, expected %d or %d) - run 'rebuild'", - iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE - ); - } + sqlite3Fts5ConfigErrmsg(pConfig, "invalid fts5 file format " + "(found %d, expected %d or %d) - run 'rebuild'", + iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE + ); }else{ pConfig->iVersion = iVersion; } @@ -236668,6 +238340,29 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ return rc; } +/* +** Set (*pConfig->pzErrmsg) to point to an sqlite3_malloc()ed buffer +** containing the error message created using printf() style formatting +** string zFmt and its trailing arguments. +*/ +static void sqlite3Fts5ConfigErrmsg(Fts5Config *pConfig, const char *zFmt, ...){ + va_list ap; /* ... printf arguments */ + char *zMsg = 0; + + va_start(ap, zFmt); + zMsg = sqlite3_vmprintf(zFmt, ap); + if( pConfig->pzErrmsg ){ + assert( *pConfig->pzErrmsg==0 ); + *pConfig->pzErrmsg = zMsg; + }else{ + sqlite3_free(zMsg); + } + + va_end(ap); +} + + + /* ** 2014 May 31 ** @@ -236724,7 +238419,7 @@ struct Fts5Expr { /* ** eType: -** Expression node type. Always one of: +** Expression node type. Usually one of: ** ** FTS5_AND (nChild, apChild valid) ** FTS5_OR (nChild, apChild valid) @@ -236732,6 +238427,10 @@ struct Fts5Expr { ** FTS5_STRING (pNear valid) ** FTS5_TERM (pNear valid) ** +** An expression node with eType==0 may also exist. It always matches zero +** rows. This is created when a phrase containing no tokens is parsed. +** e.g. "". +** ** iHeight: ** Distance from this node to furthest leaf. This is always 0 for nodes ** of type FTS5_STRING and FTS5_TERM. For all other nodes it is one @@ -236952,11 +238651,12 @@ static int sqlite3Fts5ExprNew( }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); sqlite3Fts5ParserFree(pEngine, fts5ParseFree); + assert( sParse.pExpr || sParse.rc!=SQLITE_OK ); assert_expr_depth_ok(sParse.rc, sParse.pExpr); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ - if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ + if( sParse.rc==SQLITE_OK && iColnCol ){ int n = sizeof(Fts5Colset); Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); if( pColset ){ @@ -236973,15 +238673,7 @@ static int sqlite3Fts5ExprNew( sParse.rc = SQLITE_NOMEM; sqlite3Fts5ParseNodeFree(sParse.pExpr); }else{ - if( !sParse.pExpr ){ - const int nByte = sizeof(Fts5ExprNode); - pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte); - if( pNew->pRoot ){ - pNew->pRoot->bEof = 1; - } - }else{ - pNew->pRoot = sParse.pExpr; - } + pNew->pRoot = sParse.pExpr; pNew->pIndex = 0; pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; @@ -237799,7 +239491,7 @@ static int fts5ExprNodeTest_STRING( } }else{ Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; - if( pIter->iRowid==iLast || pIter->bEof ) continue; + if( pIter->iRowid==iLast ) continue; bMatch = 0; if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ return rc; @@ -238321,9 +240013,6 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( Fts5ExprNearset *pRet = 0; if( pParse->rc==SQLITE_OK ){ - if( pPhrase==0 ){ - return pNear; - } if( pNear==0 ){ sqlite3_int64 nByte; nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); @@ -238545,6 +240234,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } + assert( pParse->apPhrase!=0 ); pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } @@ -238564,7 +240254,7 @@ static int sqlite3Fts5ExprClonePhrase( Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ - if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + if( !pExpr || iPhrase<0 || iPhrase>=pExpr->nPhrase ){ rc = SQLITE_RANGE; }else{ pOrig = pExpr->apExprPhrase[iPhrase]; @@ -238932,6 +240622,9 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ } } +/* +** Add pSub as a child of p. +*/ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int ii = p->nChild; if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ @@ -239076,19 +240769,23 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; + pNear = 0; + assert( pLeft==0 && pRight==0 ); } } }else{ + assert( pNear==0 ); fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); + pLeft = pRight = 0; if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){ sqlite3Fts5ParseError(pParse, "fts5 expression tree is too large (maximum depth %d)", SQLITE_FTS5_MAX_EXPR_DEPTH ); - sqlite3_free(pRet); + sqlite3Fts5ParseNodeFree(pRet); pRet = 0; } } @@ -239140,6 +240837,8 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( ); if( pRight->eType==FTS5_EOF ){ + assert( pParse->apPhrase!=0 ); + assert( pParse->nPhrase>0 ); assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); sqlite3Fts5ParseNodeFree(pRight); pRet = pLeft; @@ -239772,6 +241471,7 @@ static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ pNode->iRowid = iRowid; pNode->bEof = 0; switch( pNode->eType ){ + case 0: case FTS5_TERM: case FTS5_STRING: return (pNode->pNear->apPhrase[0]->poslist.n>0); @@ -241355,11 +243055,12 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); - sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; + int szData = (sizeof(Fts5Data) + 7) & ~7; + sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING; pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; - aOut = pRet->p = (u8*)&pRet[1]; + aOut = pRet->p = (u8*)pRet + szData; }else{ rc = SQLITE_NOMEM; } @@ -241382,6 +243083,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ } assert( (pRet==0)==(p->rc!=SQLITE_OK) ); + assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) ); return pRet; } @@ -242707,7 +244409,7 @@ static void fts5SegIterNext_None( if( iOffiEndofDoclist ){ /* Next entry is on the current page */ - i64 iDelta; + u64 iDelta; iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); pIter->iLeafOffset = iOff; pIter->iRowid += iDelta; @@ -245411,6 +247113,11 @@ static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ nBest = nPercent; } } + + /* If pLvl is already the input level to an ongoing merge, look no + ** further for a merge candidate. The caller should be allowed to + ** continue merging from pLvl first. */ + if( pLvl->nMerge ) break; } } return iRet; @@ -249335,7 +251042,7 @@ static int fts5structConnectMethod( /* ** We must have a single struct=? constraint that will be passed through -** into the xFilter method. If there is no valid stmt=? constraint, +** into the xFilter method. If there is no valid struct=? constraint, ** then return an SQLITE_CONSTRAINT error. */ static int fts5structBestIndexMethod( @@ -249677,8 +251384,17 @@ struct Fts5Global { Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */ Fts5Cursor *pCsr; /* First in list of all open cursors */ + u32 aLocaleHdr[4]; }; +/* +** Size of header on fts5_locale() values. And macro to access a buffer +** containing a copy of the header from an Fts5Config pointer. +*/ +#define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr )) +#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr)) + + /* ** Each auxiliary function registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part @@ -249697,11 +251413,28 @@ struct Fts5Auxiliary { ** Each tokenizer module registered with the FTS5 module is represented ** by an object of the following type. All such objects are stored as part ** of the Fts5Global.pTok list. +** +** bV2Native: +** True if the tokenizer was registered using xCreateTokenizer_v2(), false +** for xCreateTokenizer(). If this variable is true, then x2 is populated +** with the routines as supplied by the caller and x1 contains synthesized +** wrapper routines. In this case the user-data pointer passed to +** x1.xCreate should be a pointer to the Fts5TokenizerModule structure, +** not a copy of pUserData. +** +** Of course, if bV2Native is false, then x1 contains the real routines and +** x2 the synthesized ones. In this case a pointer to the Fts5TokenizerModule +** object should be passed to x2.xCreate. +** +** The synthesized wrapper routines are necessary for xFindTokenizer(_v2) +** calls. */ struct Fts5TokenizerModule { char *zName; /* Name of tokenizer */ void *pUserData; /* User pointer passed to xCreate() */ - fts5_tokenizer x; /* Tokenizer functions */ + int bV2Native; /* True if v2 native tokenizer */ + fts5_tokenizer x1; /* Tokenizer functions */ + fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ void (*xDestroy)(void*); /* Destructor function */ Fts5TokenizerModule *pNext; /* Next registered tokenizer module */ }; @@ -249789,7 +251522,7 @@ struct Fts5Cursor { Fts5Auxiliary *pAux; /* Currently executing extension function */ Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */ - /* Cache used by auxiliary functions xInst() and xInstCount() */ + /* Cache used by auxiliary API functions xInst() and xInstCount() */ Fts5PoslistReader *aInstIter; /* One for each phrase */ int nInstAlloc; /* Size of aInst[] array (entries / 3) */ int nInstCount; /* Number of phrase instances */ @@ -249900,10 +251633,16 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ #endif /* -** Return true if pTab is a contentless table. +** Return true if pTab is a contentless table. If parameter bIncludeUnindexed +** is true, this includes contentless tables that store UNINDEXED columns +** only. */ -static int fts5IsContentless(Fts5FullTable *pTab){ - return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE; +static int fts5IsContentless(Fts5FullTable *pTab, int bIncludeUnindexed){ + int eContent = pTab->p.pConfig->eContent; + return ( + eContent==FTS5_CONTENT_NONE + || (bIncludeUnindexed && eContent==FTS5_CONTENT_UNINDEXED) + ); } /* @@ -249971,8 +251710,12 @@ static int fts5InitVtab( assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ + pConfig->pzErrmsg = pzErr; pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; + if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } } /* Open the index sub-system */ @@ -249994,11 +251737,7 @@ static int fts5InitVtab( /* Load the initial configuration */ if( rc==SQLITE_OK ){ - assert( pConfig->pzErrmsg==0 ); - pConfig->pzErrmsg = pzErr; - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - sqlite3Fts5IndexRollback(pTab->p.pIndex); - pConfig->pzErrmsg = 0; + rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie-1); } if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -250008,6 +251747,7 @@ static int fts5InitVtab( rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } + if( pConfig ) pConfig->pzErrmsg = 0; if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; @@ -250075,10 +251815,10 @@ static int fts5UsePatternMatch( ){ assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); - if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ + if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ return 1; } - if( pConfig->ePattern==FTS5_PATTERN_LIKE + if( pConfig->t.ePattern==FTS5_PATTERN_LIKE && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) ){ return 1; @@ -250125,10 +251865,10 @@ static int fts5UsePatternMatch( ** This function ensures that there is at most one "r" or "=". And that if ** there exists an "=" then there is no "<" or ">". ** -** Costs are assigned as follows: +** If an unusable MATCH operator is present in the WHERE clause, then +** SQLITE_CONSTRAINT is returned. ** -** a) If an unusable MATCH operator is present in the WHERE clause, the -** cost is unconditionally set to 1e50 (a really big number). +** Costs are assigned as follows: ** ** a) If a MATCH operator is present, the cost depends on the other ** constraints also present. As follows: @@ -250161,7 +251901,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ int bSeenEq = 0; int bSeenGt = 0; int bSeenLt = 0; - int bSeenMatch = 0; + int nSeenMatch = 0; int bSeenRank = 0; @@ -250192,18 +251932,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* A MATCH operator or equivalent */ if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an - ** unusable plan. Set a prohibitively high cost. */ - pInfo->estimatedCost = 1e50; - assert( iIdxStr < pInfo->nConstraint*6 + 1 ); - idxStr[iIdxStr] = 0; - return SQLITE_OK; + ** unusable plan. Return SQLITE_CONSTRAINT. */ + return SQLITE_CONSTRAINT; }else{ if( iCol==nCol+1 ){ if( bSeenRank ) continue; idxStr[iIdxStr++] = 'r'; bSeenRank = 1; - }else if( iCol>=0 ){ - bSeenMatch = 1; + }else{ + nSeenMatch++; idxStr[iIdxStr++] = 'M'; sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); idxStr += strlen(&idxStr[iIdxStr]); @@ -250220,6 +251957,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ idxStr += strlen(&idxStr[iIdxStr]); pInfo->aConstraintUsage[i].argvIndex = ++iCons; assert( idxStr[iIdxStr]=='\0' ); + nSeenMatch++; }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ idxStr[iIdxStr++] = '='; bSeenEq = 1; @@ -250256,7 +251994,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; - if( iSort==(pConfig->nCol+1) && bSeenMatch ){ + if( iSort==(pConfig->nCol+1) && nSeenMatch>0 ){ idxFlags |= FTS5_BI_ORDER_RANK; }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ idxFlags |= FTS5_BI_ORDER_ROWID; @@ -250271,14 +252009,17 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* Calculate the estimated cost based on the flags set in idxFlags. */ if( bSeenEq ){ - pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0; - if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo); + pInfo->estimatedCost = nSeenMatch ? 1000.0 : 10.0; + if( nSeenMatch==0 ) fts5SetUniqueFlag(pInfo); }else if( bSeenLt && bSeenGt ){ - pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0; + pInfo->estimatedCost = nSeenMatch ? 5000.0 : 250000.0; }else if( bSeenLt || bSeenGt ){ - pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0; + pInfo->estimatedCost = nSeenMatch ? 7500.0 : 750000.0; }else{ - pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0; + pInfo->estimatedCost = nSeenMatch ? 10000.0 : 1000000.0; + } + for(i=1; iestimatedCost *= 0.4; } pInfo->idxNum = idxFlags; @@ -250554,6 +252295,7 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ } }else{ rc = SQLITE_OK; + CsrFlagSet(pCsr, FTS5CSR_REQUIRE_DOCSIZE); } break; } @@ -250583,7 +252325,7 @@ static int fts5PrepareStatement( rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, &pRet, 0); if( rc!=SQLITE_OK ){ - *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db)); + sqlite3Fts5ConfigErrmsg(pConfig, "%s", sqlite3_errmsg(pConfig->db)); } sqlite3_free(zSql); } @@ -250807,6 +252549,145 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){ return iDefault; } +/* +** Set the error message on the virtual table passed as the first argument. +*/ +static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ + va_list ap; /* ... printf arguments */ + va_start(ap, zFormat); + sqlite3_free(p->p.base.zErrMsg); + p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + +/* +** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale +** specified by pLocale/nLocale. The buffer indicated by pLocale must remain +** valid until after the final call to sqlite3Fts5Tokenize() that will use +** the locale. +*/ +static void sqlite3Fts5SetLocale( + Fts5Config *pConfig, + const char *zLocale, + int nLocale +){ + Fts5TokenizerConfig *pT = &pConfig->t; + pT->pLocale = zLocale; + pT->nLocale = nLocale; +} + +/* +** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale(). +*/ +static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){ + sqlite3Fts5SetLocale(pConfig, 0, 0); +} + +/* +** Return true if the value passed as the only argument is an +** fts5_locale() value. +*/ +static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){ + int ret = 0; + if( sqlite3_value_type(pVal)==SQLITE_BLOB ){ + /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case. + ** If the blob was created using zeroblob(), then sqlite3_value_blob() + ** may call malloc(). If this malloc() fails, then the values returned + ** by both value_blob() and value_bytes() will be 0. If value_bytes() were + ** called first, then the NULL pointer returned by value_blob() might + ** be dereferenced. */ + const u8 *pBlob = sqlite3_value_blob(pVal); + int nBlob = sqlite3_value_bytes(pVal); + if( nBlob>FTS5_LOCALE_HDR_SIZE + && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE) + ){ + ret = 1; + } + } + return ret; +} + +/* +** Value pVal is guaranteed to be an fts5_locale() value, according to +** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale +** from the value and returns them separately. +** +** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set +** to point to buffers containing the text and locale, as utf-8, +** respectively. In this case output parameters (*pnText) and (*pnLoc) are +** set to the sizes in bytes of these two buffers. +** +** Or, if an error occurs, then an SQLite error code is returned. The final +** value of the four output parameters is undefined in this case. +*/ +static int sqlite3Fts5DecodeLocaleValue( + sqlite3_value *pVal, + const char **ppText, + int *pnText, + const char **ppLoc, + int *pnLoc +){ + const char *p = sqlite3_value_blob(pVal); + int n = sqlite3_value_bytes(pVal); + int nLoc = 0; + + assert( sqlite3_value_type(pVal)==SQLITE_BLOB ); + assert( n>FTS5_LOCALE_HDR_SIZE ); + + for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){ + if( nLoc==(n-1) ){ + return SQLITE_MISMATCH; + } + } + *ppLoc = &p[FTS5_LOCALE_HDR_SIZE]; + *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE; + + *ppText = &p[nLoc+1]; + *pnText = n - nLoc - 1; + return SQLITE_OK; +} + +/* +** Argument pVal is the text of a full-text search expression. It may or +** may not have been wrapped by fts5_locale(). This function extracts +** the text of the expression, and sets output variable (*pzText) to +** point to a nul-terminated buffer containing the expression. +** +** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called +** to set the tokenizer to use the specified locale. +** +** If output variable (*pbFreeAndReset) is set to true, then the caller +** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer +** locale, and (b) call sqlite3_free() to free (*pzText). +*/ +static int fts5ExtractExprText( + Fts5Config *pConfig, /* Fts5 configuration */ + sqlite3_value *pVal, /* Value to extract expression text from */ + char **pzText, /* OUT: nul-terminated buffer of text */ + int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */ +){ + int rc = SQLITE_OK; + + if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText); + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + } + *pbFreeAndReset = 1; + }else{ + *pzText = (char*)sqlite3_value_text(pVal); + *pbFreeAndReset = 0; + } + + return rc; +} + + /* ** This is the xFilter interface for the virtual table. See ** the virtual table xFilter method documentation for additional @@ -250841,13 +252722,7 @@ static int fts5FilterMethod( int iIdxStr = 0; Fts5Expr *pExpr = 0; - if( pConfig->bLock ){ - pTab->p.base.zErrMsg = sqlite3_mprintf( - "recursively defined fts5 content table" - ); - return SQLITE_ERROR; - } - + assert( pConfig->bLock==0 ); if( pCsr->ePlan ){ fts5FreeCursorComponents(pCsr); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr)); @@ -250871,8 +252746,14 @@ static int fts5FilterMethod( pRank = apVal[i]; break; case 'M': { - const char *zText = (const char*)sqlite3_value_text(apVal[i]); + char *zText = 0; + int bFreeAndReset = 0; + int bInternal = 0; + + rc = fts5ExtractExprText(pConfig, apVal[i], &zText, &bFreeAndReset); + if( rc!=SQLITE_OK ) goto filter_out; if( zText==0 ) zText = ""; + iCol = 0; do{ iCol = iCol*10 + (idxStr[iIdxStr]-'0'); @@ -250884,7 +252765,7 @@ static int fts5FilterMethod( ** indicates that the MATCH expression is not a full text query, ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); - goto filter_out; + bInternal = 1; }else{ char **pzErr = &pTab->p.base.zErrMsg; rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); @@ -250892,9 +252773,15 @@ static int fts5FilterMethod( rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; } - if( rc!=SQLITE_OK ) goto filter_out; } + if( bFreeAndReset ){ + sqlite3_free(zText); + sqlite3Fts5ClearLocale(pConfig); + } + + if( bInternal || rc!=SQLITE_OK ) goto filter_out; + break; } case 'L': @@ -250982,9 +252869,7 @@ static int fts5FilterMethod( } } }else if( pConfig->zContent==0 ){ - *pConfig->pzErrmsg = sqlite3_mprintf( - "%s: table does not support scanning", pConfig->zName - ); + fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName); rc = SQLITE_ERROR; }else{ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup @@ -251027,9 +252912,13 @@ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ assert( pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SORTED_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE + || pCsr->ePlan==FTS5_PLAN_SCAN + || pCsr->ePlan==FTS5_PLAN_ROWID ); if( pCsr->pSorter ){ return pCsr->pSorter->iRowid; + }else if( pCsr->ePlan>=FTS5_PLAN_SCAN ){ + return sqlite3_column_int64(pCsr->pStmt, 0); }else{ return sqlite3Fts5ExprRowid(pCsr->pExpr); } @@ -251046,25 +252935,16 @@ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ int ePlan = pCsr->ePlan; assert( CsrFlagTest(pCsr, FTS5CSR_EOF)==0 ); - switch( ePlan ){ - case FTS5_PLAN_SPECIAL: - *pRowid = 0; - break; - - case FTS5_PLAN_SOURCE: - case FTS5_PLAN_MATCH: - case FTS5_PLAN_SORTED_MATCH: - *pRowid = fts5CursorRowid(pCsr); - break; - - default: - *pRowid = sqlite3_column_int64(pCsr->pStmt, 0); - break; + if( ePlan==FTS5_PLAN_SPECIAL ){ + *pRowid = 0; + }else{ + *pRowid = fts5CursorRowid(pCsr); } return SQLITE_OK; } + /* ** If the cursor requires seeking (bSeekRequired flag is set), seek it. ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. @@ -251101,8 +252981,13 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; + fts5SetVtabError((Fts5FullTable*)pTab, + "fts5: missing row %lld from content table %s", + fts5CursorRowid(pCsr), + pTab->pConfig->zContent + ); }else if( pTab->pConfig->pzErrmsg ){ - *pTab->pConfig->pzErrmsg = sqlite3_mprintf( + fts5SetVtabError((Fts5FullTable*)pTab, "%s", sqlite3_errmsg(pTab->pConfig->db) ); } @@ -251111,14 +252996,6 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ return rc; } -static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ - va_list ap; /* ... printf arguments */ - va_start(ap, zFormat); - assert( p->p.base.zErrMsg==0 ); - p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); - va_end(ap); -} - /* ** This function is called to handle an FTS INSERT command. In other words, ** an INSERT statement of the form: @@ -251156,7 +253033,7 @@ static int fts5SpecialInsert( } bLoadConfig = 1; }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ - if( pConfig->eContent==FTS5_CONTENT_NONE ){ + if( fts5IsContentless(pTab, 1) ){ fts5SetVtabError(pTab, "'rebuild' may not be used with a contentless fts5 table" ); @@ -251212,7 +253089,7 @@ static int fts5SpecialDelete( int eType1 = sqlite3_value_type(apVal[1]); if( eType1==SQLITE_INTEGER ){ sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2], 0); } return rc; } @@ -251225,7 +253102,7 @@ static void fts5StorageInsert( ){ int rc = *pRc; if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid); + rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, 0, apVal, piRowid); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid); @@ -251233,6 +253110,67 @@ static void fts5StorageInsert( *pRc = rc; } +/* +** +** This function is called when the user attempts an UPDATE on a contentless +** table. Parameter bRowidModified is true if the UPDATE statement modifies +** the rowid value. Parameter apVal[] contains the new values for each user +** defined column of the fts5 table. pConfig is the configuration object of the +** table being updated (guaranteed to be contentless). The contentless_delete=1 +** and contentless_unindexed=1 options may or may not be set. +** +** This function returns SQLITE_OK if the UPDATE can go ahead, or an SQLite +** error code if it cannot. In this case an error message is also loaded into +** pConfig. Output parameter (*pbContent) is set to true if the caller should +** update the %_content table only - not the FTS index or any other shadow +** table. This occurs when an UPDATE modifies only UNINDEXED columns of the +** table. +** +** An UPDATE may proceed if: +** +** * The only columns modified are UNINDEXED columns, or +** +** * The contentless_delete=1 option was specified and all of the indexed +** columns (not a subset) have been modified. +*/ +static int fts5ContentlessUpdate( + Fts5Config *pConfig, + sqlite3_value **apVal, + int bRowidModified, + int *pbContent +){ + int ii; + int bSeenIndex = 0; /* Have seen modified indexed column */ + int bSeenIndexNC = 0; /* Have seen unmodified indexed column */ + int rc = SQLITE_OK; + + for(ii=0; iinCol; ii++){ + if( pConfig->abUnindexed[ii]==0 ){ + if( sqlite3_value_nochange(apVal[ii]) ){ + bSeenIndexNC++; + }else{ + bSeenIndex++; + } + } + } + + if( bSeenIndex==0 && bRowidModified==0 ){ + *pbContent = 1; + }else{ + if( bSeenIndexNC || pConfig->bContentlessDelete==0 ){ + rc = SQLITE_ERROR; + sqlite3Fts5ConfigErrmsg(pConfig, + (pConfig->bContentlessDelete ? + "%s a subset of columns on fts5 contentless-delete table: %s" : + "%s contentless fts5 table: %s") + , "cannot UPDATE", pConfig->zName + ); + } + } + + return rc; +} + /* ** This function is the implementation of the xUpdate callback used by ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be @@ -251319,41 +253257,46 @@ static int fts5UpdateMethod( assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); assert( nArg!=1 || eType0==SQLITE_INTEGER ); - /* Filter out attempts to run UPDATE or DELETE on contentless tables. - ** This is not suported. Except - they are both supported if the CREATE - ** VIRTUAL TABLE statement contained "contentless_delete=1". */ - if( eType0==SQLITE_INTEGER - && pConfig->eContent==FTS5_CONTENT_NONE - && pConfig->bContentlessDelete==0 - ){ - pTab->p.base.zErrMsg = sqlite3_mprintf( - "cannot %s contentless fts5 table: %s", - (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName - ); - rc = SQLITE_ERROR; - } - /* DELETE */ - else if( nArg==1 ){ - i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); - bUpdateOrDelete = 1; + if( nArg==1 ){ + /* It is only possible to DELETE from a contentless table if the + ** contentless_delete=1 flag is set. */ + if( fts5IsContentless(pTab, 1) && pConfig->bContentlessDelete==0 ){ + fts5SetVtabError(pTab, + "cannot DELETE from contentless fts5 table: %s", pConfig->zName + ); + rc = SQLITE_ERROR; + }else{ + i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0); + bUpdateOrDelete = 1; + } } /* INSERT or UPDATE */ else{ int eType1 = sqlite3_value_numeric_type(apVal[1]); - if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){ - rc = SQLITE_MISMATCH; + /* It is an error to write an fts5_locale() value to a table without + ** the locale=1 option. */ + if( pConfig->bLocale==0 ){ + int ii; + for(ii=0; iinCol; ii++){ + sqlite3_value *pVal = apVal[ii+2]; + if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + fts5SetVtabError(pTab, "fts5_locale() requires locale=1"); + rc = SQLITE_MISMATCH; + goto update_out; + } + } } - else if( eType0!=SQLITE_INTEGER ){ + if( eType0!=SQLITE_INTEGER ){ /* An INSERT statement. If the conflict-mode is REPLACE, first remove ** the current entry (if any). */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0); bUpdateOrDelete = 1; } fts5StorageInsert(&rc, pTab, apVal, pRowid); @@ -251361,30 +253304,57 @@ static int fts5UpdateMethod( /* UPDATE */ else{ + Fts5Storage *pStorage = pTab->pStorage; i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ - if( eType1==SQLITE_INTEGER && iOld!=iNew ){ + int bContent = 0; /* Content only update */ + + /* If this is a contentless table (including contentless_unindexed=1 + ** tables), check if the UPDATE may proceed. */ + if( fts5IsContentless(pTab, 1) ){ + rc = fts5ContentlessUpdate(pConfig, &apVal[2], iOld!=iNew, &bContent); + if( rc!=SQLITE_OK ) goto update_out; + } + + if( eType1!=SQLITE_INTEGER ){ + rc = SQLITE_MISMATCH; + }else if( iOld!=iNew ){ + assert( bContent==0 ); if( eConflict==SQLITE_REPLACE ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iNew, 0, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); }else{ - rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); + rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageContentInsert(pStorage, 0, apVal, pRowid); } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageIndexInsert(pStorage, apVal, *pRowid); + } + } + }else if( bContent ){ + /* This occurs when an UPDATE on a contentless table affects *only* + ** UNINDEXED columns. This is a no-op for contentless_unindexed=0 + ** tables, or a write to the %_content table only for =1 tables. */ + assert( fts5IsContentless(pTab, 1) ); + rc = sqlite3Fts5StorageFindDeleteRow(pStorage, iOld); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid); } }else{ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1); fts5StorageInsert(&rc, pTab, apVal, pRowid); } bUpdateOrDelete = 1; + sqlite3Fts5StorageReleaseDeleteRow(pStorage); } + } } @@ -251401,6 +253371,7 @@ static int fts5UpdateMethod( } } + update_out: pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -251422,9 +253393,11 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ ** Implementation of xBegin() method. */ static int fts5BeginMethod(sqlite3_vtab *pVtab){ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); - fts5NewTransaction((Fts5FullTable*)pVtab); - return SQLITE_OK; + int rc = fts5NewTransaction((Fts5FullTable*)pVtab); + if( rc==SQLITE_OK ){ + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); + } + return rc; } /* @@ -251478,17 +253451,40 @@ static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); } -static int fts5ApiTokenize( +/* +** Implementation of xTokenize_v2() API. +*/ +static int fts5ApiTokenize_v2( Fts5Context *pCtx, const char *pText, int nText, + const char *pLoc, int nLoc, void *pUserData, int (*xToken)(void*, int, const char*, int, int, int) ){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); - return sqlite3Fts5Tokenize( - pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken + int rc = SQLITE_OK; + + sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pTab->pConfig, + FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken ); + sqlite3Fts5SetLocale(pTab->pConfig, 0, 0); + + return rc; +} + +/* +** Implementation of xTokenize() API. This is just xTokenize_v2() with NULL/0 +** passed as the locale. +*/ +static int fts5ApiTokenize( + Fts5Context *pCtx, + const char *pText, int nText, + void *pUserData, + int (*xToken)(void*, int, const char*, int, int, int) +){ + return fts5ApiTokenize_v2(pCtx, pText, nText, 0, 0, pUserData, xToken); } static int fts5ApiPhraseCount(Fts5Context *pCtx){ @@ -251501,6 +253497,49 @@ static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){ return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); } +/* +** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This +** function extracts the text value of column iCol of the current row. +** Additionally, if there is an associated locale, it invokes +** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller +** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point +** after this function returns. +** +** If successful, (*ppText) is set to point to a buffer containing the text +** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that +** buffer in bytes. It is not guaranteed to be nul-terminated. If an error +** occurs, an SQLite error code is returned. The final values of the two +** output parameters are undefined in this case. +*/ +static int fts5TextFromStmt( + Fts5Config *pConfig, + sqlite3_stmt *pStmt, + int iCol, + const char **ppText, + int *pnText +){ + sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1); + const char *pLoc = 0; + int nLoc = 0; + int rc = SQLITE_OK; + + if( pConfig->bLocale + && pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc); + }else{ + *ppText = (const char*)sqlite3_value_text(pVal); + *pnText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){ + pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol); + nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol); + } + } + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + return rc; +} + static int fts5ApiColumnText( Fts5Context *pCtx, int iCol, @@ -251510,28 +253549,35 @@ static int fts5ApiColumnText( int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); if( iCol<0 || iCol>=pTab->pConfig->nCol ){ rc = SQLITE_RANGE; - }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) - || pCsr->ePlan==FTS5_PLAN_SPECIAL - ){ + }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab), 0) ){ *pz = 0; *pn = 0; }else{ rc = fts5SeekCursor(pCsr, 0); if( rc==SQLITE_OK ){ - *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1); - *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1); + rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn); + sqlite3Fts5ClearLocale(pTab->pConfig); } } return rc; } +/* +** This is called by various API functions - xInst, xPhraseFirst, +** xPhraseFirstColumn etc. - to obtain the position list for phrase iPhrase +** of the current row. This function works for both detail=full tables (in +** which case the position-list was read from the fts index) or for other +** detail= modes if the row content is available. +*/ static int fts5CsrPoslist( - Fts5Cursor *pCsr, - int iPhrase, - const u8 **pa, - int *pn + Fts5Cursor *pCsr, /* Fts5 cursor object */ + int iPhrase, /* Phrase to find position list for */ + const u8 **pa, /* OUT: Pointer to position list buffer */ + int *pn /* OUT: Size of (*pa) in bytes */ ){ Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; int rc = SQLITE_OK; @@ -251539,20 +253585,32 @@ static int fts5CsrPoslist( if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ rc = SQLITE_RANGE; + }else if( pConfig->eDetail!=FTS5_DETAIL_FULL + && fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) + ){ + *pa = 0; + *pn = 0; + return SQLITE_OK; }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5PoslistPopulator *aPopulator; int i; + aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); if( aPopulator==0 ) rc = SQLITE_NOMEM; + if( rc==SQLITE_OK ){ + rc = fts5SeekCursor(pCsr, 0); + } for(i=0; inCol && rc==SQLITE_OK; i++){ - int n; const char *z; - rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n); + const char *z = 0; + int n = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprPopulatePoslists( pConfig, pCsr->pExpr, aPopulator, i, z, n ); } + sqlite3Fts5ClearLocale(pConfig); } sqlite3_free(aPopulator); @@ -251577,7 +253635,6 @@ static int fts5CsrPoslist( *pn = 0; } - return rc; } @@ -251646,7 +253703,8 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ aInst[0] = iBest; aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); - if( aInst[1]<0 || aInst[1]>=nCol ){ + assert( aInst[1]>=0 ); + if( aInst[1]>=nCol ){ rc = FTS5_CORRUPT; break; } @@ -251724,7 +253782,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ if( pConfig->bColumnsize ){ i64 iRowid = fts5CursorRowid(pCsr); rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize); - }else if( pConfig->zContent==0 ){ + }else if( !pConfig->zContent || pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ int i; for(i=0; inCol; i++){ if( pConfig->abUnindexed[i]==0 ){ @@ -251733,17 +253791,19 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ } }else{ int i; + rc = fts5SeekCursor(pCsr, 0); for(i=0; rc==SQLITE_OK && inCol; i++){ if( pConfig->abUnindexed[i]==0 ){ - const char *z; int n; - void *p = (void*)(&pCsr->aColumnSize[i]); + const char *z = 0; + int n = 0; pCsr->aColumnSize[i] = 0; - rc = fts5ApiColumnText(pCtx, i, &z, &n); + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5Tokenize( - pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX, + z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb ); } + sqlite3Fts5ClearLocale(pConfig); } } } @@ -251823,11 +253883,10 @@ static void *fts5ApiGetAuxdata(Fts5Context *pCtx, int bClear){ } static void fts5ApiPhraseNext( - Fts5Context *pUnused, + Fts5Context *pCtx, Fts5PhraseIter *pIter, int *piCol, int *piOff ){ - UNUSED_PARAM(pUnused); if( pIter->a>=pIter->b ){ *piCol = -1; *piOff = -1; @@ -251835,8 +253894,12 @@ static void fts5ApiPhraseNext( int iVal; pIter->a += fts5GetVarint32(pIter->a, iVal); if( iVal==1 ){ + /* Avoid returning a (*piCol) value that is too large for the table, + ** even if the position-list is corrupt. The caller might not be + ** expecting it. */ + int nCol = ((Fts5Table*)(((Fts5Cursor*)pCtx)->base.pVtab))->pConfig->nCol; pIter->a += fts5GetVarint32(pIter->a, iVal); - *piCol = iVal; + *piCol = (iVal>=nCol ? nCol-1 : iVal); *piOff = 0; pIter->a += fts5GetVarint32(pIter->a, iVal); } @@ -251986,8 +254049,48 @@ static int fts5ApiQueryPhrase(Fts5Context*, int, void*, int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) ); +/* +** The xColumnLocale() API. +*/ +static int fts5ApiColumnLocale( + Fts5Context *pCtx, + int iCol, + const char **pzLocale, + int *pnLocale +){ + int rc = SQLITE_OK; + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + Fts5Config *pConfig = ((Fts5Table*)(pCsr->base.pVtab))->pConfig; + + *pzLocale = 0; + *pnLocale = 0; + + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); + if( iCol<0 || iCol>=pConfig->nCol ){ + rc = SQLITE_RANGE; + }else if( + pConfig->abUnindexed[iCol]==0 + && 0==fts5IsContentless((Fts5FullTable*)pCsr->base.pVtab, 1) + && pConfig->bLocale + ){ + rc = fts5SeekCursor(pCsr, 0); + if( rc==SQLITE_OK ){ + const char *zDummy = 0; + int nDummy = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy); + if( rc==SQLITE_OK ){ + *pzLocale = pConfig->t.pLocale; + *pnLocale = pConfig->t.nLocale; + } + sqlite3Fts5ClearLocale(pConfig); + } + } + + return rc; +} + static const Fts5ExtensionApi sFts5Api = { - 3, /* iVersion */ + 4, /* iVersion */ fts5ApiUserData, fts5ApiColumnCount, fts5ApiRowCount, @@ -252008,7 +254111,9 @@ static const Fts5ExtensionApi sFts5Api = { fts5ApiPhraseFirstColumn, fts5ApiPhraseNextColumn, fts5ApiQueryToken, - fts5ApiInstToken + fts5ApiInstToken, + fts5ApiColumnLocale, + fts5ApiTokenize_v2 }; /* @@ -252059,6 +254164,7 @@ static void fts5ApiInvoke( sqlite3_value **argv ){ assert( pCsr->pAux==0 ); + assert( pCsr->ePlan!=FTS5_PLAN_SPECIAL ); pCsr->pAux = pAux; pAux->xFunc(&sFts5Api, (Fts5Context*)pCsr, context, argc, argv); pCsr->pAux = 0; @@ -252072,6 +254178,21 @@ static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){ return pCsr; } +/* +** Parameter zFmt is a printf() style formatting string. This function +** formats it using the trailing arguments and returns the result as +** an error message to the context passed as the first argument. +*/ +static void fts5ResultError(sqlite3_context *pCtx, const char *zFmt, ...){ + char *zErr = 0; + va_list ap; + va_start(ap, zFmt); + zErr = sqlite3_vmprintf(zFmt, ap); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); + va_end(ap); +} + static void fts5ApiCallback( sqlite3_context *context, int argc, @@ -252087,12 +254208,13 @@ static void fts5ApiCallback( iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); - if( pCsr==0 || pCsr->ePlan==0 ){ - char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId); - sqlite3_result_error(context, zErr, -1); - sqlite3_free(zErr); + if( pCsr==0 || (pCsr->ePlan==0 || pCsr->ePlan==FTS5_PLAN_SPECIAL) ){ + fts5ResultError(context, "no such cursor: %lld", iCsrId); }else{ + sqlite3_vtab *pTab = pCsr->base.pVtab; fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); + sqlite3_free(pTab->zErrMsg); + pTab->zErrMsg = 0; } } @@ -252210,8 +254332,8 @@ static int fts5ColumnMethod( ** auxiliary function. */ sqlite3_result_int64(pCtx, pCsr->iCsrId); }else if( iCol==pConfig->nCol+1 ){ - /* The value of the "rank" column. */ + if( pCsr->ePlan==FTS5_PLAN_SOURCE ){ fts5PoslistBlob(pCtx, pCsr); }else if( @@ -252222,20 +254344,32 @@ static int fts5ColumnMethod( fts5ApiInvoke(pCsr->pRank, pCsr, pCtx, pCsr->nRankArg, pCsr->apRankArg); } } - }else if( !fts5IsContentless(pTab) ){ - pConfig->pzErrmsg = &pTab->p.base.zErrMsg; - rc = fts5SeekCursor(pCsr, 1); - if( rc==SQLITE_OK ){ - sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); + }else{ + if( !sqlite3_vtab_nochange(pCtx) && pConfig->eContent!=FTS5_CONTENT_NONE ){ + pConfig->pzErrmsg = &pTab->p.base.zErrMsg; + rc = fts5SeekCursor(pCsr, 1); + if( rc==SQLITE_OK ){ + sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1); + if( pConfig->bLocale + && pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + const char *z = 0; + int n = 0; + rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n); + if( rc==SQLITE_OK ){ + sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT); + } + sqlite3Fts5ClearLocale(pConfig); + }else{ + sqlite3_result_value(pCtx, pVal); + } + } + + pConfig->pzErrmsg = 0; } - pConfig->pzErrmsg = 0; - }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){ - char *zErr = sqlite3_mprintf("cannot UPDATE a subset of " - "columns on fts5 contentless-delete table: %s", pConfig->zName - ); - sqlite3_result_error(pCtx, zErr, -1); - sqlite3_free(zErr); } + return rc; } @@ -252375,47 +254509,210 @@ static int fts5CreateAux( } /* -** Register a new tokenizer. This is the implementation of the -** fts5_api.xCreateTokenizer() method. +** This function is used by xCreateTokenizer_v2() and xCreateTokenizer(). +** It allocates and partially populates a new Fts5TokenizerModule object. +** The new object is already linked into the Fts5Global context before +** returning. +** +** If successful, SQLITE_OK is returned and a pointer to the new +** Fts5TokenizerModule object returned via output parameter (*ppNew). All +** that is required is for the caller to fill in the methods in +** Fts5TokenizerModule.x1 and x2, and to set Fts5TokenizerModule.bV2Native +** as appropriate. +** +** If an error occurs, an SQLite error code is returned and the final value +** of (*ppNew) undefined. */ -static int fts5CreateTokenizer( - fts5_api *pApi, /* Global context (one per db handle) */ +static int fts5NewTokenizerModule( + Fts5Global *pGlobal, /* Global context (one per db handle) */ const char *zName, /* Name of new function */ void *pUserData, /* User data for aux. function */ - fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ - void(*xDestroy)(void*) /* Destructor for pUserData */ + void(*xDestroy)(void*), /* Destructor for pUserData */ + Fts5TokenizerModule **ppNew ){ - Fts5Global *pGlobal = (Fts5Global*)pApi; - Fts5TokenizerModule *pNew; - sqlite3_int64 nName; /* Size of zName and its \0 terminator */ - sqlite3_int64 nByte; /* Bytes of space to allocate */ int rc = SQLITE_OK; + Fts5TokenizerModule *pNew; + sqlite3_int64 nName; /* Size of zName and its \0 terminator */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ nName = strlen(zName) + 1; nByte = sizeof(Fts5TokenizerModule) + nName; - pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte); + *ppNew = pNew = (Fts5TokenizerModule*)sqlite3Fts5MallocZero(&rc, nByte); if( pNew ){ - memset(pNew, 0, (size_t)nByte); pNew->zName = (char*)&pNew[1]; memcpy(pNew->zName, zName, nName); pNew->pUserData = pUserData; - pNew->x = *pTokenizer; pNew->xDestroy = xDestroy; pNew->pNext = pGlobal->pTok; pGlobal->pTok = pNew; if( pNew->pNext==0 ){ pGlobal->pDfltTok = pNew; } + } + + return rc; +} + +/* +** An instance of this type is used as the Fts5Tokenizer object for +** wrapper tokenizers - those that provide access to a v1 tokenizer via +** the fts5_tokenizer_v2 API, and those that provide access to a v2 tokenizer +** via the fts5_tokenizer API. +*/ +typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer; +struct Fts5VtoVTokenizer { + int bV2Native; /* True if v2 native tokenizer */ + fts5_tokenizer x1; /* Tokenizer functions */ + fts5_tokenizer_v2 x2; /* V2 tokenizer functions */ + Fts5Tokenizer *pReal; +}; + +/* +** Create a wrapper tokenizer. The context argument pCtx points to the +** Fts5TokenizerModule object. +*/ +static int fts5VtoVCreate( + void *pCtx, + const char **azArg, + int nArg, + Fts5Tokenizer **ppOut +){ + Fts5TokenizerModule *pMod = (Fts5TokenizerModule*)pCtx; + Fts5VtoVTokenizer *pNew = 0; + int rc = SQLITE_OK; + + pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); + if( rc==SQLITE_OK ){ + pNew->x1 = pMod->x1; + pNew->x2 = pMod->x2; + pNew->bV2Native = pMod->bV2Native; + if( pMod->bV2Native ){ + rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); + }else{ + rc = pMod->x1.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal); + } + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew); + pNew = 0; + } + } + + *ppOut = (Fts5Tokenizer*)pNew; + return rc; +} + +/* +** Delete an Fts5VtoVTokenizer wrapper tokenizer. +*/ +static void fts5VtoVDelete(Fts5Tokenizer *pTok){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + if( p ){ + if( p->bV2Native ){ + p->x2.xDelete(p->pReal); + }else{ + p->x1.xDelete(p->pReal); + } + sqlite3_free(p); + } +} + + +/* +** xTokenizer method for a wrapper tokenizer that offers the v1 interface +** (no support for locales). +*/ +static int fts5V1toV2Tokenize( + Fts5Tokenizer *pTok, + void *pCtx, int flags, + const char *pText, int nText, + int (*xToken)(void*, int, const char*, int, int, int) +){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + assert( p->bV2Native ); + return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken); +} + +/* +** xTokenizer method for a wrapper tokenizer that offers the v2 interface +** (with locale support). +*/ +static int fts5V2toV1Tokenize( + Fts5Tokenizer *pTok, + void *pCtx, int flags, + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)(void*, int, const char*, int, int, int) +){ + Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok; + assert( p->bV2Native==0 ); + UNUSED_PARAM2(pLocale,nLocale); + return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken); +} + +/* +** Register a new tokenizer. This is the implementation of the +** fts5_api.xCreateTokenizer_v2() method. +*/ +static int fts5CreateTokenizer_v2( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of new function */ + void *pUserData, /* User data for aux. function */ + fts5_tokenizer_v2 *pTokenizer, /* Tokenizer implementation */ + void(*xDestroy)(void*) /* Destructor for pUserData */ +){ + Fts5Global *pGlobal = (Fts5Global*)pApi; + int rc = SQLITE_OK; + + if( pTokenizer->iVersion>2 ){ + rc = SQLITE_ERROR; }else{ - rc = SQLITE_NOMEM; + Fts5TokenizerModule *pNew = 0; + rc = fts5NewTokenizerModule(pGlobal, zName, pUserData, xDestroy, &pNew); + if( pNew ){ + pNew->x2 = *pTokenizer; + pNew->bV2Native = 1; + pNew->x1.xCreate = fts5VtoVCreate; + pNew->x1.xTokenize = fts5V1toV2Tokenize; + pNew->x1.xDelete = fts5VtoVDelete; + } } return rc; } +/* +** The fts5_api.xCreateTokenizer() method. +*/ +static int fts5CreateTokenizer( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of new function */ + void *pUserData, /* User data for aux. function */ + fts5_tokenizer *pTokenizer, /* Tokenizer implementation */ + void(*xDestroy)(void*) /* Destructor for pUserData */ +){ + Fts5TokenizerModule *pNew = 0; + int rc = SQLITE_OK; + + rc = fts5NewTokenizerModule( + (Fts5Global*)pApi, zName, pUserData, xDestroy, &pNew + ); + if( pNew ){ + pNew->x1 = *pTokenizer; + pNew->x2.xCreate = fts5VtoVCreate; + pNew->x2.xTokenize = fts5V2toV1Tokenize; + pNew->x2.xDelete = fts5VtoVDelete; + } + return rc; +} + +/* +** Search the global context passed as the first argument for a tokenizer +** module named zName. If found, return a pointer to the Fts5TokenizerModule +** object. Otherwise, return NULL. +*/ static Fts5TokenizerModule *fts5LocateTokenizer( - Fts5Global *pGlobal, - const char *zName + Fts5Global *pGlobal, /* Global (one per db handle) object */ + const char *zName /* Name of tokenizer module to find */ ){ Fts5TokenizerModule *pMod = 0; @@ -252430,6 +254727,36 @@ static Fts5TokenizerModule *fts5LocateTokenizer( return pMod; } +/* +** Find a tokenizer. This is the implementation of the +** fts5_api.xFindTokenizer_v2() method. +*/ +static int fts5FindTokenizer_v2( + fts5_api *pApi, /* Global context (one per db handle) */ + const char *zName, /* Name of tokenizer */ + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer /* Populate this object */ +){ + int rc = SQLITE_OK; + Fts5TokenizerModule *pMod; + + pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); + if( pMod ){ + if( pMod->bV2Native ){ + *ppUserData = pMod->pUserData; + }else{ + *ppUserData = (void*)pMod; + } + *ppTokenizer = &pMod->x2; + }else{ + *ppTokenizer = 0; + *ppUserData = 0; + rc = SQLITE_ERROR; + } + + return rc; +} + /* ** Find a tokenizer. This is the implementation of the ** fts5_api.xFindTokenizer() method. @@ -252445,55 +254772,75 @@ static int fts5FindTokenizer( pMod = fts5LocateTokenizer((Fts5Global*)pApi, zName); if( pMod ){ - *pTokenizer = pMod->x; - *ppUserData = pMod->pUserData; + if( pMod->bV2Native==0 ){ + *ppUserData = pMod->pUserData; + }else{ + *ppUserData = (void*)pMod; + } + *pTokenizer = pMod->x1; }else{ - memset(pTokenizer, 0, sizeof(fts5_tokenizer)); + memset(pTokenizer, 0, sizeof(*pTokenizer)); + *ppUserData = 0; rc = SQLITE_ERROR; } return rc; } -static int sqlite3Fts5GetTokenizer( - Fts5Global *pGlobal, - const char **azArg, - int nArg, - Fts5Config *pConfig, - char **pzErr -){ - Fts5TokenizerModule *pMod; +/* +** Attempt to instantiate the tokenizer. +*/ +static int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){ + const char **azArg = pConfig->t.azArg; + const int nArg = pConfig->t.nArg; + Fts5TokenizerModule *pMod = 0; int rc = SQLITE_OK; - pMod = fts5LocateTokenizer(pGlobal, nArg==0 ? 0 : azArg[0]); + pMod = fts5LocateTokenizer(pConfig->pGlobal, nArg==0 ? 0 : azArg[0]); if( pMod==0 ){ assert( nArg>0 ); rc = SQLITE_ERROR; - if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); + sqlite3Fts5ConfigErrmsg(pConfig, "no such tokenizer: %s", azArg[0]); }else{ - rc = pMod->x.xCreate( - pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok + int (*xCreate)(void*, const char**, int, Fts5Tokenizer**) = 0; + if( pMod->bV2Native ){ + xCreate = pMod->x2.xCreate; + pConfig->t.pApi2 = &pMod->x2; + }else{ + pConfig->t.pApi1 = &pMod->x1; + xCreate = pMod->x1.xCreate; + } + + rc = xCreate(pMod->pUserData, + (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok ); - pConfig->pTokApi = &pMod->x; + if( rc!=SQLITE_OK ){ - if( pzErr && rc!=SQLITE_NOMEM ){ - *pzErr = sqlite3_mprintf("error in tokenizer constructor"); + if( rc!=SQLITE_NOMEM ){ + sqlite3Fts5ConfigErrmsg(pConfig, "error in tokenizer constructor"); } - }else{ - pConfig->ePattern = sqlite3Fts5TokenizerPattern( - pMod->x.xCreate, pConfig->pTok + }else if( pMod->bV2Native==0 ){ + pConfig->t.ePattern = sqlite3Fts5TokenizerPattern( + pMod->x1.xCreate, pConfig->t.pTok ); } } if( rc!=SQLITE_OK ){ - pConfig->pTokApi = 0; - pConfig->pTok = 0; + pConfig->t.pApi1 = 0; + pConfig->t.pApi2 = 0; + pConfig->t.pTok = 0; } return rc; } + +/* +** xDestroy callback passed to sqlite3_create_module(). This is invoked +** when the db handle is being closed. Free memory associated with +** tokenizers and aux functions registered with this db handle. +*/ static void fts5ModuleDestroy(void *pCtx){ Fts5TokenizerModule *pTok, *pNextTok; Fts5Auxiliary *pAux, *pNextAux; @@ -252514,6 +254861,10 @@ static void fts5ModuleDestroy(void *pCtx){ sqlite3_free(pGlobal); } +/* +** Implementation of the fts5() function used by clients to obtain the +** API pointer. +*/ static void fts5Fts5Func( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ @@ -252537,7 +254888,68 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e", -1, SQLITE_TRANSIENT); +} + +/* +** Implementation of fts5_locale(LOCALE, TEXT) function. +** +** If parameter LOCALE is NULL, or a zero-length string, then a copy of +** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as +** text, and the value returned is a blob consisting of: +** +** * The 4 bytes 0x00, 0xE0, 0xB2, 0xEb (FTS5_LOCALE_HEADER). +** * The LOCALE, as utf-8 text, followed by +** * 0x00, followed by +** * The TEXT, as utf-8 text. +** +** There is no final nul-terminator following the TEXT value. +*/ +static void fts5LocaleFunc( + sqlite3_context *pCtx, /* Function call context */ + int nArg, /* Number of args */ + sqlite3_value **apArg /* Function arguments */ +){ + const char *zLocale = 0; + int nLocale = 0; + const char *zText = 0; + int nText = 0; + + assert( nArg==2 ); + UNUSED_PARAM(nArg); + + zLocale = (const char*)sqlite3_value_text(apArg[0]); + nLocale = sqlite3_value_bytes(apArg[0]); + + zText = (const char*)sqlite3_value_text(apArg[1]); + nText = sqlite3_value_bytes(apArg[1]); + + if( zLocale==0 || zLocale[0]=='\0' ){ + sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT); + }else{ + Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx); + u8 *pBlob = 0; + u8 *pCsr = 0; + int nBlob = 0; + + nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText; + pBlob = (u8*)sqlite3_malloc(nBlob); + if( pBlob==0 ){ + sqlite3_result_error_nomem(pCtx); + return; + } + + pCsr = pBlob; + memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE); + pCsr += FTS5_LOCALE_HDR_SIZE; + memcpy(pCsr, zLocale, nLocale); + pCsr += nLocale; + (*pCsr++) = 0x00; + if( zText ) memcpy(pCsr, zText, nText); + assert( &pCsr[nText]==&pBlob[nBlob] ); + + sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free); + } } /* @@ -252632,10 +255044,22 @@ static int fts5Init(sqlite3 *db){ void *p = (void*)pGlobal; memset(pGlobal, 0, sizeof(Fts5Global)); pGlobal->db = db; - pGlobal->api.iVersion = 2; + pGlobal->api.iVersion = 3; pGlobal->api.xCreateFunction = fts5CreateAux; pGlobal->api.xCreateTokenizer = fts5CreateTokenizer; pGlobal->api.xFindTokenizer = fts5FindTokenizer; + pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2; + pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2; + + /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector. + ** The constants below were generated randomly. */ + sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr); + pGlobal->aLocaleHdr[0] ^= 0xF924976D; + pGlobal->aLocaleHdr[1] ^= 0x16596E13; + pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA; + pGlobal->aLocaleHdr[3] ^= 0x9B03A67F; + assert( sizeof(pGlobal->aLocaleHdr)==16 ); + rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db); if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db); @@ -252654,6 +255078,13 @@ static int fts5Init(sqlite3 *db){ p, fts5SourceIdFunc, 0, 0 ); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function( + db, "fts5_locale", 2, + SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE, + p, fts5LocaleFunc, 0, 0 + ); + } } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file @@ -252728,13 +255159,40 @@ SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){ /* #include "fts5Int.h" */ +/* +** pSavedRow: +** SQL statement FTS5_STMT_LOOKUP2 is a copy of FTS5_STMT_LOOKUP, it +** does a by-rowid lookup to retrieve a single row from the %_content +** table or equivalent external-content table/view. +** +** However, FTS5_STMT_LOOKUP2 is only used when retrieving the original +** values for a row being UPDATEd. In that case, the SQL statement is +** not reset and pSavedRow is set to point at it. This is so that the +** insert operation that follows the delete may access the original +** row values for any new values for which sqlite3_value_nochange() returns +** true. i.e. if the user executes: +** +** CREATE VIRTUAL TABLE ft USING fts5(a, b, c, locale=1); +** ... +** UPDATE fts SET a=?, b=? WHERE rowid=?; +** +** then the value passed to the xUpdate() method of this table as the +** new.c value is an sqlite3_value_nochange() value. So in this case it +** must be read from the saved row stored in Fts5Storage.pSavedRow. +** +** This is necessary - using sqlite3_value_nochange() instead of just having +** SQLite pass the original value back via xUpdate() - so as not to discard +** any locale information associated with such values. +** +*/ struct Fts5Storage { Fts5Config *pConfig; Fts5Index *pIndex; int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ i64 nTotalRow; /* Total number of rows in FTS table */ i64 *aTotalSize; /* Total sizes of each column */ - sqlite3_stmt *aStmt[11]; + sqlite3_stmt *pSavedRow; + sqlite3_stmt *aStmt[12]; }; @@ -252748,14 +255206,15 @@ struct Fts5Storage { # error "FTS5_STMT_LOOKUP mismatch" #endif -#define FTS5_STMT_INSERT_CONTENT 3 -#define FTS5_STMT_REPLACE_CONTENT 4 -#define FTS5_STMT_DELETE_CONTENT 5 -#define FTS5_STMT_REPLACE_DOCSIZE 6 -#define FTS5_STMT_DELETE_DOCSIZE 7 -#define FTS5_STMT_LOOKUP_DOCSIZE 8 -#define FTS5_STMT_REPLACE_CONFIG 9 -#define FTS5_STMT_SCAN 10 +#define FTS5_STMT_LOOKUP2 3 +#define FTS5_STMT_INSERT_CONTENT 4 +#define FTS5_STMT_REPLACE_CONTENT 5 +#define FTS5_STMT_DELETE_CONTENT 6 +#define FTS5_STMT_REPLACE_DOCSIZE 7 +#define FTS5_STMT_DELETE_DOCSIZE 8 +#define FTS5_STMT_LOOKUP_DOCSIZE 9 +#define FTS5_STMT_REPLACE_CONFIG 10 +#define FTS5_STMT_SCAN 11 /* ** Prepare the two insert statements - Fts5Storage.pInsertContent and @@ -252785,6 +255244,7 @@ static int fts5StorageGetStmt( "SELECT %s FROM %s T WHERE T.%Q >= ? AND T.%Q <= ? ORDER BY T.%Q ASC", "SELECT %s FROM %s T WHERE T.%Q <= ? AND T.%Q >= ? ORDER BY T.%Q DESC", "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP */ + "SELECT %s FROM %s T WHERE T.%Q=?", /* LOOKUP2 */ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ @@ -252800,6 +255260,8 @@ static int fts5StorageGetStmt( Fts5Config *pC = p->pConfig; char *zSql = 0; + assert( ArraySize(azStmt)==ArraySize(p->aStmt) ); + switch( eStmt ){ case FTS5_STMT_SCAN: zSql = sqlite3_mprintf(azStmt[eStmt], @@ -252816,6 +255278,7 @@ static int fts5StorageGetStmt( break; case FTS5_STMT_LOOKUP: + case FTS5_STMT_LOOKUP2: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid ); @@ -252823,20 +255286,35 @@ static int fts5StorageGetStmt( case FTS5_STMT_INSERT_CONTENT: case FTS5_STMT_REPLACE_CONTENT: { - int nCol = pC->nCol + 1; - char *zBind; + char *zBind = 0; int i; - zBind = sqlite3_malloc64(1 + nCol*2); - if( zBind ){ - for(i=0; ieContent==FTS5_CONTENT_NORMAL + || pC->eContent==FTS5_CONTENT_UNINDEXED + ); + + /* Add bindings for the "c*" columns - those that store the actual + ** table content. If eContent==NORMAL, then there is one binding + ** for each column. Or, if eContent==UNINDEXED, then there are only + ** bindings for the UNINDEXED columns. */ + for(i=0; rc==SQLITE_OK && i<(pC->nCol+1); i++){ + if( !i || pC->eContent==FTS5_CONTENT_NORMAL || pC->abUnindexed[i-1] ){ + zBind = sqlite3Fts5Mprintf(&rc, "%z%s?%d", zBind, zBind?",":"",i+1); } - zBind[i*2-1] = '\0'; - zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind); - sqlite3_free(zBind); } + + /* Add bindings for any "l*" columns. Only non-UNINDEXED columns + ** require these. */ + if( pC->bLocale && pC->eContent==FTS5_CONTENT_NORMAL ){ + for(i=0; rc==SQLITE_OK && inCol; i++){ + if( pC->abUnindexed[i]==0 ){ + zBind = sqlite3Fts5Mprintf(&rc, "%z,?%d", zBind, pC->nCol+i+2); + } + } + } + + zSql = sqlite3Fts5Mprintf(&rc, azStmt[eStmt], pC->zDb, pC->zName,zBind); + sqlite3_free(zBind); break; } @@ -252862,7 +255340,7 @@ static int fts5StorageGetStmt( rc = SQLITE_NOMEM; }else{ int f = SQLITE_PREPARE_PERSISTENT; - if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; + if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB; p->pConfig->bLock++; rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); p->pConfig->bLock--; @@ -253022,9 +255500,11 @@ static int sqlite3Fts5StorageOpen( p->pIndex = pIndex; if( bCreate ){ - if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ int nDefn = 32 + pConfig->nCol*10; - char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10); + char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ @@ -253033,8 +255513,20 @@ static int sqlite3Fts5StorageOpen( sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); iOff = (int)strlen(zDefn); for(i=0; inCol; i++){ - sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); - iOff += (int)strlen(&zDefn[iOff]); + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->abUnindexed[i] + ){ + sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); + iOff += (int)strlen(&zDefn[iOff]); + } + } + if( pConfig->bLocale ){ + for(i=0; inCol; i++){ + if( pConfig->abUnindexed[i]==0 ){ + sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i); + iOff += (int)strlen(&zDefn[iOff]); + } + } } rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); } @@ -253111,15 +255603,49 @@ static int fts5StorageInsertCallback( return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } +/* +** This function is used as part of an UPDATE statement that modifies the +** rowid of a row. In that case, this function is called first to set +** Fts5Storage.pSavedRow to point to a statement that may be used to +** access the original values of the row being deleted - iDel. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** It is not considered an error if row iDel does not exist. In this case +** pSavedRow is not set and SQLITE_OK returned. +*/ +static int sqlite3Fts5StorageFindDeleteRow(Fts5Storage *p, i64 iDel){ + int rc = SQLITE_OK; + sqlite3_stmt *pSeek = 0; + + assert( p->pSavedRow==0 ); + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+1, &pSeek, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pSeek, 1, iDel); + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + rc = sqlite3_reset(pSeek); + }else{ + p->pSavedRow = pSeek; + } + } + + return rc; +} + /* ** If a row with rowid iDel is present in the %_content table, add the ** delete-markers to the FTS index necessary to delete it. Do not actually ** remove the %_content row at this time though. +** +** If parameter bSaveRow is true, then Fts5Storage.pSavedRow is left +** pointing to a statement (FTS5_STMT_LOOKUP2) that may be used to access +** the original values of the row being deleted. This is used by UPDATE +** statements. */ static int fts5StorageDeleteFromIndex( Fts5Storage *p, i64 iDel, - sqlite3_value **apVal + sqlite3_value **apVal, + int bSaveRow /* True to set pSavedRow */ ){ Fts5Config *pConfig = p->pConfig; sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ @@ -253128,12 +255654,21 @@ static int fts5StorageDeleteFromIndex( int iCol; Fts5InsertCtx ctx; + assert( bSaveRow==0 || apVal==0 ); + assert( bSaveRow==0 || bSaveRow==1 ); + assert( FTS5_STMT_LOOKUP2==FTS5_STMT_LOOKUP+1 ); + if( apVal==0 ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_int64(pSeek, 1, iDel); - if( sqlite3_step(pSeek)!=SQLITE_ROW ){ - return sqlite3_reset(pSeek); + if( p->pSavedRow && bSaveRow ){ + pSeek = p->pSavedRow; + p->pSavedRow = 0; + }else{ + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP+bSaveRow, &pSeek, 0); + if( rc!=SQLITE_OK ) return rc; + sqlite3_bind_int64(pSeek, 1, iDel); + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + return sqlite3_reset(pSeek); + } } } @@ -253141,26 +255676,42 @@ static int fts5StorageDeleteFromIndex( ctx.iCol = -1; for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ - const char *zText; - int nText; + sqlite3_value *pVal = 0; + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + assert( pSeek==0 || apVal==0 ); assert( pSeek!=0 || apVal!=0 ); if( pSeek ){ - zText = (const char*)sqlite3_column_text(pSeek, iCol); - nText = sqlite3_column_bytes(pSeek, iCol); - }else if( ALWAYS(apVal) ){ - zText = (const char*)sqlite3_value_text(apVal[iCol-1]); - nText = sqlite3_value_bytes(apVal[iCol-1]); + pVal = sqlite3_column_value(pSeek, iCol); }else{ - continue; + pVal = apVal[iCol-1]; } - ctx.szCol = 0; - rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - zText, nText, (void*)&ctx, fts5StorageInsertCallback - ); - p->aTotalSize[iCol-1] -= (i64)ctx.szCol; - if( p->aTotalSize[iCol-1]<0 ){ - rc = FTS5_CORRUPT; + + if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale && pSeek ){ + pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol); + nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + ctx.szCol = 0; + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, + pText, nText, (void*)&ctx, fts5StorageInsertCallback + ); + p->aTotalSize[iCol-1] -= (i64)ctx.szCol; + if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){ + rc = FTS5_CORRUPT; + } + sqlite3Fts5ClearLocale(pConfig); } } } @@ -253170,11 +255721,29 @@ static int fts5StorageDeleteFromIndex( p->nTotalRow--; } - rc2 = sqlite3_reset(pSeek); - if( rc==SQLITE_OK ) rc = rc2; + if( rc==SQLITE_OK && bSaveRow ){ + assert( p->pSavedRow==0 ); + p->pSavedRow = pSeek; + }else{ + rc2 = sqlite3_reset(pSeek); + if( rc==SQLITE_OK ) rc = rc2; + } return rc; } +/* +** Reset any saved statement pSavedRow. Zero pSavedRow as well. This +** should be called by the xUpdate() method of the fts5 table before +** returning from any operation that may have set Fts5Storage.pSavedRow. +*/ +static void sqlite3Fts5StorageReleaseDeleteRow(Fts5Storage *pStorage){ + assert( pStorage->pSavedRow==0 + || pStorage->pSavedRow==pStorage->aStmt[FTS5_STMT_LOOKUP2] + ); + sqlite3_reset(pStorage->pSavedRow); + pStorage->pSavedRow = 0; +} + /* ** This function is called to process a DELETE on a contentless_delete=1 ** table. It adds the tombstone required to delete the entry with rowid @@ -253187,7 +255756,9 @@ static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ int rc = SQLITE_OK; assert( p->pConfig->bContentlessDelete ); - assert( p->pConfig->eContent==FTS5_CONTENT_NONE ); + assert( p->pConfig->eContent==FTS5_CONTENT_NONE + || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED + ); /* Look up the origin of the document in the %_docsize table. Store ** this in stack variable iOrigin. */ @@ -253231,12 +255802,12 @@ static int fts5StorageInsertDocsize( rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); sqlite3_bind_int64(pReplace, 3, iOrigin); } - if( rc==SQLITE_OK ){ - sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); - sqlite3_bind_null(pReplace, 2); - } + } + if( rc==SQLITE_OK ){ + sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } } return rc; @@ -253290,7 +255861,12 @@ static int fts5StorageSaveTotals(Fts5Storage *p){ /* ** Remove a row from the FTS table. */ -static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){ +static int sqlite3Fts5StorageDelete( + Fts5Storage *p, /* Storage object */ + i64 iDel, /* Rowid to delete from table */ + sqlite3_value **apVal, /* Optional - values to remove from index */ + int bSaveRow /* If true, set pSavedRow for deleted row */ +){ Fts5Config *pConfig = p->pConfig; int rc; sqlite3_stmt *pDel = 0; @@ -253306,8 +255882,14 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap if( rc==SQLITE_OK ){ if( p->pConfig->bContentlessDelete ){ rc = fts5StorageContentlessDelete(p, iDel); + if( rc==SQLITE_OK + && bSaveRow + && p->pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ + rc = sqlite3Fts5StorageFindDeleteRow(p, iDel); + } }else{ - rc = fts5StorageDeleteFromIndex(p, iDel, apVal); + rc = fts5StorageDeleteFromIndex(p, iDel, apVal, bSaveRow); } } @@ -253322,7 +255904,9 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap } /* Delete the %_content record */ - if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL + || pConfig->eContent==FTS5_CONTENT_UNINDEXED + ){ if( rc==SQLITE_OK ){ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); } @@ -253354,8 +255938,13 @@ static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){ ); if( rc==SQLITE_OK && pConfig->bColumnsize ){ rc = fts5ExecPrintf(pConfig->db, 0, - "DELETE FROM %Q.'%q_docsize';", - pConfig->zDb, pConfig->zName + "DELETE FROM %Q.'%q_docsize';", pConfig->zDb, pConfig->zName + ); + } + + if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_UNINDEXED ){ + rc = fts5ExecPrintf(pConfig->db, 0, + "DELETE FROM %Q.'%q_content';", pConfig->zDb, pConfig->zName ); } @@ -253396,14 +255985,36 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1); - int nText = sqlite3_column_bytes(pScan, ctx.iCol+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageInsertCallback - ); + int nText = 0; /* Size of pText in bytes */ + const char *pText = 0; /* Pointer to buffer containing text value */ + int nLoc = 0; /* Size of pLoc in bytes */ + const char *pLoc = 0; /* Pointer to buffer containing text value */ + + sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1); + if( pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + if( pConfig->bLocale ){ + int iCol = ctx.iCol + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(pScan, iCol); + nLoc = sqlite3_column_bytes(pScan, iCol); + } + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + pText, nText, + (void*)&ctx, + fts5StorageInsertCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; @@ -253469,6 +256080,7 @@ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){ */ static int sqlite3Fts5StorageContentInsert( Fts5Storage *p, + int bReplace, /* True to use REPLACE instead of INSERT */ sqlite3_value **apVal, i64 *piRowid ){ @@ -253476,7 +256088,9 @@ static int sqlite3Fts5StorageContentInsert( int rc = SQLITE_OK; /* Insert the new row into the %_content table. */ - if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent!=FTS5_CONTENT_NORMAL + && pConfig->eContent!=FTS5_CONTENT_UNINDEXED + ){ if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ *piRowid = sqlite3_value_int64(apVal[1]); }else{ @@ -253485,9 +256099,52 @@ static int sqlite3Fts5StorageContentInsert( }else{ sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ - rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); - for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ - rc = sqlite3_bind_value(pInsert, i, apVal[i]); + + assert( FTS5_STMT_INSERT_CONTENT+1==FTS5_STMT_REPLACE_CONTENT ); + assert( bReplace==0 || bReplace==1 ); + rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT+bReplace, &pInsert, 0); + if( pInsert ) sqlite3_clear_bindings(pInsert); + + /* Bind the rowid value */ + sqlite3_bind_value(pInsert, 1, apVal[1]); + + /* Loop through values for user-defined columns. i=2 is the leftmost + ** user-defined column. As is column 1 of pSavedRow. */ + for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ + int bUnindexed = pConfig->abUnindexed[i-2]; + if( pConfig->eContent==FTS5_CONTENT_NORMAL || bUnindexed ){ + sqlite3_value *pVal = apVal[i]; + + if( sqlite3_value_nochange(pVal) && p->pSavedRow ){ + /* This is an UPDATE statement, and user-defined column (i-2) was not + ** modified. Retrieve the value from Fts5Storage.pSavedRow. */ + pVal = sqlite3_column_value(p->pSavedRow, i-1); + if( pConfig->bLocale && bUnindexed==0 ){ + sqlite3_bind_value(pInsert, pConfig->nCol + i, + sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1) + ); + } + }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + const char *pText = 0; + const char *pLoc = 0; + int nText = 0; + int nLoc = 0; + assert( pConfig->bLocale ); + + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + if( rc==SQLITE_OK ){ + sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT); + if( bUnindexed==0 ){ + int iLoc = pConfig->nCol + i; + sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT); + } + } + + continue; + } + + rc = sqlite3_bind_value(pInsert, i, pVal); + } } if( rc==SQLITE_OK ){ sqlite3_step(pInsert); @@ -253522,14 +256179,38 @@ static int sqlite3Fts5StorageIndexInsert( for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]); - int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageInsertCallback - ); + int nText = 0; /* Size of pText in bytes */ + const char *pText = 0; /* Pointer to buffer containing text value */ + int nLoc = 0; /* Size of pText in bytes */ + const char *pLoc = 0; /* Pointer to buffer containing text value */ + + sqlite3_value *pVal = apVal[ctx.iCol+2]; + if( p->pSavedRow && sqlite3_value_nochange(pVal) ){ + pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1); + if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ + int iCol = ctx.iCol + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol); + nLoc = sqlite3_column_bytes(p->pSavedRow, iCol); + } + }else{ + pVal = apVal[ctx.iCol+2]; + } + + if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){ + rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc); + }else{ + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx, + fts5StorageInsertCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } } sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; @@ -253693,29 +256374,61 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } for(i=0; rc==SQLITE_OK && inCol; i++){ - if( pConfig->abUnindexed[i] ) continue; - ctx.iCol = i; - ctx.szCol = 0; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - rc = sqlite3Fts5TermsetNew(&ctx.pTermset); - } - if( rc==SQLITE_OK ){ - const char *zText = (const char*)sqlite3_column_text(pScan, i+1); - int nText = sqlite3_column_bytes(pScan, i+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageIntegrityCallback - ); - } - if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ - rc = FTS5_CORRUPT; - } - aTotalSize[i] += ctx.szCol; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - sqlite3Fts5TermsetFree(ctx.pTermset); - ctx.pTermset = 0; + if( pConfig->abUnindexed[i]==0 ){ + const char *pText = 0; + int nText = 0; + const char *pLoc = 0; + int nLoc = 0; + sqlite3_value *pVal = sqlite3_column_value(pScan, i+1); + + if( pConfig->eContent==FTS5_CONTENT_EXTERNAL + && sqlite3Fts5IsLocaleValue(pConfig, pVal) + ){ + rc = sqlite3Fts5DecodeLocaleValue( + pVal, &pText, &nText, &pLoc, &nLoc + ); + }else{ + if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){ + int iCol = i + 1 + pConfig->nCol; + pLoc = (const char*)sqlite3_column_text(pScan, iCol); + nLoc = sqlite3_column_bytes(pScan, iCol); + } + pText = (const char*)sqlite3_value_text(pVal); + nText = sqlite3_value_bytes(pVal); + } + + ctx.iCol = i; + ctx.szCol = 0; + + if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); + } + + if( rc==SQLITE_OK ){ + sqlite3Fts5SetLocale(pConfig, pLoc, nLoc); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + pText, nText, + (void*)&ctx, + fts5StorageIntegrityCallback + ); + sqlite3Fts5ClearLocale(pConfig); + } + + /* If this is not a columnsize=0 database, check that the number + ** of tokens in the value matches the aColSize[] value read from + ** the %_docsize table. */ + if( rc==SQLITE_OK + && pConfig->bColumnsize + && ctx.szCol!=aColSize[i] + ){ + rc = FTS5_CORRUPT; + } + aTotalSize[i] += ctx.szCol; + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + sqlite3Fts5TermsetFree(ctx.pTermset); + ctx.pTermset = 0; + } } } sqlite3Fts5TermsetFree(ctx.pTermset); @@ -254022,7 +256735,7 @@ static int fts5AsciiCreate( int i; memset(p, 0, sizeof(AsciiTokenizer)); memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); - for(i=0; rc==SQLITE_OK && i=0xc0 ){ \ c = sqlite3Utf8Trans1[c-0xc0]; \ - while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ + while( zInpTokenizer ){ - p->tokenizer.xDelete(p->pTokenizer); + p->tokenizer_v2.xDelete(p->pTokenizer); } sqlite3_free(p); } @@ -254530,6 +257240,7 @@ static int fts5PorterCreate( PorterTokenizer *pRet; void *pUserdata = 0; const char *zBase = "unicode61"; + fts5_tokenizer_v2 *pV2 = 0; if( nArg>0 ){ zBase = azArg[0]; @@ -254538,14 +257249,15 @@ static int fts5PorterCreate( pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); if( pRet ){ memset(pRet, 0, sizeof(PorterTokenizer)); - rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer); + rc = pApi->xFindTokenizer_v2(pApi, zBase, &pUserdata, &pV2); }else{ rc = SQLITE_NOMEM; } if( rc==SQLITE_OK ){ int nArg2 = (nArg>0 ? nArg-1 : 0); - const char **azArg2 = (nArg2 ? &azArg[1] : 0); - rc = pRet->tokenizer.xCreate(pUserdata, azArg2, nArg2, &pRet->pTokenizer); + const char **az2 = (nArg2 ? &azArg[1] : 0); + memcpy(&pRet->tokenizer_v2, pV2, sizeof(fts5_tokenizer_v2)); + rc = pRet->tokenizer_v2.xCreate(pUserdata, az2, nArg2, &pRet->pTokenizer); } if( rc!=SQLITE_OK ){ @@ -255196,6 +257908,7 @@ static int fts5PorterTokenize( void *pCtx, int flags, const char *pText, int nText, + const char *pLoc, int nLoc, int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd) ){ PorterTokenizer *p = (PorterTokenizer*)pTokenizer; @@ -255203,8 +257916,8 @@ static int fts5PorterTokenize( sCtx.xToken = xToken; sCtx.pCtx = pCtx; sCtx.aBuf = p->aBuf; - return p->tokenizer.xTokenize( - p->pTokenizer, (void*)&sCtx, flags, pText, nText, fts5PorterCb + return p->tokenizer_v2.xTokenize( + p->pTokenizer, (void*)&sCtx, flags, pText, nText, pLoc, nLoc, fts5PorterCb ); } @@ -255234,41 +257947,46 @@ static int fts5TriCreate( Fts5Tokenizer **ppOut ){ int rc = SQLITE_OK; - TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); + TrigramTokenizer *pNew = 0; UNUSED_PARAM(pUnused); - if( pNew==0 ){ - rc = SQLITE_NOMEM; + if( nArg%2 ){ + rc = SQLITE_ERROR; }else{ int i; - pNew->bFold = 1; - pNew->iFoldParam = 0; - for(i=0; rc==SQLITE_OK && ibFold = 1; + pNew->iFoldParam = 0; + + for(i=0; rc==SQLITE_OK && ibFold = (zArg[0]=='0'); + } + }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ + if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ + rc = SQLITE_ERROR; + }else{ + pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; + } }else{ - pNew->bFold = (zArg[0]=='0'); - } - }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ - if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ rc = SQLITE_ERROR; - }else{ - pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; } - }else{ - rc = SQLITE_ERROR; } - } - if( iiFoldParam!=0 && pNew->bFold==0 ){ - rc = SQLITE_ERROR; - } + if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ + rc = SQLITE_ERROR; + } - if( rc!=SQLITE_OK ){ - fts5TriDelete((Fts5Tokenizer*)pNew); - pNew = 0; + if( rc!=SQLITE_OK ){ + fts5TriDelete((Fts5Tokenizer*)pNew); + pNew = 0; + } } } *ppOut = (Fts5Tokenizer*)pNew; @@ -255373,6 +258091,16 @@ static int sqlite3Fts5TokenizerPattern( return FTS5_PATTERN_NONE; } +/* +** Return true if the tokenizer described by p->azArg[] is the trigram +** tokenizer. This tokenizer needs to be loaded before xBestIndex is +** called for the first time in order to correctly handle LIKE/GLOB. +*/ +static int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){ + return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram")); +} + + /* ** Register all built-in tokenizers with FTS5. */ @@ -255383,7 +258111,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ } aBuiltin[] = { { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, - { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, }; @@ -255398,7 +258125,20 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ 0 ); } - + if( rc==SQLITE_OK ){ + fts5_tokenizer_v2 sPorter = { + 2, + fts5PorterCreate, + fts5PorterDelete, + fts5PorterTokenize + }; + rc = pApi->xCreateTokenizer_v2(pApi, + "porter", + (void*)pApi, + &sPorter, + 0 + ); + } return rc; } @@ -255768,6 +258508,9 @@ static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ default: return 1; } break; + + default: + return 1; } return 0; } @@ -256592,6 +259335,7 @@ struct Fts5VocabCursor { int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ + int colUsed; /* Copy of sqlite3_index_info.colUsed */ /* These are used by 'col' tables only */ int iCol; @@ -256618,9 +259362,11 @@ struct Fts5VocabCursor { /* ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. */ -#define FTS5_VOCAB_TERM_EQ 0x01 -#define FTS5_VOCAB_TERM_GE 0x02 -#define FTS5_VOCAB_TERM_LE 0x04 +#define FTS5_VOCAB_TERM_EQ 0x0100 +#define FTS5_VOCAB_TERM_GE 0x0200 +#define FTS5_VOCAB_TERM_LE 0x0400 + +#define FTS5_VOCAB_COLUSED_MASK 0xFF /* @@ -256797,11 +259543,13 @@ static int fts5VocabBestIndexMethod( int iTermEq = -1; int iTermGe = -1; int iTermLe = -1; - int idxNum = 0; + int idxNum = (int)pInfo->colUsed; int nArg = 0; UNUSED_PARAM(pUnused); + assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed ); + for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; @@ -256893,7 +259641,7 @@ static int fts5VocabOpenMethod( if( rc==SQLITE_OK ){ pVTab->zErrMsg = sqlite3_mprintf( "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl - ); + ); rc = SQLITE_ERROR; } }else{ @@ -257053,9 +259801,19 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ switch( pTab->eType ){ case FTS5_VOCAB_ROW: - if( eDetail==FTS5_DETAIL_FULL ){ - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - pCsr->aCnt[0]++; + /* Do not bother counting the number of instances if the "cnt" + ** column is not being read (according to colUsed). */ + if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){ + while( iPosaCnt[] */ + pCsr->aCnt[0]++; + } } } pCsr->aDoc[0]++; @@ -257153,6 +259911,7 @@ static int fts5VocabFilterMethod( if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; + pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq); diff --git a/deps/sqlite/sqlite3.h b/deps/sqlite/sqlite3.h index f64ca01727829c..eaffd1ec167ad4 100644 --- a/deps/sqlite/sqlite3.h +++ b/deps/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.46.1" -#define SQLITE_VERSION_NUMBER 3046001 -#define SQLITE_SOURCE_ID "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33" +#define SQLITE_VERSION "3.47.0" +#define SQLITE_VERSION_NUMBER 3047000 +#define SQLITE_SOURCE_ID "2024-10-21 16:30:22 03a9703e27c44437c39363d0baf82db4ebc94538a0f28411c85dda156f82636e" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -772,8 +772,8 @@ struct sqlite3_file { ** to xUnlock() is a no-op. ** The xCheckReservedLock() method checks whether any database connection, ** either in this process or in some other process, is holding a RESERVED, -** PENDING, or EXCLUSIVE lock on the file. It returns true -** if such a lock exists and false otherwise. +** PENDING, or EXCLUSIVE lock on the file. It returns, via its output +** pointer parameter, true if such a lock exists and false otherwise. ** ** The xFileControl() method is a generic interface that allows custom ** VFS implementations to directly control an open file using the @@ -3570,8 +3570,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** [[OPEN_EXRESCODE]] ^(
[SQLITE_OPEN_EXRESCODE]
**
The database connection comes up in "extended result code mode". -** In other words, the database behaves has if -** [sqlite3_extended_result_codes(db,1)] where called on the database +** In other words, the database behaves as if +** [sqlite3_extended_result_codes(db,1)] were called on the database ** connection as soon as the connection is created. In addition to setting ** the extended result code mode, this flag also causes [sqlite3_open_v2()] ** to return an extended result code.
@@ -4222,13 +4222,17 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the -** first zero terminator. ^If nByte is positive, then it is the -** number of bytes read from zSql. ^If nByte is zero, then no prepared +** first zero terminator. ^If nByte is positive, then it is the maximum +** number of bytes read from zSql. When nByte is positive, zSql is read +** up to the first zero terminator or until the nByte bytes have been read, +** whichever comes first. ^If nByte is zero, then no prepared ** statement is generated. ** If the caller knows that the supplied string is nul-terminated, then ** there is a small performance advantage to passing an nByte parameter that ** is the number of bytes in the input string including ** the nul-terminator. +** Note that nByte measure the length of the input in bytes, not +** characters, even for the UTF-16 interfaces. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only @@ -5599,7 +5603,7 @@ SQLITE_API int sqlite3_create_window_function( ** This flag instructs SQLite to omit some corner-case optimizations that ** might disrupt the operation of the [sqlite3_value_subtype()] function, ** causing it to return zero rather than the correct subtype(). -** SQL functions that invokes [sqlite3_value_subtype()] should have this +** All SQL functions that invoke [sqlite3_value_subtype()] should have this ** property. If the SQLITE_SUBTYPE property is omitted, then the return ** value from [sqlite3_value_subtype()] might sometimes be zero even though ** a non-zero subtype was specified by the function argument expression. @@ -5615,6 +5619,15 @@ SQLITE_API int sqlite3_create_window_function( ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. +** +** [[SQLITE_SELFORDER1]]
SQLITE_SELFORDER1
+** The SQLITE_SELFORDER1 flag indicates that the function is an aggregate +** that internally orders the values provided to the first argument. The +** ordered-set aggregate SQL notation with a single ORDER BY term can be +** used to invoke this function. If the ordered-set aggregate notation is +** used on a function that lacks this flag, then an error is raised. Note +** that the ordered-set aggregate syntax is only available if SQLite is +** built using the -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES compile-time option. **
** */ @@ -5623,6 +5636,7 @@ SQLITE_API int sqlite3_create_window_function( #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 +#define SQLITE_SELFORDER1 0x002000000 /* ** CAPI3REF: Deprecated Functions @@ -5820,7 +5834,7 @@ SQLITE_API int sqlite3_value_encoding(sqlite3_value*); ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** -** Every [application-defined SQL function] that invoke this interface +** Every [application-defined SQL function] that invokes this interface ** should include the [SQLITE_SUBTYPE] property in the text ** encoding argument when the function is [sqlite3_create_function|registered]. ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() @@ -7427,9 +7441,11 @@ struct sqlite3_module { ** will be returned by the strategy. ** ** The xBestIndex method may optionally populate the idxFlags field with a -** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - -** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite -** assumes that the strategy may visit at most one row. +** mask of SQLITE_INDEX_SCAN_* flags. One such flag is +** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN] +** output to show the idxNum has hex instead of as decimal. Another flag is +** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will +** return at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as @@ -7493,7 +7509,9 @@ struct sqlite3_index_info { ** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ -#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ +#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */ +#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */ + /* in EXPLAIN QUERY PLAN */ /* ** CAPI3REF: Virtual Table Constraint Operator Codes @@ -8330,6 +8348,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ +#define SQLITE_TESTCTRL_GETOPT 16 #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 @@ -8349,7 +8368,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 -#define SQLITE_TESTCTRL_USELONGDOUBLE 34 +#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */ #define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* @@ -9325,6 +9344,16 @@ typedef struct sqlite3_backup sqlite3_backup; ** APIs are not strictly speaking threadsafe. If they are invoked at the ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. +** +** Alternatives To Using The Backup API +** +** Other techniques for safely creating a consistent backup of an SQLite +** database include: +** +**
    +**
  • The [VACUUM INTO] command. +**
  • The [sqlite3_rsync] utility program. +**
*/ SQLITE_API sqlite3_backup *sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ @@ -10524,6 +10553,14 @@ typedef struct sqlite3_snapshot { ** If there is not already a read-transaction open on schema S when ** this function is called, one is opened automatically. ** +** If a read-transaction is opened by this function, then it is guaranteed +** that the returned snapshot object may not be invalidated by a database +** writer or checkpointer until after the read-transaction is closed. This +** is not guaranteed if a read-transaction is already open when this +** function is called. In that case, any subsequent write or checkpoint +** operation on the database may invalidate the returned snapshot handle, +** even while the read-transaction remains open. +** ** The following must be true for this function to succeed. If any of ** the following statements are false when sqlite3_snapshot_get() is ** called, SQLITE_ERROR is returned. The final value of *P is undefined @@ -10832,8 +10869,6 @@ SQLITE_API int sqlite3_deserialize( #if defined(__wasi__) # undef SQLITE_WASI # define SQLITE_WASI 1 -# undef SQLITE_OMIT_WAL -# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */ # ifndef SQLITE_OMIT_LOAD_EXTENSION # define SQLITE_OMIT_LOAD_EXTENSION # endif @@ -13036,6 +13071,10 @@ struct Fts5PhraseIter { ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** ** xPhraseNext() ** See xPhraseFirst above. ** @@ -13102,9 +13141,32 @@ struct Fts5PhraseIter { ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. +** +** xColumnLocale(pFts5, iIdx, pzLocale, pnLocale) +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the locale associated +** with column iCol of the current row. Usually, there is no associated +** locale, and output parameters (*pzLocale) and (*pnLocale) are set +** to NULL and 0, respectively. However, if the fts5_locale() function +** was used to associate a locale with the value when it was inserted +** into the fts5 table, then (*pzLocale) is set to point to a nul-terminated +** buffer containing the name of the locale in utf-8 encoding. (*pnLocale) +** is set to the size in bytes of the buffer, not including the +** nul-terminator. +** +** If successful, SQLITE_OK is returned. Or, if an error occurs, an +** SQLite error code is returned. The final value of the output parameters +** is undefined in this case. +** +** xTokenize_v2: +** Tokenize text using the tokenizer belonging to the FTS5 table. This +** API is the same as the xTokenize() API, except that it allows a tokenizer +** locale to be specified. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 3 */ + int iVersion; /* Currently always set to 4 */ void *(*xUserData)(Fts5Context*); @@ -13146,6 +13208,15 @@ struct Fts5ExtensionApi { const char **ppToken, int *pnToken ); int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); + + /* Below this point are iVersion>=4 only */ + int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xTokenize_v2)(Fts5Context*, + const char *pText, int nText, /* Text to tokenize */ + const char *pLocale, int nLocale, /* Locale to pass to tokenizer */ + void *pCtx, /* Context passed to xToken() */ + int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ + ); }; /* @@ -13166,7 +13237,7 @@ struct Fts5ExtensionApi { ** A tokenizer instance is required to actually tokenize text. ** ** The first argument passed to this function is a copy of the (void*) -** pointer provided by the application when the fts5_tokenizer object +** pointer provided by the application when the fts5_tokenizer_v2 object ** was registered with FTS5 (the third argument to xCreateTokenizer()). ** The second and third arguments are an array of nul-terminated strings ** containing the tokenizer arguments, if any, specified following the @@ -13190,7 +13261,7 @@ struct Fts5ExtensionApi { ** argument passed to this function is a pointer to an Fts5Tokenizer object ** returned by an earlier call to xCreate(). ** -** The second argument indicates the reason that FTS5 is requesting +** The third argument indicates the reason that FTS5 is requesting ** tokenization of the supplied text. This is always one of the following ** four values: ** @@ -13214,6 +13285,13 @@ struct Fts5ExtensionApi { ** on a columnsize=0 database. ** ** +** The sixth and seventh arguments passed to xTokenize() - pLocale and +** nLocale - are a pointer to a buffer containing the locale to use for +** tokenization (e.g. "en_US") and its size in bytes, respectively. The +** pLocale buffer is not nul-terminated. pLocale may be passed NULL (in +** which case nLocale is always 0) to indicate that the tokenizer should +** use its default locale. +** ** For each token in the input string, the supplied callback xToken() must ** be invoked. The first argument to it should be a copy of the pointer ** passed as the second argument to xTokenize(). The third and fourth @@ -13237,6 +13315,30 @@ struct Fts5ExtensionApi { ** may abandon the tokenization and return any error code other than ** SQLITE_OK or SQLITE_DONE. ** +** If the tokenizer is registered using an fts5_tokenizer_v2 object, +** then the xTokenize() method has two additional arguments - pLocale +** and nLocale. These specify the locale that the tokenizer should use +** for the current request. If pLocale and nLocale are both 0, then the +** tokenizer should use its default locale. Otherwise, pLocale points to +** an nLocale byte buffer containing the name of the locale to use as utf-8 +** text. pLocale is not nul-terminated. +** +** FTS5_TOKENIZER +** +** There is also an fts5_tokenizer object. This is an older, deprecated, +** version of fts5_tokenizer_v2. It is similar except that: +** +**
    +**
  • There is no "iVersion" field, and +**
  • The xTokenize() method does not take a locale argument. +**
+** +** Legacy fts5_tokenizer tokenizers must be registered using the +** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2(). +** +** Tokenizer implementations registered using either API may be retrieved +** using both xFindTokenizer() and xFindTokenizer_v2(). +** ** SYNONYM SUPPORT ** ** Custom tokenizers may also support synonyms. Consider a case in which a @@ -13345,6 +13447,33 @@ struct Fts5ExtensionApi { ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer_v2 fts5_tokenizer_v2; +struct fts5_tokenizer_v2 { + int iVersion; /* Currently always 2 */ + + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, /* Mask of FTS5_TOKENIZE_* flags */ + const char *pText, int nText, + const char *pLocale, int nLocale, + int (*xToken)( + void *pCtx, /* Copy of 2nd argument to xTokenize() */ + int tflags, /* Mask of FTS5_TOKEN_* flags */ + const char *pToken, /* Pointer to buffer containing token */ + int nToken, /* Size of token in bytes */ + int iStart, /* Byte offset of token within input text */ + int iEnd /* Byte offset of end of token within input text */ + ) + ); +}; + +/* +** New code should use the fts5_tokenizer_v2 type to define tokenizer +** implementations. The following type is included for legacy applications +** that still use it. +*/ typedef struct fts5_tokenizer fts5_tokenizer; struct fts5_tokenizer { int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); @@ -13364,6 +13493,7 @@ struct fts5_tokenizer { ); }; + /* Flags that may be passed as the third argument to xTokenize() */ #define FTS5_TOKENIZE_QUERY 0x0001 #define FTS5_TOKENIZE_PREFIX 0x0002 @@ -13383,7 +13513,7 @@ struct fts5_tokenizer { */ typedef struct fts5_api fts5_api; struct fts5_api { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ /* Create a new tokenizer */ int (*xCreateTokenizer)( @@ -13410,6 +13540,25 @@ struct fts5_api { fts5_extension_function xFunction, void (*xDestroy)(void*) ); + + /* APIs below this point are only available if iVersion>=3 */ + + /* Create a new tokenizer */ + int (*xCreateTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void *pUserData, + fts5_tokenizer_v2 *pTokenizer, + void (*xDestroy)(void*) + ); + + /* Find an existing tokenizer */ + int (*xFindTokenizer_v2)( + fts5_api *pApi, + const char *zName, + void **ppUserData, + fts5_tokenizer_v2 **ppTokenizer + ); }; /* From 9b351b074936dfa476e98eb013f7b887ee6eaed1 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Sun, 3 Nov 2024 01:01:48 +0000 Subject: [PATCH 62/93] crypto: fix `RSA_PKCS1_PADDING` error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ability to revert the fix for CVE-2023-46809 was only added to Node.js 18.x, 20.x and 21.x as, per policy, security reverts are only added to the existing supported release lines at the time of the fix. The error message thrown when `RSA_PKCS1_PADDING` is used on `main` and subsequent major versions (i.e. Node.js 22 and 23) when OpenSSL does not support implicit rejections should not have suggested that it is possible to revert the fix. PR-URL: https://github.com/nodejs/node/pull/55629 Fixes: https://github.com/nodejs/node/issues/55628 Reviewed-By: Filip Skokan Reviewed-By: Antoine du Hamel Reviewed-By: Michael Dawson Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: Rafael Gonzaga --- src/crypto/crypto_cipher.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 92ebee231f0983..51e311be705393 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -1092,8 +1092,7 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo& args) { if (rsa_pkcs1_implicit_rejection <= 0) { return THROW_ERR_INVALID_ARG_VALUE( env, - "RSA_PKCS1_PADDING is no longer supported for private decryption," - " this can be reverted with --security-revert=CVE-2024-PEND"); + "RSA_PKCS1_PADDING is no longer supported for private decryption"); } } From 19b1edfc5c6a3fa9323df1292e2ab222381a3a86 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sun, 3 Nov 2024 17:11:34 +0000 Subject: [PATCH 63/93] module: simplify --inspect-brk handling Previously in the CommonJS loader, --inspect-brk is implemented checking whether the module points to the result of re-resolving process.argv[1] to determine whether the module is the entry point. This is unnecessarily complex, especially now that we store that information in the module as kIsMainSymbol. This patch updates it to simply check that symbol property instead. PR-URL: https://github.com/nodejs/node/pull/55679 Reviewed-By: Marco Ippolito Reviewed-By: Benjamin Gruenbaum --- lib/internal/modules/cjs/loader.js | 42 +++--------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index da948167e7fdd6..3f161daa7f3c55 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1332,15 +1332,6 @@ Module.prototype.require = function(id) { } }; -/** - * Resolved path to `process.argv[1]` will be lazily placed here - * (needed for setting breakpoint when called with `--inspect-brk`). - * @type {string | undefined} - */ -let resolvedArgv; -let hasPausedEntry = false; -/** @type {import('vm').Script} */ - /** * Resolve and evaluate it synchronously as ESM if it's ESM. * @param {Module} mod CJS module instance @@ -1542,32 +1533,6 @@ Module.prototype._compile = function(content, filename, format) { return; } - // TODO(joyeecheung): the detection below is unnecessarily complex. Using the - // kIsMainSymbol, or a kBreakOnStartSymbol that gets passed from - // higher level instead of doing hacky detection here. - let inspectorWrapper = null; - if (getOptionValue('--inspect-brk') && process._eval == null) { - if (!resolvedArgv) { - // We enter the repl if we're not given a filename argument. - if (process.argv[1]) { - try { - resolvedArgv = Module._resolveFilename(process.argv[1], null, false); - } catch { - // We only expect this codepath to be reached in the case of a - // preloaded module (it will fail earlier with the main entry) - assert(ArrayIsArray(getOptionValue('--require'))); - } - } else { - resolvedArgv = 'repl'; - } - } - - // Set breakpoint on module start - if (resolvedArgv && !hasPausedEntry && filename === resolvedArgv) { - hasPausedEntry = true; - inspectorWrapper = internalBinding('inspector').callAndPauseOnStart; - } - } const dirname = path.dirname(filename); const require = makeRequireFunction(this, redirects); let result; @@ -1577,9 +1542,10 @@ Module.prototype._compile = function(content, filename, format) { if (requireDepth === 0) { statCache = new SafeMap(); } setHasStartedUserCJSExecution(); this[kIsExecuting] = true; - if (inspectorWrapper) { - result = inspectorWrapper(compiledWrapper, thisValue, exports, - require, module, filename, dirname); + if (this[kIsMainSymbol] && getOptionValue('--inspect-brk')) { + const { callAndPauseOnStart } = internalBinding('inspector'); + result = callAndPauseOnStart(compiledWrapper, thisValue, exports, + require, module, filename, dirname); } else { result = ReflectApply(compiledWrapper, thisValue, [exports, require, module, filename, dirname]); From d79c8bf7a1f5f2391e6e1590b938b1736823ec9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:03:18 +0000 Subject: [PATCH 64/93] meta: bump github/codeql-action from 3.26.10 to 3.27.0 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.10 to 3.27.0. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e2b3eafc8d227b0241d48be5f425d47c2d750a13...662472033e021d55d94146f66f6058822b0b39fd) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55682 Reviewed-By: Marco Ippolito Reviewed-By: Antoine du Hamel --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c23dae03fc036c..2ce8b534de03c9 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -73,6 +73,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: Upload to code-scanning - uses: github/codeql-action/upload-sarif@e2b3eafc8d227b0241d48be5f425d47c2d750a13 # v3.26.10 + uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 with: sarif_file: results.sarif From 5c2e4729cc3c73f2a44aa81774a084f2fb42a608 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:03:33 +0000 Subject: [PATCH 65/93] meta: bump actions/checkout from 4.2.0 to 4.2.2 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.0 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/d632683dd7b4114ad314bca15554477dd762a938...11bd71901bbe5b1630ceea73d27597364c9af683) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55683 Reviewed-By: Marco Ippolito Reviewed-By: Luigi Pinca --- .github/workflows/auto-start-ci.yml | 2 +- .github/workflows/build-tarball.yml | 4 ++-- .github/workflows/commit-lint.yml | 2 +- .github/workflows/commit-queue.yml | 2 +- .../workflows/coverage-linux-without-intl.yml | 2 +- .github/workflows/coverage-linux.yml | 2 +- .github/workflows/coverage-windows.yml | 2 +- .github/workflows/daily-wpt-fyi.yml | 6 +++--- .github/workflows/daily.yml | 2 +- .github/workflows/doc.yml | 2 +- .../workflows/find-inactive-collaborators.yml | 2 +- .github/workflows/find-inactive-tsc.yml | 4 ++-- .github/workflows/license-builder.yml | 2 +- .github/workflows/linters.yml | 20 +++++++++---------- .github/workflows/notify-on-push.yml | 2 +- .github/workflows/scorecard.yml | 2 +- .github/workflows/test-asan.yml | 2 +- .github/workflows/test-internet.yml | 2 +- .github/workflows/test-linux.yml | 2 +- .github/workflows/test-macos.yml | 2 +- .github/workflows/test-ubsan.yml | 2 +- .github/workflows/timezone-update.yml | 4 ++-- .github/workflows/tools.yml | 2 +- .github/workflows/update-openssl.yml | 2 +- .github/workflows/update-v8.yml | 2 +- 25 files changed, 39 insertions(+), 39 deletions(-) diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index f22a13b1abf188..d2a6c3ff2919a4 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -45,7 +45,7 @@ jobs: if: needs.get-prs-for-ci.outputs.numbers != '' runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false diff --git a/.github/workflows/build-tarball.yml b/.github/workflows/build-tarball.yml index 3487b62d4c105a..a5082386eefcd8 100644 --- a/.github/workflows/build-tarball.yml +++ b/.github/workflows/build-tarball.yml @@ -42,7 +42,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -72,7 +72,7 @@ jobs: needs: build-tarball runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index 0b39ccc287340f..cdada624420302 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -17,7 +17,7 @@ jobs: run: | echo "plusOne=$((${{ github.event.pull_request.commits }} + 1))" >> $GITHUB_OUTPUT echo "minusOne=$((${{ github.event.pull_request.commits }} - 1))" >> $GITHUB_OUTPUT - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: ${{ steps.nb-of-commits.outputs.plusOne }} persist-credentials: false diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index 8fc0a4a057fd7c..f72211d345e664 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -58,7 +58,7 @@ jobs: if: needs.get_mergeable_prs.outputs.numbers != '' runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: # Needs the whole git history for ncu to work # See https://github.com/nodejs/node-core-utils/pull/486 diff --git a/.github/workflows/coverage-linux-without-intl.yml b/.github/workflows/coverage-linux-without-intl.yml index 744e9b30b89ab7..919995b76fbcca 100644 --- a/.github/workflows/coverage-linux-without-intl.yml +++ b/.github/workflows/coverage-linux-without-intl.yml @@ -48,7 +48,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/coverage-linux.yml b/.github/workflows/coverage-linux.yml index 68f98937e73ba5..66c5bc1dcde878 100644 --- a/.github/workflows/coverage-linux.yml +++ b/.github/workflows/coverage-linux.yml @@ -48,7 +48,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/coverage-windows.yml b/.github/workflows/coverage-windows.yml index ced6ff661c297a..1224b91ef2dccd 100644 --- a/.github/workflows/coverage-windows.yml +++ b/.github/workflows/coverage-windows.yml @@ -45,7 +45,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: windows-2022 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index a148f21428170c..ff8b4a25d8d62f 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -63,7 +63,7 @@ jobs: SHORT_SHA=$(node -p 'process.version.split(/-nightly\d{8}/)[1]') echo "NIGHTLY_REF=$(gh api /repos/nodejs/node/commits/$SHORT_SHA --jq '.sha')" >> $GITHUB_ENV - name: Checkout ${{ steps.setup-node.outputs.node-version }} - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false ref: ${{ env.NIGHTLY_REF || steps.setup-node.outputs.node-version }} @@ -79,7 +79,7 @@ jobs: run: rm -rf wpt working-directory: test/fixtures - name: Checkout epochs/daily WPT - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: web-platform-tests/wpt persist-credentials: false @@ -104,7 +104,7 @@ jobs: run: rm -rf deps/undici - name: Checkout undici if: ${{ env.WPT_REPORT != '' }} - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: repository: nodejs/undici persist-credentials: false diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index a94a3a52677165..619ba34b117003 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -15,7 +15,7 @@ jobs: build-lto: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index b14a608163b10e..1a40c225f723a1 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -24,7 +24,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} diff --git a/.github/workflows/find-inactive-collaborators.yml b/.github/workflows/find-inactive-collaborators.yml index 813b6c5ff3dcbd..987797b924b0c5 100644 --- a/.github/workflows/find-inactive-collaborators.yml +++ b/.github/workflows/find-inactive-collaborators.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/find-inactive-tsc.yml b/.github/workflows/find-inactive-tsc.yml index ea35029a74c553..9a5d1fae481b5d 100644 --- a/.github/workflows/find-inactive-tsc.yml +++ b/.github/workflows/find-inactive-tsc.yml @@ -20,13 +20,13 @@ jobs: steps: - name: Checkout the repo - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 persist-credentials: false - name: Clone nodejs/TSC repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 path: .tmp diff --git a/.github/workflows/license-builder.yml b/.github/workflows/license-builder.yml index 6068e41b80e2f4..c62e9b1f08fe54 100644 --- a/.github/workflows/license-builder.yml +++ b/.github/workflows/license-builder.yml @@ -17,7 +17,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - run: ./tools/license-builder.sh # Run the license builder tool diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 09a6b779d27dbe..ea6c774b6f0464 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -25,7 +25,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} @@ -40,7 +40,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -55,7 +55,7 @@ jobs: if: ${{ github.event.pull_request && github.event.pull_request.draft == false && github.base_ref == github.event.repository.default_branch }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 0 persist-credentials: false @@ -93,7 +93,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} @@ -118,7 +118,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -135,7 +135,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Use Python ${{ env.PYTHON_VERSION }} @@ -153,7 +153,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - run: shellcheck -V @@ -163,7 +163,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - uses: mszostok/codeowners-validator@7f3f5e28c6d7b8dfae5731e54ce2272ca384592f @@ -173,7 +173,7 @@ jobs: if: ${{ github.event.pull_request }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: fetch-depth: 2 persist-credentials: false @@ -182,7 +182,7 @@ jobs: lint-readme: runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Get team members if possible diff --git a/.github/workflows/notify-on-push.yml b/.github/workflows/notify-on-push.yml index 1e3d618f2dc6df..3f100b68976383 100644 --- a/.github/workflows/notify-on-push.yml +++ b/.github/workflows/notify-on-push.yml @@ -34,7 +34,7 @@ jobs: permissions: pull-requests: write steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Check commit message diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 2ce8b534de03c9..c5bc60632cbc71 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -38,7 +38,7 @@ jobs: egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs - name: Checkout code - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false diff --git a/.github/workflows/test-asan.yml b/.github/workflows/test-asan.yml index 2965008cca1e27..ca70add4d3d55c 100644 --- a/.github/workflows/test-asan.yml +++ b/.github/workflows/test-asan.yml @@ -47,7 +47,7 @@ jobs: CONFIG_FLAGS: --enable-asan SCCACHE_GHA_ENABLED: 'true' steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-internet.yml b/.github/workflows/test-internet.yml index b7eba9d5015814..8a0280780e4e12 100644 --- a/.github/workflows/test-internet.yml +++ b/.github/workflows/test-internet.yml @@ -44,7 +44,7 @@ jobs: if: github.repository == 'nodejs/node' || github.event_name != 'schedule' runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index bc63a2e1edd588..19d37966a16181 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -37,7 +37,7 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml index 74e9f45a0fe51c..ce4abdf54ca4fe 100644 --- a/.github/workflows/test-macos.yml +++ b/.github/workflows/test-macos.yml @@ -44,7 +44,7 @@ jobs: CXX: sccache g++ SCCACHE_GHA_ENABLED: 'true' steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} diff --git a/.github/workflows/test-ubsan.yml b/.github/workflows/test-ubsan.yml index 9ee7a53229fd8d..f8fb51d15189ff 100644 --- a/.github/workflows/test-ubsan.yml +++ b/.github/workflows/test-ubsan.yml @@ -45,7 +45,7 @@ jobs: LINK: sccache g++ CONFIG_FLAGS: --enable-ubsan steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Store suppressions path diff --git a/.github/workflows/timezone-update.yml b/.github/workflows/timezone-update.yml index cf2b53fe62c264..e951b848ad4155 100644 --- a/.github/workflows/timezone-update.yml +++ b/.github/workflows/timezone-update.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Checkout nodejs/node - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Checkout unicode-org/icu-data - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: path: icu-data persist-credentials: false diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index 11d6ac02a0d511..26af21a965b534 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -296,7 +296,7 @@ jobs: tail -n1 temp-output | grep "NEW_VERSION=" >> "$GITHUB_ENV" || true rm temp-output steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 if: github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id with: persist-credentials: false diff --git a/.github/workflows/update-openssl.yml b/.github/workflows/update-openssl.yml index aaa554e1bc06b0..856a486dcc6d62 100644 --- a/.github/workflows/update-openssl.yml +++ b/.github/workflows/update-openssl.yml @@ -14,7 +14,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Check and download new OpenSSL version diff --git a/.github/workflows/update-v8.yml b/.github/workflows/update-v8.yml index b23bdae0de578f..611b0ce17b418e 100644 --- a/.github/workflows/update-v8.yml +++ b/.github/workflows/update-v8.yml @@ -16,7 +16,7 @@ jobs: if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Cache node modules and update-v8 From 9042e9acc99c9e3bb37d2d759c2a397928963520 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:04:01 +0000 Subject: [PATCH 66/93] meta: bump actions/cache from 4.0.2 to 4.1.2 Bumps [actions/cache](https://github.com/actions/cache) from 4.0.2 to 4.1.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/0c45773b623bea8c8e75f6c82b208c3cf94ea4f9...6849a6489940f00c2f30c0fb92c6274307ccb58a) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55684 Reviewed-By: Marco Ippolito Reviewed-By: Luigi Pinca --- .github/workflows/update-v8.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-v8.yml b/.github/workflows/update-v8.yml index 611b0ce17b418e..b5bcfce70a6c25 100644 --- a/.github/workflows/update-v8.yml +++ b/.github/workflows/update-v8.yml @@ -20,7 +20,7 @@ jobs: with: persist-credentials: false - name: Cache node modules and update-v8 - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 id: cache-v8-npm env: cache-name: cache-v8-npm From 42e6c47086e0a98c0d7f8f83a60aa31662d18cf3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:04:57 +0000 Subject: [PATCH 67/93] meta: bump actions/upload-artifact from 4.4.0 to 4.4.3 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.4.0 to 4.4.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/50769540e7f4bd5e21e526ee35c689e35e0d6874...b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55685 Reviewed-By: Marco Ippolito Reviewed-By: Luigi Pinca --- .github/workflows/build-tarball.yml | 2 +- .github/workflows/daily-wpt-fyi.yml | 2 +- .github/workflows/doc.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-tarball.yml b/.github/workflows/build-tarball.yml index a5082386eefcd8..59e5e8391e150a 100644 --- a/.github/workflows/build-tarball.yml +++ b/.github/workflows/build-tarball.yml @@ -64,7 +64,7 @@ jobs: mkdir tarballs mv *.tar.gz tarballs - name: Upload tarball artifact - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: tarballs path: tarballs diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index ff8b4a25d8d62f..6272248406ed2a 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -127,7 +127,7 @@ jobs: run: cp wptreport.json wptreport-${{ steps.setup-node.outputs.node-version }}.json - name: Upload GitHub Actions artifact if: ${{ env.WPT_REPORT != '' }} - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: path: out/wpt/wptreport-*.json name: WPT Report for ${{ steps.setup-node.outputs.node-version }} diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 1a40c225f723a1..685950677744a1 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -35,7 +35,7 @@ jobs: run: npx envinfo - name: Build run: NODE=$(command -v node) make doc-only - - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: docs path: out/doc diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c5bc60632cbc71..6fbf46e7f3e22f 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -65,7 +65,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: Upload artifact - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: name: SARIF file path: results.sarif From 2ae8d3b2ff809b4fd23e90a7a4cabe15c65cf9dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:05:54 +0000 Subject: [PATCH 68/93] meta: bump rtCamp/action-slack-notify from 2.3.0 to 2.3.2 Bumps [rtCamp/action-slack-notify](https://github.com/rtcamp/action-slack-notify) from 2.3.0 to 2.3.2. - [Release notes](https://github.com/rtcamp/action-slack-notify/releases) - [Commits](https://github.com/rtcamp/action-slack-notify/compare/4e5fb42d249be6a45a298f3c9543b111b02f7907...c33737706dea87cd7784c687dadc9adf1be59990) --- updated-dependencies: - dependency-name: rtCamp/action-slack-notify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55686 Reviewed-By: Marco Ippolito Reviewed-By: Antoine du Hamel --- .github/workflows/notify-on-push.yml | 4 ++-- .github/workflows/notify-on-review-wanted.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/notify-on-push.yml b/.github/workflows/notify-on-push.yml index 3f100b68976383..14b184deb515c2 100644 --- a/.github/workflows/notify-on-push.yml +++ b/.github/workflows/notify-on-push.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Slack Notification - uses: rtCamp/action-slack-notify@4e5fb42d249be6a45a298f3c9543b111b02f7907 # 2.3.0 + uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990 # 2.3.2 env: SLACK_COLOR: '#DE512A' SLACK_ICON: https://github.com/nodejs.png?size=48 @@ -56,7 +56,7 @@ jobs: GH_TOKEN: ${{ github.token }} - name: Slack Notification if: ${{ env.INVALID_COMMIT_MESSAGE }} - uses: rtCamp/action-slack-notify@4e5fb42d249be6a45a298f3c9543b111b02f7907 # 2.3.0 + uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990 # 2.3.2 env: SLACK_COLOR: '#DE512A' SLACK_ICON: https://github.com/nodejs.png?size=48 diff --git a/.github/workflows/notify-on-review-wanted.yml b/.github/workflows/notify-on-review-wanted.yml index 1f076a00027766..b4e3490f31f3d6 100644 --- a/.github/workflows/notify-on-review-wanted.yml +++ b/.github/workflows/notify-on-review-wanted.yml @@ -33,7 +33,7 @@ jobs: fi - name: Slack Notification - uses: rtCamp/action-slack-notify@4e5fb42d249be6a45a298f3c9543b111b02f7907 # 2.3.0 + uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990 # 2.3.2 env: MSG_MINIMAL: actions url SLACK_COLOR: '#3d85c6' From 21e3b7b2f470bba035bd46ebb524c7718386695d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:06:43 +0000 Subject: [PATCH 69/93] meta: bump actions/setup-node from 4.0.4 to 4.1.0 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.0.4 to 4.1.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/0a44ba7841725637a19e28fa30b79a866c81b0a6...39370e3970a6d050c480ffad4ff0ed4d3fdee5af) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55687 Reviewed-By: Marco Ippolito Reviewed-By: Michael Dawson Reviewed-By: Rafael Gonzaga Reviewed-By: Yagiz Nizipli Reviewed-By: Luigi Pinca --- .github/workflows/auto-start-ci.yml | 2 +- .github/workflows/commit-lint.yml | 2 +- .github/workflows/commit-queue.yml | 2 +- .github/workflows/daily-wpt-fyi.yml | 2 +- .github/workflows/daily.yml | 2 +- .github/workflows/doc.yml | 2 +- .github/workflows/find-inactive-collaborators.yml | 2 +- .github/workflows/find-inactive-tsc.yml | 2 +- .github/workflows/linters.yml | 6 +++--- .github/workflows/update-v8.yml | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index d2a6c3ff2919a4..3703a28abbc231 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -50,7 +50,7 @@ jobs: persist-credentials: false - name: Install Node.js - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index cdada624420302..1eb5622358ed7d 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -23,7 +23,7 @@ jobs: persist-credentials: false - run: git reset HEAD^2 - name: Install Node.js - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Validate commit message diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index f72211d345e664..3417ed62a53b6b 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -71,7 +71,7 @@ jobs: # Install dependencies - name: Install Node.js - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Install @node-core/utils diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index 6272248406ed2a..cb57f02c02e1b8 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -51,7 +51,7 @@ jobs: run: echo "NIGHTLY=$(curl -s https://nodejs.org/download/nightly/index.json | jq -r '[.[] | select(.files[] | contains("linux-x64"))][0].version')" >> $GITHUB_ENV - name: Install Node.js id: setup-node - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NIGHTLY || matrix.node-version }} check-latest: true diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 619ba34b117003..e929e8168b0e66 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -19,7 +19,7 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 685950677744a1..5ab4277879ecb9 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -28,7 +28,7 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information diff --git a/.github/workflows/find-inactive-collaborators.yml b/.github/workflows/find-inactive-collaborators.yml index 987797b924b0c5..30ae63ee115be8 100644 --- a/.github/workflows/find-inactive-collaborators.yml +++ b/.github/workflows/find-inactive-collaborators.yml @@ -25,7 +25,7 @@ jobs: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/find-inactive-tsc.yml b/.github/workflows/find-inactive-tsc.yml index 9a5d1fae481b5d..85c16ad0648fca 100644 --- a/.github/workflows/find-inactive-tsc.yml +++ b/.github/workflows/find-inactive-tsc.yml @@ -34,7 +34,7 @@ jobs: repository: nodejs/TSC - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index ea6c774b6f0464..7c3e631a41414d 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -29,7 +29,7 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information @@ -60,7 +60,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Set up Python ${{ env.PYTHON_VERSION }} @@ -97,7 +97,7 @@ jobs: with: persist-credentials: false - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Environment Information diff --git a/.github/workflows/update-v8.yml b/.github/workflows/update-v8.yml index b5bcfce70a6c25..f744ae6bb53d30 100644 --- a/.github/workflows/update-v8.yml +++ b/.github/workflows/update-v8.yml @@ -30,7 +30,7 @@ jobs: ~/.npm key: ${{ runner.os }}-build-${{ env.cache-name }} - name: Install Node.js - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 with: node-version: ${{ env.NODE_VERSION }} - name: Install @node-core/utils From 7bfd2954164265079923ddce116b58c2638c55f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:07:53 +0000 Subject: [PATCH 70/93] meta: bump actions/setup-python from 5.2.0 to 5.3.0 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/f677139bbe7f9c59b41e40162b753c062f5d49a3...0b93645e9fea7318ecaed2b359559ac225c90a2b) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55688 Reviewed-By: Rafael Gonzaga Reviewed-By: Marco Ippolito Reviewed-By: Luigi Pinca --- .github/workflows/build-tarball.yml | 4 ++-- .github/workflows/coverage-linux-without-intl.yml | 2 +- .github/workflows/coverage-linux.yml | 2 +- .github/workflows/coverage-windows.yml | 2 +- .github/workflows/daily-wpt-fyi.yml | 2 +- .github/workflows/linters.yml | 8 ++++---- .github/workflows/test-asan.yml | 2 +- .github/workflows/test-internet.yml | 2 +- .github/workflows/test-linux.yml | 2 +- .github/workflows/test-macos.yml | 2 +- .github/workflows/test-ubsan.yml | 2 +- .github/workflows/tools.yml | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build-tarball.yml b/.github/workflows/build-tarball.yml index 59e5e8391e150a..7d8b38a21f8831 100644 --- a/.github/workflows/build-tarball.yml +++ b/.github/workflows/build-tarball.yml @@ -46,7 +46,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache @@ -76,7 +76,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache diff --git a/.github/workflows/coverage-linux-without-intl.yml b/.github/workflows/coverage-linux-without-intl.yml index 919995b76fbcca..ddd85fb8a4ff0e 100644 --- a/.github/workflows/coverage-linux-without-intl.yml +++ b/.github/workflows/coverage-linux-without-intl.yml @@ -52,7 +52,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache diff --git a/.github/workflows/coverage-linux.yml b/.github/workflows/coverage-linux.yml index 66c5bc1dcde878..153504ba4280d6 100644 --- a/.github/workflows/coverage-linux.yml +++ b/.github/workflows/coverage-linux.yml @@ -52,7 +52,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache diff --git a/.github/workflows/coverage-windows.yml b/.github/workflows/coverage-windows.yml index 1224b91ef2dccd..84feb7b09018de 100644 --- a/.github/workflows/coverage-windows.yml +++ b/.github/workflows/coverage-windows.yml @@ -49,7 +49,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install deps diff --git a/.github/workflows/daily-wpt-fyi.yml b/.github/workflows/daily-wpt-fyi.yml index cb57f02c02e1b8..ebac102f63e115 100644 --- a/.github/workflows/daily-wpt-fyi.yml +++ b/.github/workflows/daily-wpt-fyi.yml @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 7c3e631a41414d..6adc799970cd84 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -44,7 +44,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information @@ -64,7 +64,7 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information @@ -122,7 +122,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information @@ -139,7 +139,7 @@ jobs: with: persist-credentials: false - name: Use Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information diff --git a/.github/workflows/test-asan.yml b/.github/workflows/test-asan.yml index ca70add4d3d55c..d918fa7d87300b 100644 --- a/.github/workflows/test-asan.yml +++ b/.github/workflows/test-asan.yml @@ -51,7 +51,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache diff --git a/.github/workflows/test-internet.yml b/.github/workflows/test-internet.yml index 8a0280780e4e12..eced01cfbdaa0e 100644 --- a/.github/workflows/test-internet.yml +++ b/.github/workflows/test-internet.yml @@ -48,7 +48,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Environment Information diff --git a/.github/workflows/test-linux.yml b/.github/workflows/test-linux.yml index 19d37966a16181..24cf47f9b376bd 100644 --- a/.github/workflows/test-linux.yml +++ b/.github/workflows/test-linux.yml @@ -41,7 +41,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache diff --git a/.github/workflows/test-macos.yml b/.github/workflows/test-macos.yml index ce4abdf54ca4fe..6bb22265032605 100644 --- a/.github/workflows/test-macos.yml +++ b/.github/workflows/test-macos.yml @@ -48,7 +48,7 @@ jobs: with: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache diff --git a/.github/workflows/test-ubsan.yml b/.github/workflows/test-ubsan.yml index f8fb51d15189ff..9f33fa670b8231 100644 --- a/.github/workflows/test-ubsan.yml +++ b/.github/workflows/test-ubsan.yml @@ -52,7 +52,7 @@ jobs: run: | echo "UBSAN_OPTIONS=suppressions=$GITHUB_WORKSPACE/suppressions.supp" >> $GITHUB_ENV - name: Set up Python ${{ env.PYTHON_VERSION }} - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - name: Set up sccache diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index 26af21a965b534..7cd0c496c6ca68 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -302,7 +302,7 @@ jobs: persist-credentials: false - name: Set up Python ${{ env.PYTHON_VERSION }} if: matrix.id == 'icu' && (github.event_name == 'schedule' || inputs.id == 'all' || inputs.id == matrix.id) - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: python-version: ${{ env.PYTHON_VERSION }} - run: ${{ matrix.run }} From 8fc962f1af011e6fcde1995d6a7fa431f2496c2f Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Fri, 1 Nov 2024 16:36:45 +0000 Subject: [PATCH 71/93] tools: fix root certificate updater MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Determine the NSS version from actual Firefox releases, instead of attempting to parse a wiki page (which is sensitive to formatting changes and relies on the page being up to date). PR-URL: https://github.com/nodejs/node/pull/55681 Reviewed-By: Luigi Pinca Reviewed-By: Michaël Zasso Reviewed-By: Rafael Gonzaga --- tools/dep_updaters/update-root-certs.mjs | 186 +++++++++-------------- 1 file changed, 69 insertions(+), 117 deletions(-) diff --git a/tools/dep_updaters/update-root-certs.mjs b/tools/dep_updaters/update-root-certs.mjs index 64f3c88b851b7f..a9e0a009f02deb 100644 --- a/tools/dep_updaters/update-root-certs.mjs +++ b/tools/dep_updaters/update-root-certs.mjs @@ -8,109 +8,78 @@ import { pipeline } from 'node:stream/promises'; import { fileURLToPath } from 'node:url'; import { parseArgs } from 'node:util'; -// Constants for NSS release metadata. -const kNSSVersion = 'version'; -const kNSSDate = 'date'; -const kFirefoxVersion = 'firefoxVersion'; -const kFirefoxDate = 'firefoxDate'; - const __filename = fileURLToPath(import.meta.url); -const now = new Date(); - -const formatDate = (d) => { - const iso = d.toISOString(); - return iso.substring(0, iso.indexOf('T')); -}; const getCertdataURL = (version) => { const tag = `NSS_${version.replaceAll('.', '_')}_RTM`; - const certdataURL = `https://hg.mozilla.org/projects/nss/raw-file/${tag}/lib/ckfw/builtins/certdata.txt`; + const certdataURL = `https://raw.githubusercontent.com/nss-dev/nss/refs/tags/${tag}/lib/ckfw/builtins/certdata.txt`; return certdataURL; }; -const normalizeTD = (text = '') => { - // Remove whitespace and any HTML tags. - return text?.trim().replace(/<.*?>/g, ''); -}; -const getReleases = (text) => { - const releases = []; - const tableRE = /
]+>([\S\s]*?)<\/table>/g; - const tableRowRE = /]*>([\S\s]*?)<\/tr>/g; - const tableHeaderRE = / -23.1.0
+23.2.0
+23.1.0
23.0.0
@@ -39,6 +40,128 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2024-11-11, Version 23.2.0 (Current), @aduh95 + +### Notable Changes + +#### Update root certificates to NSS 3.104 + +This is the version of NSS that shipped in Firefox 131.0 on 2024-10-01. + +Certificates added: + +* FIRMAPROFESIONAL CA ROOT-A WEB +* TWCA CYBER Root CA +* SecureSign Root CA12 +* SecureSign Root CA14 +* SecureSign Root CA15 + +#### Other notable changes + +* \[[`fa61dced44`](https://github.com/nodejs/node/commit/fa61dced44)] - **doc**: move typescript support to active development (Marco Ippolito) [#55536](https://github.com/nodejs/node/pull/55536) +* \[[`9dcca5441b`](https://github.com/nodejs/node/commit/9dcca5441b)] - **doc**: add jazelly to collaborators (Jason Zhang) [#55531](https://github.com/nodejs/node/pull/55531) +* \[[`f628fc43cb`](https://github.com/nodejs/node/commit/f628fc43cb)] - **(SEMVER-MINOR)** **fs**: make `dirent.path` writable (Antoine du Hamel) [#55547](https://github.com/nodejs/node/pull/55547) +* \[[`25b1422337`](https://github.com/nodejs/node/commit/25b1422337)] - **(SEMVER-MINOR)** **http**: add diagnostic channel `http.client.request.created` (Marco Ippolito) [#55586](https://github.com/nodejs/node/pull/55586) +* \[[`adda37f00c`](https://github.com/nodejs/node/commit/adda37f00c)] - **(SEMVER-MINOR)** **module**: add `findPackageJSON` util (Jacob Smith) [#55412](https://github.com/nodejs/node/pull/55412) +* \[[`69dd1e13c3`](https://github.com/nodejs/node/commit/69dd1e13c3)] - **(SEMVER-MINOR)** **module**: add `module.stripTypeScriptTypes` (Marco Ippolito) [#55282](https://github.com/nodejs/node/pull/55282) + +### Commits + +* \[[`9dbb255efb`](https://github.com/nodejs/node/commit/9dbb255efb)] - **assert**: fix `deepStrictEqual` on errors when `cause` is not undefined (Edigleysson Silva (Edy)) [#55406](https://github.com/nodejs/node/pull/55406) +* \[[`7af76ef0b3`](https://github.com/nodejs/node/commit/7af76ef0b3)] - **assert**: fix the string length check for printing the simple diff (Giovanni Bucci) [#55474](https://github.com/nodejs/node/pull/55474) +* \[[`34483a299b`](https://github.com/nodejs/node/commit/34483a299b)] - **benchmark**: add nodeTiming.uvmetricsinfo bench (RafaelGSS) [#55614](https://github.com/nodejs/node/pull/55614) +* \[[`b79e4835ab`](https://github.com/nodejs/node/commit/b79e4835ab)] - **build**: use rclone instead of aws CLI (Michaël Zasso) [#55617](https://github.com/nodejs/node/pull/55617) +* \[[`7ab1f46b8a`](https://github.com/nodejs/node/commit/7ab1f46b8a)] - **build**: stop pre-compiling `lint-md` (Aviv Keller) [#55266](https://github.com/nodejs/node/pull/55266) +* \[[`4887214e23`](https://github.com/nodejs/node/commit/4887214e23)] - **build**: fix building with system icu 76 (Michael Cho) [#55563](https://github.com/nodejs/node/pull/55563) +* \[[`f8df27aa5a`](https://github.com/nodejs/node/commit/f8df27aa5a)] - **build**: fix GN arg used in generate\_config\_gypi.py (Shelley Vohr) [#55530](https://github.com/nodejs/node/pull/55530) +* \[[`bb78904548`](https://github.com/nodejs/node/commit/bb78904548)] - **build**: fix GN build for sqlite and nghttp2 (Shelley Vohr) [#55529](https://github.com/nodejs/node/pull/55529) +* \[[`535f1b0d4c`](https://github.com/nodejs/node/commit/535f1b0d4c)] - **crypto**: update root certificates to NSS 3.104 (Richard Lau) [#55681](https://github.com/nodejs/node/pull/55681) +* \[[`9b351b0749`](https://github.com/nodejs/node/commit/9b351b0749)] - **crypto**: fix `RSA_PKCS1_PADDING` error message (Richard Lau) [#55629](https://github.com/nodejs/node/pull/55629) +* \[[`4b192daac0`](https://github.com/nodejs/node/commit/4b192daac0)] - **deps**: update acorn to 8.14.0 (Node.js GitHub Bot) [#55699](https://github.com/nodejs/node/pull/55699) +* \[[`dfb764cbc6`](https://github.com/nodejs/node/commit/dfb764cbc6)] - **deps**: update sqlite to 3.47.0 (Node.js GitHub Bot) [#55557](https://github.com/nodejs/node/pull/55557) +* \[[`3477492588`](https://github.com/nodejs/node/commit/3477492588)] - **deps**: update amaro to 0.2.0 (Node.js GitHub Bot) [#55601](https://github.com/nodejs/node/pull/55601) +* \[[`3a1d490535`](https://github.com/nodejs/node/commit/3a1d490535)] - **deps**: update nghttp2 to 1.64.0 (Node.js GitHub Bot) [#55559](https://github.com/nodejs/node/pull/55559) +* \[[`50552fdc92`](https://github.com/nodejs/node/commit/50552fdc92)] - **deps**: update acorn to 8.13.0 (Node.js GitHub Bot) [#55558](https://github.com/nodejs/node/pull/55558) +* \[[`1b82013f06`](https://github.com/nodejs/node/commit/1b82013f06)] - **deps**: update undici to 6.20.1 (Node.js GitHub Bot) [#55503](https://github.com/nodejs/node/pull/55503) +* \[[`09060045b1`](https://github.com/nodejs/node/commit/09060045b1)] - **dns**: stop using deprecated `ares_query` (Aviv Keller) [#55430](https://github.com/nodejs/node/pull/55430) +* \[[`2d0914f337`](https://github.com/nodejs/node/commit/2d0914f337)] - **doc**: consolidate history table of `CustomEvent` (Edigleysson Silva) [#55758](https://github.com/nodejs/node/pull/55758) +* \[[`cbe09b579f`](https://github.com/nodejs/node/commit/cbe09b579f)] - **doc**: add path aliases typescript doc (Carlos Espa) [#55766](https://github.com/nodejs/node/pull/55766) +* \[[`89aa83842a`](https://github.com/nodejs/node/commit/89aa83842a)] - **doc**: add esm example in `path.md` (Aviv Keller) [#55745](https://github.com/nodejs/node/pull/55745) +* \[[`ee12431298`](https://github.com/nodejs/node/commit/ee12431298)] - **doc**: consistent use of word child process (Gireesh Punathil) [#55654](https://github.com/nodejs/node/pull/55654) +* \[[`20cb52d1d8`](https://github.com/nodejs/node/commit/20cb52d1d8)] - **doc**: clarity to available addon options (Preveen P) [#55715](https://github.com/nodejs/node/pull/55715) +* \[[`bffbaa13a2`](https://github.com/nodejs/node/commit/bffbaa13a2)] - **doc**: update `--max-semi-space-size` description (Joe Bowbeer) [#55495](https://github.com/nodejs/node/pull/55495) +* \[[`505ff199b6`](https://github.com/nodejs/node/commit/505ff199b6)] - **doc**: broken `PerformanceObserver` code sample (Dom Harrington) [#54227](https://github.com/nodejs/node/pull/54227) +* \[[`b8ca9d89f4`](https://github.com/nodejs/node/commit/b8ca9d89f4)] - **doc**: add write flag when open file as the demo code's intention (robberfree) [#54626](https://github.com/nodejs/node/pull/54626) +* \[[`6662752b62`](https://github.com/nodejs/node/commit/6662752b62)] - **doc**: add a note on console stream behavior (Gireesh Punathil) [#55616](https://github.com/nodejs/node/pull/55616) +* \[[`9743fa44ed`](https://github.com/nodejs/node/commit/9743fa44ed)] - **doc**: remove mention of ECDH-ES in crypto.diffieHellman (Filip Skokan) [#55611](https://github.com/nodejs/node/pull/55611) +* \[[`5de2567644`](https://github.com/nodejs/node/commit/5de2567644)] - **doc**: improve c++ embedder API doc (Gireesh Punathil) [#55597](https://github.com/nodejs/node/pull/55597) +* \[[`f355054ec7`](https://github.com/nodejs/node/commit/f355054ec7)] - **doc**: capitalize "MIT License" (Aviv Keller) [#55575](https://github.com/nodejs/node/pull/55575) +* \[[`fa61dced44`](https://github.com/nodejs/node/commit/fa61dced44)] - **doc**: move typescript support to active development (Marco Ippolito) [#55536](https://github.com/nodejs/node/pull/55536) +* \[[`f77bf65059`](https://github.com/nodejs/node/commit/f77bf65059)] - **doc**: add suggested tsconfig for type stripping (Marco Ippolito) [#55534](https://github.com/nodejs/node/pull/55534) +* \[[`f00ad27132`](https://github.com/nodejs/node/commit/f00ad27132)] - **doc**: add esm examples to node:string\_decoder (Alfredo González) [#55507](https://github.com/nodejs/node/pull/55507) +* \[[`9dcca5441b`](https://github.com/nodejs/node/commit/9dcca5441b)] - **doc**: add jazelly to collaborators (Jason Zhang) [#55531](https://github.com/nodejs/node/pull/55531) +* \[[`f628fc43cb`](https://github.com/nodejs/node/commit/f628fc43cb)] - **(SEMVER-MINOR)** **fs**: make `dirent.path` writable (Antoine du Hamel) [#55547](https://github.com/nodejs/node/pull/55547) +* \[[`dd9b6833c7`](https://github.com/nodejs/node/commit/dd9b6833c7)] - _**Revert**_ "**fs,win**: fix bug in paths with trailing slashes" (Rod Vagg) [#55527](https://github.com/nodejs/node/pull/55527) +* \[[`8d0526f1f4`](https://github.com/nodejs/node/commit/8d0526f1f4)] - **http**: add diagnostic channel `http.server.response.created` (Marco Ippolito) [#55622](https://github.com/nodejs/node/pull/55622) +* \[[`25b1422337`](https://github.com/nodejs/node/commit/25b1422337)] - **(SEMVER-MINOR)** **http**: add diagnostic channel `http.client.request.created` (Marco Ippolito) [#55586](https://github.com/nodejs/node/pull/55586) +* \[[`f92f20b930`](https://github.com/nodejs/node/commit/f92f20b930)] - **http**: don't emit error after destroy (Robert Nagy) [#55457](https://github.com/nodejs/node/pull/55457) +* \[[`137aa5c9f6`](https://github.com/nodejs/node/commit/137aa5c9f6)] - **http2**: fix client async storage persistence (Orgad Shaneh) [#55460](https://github.com/nodejs/node/pull/55460) +* \[[`d1965f9f5b`](https://github.com/nodejs/node/commit/d1965f9f5b)] - **lib**: implement webidl dictionary converter and use it in structuredClone (Jason Zhang) [#55489](https://github.com/nodejs/node/pull/55489) +* \[[`bf552fa3cc`](https://github.com/nodejs/node/commit/bf552fa3cc)] - **lib**: prefer number to string in webidl `type` function (Jason Zhang) [#55489](https://github.com/nodejs/node/pull/55489) +* \[[`7bfd295416`](https://github.com/nodejs/node/commit/7bfd295416)] - **meta**: bump actions/setup-python from 5.2.0 to 5.3.0 (dependabot\[bot]) [#55688](https://github.com/nodejs/node/pull/55688) +* \[[`21e3b7b2f4`](https://github.com/nodejs/node/commit/21e3b7b2f4)] - **meta**: bump actions/setup-node from 4.0.4 to 4.1.0 (dependabot\[bot]) [#55687](https://github.com/nodejs/node/pull/55687) +* \[[`2ae8d3b2ff`](https://github.com/nodejs/node/commit/2ae8d3b2ff)] - **meta**: bump rtCamp/action-slack-notify from 2.3.0 to 2.3.2 (dependabot\[bot]) [#55686](https://github.com/nodejs/node/pull/55686) +* \[[`42e6c47086`](https://github.com/nodejs/node/commit/42e6c47086)] - **meta**: bump actions/upload-artifact from 4.4.0 to 4.4.3 (dependabot\[bot]) [#55685](https://github.com/nodejs/node/pull/55685) +* \[[`9042e9acc9`](https://github.com/nodejs/node/commit/9042e9acc9)] - **meta**: bump actions/cache from 4.0.2 to 4.1.2 (dependabot\[bot]) [#55684](https://github.com/nodejs/node/pull/55684) +* \[[`5c2e4729cc`](https://github.com/nodejs/node/commit/5c2e4729cc)] - **meta**: bump actions/checkout from 4.2.0 to 4.2.2 (dependabot\[bot]) [#55683](https://github.com/nodejs/node/pull/55683) +* \[[`d79c8bf7a1`](https://github.com/nodejs/node/commit/d79c8bf7a1)] - **meta**: bump github/codeql-action from 3.26.10 to 3.27.0 (dependabot\[bot]) [#55682](https://github.com/nodejs/node/pull/55682) +* \[[`d0ea9815f6`](https://github.com/nodejs/node/commit/d0ea9815f6)] - **meta**: make review-wanted message minimal (Aviv Keller) [#55607](https://github.com/nodejs/node/pull/55607) +* \[[`b1ca7ab0a1`](https://github.com/nodejs/node/commit/b1ca7ab0a1)] - **meta**: show PR/issue title on review-wanted (Aviv Keller) [#55606](https://github.com/nodejs/node/pull/55606) +* \[[`19b1edfc5c`](https://github.com/nodejs/node/commit/19b1edfc5c)] - **module**: simplify --inspect-brk handling (Joyee Cheung) [#55679](https://github.com/nodejs/node/pull/55679) +* \[[`869e88c6a8`](https://github.com/nodejs/node/commit/869e88c6a8)] - **module**: simplify `findPackageJSON` implementation (Antoine du Hamel) [#55543](https://github.com/nodejs/node/pull/55543) +* \[[`56c46ab686`](https://github.com/nodejs/node/commit/56c46ab686)] - **module**: unify TypeScript and .mjs handling in CommonJS (Joyee Cheung) [#55590](https://github.com/nodejs/node/pull/55590) +* \[[`d3be3da6f8`](https://github.com/nodejs/node/commit/d3be3da6f8)] - **module**: fix error thrown from require(esm) hitting TLA repeatedly (Joyee Cheung) [#55520](https://github.com/nodejs/node/pull/55520) +* \[[`b3971bbf13`](https://github.com/nodejs/node/commit/b3971bbf13)] - **module**: trim off internal stack frames for require(esm) warnings (Joyee Cheung) [#55496](https://github.com/nodejs/node/pull/55496) +* \[[`a9e08cfe6d`](https://github.com/nodejs/node/commit/a9e08cfe6d)] - **module**: allow ESM that failed to be required to be re-imported (Joyee Cheung) [#55502](https://github.com/nodejs/node/pull/55502) +* \[[`adda37f00c`](https://github.com/nodejs/node/commit/adda37f00c)] - **(SEMVER-MINOR)** **module**: add `findPackageJSON` util (Jacob Smith) [#55412](https://github.com/nodejs/node/pull/55412) +* \[[`69dd1e13c3`](https://github.com/nodejs/node/commit/69dd1e13c3)] - **(SEMVER-MINOR)** **module**: add module.stripTypeScriptTypes (Marco Ippolito) [#55282](https://github.com/nodejs/node/pull/55282) +* \[[`6ab59c81b6`](https://github.com/nodejs/node/commit/6ab59c81b6)] - **os**: improve path check with direct index access (Mert Can Altin) [#55434](https://github.com/nodejs/node/pull/55434) +* \[[`038ac01d26`](https://github.com/nodejs/node/commit/038ac01d26)] - **path,win**: fix bug in resolve and normalize (Hüseyin Açacak) [#55623](https://github.com/nodejs/node/pull/55623) +* \[[`7aa250afda`](https://github.com/nodejs/node/commit/7aa250afda)] - **sqlite**: improve error handling using MaybeLocal (Tobias Nießen) [#55571](https://github.com/nodejs/node/pull/55571) +* \[[`2ec4ae7c16`](https://github.com/nodejs/node/commit/2ec4ae7c16)] - **sqlite**: add readOnly option (Tobias Nießen) [#55567](https://github.com/nodejs/node/pull/55567) +* \[[`88c7f5b489`](https://github.com/nodejs/node/commit/88c7f5b489)] - **sqlite**: refactor open options (Tobias Nießen) [#55442](https://github.com/nodejs/node/pull/55442) +* \[[`7853462a61`](https://github.com/nodejs/node/commit/7853462a61)] - **src**: provide workaround for container-overflow (Daniel Lemire) [#55591](https://github.com/nodejs/node/pull/55591) +* \[[`0302efe4b2`](https://github.com/nodejs/node/commit/0302efe4b2)] - **src**: move more key related stuff to ncrypto (James M Snell) [#55368](https://github.com/nodejs/node/pull/55368) +* \[[`d26dedf41d`](https://github.com/nodejs/node/commit/d26dedf41d)] - **src**: refactor ECDHBitsJob signature (Filip Skokan) [#55610](https://github.com/nodejs/node/pull/55610) +* \[[`4c34891454`](https://github.com/nodejs/node/commit/4c34891454)] - **src**: fix dns crash when failed to create NodeAresTask (theanarkh) [#55521](https://github.com/nodejs/node/pull/55521) +* \[[`467618418a`](https://github.com/nodejs/node/commit/467618418a)] - **src**: use NewFromUtf8Literal in NODE\_DEFINE\_CONSTANT (Charles Kerr) [#55581](https://github.com/nodejs/node/pull/55581) +* \[[`016baaebbe`](https://github.com/nodejs/node/commit/016baaebbe)] - **src**: do not run IsWindowsBatchFile on non-windows (Yagiz Nizipli) [#55560](https://github.com/nodejs/node/pull/55560) +* \[[`efa142c108`](https://github.com/nodejs/node/commit/efa142c108)] - **src**: migrate `String::Value` to `String::ValueView` (Aviv Keller) [#55458](https://github.com/nodejs/node/pull/55458) +* \[[`cfa4d960c8`](https://github.com/nodejs/node/commit/cfa4d960c8)] - **src,lib**: optimize nodeTiming.uvMetricsInfo (RafaelGSS) [#55614](https://github.com/nodejs/node/pull/55614) +* \[[`19da4de475`](https://github.com/nodejs/node/commit/19da4de475)] - **test**: update `performance-timeline` wpt (RedYetiDev) [#55197](https://github.com/nodejs/node/pull/55197) +* \[[`10b68ed975`](https://github.com/nodejs/node/commit/10b68ed975)] - **test**: ignore unrelated events in FW watch tests (Carlos Espa) [#55605](https://github.com/nodejs/node/pull/55605) +* \[[`7d93c0c3ae`](https://github.com/nodejs/node/commit/7d93c0c3ae)] - **test**: refactor some esm tests (Antoine du Hamel) [#55472](https://github.com/nodejs/node/pull/55472) +* \[[`815e2524a6`](https://github.com/nodejs/node/commit/815e2524a6)] - **test**: split up test-runner-mock-timers test (Julian Gassner) [#55506](https://github.com/nodejs/node/pull/55506) +* \[[`6aa797de4e`](https://github.com/nodejs/node/commit/6aa797de4e)] - **test**: remove unneeded listeners (Luigi Pinca) [#55486](https://github.com/nodejs/node/pull/55486) +* \[[`649d767a40`](https://github.com/nodejs/node/commit/649d767a40)] - **test**: increase coverage of `pathToFileURL` (Antoine du Hamel) [#55493](https://github.com/nodejs/node/pull/55493) +* \[[`71cc20a3a5`](https://github.com/nodejs/node/commit/71cc20a3a5)] - **test**: avoid `apply()` calls with large amount of elements (Livia Medeiros) [#55501](https://github.com/nodejs/node/pull/55501) +* \[[`2d19614020`](https://github.com/nodejs/node/commit/2d19614020)] - **test**: increase test coverage for `http.OutgoingMessage.appendHeader()` (Juan José) [#55467](https://github.com/nodejs/node/pull/55467) +* \[[`aebf676569`](https://github.com/nodejs/node/commit/aebf676569)] - **test,crypto**: update WebCryptoAPI WPT (Filip Skokan) [#55703](https://github.com/nodejs/node/pull/55703) +* \[[`53a7d8e75b`](https://github.com/nodejs/node/commit/53a7d8e75b)] - **test,crypto**: update WebCryptoAPI WPT (Filip Skokan) [#55512](https://github.com/nodejs/node/pull/55512) +* \[[`0ea74f3d02`](https://github.com/nodejs/node/commit/0ea74f3d02)] - **test,crypto**: make crypto tests work with BoringSSL (Shelley Vohr) [#55491](https://github.com/nodejs/node/pull/55491) +* \[[`3234dc6100`](https://github.com/nodejs/node/commit/3234dc6100)] - **test\_runner**: pass `options` directly to `TestCoverage` (Aviv Keller) [#55578](https://github.com/nodejs/node/pull/55578) +* \[[`15028dd073`](https://github.com/nodejs/node/commit/15028dd073)] - **tools**: update ESLint to 9.14.0 (dependabot\[bot]) [#55689](https://github.com/nodejs/node/pull/55689) +* \[[`961cbc9c0f`](https://github.com/nodejs/node/commit/961cbc9c0f)] - **tools**: use `util.parseArgs` in `lint-md` (Aviv Keller) [#55694](https://github.com/nodejs/node/pull/55694) +* \[[`8fc962f1af`](https://github.com/nodejs/node/commit/8fc962f1af)] - **tools**: fix root certificate updater (Richard Lau) [#55681](https://github.com/nodejs/node/pull/55681) +* \[[`d0b2d6be84`](https://github.com/nodejs/node/commit/d0b2d6be84)] - **tools**: compact jq output in daily-wpt-fyi.yml action (Filip Skokan) [#55695](https://github.com/nodejs/node/pull/55695) +* \[[`cba05cda38`](https://github.com/nodejs/node/commit/cba05cda38)] - **tools**: run daily WPT.fyi report on all supported releases (Filip Skokan) [#55619](https://github.com/nodejs/node/pull/55619) +* \[[`7ce7eab324`](https://github.com/nodejs/node/commit/7ce7eab324)] - **tools**: lint README lists more strictly (Antoine du Hamel) [#55625](https://github.com/nodejs/node/pull/55625) +* \[[`c2fcda45ca`](https://github.com/nodejs/node/commit/c2fcda45ca)] - **typings**: fix `ModulesBinding` types (Antoine du Hamel) [#55549](https://github.com/nodejs/node/pull/55549) +* \[[`2b9928561d`](https://github.com/nodejs/node/commit/2b9928561d)] - **url**: refactor `pathToFileURL` to native (Antoine du Hamel) [#55476](https://github.com/nodejs/node/pull/55476) +* \[[`4129bc72e2`](https://github.com/nodejs/node/commit/4129bc72e2)] - **util**: do not catch on circular `@@toStringTag` errors (Aviv Keller) [#55544](https://github.com/nodejs/node/pull/55544) + ## 2024-10-24, Version 23.1.0 (Current), @aduh95 diff --git a/src/node_version.h b/src/node_version.h index 1901b4040e937b..712f7472c80b67 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 23 -#define NODE_MINOR_VERSION 1 -#define NODE_PATCH_VERSION 1 +#define NODE_MINOR_VERSION 2 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)
]*>([\S\s]*?)<\/th>/g; - const tableDataRE = /]*>([\S\s]*?)<\/td>/g; - for (const table of text.matchAll(tableRE)) { - const columns = {}; - const matches = table[1].matchAll(tableRowRE); - // First row has the table header. - let row = matches.next(); - if (row.done) { - continue; - } - const headers = Array.from(row.value[1].matchAll(tableHeaderRE), (m) => m[1]); - if (headers.length > 0) { - for (let i = 0; i < headers.length; i++) { - if (/NSS version/i.test(headers[i])) { - columns[kNSSVersion] = i; - } else if (/Release.*from branch/i.test(headers[i])) { - columns[kNSSDate] = i; - } else if (/Firefox version/i.test(headers[i])) { - columns[kFirefoxVersion] = i; - } else if (/Firefox release date/i.test(headers[i])) { - columns[kFirefoxDate] = i; - } - } - } - // Filter out "NSS Certificate bugs" table. - if (columns[kNSSDate] === undefined) { - continue; - } - // Scrape releases. - row = matches.next(); - while (!row.done) { - const cells = Array.from(row.value[1].matchAll(tableDataRE), (m) => m[1]); - const release = {}; - release[kNSSVersion] = normalizeTD(cells[columns[kNSSVersion]]); - release[kNSSDate] = new Date(normalizeTD(cells[columns[kNSSDate]])); - release[kFirefoxVersion] = normalizeTD(cells[columns[kFirefoxVersion]]); - release[kFirefoxDate] = new Date(normalizeTD(cells[columns[kFirefoxDate]])); - releases.push(release); - row = matches.next(); - } +const getFirefoxReleases = async (everything = false) => { + const releaseDataURL = `https://nucleus.mozilla.org/rna/all-releases.json${everything ? '?all=true' : ''}`; + if (values.verbose) { + console.log(`Fetching Firefox release data from ${releaseDataURL}.`); + } + const releaseData = await fetch(releaseDataURL); + if (!releaseData.ok) { + console.error(`Failed to fetch ${releaseDataURL}: ${releaseData.status}: ${releaseData.statusText}.`); + process.exit(-1); } - return releases; + return (await releaseData.json()).filter((release) => { + // We're only interested in public releases of Firefox. + return (release.product === 'Firefox' && release.channel === 'Release' && release.is_public === true); + }).sort((a, b) => { + // Sort results by release date. + return new Date(b.release_date) - new Date(a.release_date); + }); }; -const getLatestVersion = async (releases) => { - const arrayNumberSortDescending = (x, y, i) => { - if (x[i] === undefined && y[i] === undefined) { - return 0; - } else if (x[i] === y[i]) { - return arrayNumberSortDescending(x, y, i + 1); - } - return (y[i] ?? 0) - (x[i] ?? 0); - }; - const extractVersion = (t) => { - return t[kNSSVersion].split('.').map((n) => parseInt(n)); - }; - const releaseSorter = (x, y) => { - return arrayNumberSortDescending(extractVersion(x), extractVersion(y), 0); - }; - // Return the most recent certadata.txt that exists on the server. - const sortedReleases = releases.sort(releaseSorter).filter(pastRelease); - for (const candidate of sortedReleases) { - const candidateURL = getCertdataURL(candidate[kNSSVersion]); - if (values.verbose) { - console.log(`Trying ${candidateURL}`); +const getFirefoxRelease = async (version) => { + let releases = await getFirefoxReleases(); + let found; + if (version === undefined) { + // No version specified. Find the most recent. + if (releases.length > 0) { + found = releases[0]; + } else { + if (values.verbose) { + console.log('Unable to find release data for Firefox. Searching full release data.'); + } + releases = await getFirefoxReleases(true); + found = releases[0]; } - const response = await fetch(candidateURL, { method: 'HEAD' }); - if (response.ok) { - return candidate[kNSSVersion]; + } else { + // Search for the specified release. + found = releases.find((release) => release.version === version); + if (found === undefined) { + if (values.verbose) { + console.log(`Unable to find release data for Firefox ${version}. Searching full release data.`); + } + releases = await getFirefoxReleases(true); + found = releases.find((release) => release.version === version); } } + return found; }; -const pastRelease = (r) => { - return r[kNSSDate] < now; +const getNSSVersion = async (release) => { + const latestFirefox = release.version; + const firefoxTag = `FIREFOX_${latestFirefox.replace('.', '_')}_RELEASE`; + const tagInfoURL = `https://hg.mozilla.org/releases/mozilla-release/raw-file/${firefoxTag}/security/nss/TAG-INFO`; + if (values.verbose) { + console.log(`Fetching NSS tag from ${tagInfoURL}.`); + } + const tagInfo = await fetch(tagInfoURL); + if (!tagInfo.ok) { + console.error(`Failed to fetch ${tagInfoURL}: ${tagInfo.status}: ${tagInfo.statusText}`); + } + const tag = await tagInfo.text(); + if (values.verbose) { + console.log(`Found tag ${tag}.`); + } + // Tag will be of form `NSS_x_y_RTM`. Convert to `x.y`. + return tag.split('_').slice(1, -1).join('.'); }; const options = { @@ -135,9 +104,9 @@ const { }); if (values.help) { - console.log(`Usage: ${basename(__filename)} [OPTION]... [VERSION]...`); + console.log(`Usage: ${basename(__filename)} [OPTION]... [RELEASE]...`); console.log(); - console.log('Updates certdata.txt to NSS VERSION (most recent release by default).'); + console.log('Updates certdata.txt to NSS version contained in Firefox RELEASE (default: most recent release).'); console.log(''); console.log(' -f, --file=FILE writes a commit message reflecting the change to the'); console.log(' specified FILE'); @@ -146,29 +115,11 @@ if (values.help) { process.exit(0); } -const scheduleURL = 'https://wiki.mozilla.org/NSS:Release_Versions'; -if (values.verbose) { - console.log(`Fetching NSS release schedule from ${scheduleURL}`); -} -const schedule = await fetch(scheduleURL); -if (!schedule.ok) { - console.error(`Failed to fetch ${scheduleURL}: ${schedule.status}: ${schedule.statusText}`); - process.exit(-1); -} -const scheduleText = await schedule.text(); -const nssReleases = getReleases(scheduleText); - +const firefoxRelease = await getFirefoxRelease(positionals[0]); // Retrieve metadata for the NSS release being updated to. -const version = positionals[0] ?? await getLatestVersion(nssReleases); -const release = nssReleases.find((r) => { - return new RegExp(`^${version.replace('.', '\\.')}\\b`).test(r[kNSSVersion]); -}); -if (!pastRelease(release)) { - console.warn(`Warning: NSS ${version} is not due to be released until ${formatDate(release[kNSSDate])}`); -} +const version = await getNSSVersion(firefoxRelease); if (values.verbose) { - console.log('Found NSS version:'); - console.log(release); + console.log(`Updating to NSS version ${version}`); } // Fetch certdata.txt and overwrite the local copy. @@ -213,14 +164,15 @@ const added = [ ...diff.matchAll(certsAddedRE) ].map((m) => m[1]); const removed = [ ...diff.matchAll(certsRemovedRE) ].map((m) => m[1]); const commitMsg = [ - `crypto: update root certificates to NSS ${release[kNSSVersion]}`, + `crypto: update root certificates to NSS ${version}`, '', - `This is the certdata.txt[0] from NSS ${release[kNSSVersion]}, released on ${formatDate(release[kNSSDate])}.`, - '', - `This is the version of NSS that ${release[kFirefoxDate] < now ? 'shipped' : 'will ship'} in Firefox ${release[kFirefoxVersion]} on`, - `${formatDate(release[kFirefoxDate])}.`, + `This is the certdata.txt[0] from NSS ${version}.`, '', ]; +if (firefoxRelease) { + commitMsg.push(`This is the version of NSS that shipped in Firefox ${firefoxRelease.version} on ${firefoxRelease.release_date}.`); + commitMsg.push(''); +} if (added.length > 0) { commitMsg.push('Certificates added:'); commitMsg.push(...added.map((cert) => `- ${cert}`)); @@ -234,7 +186,7 @@ if (removed.length > 0) { commitMsg.push(`[0] ${certdataURL}`); const delimiter = randomUUID(); const properties = [ - `NEW_VERSION=${release[kNSSVersion]}`, + `NEW_VERSION=${version}`, `COMMIT_MSG<<${delimiter}`, ...commitMsg, delimiter, From 535f1b0d4c0a483457da7a598d34afaf7747a897 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Fri, 1 Nov 2024 17:53:50 +0000 Subject: [PATCH 72/93] crypto: update root certificates to NSS 3.104 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the certdata.txt[0] from NSS 3.104. This is the version of NSS that shipped in Firefox 131.0 on 2024-10-01. Certificates added: - FIRMAPROFESIONAL CA ROOT-A WEB - TWCA CYBER Root CA - SecureSign Root CA12 - SecureSign Root CA14 - SecureSign Root CA15 [0] https://raw.githubusercontent.com/nss-dev/nss/refs/tags/NSS_3_104_RTM/lib/ckfw/builtins/certdata.txt PR-URL: https://github.com/nodejs/node/pull/55681 Reviewed-By: Luigi Pinca Reviewed-By: Michaël Zasso Reviewed-By: Rafael Gonzaga --- src/node_root_certs.h | 113 ++++++ tools/certdata.txt | 896 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 1005 insertions(+), 4 deletions(-) diff --git a/src/node_root_certs.h b/src/node_root_certs.h index 93af565fbc1add..2c8670be39e586 100644 --- a/src/node_root_certs.h +++ b/src/node_root_certs.h @@ -3571,4 +3571,117 @@ "4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bM\n" "NSWSs1A=\n" "-----END CERTIFICATE-----", + +/* FIRMAPROFESIONAL CA ROOT-A WEB */ +"-----BEGIN CERTIFICATE-----\n" +"MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQG\n" +"EwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYy\n" +"NjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIw\n" +"NDA2MDkwMTM2WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmly\n" +"bWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5G\n" +"SVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARH\n" +"U+osEaR3xyrq89Zfe9MEkVz6iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K\n" +"6k84Si6CcyvHZpsKjECcfIr28jlgst7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB\n" +"/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FDY1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPh\n" +"Q2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAd\n" +"fKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFwhVmpHqTm6iMxoAACMQD94viz\n" +"rxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQpYXFuXqUPoeovQA=\n" +"-----END CERTIFICATE-----", + +/* TWCA CYBER Root CA */ +"-----BEGIN CERTIFICATE-----\n" +"MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYD\n" +"VQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQD\n" +"ExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQ\n" +"MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRsw\n" +"GQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\n" +"AoICAQDG+Moe2Qkgfh1sTs6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33\n" +"Kc7wb3+szT3vsxxFavcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYd\n" +"HNWdZsc/34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i\n" +"JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjp\n" +"Ji+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY55\n" +"83WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP2oi3aQiotyMuRAlZN1vH4xfy\n" +"IutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZ\n" +"QXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff\n" +"+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0Ja\n" +"WHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMC\n" +"AQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd\n" +"BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIBAGSPesRi\n" +"DrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olNc79p\n" +"j3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x\n" +"X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o63\n" +"5yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1J\n" +"SdJlBTrq/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4\n" +"iuO/Qq+n1M0RFxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY\n" +"73NxW0Qz8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4\n" +"NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrr\n" +"uoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0Be\n" +"Jsas7a5wFsWqynKKTbDPAYsDP27X\n" +"-----END CERTIFICATE-----", + +/* SecureSign Root CA12 */ +"-----BEGIN CERTIFICATE-----\n" +"MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTEL\n" +"MAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYD\n" +"VQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2\n" +"NDZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRk\n" +"LjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" +"DwAwggEKAoIBAQC6OcE3emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048\n" +"luT9Ub+ZyZN+v/mtp7JIKwccJ/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPj\n" +"cf59q5zdJ1M3s6oYwlkm7Fsf0uZlfO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gur\n" +"FzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBFEaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5P\n" +"ro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1UefNzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMB\n" +"AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0\n" +"zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOCAQEAPrvbFxbS8hQBICw4g0utvsqF\n" +"epq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQiLUoT865AQ9tPkbeGGuwAtEGB\n" +"pE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBo\n" +"uVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7\n" +"bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/\n" +"yOPiZwud9AzqVN/Ssq+xIvEg37xEHA==\n" +"-----END CERTIFICATE-----", + +/* SecureSign Root CA14 */ +"-----BEGIN CERTIFICATE-----\n" +"MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTEL\n" +"MAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYD\n" +"VQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2\n" +"MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRk\n" +"LjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4IC\n" +"DwAwggIKAoICAQDF0nqh1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG\n" +"3rdSINVSW0KZnvOgvlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6Kx\n" +"NedlsmGy6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo\n" +"/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn9\n" +"0Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbpra\n" +"fZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH\n" +"064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18izju3Gm5h1DVXoX+WViwKkrkMpKBGk\n" +"5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6e\n" +"VL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt\n" +"33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMB\n" +"Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk\n" +"86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0ErX+lRVAQ\n" +"Zk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoAymzv\n" +"ftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds\n" +"Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPj\n" +"YYPGFrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHV\n" +"dqqGuw6qnsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI\n" +"2i/6GaX7i+B/OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDe\n" +"M9ovnhp6dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl\n" +"Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6Ue\n" +"To3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S\n" +"-----END CERTIFICATE-----", + +/* SecureSign Root CA15 */ +"-----BEGIN CERTIFICATE-----\n" +"MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkG\n" +"A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQD\n" +"ExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZa\n" +"MFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEd\n" +"MBsGA1UEAxMUU2VjdXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQL\n" +"UHSNZDKZmbPSYAi4Io5GdCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq\n" +"8bOLbe1PL0vJSpSRZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB\n" +"/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT\n" +"9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO\n" +"4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr\n" +"62Nuk22rGwlgMU4=\n" +"-----END CERTIFICATE-----", #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/tools/certdata.txt b/tools/certdata.txt index ed5e6cb17cab57..110a814718cfd7 100644 --- a/tools/certdata.txt +++ b/tools/certdata.txt @@ -3645,7 +3645,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\006\040\006\005\026\160\002 END CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE @@ -7252,7 +7252,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL \002\010\136\303\267\246\103\177\244\340 END CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE @@ -17020,8 +17020,14 @@ CKA_VALUE MULTILINE_OCTAL \155\015\277\173\327\222 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE -CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE -CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE +# For Server Distrust After: Sun Jun 30 00:00:00 2024 +CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL +\062\064\060\066\063\060\060\060\060\060\060\060\132 +END +# For Email Distrust After: Sun Jun 30 00:00:00 2024 +CKA_NSS_EMAIL_DISTRUST_AFTER MULTILINE_OCTAL +\062\064\060\066\063\060\060\060\060\060\060\060\132 +END # Trust for "GLOBALTRUST 2020" # Issuer: CN=GLOBALTRUST 2020,O=e-commerce monitoring GmbH,C=AT @@ -25359,3 +25365,885 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "FIRMAPROFESIONAL CA ROOT-A WEB" +# +# Issuer: CN=FIRMAPROFESIONAL CA ROOT-A WEB,OID.2.5.4.97=VATES-A62634068,O=Firmaprofesional SA,C=ES +# Serial Number:31:97:21:ed:af:89:42:7f:35:41:87:a1:67:56:4c:6d +# Subject: CN=FIRMAPROFESIONAL CA ROOT-A WEB,OID.2.5.4.97=VATES-A62634068,O=Firmaprofesional SA,C=ES +# Not Valid Before: Wed Apr 06 09:01:36 2022 +# Not Valid After : Sun Mar 31 09:01:36 2047 +# Fingerprint (SHA-256): BE:F2:56:DA:F2:6E:9C:69:BD:EC:16:02:35:97:98:F3:CA:F7:18:21:A0:3E:01:82:57:C5:3C:65:61:7F:3D:4A +# Fingerprint (SHA1): A8:31:11:74:A6:14:15:0D:CA:77:DD:0E:E4:0C:5D:58:FC:A0:72:A5 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "FIRMAPROFESIONAL CA ROOT-A WEB" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\156\061\013\060\011\006\003\125\004\006\023\002\105\123\061 +\034\060\032\006\003\125\004\012\014\023\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\123\101\061\030\060 +\026\006\003\125\004\141\014\017\126\101\124\105\123\055\101\066 +\062\066\063\064\060\066\070\061\047\060\045\006\003\125\004\003 +\014\036\106\111\122\115\101\120\122\117\106\105\123\111\117\116 +\101\114\040\103\101\040\122\117\117\124\055\101\040\127\105\102 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\156\061\013\060\011\006\003\125\004\006\023\002\105\123\061 +\034\060\032\006\003\125\004\012\014\023\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\123\101\061\030\060 +\026\006\003\125\004\141\014\017\126\101\124\105\123\055\101\066 +\062\066\063\064\060\066\070\061\047\060\045\006\003\125\004\003 +\014\036\106\111\122\115\101\120\122\117\106\105\123\111\117\116 +\101\114\040\103\101\040\122\117\117\124\055\101\040\127\105\102 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\061\227\041\355\257\211\102\177\065\101\207\241\147\126 +\114\155 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\002\172\060\202\002\000\240\003\002\001\002\002\020\061 +\227\041\355\257\211\102\177\065\101\207\241\147\126\114\155\060 +\012\006\010\052\206\110\316\075\004\003\003\060\156\061\013\060 +\011\006\003\125\004\006\023\002\105\123\061\034\060\032\006\003 +\125\004\012\014\023\106\151\162\155\141\160\162\157\146\145\163 +\151\157\156\141\154\040\123\101\061\030\060\026\006\003\125\004 +\141\014\017\126\101\124\105\123\055\101\066\062\066\063\064\060 +\066\070\061\047\060\045\006\003\125\004\003\014\036\106\111\122 +\115\101\120\122\117\106\105\123\111\117\116\101\114\040\103\101 +\040\122\117\117\124\055\101\040\127\105\102\060\036\027\015\062 +\062\060\064\060\066\060\071\060\061\063\066\132\027\015\064\067 +\060\063\063\061\060\071\060\061\063\066\132\060\156\061\013\060 +\011\006\003\125\004\006\023\002\105\123\061\034\060\032\006\003 +\125\004\012\014\023\106\151\162\155\141\160\162\157\146\145\163 +\151\157\156\141\154\040\123\101\061\030\060\026\006\003\125\004 +\141\014\017\126\101\124\105\123\055\101\066\062\066\063\064\060 +\066\070\061\047\060\045\006\003\125\004\003\014\036\106\111\122 +\115\101\120\122\117\106\105\123\111\117\116\101\114\040\103\101 +\040\122\117\117\124\055\101\040\127\105\102\060\166\060\020\006 +\007\052\206\110\316\075\002\001\006\005\053\201\004\000\042\003 +\142\000\004\107\123\352\054\021\244\167\307\052\352\363\326\137 +\173\323\004\221\134\372\210\306\042\271\203\020\142\167\204\063 +\055\351\003\210\324\340\063\367\355\167\054\112\140\352\344\157 +\255\155\264\370\114\212\244\344\037\312\352\117\070\112\056\202 +\163\053\307\146\233\012\214\100\234\174\212\366\362\071\140\262 +\336\313\354\270\344\157\352\233\135\267\123\220\030\062\125\305 +\040\267\224\243\143\060\141\060\017\006\003\125\035\023\001\001 +\377\004\005\060\003\001\001\377\060\037\006\003\125\035\043\004 +\030\060\026\200\024\223\341\103\143\134\074\235\326\047\363\122 +\354\027\262\251\257\054\367\166\370\060\035\006\003\125\035\016 +\004\026\004\024\223\341\103\143\134\074\235\326\047\363\122\354 +\027\262\251\257\054\367\166\370\060\016\006\003\125\035\017\001 +\001\377\004\004\003\002\001\006\060\012\006\010\052\206\110\316 +\075\004\003\003\003\150\000\060\145\002\060\035\174\244\173\303 +\211\165\063\341\073\251\105\277\106\351\351\241\335\311\042\026 +\267\107\021\013\330\232\272\361\310\013\160\120\123\002\221\160 +\205\131\251\036\244\346\352\043\061\240\000\002\061\000\375\342 +\370\263\257\026\271\036\163\304\226\343\301\060\031\330\176\346 +\303\227\336\034\117\270\211\057\063\353\110\017\031\367\207\106 +\135\046\220\245\205\305\271\172\224\076\207\250\275\000 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE + +# Trust for "FIRMAPROFESIONAL CA ROOT-A WEB" +# Issuer: CN=FIRMAPROFESIONAL CA ROOT-A WEB,OID.2.5.4.97=VATES-A62634068,O=Firmaprofesional SA,C=ES +# Serial Number:31:97:21:ed:af:89:42:7f:35:41:87:a1:67:56:4c:6d +# Subject: CN=FIRMAPROFESIONAL CA ROOT-A WEB,OID.2.5.4.97=VATES-A62634068,O=Firmaprofesional SA,C=ES +# Not Valid Before: Wed Apr 06 09:01:36 2022 +# Not Valid After : Sun Mar 31 09:01:36 2047 +# Fingerprint (SHA-256): BE:F2:56:DA:F2:6E:9C:69:BD:EC:16:02:35:97:98:F3:CA:F7:18:21:A0:3E:01:82:57:C5:3C:65:61:7F:3D:4A +# Fingerprint (SHA1): A8:31:11:74:A6:14:15:0D:CA:77:DD:0E:E4:0C:5D:58:FC:A0:72:A5 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "FIRMAPROFESIONAL CA ROOT-A WEB" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\250\061\021\164\246\024\025\015\312\167\335\016\344\014\135\130 +\374\240\162\245 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\202\262\255\105\000\202\260\146\143\370\137\303\147\116\316\243 +END +CKA_ISSUER MULTILINE_OCTAL +\060\156\061\013\060\011\006\003\125\004\006\023\002\105\123\061 +\034\060\032\006\003\125\004\012\014\023\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\123\101\061\030\060 +\026\006\003\125\004\141\014\017\126\101\124\105\123\055\101\066 +\062\066\063\064\060\066\070\061\047\060\045\006\003\125\004\003 +\014\036\106\111\122\115\101\120\122\117\106\105\123\111\117\116 +\101\114\040\103\101\040\122\117\117\124\055\101\040\127\105\102 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\061\227\041\355\257\211\102\177\065\101\207\241\147\126 +\114\155 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "TWCA CYBER Root CA" +# +# Issuer: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW +# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:3c:f2:c6 +# Subject: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW +# Not Valid Before: Tue Nov 22 06:54:29 2022 +# Not Valid After : Fri Nov 22 15:59:59 2047 +# Fingerprint (SHA-256): 3F:63:BB:28:14:BE:17:4E:C8:B6:43:9C:F0:8D:6D:56:F0:B7:C4:05:88:3A:56:48:A3:34:42:4D:6B:3E:C5:58 +# Fingerprint (SHA1): F6:B1:1C:1A:83:38:E9:7B:DB:B3:A8:C8:33:24:E0:2D:9C:7F:26:66 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "TWCA CYBER Root CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116 +\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157 +\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022 +\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040 +\103\101 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116 +\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157 +\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022 +\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040 +\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\074 +\362\306 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\215\060\202\003\165\240\003\002\001\002\002\020\100 +\001\064\214\302\000\000\000\000\000\000\000\001\074\362\306\060 +\015\006\011\052\206\110\206\367\015\001\001\014\005\000\060\120 +\061\013\060\011\006\003\125\004\006\023\002\124\127\061\022\060 +\020\006\003\125\004\012\023\011\124\101\111\127\101\116\055\103 +\101\061\020\060\016\006\003\125\004\013\023\007\122\157\157\164 +\040\103\101\061\033\060\031\006\003\125\004\003\023\022\124\127 +\103\101\040\103\131\102\105\122\040\122\157\157\164\040\103\101 +\060\036\027\015\062\062\061\061\062\062\060\066\065\064\062\071 +\132\027\015\064\067\061\061\062\062\061\065\065\071\065\071\132 +\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116 +\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157 +\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022 +\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040 +\103\101\060\202\002\042\060\015\006\011\052\206\110\206\367\015 +\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202 +\002\001\000\306\370\312\036\331\011\040\176\035\154\116\316\217 +\343\107\063\104\234\307\311\151\252\072\133\170\356\160\322\222 +\370\004\263\122\122\035\147\162\050\241\337\213\135\225\012\376 +\352\315\355\367\051\316\360\157\177\254\315\075\357\263\034\105 +\152\367\050\220\361\141\127\305\014\304\243\120\135\336\324\265 +\313\031\312\200\271\165\316\051\316\322\205\042\354\002\143\314 +\104\060\040\332\352\221\133\126\346\035\034\325\235\146\307\077 +\337\206\312\113\123\304\331\215\262\035\352\370\334\047\123\243 +\107\341\141\314\175\265\260\370\356\163\221\305\316\163\157\316 +\356\020\037\032\006\317\351\047\140\305\117\031\344\353\316\042 +\046\105\327\140\231\335\316\117\067\340\177\347\143\255\260\270 +\131\270\320\006\150\065\140\323\066\256\161\103\004\361\151\145 +\170\174\363\037\363\312\050\237\132\040\225\146\264\315\267\356 +\217\170\244\105\030\351\046\057\215\233\051\050\261\244\267\072 +\155\271\324\034\070\162\105\130\261\136\353\360\050\233\267\202 +\312\375\317\326\063\017\237\373\227\236\261\034\234\236\352\137 +\136\333\252\335\124\351\060\041\050\155\216\171\363\165\222\214 +\046\376\334\305\366\303\260\337\104\131\103\243\266\003\050\366 +\010\060\252\015\063\341\357\234\251\007\042\343\131\133\100\217 +\332\210\267\151\010\250\267\043\056\104\011\131\067\133\307\343 +\027\362\042\353\156\071\122\305\336\124\247\230\311\113\040\225 +\334\106\211\137\264\022\371\205\051\216\353\310\047\025\040\300 +\113\324\314\174\014\154\064\014\046\233\046\061\246\074\247\366 +\331\320\113\242\144\377\073\231\101\162\301\340\160\227\361\044 +\273\053\304\164\042\261\254\153\042\062\044\323\170\052\300\300 +\241\057\361\122\005\311\077\357\166\146\342\105\330\015\075\255 +\225\310\307\211\046\310\017\256\247\003\056\373\301\137\372\040 +\341\160\255\260\145\040\067\063\140\260\325\257\327\014\034\302 +\220\160\327\112\030\274\176\001\260\260\353\025\036\104\006\315 +\244\117\350\014\321\303\040\020\341\124\145\236\266\121\320\032 +\166\153\102\132\130\166\064\352\267\067\031\256\056\165\371\226 +\345\301\131\367\224\127\051\045\215\072\114\253\115\232\101\320 +\137\046\003\002\003\001\000\001\243\143\060\141\060\016\006\003 +\125\035\017\001\001\377\004\004\003\002\001\006\060\017\006\003 +\125\035\023\001\001\377\004\005\060\003\001\001\377\060\037\006 +\003\125\035\043\004\030\060\026\200\024\235\205\141\024\174\301 +\142\157\227\150\344\117\067\100\341\255\340\015\126\067\060\035 +\006\003\125\035\016\004\026\004\024\235\205\141\024\174\301\142 +\157\227\150\344\117\067\100\341\255\340\015\126\067\060\015\006 +\011\052\206\110\206\367\015\001\001\014\005\000\003\202\002\001 +\000\144\217\172\304\142\016\265\210\314\270\307\206\016\241\112 +\026\315\160\013\267\247\205\013\263\166\266\017\247\377\010\213 +\013\045\317\250\324\203\165\052\270\226\210\266\373\337\055\055 +\264\151\123\041\065\127\326\211\115\163\277\151\217\160\243\141 +\314\232\333\036\232\340\040\370\154\273\233\042\235\135\204\061 +\232\054\212\335\152\241\327\050\151\312\376\166\125\172\106\147 +\353\314\103\210\026\242\003\326\271\027\370\031\154\155\043\002 +\177\361\137\320\012\051\043\073\321\252\012\355\251\027\046\124 +\012\115\302\245\115\370\305\375\270\201\317\053\054\170\243\147 +\114\251\007\232\363\337\136\373\174\365\211\315\164\227\141\020 +\152\007\053\201\132\322\216\267\347\040\321\040\156\044\250\204 +\047\241\127\254\252\125\130\057\334\331\312\372\150\004\236\355 +\104\044\371\164\100\073\043\063\253\203\132\030\046\102\266\155 +\124\265\026\140\060\154\261\240\370\270\101\240\135\111\111\322 +\145\005\072\352\376\235\141\274\206\331\277\336\323\272\072\261 +\177\176\222\064\216\311\000\156\334\230\275\334\354\200\005\255 +\002\075\337\145\355\013\003\367\367\026\204\004\061\272\223\224 +\330\362\022\370\212\343\277\102\257\247\324\315\021\027\026\310 +\102\035\024\250\102\366\322\100\206\240\117\043\312\226\105\126 +\140\006\315\267\125\001\246\001\224\145\376\156\005\011\272\264 +\244\252\342\357\130\276\275\047\126\330\357\163\161\133\104\063 +\362\232\162\352\260\136\076\156\251\122\133\354\160\155\265\207 +\217\067\136\074\214\234\316\344\360\316\014\147\101\314\316\366 +\200\253\116\314\114\126\365\301\141\131\223\264\076\246\332\270 +\067\022\237\052\062\343\213\270\041\354\303\053\145\014\357\042 +\336\210\051\073\114\327\372\376\267\341\107\276\234\076\076\203 +\373\121\135\365\150\367\056\041\205\334\277\361\132\342\174\327 +\305\344\203\301\152\353\272\200\132\336\134\055\160\166\370\310 +\345\207\207\312\240\235\241\345\042\022\047\017\104\075\035\154 +\352\324\302\213\057\157\171\253\177\120\246\304\031\247\241\172 +\267\226\371\301\037\142\132\242\103\007\100\136\046\306\254\355 +\256\160\026\305\252\312\162\212\115\260\317\001\213\003\077\156 +\327 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE + +# Trust for "TWCA CYBER Root CA" +# Issuer: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW +# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:3c:f2:c6 +# Subject: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW +# Not Valid Before: Tue Nov 22 06:54:29 2022 +# Not Valid After : Fri Nov 22 15:59:59 2047 +# Fingerprint (SHA-256): 3F:63:BB:28:14:BE:17:4E:C8:B6:43:9C:F0:8D:6D:56:F0:B7:C4:05:88:3A:56:48:A3:34:42:4D:6B:3E:C5:58 +# Fingerprint (SHA1): F6:B1:1C:1A:83:38:E9:7B:DB:B3:A8:C8:33:24:E0:2D:9C:7F:26:66 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "TWCA CYBER Root CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\366\261\034\032\203\070\351\173\333\263\250\310\063\044\340\055 +\234\177\046\146 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\013\063\240\227\122\225\324\251\375\273\333\156\243\125\133\121 +END +CKA_ISSUER MULTILINE_OCTAL +\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116 +\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157 +\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022 +\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040 +\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\074 +\362\306 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "TWCA Global Root CA G2" +# +# Issuer: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW +# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:97:58:f4 +# Subject: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW +# Not Valid Before: Tue Nov 22 06:42:21 2022 +# Not Valid After : Fri Nov 22 15:59:59 2047 +# Fingerprint (SHA-256): 3A:00:72:D4:9F:FC:04:E9:96:C5:9A:EB:75:99:1D:3C:34:0F:36:15:D6:FD:4D:CE:90:AC:0B:3D:88:EA:D4:F4 +# Fingerprint (SHA1): 73:FE:92:2F:83:63:91:FF:C8:C6:C4:DA:D6:20:2F:6B:07:2E:7F:1B +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "TWCA Global Root CA G2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\124\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116 +\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157 +\157\164\040\103\101\061\037\060\035\006\003\125\004\003\023\026 +\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164 +\040\103\101\040\107\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\124\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116 +\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157 +\157\164\040\103\101\061\037\060\035\006\003\125\004\003\023\026 +\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164 +\040\103\101\040\107\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\227 +\130\364 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\225\060\202\003\175\240\003\002\001\002\002\020\100 +\001\064\214\302\000\000\000\000\000\000\000\001\227\130\364\060 +\015\006\011\052\206\110\206\367\015\001\001\014\005\000\060\124 +\061\013\060\011\006\003\125\004\006\023\002\124\127\061\022\060 +\020\006\003\125\004\012\023\011\124\101\111\127\101\116\055\103 +\101\061\020\060\016\006\003\125\004\013\023\007\122\157\157\164 +\040\103\101\061\037\060\035\006\003\125\004\003\023\026\124\127 +\103\101\040\107\154\157\142\141\154\040\122\157\157\164\040\103 +\101\040\107\062\060\036\027\015\062\062\061\061\062\062\060\066 +\064\062\062\061\132\027\015\064\067\061\061\062\062\061\065\065 +\071\065\071\132\060\124\061\013\060\011\006\003\125\004\006\023 +\002\124\127\061\022\060\020\006\003\125\004\012\023\011\124\101 +\111\127\101\116\055\103\101\061\020\060\016\006\003\125\004\013 +\023\007\122\157\157\164\040\103\101\061\037\060\035\006\003\125 +\004\003\023\026\124\127\103\101\040\107\154\157\142\141\154\040 +\122\157\157\164\040\103\101\040\107\062\060\202\002\042\060\015 +\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 +\017\000\060\202\002\012\002\202\002\001\000\252\016\325\040\222 +\001\255\202\371\014\010\221\064\153\212\026\320\106\026\377\003 +\270\330\215\352\223\064\373\377\053\275\375\156\252\334\233\362 +\206\201\125\365\211\034\304\215\165\152\130\170\221\023\036\002 +\023\160\075\357\276\012\347\000\217\270\061\345\164\305\060\276 +\377\175\326\231\345\302\102\243\317\041\326\263\010\177\221\325 +\141\346\242\225\020\015\357\136\227\013\111\070\325\042\260\327 +\213\131\157\237\065\233\177\322\221\314\172\177\273\240\237\336 +\125\063\366\113\215\012\352\175\011\300\171\334\275\104\342\376 +\034\347\144\041\050\317\004\112\342\264\277\206\171\052\273\016 +\223\311\217\136\254\060\071\122\220\007\271\352\234\046\102\024 +\304\147\106\376\321\032\150\241\076\120\031\243\046\012\047\051 +\220\302\366\264\353\163\232\170\036\341\230\364\145\014\065\041 +\006\370\013\336\142\345\115\301\263\135\331\271\372\141\227\052 +\343\352\307\104\125\044\222\376\022\247\077\304\167\340\055\002 +\201\007\325\373\175\346\020\236\072\264\250\357\354\373\120\352 +\065\317\314\176\273\102\271\104\154\122\351\277\052\162\037\077 +\336\233\160\351\334\132\305\073\273\277\360\131\205\257\057\301 +\260\024\171\005\254\165\237\045\365\021\047\006\140\041\307\155 +\145\276\250\211\234\345\254\106\337\370\135\104\003\215\140\275 +\367\261\015\314\057\357\101\124\057\356\153\225\271\116\174\064 +\337\073\371\167\235\175\315\007\075\034\006\063\022\200\354\162 +\234\362\055\202\332\325\073\304\307\371\004\303\144\002\174\365 +\065\140\247\264\106\051\056\033\357\245\130\200\056\172\211\121 +\070\066\074\375\241\167\270\200\060\320\212\336\215\247\064\046 +\354\043\273\030\125\030\066\105\356\355\001\006\252\115\277\144 +\014\312\230\227\032\061\002\146\370\170\150\133\210\337\011\250 +\347\233\372\064\155\160\034\041\255\010\213\362\241\266\254\166 +\152\277\361\200\045\000\276\074\036\115\256\271\074\266\225\143 +\275\153\176\107\022\220\125\105\021\215\354\027\037\301\276\047 +\201\223\127\143\151\000\046\167\213\303\131\345\173\321\015\104 +\362\250\360\367\205\232\005\367\302\056\160\232\223\205\330\225 +\220\061\220\124\246\354\013\237\067\105\017\002\003\001\000\001 +\243\143\060\141\060\016\006\003\125\035\017\001\001\377\004\004 +\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005 +\060\003\001\001\377\060\037\006\003\125\035\043\004\030\060\026 +\200\024\222\214\324\066\321\133\107\123\304\161\015\204\335\144 +\052\365\066\144\100\347\060\035\006\003\125\035\016\004\026\004 +\024\222\214\324\066\321\133\107\123\304\161\015\204\335\144\052 +\365\066\144\100\347\060\015\006\011\052\206\110\206\367\015\001 +\001\014\005\000\003\202\002\001\000\045\374\113\332\220\264\332 +\165\347\101\072\201\321\246\376\240\152\363\030\161\142\152\044 +\010\213\251\172\115\311\125\316\317\020\050\056\004\031\226\005 +\317\135\002\040\052\073\263\125\077\001\315\102\315\262\167\355 +\377\165\363\174\167\333\226\245\317\214\147\006\364\244\233\162 +\366\041\111\011\230\243\062\136\167\132\143\011\357\142\103\227 +\002\070\265\352\074\030\120\150\374\131\133\331\171\324\361\344 +\126\110\023\126\330\323\161\013\136\170\224\070\021\105\372\005 +\027\365\016\165\036\142\122\141\106\272\056\031\255\206\264\210 +\017\261\120\346\100\000\064\032\225\235\223\340\121\371\324\125 +\106\351\225\074\045\206\056\227\327\001\061\030\104\354\034\140 +\351\175\151\257\062\370\227\100\045\044\266\215\032\125\074\305 +\267\367\274\006\122\073\161\060\160\076\161\027\176\361\146\004 +\136\135\274\212\061\103\246\222\035\173\124\322\245\066\213\157 +\215\326\136\332\324\303\056\035\337\071\125\140\202\060\236\047 +\377\216\200\335\143\114\246\125\065\330\320\063\251\200\155\076 +\136\235\314\250\147\200\146\372\231\127\014\122\312\031\165\260 +\070\065\125\052\201\305\214\036\126\327\137\220\362\040\330\332 +\340\146\161\351\262\170\253\147\271\044\156\153\066\162\374\157 +\215\375\177\162\071\050\147\122\221\005\037\127\145\322\243\247 +\015\141\372\241\347\325\065\106\225\311\006\207\366\060\354\062 +\121\251\254\126\300\041\116\243\024\164\005\072\274\343\277\155 +\075\116\077\136\245\244\155\051\277\204\121\165\123\216\206\032 +\365\121\160\052\015\034\116\100\341\375\243\343\245\053\147\220 +\222\307\154\256\205\277\072\233\027\025\312\234\052\223\324\115 +\071\015\274\040\010\243\215\210\154\011\015\214\256\104\041\115 +\311\161\354\330\046\327\027\236\055\021\030\074\243\042\175\270 +\047\124\277\150\310\073\102\314\217\136\116\347\334\302\305\372 +\152\104\017\215\126\210\172\337\211\204\154\240\263\076\075\361 +\145\000\011\210\352\052\353\100\316\263\135\254\062\027\256\301 +\233\351\320\301\365\111\224\335\247\316\174\132\007\353\256\040 +\234\027\060\222\151\223\162\363\232\133\161\233\376\152\337\172 +\060\151\216\263\056\333\017\054\335 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE + +# Trust for "TWCA Global Root CA G2" +# Issuer: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW +# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:97:58:f4 +# Subject: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW +# Not Valid Before: Tue Nov 22 06:42:21 2022 +# Not Valid After : Fri Nov 22 15:59:59 2047 +# Fingerprint (SHA-256): 3A:00:72:D4:9F:FC:04:E9:96:C5:9A:EB:75:99:1D:3C:34:0F:36:15:D6:FD:4D:CE:90:AC:0B:3D:88:EA:D4:F4 +# Fingerprint (SHA1): 73:FE:92:2F:83:63:91:FF:C8:C6:C4:DA:D6:20:2F:6B:07:2E:7F:1B +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "TWCA Global Root CA G2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\163\376\222\057\203\143\221\377\310\306\304\332\326\040\057\153 +\007\056\177\033 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\023\215\135\372\031\265\346\253\144\173\020\164\160\032\043\056 +END +CKA_ISSUER MULTILINE_OCTAL +\060\124\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116 +\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157 +\157\164\040\103\101\061\037\060\035\006\003\125\004\003\023\026 +\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164 +\040\103\101\040\107\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\227 +\130\364 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "SecureSign Root CA12" +# +# Issuer: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP +# Serial Number:66:f9:c7:c1:af:ec:c2:51:b4:ed:53:97:e6:e6:82:c3:2b:1c:90:16 +# Subject: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP +# Not Valid Before: Wed Apr 08 05:36:46 2020 +# Not Valid After : Sun Apr 08 05:36:46 2040 +# Fingerprint (SHA-256): 3F:03:4B:B5:70:4D:44:B2:D0:85:45:A0:20:57:DE:93:EB:F3:90:5F:CE:72:1A:CB:C7:30:C0:6D:DA:EE:90:4E +# Fingerprint (SHA1): 7A:22:1E:3D:DE:1B:06:AC:9E:C8:47:70:16:8E:3C:E5:F7:6B:06:F4 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "SecureSign Root CA12" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\024\146\371\307\301\257\354\302\121\264\355\123\227\346\346 +\202\303\053\034\220\026 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\003\162\060\202\002\132\240\003\002\001\002\002\024\146 +\371\307\301\257\354\302\121\264\355\123\227\346\346\202\303\053 +\034\220\026\060\015\006\011\052\206\110\206\367\015\001\001\013 +\005\000\060\121\061\013\060\011\006\003\125\004\006\023\002\112 +\120\061\043\060\041\006\003\125\004\012\023\032\103\171\142\145 +\162\164\162\165\163\164\040\112\141\160\141\156\040\103\157\056 +\054\040\114\164\144\056\061\035\060\033\006\003\125\004\003\023 +\024\123\145\143\165\162\145\123\151\147\156\040\122\157\157\164 +\040\103\101\061\062\060\036\027\015\062\060\060\064\060\070\060 +\065\063\066\064\066\132\027\015\064\060\060\064\060\070\060\065 +\063\066\064\066\132\060\121\061\013\060\011\006\003\125\004\006 +\023\002\112\120\061\043\060\041\006\003\125\004\012\023\032\103 +\171\142\145\162\164\162\165\163\164\040\112\141\160\141\156\040 +\103\157\056\054\040\114\164\144\056\061\035\060\033\006\003\125 +\004\003\023\024\123\145\143\165\162\145\123\151\147\156\040\122 +\157\157\164\040\103\101\061\062\060\202\001\042\060\015\006\011 +\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000 +\060\202\001\012\002\202\001\001\000\272\071\301\067\172\150\105 +\053\024\264\353\344\023\353\127\165\043\115\217\044\055\026\350 +\256\216\311\175\244\127\073\052\166\045\063\203\154\352\062\212 +\224\233\116\074\226\344\375\121\277\231\311\223\176\277\371\255 +\247\262\110\053\007\034\047\365\114\274\160\022\167\244\205\124 +\265\375\220\172\344\243\344\121\130\003\315\020\171\171\356\153 +\223\037\144\216\153\144\253\243\023\343\161\376\175\253\234\335 +\047\123\067\263\252\030\302\131\046\354\133\037\322\346\145\174 +\357\223\275\330\130\134\013\300\343\145\157\074\307\312\131\343 +\376\156\137\254\203\276\375\135\045\116\052\051\073\326\013\253 +\027\062\170\244\341\076\224\106\276\142\156\233\336\106\250\261 +\026\347\205\156\364\010\100\105\021\240\236\124\104\204\367\330 +\066\316\365\120\107\334\054\060\233\356\300\365\226\322\376\011 +\206\307\006\131\256\117\256\216\021\230\173\363\013\122\252\142 +\046\252\041\337\216\045\063\171\227\026\111\215\365\076\325\107 +\237\067\061\111\063\162\005\115\014\266\125\214\361\127\217\212 +\207\321\255\305\021\022\071\240\255\002\003\001\000\001\243\102 +\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060\003 +\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003 +\002\001\006\060\035\006\003\125\035\016\004\026\004\024\127\064 +\363\164\317\004\113\325\045\346\361\100\266\054\114\331\055\351 +\240\255\060\015\006\011\052\206\110\206\367\015\001\001\013\005 +\000\003\202\001\001\000\076\273\333\027\026\322\362\024\001\040 +\054\070\203\113\255\276\312\205\172\232\266\233\153\246\341\374 +\245\072\254\255\264\050\072\257\327\001\203\111\053\143\242\335 +\232\144\016\230\134\157\335\216\273\212\124\042\055\112\023\363 +\256\100\103\333\117\221\267\206\032\354\000\264\101\201\244\117 +\372\152\213\210\263\166\010\162\052\111\100\303\323\303\205\211 +\230\020\245\235\157\031\267\273\317\172\145\125\333\067\353\074 +\212\162\062\227\036\232\051\076\255\215\346\243\033\155\365\165 +\032\346\260\150\271\133\242\356\151\107\047\065\241\206\231\200 +\363\063\113\341\153\244\046\303\357\164\131\154\172\242\144\266 +\036\104\303\120\340\017\071\075\251\063\361\245\363\322\275\142 +\204\254\216\034\251\315\132\275\067\073\156\012\042\264\364\025 +\347\221\130\305\072\104\323\225\050\331\300\145\351\162\312\320 +\017\275\037\263\025\331\251\343\244\107\011\236\340\313\067\373 +\375\275\227\325\276\030\032\151\242\071\201\331\032\365\253\177 +\310\343\342\147\013\235\364\014\352\124\337\322\262\257\261\042 +\361\040\337\274\104\034 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE + +# Trust for "SecureSign Root CA12" +# Issuer: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP +# Serial Number:66:f9:c7:c1:af:ec:c2:51:b4:ed:53:97:e6:e6:82:c3:2b:1c:90:16 +# Subject: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP +# Not Valid Before: Wed Apr 08 05:36:46 2020 +# Not Valid After : Sun Apr 08 05:36:46 2040 +# Fingerprint (SHA-256): 3F:03:4B:B5:70:4D:44:B2:D0:85:45:A0:20:57:DE:93:EB:F3:90:5F:CE:72:1A:CB:C7:30:C0:6D:DA:EE:90:4E +# Fingerprint (SHA1): 7A:22:1E:3D:DE:1B:06:AC:9E:C8:47:70:16:8E:3C:E5:F7:6B:06:F4 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "SecureSign Root CA12" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\172\042\036\075\336\033\006\254\236\310\107\160\026\216\074\345 +\367\153\006\364 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\306\211\312\144\102\233\142\010\111\013\036\177\351\007\075\350 +END +CKA_ISSUER MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\024\146\371\307\301\257\354\302\121\264\355\123\227\346\346 +\202\303\053\034\220\026 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "SecureSign Root CA14" +# +# Issuer: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP +# Serial Number:64:db:5a:0c:20:4e:e8:d7:29:77:c8:50:27:a2:5a:27:dd:2d:f2:cb +# Subject: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP +# Not Valid Before: Wed Apr 08 07:06:19 2020 +# Not Valid After : Sat Apr 08 07:06:19 2045 +# Fingerprint (SHA-256): 4B:00:9C:10:34:49:4F:9A:B5:6B:BA:3B:A1:D6:27:31:FC:4D:20:D8:95:5A:DC:EC:10:A9:25:60:72:61:E3:38 +# Fingerprint (SHA1): DD:50:C0:F7:79:B3:64:2E:74:A2:B8:9D:9F:D3:40:DD:BB:F0:F2:4F +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "SecureSign Root CA14" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\064 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\064 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\024\144\333\132\014\040\116\350\327\051\167\310\120\047\242 +\132\047\335\055\362\313 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\162\060\202\003\132\240\003\002\001\002\002\024\144 +\333\132\014\040\116\350\327\051\167\310\120\047\242\132\047\335 +\055\362\313\060\015\006\011\052\206\110\206\367\015\001\001\014 +\005\000\060\121\061\013\060\011\006\003\125\004\006\023\002\112 +\120\061\043\060\041\006\003\125\004\012\023\032\103\171\142\145 +\162\164\162\165\163\164\040\112\141\160\141\156\040\103\157\056 +\054\040\114\164\144\056\061\035\060\033\006\003\125\004\003\023 +\024\123\145\143\165\162\145\123\151\147\156\040\122\157\157\164 +\040\103\101\061\064\060\036\027\015\062\060\060\064\060\070\060 +\067\060\066\061\071\132\027\015\064\065\060\064\060\070\060\067 +\060\066\061\071\132\060\121\061\013\060\011\006\003\125\004\006 +\023\002\112\120\061\043\060\041\006\003\125\004\012\023\032\103 +\171\142\145\162\164\162\165\163\164\040\112\141\160\141\156\040 +\103\157\056\054\040\114\164\144\056\061\035\060\033\006\003\125 +\004\003\023\024\123\145\143\165\162\145\123\151\147\156\040\122 +\157\157\164\040\103\101\061\064\060\202\002\042\060\015\006\011 +\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000 +\060\202\002\012\002\202\002\001\000\305\322\172\241\326\212\277 +\026\061\320\230\321\072\224\374\132\270\156\042\301\142\367\247 +\012\047\357\120\366\056\261\236\150\022\360\154\044\143\071\361 +\360\337\020\306\336\267\122\040\325\122\133\102\231\236\363\240 +\276\122\037\137\314\147\155\247\056\120\242\301\227\215\266\370 +\225\365\260\272\334\235\340\276\313\337\367\070\362\107\365\246 +\232\222\225\052\142\131\120\013\242\261\065\347\145\262\141\262 +\352\222\161\151\344\051\360\117\201\201\004\074\262\245\133\324 +\305\250\131\147\173\125\034\111\253\172\235\302\347\163\115\357 +\315\011\302\304\127\022\333\001\016\043\171\011\007\073\242\350 +\374\212\317\217\300\106\044\234\070\047\340\203\235\033\240\277 +\170\025\020\353\206\116\012\132\375\337\332\054\202\176\356\312 +\366\051\341\372\161\241\367\210\150\234\234\360\215\276\017\111 +\221\330\352\072\371\375\320\150\161\333\351\265\053\116\202\222 +\157\146\037\340\360\334\114\354\312\321\352\272\164\006\371\263 +\204\220\224\321\137\216\163\031\020\135\002\345\160\245\300\020 +\320\020\174\157\305\130\111\264\260\156\232\332\175\225\365\314 +\332\002\257\270\054\175\171\217\276\103\361\371\050\050\215\011 +\103\370\010\335\153\310\213\054\044\261\215\122\007\275\170\233 +\313\312\150\262\244\335\014\114\171\140\306\231\321\223\361\060 +\032\007\323\256\042\302\352\316\361\204\011\314\340\024\156\177 +\077\176\322\202\205\254\334\251\026\116\205\240\140\313\366\234 +\327\310\263\216\355\306\233\230\165\015\125\350\137\345\225\213 +\002\244\256\103\051\050\021\244\346\022\060\001\113\165\153\036 +\146\235\171\057\245\166\057\035\100\264\155\311\175\171\010\354 +\321\152\266\135\052\262\245\146\275\153\205\364\164\126\303\365 +\347\165\122\050\054\245\377\146\107\245\324\376\376\236\124\277 +\145\176\001\326\060\217\245\066\234\242\120\034\356\070\200\001 +\110\306\307\164\364\306\254\303\100\111\026\141\164\054\257\214 +\157\065\355\173\030\000\133\066\074\234\120\015\312\222\063\020 +\361\046\111\155\337\165\044\067\202\042\327\350\226\375\025\113 +\002\226\076\007\162\225\176\253\075\114\056\327\312\360\337\340 +\130\077\055\057\004\232\070\243\001\002\003\001\000\001\243\102 +\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060\003 +\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003 +\002\001\006\060\035\006\003\125\035\016\004\026\004\024\006\223 +\243\012\136\050\151\067\252\141\035\353\353\374\055\157\043\344 +\363\240\060\015\006\011\052\206\110\206\367\015\001\001\014\005 +\000\003\202\002\001\000\226\200\162\011\006\176\234\314\223\004 +\026\273\240\072\215\222\116\267\021\032\012\161\161\020\315\004 +\255\177\245\105\120\020\146\116\112\101\242\003\331\021\117\172 +\067\271\113\342\306\217\062\146\165\045\373\353\316\077\003\051 +\046\215\270\026\035\366\037\063\156\110\346\350\370\127\262\033 +\171\337\073\207\012\342\144\272\000\312\154\357\176\320\043\353 +\170\217\377\144\233\064\067\237\065\145\242\244\000\075\022\043 +\226\130\135\312\143\207\306\243\007\210\115\347\151\166\212\123 +\315\361\117\354\102\362\223\343\231\244\067\074\207\270\142\333 +\360\354\037\067\077\067\137\103\314\121\235\265\360\227\302\267 +\205\152\150\013\104\036\345\121\356\223\316\113\156\206\301\322 +\014\044\131\066\032\237\054\221\217\343\030\333\224\225\012\355 +\221\252\016\231\334\226\123\343\141\203\306\026\272\043\272\334 +\335\176\032\306\173\102\266\331\132\005\334\232\137\325\337\270 +\332\107\175\332\070\333\254\071\325\036\153\154\052\027\214\141 +\315\261\155\162\001\303\303\040\000\142\150\026\061\325\166\252 +\206\273\016\252\236\306\371\360\331\370\015\041\002\344\305\050 +\026\131\021\271\331\151\163\052\222\170\270\222\127\233\010\362 +\072\345\057\225\260\130\267\153\040\024\155\024\357\012\274\176 +\330\125\330\210\332\057\372\031\245\373\213\340\177\071\365\162 +\053\205\304\054\254\357\031\105\222\114\263\141\007\334\115\037 +\156\322\201\023\134\232\363\022\147\203\317\233\077\213\237\235 +\244\271\250\226\003\172\305\356\040\336\063\332\057\236\032\172 +\164\036\341\356\314\132\072\004\335\263\032\004\250\024\143\254 +\267\107\022\203\232\154\365\346\351\025\025\221\032\204\031\016 +\224\104\347\022\216\045\133\200\147\031\334\143\223\020\013\145 +\056\212\372\011\232\116\332\206\050\175\252\141\065\330\016\247 +\050\032\273\122\340\170\370\154\272\154\260\156\271\207\136\351 +\231\065\067\361\075\144\053\251\240\064\223\317\143\057\325\201 +\337\256\143\047\245\036\116\215\334\051\170\131\370\371\241\040 +\214\247\046\100\156\202\162\315\170\262\310\217\074\036\163\347 +\301\037\277\317\316\245\052\233\333\104\144\062\240\273\177\134 +\045\023\110\265\177\222 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE + +# Trust for "SecureSign Root CA14" +# Issuer: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP +# Serial Number:64:db:5a:0c:20:4e:e8:d7:29:77:c8:50:27:a2:5a:27:dd:2d:f2:cb +# Subject: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP +# Not Valid Before: Wed Apr 08 07:06:19 2020 +# Not Valid After : Sat Apr 08 07:06:19 2045 +# Fingerprint (SHA-256): 4B:00:9C:10:34:49:4F:9A:B5:6B:BA:3B:A1:D6:27:31:FC:4D:20:D8:95:5A:DC:EC:10:A9:25:60:72:61:E3:38 +# Fingerprint (SHA1): DD:50:C0:F7:79:B3:64:2E:74:A2:B8:9D:9F:D3:40:DD:BB:F0:F2:4F +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "SecureSign Root CA14" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\335\120\300\367\171\263\144\056\164\242\270\235\237\323\100\335 +\273\360\362\117 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\161\015\162\372\222\031\145\136\211\004\254\026\063\360\274\325 +END +CKA_ISSUER MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\064 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\024\144\333\132\014\040\116\350\327\051\167\310\120\047\242 +\132\047\335\055\362\313 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "SecureSign Root CA15" +# +# Issuer: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP +# Serial Number:16:15:c7:c3:d8:49:a7:be:69:0c:8a:88:ed:f0:70:f9:dd:b7:3e:87 +# Subject: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP +# Not Valid Before: Wed Apr 08 08:32:56 2020 +# Not Valid After : Sat Apr 08 08:32:56 2045 +# Fingerprint (SHA-256): E7:78:F0:F0:95:FE:84:37:29:CD:1A:00:82:17:9E:53:14:A9:C2:91:44:28:05:E1:FB:1D:8F:B6:B8:88:6C:3A +# Fingerprint (SHA1): CB:BA:83:C8:C1:5A:5D:F1:F9:73:6F:CA:D7:EF:28:13:06:4A:07:7D +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "SecureSign Root CA15" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\065 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\065 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\024\026\025\307\303\330\111\247\276\151\014\212\210\355\360 +\160\371\335\267\076\207 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\002\043\060\202\001\251\240\003\002\001\002\002\024\026 +\025\307\303\330\111\247\276\151\014\212\210\355\360\160\371\335 +\267\076\207\060\012\006\010\052\206\110\316\075\004\003\003\060 +\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061\043 +\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164\162 +\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040\114 +\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123\145 +\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103\101 +\061\065\060\036\027\015\062\060\060\064\060\070\060\070\063\062 +\065\066\132\027\015\064\065\060\064\060\070\060\070\063\062\065 +\066\132\060\121\061\013\060\011\006\003\125\004\006\023\002\112 +\120\061\043\060\041\006\003\125\004\012\023\032\103\171\142\145 +\162\164\162\165\163\164\040\112\141\160\141\156\040\103\157\056 +\054\040\114\164\144\056\061\035\060\033\006\003\125\004\003\023 +\024\123\145\143\165\162\145\123\151\147\156\040\122\157\157\164 +\040\103\101\061\065\060\166\060\020\006\007\052\206\110\316\075 +\002\001\006\005\053\201\004\000\042\003\142\000\004\013\120\164 +\215\144\062\231\231\263\322\140\010\270\042\216\106\164\054\170 +\300\053\104\055\155\137\035\311\256\113\122\040\203\075\270\024 +\155\123\207\140\236\137\154\205\333\006\024\225\340\307\050\377 +\235\137\344\252\361\263\213\155\355\117\057\113\311\112\224\221 +\144\165\376\001\354\301\330\353\172\224\170\126\030\103\137\153 +\201\313\366\274\332\264\014\266\051\223\010\151\217\243\102\060 +\100\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001 +\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002 +\001\006\060\035\006\003\125\035\016\004\026\004\024\353\101\310 +\256\374\325\236\121\110\365\275\213\364\207\040\223\101\053\323 +\364\060\012\006\010\052\206\110\316\075\004\003\003\003\150\000 +\060\145\002\061\000\331\056\211\176\136\116\244\021\007\275\131 +\302\007\336\253\062\070\123\052\106\104\006\027\172\316\121\351 +\340\377\146\055\011\116\340\117\364\005\321\205\366\065\140\334 +\365\162\263\106\175\002\060\104\230\106\032\202\205\036\141\151 +\211\113\007\113\146\265\236\252\272\240\036\101\331\001\164\072 +\156\105\072\211\200\031\173\062\230\125\143\253\353\143\156\223 +\155\253\033\011\140\061\116 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE + +# Trust for "SecureSign Root CA15" +# Issuer: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP +# Serial Number:16:15:c7:c3:d8:49:a7:be:69:0c:8a:88:ed:f0:70:f9:dd:b7:3e:87 +# Subject: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP +# Not Valid Before: Wed Apr 08 08:32:56 2020 +# Not Valid After : Sat Apr 08 08:32:56 2045 +# Fingerprint (SHA-256): E7:78:F0:F0:95:FE:84:37:29:CD:1A:00:82:17:9E:53:14:A9:C2:91:44:28:05:E1:FB:1D:8F:B6:B8:88:6C:3A +# Fingerprint (SHA1): CB:BA:83:C8:C1:5A:5D:F1:F9:73:6F:CA:D7:EF:28:13:06:4A:07:7D +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "SecureSign Root CA15" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\313\272\203\310\301\132\135\361\371\163\157\312\327\357\050\023 +\006\112\007\175 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\023\060\374\304\142\246\251\336\265\301\150\257\265\322\061\107 +END +CKA_ISSUER MULTILINE_OCTAL +\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061 +\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164 +\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040 +\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123 +\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103 +\101\061\065 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\024\026\025\307\303\330\111\247\276\151\014\212\210\355\360 +\160\371\335\267\076\207 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE From 7aa250afdae93230e2abce6709664f7c4d1ea6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Mon, 4 Nov 2024 13:51:19 +0100 Subject: [PATCH 73/93] sqlite: improve error handling using MaybeLocal As per James' suggestion, consistently use MaybeLocal and avoid Check() and ToLocalChecked() entirely. Refs: https://github.com/nodejs/node/pull/54687 PR-URL: https://github.com/nodejs/node/pull/55571 Reviewed-By: Colin Ihrig --- src/node_sqlite.cc | 58 +++++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index 742c15233ccd13..3e08ed796e9ccb 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -56,40 +56,56 @@ using v8::Value; } \ } while (0) -inline Local CreateSQLiteError(Isolate* isolate, const char* message) { - Local js_msg = String::NewFromUtf8(isolate, message).ToLocalChecked(); - Local e = Exception::Error(js_msg) - ->ToObject(isolate->GetCurrentContext()) - .ToLocalChecked(); - e->Set(isolate->GetCurrentContext(), - OneByteString(isolate, "code"), - OneByteString(isolate, "ERR_SQLITE_ERROR")) - .Check(); +inline MaybeLocal CreateSQLiteError(Isolate* isolate, + const char* message) { + Local js_msg; + Local e; + if (!String::NewFromUtf8(isolate, message).ToLocal(&js_msg) || + !Exception::Error(js_msg) + ->ToObject(isolate->GetCurrentContext()) + .ToLocal(&e) || + e->Set(isolate->GetCurrentContext(), + OneByteString(isolate, "code"), + OneByteString(isolate, "ERR_SQLITE_ERROR")) + .IsNothing()) { + return MaybeLocal(); + } return e; } -inline Local CreateSQLiteError(Isolate* isolate, sqlite3* db) { +inline MaybeLocal CreateSQLiteError(Isolate* isolate, sqlite3* db) { int errcode = sqlite3_extended_errcode(db); const char* errstr = sqlite3_errstr(errcode); const char* errmsg = sqlite3_errmsg(db); - Local e = CreateSQLiteError(isolate, errmsg); - e->Set(isolate->GetCurrentContext(), - OneByteString(isolate, "errcode"), - Integer::New(isolate, errcode)) - .Check(); - e->Set(isolate->GetCurrentContext(), - OneByteString(isolate, "errstr"), - String::NewFromUtf8(isolate, errstr).ToLocalChecked()) - .Check(); + Local js_errmsg; + Local e; + if (!String::NewFromUtf8(isolate, errstr).ToLocal(&js_errmsg) || + !CreateSQLiteError(isolate, errmsg).ToLocal(&e) || + e->Set(isolate->GetCurrentContext(), + OneByteString(isolate, "errcode"), + Integer::New(isolate, errcode)) + .IsNothing() || + e->Set(isolate->GetCurrentContext(), + OneByteString(isolate, "errstr"), + js_errmsg) + .IsNothing()) { + return MaybeLocal(); + } return e; } inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, sqlite3* db) { - isolate->ThrowException(CreateSQLiteError(isolate, db)); + Local e; + if (CreateSQLiteError(isolate, db).ToLocal(&e)) { + isolate->ThrowException(e); + } } inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, const char* message) { - isolate->ThrowException(CreateSQLiteError(isolate, message)); + Local e; + if (CreateSQLiteError(isolate, message).ToLocal(&e)) { + isolate->ThrowException(e); + } } DatabaseSync::DatabaseSync(Environment* env, From 961cbc9c0ff1b022e267d77ba9b467e4da96f28b Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Mon, 4 Nov 2024 14:16:32 -0500 Subject: [PATCH 74/93] tools: use `util.parseArgs` in `lint-md` PR-URL: https://github.com/nodejs/node/pull/55694 Reviewed-By: Moshe Atlow Reviewed-By: Chemi Atlow --- tools/lint-md/lint-md.mjs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tools/lint-md/lint-md.mjs b/tools/lint-md/lint-md.mjs index 4116d7e803b64e..fd5576d404c905 100644 --- a/tools/lint-md/lint-md.mjs +++ b/tools/lint-md/lint-md.mjs @@ -1,4 +1,5 @@ -import fs from 'fs'; +import fs from 'node:fs'; +import { parseArgs } from 'node:util'; import { unified } from 'unified'; import remarkParse from 'remark-parse'; @@ -7,20 +8,18 @@ import presetLintNode from 'remark-preset-lint-node'; import { read } from 'to-vfile'; import { reporter } from 'vfile-reporter'; -const paths = process.argv.slice(2); +const { values: { format }, positionals: paths } = parseArgs({ + options: { + format: { type: 'boolean', default: false }, + }, + allowPositionals: true, +}); if (!paths.length) { - console.error('Usage: lint-md.mjs [ ...]'); + console.error('Usage: lint-md.mjs [--format] [ ...]'); process.exit(1); } -let format = false; - -if (paths[0] === '--format') { - paths.shift(); - format = true; -} - const linter = unified() .use(remarkParse) .use(presetLintNode) From 4b192daac0091ea7fdbb7b7c7648ea9113e81d95 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Mon, 4 Nov 2024 20:00:11 -0500 Subject: [PATCH 75/93] deps: update acorn to 8.14.0 PR-URL: https://github.com/nodejs/node/pull/55699 Reviewed-By: Rafael Gonzaga Reviewed-By: Antoine du Hamel --- deps/acorn/acorn/CHANGELOG.md | 12 +++ deps/acorn/acorn/dist/acorn.d.mts | 12 ++- deps/acorn/acorn/dist/acorn.d.ts | 12 ++- deps/acorn/acorn/dist/acorn.js | 135 +++++++++++++++++++++++++++--- deps/acorn/acorn/dist/acorn.mjs | 135 +++++++++++++++++++++++++++--- deps/acorn/acorn/package.json | 2 +- src/acorn_version.h | 2 +- 7 files changed, 280 insertions(+), 30 deletions(-) diff --git a/deps/acorn/acorn/CHANGELOG.md b/deps/acorn/acorn/CHANGELOG.md index 1e090161fffa80..313718616b575a 100644 --- a/deps/acorn/acorn/CHANGELOG.md +++ b/deps/acorn/acorn/CHANGELOG.md @@ -1,3 +1,15 @@ +## 8.14.0 (2024-10-27) + +### New features + +Support ES2025 import attributes. + +Support ES2025 RegExp modifiers. + +### Bug fixes + +Support some missing Unicode properties. + ## 8.13.0 (2024-10-16) ### New features diff --git a/deps/acorn/acorn/dist/acorn.d.mts b/deps/acorn/acorn/dist/acorn.d.mts index cd204b1c50db94..81f4e38fdbf4c9 100644 --- a/deps/acorn/acorn/dist/acorn.d.mts +++ b/deps/acorn/acorn/dist/acorn.d.mts @@ -403,6 +403,7 @@ export interface ImportDeclaration extends Node { type: "ImportDeclaration" specifiers: Array source: Literal + attributes: Array } export interface ImportSpecifier extends Node { @@ -421,11 +422,18 @@ export interface ImportNamespaceSpecifier extends Node { local: Identifier } +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + export interface ExportNamedDeclaration extends Node { type: "ExportNamedDeclaration" declaration?: Declaration | null specifiers: Array source?: Literal | null + attributes: Array } export interface ExportSpecifier extends Node { @@ -454,6 +462,7 @@ export interface ExportAllDeclaration extends Node { type: "ExportAllDeclaration" source: Literal exported?: Identifier | Literal | null + attributes: Array } export interface AwaitExpression extends Node { @@ -469,6 +478,7 @@ export interface ChainExpression extends Node { export interface ImportExpression extends Node { type: "ImportExpression" source: Expression + options: Expression | null } export interface ParenthesizedExpression extends Node { @@ -562,7 +572,7 @@ export type ModuleDeclaration = | ExportDefaultDeclaration | ExportAllDeclaration -export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator export function parse(input: string, options: Options): Program diff --git a/deps/acorn/acorn/dist/acorn.d.ts b/deps/acorn/acorn/dist/acorn.d.ts index cd204b1c50db94..81f4e38fdbf4c9 100644 --- a/deps/acorn/acorn/dist/acorn.d.ts +++ b/deps/acorn/acorn/dist/acorn.d.ts @@ -403,6 +403,7 @@ export interface ImportDeclaration extends Node { type: "ImportDeclaration" specifiers: Array source: Literal + attributes: Array } export interface ImportSpecifier extends Node { @@ -421,11 +422,18 @@ export interface ImportNamespaceSpecifier extends Node { local: Identifier } +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + export interface ExportNamedDeclaration extends Node { type: "ExportNamedDeclaration" declaration?: Declaration | null specifiers: Array source?: Literal | null + attributes: Array } export interface ExportSpecifier extends Node { @@ -454,6 +462,7 @@ export interface ExportAllDeclaration extends Node { type: "ExportAllDeclaration" source: Literal exported?: Identifier | Literal | null + attributes: Array } export interface AwaitExpression extends Node { @@ -469,6 +478,7 @@ export interface ChainExpression extends Node { export interface ImportExpression extends Node { type: "ImportExpression" source: Expression + options: Expression | null } export interface ParenthesizedExpression extends Node { @@ -562,7 +572,7 @@ export type ModuleDeclaration = | ExportDefaultDeclaration | ExportAllDeclaration -export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +export type AnyNode = Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator export function parse(input: string, options: Options): Program diff --git a/deps/acorn/acorn/dist/acorn.js b/deps/acorn/acorn/dist/acorn.js index 7cd26fa36b5caa..2bfc15b5ef2204 100644 --- a/deps/acorn/acorn/dist/acorn.js +++ b/deps/acorn/acorn/dist/acorn.js @@ -1678,6 +1678,8 @@ this.expectContextual("from"); if (this.type !== types$1.string) { this.unexpected(); } node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } this.semicolon(); return this.finishNode(node, "ExportAllDeclaration") }; @@ -1708,6 +1710,8 @@ if (this.eatContextual("from")) { if (this.type !== types$1.string) { this.unexpected(); } node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } } else { for (var i = 0, list = node.specifiers; i < list.length; i += 1) { // check for keywords used as local names @@ -1848,6 +1852,8 @@ this.expectContextual("from"); node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected(); } + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } this.semicolon(); return this.finishNode(node, "ImportDeclaration") }; @@ -1908,6 +1914,41 @@ return nodes }; + pp$8.parseWithClause = function() { + var nodes = []; + if (!this.eat(types$1._with)) { + return nodes + } + this.expect(types$1.braceL); + var attributeKeys = {}; + var first = true; + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var attr = this.parseImportAttribute(); + var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value; + if (hasOwn(attributeKeys, keyName)) + { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); } + attributeKeys[keyName] = true; + nodes.push(attr); + } + return nodes + }; + + pp$8.parseImportAttribute = function() { + var node = this.startNode(); + node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never"); + this.expect(types$1.colon); + if (this.type !== types$1.string) { + this.unexpected(); + } + node.value = this.parseExprAtom(); + return this.finishNode(node, "ImportAttribute") + }; + pp$8.parseModuleExportName = function() { if (this.options.ecmaVersion >= 13 && this.type === types$1.string) { var stringLiteral = this.parseLiteral(this.value); @@ -2975,13 +3016,32 @@ // Parse node.source. node.source = this.parseMaybeAssign(); - // Verify ending. - if (!this.eat(types$1.parenR)) { - var errorPos = this.start; - if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { - this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + if (this.options.ecmaVersion >= 16) { + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + node.options = this.parseMaybeAssign(); + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + this.unexpected(); + } + } + } else { + node.options = null; + } } else { - this.unexpected(errorPos); + node.options = null; + } + } else { + // Verify ending. + if (!this.eat(types$1.parenR)) { + var errorPos = this.start; + if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } } } @@ -3741,6 +3801,9 @@ return newNode }; + // This file was generated by "bin/generate-unicode-script-values.js". Do not modify manually! + var scriptValuesAddedInUnicode = "Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz"; + // This file contains Unicode properties extracted from the ECMAScript specification. // The lists are extracted like so: // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) @@ -3783,7 +3846,7 @@ var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"; - var ecma14ScriptValues = ecma13ScriptValues + " Hrkt Katakana_Or_Hiragana Kawi Nag_Mundari Nagm Unknown Zzzz"; + var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode; var unicodeScriptValues = { 9: ecma9ScriptValues, @@ -4208,12 +4271,41 @@ pp$1.regexp_eatUncapturingGroup = function(state) { var start = state.pos; if (state.eat(0x28 /* ( */)) { - if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) { - this.regexp_disjunction(state); - if (state.eat(0x29 /* ) */)) { - return true + if (state.eat(0x3F /* ? */)) { + if (this.options.ecmaVersion >= 16) { + var addModifiers = this.regexp_eatModifiers(state); + var hasHyphen = state.eat(0x2D /* - */); + if (addModifiers || hasHyphen) { + for (var i = 0; i < addModifiers.length; i++) { + var modifier = addModifiers.charAt(i); + if (addModifiers.indexOf(modifier, i + 1) > -1) { + state.raise("Duplicate regular expression modifiers"); + } + } + if (hasHyphen) { + var removeModifiers = this.regexp_eatModifiers(state); + if (!addModifiers && !removeModifiers && state.current() === 0x3A /* : */) { + state.raise("Invalid regular expression modifiers"); + } + for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) { + var modifier$1 = removeModifiers.charAt(i$1); + if ( + removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 || + addModifiers.indexOf(modifier$1) > -1 + ) { + state.raise("Duplicate regular expression modifiers"); + } + } + } + } + } + if (state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); } - state.raise("Unterminated group"); } state.pos = start; } @@ -4235,6 +4327,23 @@ } return false }; + // RegularExpressionModifiers :: + // [empty] + // RegularExpressionModifiers RegularExpressionModifier + pp$1.regexp_eatModifiers = function(state) { + var modifiers = ""; + var ch = 0; + while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) { + modifiers += codePointToString(ch); + state.advance(); + } + return modifiers + }; + // RegularExpressionModifier :: one of + // `i` `m` `s` + function isRegularExpressionModifier(ch) { + return ch === 0x69 /* i */ || ch === 0x6d /* m */ || ch === 0x73 /* s */ + } // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom pp$1.regexp_eatExtendedAtom = function(state) { @@ -5990,7 +6099,7 @@ // [walk]: util/walk.js - var version = "8.13.0"; + var version = "8.14.0"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/dist/acorn.mjs b/deps/acorn/acorn/dist/acorn.mjs index 21b860f275a064..43e58efe7f03e1 100644 --- a/deps/acorn/acorn/dist/acorn.mjs +++ b/deps/acorn/acorn/dist/acorn.mjs @@ -1672,6 +1672,8 @@ pp$8.parseExportAllDeclaration = function(node, exports) { this.expectContextual("from"); if (this.type !== types$1.string) { this.unexpected(); } node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } this.semicolon(); return this.finishNode(node, "ExportAllDeclaration") }; @@ -1702,6 +1704,8 @@ pp$8.parseExport = function(node, exports) { if (this.eatContextual("from")) { if (this.type !== types$1.string) { this.unexpected(); } node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } } else { for (var i = 0, list = node.specifiers; i < list.length; i += 1) { // check for keywords used as local names @@ -1842,6 +1846,8 @@ pp$8.parseImport = function(node) { this.expectContextual("from"); node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected(); } + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } this.semicolon(); return this.finishNode(node, "ImportDeclaration") }; @@ -1902,6 +1908,41 @@ pp$8.parseImportSpecifiers = function() { return nodes }; +pp$8.parseWithClause = function() { + var nodes = []; + if (!this.eat(types$1._with)) { + return nodes + } + this.expect(types$1.braceL); + var attributeKeys = {}; + var first = true; + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var attr = this.parseImportAttribute(); + var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value; + if (hasOwn(attributeKeys, keyName)) + { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); } + attributeKeys[keyName] = true; + nodes.push(attr); + } + return nodes +}; + +pp$8.parseImportAttribute = function() { + var node = this.startNode(); + node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never"); + this.expect(types$1.colon); + if (this.type !== types$1.string) { + this.unexpected(); + } + node.value = this.parseExprAtom(); + return this.finishNode(node, "ImportAttribute") +}; + pp$8.parseModuleExportName = function() { if (this.options.ecmaVersion >= 13 && this.type === types$1.string) { var stringLiteral = this.parseLiteral(this.value); @@ -2969,13 +3010,32 @@ pp$5.parseDynamicImport = function(node) { // Parse node.source. node.source = this.parseMaybeAssign(); - // Verify ending. - if (!this.eat(types$1.parenR)) { - var errorPos = this.start; - if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { - this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + if (this.options.ecmaVersion >= 16) { + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + node.options = this.parseMaybeAssign(); + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + this.unexpected(); + } + } + } else { + node.options = null; + } } else { - this.unexpected(errorPos); + node.options = null; + } + } else { + // Verify ending. + if (!this.eat(types$1.parenR)) { + var errorPos = this.start; + if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } } } @@ -3735,6 +3795,9 @@ pp$2.copyNode = function(node) { return newNode }; +// This file was generated by "bin/generate-unicode-script-values.js". Do not modify manually! +var scriptValuesAddedInUnicode = "Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz"; + // This file contains Unicode properties extracted from the ECMAScript specification. // The lists are extracted like so: // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) @@ -3777,7 +3840,7 @@ var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Han var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"; -var ecma14ScriptValues = ecma13ScriptValues + " Hrkt Katakana_Or_Hiragana Kawi Nag_Mundari Nagm Unknown Zzzz"; +var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode; var unicodeScriptValues = { 9: ecma9ScriptValues, @@ -4202,12 +4265,41 @@ pp$1.regexp_eatReverseSolidusAtomEscape = function(state) { pp$1.regexp_eatUncapturingGroup = function(state) { var start = state.pos; if (state.eat(0x28 /* ( */)) { - if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) { - this.regexp_disjunction(state); - if (state.eat(0x29 /* ) */)) { - return true + if (state.eat(0x3F /* ? */)) { + if (this.options.ecmaVersion >= 16) { + var addModifiers = this.regexp_eatModifiers(state); + var hasHyphen = state.eat(0x2D /* - */); + if (addModifiers || hasHyphen) { + for (var i = 0; i < addModifiers.length; i++) { + var modifier = addModifiers.charAt(i); + if (addModifiers.indexOf(modifier, i + 1) > -1) { + state.raise("Duplicate regular expression modifiers"); + } + } + if (hasHyphen) { + var removeModifiers = this.regexp_eatModifiers(state); + if (!addModifiers && !removeModifiers && state.current() === 0x3A /* : */) { + state.raise("Invalid regular expression modifiers"); + } + for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) { + var modifier$1 = removeModifiers.charAt(i$1); + if ( + removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 || + addModifiers.indexOf(modifier$1) > -1 + ) { + state.raise("Duplicate regular expression modifiers"); + } + } + } + } + } + if (state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); } - state.raise("Unterminated group"); } state.pos = start; } @@ -4229,6 +4321,23 @@ pp$1.regexp_eatCapturingGroup = function(state) { } return false }; +// RegularExpressionModifiers :: +// [empty] +// RegularExpressionModifiers RegularExpressionModifier +pp$1.regexp_eatModifiers = function(state) { + var modifiers = ""; + var ch = 0; + while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) { + modifiers += codePointToString(ch); + state.advance(); + } + return modifiers +}; +// RegularExpressionModifier :: one of +// `i` `m` `s` +function isRegularExpressionModifier(ch) { + return ch === 0x69 /* i */ || ch === 0x6d /* m */ || ch === 0x73 /* s */ +} // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom pp$1.regexp_eatExtendedAtom = function(state) { @@ -5984,7 +6093,7 @@ pp.readWord = function() { // [walk]: util/walk.js -var version = "8.13.0"; +var version = "8.14.0"; Parser.acorn = { Parser: Parser, diff --git a/deps/acorn/acorn/package.json b/deps/acorn/acorn/package.json index 3396013bbbf060..795cf83eff64d7 100644 --- a/deps/acorn/acorn/package.json +++ b/deps/acorn/acorn/package.json @@ -16,7 +16,7 @@ ], "./package.json": "./package.json" }, - "version": "8.13.0", + "version": "8.14.0", "engines": { "node": ">=0.4.0" }, diff --git a/src/acorn_version.h b/src/acorn_version.h index fdafbf96987762..b4e18696f8b6db 100644 --- a/src/acorn_version.h +++ b/src/acorn_version.h @@ -2,5 +2,5 @@ // Refer to tools/dep_updaters/update-acorn.sh #ifndef SRC_ACORN_VERSION_H_ #define SRC_ACORN_VERSION_H_ -#define ACORN_VERSION "8.13.0" +#define ACORN_VERSION "8.14.0" #endif // SRC_ACORN_VERSION_H_ From aebf676569b75a8cb5f326711589c76aa9fc5e38 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Tue, 5 Nov 2024 10:13:52 +0000 Subject: [PATCH 76/93] test,crypto: update WebCryptoAPI WPT PR-URL: https://github.com/nodejs/node/pull/55703 Reviewed-By: Antoine du Hamel Reviewed-By: Luigi Pinca --- test/fixtures/wpt/README.md | 2 +- .../derive_key_and_encrypt.https.any.js | 9 ++++ .../derive_key_and_encrypt.js | 49 +++++++++++++++++++ .../fixtures/wpt/WebCryptoAPI/util/helpers.js | 38 ++++++++++++++ test/fixtures/wpt/versions.json | 2 +- 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.https.any.js create mode 100644 test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.js diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index 4c8f6e8b0268d6..048ce7e49a69ef 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -32,7 +32,7 @@ Last update: - user-timing: https://github.com/web-platform-tests/wpt/tree/5ae85bf826/user-timing - wasm/jsapi: https://github.com/web-platform-tests/wpt/tree/cde25e7e3c/wasm/jsapi - wasm/webapi: https://github.com/web-platform-tests/wpt/tree/fd1b23eeaa/wasm/webapi -- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/75db68b054/WebCryptoAPI +- WebCryptoAPI: https://github.com/web-platform-tests/wpt/tree/5f0f4ac1af/WebCryptoAPI - webidl/ecmascript-binding/es-exceptions: https://github.com/web-platform-tests/wpt/tree/a370aad338/webidl/ecmascript-binding/es-exceptions - webmessaging/broadcastchannel: https://github.com/web-platform-tests/wpt/tree/6495c91853/webmessaging/broadcastchannel - webstorage: https://github.com/web-platform-tests/wpt/tree/9dafa89214/webstorage diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.https.any.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.https.any.js new file mode 100644 index 00000000000000..5edc832b6163bd --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.https.any.js @@ -0,0 +1,9 @@ +// META: title=WebCryptoAPI: deriveKey() Using HKDF and PBKDF2 from an ECDH key +// META: script=derive_key_and_encrypt.js +// META: script=../util/helpers.js + +// Test imported from WebKit's source, defined to check the impact of the +// 'Get Key Length' behavior of HKDF and PBKDF2, which should return 'null' +// in both cases, in the 'deriveKey' operation. +// https://bugs.webkit.org/show_bug.cgi?id=282096 +promise_test(define_tests, 'setup - define tests'); diff --git a/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.js b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.js new file mode 100644 index 00000000000000..5963a852fcfbe1 --- /dev/null +++ b/test/fixtures/wpt/WebCryptoAPI/derive_bits_keys/derive_key_and_encrypt.js @@ -0,0 +1,49 @@ +let iv = new Uint8Array(Array(12).keys()); +let salt = new Uint8Array(Array(10).keys()); +let plaintext = new Uint8Array(Array(100).keys()); + +function define_tests() { + importKeys().then((keys) => { + // Make sure that ecdh produces the same shared secret and the same encryption results using a key derived from that secret. + keys.forEach(keyData => { + promise_test(async() => { + let hkdfKey = await crypto.subtle.deriveKey({name: "ECDH", public: keyData.publicKey }, keyData.privateKey, { name: "HKDF", hash: "" , salt: new Uint8Array(), info: new Uint8Array() }, false, ["deriveKey"]); + let aesKey = await crypto.subtle.deriveKey({name: "HKDF", hash: "SHA-256", salt: salt, info: plaintext}, hkdfKey, {name:"AES-GCM", length: 256}, true, ["encrypt", "decrypt"]); + let result = await crypto.subtle.encrypt({ name: "AES-GCM", iv: iv }, aesKey, plaintext); + assert_equals(bytesToHexString(result), "a6280c522670eaf82f6564afbeb20a5b3f2d4e13c5596f6df3dcff8c34cb2118d2770fb24d83cfac5079c323118485bb01170292ee41eb82b07208f4840478fea3771d8922785c476ba06c2a0b933fc1661431419530a916ad4468545d1af5004a1149fea241c2ff1582ee58a8b7d79935de5def"); + }, "HKDF derivation of a ECDH key " + keyData.test); + promise_test(async() => { + let pkdf2Key = await crypto.subtle.deriveKey({name: "ECDH", public: keyData.publicKey }, keyData.privateKey, { name: "PBKDF2", hash: "" , salt: new Uint8Array(), iterations: 32 }, false, ["deriveKey"]); + let aesKey = await crypto.subtle.deriveKey({name: "PBKDF2", hash: "SHA-256", salt: salt, iterations: 32 }, pkdf2Key, { name:"AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]); + let result = await crypto.subtle.encrypt({ name: "AES-GCM", iv: iv }, aesKey, plaintext); + assert_equals(bytesToHexString(result), "c6201dfbb6fa92c1c246f6ce52f8f1c037f087efde41bac7f6485a2a8207623d2d3825b9cbe8ef864a90378667ed25544ce44cd2904bd96c19f0eeb611d626185165a8afb4e52f95700d7880f83939a42712fc4e377f198c01a61b397b76c3a4b93d932c321084bbef33332169dea09458b27df3"); + }, "PBKDF2 derivation of a ECDH key " + keyData.test); + }); + }, (e) => { + assert_unreached("Setup failed: " + e.message); + }); + + return Promise.resolve("define_tests"); +} + +async function importKeys() { + // "ECDSA" with a 'P-256' curve + let keyData = [ + hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420fe77a808a7109ba5ceb93ebebad2c84a714d864ad29b62d6537e1969035c0079a144034200042684c752eef1c927a80c74e8b02ce459f848b5977f37fd878b36dae632be9a6cadd56126e404a4f75c535e5769d95b49fb1106f784f3d231b776d1f4d57927ce"), + hexStringToUint8Array("042684c752eef1c927a80c74e8b02ce459f848b5977f37fd878b36dae632be9a6cadd56126e404a4f75c535e5769d95b49fb1106f784f3d231b776d1f4d57927ce"), + hexStringToUint8Array("308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b020101042067521ccd1f85516118182bca3394c273bab9ce5cd6265105559e325e01f2df1ca144034200043042d8698882f2b59de972390d3fc9277e2e677a6c560148017c9475218fda1b38f76f7645fbcaf3d03e6259d080204fbafb04731b6ad53cb25c3d35d95b7c73"), + hexStringToUint8Array("043042d8698882f2b59de972390d3fc9277e2e677a6c560148017c9475218fda1b38f76f7645fbcaf3d03e6259d080204fbafb04731b6ad53cb25c3d35d95b7c73"), + ]; + let extractable = true; + var allKeys = await Promise.all([ + crypto.subtle.importKey("pkcs8", keyData[0], {name: "ECDH", namedCurve: "P-256"}, extractable, ["deriveKey", 'deriveBits']), + crypto.subtle.importKey("raw", keyData[1], {name: "ECDH", namedCurve: "P-256"}, extractable, []), + crypto.subtle.importKey("pkcs8", keyData[2], {name: "ECDH", namedCurve: "P-256"}, extractable, ["deriveKey", 'deriveBits']), + crypto.subtle.importKey("raw", keyData[3], {name: "ECDH", namedCurve: "P-256"}, extractable, []), + ]); + // Test cases defined combining public and private keys of each key-pair. + return [ + { test: 1, publicKey: allKeys[3], privateKey: allKeys[0] }, + { test: 2, publicKey: allKeys[1], privateKey: allKeys[2] } + ]; +} diff --git a/test/fixtures/wpt/WebCryptoAPI/util/helpers.js b/test/fixtures/wpt/WebCryptoAPI/util/helpers.js index bda97003263ff4..c60371dc6adac9 100644 --- a/test/fixtures/wpt/WebCryptoAPI/util/helpers.js +++ b/test/fixtures/wpt/WebCryptoAPI/util/helpers.js @@ -259,3 +259,41 @@ function allNameVariants(name, slowTest) { if (slowTest) return [mixedCaseName]; return unique([upCaseName, lowCaseName, mixedCaseName]); } + +// Builds a hex string representation for an array-like input. +// "bytes" can be an Array of bytes, an ArrayBuffer, or any TypedArray. +// The output looks like this: +// ab034c99 +function bytesToHexString(bytes) +{ + if (!bytes) + return null; + + bytes = new Uint8Array(bytes); + var hexBytes = []; + + for (var i = 0; i < bytes.length; ++i) { + var byteString = bytes[i].toString(16); + if (byteString.length < 2) + byteString = "0" + byteString; + hexBytes.push(byteString); + } + + return hexBytes.join(""); +} + +function hexStringToUint8Array(hexString) +{ + if (hexString.length % 2 != 0) + throw "Invalid hexString"; + var arrayBuffer = new Uint8Array(hexString.length / 2); + + for (var i = 0; i < hexString.length; i += 2) { + var byteValue = parseInt(hexString.substr(i, 2), 16); + if (byteValue == NaN) + throw "Invalid hexString"; + arrayBuffer[i/2] = byteValue; + } + + return arrayBuffer; +} diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index d3aef559ecd588..103e3962845f20 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -88,7 +88,7 @@ "path": "wasm/webapi" }, "WebCryptoAPI": { - "commit": "75db68b05454e7f3a81e063373defd094c176a16", + "commit": "5f0f4ac1af4848480406621fac99163c8ba0e242", "path": "WebCryptoAPI" }, "webidl/ecmascript-binding/es-exceptions": { From bf552fa3ccbe77aaf79bcd5ca9df6900108a8a57 Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Thu, 24 Oct 2024 23:36:58 +1030 Subject: [PATCH 77/93] lib: prefer number to string in webidl `type` function PR-URL: https://github.com/nodejs/node/pull/55489 Reviewed-By: Matthew Aitken Reviewed-By: Yagiz Nizipli Reviewed-By: Matteo Collina --- lib/internal/webidl.js | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/internal/webidl.js b/lib/internal/webidl.js index 351c1398c6d49c..e57108b14babf9 100644 --- a/lib/internal/webidl.js +++ b/lib/internal/webidl.js @@ -29,6 +29,15 @@ const { kEmptyObject } = require('internal/util'); const converters = { __proto__: null }; +const UNDEFINED = 1; +const BOOLEAN = 2; +const STRING = 3; +const SYMBOL = 4; +const NUMBER = 5; +const BIGINT = 6; +const NULL = 7; +const OBJECT = 8; + /** * @see https://webidl.spec.whatwg.org/#es-any * @param {any} V @@ -39,7 +48,7 @@ converters.any = (V) => { }; converters.object = (V, opts = kEmptyObject) => { - if (type(V) !== 'Object') { + if (type(V) !== OBJECT) { throw makeException( 'is not an object', kEmptyObject, @@ -236,37 +245,37 @@ function createEnumConverter(name, values) { // https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values function type(V) { - if (V === null) - return 'Null'; - switch (typeof V) { case 'undefined': - return 'Undefined'; + return UNDEFINED; case 'boolean': - return 'Boolean'; + return BOOLEAN; case 'number': - return 'Number'; + return NUMBER; case 'string': - return 'String'; + return STRING; case 'symbol': - return 'Symbol'; + return SYMBOL; case 'bigint': - return 'BigInt'; + return BIGINT; case 'object': // Fall through case 'function': // Fall through default: + if (V === null) { + return NULL; + } // Per ES spec, typeof returns an implementation-defined value that is not // any of the existing ones for uncallable non-standard exotic objects. // Yet Type() which the Web IDL spec depends on returns Object for such // cases. So treat the default case as an object. - return 'Object'; + return OBJECT; } } // https://webidl.spec.whatwg.org/#es-sequence function createSequenceConverter(converter) { return function(V, opts = kEmptyObject) { - if (type(V) !== 'Object') { + if (type(V) !== OBJECT) { throw makeException( 'can not be converted to sequence.', opts); From d1965f9f5b5659317a50060204d8c85489cbe1dd Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Sun, 20 Oct 2024 22:37:00 +1030 Subject: [PATCH 78/93] lib: implement webidl dictionary converter and use it in structuredClone This commit provides a factory to generate `dictionaryConverter` compliant with the spec. The implemented factory function is used for the `structuredClone` algorithm with updated test cases. PR-URL: https://github.com/nodejs/node/pull/55489 Reviewed-By: Matthew Aitken Reviewed-By: Yagiz Nizipli Reviewed-By: Matteo Collina --- lib/internal/webidl.js | 63 ++++++++++++++++++++ lib/internal/worker/js_transferable.js | 37 ++++++------ test/parallel/test-structuredClone-global.js | 21 +++++-- 3 files changed, 98 insertions(+), 23 deletions(-) diff --git a/lib/internal/webidl.js b/lib/internal/webidl.js index e57108b14babf9..071e8b9967e03a 100644 --- a/lib/internal/webidl.js +++ b/lib/internal/webidl.js @@ -2,6 +2,7 @@ const { ArrayPrototypePush, + ArrayPrototypeToSorted, MathAbs, MathMax, MathMin, @@ -272,6 +273,67 @@ function type(V) { } } +// https://webidl.spec.whatwg.org/#js-dictionary +function createDictionaryConverter(members) { + // The spec requires us to operate the members of a dictionary in + // lexicographical order. We are doing this in the outer scope to + // reduce the overhead that could happen in the returned function. + const sortedMembers = ArrayPrototypeToSorted(members, (a, b) => { + if (a.key === b.key) { + return 0; + } + return a.key < b.key ? -1 : 1; + }); + + return function( + V, + opts = kEmptyObject, + ) { + if (V != null && type(V) !== OBJECT) { + throw makeException( + 'cannot be converted to a dictionary', + opts, + ); + } + + const idlDict = { __proto__: null }; + for (let i = 0; i < sortedMembers.length; i++) { + const member = sortedMembers[i]; + const key = member.key; + let jsMemberValue; + if (V == null) { + jsMemberValue = undefined; + } else { + jsMemberValue = V[key]; + } + + if (jsMemberValue !== undefined) { + const memberContext = opts.context ? `${key} in ${opts.context}` : `${key}`; + const converter = member.converter; + const idlMemberValue = converter( + jsMemberValue, + { + __proto__: null, + prefix: opts.prefix, + context: memberContext, + }, + ); + idlDict[key] = idlMemberValue; + } else if (typeof member.defaultValue === 'function') { + const idlMemberValue = member.defaultValue(); + idlDict[key] = idlMemberValue; + } else if (member.required) { + throw makeException( + `cannot be converted because of the missing '${key}'`, + opts, + ); + } + } + + return idlDict; + }; +} + // https://webidl.spec.whatwg.org/#es-sequence function createSequenceConverter(converter) { return function(V, opts = kEmptyObject) { @@ -327,6 +389,7 @@ module.exports = { createEnumConverter, createInterfaceConverter, createSequenceConverter, + createDictionaryConverter, evenRound, makeException, }; diff --git a/lib/internal/worker/js_transferable.js b/lib/internal/worker/js_transferable.js index 58e377b87a9d11..592d43d2152e0a 100644 --- a/lib/internal/worker/js_transferable.js +++ b/lib/internal/worker/js_transferable.js @@ -5,7 +5,6 @@ const { } = primordials; const { codes: { - ERR_INVALID_ARG_TYPE, ERR_MISSING_ARGS, }, } = require('internal/errors'); @@ -98,29 +97,31 @@ function markTransferMode(obj, cloneable = false, transferable = false) { obj[transfer_mode_private_symbol] = mode; } + +webidl.converters.StructuredSerializeOptions = webidl + .createDictionaryConverter( + [ + { + key: 'transfer', + converter: webidl.converters['sequence'], + defaultValue: () => [], + }, + ], + ); + function structuredClone(value, options) { if (arguments.length === 0) { throw new ERR_MISSING_ARGS('The value argument must be specified'); } - // TODO(jazelly): implement generic webidl dictionary converter - const prefix = 'Options'; - const optionsType = webidl.type(options); - if (optionsType !== 'Undefined' && optionsType !== 'Null' && optionsType !== 'Object') { - throw new ERR_INVALID_ARG_TYPE( - prefix, - ['object', 'null', 'undefined'], - options, - ); - } - const key = 'transfer'; - const idlOptions = { __proto__: null, [key]: [] }; - if (options != null && key in options && options[key] !== undefined) { - idlOptions[key] = webidl.converters['sequence'](options[key], { + const idlOptions = webidl.converters.StructuredSerializeOptions( + options, + { __proto__: null, - context: 'Transfer', - }); - } + prefix: "Failed to execute 'structuredClone'", + context: 'Options', + }, + ); const serializedData = nativeStructuredClone(value, idlOptions); return serializedData; diff --git a/test/parallel/test-structuredClone-global.js b/test/parallel/test-structuredClone-global.js index ef6ddc56a73cca..e6b63c382b39b1 100644 --- a/test/parallel/test-structuredClone-global.js +++ b/test/parallel/test-structuredClone-global.js @@ -3,12 +3,23 @@ require('../common'); const assert = require('assert'); +const prefix = "Failed to execute 'structuredClone'"; +const key = 'transfer'; +const context = 'Options'; +const memberConverterError = `${prefix}: ${key} in ${context} can not be converted to sequence.`; +const dictionaryConverterError = `${prefix}: ${context} cannot be converted to a dictionary`; + assert.throws(() => structuredClone(), { code: 'ERR_MISSING_ARGS' }); -assert.throws(() => structuredClone(undefined, ''), { code: 'ERR_INVALID_ARG_TYPE' }); -assert.throws(() => structuredClone(undefined, 1), { code: 'ERR_INVALID_ARG_TYPE' }); -assert.throws(() => structuredClone(undefined, { transfer: 1 }), { code: 'ERR_INVALID_ARG_TYPE' }); -assert.throws(() => structuredClone(undefined, { transfer: '' }), { code: 'ERR_INVALID_ARG_TYPE' }); -assert.throws(() => structuredClone(undefined, { transfer: null }), { code: 'ERR_INVALID_ARG_TYPE' }); +assert.throws(() => structuredClone(undefined, ''), + { code: 'ERR_INVALID_ARG_TYPE', message: dictionaryConverterError }); +assert.throws(() => structuredClone(undefined, 1), + { code: 'ERR_INVALID_ARG_TYPE', message: dictionaryConverterError }); +assert.throws(() => structuredClone(undefined, { transfer: 1 }), + { code: 'ERR_INVALID_ARG_TYPE', message: memberConverterError }); +assert.throws(() => structuredClone(undefined, { transfer: '' }), + { code: 'ERR_INVALID_ARG_TYPE', message: memberConverterError }); +assert.throws(() => structuredClone(undefined, { transfer: null }), + { code: 'ERR_INVALID_ARG_TYPE', message: memberConverterError }); // Options can be null or undefined. assert.strictEqual(structuredClone(undefined), undefined); From bffbaa13a2857f27f9b6bb8adee46b4e8b685f60 Mon Sep 17 00:00:00 2001 From: Joe Bowbeer Date: Tue, 5 Nov 2024 15:14:15 -0800 Subject: [PATCH 79/93] doc: update `--max-semi-space-size` description PR-URL: https://github.com/nodejs/node/pull/55495 Fixes: https://github.com/nodejs/node/issues/55487 Reviewed-By: Luigi Pinca Reviewed-By: Trivikram Kamat --- doc/api/cli.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index eff03727e86f12..3cd18736534a7b 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -3542,8 +3542,12 @@ an increase of 1 MiB to semi-space applies to each of the three individual semi-spaces and causes the heap size to increase by 3 MiB. The throughput improvement depends on your workload (see [#42511][]). -The default value is 16 MiB for 64-bit systems and 8 MiB for 32-bit systems. To -get the best configuration for your application, you should try different +The default value depends on the memory limit. For example, on 64-bit systems +with a memory limit of 512 MiB, the max size of a semi-space defaults to 1 MiB. +On 64-bit systems with a memory limit of 2 GiB, the max size of a semi-space +defaults to 16 MiB. + +To get the best configuration for your application, you should try different max-semi-space-size values when running benchmarks for your application. For example, benchmark on a 64-bit systems: From 038ac01d2666c706322ea43d5127cc9d36ecc9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=BCseyin=20A=C3=A7acak?= <110401522+huseyinacacak-janea@users.noreply.github.com> Date: Wed, 6 Nov 2024 02:21:54 +0300 Subject: [PATCH 80/93] path,win: fix bug in resolve and normalize Fixes: https://github.com/nodejs/node/issues/54025 PR-URL: https://github.com/nodejs/node/pull/55623 Reviewed-By: Antoine du Hamel Reviewed-By: Ruben Bridgewater Reviewed-By: Luigi Pinca --- lib/path.js | 41 ++++++++++++++++++---------- src/path.cc | 13 +++++++-- test/cctest/test_path.cc | 4 +++ test/parallel/test-path-makelong.js | 2 +- test/parallel/test-path-normalize.js | 2 ++ test/parallel/test-path-resolve.js | 2 ++ 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/lib/path.js b/lib/path.js index eefa9bc5db0729..40161c45e2a911 100644 --- a/lib/path.js +++ b/lib/path.js @@ -268,10 +268,16 @@ const win32 = { j++; } if (j === len || j !== last) { - // We matched a UNC root - device = - `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; - rootEnd = j; + if (firstPart !== '.' && firstPart !== '?') { + // We matched a UNC root + device = + `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; + rootEnd = j; + } else { + // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0) + device = `\\\\${firstPart}`; + rootEnd = 4; + } } } } @@ -381,17 +387,22 @@ const win32 = { !isPathSeparator(StringPrototypeCharCodeAt(path, j))) { j++; } - if (j === len) { - // We matched a UNC root only - // Return the normalized version of the UNC root since there - // is nothing left to process - return `\\\\${firstPart}\\${StringPrototypeSlice(path, last)}\\`; - } - if (j !== last) { - // We matched a UNC root with leftovers - device = - `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; - rootEnd = j; + if (j === len || j !== last) { + if (firstPart === '.' || firstPart === '?') { + // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0) + device = `\\\\${firstPart}`; + rootEnd = 4; + } else if (j === len) { + // We matched a UNC root only + // Return the normalized version of the UNC root since there + // is nothing left to process + return `\\\\${firstPart}\\${StringPrototypeSlice(path, last)}\\`; + } else { + // We matched a UNC root with leftovers + device = + `\\\\${firstPart}\\${StringPrototypeSlice(path, last, j)}`; + rootEnd = j; + } } } } diff --git a/src/path.cc b/src/path.cc index 4068e1d892d6b7..47ddba31443644 100644 --- a/src/path.cc +++ b/src/path.cc @@ -170,9 +170,16 @@ std::string PathResolve(Environment* env, j++; } if (j == len || j != last) { - // We matched a UNC root - device = "\\\\" + firstPart + "\\" + path.substr(last, j - last); - rootEnd = j; + if (firstPart != "." && firstPart != "?") { + // We matched a UNC root + device = + "\\\\" + firstPart + "\\" + path.substr(last, j - last); + rootEnd = j; + } else { + // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0) + device = "\\\\" + firstPart; + rootEnd = 4; + } } } } diff --git a/test/cctest/test_path.cc b/test/cctest/test_path.cc index 16bd9872f3b035..9e860d02cf77bd 100644 --- a/test/cctest/test_path.cc +++ b/test/cctest/test_path.cc @@ -39,6 +39,10 @@ TEST_F(PathTest, PathResolve) { EXPECT_EQ( PathResolve(*env, {"C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js"}), "C:\\foo\\tmp.3\\cycles\\root.js"); + EXPECT_EQ(PathResolve(*env, {"\\\\.\\PHYSICALDRIVE0"}), + "\\\\.\\PHYSICALDRIVE0"); + EXPECT_EQ(PathResolve(*env, {"\\\\?\\PHYSICALDRIVE0"}), + "\\\\?\\PHYSICALDRIVE0"); #else EXPECT_EQ(PathResolve(*env, {"/var/lib", "../", "file/"}), "/var/file"); EXPECT_EQ(PathResolve(*env, {"/var/lib", "/../", "file/"}), "/file"); diff --git a/test/parallel/test-path-makelong.js b/test/parallel/test-path-makelong.js index 7a4783953c8fde..4a6589cb6b1a45 100644 --- a/test/parallel/test-path-makelong.js +++ b/test/parallel/test-path-makelong.js @@ -79,7 +79,7 @@ assert.strictEqual(path.win32.toNamespacedPath('\\\\foo\\bar'), '\\\\?\\UNC\\foo\\bar\\'); assert.strictEqual(path.win32.toNamespacedPath('//foo//bar'), '\\\\?\\UNC\\foo\\bar\\'); -assert.strictEqual(path.win32.toNamespacedPath('\\\\?\\foo'), '\\\\?\\foo\\'); +assert.strictEqual(path.win32.toNamespacedPath('\\\\?\\foo'), '\\\\?\\foo'); assert.strictEqual(path.win32.toNamespacedPath('\\\\?\\c:\\Windows/System'), '\\\\?\\c:\\Windows\\System'); assert.strictEqual(path.win32.toNamespacedPath(null), null); assert.strictEqual(path.win32.toNamespacedPath(true), true); diff --git a/test/parallel/test-path-normalize.js b/test/parallel/test-path-normalize.js index e1d3b9ce1e6c02..7a3d02cb7fe126 100644 --- a/test/parallel/test-path-normalize.js +++ b/test/parallel/test-path-normalize.js @@ -40,6 +40,8 @@ assert.strictEqual( '..\\..\\..\\..\\baz' ); assert.strictEqual(path.win32.normalize('foo/bar\\baz'), 'foo\\bar\\baz'); +assert.strictEqual(path.win32.normalize('\\\\.\\foo'), '\\\\.\\foo'); +assert.strictEqual(path.win32.normalize('\\\\.\\foo\\'), '\\\\.\\foo\\'); assert.strictEqual(path.posix.normalize('./fixtures///b/../b/c.js'), 'fixtures/b/c.js'); diff --git a/test/parallel/test-path-resolve.js b/test/parallel/test-path-resolve.js index 3fc9b2e3abd90a..6b1dfa7567d3d1 100644 --- a/test/parallel/test-path-resolve.js +++ b/test/parallel/test-path-resolve.js @@ -33,6 +33,8 @@ const resolveTests = [ [['c:/', '///some//dir'], 'c:\\some\\dir'], [['C:\\foo\\tmp.3\\', '..\\tmp.3\\cycles\\root.js'], 'C:\\foo\\tmp.3\\cycles\\root.js'], + [['\\\\.\\PHYSICALDRIVE0'], '\\\\.\\PHYSICALDRIVE0'], + [['\\\\?\\PHYSICALDRIVE0'], '\\\\?\\PHYSICALDRIVE0'], ], ], [ path.posix.resolve, From 15028dd073a4ff5049e9eb90285fcbc86f31b61c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 00:37:39 +0100 Subject: [PATCH 81/93] tools: update ESLint to 9.14.0 Bumps the eslint group with 7 updates in the /tools/eslint directory: | Package | From | To | | --- | --- | --- | | [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.25.2` | `7.26.0` | | [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) | `7.25.1` | `7.25.9` | | [@babel/plugin-syntax-import-attributes](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-syntax-import-attributes) | `7.25.6` | `7.26.0` | | [@stylistic/eslint-plugin-js](https://github.com/eslint-stylistic/eslint-stylistic/tree/HEAD/packages/eslint-plugin-js) | `2.8.0` | `2.10.1` | | [eslint](https://github.com/eslint/eslint) | `9.11.1` | `9.14.0` | | [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) | `50.3.1` | `50.4.3` | | [globals](https://github.com/sindresorhus/globals) | `15.10.0` | `15.11.0` | Updates `@babel/core` from 7.25.2 to 7.26.0 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.0/packages/babel-core) Updates `@babel/eslint-parser` from 7.25.1 to 7.25.9 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.25.9/eslint/babel-eslint-parser) Updates `@babel/plugin-syntax-import-attributes` from 7.25.6 to 7.26.0 - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.26.0/packages/babel-plugin-syntax-import-attributes) Updates `@stylistic/eslint-plugin-js` from 2.8.0 to 2.10.1 - [Release notes](https://github.com/eslint-stylistic/eslint-stylistic/releases) - [Changelog](https://github.com/eslint-stylistic/eslint-stylistic/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint-stylistic/eslint-stylistic/commits/v2.10.1/packages/eslint-plugin-js) Updates `eslint` from 9.11.1 to 9.14.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.11.1...v9.14.0) Updates `eslint-plugin-jsdoc` from 50.3.1 to 50.4.3 - [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases) - [Changelog](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/.releaserc) - [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v50.3.1...v50.4.3) Updates `globals` from 15.10.0 to 15.11.0 - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v15.10.0...v15.11.0) --- updated-dependencies: - dependency-name: "@babel/core" dependency-type: direct:production update-type: version-update:semver-minor dependency-group: eslint - dependency-name: "@babel/eslint-parser" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: eslint - dependency-name: "@babel/plugin-syntax-import-attributes" dependency-type: direct:production update-type: version-update:semver-minor dependency-group: eslint - dependency-name: "@stylistic/eslint-plugin-js" dependency-type: direct:production update-type: version-update:semver-minor dependency-group: eslint - dependency-name: eslint dependency-type: direct:production update-type: version-update:semver-minor dependency-group: eslint - dependency-name: eslint-plugin-jsdoc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: eslint - dependency-name: globals dependency-type: direct:production update-type: version-update:semver-minor dependency-group: eslint ... Signed-off-by: dependabot[bot] PR-URL: https://github.com/nodejs/node/pull/55689 Reviewed-By: Antoine du Hamel Reviewed-By: Luigi Pinca --- eslint.config.mjs | 2 +- test/es-module/test-esm-loader-hooks.mjs | 20 +- tools/doc/addon-verify.mjs | 6 +- tools/eslint/package-lock.json | 651 ++++++++--------------- tools/eslint/package.json | 14 +- 5 files changed, 235 insertions(+), 458 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index a26ea19154e8c7..2561c9359d73bd 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -289,7 +289,7 @@ export default [ 'error', { blankLine: 'always', prev: 'function', next: 'function' }, ], - '@stylistic/js/quotes': ['error', 'single', { avoidEscape: true }], + '@stylistic/js/quotes': ['error', 'single', { avoidEscape: true, allowTemplateLiterals: true }], '@stylistic/js/quote-props': ['error', 'consistent'], '@stylistic/js/rest-spread-spacing': 'error', '@stylistic/js/semi': 'error', diff --git a/test/es-module/test-esm-loader-hooks.mjs b/test/es-module/test-esm-loader-hooks.mjs index d35f0964fe36c4..4a4d15648a79b5 100644 --- a/test/es-module/test-esm-loader-hooks.mjs +++ b/test/es-module/test-esm-loader-hooks.mjs @@ -791,14 +791,14 @@ describe('Loader hooks', { concurrency: !process.env.TEST_PARALLEL }, () => { const hook = ` import { readFile } from 'node:fs/promises'; export ${ - async function load(url, context, nextLoad) { - const resolved = await nextLoad(url, context); - if (context.format === 'commonjs') { - resolved.source = await readFile(new URL(url)); - } - return resolved; - } -}`; + async function load(url, context, nextLoad) { + const resolved = await nextLoad(url, context); + if (context.format === 'commonjs') { + resolved.source = await readFile(new URL(url)); + } + return resolved; + } + }`; const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ '--no-warnings', @@ -807,8 +807,8 @@ describe('Loader hooks', { concurrency: !process.env.TEST_PARALLEL }, () => { `data:text/javascript,${encodeURIComponent(` import{ register } from "node:module"; register(${ - JSON.stringify('data:text/javascript,' + encodeURIComponent(hook)) -}); + JSON.stringify('data:text/javascript,' + encodeURIComponent(hook)) + }); `)}`, fixtures.path('source-map/throw-on-require.js'), ]); diff --git a/tools/doc/addon-verify.mjs b/tools/doc/addon-verify.mjs index 999fcc1c553ada..b30787dd7625ea 100644 --- a/tools/doc/addon-verify.mjs +++ b/tools/doc/addon-verify.mjs @@ -61,9 +61,9 @@ function verifyFiles(files, blockName) { files[name] = `'use strict'; const common = require('../../common'); ${files[name].replace( - "'./build/Release/addon'", - // eslint-disable-next-line no-template-curly-in-string - '`./build/${common.buildType}/addon`')} + "'./build/Release/addon'", + // eslint-disable-next-line no-template-curly-in-string + '`./build/${common.buildType}/addon`')} `; } return { diff --git a/tools/eslint/package-lock.json b/tools/eslint/package-lock.json index 6db5054e94c72d..61f754e77e10df 100644 --- a/tools/eslint/package-lock.json +++ b/tools/eslint/package-lock.json @@ -8,15 +8,15 @@ "name": "eslint-tools", "version": "0.0.0", "dependencies": { - "@babel/core": "^7.25.2", - "@babel/eslint-parser": "^7.25.1", - "@babel/plugin-syntax-import-attributes": "^7.25.6", - "@stylistic/eslint-plugin-js": "^2.8.0", - "eslint": "^9.11.1", + "@babel/core": "^7.26.0", + "@babel/eslint-parser": "^7.25.9", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@stylistic/eslint-plugin-js": "^2.10.1", + "eslint": "^9.14.0", "eslint-formatter-tap": "^8.40.0", - "eslint-plugin-jsdoc": "^50.3.1", + "eslint-plugin-jsdoc": "^50.4.3", "eslint-plugin-markdown": "^5.1.0", - "globals": "^15.10.0" + "globals": "^15.11.0" } }, "node_modules/@ampproject/remapping": { @@ -33,12 +33,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "license": "MIT", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -46,28 +46,28 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", - "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -83,9 +83,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.25.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz", - "integrity": "sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz", + "integrity": "sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ==", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", @@ -100,27 +100,28 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dependencies": { - "@babel/types": "^7.25.6", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -129,26 +130,25 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -158,86 +158,55 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "license": "MIT", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "license": "MIT", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", - "license": "MIT", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.26.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -247,11 +216,11 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", - "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.8" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -261,29 +230,28 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "license": "MIT", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -300,22 +268,21 @@ } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.48.0.tgz", - "integrity": "sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==", + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", + "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", "dependencies": { "comment-parser": "1.4.1", "esquery": "^1.6.0", @@ -353,10 +320,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "license": "MIT", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -375,9 +341,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -418,9 +384,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", - "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", + "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -444,6 +410,38 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -458,10 +456,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", - "license": "Apache-2.0", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.0.tgz", + "integrity": "sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==", "engines": { "node": ">=18.18" }, @@ -527,41 +524,6 @@ "eslint-scope": "5.1.1" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@pkgr/core": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", @@ -575,12 +537,12 @@ } }, "node_modules/@stylistic/eslint-plugin-js": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.8.0.tgz", - "integrity": "sha512-/e7pSzVMrwBd6yzSDsKHwax3TS96+pd/xSKzELaTkOuYqUhYfj/becWdfDbFSBGQD7BBBCiiE4L8L2cUfu5h+A==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.10.1.tgz", + "integrity": "sha512-IikL/RKy9Sk2UMDUUpqrEcwDeYzUEt6SaL2/UVCFuVQxKACHSgStT0NxXkxZmBOUforaU52FPf2Su07FYH5s5g==", "dependencies": { - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0" + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -590,10 +552,9 @@ } }, "node_modules/@stylistic/eslint-plugin-js/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "license": "Apache-2.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -627,10 +588,9 @@ "license": "MIT" }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "license": "MIT", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "bin": { "acorn": "bin/acorn" }, @@ -663,27 +623,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/are-docs-informative": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", @@ -716,9 +655,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "funding": [ { "type": "opencollective", @@ -734,10 +673,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -756,9 +695,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001662", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001662.tgz", - "integrity": "sha512-sgMUVwLmGseH8ZIrm1d51UbrhqMCH3jvS7gF/M6byuHOnKyLOBL7W8yz5V02OHwgLGA36o/AFhWzzh4uc5aqTA==", + "version": "1.0.30001676", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz", + "integrity": "sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==", "funding": [ { "type": "opencollective", @@ -772,22 +711,7 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } + ] }, "node_modules/character-entities": { "version": "1.2.4", @@ -819,21 +743,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, "node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -892,10 +801,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.27", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", - "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", - "license": "ISC" + "version": "1.5.50", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", + "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==" }, "node_modules/es-module-lexer": { "version": "1.5.4", @@ -911,30 +819,21 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/eslint": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", - "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", + "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", + "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", + "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.11.1", + "@eslint/js": "9.14.0", "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.4.0", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", @@ -942,9 +841,9 @@ "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -954,13 +853,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { @@ -994,11 +891,11 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "50.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.3.1.tgz", - "integrity": "sha512-SY9oUuTMr6aWoJggUS40LtMjsRzJPB5ZT7F432xZIHK3EfHF+8i48GbUBpwanrtlL9l1gILNTHK9o8gEhYLcKA==", + "version": "50.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.4.3.tgz", + "integrity": "sha512-uWtwFxGRv6B8sU63HZM5dAGDhgsatb+LONwmILZJhdRALLOkCX2HFZhdL/Kw2ls8SQMAVEfK+LmnEfxInRN8HA==", "dependencies": { - "@es-joy/jsdoccomment": "~0.48.0", + "@es-joy/jsdoccomment": "~0.49.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.3.6", @@ -1140,10 +1037,9 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", - "license": "BSD-2-Clause", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -1156,10 +1052,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "license": "Apache-2.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1171,7 +1066,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -1198,14 +1092,13 @@ } }, "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", - "license": "BSD-2-Clause", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1215,10 +1108,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "license": "Apache-2.0", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1304,15 +1196,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "license": "MIT" }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -1382,9 +1265,9 @@ } }, "node_modules/globals": { - "version": "15.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.10.0.tgz", - "integrity": "sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==", + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", + "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", "engines": { "node": ">=18" }, @@ -1392,15 +1275,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -1500,15 +1374,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1518,8 +1383,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -1542,14 +1406,14 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -1818,10 +1682,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "license": "ISC" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -1841,26 +1704,6 @@ "node": ">=6" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -1870,39 +1713,6 @@ "node": ">=4" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -1961,18 +1771,6 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "license": "CC0-1.0" }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1985,18 +1783,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/synckit": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", @@ -2019,15 +1805,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "license": "MIT" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", @@ -2060,9 +1837,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -2078,8 +1855,8 @@ } ], "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" diff --git a/tools/eslint/package.json b/tools/eslint/package.json index d5378441514eb9..39beeeb2ce1bd6 100644 --- a/tools/eslint/package.json +++ b/tools/eslint/package.json @@ -3,14 +3,14 @@ "version": "0.0.0", "private": true, "dependencies": { - "@babel/core": "^7.25.2", - "@babel/eslint-parser": "^7.25.1", - "@babel/plugin-syntax-import-attributes": "^7.25.6", - "@stylistic/eslint-plugin-js": "^2.8.0", - "eslint": "^9.11.1", + "@babel/core": "^7.26.0", + "@babel/eslint-parser": "^7.25.9", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@stylistic/eslint-plugin-js": "^2.10.1", + "eslint": "^9.14.0", "eslint-formatter-tap": "^8.40.0", - "eslint-plugin-jsdoc": "^50.3.1", + "eslint-plugin-jsdoc": "^50.4.3", "eslint-plugin-markdown": "^5.1.0", - "globals": "^15.10.0" + "globals": "^15.11.0" } } From 7d93c0c3ae6a3b674d98eac21313ae985876eb1c Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Tue, 5 Nov 2024 23:40:39 +0000 Subject: [PATCH 82/93] test: refactor some esm tests PR-URL: https://github.com/nodejs/node/pull/55472 Reviewed-By: James M Snell Reviewed-By: Chemi Atlow --- .../test-esm-import-meta-resolve.mjs | 23 ++++++++-------- test/es-module/test-esm-pkgname.mjs | 27 +++++++------------ 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/test/es-module/test-esm-import-meta-resolve.mjs b/test/es-module/test-esm-import-meta-resolve.mjs index f3b153062192af..49b6d1ff906ec3 100644 --- a/test/es-module/test-esm-import-meta-resolve.mjs +++ b/test/es-module/test-esm-import-meta-resolve.mjs @@ -1,22 +1,21 @@ // Flags: --experimental-import-meta-resolve import { spawnPromisified } from '../common/index.mjs'; +import { fileURL as fixturesFileURL } from '../common/fixtures.mjs'; import assert from 'assert'; import { spawn } from 'child_process'; import { execPath } from 'process'; -const dirname = import.meta.url.slice(0, import.meta.url.lastIndexOf('/') + 1); -const fixtures = dirname.slice(0, dirname.lastIndexOf('/', dirname.length - 2) + 1) + 'fixtures/'; +const fixtures = `${fixturesFileURL()}/`; assert.strictEqual(import.meta.resolve('./test-esm-import-meta.mjs'), - dirname + 'test-esm-import-meta.mjs'); + new URL('./test-esm-import-meta.mjs', import.meta.url).href); assert.strictEqual(import.meta.resolve('./notfound.mjs'), new URL('./notfound.mjs', import.meta.url).href); assert.strictEqual(import.meta.resolve('./asset'), new URL('./asset', import.meta.url).href); -try { +assert.throws(() => { import.meta.resolve('does-not-exist'); - assert.fail(); -} catch (e) { - assert.strictEqual(e.code, 'ERR_MODULE_NOT_FOUND'); -} +}, { + code: 'ERR_MODULE_NOT_FOUND', +}); assert.strictEqual( import.meta.resolve('../fixtures/empty-with-bom.txt'), fixtures + 'empty-with-bom.txt'); @@ -60,11 +59,11 @@ await assert.rejects(import('data:text/javascript,export default import.meta.res }); { - const cp = spawn(execPath, [ + const { stdout } = await spawnPromisified(execPath, [ '--input-type=module', '--eval', 'console.log(typeof import.meta.resolve)', ]); - assert.match((await cp.stdout.toArray()).toString(), /^function\r?\n$/); + assert.match(stdout, /^function\r?\n$/); } { @@ -76,11 +75,11 @@ await assert.rejects(import('data:text/javascript,export default import.meta.res } { - const cp = spawn(execPath, [ + const { stdout } = await spawnPromisified(execPath, [ '--input-type=module', '--eval', 'import "data:text/javascript,console.log(import.meta.resolve(%22node:os%22))"', ]); - assert.match((await cp.stdout.toArray()).toString(), /^node:os\r?\n$/); + assert.match(stdout, /^node:os\r?\n$/); } { diff --git a/test/es-module/test-esm-pkgname.mjs b/test/es-module/test-esm-pkgname.mjs index 5090d6c22ce689..6f2d538841e5cf 100644 --- a/test/es-module/test-esm-pkgname.mjs +++ b/test/es-module/test-esm-pkgname.mjs @@ -1,20 +1,13 @@ -import { mustCall } from '../common/index.mjs'; -import { strictEqual } from 'assert'; +import '../common/index.mjs'; +import assert from 'node:assert'; import { importFixture } from '../fixtures/pkgexports.mjs'; -importFixture('as%2Ff').catch(mustCall((err) => { - strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); -})); - -importFixture('as%5Cf').catch(mustCall((err) => { - strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); -})); - -importFixture('as\\df').catch(mustCall((err) => { - strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); -})); - -importFixture('@as@df').catch(mustCall((err) => { - strictEqual(err.code, 'ERR_INVALID_MODULE_SPECIFIER'); -})); +await Promise.all([ + 'as%2Ff', + 'as%5Cf', + 'as\\df', + '@as@df', +].map((specifier) => assert.rejects(importFixture(specifier), { + code: 'ERR_INVALID_MODULE_SPECIFIER', +}))); From 9dbb255efbf4db3ac394d7ea185563df3ca6d7d8 Mon Sep 17 00:00:00 2001 From: "Edigleysson Silva (Edy)" Date: Tue, 5 Nov 2024 20:45:05 -0300 Subject: [PATCH 83/93] assert: fix `deepStrictEqual` on errors when `cause` is not undefined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55406 Reviewed-By: James M Snell Reviewed-By: Antoine du Hamel Reviewed-By: Ulises Gascón Reviewed-By: Ruben Bridgewater --- lib/internal/assert/assertion_error.js | 11 ++++++ test/parallel/test-assert-deep-with-error.js | 39 ++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 test/parallel/test-assert-deep-with-error.js diff --git a/lib/internal/assert/assertion_error.js b/lib/internal/assert/assertion_error.js index dd56811647e5bf..5b4124e6b29700 100644 --- a/lib/internal/assert/assertion_error.js +++ b/lib/internal/assert/assertion_error.js @@ -15,6 +15,8 @@ const { StringPrototypeSplit, } = primordials; +const { isError } = require('internal/util'); + const { inspect } = require('internal/util/inspect'); const colors = require('internal/util/colors'); const { validateObject } = require('internal/validators'); @@ -47,6 +49,15 @@ function copyError(source) { __proto__: null, value: source.message, }); + if (source.cause !== undefined) { + let cause = source.cause; + + if (isError(cause)) { + cause = copyError(cause); + } + + ObjectDefineProperty(target, 'cause', { __proto__: null, value: cause }); + } return target; } diff --git a/test/parallel/test-assert-deep-with-error.js b/test/parallel/test-assert-deep-with-error.js new file mode 100644 index 00000000000000..b4186eb642302d --- /dev/null +++ b/test/parallel/test-assert-deep-with-error.js @@ -0,0 +1,39 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const { test } = require('node:test'); + +const defaultStartMessage = 'Expected values to be strictly deep-equal:\n' + + '+ actual - expected\n' + + '\n'; + +test('Handle error causes', () => { + assert.throws(() => { + assert.deepStrictEqual(new Error('a', { cause: new Error('x') }), new Error('a', { cause: new Error('y') })); + }, { message: defaultStartMessage + ' [Error: a] {\n' + + '+ [cause]: [Error: x]\n' + + '- [cause]: [Error: y]\n' + + ' }\n' }); + + assert.throws(() => { + assert.deepStrictEqual(new Error('a'), new Error('a', { cause: new Error('y') })); + }, { message: defaultStartMessage + '+ [Error: a]\n' + + '- [Error: a] {\n' + + '- [cause]: [Error: y]\n' + + '- }\n' }); + + assert.throws(() => { + assert.deepStrictEqual(new Error('a'), new Error('a', { cause: { prop: 'value' } })); + }, { message: defaultStartMessage + '+ [Error: a]\n' + + '- [Error: a] {\n' + + '- [cause]: {\n' + + '- prop: \'value\'\n' + + '- }\n' + + '- }\n' }); + + assert.notDeepStrictEqual(new Error('a', { cause: new Error('x') }), new Error('a', { cause: new Error('y') })); + assert.notDeepStrictEqual( + new Error('a', { cause: { prop: 'value' } }), + new Error('a', { cause: { prop: 'a different value' } }) + ); +}); From 10b68ed9753f07eb0c5ee3cb8414d93267d1f8fb Mon Sep 17 00:00:00 2001 From: Carlos Espa <43477095+Ceres6@users.noreply.github.com> Date: Wed, 6 Nov 2024 02:10:33 +0100 Subject: [PATCH 84/93] test: ignore unrelated events in FW watch tests Change assertions on `test-fs-watch-recursive-add-*` tests to only take into account change events that match the file. PR-URL: https://github.com/nodejs/node/pull/55605 Reviewed-By: Luigi Pinca Reviewed-By: Pietro Marchini Reviewed-By: Yagiz Nizipli Reviewed-By: James M Snell --- ...ecursive-add-file-to-existing-subfolder.js | 3 +- ...-watch-recursive-add-file-to-new-folder.js | 36 +++++++------------ ...st-fs-watch-recursive-add-file-with-url.js | 3 +- .../test-fs-watch-recursive-add-file.js | 3 +- .../test-fs-watch-recursive-add-folder.js | 3 +- 5 files changed, 16 insertions(+), 32 deletions(-) diff --git a/test/parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js b/test/parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js index 628ca4b2fdf805..511829fa385e52 100644 --- a/test/parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js +++ b/test/parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js @@ -40,9 +40,8 @@ const relativePath = path.join(file, path.basename(subfolderPath), childrenFile) const watcher = fs.watch(testDirectory, { recursive: true }); let watcherClosed = false; watcher.on('change', function(event, filename) { - assert.strictEqual(event, 'rename'); - if (filename === relativePath) { + assert.strictEqual(event, 'rename'); watcher.close(); watcherClosed = true; } diff --git a/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js b/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js index 32a397821b8502..fcc49bb7464937 100644 --- a/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js +++ b/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js @@ -33,32 +33,20 @@ const childrenAbsolutePath = path.join(filePath, childrenFile); const childrenRelativePath = path.join(path.basename(filePath), childrenFile); let watcherClosed = false; -function doWatch() { - const watcher = fs.watch(testDirectory, { recursive: true }); - watcher.on('change', function(event, filename) { +const watcher = fs.watch(testDirectory, { recursive: true }); +watcher.on('change', function(event, filename) { + if (filename === childrenRelativePath) { assert.strictEqual(event, 'rename'); - assert.ok(filename === path.basename(filePath) || filename === childrenRelativePath); - - if (filename === childrenRelativePath) { - watcher.close(); - watcherClosed = true; - } - }); - - // Do the write with a delay to ensure that the OS is ready to notify us. - setTimeout(() => { - fs.mkdirSync(filePath); - fs.writeFileSync(childrenAbsolutePath, 'world'); - }, common.platformTimeout(200)); -} + watcher.close(); + watcherClosed = true; + } +}); -if (common.isMacOS) { - // On macOS delay watcher start to avoid leaking previous events. - // Refs: https://github.com/libuv/libuv/pull/4503 - setTimeout(doWatch, common.platformTimeout(100)); -} else { - doWatch(); -} +// Do the write with a delay to ensure that the OS is ready to notify us. +setTimeout(() => { + fs.mkdirSync(filePath); + fs.writeFileSync(childrenAbsolutePath, 'world'); +}, common.platformTimeout(200)); process.once('exit', function() { assert(watcherClosed, 'watcher Object was not closed'); diff --git a/test/parallel/test-fs-watch-recursive-add-file-with-url.js b/test/parallel/test-fs-watch-recursive-add-file-with-url.js index ee726961c41e9e..852c7088d59792 100644 --- a/test/parallel/test-fs-watch-recursive-add-file-with-url.js +++ b/test/parallel/test-fs-watch-recursive-add-file-with-url.js @@ -35,9 +35,8 @@ tmpdir.refresh(); const watcher = fs.watch(url, { recursive: true }); let watcherClosed = false; watcher.on('change', function(event, filename) { - assert.strictEqual(event, 'rename'); - if (filename === path.basename(filePath)) { + assert.strictEqual(event, 'rename'); watcher.close(); watcherClosed = true; } diff --git a/test/parallel/test-fs-watch-recursive-add-file.js b/test/parallel/test-fs-watch-recursive-add-file.js index 27b933871cb403..e8724102c89ff8 100644 --- a/test/parallel/test-fs-watch-recursive-add-file.js +++ b/test/parallel/test-fs-watch-recursive-add-file.js @@ -31,9 +31,8 @@ const testFile = path.join(testDirectory, 'file-1.txt'); const watcher = fs.watch(testDirectory, { recursive: true }); let watcherClosed = false; watcher.on('change', function(event, filename) { - assert.strictEqual(event, 'rename'); - if (filename === path.basename(testFile)) { + assert.strictEqual(event, 'rename'); watcher.close(); watcherClosed = true; } diff --git a/test/parallel/test-fs-watch-recursive-add-folder.js b/test/parallel/test-fs-watch-recursive-add-folder.js index 1851a7850f66ff..1a6671de2f3617 100644 --- a/test/parallel/test-fs-watch-recursive-add-folder.js +++ b/test/parallel/test-fs-watch-recursive-add-folder.js @@ -33,9 +33,8 @@ tmpdir.refresh(); const watcher = fs.watch(testDirectory, { recursive: true }); let watcherClosed = false; watcher.on('change', function(event, filename) { - assert.strictEqual(event, 'rename'); - if (filename === path.basename(testFile)) { + assert.strictEqual(event, 'rename'); watcher.close(); watcherClosed = true; } From 7853462a6135b31d64e2e6513f45168329a88265 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Tue, 5 Nov 2024 20:24:39 -0500 Subject: [PATCH 85/93] src: provide workaround for container-overflow PR-URL: https://github.com/nodejs/node/pull/55591 Refs: https://github.com/nodejs/node/issues/55584 Reviewed-By: Shelley Vohr Reviewed-By: Yagiz Nizipli Reviewed-By: James M Snell --- src/node_modules.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/node_modules.cc b/src/node_modules.cc index dfd115a9eccc6b..16a9f923148835 100644 --- a/src/node_modules.cc +++ b/src/node_modules.cc @@ -100,11 +100,23 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON( if (ReadFileSync(&package_config.raw_json, path.data()) < 0) { return nullptr; } + // In some systems, std::string is annotated to generate an + // AddressSanitizer: container-overflow error when reading beyond the end of + // the string even when we are still within the capacity of the string. + // https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow + // https://github.com/nodejs/node/issues/55584 + // The next lines are a workaround to avoid this false positive. + size_t json_length = package_config.raw_json.size(); + package_config.raw_json.append(simdjson::SIMDJSON_PADDING, ' '); + simdjson::padded_string_view json_view(package_config.raw_json.data(), + json_length, + package_config.raw_json.size()); + // End of workaround simdjson::ondemand::document document; simdjson::ondemand::object main_object; simdjson::error_code error = - binding_data->json_parser.iterate(package_config.raw_json).get(document); + binding_data->json_parser.iterate(json_view).get(document); const auto throw_invalid_package_config = [error_context, path, realm]() { if (error_context == nullptr) { From 20cb52d1d8a964ea6b4dec98dd548f84b83bee70 Mon Sep 17 00:00:00 2001 From: Preveen P <31464911+preveen-stack@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:25:49 +0530 Subject: [PATCH 86/93] doc: clarity to available addon options bullet pointed addon optons; wording clarity; fixes typo PR-URL: https://github.com/nodejs/node/pull/55715 Reviewed-By: Gireesh Punathil Reviewed-By: Antoine du Hamel --- doc/api/addons.md | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/doc/api/addons.md b/doc/api/addons.md index 446a63b1a2fc8f..e0e00dca0b9e8b 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -8,20 +8,25 @@ _Addons_ are dynamically-linked shared objects written in C++. The [`require()`][require] function can load addons as ordinary Node.js modules. Addons provide an interface between JavaScript and C/C++ libraries. -There are three options for implementing addons: Node-API, nan, or direct -use of internal V8, libuv, and Node.js libraries. Unless there is a need for -direct access to functionality which is not exposed by Node-API, use Node-API. +There are three options for implementing addons: + +* Node-API +* `nan` ([Native Abstractions for Node.js][]) +* direct use of internal V8, libuv, and Node.js libraries + +Unless there is a need for direct access to functionality which is not\ +exposed by Node-API, use Node-API. Refer to [C/C++ addons with Node-API](n-api.md) for more information on Node-API. -When not using Node-API, implementing addons is complicated, -involving knowledge of several components and APIs: +When not using Node-API, implementing addons becomes more complex, requiring\ +knowledge of multiple components and APIs: * [V8][]: the C++ library Node.js uses to provide the - JavaScript implementation. V8 provides the mechanisms for creating objects, - calling functions, etc. V8's API is documented mostly in the + JavaScript implementation. It provides the mechanisms for creating objects, + calling functions, etc. The V8's API is documented mostly in the `v8.h` header file (`deps/v8/include/v8.h` in the Node.js source - tree), which is also available [online][v8-docs]. + tree), and is also available [online][v8-docs]. * [libuv][]: The C library that implements the Node.js event loop, its worker threads and all of the asynchronous behaviors of the platform. It also @@ -35,10 +40,10 @@ involving knowledge of several components and APIs: offloading work via libuv to non-blocking system operations, worker threads, or a custom use of libuv threads. -* Internal Node.js libraries. Node.js itself exports C++ APIs that addons can +* Internal Node.js libraries: Node.js itself exports C++ APIs that addons can use, the most important of which is the `node::ObjectWrap` class. -* Node.js includes other statically linked libraries including OpenSSL. These +* Other statically linked libraries (including OpenSSL): These other libraries are located in the `deps/` directory in the Node.js source tree. Only the libuv, OpenSSL, V8, and zlib symbols are purposefully re-exported by Node.js and may be used to various extents by addons. See @@ -148,8 +153,8 @@ invocation of `NODE_MODULE_INIT()`: * `Local module`, and * `Local context` -The choice to build a context-aware addon carries with it the responsibility of -carefully managing global static data. Since the addon may be loaded multiple +Building a context-aware addon requires careful management of global static data +to ensure stability and correctness. Since the addon may be loaded multiple times, potentially even from different threads, any global static data stored in the addon must be properly protected, and must not contain any persistent references to JavaScript objects. The reason for this is that JavaScript @@ -255,7 +260,7 @@ such as a main thread and a Worker thread, an add-on needs to either: * Be declared as context-aware using `NODE_MODULE_INIT()` as described above In order to support [`Worker`][] threads, addons need to clean up any resources -they may have allocated when such a thread exists. This can be achieved through +they may have allocated when such a thread exits. This can be achieved through the usage of the `AddEnvironmentCleanupHook()` function: ```cpp @@ -1273,7 +1278,7 @@ class MyObject : public node::ObjectWrap { #endif ``` -The implementation of `myobject.cc` is similar to before: +The implementation of `myobject.cc` remains similar to the previous version: ```cpp // myobject.cc From 4129bc72e20c3c5a6c97c0116123d5f5fc3ea2c2 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Wed, 6 Nov 2024 04:57:15 -0500 Subject: [PATCH 87/93] util: do not catch on circular `@@toStringTag` errors PR-URL: https://github.com/nodejs/node/pull/55544 Fixes: https://github.com/nodejs/node/issues/55539 Reviewed-By: James M Snell Co-Authored-By: Colin Ihrig --- lib/internal/util/inspect.js | 19 ++++++++----------- test/parallel/test-util-inspect.js | 9 +++++++++ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 9480bcb2619bb1..a697459468d7b9 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1072,6 +1072,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { ArrayPrototypePushApply(output, protoProps); } } catch (err) { + if (!isStackOverflowError(err)) throw err; const constructorName = StringPrototypeSlice(getCtxStyle(value, constructor, tag), 0, -1); return handleMaxCallStackSize(ctx, err, constructorName, indentationLvl); } @@ -1557,17 +1558,13 @@ function groupArrayElements(ctx, output, value) { } function handleMaxCallStackSize(ctx, err, constructorName, indentationLvl) { - if (isStackOverflowError(err)) { - ctx.seen.pop(); - ctx.indentationLvl = indentationLvl; - return ctx.stylize( - `[${constructorName}: Inspection interrupted ` + - 'prematurely. Maximum call stack size exceeded.]', - 'special', - ); - } - /* c8 ignore next */ - assert.fail(err.stack); + ctx.seen.pop(); + ctx.indentationLvl = indentationLvl; + return ctx.stylize( + `[${constructorName}: Inspection interrupted ` + + 'prematurely. Maximum call stack size exceeded.]', + 'special', + ); } function addNumericSeparator(integerString) { diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index b95d1c3784728b..3da292fc663c35 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1644,6 +1644,15 @@ util.inspect(process); assert.throws(() => util.inspect(new ThrowingClass()), /toStringTag error/); + const y = { + get [Symbol.toStringTag]() { + return JSON.stringify(this); + } + }; + const x = { y }; + y.x = x; + assert.throws(() => util.inspect(x), /TypeError: Converting circular structure to JSON/); + class NotStringClass { get [Symbol.toStringTag]() { return null; From 19da4de4755c1b0e4d5e8c3c997b680e68f0b734 Mon Sep 17 00:00:00 2001 From: RedYetiDev <38299977+RedYetiDev@users.noreply.github.com> Date: Mon, 30 Sep 2024 15:56:18 -0400 Subject: [PATCH 88/93] test: update `performance-timeline` wpt PR-URL: https://github.com/nodejs/node/pull/55197 Reviewed-By: Filip Skokan --- test/fixtures/wpt/README.md | 2 +- ...k-forward-cache-restoration.tentative.html | 95 ++++++++++++ .../droppedentriescount.any.js | 81 ++++++++++ .../idlharness-shadowrealm.window.js | 2 + ...avigation-id-detached-frame.tentative.html | 30 ++++ ...avigation-id-element-timing.tentative.html | 14 ++ .../navigation-id-initial-load.tentative.html | 49 ++++++ ...-long-task-task-attribution.tentative.html | 14 ++ .../navigation-id-mark-measure.tentative.html | 14 ++ .../navigation-id-reset.tentative.html | 53 +++++++ ...vigation-id-resource-timing.tentative.html | 14 ++ .../navigation-id-worker-created-entries.html | 27 ++++ .../navigation-id.helper.js | 144 ++++++++++++++++++ .../abort-block-bfcache.window.js | 21 +++ ...tion-timing-attributes.tentative.window.js | 55 +++++++ ...g-bfcache-reasons-stay.tentative.window.js | 47 ++++++ ...igation-timing-bfcache.tentative.window.js | 28 ++++ ...g-cross-origin-bfcache.tentative.window.js | 60 ++++++++ ...avigation-timing-fetch.tentative.window.js | 40 +++++ ...mes-without-attributes.tentative.window.js | 103 +++++++++++++ ...tion-timing-lock.https.tentative.window.js | 32 ++++ ...ing-navigation-failure.tentative.window.js | 26 ++++ ...on-timing-not-bfcached.tentative.window.js | 36 +++++ ...ng-redirect-on-history.tentative.window.js | 53 +++++++ ...vigation-timing-reload.tentative.window.js | 50 ++++++ ...ng-same-origin-bfcache.tentative.window.js | 61 ++++++++ ...ng-same-origin-replace.tentative.window.js | 43 ++++++ .../not-restored-reasons/test-helper.js | 57 +++++++ .../resources/child-frame.html | 7 + .../performance-timeline/resources/empty.html | 0 .../resources/going-back.html | 9 ++ .../resources/include-frames-helper.js | 60 ++++++++ .../resources/include-frames-subframe.html | 43 ++++++ .../resources/json_resource.json | 4 + .../resources/make_long_task.js | 4 + .../navigation-id-detached-frame-page.html | 21 +++ .../resources/worker-navigation-id.js | 6 + ...upportedEntryTypes-cross-realm-access.html | 18 +++ .../tentative/detached-frame.html | 27 ++++ .../tentative/include-frames-originA-A-A.html | 93 +++++++++++ .../tentative/include-frames-originA-A.html | 76 +++++++++ .../tentative/include-frames-originA-AA.html | 51 +++++++ .../tentative/include-frames-originA-AB.html | 53 +++++++ .../tentative/include-frames-originA-B-A.html | 91 +++++++++++ .../tentative/include-frames-originA-B-B.html | 57 +++++++ .../tentative/include-frames-originA-B.html | 50 ++++++ .../tentative/performance-entry-source.html | 37 +++++ .../with-filter-options-originA.html | 26 ++++ .../timing-removed-iframe.html | 16 ++ test/fixtures/wpt/versions.json | 2 +- test/wpt/status/performance-timeline.json | 53 +++++++ 51 files changed, 2053 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/wpt/performance-timeline/back-forward-cache-restoration.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/droppedentriescount.any.js create mode 100644 test/fixtures/wpt/performance-timeline/idlharness-shadowrealm.window.js create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-detached-frame.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-element-timing.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-initial-load.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-long-task-task-attribution.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-mark-measure.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-reset.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-resource-timing.tentative.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id-worker-created-entries.html create mode 100644 test/fixtures/wpt/performance-timeline/navigation-id.helper.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-attributes.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-fetch.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-lock.https.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-redirect-on-history.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-reload.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-replace.tentative.window.js create mode 100644 test/fixtures/wpt/performance-timeline/not-restored-reasons/test-helper.js create mode 100644 test/fixtures/wpt/performance-timeline/resources/child-frame.html create mode 100644 test/fixtures/wpt/performance-timeline/resources/empty.html create mode 100644 test/fixtures/wpt/performance-timeline/resources/going-back.html create mode 100644 test/fixtures/wpt/performance-timeline/resources/include-frames-helper.js create mode 100644 test/fixtures/wpt/performance-timeline/resources/include-frames-subframe.html create mode 100644 test/fixtures/wpt/performance-timeline/resources/json_resource.json create mode 100644 test/fixtures/wpt/performance-timeline/resources/make_long_task.js create mode 100644 test/fixtures/wpt/performance-timeline/resources/navigation-id-detached-frame-page.html create mode 100644 test/fixtures/wpt/performance-timeline/resources/worker-navigation-id.js create mode 100644 test/fixtures/wpt/performance-timeline/supportedEntryTypes-cross-realm-access.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/detached-frame.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A-A.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AA.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AB.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-A.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-B.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/performance-entry-source.html create mode 100644 test/fixtures/wpt/performance-timeline/tentative/with-filter-options-originA.html create mode 100644 test/fixtures/wpt/performance-timeline/timing-removed-iframe.html diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md index 048ce7e49a69ef..3c7b7fb845d70a 100644 --- a/test/fixtures/wpt/README.md +++ b/test/fixtures/wpt/README.md @@ -24,7 +24,7 @@ Last update: - html/webappapis/structured-clone: https://github.com/web-platform-tests/wpt/tree/47d3fb280c/html/webappapis/structured-clone - html/webappapis/timers: https://github.com/web-platform-tests/wpt/tree/5873f2d8f1/html/webappapis/timers - interfaces: https://github.com/web-platform-tests/wpt/tree/e90ece61d6/interfaces -- performance-timeline: https://github.com/web-platform-tests/wpt/tree/17ebc3aea0/performance-timeline +- performance-timeline: https://github.com/web-platform-tests/wpt/tree/94caab7038/performance-timeline - resource-timing: https://github.com/web-platform-tests/wpt/tree/22d38586d0/resource-timing - resources: https://github.com/web-platform-tests/wpt/tree/1e140d63ec/resources - streams: https://github.com/web-platform-tests/wpt/tree/2bd26e124c/streams diff --git a/test/fixtures/wpt/performance-timeline/back-forward-cache-restoration.tentative.html b/test/fixtures/wpt/performance-timeline/back-forward-cache-restoration.tentative.html new file mode 100644 index 00000000000000..c673e09cb461e0 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/back-forward-cache-restoration.tentative.html @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/droppedentriescount.any.js b/test/fixtures/wpt/performance-timeline/droppedentriescount.any.js new file mode 100644 index 00000000000000..4de816bdc42bd8 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/droppedentriescount.any.js @@ -0,0 +1,81 @@ +promise_test(t => { + // This setup is required for later tests as well. + // Await for a dropped entry. + return new Promise(res => { + // Set a buffer size of 0 so that new resource entries count as dropped. + performance.setResourceTimingBufferSize(0); + // Use an observer to make sure the promise is resolved only when the + // new entry has been created. + new PerformanceObserver(res).observe({type: 'resource'}); + fetch('resources/square.png?id=1'); + }).then(() => { + return new Promise(resolve => { + new PerformanceObserver(t.step_func((entries, obs, options) => { + assert_equals(options['droppedEntriesCount'], 0); + resolve(); + })).observe({type: 'mark'}); + performance.mark('test'); + })}); +}, 'Dropped entries count is 0 when there are no dropped entries of relevant type.'); + +promise_test(async t => { + return new Promise(resolve => { + new PerformanceObserver(t.step_func((entries, obs, options) => { + assert_equals(options['droppedEntriesCount'], 1); + resolve(); + })).observe({entryTypes: ['mark', 'resource']}); + performance.mark('meow'); + }); +}, 'Dropped entries correctly counted with multiple types.'); + +promise_test(t => { + return new Promise(resolve => { + new PerformanceObserver(t.step_func((entries, obs, options) => { + assert_equals(options['droppedEntriesCount'], 1, + 'There should have been some dropped resource timing entries at this point'); + resolve(); + })).observe({type: 'resource', buffered: true}); + }); +}, 'Dropped entries counted even if observer was not registered at the time.'); + +promise_test(t => { + return new Promise(resolve => { + let callback_ran = false; + new PerformanceObserver(t.step_func((entries, obs, options) => { + if (!callback_ran) { + assert_equals(options['droppedEntriesCount'], 2, + 'There should be two dropped entries right now.'); + fetch('resources/square.png?id=3'); + callback_ran = true; + } else { + assert_equals(options['droppedEntriesCount'], undefined, + 'droppedEntriesCount should be unset after the first callback!'); + resolve(); + } + })).observe({type: 'resource'}); + fetch('resources/square.png?id=2'); + }); +}, 'Dropped entries only surfaced on the first callback.'); + + +promise_test(t => { + return new Promise(resolve => { + let callback_ran = false; + let droppedEntriesCount = -1; + new PerformanceObserver(t.step_func((entries, obs, options) => { + if (!callback_ran) { + assert_greater_than(options['droppedEntriesCount'], 0, + 'There should be several dropped entries right now.'); + droppedEntriesCount = options['droppedEntriesCount']; + callback_ran = true; + obs.observe({type: 'mark'}); + performance.mark('woof'); + } else { + assert_equals(options['droppedEntriesCount'], droppedEntriesCount, + 'There should be droppedEntriesCount due to the new observe().'); + resolve(); + } + })).observe({type: 'resource'}); + fetch('resources/square.png?id=4'); + }); +}, 'Dropped entries surfaced after an observe() call!'); diff --git a/test/fixtures/wpt/performance-timeline/idlharness-shadowrealm.window.js b/test/fixtures/wpt/performance-timeline/idlharness-shadowrealm.window.js new file mode 100644 index 00000000000000..6caaa3306132bd --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/idlharness-shadowrealm.window.js @@ -0,0 +1,2 @@ +// META: script=/resources/idlharness-shadowrealm.js +idl_test_shadowrealm(["performance-timeline"], ["hr-time", "dom"]); diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-detached-frame.tentative.html b/test/fixtures/wpt/performance-timeline/navigation-id-detached-frame.tentative.html new file mode 100644 index 00000000000000..add11255af45c0 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-detached-frame.tentative.html @@ -0,0 +1,30 @@ + + + + + + The navigation_id Detached iframe Parent Page. + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-element-timing.tentative.html b/test/fixtures/wpt/performance-timeline/navigation-id-element-timing.tentative.html new file mode 100644 index 00000000000000..7ff415530bc69d --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-element-timing.tentative.html @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-initial-load.tentative.html b/test/fixtures/wpt/performance-timeline/navigation-id-initial-load.tentative.html new file mode 100644 index 00000000000000..b996f0f117922d --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-initial-load.tentative.html @@ -0,0 +1,49 @@ + + + + + + + +

This text is to trigger a LCP entry emission.

+ + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-long-task-task-attribution.tentative.html b/test/fixtures/wpt/performance-timeline/navigation-id-long-task-task-attribution.tentative.html new file mode 100644 index 00000000000000..e1da9100aeee55 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-long-task-task-attribution.tentative.html @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-mark-measure.tentative.html b/test/fixtures/wpt/performance-timeline/navigation-id-mark-measure.tentative.html new file mode 100644 index 00000000000000..30613ebb980eb0 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-mark-measure.tentative.html @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-reset.tentative.html b/test/fixtures/wpt/performance-timeline/navigation-id-reset.tentative.html new file mode 100644 index 00000000000000..f5a2428e5f568a --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-reset.tentative.html @@ -0,0 +1,53 @@ + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-resource-timing.tentative.html b/test/fixtures/wpt/performance-timeline/navigation-id-resource-timing.tentative.html new file mode 100644 index 00000000000000..6d0614a6e23940 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-resource-timing.tentative.html @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/navigation-id-worker-created-entries.html b/test/fixtures/wpt/performance-timeline/navigation-id-worker-created-entries.html new file mode 100644 index 00000000000000..96fc57be1d426c --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id-worker-created-entries.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/navigation-id.helper.js b/test/fixtures/wpt/performance-timeline/navigation-id.helper.js new file mode 100644 index 00000000000000..1b72fe9908d573 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/navigation-id.helper.js @@ -0,0 +1,144 @@ +// The test functions called in the navigation-counter test. They rely on +// artifacts defined in +// '/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js' +// which should be included before this file to use these functions. + +// This function is to obtain navigation ids of all performance entries to +// verify. +let testInitial = () => { + return window.performance.getEntries().map(e => e.navigationId); +} + +let testMarkMeasure = (markId, markName, MeasureName) => { + const markName1 = 'test-mark'; + const markName2 = 'test-mark' + markId; + const measureName = 'test-measure' + markId; + + window.performance.mark(markName1); + window.performance.mark(markName2); + window.performance.measure(measureName, markName1, markName2); + return window.performance.getEntriesByName(markName2).concat( + window.performance.getEntriesByName(measureName)).map(e => e.navigationId); +} + +let testResourceTiming = async (resourceTimingEntryId) => { + let navigationId; + + let p = new Promise(resolve => { + new PerformanceObserver((list) => { + const entry = list.getEntries().find( + e => e.name.includes('json_resource' + resourceTimingEntryId)); + if (entry) { + navigationId = entry.navigationId; + resolve(); + } + }).observe({ type: 'resource' }); + }); + + const resp = await fetch( + '/performance-timeline/resources/json_resource' + resourceTimingEntryId + '.json'); + await p; + return [navigationId]; +} + +let testElementTiming = async (elementTimingEntryId) => { + let navigationId; + let p = new Promise(resolve => { + new PerformanceObserver((list) => { + const entry = list.getEntries().find( + e => e.entryType === 'element' && e.identifier === 'test-element-timing' + elementTimingEntryId); + if (entry) { + navigationId = entry.navigationId; + resolve(); + } + }).observe({ type: 'element' }); + }); + + let el = document.createElement('p'); + el.setAttribute('elementtiming', 'test-element-timing' + elementTimingEntryId); + el.textContent = 'test element timing text'; + document.body.appendChild(el); + await p; + return [navigationId]; +} + +let testLongTask = async () => { + let navigationIds = []; + + let p = new Promise(resolve => { + new PerformanceObserver((list) => { + const entry = list.getEntries().find(e => e.entryType === 'longtask') + if (entry) { + navigationIds.push(entry.navigationId); + navigationIds = navigationIds.concat( + entry.attribution.map(a => a.navigationId)); + resolve(); + } + }).observe({ type: 'longtask' }); + }); + + const script = document.createElement('script'); + script.src = '/performance-timeline/resources/make_long_task.js'; + document.body.appendChild(script); + await p; + document.body.removeChild(script); + return navigationIds; +} + +const testFunctionMap = { + 'mark_measure': testMarkMeasure, + 'resource_timing': testResourceTiming, + 'element_timing': testElementTiming, + 'long_task_task_attribution': testLongTask, +}; + +function runNavigationIdTest(params, description) { + const defaultParams = { + openFunc: url => window.open(url, '_blank', 'noopener'), + scripts: [], + funcBeforeNavigation: () => { }, + targetOrigin: originCrossSite, + navigationTimes: 4, + funcAfterAssertion: () => { }, + } // Apply defaults. + params = { ...defaultParams, ...params }; + + promise_test(async t => { + const pageA = new RemoteContext(token()); + const pageB = new RemoteContext(token()); + + const urlA = executorPath + pageA.context_id; + const urlB = params.targetOrigin + executorPath + pageB.context_id; + // Open url A. + params.openFunc(urlA); + await pageA.execute_script(waitForPageShow); + + // Assert navigation ids of all performance entries are the same. + let navigationIds = await pageA.execute_script(testInitial); + assert_true( + navigationIds.every(t => t === navigationIds[0]), + 'Navigation Ids should be the same as the initial load.'); + + for (i = 1; i <= params.navigationTimes; i++) { + // Navigate away to url B and back. + await navigateAndThenBack(pageA, pageB, urlB); + + // Assert new navigation ids are generated when the document is load from bfcache. + let nextNavigationIds = await pageA.execute_script( + testFunctionMap[params.testName], [i + 1]); + + // Assert navigation ids of all performance entries are the same. + assert_true( + nextNavigationIds.every(t => t === nextNavigationIds[0]), + 'All Navigation Ids should be same after bfcache navigation.'); + + // Assert navigation ids after bfcache navigation are different from those before. + assert_true( + navigationIds[0] !== nextNavigationIds[0], + params.testName + + ' Navigation Ids should be re-generated and different from the previous ones.'); + + navigationIds = nextNavigationIds; + } + }, description); +} \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js new file mode 100644 index 00000000000000..e5dbb0f43c8dd3 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js @@ -0,0 +1,21 @@ +// META: title=Aborting a parser should block bfcache +// META: script=./test-helper.js +// META: timeout=long + + +async_test(t => { + if (!sessionStorage.getItem("pageVisited")) { + // This is the first time loading the page. + sessionStorage.setItem("pageVisited", 1); + t.step_timeout(() => { + // Go to another page and instantly come back to this page. + location.href = new URL("../resources/going-back.html", window.location); + }, 0); + // Abort parsing in the middle of loading the page. + window.stop(); + } else { + const nrr = performance.getEntriesByType('navigation')[0].notRestoredReasons; + assert_true(ReasonsInclude(nrr.reasons, "parser-aborted")); + t.done(); + } +}, "aborting a parser should block bfcache."); diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-attributes.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-attributes.tentative.window.js new file mode 100644 index 00000000000000..44495fa981b752 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-attributes.tentative.window.js @@ -0,0 +1,55 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; + +// Ensure that empty attributes are reported as empty strings and missing +// attributes are reported as null. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + // Add a cross-origin iframe. + const rc1_child = await rc1.addIframe( + /*extraConfig=*/ { + origin: 'HTTP_REMOTE_ORIGIN', + scripts: [], + headers: [], + }, + /*attributes=*/ {id: '', name: ''}, + ); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + const rc1_child_url = await rc1_child.executeScript(() => { + return location.href; + }); + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'websocket'}], + /*children=*/[{ + 'url': null, + 'src': rc1_child_url, + // Id and name should be empty. + 'id': '', + 'name': '', + 'reasons': null, + 'children': null + }]); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js new file mode 100644 index 00000000000000..28dbc38575a3b2 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js @@ -0,0 +1,47 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; + +// Ensure that notRestoredReasons are only updated after non BFCache navigation. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'websocket'}], + /*children=*/ []); + + // This time no blocking feature is used, so the page is restored + // from BFCache. Ensure that the previous reasons stay there. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'websocket'}], + /*children=*/ []); +}); diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.tentative.window.js new file mode 100644 index 00000000000000..bfb685451c36d6 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-bfcache.tentative.window.js @@ -0,0 +1,28 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: timeout=long + +'use strict'; + +// Ensure that notRestoredReasons is empty for successful BFCache restore. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + + // Check the BFCache result and verify that no reasons are recorded + // for successful restore. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); + assert_true(await rc1.executeScript(() => { + let reasons = + performance.getEntriesByType('navigation')[0].notRestoredReasons; + return reasons === null; + })); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.tentative.window.js new file mode 100644 index 00000000000000..2a313fe7b14334 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.tentative.window.js @@ -0,0 +1,60 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; + +// Ensure that cross-origin subtree's reasons are not exposed to +// notRestoredReasons. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + // Add a cross-origin iframe. + const rc1_child = await rc1.addIframe( + /*extraConfig=*/ { + origin: 'HTTP_REMOTE_ORIGIN', + scripts: [], + headers: [], + }, + /*attributes=*/ {id: 'test-id'}, + ); + // Use WebSocket to block BFCache. + await useWebSocket(rc1_child); + const rc1_child_url = await rc1_child.executeScript(() => { + return location.href; + }); + // Add a child to the iframe. + const rc1_grand_child = await rc1_child.addIframe(); + const rc1_grand_child_url = await rc1_grand_child.executeScript(() => { + return location.href; + }); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': "masked"}], + /*children=*/[{ + 'url': null, + 'src': rc1_child_url, + 'id': 'test-id', + 'name': null, + 'reasons': null, + 'children': null + }]); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-fetch.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-fetch.tentative.window.js new file mode 100644 index 00000000000000..c8f53a660fa9a1 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-fetch.tentative.window.js @@ -0,0 +1,40 @@ +// META: title=Ensure that ongoing fetch upon entering bfcache blocks bfcache and recorded. +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: timeout=long + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + const wavURL = new URL(get_host_info().HTTP_REMOTE_ORIGIN + '/fetch/range/resources/long-wav.py'); + await rc1.executeScript((wavURL) => { + // Register pagehide handler to create a fetch request. + addEventListener('pagehide', (wavURL) => { + fetch(wavURL, { + keepalive: true + }); + }) + }); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'fetch'}], + /*children=*/[]); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js new file mode 100644 index 00000000000000..cda0ac43944742 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js @@ -0,0 +1,103 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; + +// Ensure that empty attributes are reported as empty strings and missing +// attributes are reported as null. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + // Add a cross-origin iframe. + const rc1_child = await rc1.addIframe( + /*extraConfig=*/ { + origin: 'HTTP_REMOTE_ORIGIN', + scripts: [], + headers: [], + }, + /*attributes=*/ {id: '', name: ''}, + ); + const rc2_child = await rc1.addIframe( + /*extraConfig=*/ { + origin: 'HTTP_REMOTE_ORIGIN', + scripts: [], + headers: [], + }, + /*attributes=*/ {}, + ); + const rc3_child = await rc1.addIframe( + /*extraConfig=*/ {}, + /*attributes=*/ {}, + ); + const rc4_child = await rc1.addIframe( + /*extraConfig=*/ {}, + /*attributes=*/ {id: '', name: ''}, + ); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + const rc1_child_url = await rc1_child.executeScript(() => { + return location.href; + }); + const rc2_child_url = await rc2_child.executeScript(() => { + return location.href; + }); + const rc3_child_url = await rc3_child.executeScript(() => { + return location.href; + }); + const rc4_child_url = await rc4_child.executeScript(() => { + return location.href; + }); + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'websocket'}], + /*children=*/[{ + 'url': null, + 'src': rc1_child_url, + // Id and name should be empty. + 'id': '', + 'name': '', + 'reasons': null, + 'children': null + }, { + 'url': null, + 'src': rc2_child_url, + // Id and name should be null. + 'id': null, + 'name': null, + 'reasons': null, + 'children': null + },{ + 'url': rc3_child_url, + 'src': rc3_child_url, + // Id and name should be null. + 'id': null, + 'name': null, + 'reasons': [], + 'children': [] + }, { + 'url': rc4_child_url, + 'src': rc4_child_url, + 'id': '', + 'name': '', + 'reasons': [], + 'children': [] + }]); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-lock.https.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-lock.https.tentative.window.js new file mode 100644 index 00000000000000..46d8752f20d967 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-lock.https.tentative.window.js @@ -0,0 +1,32 @@ +// META: title=Ensure that if WebLock is held upon entering bfcache, it cannot enter bfcache and gets reported. +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: timeout=long + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + + // Request a WebLock. + let return_value = await rc1.executeScript(() => { + return new Promise((resolve) => { + navigator.locks.request('resource', () => { + resolve(42); + }); + }) + }); + assert_equals(return_value, 42); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredFromBFCache(rc1, ['lock']); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js new file mode 100644 index 00000000000000..faa7649bc33c3f --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js @@ -0,0 +1,26 @@ +// META: title=Ensure that navigation failure blocks bfcache and gets recorded. +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/404.py +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: timeout=long + +'use strict'; +const {ORIGIN} = get_host_info(); + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ {status: 404}, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredFromBFCache(rc1, ['response-status-not-ok']); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.tentative.window.js new file mode 100644 index 00000000000000..1cf1d55d90f78a --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-not-bfcached.tentative.window.js @@ -0,0 +1,36 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; + +// Ensure that notRestoredReasons is populated when not restored. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'websocket'}], + /*children=*/ []); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-redirect-on-history.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-redirect-on-history.tentative.window.js new file mode 100644 index 00000000000000..7191456cc845bd --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-redirect-on-history.tentative.window.js @@ -0,0 +1,53 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; +const {ORIGIN, REMOTE_ORIGIN} = get_host_info(); + +// Ensure that notRestoredReasons reset after the server redirect. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + + // Create a remote context with the redirected URL. + let rc1_redirected = + await rcHelper.createContext(/*extraConfig=*/ { + origin: 'HTTP_ORIGIN', + scripts: [], + headers: [], + }); + + const redirectUrl = + `${ORIGIN}/common/redirect.py?location=${encodeURIComponent(rc1_redirected.url)}`; + // Replace the history state. + await rc1.executeScript((url) => { + window.history.replaceState(null, '', url); + }, [redirectUrl]); + + // Navigate away. + const newRemoteContextHelper = await rc1.navigateToNew(); + + // Go back. + await newRemoteContextHelper.historyBack(); + + const navigation_entry = await rc1_redirected.executeScript(() => { + return performance.getEntriesByType('navigation')[0]; + }); + assert_equals( + navigation_entry.redirectCount, 1, 'Expected redirectCount is 1.'); + // Becauase of the redirect, notRestoredReasons is reset. + assert_equals( + navigation_entry.notRestoredReasons, null, + 'Expected notRestoredReasons is null.'); +}); diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-reload.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-reload.tentative.window.js new file mode 100644 index 00000000000000..1a8972778d287c --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-reload.tentative.window.js @@ -0,0 +1,50 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; +const {ORIGIN, REMOTE_ORIGIN} = get_host_info(); + +// Ensure that notRestoredReasons reset after the server redirect. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'websocket'}], + /*children=*/ []); + + // Reload. + await rc1.navigate(() => { + location.reload(); + }, []); + + // Becauase of the reload, notRestoredReasons is reset. + const navigation_entry = await rc1.executeScript(() => { + return performance.getEntriesByType('navigation')[0]; + }); + + assert_equals( + navigation_entry.notRestoredReasons, null, + 'Expected notRestoredReasons is null.'); +}); diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.js new file mode 100644 index 00000000000000..89d66b070ed8c4 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.js @@ -0,0 +1,61 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + + +'use strict'; + +// Ensure that same-origin subtree's reasons are exposed to notRestoredReasons. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + // Add a same-origin iframe and use WebSocket. + const rc1_child = await rc1.addIframe( + /*extra_config=*/ {}, /*attributes=*/ {id: 'test-id'}); + await useWebSocket(rc1_child); + + const rc1_child_url = await rc1_child.executeScript(() => { + return location.href; + }); + // Add a child to the iframe. + const rc1_grand_child = await rc1_child.addIframe(); + const rc1_grand_child_url = await rc1_grand_child.executeScript(() => { + return location.href; + }); + + // Check the BFCache result and the reported reasons. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[], + /*children=*/[{ + 'url': rc1_child_url, + 'src': rc1_child_url, + 'id': 'test-id', + 'name': '', + 'reasons': [{'reason': 'websocket'}], + 'children': [{ + 'url': rc1_grand_child_url, + 'src': rc1_grand_child_url, + 'id': '', + 'name': '', + 'reasons': [], + 'children': [] + }] + }]); +}); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-replace.tentative.window.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-replace.tentative.window.js new file mode 100644 index 00000000000000..1162bfaf7600fd --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/performance-navigation-timing-same-origin-replace.tentative.window.js @@ -0,0 +1,43 @@ +// META: title=RemoteContextHelper navigation using BFCache +// META: script=./test-helper.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: timeout=long + +'use strict'; + +// Ensure that notRestoredReasons are accessible after history replace. +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + const rc1_url = await rc1.executeScript(() => { + return location.href; + }); + + // Use WebSocket to block BFCache. + await useWebSocket(rc1); + // Navigate away. + const newRemoteContextHelper = await rc1.navigateToNew(); + // Replace the history state to a same-origin site. + await newRemoteContextHelper.executeScript((destUrl) => { + window.history.replaceState(null, '', '#'); + }); + // Go back. + await newRemoteContextHelper.historyBack(); + + // Reasons are not reset for same-origin replace. + await assertNotRestoredReasonsEquals( + rc1, + /*url=*/ rc1_url, + /*src=*/ null, + /*id=*/ null, + /*name=*/ null, + /*reasons=*/[{'reason': 'websocket'}], + /*children=*/ []); +}); diff --git a/test/fixtures/wpt/performance-timeline/not-restored-reasons/test-helper.js b/test/fixtures/wpt/performance-timeline/not-restored-reasons/test-helper.js new file mode 100644 index 00000000000000..ba9a4c0342fcb5 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/not-restored-reasons/test-helper.js @@ -0,0 +1,57 @@ +// META: script=../../html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js + +async function assertNotRestoredReasonsEquals( + remoteContextHelper, url, src, id, name, reasons, children) { + let result = await remoteContextHelper.executeScript(() => { + return performance.getEntriesByType('navigation')[0].notRestoredReasons; + }); + assertReasonsStructEquals( + result, url, src, id, name, reasons, children); +} + +function assertReasonsStructEquals( + result, url, src, id, name, reasons, children) { + assert_equals(result.url, url); + assert_equals(result.src, src); + assert_equals(result.id, id); + assert_equals(result.name, name); + + // Reasons should match. + let expected = new Set(reasons); + let actual = new Set(result.reasons); + matchReasons(extractReason(expected), extractReason(actual)); + + // Children should match. + if (children == null) { + assert_equals(result.children, children); + } else { + for (let j = 0; j < children.length; j++) { + assertReasonsStructEquals( + result.children[j], children[j].url, + children[j].src, children[j].id, children[j].name, children[j].reasons, + children[j].children); + } + } +} + +function ReasonsInclude(reasons, targetReason) { + for (const reason of reasons) { + if (reason.reason == targetReason) { + return true; + } + } + return false; +} + +// Requires: +// - /websockets/constants.sub.js in the test file and pass the domainPort +// constant here. +async function useWebSocket(remoteContextHelper) { + let return_value = await remoteContextHelper.executeScript((domain) => { + return new Promise((resolve) => { + var webSocketInNotRestoredReasonsTests = new WebSocket(domain + '/echo'); + webSocketInNotRestoredReasonsTests.onopen = () => { resolve(42); }; + }); + }, [SCHEME_DOMAIN_PORT]); + assert_equals(return_value, 42); +} \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/resources/child-frame.html b/test/fixtures/wpt/performance-timeline/resources/child-frame.html new file mode 100644 index 00000000000000..40c8f7268857d0 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/child-frame.html @@ -0,0 +1,7 @@ + + + + + diff --git a/test/fixtures/wpt/performance-timeline/resources/empty.html b/test/fixtures/wpt/performance-timeline/resources/empty.html new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/test/fixtures/wpt/performance-timeline/resources/going-back.html b/test/fixtures/wpt/performance-timeline/resources/going-back.html new file mode 100644 index 00000000000000..f4a26669baa163 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/going-back.html @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/resources/include-frames-helper.js b/test/fixtures/wpt/performance-timeline/resources/include-frames-helper.js new file mode 100644 index 00000000000000..a56489baaf4d06 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/include-frames-helper.js @@ -0,0 +1,60 @@ +const verifyEntries = (entries, filterOptions) => { + for (const filterOption of filterOptions) { + let countBeforeFiltering = entries.length; + + // Using negate of the condition so that the next filtering is applied on less entries. + entries = entries.filter( + e => !(e.entryType == filterOption['entryType'] && e.name.includes(filterOption['name']))); + + assert_equals( + countBeforeFiltering - entries.length, filterOption['expectedCount'], filterOption['failureMsg']); + } +} + +const createFilterOption = (name, entryType, expectedCount, msgPrefix, description = '') => { + if (description) { + description = ' ' + description; + } + + let failureMsg = + `${msgPrefix} should have ${expectedCount} ${entryType} entries for name ${name}` + description; + + return { + name: name, + entryType: entryType, + expectedCount: expectedCount, + failureMsg: failureMsg + }; +} + +const loadChildFrame = (src) => { + return new Promise(resolve => { + + const childFrame = document.createElement('iframe'); + + childFrame.addEventListener("load", resolve); + + childFrame.src = src; + + document.body.appendChild(childFrame); + }); +} + +const loadChildFrameAndGrandchildFrame = (src) => { + return new Promise(resolve => { + + const crossOriginChildFrame = document.createElement('iframe'); + + // Wait for the child frame to send a message. The child frame would send a message + // when it loads its child frame. + window.addEventListener('message', e => { + if (e.data == 'Load completed') { + resolve(); + } + }); + + crossOriginChildFrame.src = src; + + document.body.appendChild(crossOriginChildFrame) + }); +} diff --git a/test/fixtures/wpt/performance-timeline/resources/include-frames-subframe.html b/test/fixtures/wpt/performance-timeline/resources/include-frames-subframe.html new file mode 100644 index 00000000000000..0d43f418a096a0 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/include-frames-subframe.html @@ -0,0 +1,43 @@ + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/resources/json_resource.json b/test/fixtures/wpt/performance-timeline/resources/json_resource.json new file mode 100644 index 00000000000000..68b6ac1d56f7c2 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/json_resource.json @@ -0,0 +1,4 @@ +{ + "name": "nav_id_test", + "target": "resource_timing" +} \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/resources/make_long_task.js b/test/fixtures/wpt/performance-timeline/resources/make_long_task.js new file mode 100644 index 00000000000000..a52d6d839298cc --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/make_long_task.js @@ -0,0 +1,4 @@ +(function () { + let now = window.performance.now(); + while (window.performance.now() < now + 60); +}()); \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/resources/navigation-id-detached-frame-page.html b/test/fixtures/wpt/performance-timeline/resources/navigation-id-detached-frame-page.html new file mode 100644 index 00000000000000..02aafbb5c78368 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/navigation-id-detached-frame-page.html @@ -0,0 +1,21 @@ + + + + + + The navigation_id Detached iframe Page. + + + + + + + \ No newline at end of file diff --git a/test/fixtures/wpt/performance-timeline/resources/worker-navigation-id.js b/test/fixtures/wpt/performance-timeline/resources/worker-navigation-id.js new file mode 100644 index 00000000000000..3a2740d0675c84 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/resources/worker-navigation-id.js @@ -0,0 +1,6 @@ +self.onmessage = () => { + const mark_name = 'user_timig_mark'; + performance.mark(mark_name); + postMessage(performance.getEntriesByName(mark_name)[0].navigationId); + self.close(); +} diff --git a/test/fixtures/wpt/performance-timeline/supportedEntryTypes-cross-realm-access.html b/test/fixtures/wpt/performance-timeline/supportedEntryTypes-cross-realm-access.html new file mode 100644 index 00000000000000..8b86a6398bfd49 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/supportedEntryTypes-cross-realm-access.html @@ -0,0 +1,18 @@ + + +Cross-realm access of supportedEntryTypes returns Array of another realm + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/detached-frame.html b/test/fixtures/wpt/performance-timeline/tentative/detached-frame.html new file mode 100644 index 00000000000000..70019223a648d9 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/detached-frame.html @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A-A.html b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A-A.html new file mode 100644 index 00000000000000..57623e5b33bfb0 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A-A.html @@ -0,0 +1,93 @@ + + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A.html b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A.html new file mode 100644 index 00000000000000..bcb9a81657f227 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-A.html @@ -0,0 +1,76 @@ + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AA.html b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AA.html new file mode 100644 index 00000000000000..cccbf4100dd2ae --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AA.html @@ -0,0 +1,51 @@ + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AB.html b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AB.html new file mode 100644 index 00000000000000..d630665b652cb1 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-AB.html @@ -0,0 +1,53 @@ + + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-A.html b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-A.html new file mode 100644 index 00000000000000..58cad40faba658 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-A.html @@ -0,0 +1,91 @@ + + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-B.html b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-B.html new file mode 100644 index 00000000000000..2368a8e881aa3a --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B-B.html @@ -0,0 +1,57 @@ + + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B.html b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B.html new file mode 100644 index 00000000000000..b823d6edaa3262 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/include-frames-originA-B.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/performance-entry-source.html b/test/fixtures/wpt/performance-timeline/tentative/performance-entry-source.html new file mode 100644 index 00000000000000..d10d3c5ed512b7 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/performance-entry-source.html @@ -0,0 +1,37 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/tentative/with-filter-options-originA.html b/test/fixtures/wpt/performance-timeline/tentative/with-filter-options-originA.html new file mode 100644 index 00000000000000..6c6643df75cf09 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/tentative/with-filter-options-originA.html @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/test/fixtures/wpt/performance-timeline/timing-removed-iframe.html b/test/fixtures/wpt/performance-timeline/timing-removed-iframe.html new file mode 100644 index 00000000000000..43988b21fbbe02 --- /dev/null +++ b/test/fixtures/wpt/performance-timeline/timing-removed-iframe.html @@ -0,0 +1,16 @@ + + + + + + + diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json index 103e3962845f20..6d521f98a4abfa 100644 --- a/test/fixtures/wpt/versions.json +++ b/test/fixtures/wpt/versions.json @@ -56,7 +56,7 @@ "path": "interfaces" }, "performance-timeline": { - "commit": "17ebc3aea0d6321e69554067c39ab5855e6fb67e", + "commit": "94caab7038b27c16d605fa3547dacbee3a2fde4e", "path": "performance-timeline" }, "resource-timing": { diff --git a/test/wpt/status/performance-timeline.json b/test/wpt/status/performance-timeline.json index 73e1aad56cf707..799ee97538d08b 100644 --- a/test/wpt/status/performance-timeline.json +++ b/test/wpt/status/performance-timeline.json @@ -21,5 +21,58 @@ }, "webtiming-resolution.any.js": { "skip": "flaky" + }, + "not-restored-reasons/performance-navigation-timing-attributes.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-bfcache-reasons-stay.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-bfcache.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-cross-origin-bfcache.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-fetch.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-lock.https.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-not-bfcached.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-redirect-on-history.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-reload.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-same-origin-bfcache.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/performance-navigation-timing-same-origin-replace.tentative.window.js": { + "skip": "Depends on HTML WPT" + }, + "not-restored-reasons/abort-block-bfcache.window.js": { + "fail": { + "note": "Requires window.stop()", + "expected": [ + "aborting a parser should block bfcache." + ] + } + }, + "idlharness-shadowrealm.window.js": { + "skip": "ShadowRealm support is not enabled" + }, + "droppedentriescount.any.js": { + "skip": "WPTRunner does not support fetch()" } } From ee12431298a2eb9d626eb2165056928241b4a0f2 Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Wed, 6 Nov 2024 15:58:28 +0530 Subject: [PATCH 89/93] doc: consistent use of word child process reword "child" to "child process" wherever possible. this helps in maintaining clarity and precision, consistency while avoiding misinterpretation. PR-URL: https://github.com/nodejs/node/pull/55654 Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Antoine du Hamel --- doc/api/child_process.md | 110 ++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index f70d96a3395300..0c0c80b35dc40c 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -280,9 +280,9 @@ exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => { }); ``` -If `timeout` is greater than `0`, the parent will send the signal +If `timeout` is greater than `0`, the parent process will send the signal identified by the `killSignal` property (the default is `'SIGTERM'`) if the -child runs longer than `timeout` milliseconds. +child process runs longer than `timeout` milliseconds. Unlike the exec(3) POSIX system call, `child_process.exec()` does not replace the existing process and uses a shell to execute the command. @@ -535,8 +535,8 @@ changes: * `args` {string\[]} List of string arguments. * `options` {Object} * `cwd` {string|URL} Current working directory of the child process. - * `detached` {boolean} Prepare child to run independently of its parent - process. Specific behavior depends on the platform, see + * `detached` {boolean} Prepare child process to run independently of its + parent process. Specific behavior depends on the platform, see [`options.detached`][]). * `env` {Object} Environment key-value pairs. **Default:** `process.env`. * `execPath` {string} Executable used to create the child process. @@ -550,10 +550,11 @@ changes: AbortSignal. * `killSignal` {string|integer} The signal value to be used when the spawned process will be killed by timeout or abort signal. **Default:** `'SIGTERM'`. - * `silent` {boolean} If `true`, stdin, stdout, and stderr of the child will be - piped to the parent, otherwise they will be inherited from the parent, see - the `'pipe'` and `'inherit'` options for [`child_process.spawn()`][]'s - [`stdio`][] for more details. **Default:** `false`. + * `silent` {boolean} If `true`, stdin, stdout, and stderr of the child + process will be piped to the parent process, otherwise they will be inherited + from the parent process, see the `'pipe'` and `'inherit'` options for + [`child_process.spawn()`][]'s [`stdio`][] for more details. + **Default:** `false`. * `stdio` {Array|string} See [`child_process.spawn()`][]'s [`stdio`][]. When this option is provided, it overrides `silent`. If the array variant is used, it must contain exactly one item with value `'ipc'` or an error @@ -686,8 +687,8 @@ changes: process. This will be set to `command` if not specified. * `stdio` {Array|string} Child's stdio configuration (see [`options.stdio`][`stdio`]). - * `detached` {boolean} Prepare child to run independently of its parent - process. Specific behavior depends on the platform, see + * `detached` {boolean} Prepare child process to run independently of + its parent process. Specific behavior depends on the platform, see [`options.detached`][]). * `uid` {number} Sets the user identity of the process (see setuid(2)). * `gid` {number} Sets the group identity of the process (see setgid(2)). @@ -909,27 +910,27 @@ added: v0.7.10 --> On Windows, setting `options.detached` to `true` makes it possible for the -child process to continue running after the parent exits. The child will have -its own console window. Once enabled for a child process, it cannot be -disabled. +child process to continue running after the parent exits. The child process +will have its own console window. Once enabled for a child process, +it cannot be disabled. On non-Windows platforms, if `options.detached` is set to `true`, the child process will be made the leader of a new process group and session. Child processes may continue running after the parent exits regardless of whether they are detached or not. See setsid(2) for more information. -By default, the parent will wait for the detached child to exit. To prevent the -parent from waiting for a given `subprocess` to exit, use the -`subprocess.unref()` method. Doing so will cause the parent's event loop to not -include the child in its reference count, allowing the parent to exit -independently of the child, unless there is an established IPC channel between -the child and the parent. +By default, the parent will wait for the detached child process to exit. +To prevent the parent process from waiting for a given `subprocess` to exit, use +the `subprocess.unref()` method. Doing so will cause the parent process' event +loop to not include the child process in its reference count, allowing the +parent process to exit independently of the child process, unless there is an established +IPC channel between the child and the parent processes. When using the `detached` option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a `stdio` configuration that is not connected to the parent. -If the parent's `stdio` is inherited, the child will remain attached to the -controlling terminal. +If the parent process' `stdio` is inherited, the child process will remain attached +to the controlling terminal. Example of a long-running process, by detaching and also ignoring its parent `stdio` file descriptors, in order to ignore the parent's termination: @@ -1039,10 +1040,10 @@ pipes between the parent and child. The value is one of the following: 3. `'ipc'`: Create an IPC channel for passing messages/file descriptors between parent and child. A [`ChildProcess`][] may have at most one IPC stdio file descriptor. Setting this option enables the - [`subprocess.send()`][] method. If the child is a Node.js process, the - presence of an IPC channel will enable [`process.send()`][] and + [`subprocess.send()`][] method. If the child process is a Node.js instance, + the presence of an IPC channel will enable [`process.send()`][] and [`process.disconnect()`][] methods, as well as [`'disconnect'`][] and - [`'message'`][] events within the child. + [`'message'`][] events within the child process. Accessing the IPC channel fd in any way other than [`process.send()`][] or using the IPC channel with a child process that is not a Node.js instance @@ -1109,12 +1110,12 @@ spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); ``` _It is worth noting that when an IPC channel is established between the -parent and child processes, and the child is a Node.js process, the child -is launched with the IPC channel unreferenced (using `unref()`) until the -child registers an event handler for the [`'disconnect'`][] event -or the [`'message'`][] event. This allows the child to exit -normally without the process being held open by the open IPC channel._ - +parent and child processes, and the child process is a Node.js instance, +the child process is launched with the IPC channel unreferenced (using +`unref()`) until the child process registers an event handler for the +[`'disconnect'`][] event or the [`'message'`][] event. This allows the +child process to exit normally without the process being held open by the +open IPC channel._ See also: [`child_process.exec()`][] and [`child_process.fork()`][]. ## Synchronous process creation @@ -1437,14 +1438,14 @@ instances of `ChildProcess`. added: v0.7.7 --> -* `code` {number} The exit code if the child exited on its own. +* `code` {number} The exit code if the child process exited on its own. * `signal` {string} The signal by which the child process was terminated. The `'close'` event is emitted after a process has ended _and_ the stdio streams of a child process have been closed. This is distinct from the [`'exit'`][] event, since multiple processes might share the same stdio streams. The `'close'` event will always emit after [`'exit'`][] was -already emitted, or [`'error'`][] if the child failed to spawn. +already emitted, or [`'error'`][] if the child process failed to spawn. ```cjs const { spawn } = require('node:child_process'); @@ -1515,7 +1516,7 @@ See also [`subprocess.kill()`][] and [`subprocess.send()`][]. added: v0.1.90 --> -* `code` {number} The exit code if the child exited on its own. +* `code` {number} The exit code if the child process exited on its own. * `signal` {string} The signal by which the child process was terminated. The `'exit'` event is emitted after the child process ends. If the process @@ -1625,11 +1626,12 @@ send and receive messages from a child process. When `subprocess.connected` is added: v0.7.2 --> -Closes the IPC channel between parent and child, allowing the child to exit -gracefully once there are no other connections keeping it alive. After calling -this method the `subprocess.connected` and `process.connected` properties in -both the parent and child (respectively) will be set to `false`, and it will be -no longer possible to pass messages between the processes. +Closes the IPC channel between parent and child processes, allowing the child +process to exit gracefully once there are no other connections keeping it alive. +After calling this method the `subprocess.connected` and +`process.connected` properties in both the parent and child processes +(respectively) will be set to `false`, and it will be no longer possible +to pass messages between the processes. The `'disconnect'` event will be emitted when there are no messages in the process of being received. This will most often be triggered immediately after @@ -1807,7 +1809,7 @@ added: v0.7.10 Calling `subprocess.ref()` after making a call to `subprocess.unref()` will restore the removed reference count for the child process, forcing the parent -to wait for the child to exit before exiting itself. +process to wait for the child process to exit before exiting itself. ```cjs const { spawn } = require('node:child_process'); @@ -1864,9 +1866,9 @@ changes: * `callback` {Function} * Returns: {boolean} -When an IPC channel has been established between the parent and child ( -i.e. when using [`child_process.fork()`][]), the `subprocess.send()` method can -be used to send messages to the child process. When the child process is a +When an IPC channel has been established between the parent and child processes +( i.e. when using [`child_process.fork()`][]), the `subprocess.send()` method +can be used to send messages to the child process. When the child process is a Node.js instance, these messages can be received via the [`'message'`][] event. The message goes through serialization and parsing. The resulting @@ -1910,7 +1912,7 @@ process.send({ foo: 'bar', baz: NaN }); ``` Child Node.js processes will have a [`process.send()`][] method of their own -that allows the child to send messages back to the parent. +that allows the child process to send messages back to the parent process. There is a special case when sending a `{cmd: 'NODE_foo'}` message. Messages containing a `NODE_` prefix in the `cmd` property are reserved for use within @@ -1921,14 +1923,14 @@ Applications should avoid using such messages or listening for `'internalMessage'` events as it is subject to change without notice. The optional `sendHandle` argument that may be passed to `subprocess.send()` is -for passing a TCP server or socket object to the child process. The child will +for passing a TCP server or socket object to the child process. The child process will receive the object as the second argument passed to the callback function registered on the [`'message'`][] event. Any data that is received and buffered in the socket will not be sent to the child. Sending IPC sockets is not supported on Windows. The optional `callback` is a function that is invoked after the message is -sent but before the child may have received it. The function is called with a +sent but before the child process may have received it. The function is called with a single argument: `null` on success, or an [`Error`][] object on failure. If no `callback` function is provided and the message cannot be sent, an @@ -1977,7 +1979,7 @@ server.listen(1337, () => { }); ``` -The child would then receive the server object as: +The child process would then receive the server object as: ```js process.on('message', (m, server) => { @@ -2111,7 +2113,7 @@ added: v0.1.90 A `Readable Stream` that represents the child process's `stderr`. -If the child was spawned with `stdio[2]` set to anything other than `'pipe'`, +If the child process was spawned with `stdio[2]` set to anything other than `'pipe'`, then this will be `null`. `subprocess.stderr` is an alias for `subprocess.stdio[2]`. Both properties will @@ -2130,10 +2132,10 @@ added: v0.1.90 A `Writable Stream` that represents the child process's `stdin`. -If a child process waits to read all of its input, the child will not continue +If a child process waits to read all of its input, the child process will not continue until this stream has been closed via `end()`. -If the child was spawned with `stdio[0]` set to anything other than `'pipe'`, +If the child process was spawned with `stdio[0]` set to anything other than `'pipe'`, then this will be `null`. `subprocess.stdin` is an alias for `subprocess.stdio[0]`. Both properties will @@ -2219,7 +2221,7 @@ added: v0.1.90 A `Readable Stream` that represents the child process's `stdout`. -If the child was spawned with `stdio[1]` set to anything other than `'pipe'`, +If the child process was spawned with `stdio[1]` set to anything other than `'pipe'`, then this will be `null`. `subprocess.stdout` is an alias for `subprocess.stdio[1]`. Both properties will @@ -2254,12 +2256,12 @@ if the child process could not be successfully spawned. added: v0.7.10 --> -By default, the parent will wait for the detached child to exit. To prevent the -parent from waiting for a given `subprocess` to exit, use the +By default, the parent process will wait for the detached child process to exit. +To prevent the parent process from waiting for a given `subprocess` to exit, use the `subprocess.unref()` method. Doing so will cause the parent's event loop to not -include the child in its reference count, allowing the parent to exit +include the child process in its reference count, allowing the parent to exit independently of the child, unless there is an established IPC channel between -the child and the parent. +the child and the parent processes. ```cjs const { spawn } = require('node:child_process'); From 89aa83842a50ac651b58cd68bd29f9ff4f8a028f Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Fri, 8 Nov 2024 05:27:17 -0500 Subject: [PATCH 90/93] doc: add esm example in `path.md` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/55745 Reviewed-By: Luigi Pinca Reviewed-By: Chemi Atlow Reviewed-By: Ulises Gascón --- doc/api/path.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/api/path.md b/doc/api/path.md index 8f1bf61ba2f25d..eb558e73592e4d 100644 --- a/doc/api/path.md +++ b/doc/api/path.md @@ -9,10 +9,14 @@ The `node:path` module provides utilities for working with file and directory paths. It can be accessed using: -```js +```cjs const path = require('node:path'); ``` +```mjs +import path from 'node:path'; +``` + ## Windows vs. POSIX The default operation of the `node:path` module varies based on the operating From cbe09b579fb72aa996df553a561c62f969801ac5 Mon Sep 17 00:00:00 2001 From: Carlos Espa <43477095+Ceres6@users.noreply.github.com> Date: Fri, 8 Nov 2024 11:28:40 +0100 Subject: [PATCH 91/93] doc: add path aliases typescript doc PR-URL: https://github.com/nodejs/node/pull/55766 Reviewed-By: Marco Ippolito Reviewed-By: Jacob Smith Reviewed-By: Paolo Insogna --- doc/api/typescript.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/api/typescript.md b/doc/api/typescript.md index c6dfb774c3f068..d2680670a5f316 100644 --- a/doc/api/typescript.md +++ b/doc/api/typescript.md @@ -172,14 +172,22 @@ To discourage package authors from publishing packages written in TypeScript, Node.js will by default refuse to handle TypeScript files inside folders under a `node_modules` path. +### Paths aliases + +[`tsconfig` "paths"][] won't be transformed and therefore produce an error. The closest +feature available is [subpath imports][] with the limitation that they need to start +with `#`. + [CommonJS]: modules.md [ES Modules]: esm.md [Full TypeScript support]: #full-typescript-support [`--experimental-strip-types`]: cli.md#--experimental-strip-types [`--experimental-transform-types`]: cli.md#--experimental-transform-types +[`tsconfig` "paths"]: https://www.typescriptlang.org/tsconfig/#paths [`tsx`]: https://tsx.is/ [`verbatimModuleSyntax`]: https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax [file extensions are mandatory]: esm.md#mandatory-file-extensions [full support]: #full-typescript-support +[subpath imports]: packages.md#subpath-imports [the same way as `.js` files.]: packages.md#determining-module-system [type stripping]: #type-stripping From 355af0f7006df631a7f7664b02899731951e3c76 Mon Sep 17 00:00:00 2001 From: "Edigleysson Silva (Edy)" Date: Fri, 8 Nov 2024 23:47:32 -0300 Subject: [PATCH 92/93] doc: consolidate history table of `CustomEvent` PR-URL: https://github.com/nodejs/node/pull/55758 Fixes: https://github.com/nodejs/node/issues/55733 Refs: https://github.com/nodejs/node/issues/55733 Reviewed-By: Luigi Pinca Reviewed-By: Daeyeon Jeong --- doc/api/events.md | 6 ++++++ doc/api/globals.md | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/doc/api/events.md b/doc/api/events.md index f3292841bb1230..30985b1ce0c12f 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -2427,11 +2427,17 @@ added: - v18.7.0 - v16.17.0 changes: + - version: v23.0.0 + pr-url: https://github.com/nodejs/node/pull/52723 + description: No longer experimental. - version: - v22.1.0 - v20.13.0 pr-url: https://github.com/nodejs/node/pull/52618 description: CustomEvent is now stable. + - version: v19.0.0 + pr-url: https://github.com/nodejs/node/pull/44860 + description: No longer behind `--experimental-global-customevent` CLI flag. --> > Stability: 2 - Stable diff --git a/doc/api/globals.md b/doc/api/globals.md index 34c2a15152f49a..8ee20e0f099162 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -438,6 +438,11 @@ changes: - version: v23.0.0 pr-url: https://github.com/nodejs/node/pull/52723 description: No longer experimental. + - version: + - v22.1.0 + - v20.13.0 + pr-url: https://github.com/nodejs/node/pull/52618 + description: CustomEvent is now stable. - version: v19.0.0 pr-url: https://github.com/nodejs/node/pull/44860 description: No longer behind `--experimental-global-customevent` CLI flag. From a83fbdbde16b7decf5ec41277917abe267746661 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Wed, 6 Nov 2024 11:49:36 +0100 Subject: [PATCH 93/93] 2024-11-11, Version 23.2.0 (Current) Notable changes: crypto: * update root certificates to NSS 3.104 (Richard Lau) https://github.com/nodejs/node/pull/55681 doc: * move typescript support to active development (Marco Ippolito) https://github.com/nodejs/node/pull/55536 * add jazelly to collaborators (Jason Zhang) https://github.com/nodejs/node/pull/55531 fs: * (SEMVER-MINOR) make `dirent.path` writable (Antoine du Hamel) https://github.com/nodejs/node/pull/55547 http: * (SEMVER-MINOR) add diagnostic channel `http.client.request.created` (Marco Ippolito) https://github.com/nodejs/node/pull/55586 module: * (SEMVER-MINOR) add `findPackageJSON` util (Jacob Smith) https://github.com/nodejs/node/pull/55412 * (SEMVER-MINOR) add `module.stripTypeScriptTypes` (Marco Ippolito) https://github.com/nodejs/node/pull/55282 PR-URL: https://github.com/nodejs/node/pull/55741 --- CHANGELOG.md | 3 +- doc/api/fs.md | 2 +- doc/api/module.md | 4 +- doc/changelogs/CHANGELOG_V23.md | 123 ++++++++++++++++++++++++++++++++ src/node_version.h | 6 +- 5 files changed, 131 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86c2eb38464cb7..d88380ffda9453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,8 @@ release.
18 (LTS)
diff --git a/doc/api/fs.md b/doc/api/fs.md index a6628e7bee061d..621731f133c700 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -6822,7 +6822,7 @@ deprecated: - v20.12.0 - v18.20.0 changes: - - version: REPLACEME + - version: v23.2.0 pr-url: https://github.com/nodejs/node/pull/55547 description: The property is no longer read-only. - version: v23.0.0 diff --git a/doc/api/module.md b/doc/api/module.md index 26469eb18aa41c..d5d3187439c0c0 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -220,7 +220,7 @@ added: v22.8.0 ### `module.findPackageJSON(specifier[, base])` > Stability: 1.1 - Active Development @@ -355,7 +355,7 @@ resolution and loading behavior. See [Customization hooks][]. ## `module.stripTypeScriptTypes(code[, options])` > Stability: 1.1 - Active development diff --git a/doc/changelogs/CHANGELOG_V23.md b/doc/changelogs/CHANGELOG_V23.md index 0d851e09655999..c752e97f5e2c7b 100644 --- a/doc/changelogs/CHANGELOG_V23.md +++ b/doc/changelogs/CHANGELOG_V23.md @@ -8,6 +8,7 @@
+23.2.0
23.1.0
23.0.0