diff --git a/.eslintignore b/.eslintignore index 153ac6e24f731e..268232d911bbb5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,6 +5,7 @@ test/fixtures test/message/esm_display_syntax_error.mjs tools/icu tools/lint-md/lint-md.mjs +tools/github_reporter benchmark/tmp benchmark/fixtures doc/**/*.js diff --git a/.eslintrc.js b/.eslintrc.js index 43e41026b2007e..f46a64bcbf2acd 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -53,10 +53,10 @@ module.exports = { overrides: [ { files: [ - 'test/es-module/test-esm-type-flag.js', - 'test/es-module/test-esm-type-flag-alias.js', '*.mjs', 'test/es-module/test-esm-example-loader.js', + 'test/es-module/test-esm-type-flag.js', + 'test/es-module/test-esm-type-flag-alias.js', ], parserOptions: { sourceType: 'module' }, }, @@ -111,6 +111,22 @@ module.exports = { }, ] }, }, + { + files: [ + 'lib/internal/modules/**/*.js', + ], + rules: { + 'curly': 'error', + }, + }, + { + files: [ + 'lib/internal/test_runner/**/*.js', + ], + rules: { + 'node-core/set-proto-to-null-in-object': 'error', + }, + }, ], rules: { // ESLint built-in rules diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 47e420a9457bb8..1a62e3560a23ef 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,6 +11,8 @@ # tsc /.github/CODEOWNERS @nodejs/tsc +/.github/PULL_REQUEST_TEMPLATE.md @nodejs/tsc +/.github/ISSUE_TEMPLATE/* @nodejs/tsc /CODE_OF_CONDUCT.md @nodejs/tsc /CONTRIBUTING.md @nodejs/tsc /doc/contributing/*.md @nodejs/tsc @@ -85,16 +87,16 @@ # modules, including loaders -/doc/api/esm.md @nodejs/modules @nodejs/loaders -/doc/api/module.md @nodejs/modules @nodejs/loaders -/doc/api/modules.md @nodejs/modules @nodejs/loaders -/doc/api/packages.md @nodejs/modules @nodejs/loaders -/lib/internal/bootstrap/realm.js @nodejs/modules @nodejs/loaders -/lib/internal/modules/* @nodejs/modules @nodejs/loaders -/lib/internal/process/esm_loader.js @nodejs/modules @nodejs/loaders -/lib/internal/process/execution.js @nodejs/modules @nodejs/loaders -/lib/module.js @nodejs/modules @nodejs/loaders -/src/module_wrap* @nodejs/modules @nodejs/loaders @nodejs/vm +/doc/api/esm.md @nodejs/loaders +/doc/api/module.md @nodejs/loaders +/doc/api/modules.md @nodejs/loaders +/doc/api/packages.md @nodejs/loaders +/lib/internal/bootstrap/realm.js @nodejs/loaders +/lib/internal/modules/* @nodejs/loaders +/lib/internal/process/esm_loader.js @nodejs/loaders +/lib/internal/process/execution.js @nodejs/loaders +/lib/module.js @nodejs/loaders +/src/module_wrap* @nodejs/loaders @nodejs/vm # Node-API @@ -146,6 +148,7 @@ /lib/internal/main/test_runner.js @nodejs/test_runner /lib/internal/test_runner/* @nodejs/test_runner /lib/test.js @nodejs/test_runner +/lib/test/reporters.js @nodejs/test_runner /test/parallel/test-runner-* @nodejs/test_runner # Single Executable Applications diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index fe46bf4deadeb7..936c2a06125795 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,15 +1,18 @@ regexps + let set = this.globParts.map((s, _, __) => { + if (this.isWindows && this.windowsNoMagicRoot) { + // check if it's a drive or unc path. + const isUNC = s[0] === '' && + s[1] === '' && + (s[2] === '?' || !globMagic.test(s[2])) && + !globMagic.test(s[3]); + const isDrive = /^[a-z]:/i.test(s[0]); + if (isUNC) { + return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]; + } + else if (isDrive) { + return [s[0], ...s.slice(1).map(ss => this.parse(ss))]; + } + } + return s.map(ss => this.parse(ss)); + }); + this.debug(this.pattern, set); + // filter out everything that didn't compile properly. + this.set = set.filter(s => s.indexOf(false) === -1); + // do not treat the ? in UNC paths as magic + if (this.isWindows) { + for (let i = 0; i < this.set.length; i++) { + const p = this.set[i]; + if (p[0] === '' && + p[1] === '' && + this.globParts[i][2] === '?' && + typeof p[3] === 'string' && + /^[a-z]:$/i.test(p[3])) { + p[2] = '?'; + } + } + } + this.debug(this.pattern, this.set); + } + // various transforms to equivalent pattern sets that are + // faster to process in a filesystem walk. The goal is to + // eliminate what we can, and push all ** patterns as far + // to the right as possible, even if it increases the number + // of patterns that we have to process. + preprocess(globParts) { + // if we're not in globstar mode, then turn all ** into * + if (this.options.noglobstar) { + for (let i = 0; i < globParts.length; i++) { + for (let j = 0; j < globParts[i].length; j++) { + if (globParts[i][j] === '**') { + globParts[i][j] = '*'; + } + } + } + } + const { optimizationLevel = 1 } = this.options; + if (optimizationLevel >= 2) { + // aggressive optimization for the purpose of fs walking + globParts = this.firstPhasePreProcess(globParts); + globParts = this.secondPhasePreProcess(globParts); + } + else if (optimizationLevel >= 1) { + // just basic optimizations to remove some .. parts + globParts = this.levelOneOptimize(globParts); + } + else { + globParts = this.adjascentGlobstarOptimize(globParts); + } + return globParts; + } + // just get rid of adjascent ** portions + adjascentGlobstarOptimize(globParts) { + return globParts.map(parts => { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let i = gs; + while (parts[i + 1] === '**') { + i++; + } + if (i !== gs) { + parts.splice(gs, i - gs); + } + } + return parts; + }); + } + // get rid of adjascent ** and resolve .. portions + levelOneOptimize(globParts) { + return globParts.map(parts => { + parts = parts.reduce((set, part) => { + const prev = set[set.length - 1]; + if (part === '**' && prev === '**') { + return set; + } + if (part === '..') { + if (prev && prev !== '..' && prev !== '.' && prev !== '**') { + set.pop(); + return set; + } + } + set.push(part); + return set; + }, []); + return parts.length === 0 ? [''] : parts; + }); + } + levelTwoFileOptimize(parts) { + if (!Array.isArray(parts)) { + parts = this.slashSplit(parts); + } + let didSomething = false; + do { + didSomething = false; + //
// -> 
/
+            if (!this.preserveMultipleSlashes) {
+                for (let i = 1; i < parts.length - 1; i++) {
+                    const p = parts[i];
+                    // don't squeeze out UNC patterns
+                    if (i === 1 && p === '' && parts[0] === '')
+                        continue;
+                    if (p === '.' || p === '') {
+                        didSomething = true;
+                        parts.splice(i, 1);
+                        i--;
+                    }
+                }
+                if (parts[0] === '.' &&
+                    parts.length === 2 &&
+                    (parts[1] === '.' || parts[1] === '')) {
+                    didSomething = true;
+                    parts.pop();
+                }
+            }
+            // 
/

/../ ->

/
+            let dd = 0;
+            while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                const p = parts[dd - 1];
+                if (p && p !== '.' && p !== '..' && p !== '**') {
+                    didSomething = true;
+                    parts.splice(dd - 1, 2);
+                    dd -= 2;
+                }
+            }
+        } while (didSomething);
+        return parts.length === 0 ? [''] : parts;
+    }
+    // First phase: single-pattern processing
+    // 
 is 1 or more portions
+    //  is 1 or more portions
+    // 

is any portion other than ., .., '', or ** + // is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + //

// -> 
/
+    // 
/

/../ ->

/
+    // **/**/ -> **/
+    //
+    // **/*/ -> */**/ <== not valid because ** doesn't follow
+    // this WOULD be allowed if ** did follow symlinks, or * didn't
+    firstPhasePreProcess(globParts) {
+        let didSomething = false;
+        do {
+            didSomething = false;
+            // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + for (let parts of globParts) { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let gss = gs; + while (parts[gss + 1] === '**') { + //

/**/**/ -> 
/**/
+                        gss++;
+                    }
+                    // eg, if gs is 2 and gss is 4, that means we have 3 **
+                    // parts, and can remove 2 of them.
+                    if (gss > gs) {
+                        parts.splice(gs + 1, gss - gs);
+                    }
+                    let next = parts[gs + 1];
+                    const p = parts[gs + 2];
+                    const p2 = parts[gs + 3];
+                    if (next !== '..')
+                        continue;
+                    if (!p ||
+                        p === '.' ||
+                        p === '..' ||
+                        !p2 ||
+                        p2 === '.' ||
+                        p2 === '..') {
+                        continue;
+                    }
+                    didSomething = true;
+                    // edit parts in place, and push the new one
+                    parts.splice(gs, 1);
+                    const other = parts.slice(0);
+                    other[gs] = '**';
+                    globParts.push(other);
+                    gs--;
+                }
+                // 
// -> 
/
+                if (!this.preserveMultipleSlashes) {
+                    for (let i = 1; i < parts.length - 1; i++) {
+                        const p = parts[i];
+                        // don't squeeze out UNC patterns
+                        if (i === 1 && p === '' && parts[0] === '')
+                            continue;
+                        if (p === '.' || p === '') {
+                            didSomething = true;
+                            parts.splice(i, 1);
+                            i--;
+                        }
+                    }
+                    if (parts[0] === '.' &&
+                        parts.length === 2 &&
+                        (parts[1] === '.' || parts[1] === '')) {
+                        didSomething = true;
+                        parts.pop();
+                    }
+                }
+                // 
/

/../ ->

/
+                let dd = 0;
+                while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                    const p = parts[dd - 1];
+                    if (p && p !== '.' && p !== '..' && p !== '**') {
+                        didSomething = true;
+                        const needDot = dd === 1 && parts[dd + 1] === '**';
+                        const splin = needDot ? ['.'] : [];
+                        parts.splice(dd - 1, 2, ...splin);
+                        if (parts.length === 0)
+                            parts.push('');
+                        dd -= 2;
+                    }
+                }
+            }
+        } while (didSomething);
+        return globParts;
+    }
+    // second phase: multi-pattern dedupes
+    // {
/*/,
/

/} ->

/*/
+    // {
/,
/} -> 
/
+    // {
/**/,
/} -> 
/**/
+    //
+    // {
/**/,
/**/

/} ->

/**/
+    // ^-- not valid because ** doens't follow symlinks
+    secondPhasePreProcess(globParts) {
+        for (let i = 0; i < globParts.length - 1; i++) {
+            for (let j = i + 1; j < globParts.length; j++) {
+                const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
+                if (!matched)
+                    continue;
+                globParts[i] = matched;
+                globParts[j] = [];
+            }
+        }
+        return globParts.filter(gs => gs.length);
+    }
+    partsMatch(a, b, emptyGSMatch = false) {
+        let ai = 0;
+        let bi = 0;
+        let result = [];
+        let which = '';
+        while (ai < a.length && bi < b.length) {
+            if (a[ai] === b[bi]) {
+                result.push(which === 'b' ? b[bi] : a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
+                result.push(a[ai]);
+                ai++;
+            }
+            else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
+                result.push(b[bi]);
+                bi++;
+            }
+            else if (a[ai] === '*' &&
+                b[bi] &&
+                (this.options.dot || !b[bi].startsWith('.')) &&
+                b[bi] !== '**') {
+                if (which === 'b')
+                    return false;
+                which = 'a';
+                result.push(a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (b[bi] === '*' &&
+                a[ai] &&
+                (this.options.dot || !a[ai].startsWith('.')) &&
+                a[ai] !== '**') {
+                if (which === 'a')
+                    return false;
+                which = 'b';
+                result.push(b[bi]);
+                ai++;
+                bi++;
+            }
+            else {
+                return false;
+            }
+        }
+        // if we fall out of the loop, it means they two are identical
+        // as long as their lengths match
+        return a.length === b.length && result;
+    }
+    parseNegate() {
+        if (this.nonegate)
+            return;
+        const pattern = this.pattern;
+        let negate = false;
+        let negateOffset = 0;
+        for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
+            negate = !negate;
+            negateOffset++;
+        }
+        if (negateOffset)
+            this.pattern = pattern.slice(negateOffset);
+        this.negate = negate;
+    }
+    // set partial to true to test if, for example,
+    // "/a/b" matches the start of "/*/b/*/d"
+    // Partial means, if you run out of file before you run
+    // out of pattern, then that's fine, as long as all
+    // the parts match.
+    matchOne(file, pattern, partial = false) {
+        const options = this.options;
+        // UNC paths like //?/X:/... can match X:/... and vice versa
+        // Drive letters in absolute drive or unc paths are always compared
+        // case-insensitively.
+        if (this.isWindows) {
+            const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
+            const fileUNC = !fileDrive &&
+                file[0] === '' &&
+                file[1] === '' &&
+                file[2] === '?' &&
+                /^[a-z]:$/i.test(file[3]);
+            const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
+            const patternUNC = !patternDrive &&
+                pattern[0] === '' &&
+                pattern[1] === '' &&
+                pattern[2] === '?' &&
+                typeof pattern[3] === 'string' &&
+                /^[a-z]:$/i.test(pattern[3]);
+            const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
+            const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
+            if (typeof fdi === 'number' && typeof pdi === 'number') {
+                const [fd, pd] = [file[fdi], pattern[pdi]];
+                if (fd.toLowerCase() === pd.toLowerCase()) {
+                    pattern[pdi] = fd;
+                    if (pdi > fdi) {
+                        pattern = pattern.slice(pdi);
+                    }
+                    else if (fdi > pdi) {
+                        file = file.slice(fdi);
+                    }
+                }
+            }
+        }
+        // resolve and reduce . and .. portions in the file as well.
+        // dont' need to do the second phase, because it's only one string[]
+        const { optimizationLevel = 1 } = this.options;
+        if (optimizationLevel >= 2) {
+            file = this.levelTwoFileOptimize(file);
+        }
+        this.debug('matchOne', this, { file, pattern });
+        this.debug('matchOne', file.length, pattern.length);
+        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
+            this.debug('matchOne loop');
+            var p = pattern[pi];
+            var f = file[fi];
+            this.debug(pattern, p, f);
+            // should be impossible.
+            // some invalid regexp stuff in the set.
+            /* c8 ignore start */
+            if (p === false) {
+                return false;
+            }
+            /* c8 ignore stop */
+            if (p === exports.GLOBSTAR) {
+                this.debug('GLOBSTAR', [pattern, p, f]);
+                // "**"
+                // a/**/b/**/c would match the following:
+                // a/b/x/y/z/c
+                // a/x/y/z/b/c
+                // a/b/x/b/x/c
+                // a/b/c
+                // To do this, take the rest of the pattern after
+                // the **, and see if it would match the file remainder.
+                // If so, return success.
+                // If not, the ** "swallows" a segment, and try again.
+                // This is recursively awful.
+                //
+                // a/**/b/**/c matching a/b/x/y/z/c
+                // - a matches a
+                // - doublestar
+                //   - matchOne(b/x/y/z/c, b/**/c)
+                //     - b matches b
+                //     - doublestar
+                //       - matchOne(x/y/z/c, c) -> no
+                //       - matchOne(y/z/c, c) -> no
+                //       - matchOne(z/c, c) -> no
+                //       - matchOne(c, c) yes, hit
+                var fr = fi;
+                var pr = pi + 1;
+                if (pr === pl) {
+                    this.debug('** at the end');
+                    // a ** at the end will just swallow the rest.
+                    // We have found a match.
+                    // however, it will not swallow /.x, unless
+                    // options.dot is set.
+                    // . and .. are *never* matched by **, for explosively
+                    // exponential reasons.
+                    for (; fi < fl; fi++) {
+                        if (file[fi] === '.' ||
+                            file[fi] === '..' ||
+                            (!options.dot && file[fi].charAt(0) === '.'))
+                            return false;
+                    }
+                    return true;
+                }
+                // ok, let's see if we can swallow whatever we can.
+                while (fr < fl) {
+                    var swallowee = file[fr];
+                    this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
+                    // XXX remove this slice.  Just pass the start index.
+                    if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
+                        this.debug('globstar found match!', fr, fl, swallowee);
+                        // found a match.
+                        return true;
+                    }
+                    else {
+                        // can't swallow "." or ".." ever.
+                        // can only swallow ".foo" when explicitly asked.
+                        if (swallowee === '.' ||
+                            swallowee === '..' ||
+                            (!options.dot && swallowee.charAt(0) === '.')) {
+                            this.debug('dot detected!', file, fr, pattern, pr);
+                            break;
+                        }
+                        // ** swallows a segment, and continue.
+                        this.debug('globstar swallow a segment, and continue');
+                        fr++;
+                    }
+                }
+                // no match was found.
+                // However, in partial mode, we can't say this is necessarily over.
+                /* c8 ignore start */
+                if (partial) {
+                    // ran out of file
+                    this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
+                    if (fr === fl) {
+                        return true;
+                    }
+                }
+                /* c8 ignore stop */
+                return false;
+            }
+            // something other than **
+            // non-magic patterns just have to match exactly
+            // patterns with magic have been turned into regexps.
+            let hit;
+            if (typeof p === 'string') {
+                hit = f === p;
+                this.debug('string match', p, f, hit);
+            }
+            else {
+                hit = p.test(f);
+                this.debug('pattern match', p, f, hit);
+            }
+            if (!hit)
+                return false;
+        }
+        // Note: ending in / means that we'll get a final ""
+        // at the end of the pattern.  This can only match a
+        // corresponding "" at the end of the file.
+        // If the file ends in /, then it can only match a
+        // a pattern that ends in /, unless the pattern just
+        // doesn't have any more for it. But, a/b/ should *not*
+        // match "a/b/*", even though "" matches against the
+        // [^/]*? pattern, except in partial mode, where it might
+        // simply not be reached yet.
+        // However, a/b/ should still satisfy a/*
+        // now either we fell off the end of the pattern, or we're done.
+        if (fi === fl && pi === pl) {
+            // ran out of pattern and filename at the same time.
+            // an exact hit!
+            return true;
+        }
+        else if (fi === fl) {
+            // ran out of file, but still had pattern left.
+            // this is ok if we're doing the match as part of
+            // a glob fs traversal.
+            return partial;
+        }
+        else if (pi === pl) {
+            // ran out of pattern, still have file left.
+            // this is only acceptable if we're on the very last
+            // empty segment of a file with a trailing slash.
+            // a/* should match a/b/
+            return fi === fl - 1 && file[fi] === '';
+            /* c8 ignore start */
+        }
+        else {
+            // should be unreachable.
+            throw new Error('wtf?');
+        }
+        /* c8 ignore stop */
+    }
+    braceExpand() {
+        return (0, exports.braceExpand)(this.pattern, this.options);
+    }
+    parse(pattern) {
+        (0, assert_valid_pattern_js_1.assertValidPattern)(pattern);
+        const options = this.options;
+        // shortcuts
+        if (pattern === '**')
+            return exports.GLOBSTAR;
+        if (pattern === '')
+            return '';
+        // far and away, the most common glob pattern parts are
+        // *, *.*, and *.  Add a fast check method for those.
+        let m;
+        let fastTest = null;
+        if ((m = pattern.match(starRE))) {
+            fastTest = options.dot ? starTestDot : starTest;
+        }
+        else if ((m = pattern.match(starDotExtRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? starDotExtTestNocaseDot
+                    : starDotExtTestNocase
+                : options.dot
+                    ? starDotExtTestDot
+                    : starDotExtTest)(m[1]);
+        }
+        else if ((m = pattern.match(qmarksRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? qmarksTestNocaseDot
+                    : qmarksTestNocase
+                : options.dot
+                    ? qmarksTestDot
+                    : qmarksTest)(m);
+        }
+        else if ((m = pattern.match(starDotStarRE))) {
+            fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
+        }
+        else if ((m = pattern.match(dotStarRE))) {
+            fastTest = dotStarTest;
+        }
+        const re = ast_js_1.AST.fromGlob(pattern, this.options).toMMPattern();
+        return fastTest ? Object.assign(re, { test: fastTest }) : re;
+    }
+    makeRe() {
+        if (this.regexp || this.regexp === false)
+            return this.regexp;
+        // at this point, this.set is a 2d array of partial
+        // pattern strings, or "**".
+        //
+        // It's better to use .match().  This function shouldn't
+        // be used, really, but it's pretty convenient sometimes,
+        // when you just want to work with a regex.
+        const set = this.set;
+        if (!set.length) {
+            this.regexp = false;
+            return this.regexp;
+        }
+        const options = this.options;
+        const twoStar = options.noglobstar
+            ? star
+            : options.dot
+                ? twoStarDot
+                : twoStarNoDot;
+        const flags = new Set(options.nocase ? ['i'] : []);
+        // regexpify non-globstar patterns
+        // if ** is only item, then we just do one twoStar
+        // if ** is first, and there are more, prepend (\/|twoStar\/)? to next
+        // if ** is last, append (\/twoStar|) to previous
+        // if ** is in the middle, append (\/|\/twoStar\/) to previous
+        // then filter out GLOBSTAR symbols
+        let re = set
+            .map(pattern => {
+            const pp = pattern.map(p => {
+                if (p instanceof RegExp) {
+                    for (const f of p.flags.split(''))
+                        flags.add(f);
+                }
+                return typeof p === 'string'
+                    ? regExpEscape(p)
+                    : p === exports.GLOBSTAR
+                        ? exports.GLOBSTAR
+                        : p._src;
+            });
+            pp.forEach((p, i) => {
+                const next = pp[i + 1];
+                const prev = pp[i - 1];
+                if (p !== exports.GLOBSTAR || prev === exports.GLOBSTAR) {
+                    return;
+                }
+                if (prev === undefined) {
+                    if (next !== undefined && next !== exports.GLOBSTAR) {
+                        pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next;
+                    }
+                    else {
+                        pp[i] = twoStar;
+                    }
+                }
+                else if (next === undefined) {
+                    pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
+                }
+                else if (next !== exports.GLOBSTAR) {
+                    pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
+                    pp[i + 1] = exports.GLOBSTAR;
+                }
+            });
+            return pp.filter(p => p !== exports.GLOBSTAR).join('/');
+        })
+            .join('|');
+        // need to wrap in parens if we had more than one thing with |,
+        // otherwise only the first will be anchored to ^ and the last to $
+        const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
+        // must match entire pattern
+        // ending in a * or ** will make it less strict.
+        re = '^' + open + re + close + '$';
+        // can match anything, as long as it's not this.
+        if (this.negate)
+            re = '^(?!' + re + ').+$';
+        try {
+            this.regexp = new RegExp(re, [...flags].join(''));
+            /* c8 ignore start */
+        }
+        catch (ex) {
+            // should be impossible
+            this.regexp = false;
+        }
+        /* c8 ignore stop */
+        return this.regexp;
+    }
+    slashSplit(p) {
+        // if p starts with // on windows, we preserve that
+        // so that UNC paths aren't broken.  Otherwise, any number of
+        // / characters are coalesced into one, unless
+        // preserveMultipleSlashes is set to true.
+        if (this.preserveMultipleSlashes) {
+            return p.split('/');
+        }
+        else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
+            // add an extra '' for the one we lose
+            return ['', ...p.split(/\/+/)];
+        }
+        else {
+            return p.split(/\/+/);
+        }
+    }
+    match(f, partial = this.partial) {
+        this.debug('match', f, this.pattern);
+        // short-circuit in the case of busted things.
+        // comments, etc.
+        if (this.comment) {
+            return false;
+        }
+        if (this.empty) {
+            return f === '';
+        }
+        if (f === '/' && partial) {
+            return true;
+        }
+        const options = this.options;
+        // windows: need to use /, not \
+        if (this.isWindows) {
+            f = f.split('\\').join('/');
+        }
+        // treat the test path as a set of pathparts.
+        const ff = this.slashSplit(f);
+        this.debug(this.pattern, 'split', ff);
+        // just ONE of the pattern sets in this.set needs to match
+        // in order for it to be valid.  If negating, then just one
+        // match means that we have failed.
+        // Either way, return on the first hit.
+        const set = this.set;
+        this.debug(this.pattern, 'set', set);
+        // Find the basename of the path by looking for the last non-empty segment
+        let filename = ff[ff.length - 1];
+        if (!filename) {
+            for (let i = ff.length - 2; !filename && i >= 0; i--) {
+                filename = ff[i];
+            }
+        }
+        for (let i = 0; i < set.length; i++) {
+            const pattern = set[i];
+            let file = ff;
+            if (options.matchBase && pattern.length === 1) {
+                file = [filename];
+            }
+            const hit = this.matchOne(file, pattern, partial);
+            if (hit) {
+                if (options.flipNegate) {
+                    return true;
+                }
+                return !this.negate;
+            }
+        }
+        // didn't get any hits.  this is success if it's a negative
+        // pattern, failure otherwise.
+        if (options.flipNegate) {
+            return false;
+        }
+        return this.negate;
+    }
+    static defaults(def) {
+        return exports.minimatch.defaults(def).Minimatch;
+    }
+}
+exports.Minimatch = Minimatch;
+/* c8 ignore start */
+var ast_js_2 = require("./ast.js");
+Object.defineProperty(exports, "AST", { enumerable: true, get: function () { return ast_js_2.AST; } });
+var escape_js_2 = require("./escape.js");
+Object.defineProperty(exports, "escape", { enumerable: true, get: function () { return escape_js_2.escape; } });
+var unescape_js_2 = require("./unescape.js");
+Object.defineProperty(exports, "unescape", { enumerable: true, get: function () { return unescape_js_2.unescape; } });
+/* c8 ignore stop */
+exports.minimatch.AST = ast_js_1.AST;
+exports.minimatch.Minimatch = Minimatch;
+exports.minimatch.escape = escape_js_1.escape;
+exports.minimatch.unescape = unescape_js_1.unescape;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/cjs/package.json b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/cjs/package.json
new file mode 100644
index 00000000000000..5bbefffbabee39
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/cjs/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "commonjs"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/cjs/unescape.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/cjs/unescape.js
new file mode 100644
index 00000000000000..47c36bcee5a02a
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/cjs/unescape.js
@@ -0,0 +1,24 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.unescape = void 0;
+/**
+ * Un-escape a string that has been escaped with {@link escape}.
+ *
+ * If the {@link windowsPathsNoEscape} option is used, then square-brace
+ * escapes are removed, but not backslash escapes.  For example, it will turn
+ * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
+ * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
+ *
+ * When `windowsPathsNoEscape` is not set, then both brace escapes and
+ * backslash escapes are removed.
+ *
+ * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
+ * or unescaped.
+ */
+const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
+    return windowsPathsNoEscape
+        ? s.replace(/\[([^\/\\])\]/g, '$1')
+        : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
+};
+exports.unescape = unescape;
+//# sourceMappingURL=unescape.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/assert-valid-pattern.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/assert-valid-pattern.js
new file mode 100644
index 00000000000000..7b534fc30200bb
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/assert-valid-pattern.js
@@ -0,0 +1,10 @@
+const MAX_PATTERN_LENGTH = 1024 * 64;
+export const assertValidPattern = (pattern) => {
+    if (typeof pattern !== 'string') {
+        throw new TypeError('invalid pattern');
+    }
+    if (pattern.length > MAX_PATTERN_LENGTH) {
+        throw new TypeError('pattern is too long');
+    }
+};
+//# sourceMappingURL=assert-valid-pattern.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/ast.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/ast.js
new file mode 100644
index 00000000000000..7fb1f83e6182a0
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/ast.js
@@ -0,0 +1,585 @@
+// parse a single path portion
+import { parseClass } from './brace-expressions.js';
+import { unescape } from './unescape.js';
+const types = new Set(['!', '?', '+', '*', '@']);
+const isExtglobType = (c) => types.has(c);
+// Patterns that get prepended to bind to the start of either the
+// entire string, or just a single path portion, to prevent dots
+// and/or traversal patterns, when needed.
+// Exts don't need the ^ or / bit, because the root binds that already.
+const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))';
+const startNoDot = '(?!\\.)';
+// characters that indicate a start of pattern needs the "no dots" bit,
+// because a dot *might* be matched. ( is not in the list, because in
+// the case of a child extglob, it will handle the prevention itself.
+const addPatternStart = new Set(['[', '.']);
+// cases where traversal is A-OK, no dot prevention needed
+const justDots = new Set(['..', '.']);
+const reSpecials = new Set('().*{}+?[]^$\\!');
+const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+// any single thing other than /
+const qmark = '[^/]';
+// * => any number of characters
+const star = qmark + '*?';
+// use + when we need to ensure that *something* matches, because the * is
+// the only thing in the path portion.
+const starNoEmpty = qmark + '+?';
+// remove the \ chars that we added if we end up doing a nonmagic compare
+// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
+export class AST {
+    type;
+    #root;
+    #hasMagic;
+    #uflag = false;
+    #parts = [];
+    #parent;
+    #parentIndex;
+    #negs;
+    #filledNegs = false;
+    #options;
+    #toString;
+    // set to true if it's an extglob with no children
+    // (which really means one child of '')
+    #emptyExt = false;
+    constructor(type, parent, options = {}) {
+        this.type = type;
+        // extglobs are inherently magical
+        if (type)
+            this.#hasMagic = true;
+        this.#parent = parent;
+        this.#root = this.#parent ? this.#parent.#root : this;
+        this.#options = this.#root === this ? options : this.#root.#options;
+        this.#negs = this.#root === this ? [] : this.#root.#negs;
+        if (type === '!' && !this.#root.#filledNegs)
+            this.#negs.push(this);
+        this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;
+    }
+    get hasMagic() {
+        /* c8 ignore start */
+        if (this.#hasMagic !== undefined)
+            return this.#hasMagic;
+        /* c8 ignore stop */
+        for (const p of this.#parts) {
+            if (typeof p === 'string')
+                continue;
+            if (p.type || p.hasMagic)
+                return (this.#hasMagic = true);
+        }
+        // note: will be undefined until we generate the regexp src and find out
+        return this.#hasMagic;
+    }
+    // reconstructs the pattern
+    toString() {
+        if (this.#toString !== undefined)
+            return this.#toString;
+        if (!this.type) {
+            return (this.#toString = this.#parts.map(p => String(p)).join(''));
+        }
+        else {
+            return (this.#toString =
+                this.type + '(' + this.#parts.map(p => String(p)).join('|') + ')');
+        }
+    }
+    #fillNegs() {
+        /* c8 ignore start */
+        if (this !== this.#root)
+            throw new Error('should only call on root');
+        if (this.#filledNegs)
+            return this;
+        /* c8 ignore stop */
+        // call toString() once to fill this out
+        this.toString();
+        this.#filledNegs = true;
+        let n;
+        while ((n = this.#negs.pop())) {
+            if (n.type !== '!')
+                continue;
+            // walk up the tree, appending everthing that comes AFTER parentIndex
+            let p = n;
+            let pp = p.#parent;
+            while (pp) {
+                for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {
+                    for (const part of n.#parts) {
+                        /* c8 ignore start */
+                        if (typeof part === 'string') {
+                            throw new Error('string part in extglob AST??');
+                        }
+                        /* c8 ignore stop */
+                        part.copyIn(pp.#parts[i]);
+                    }
+                }
+                p = pp;
+                pp = p.#parent;
+            }
+        }
+        return this;
+    }
+    push(...parts) {
+        for (const p of parts) {
+            if (p === '')
+                continue;
+            /* c8 ignore start */
+            if (typeof p !== 'string' && !(p instanceof AST && p.#parent === this)) {
+                throw new Error('invalid part: ' + p);
+            }
+            /* c8 ignore stop */
+            this.#parts.push(p);
+        }
+    }
+    toJSON() {
+        const ret = this.type === null
+            ? this.#parts.slice().map(p => (typeof p === 'string' ? p : p.toJSON()))
+            : [this.type, ...this.#parts.map(p => p.toJSON())];
+        if (this.isStart() && !this.type)
+            ret.unshift([]);
+        if (this.isEnd() &&
+            (this === this.#root ||
+                (this.#root.#filledNegs && this.#parent?.type === '!'))) {
+            ret.push({});
+        }
+        return ret;
+    }
+    isStart() {
+        if (this.#root === this)
+            return true;
+        // if (this.type) return !!this.#parent?.isStart()
+        if (!this.#parent?.isStart())
+            return false;
+        if (this.#parentIndex === 0)
+            return true;
+        // if everything AHEAD of this is a negation, then it's still the "start"
+        const p = this.#parent;
+        for (let i = 0; i < this.#parentIndex; i++) {
+            const pp = p.#parts[i];
+            if (!(pp instanceof AST && pp.type === '!')) {
+                return false;
+            }
+        }
+        return true;
+    }
+    isEnd() {
+        if (this.#root === this)
+            return true;
+        if (this.#parent?.type === '!')
+            return true;
+        if (!this.#parent?.isEnd())
+            return false;
+        if (!this.type)
+            return this.#parent?.isEnd();
+        // if not root, it'll always have a parent
+        /* c8 ignore start */
+        const pl = this.#parent ? this.#parent.#parts.length : 0;
+        /* c8 ignore stop */
+        return this.#parentIndex === pl - 1;
+    }
+    copyIn(part) {
+        if (typeof part === 'string')
+            this.push(part);
+        else
+            this.push(part.clone(this));
+    }
+    clone(parent) {
+        const c = new AST(this.type, parent);
+        for (const p of this.#parts) {
+            c.copyIn(p);
+        }
+        return c;
+    }
+    static #parseAST(str, ast, pos, opt) {
+        let escaping = false;
+        let inBrace = false;
+        let braceStart = -1;
+        let braceNeg = false;
+        if (ast.type === null) {
+            // outside of a extglob, append until we find a start
+            let i = pos;
+            let acc = '';
+            while (i < str.length) {
+                const c = str.charAt(i++);
+                // still accumulate escapes at this point, but we do ignore
+                // starts that are escaped
+                if (escaping || c === '\\') {
+                    escaping = !escaping;
+                    acc += c;
+                    continue;
+                }
+                if (inBrace) {
+                    if (i === braceStart + 1) {
+                        if (c === '^' || c === '!') {
+                            braceNeg = true;
+                        }
+                    }
+                    else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
+                        inBrace = false;
+                    }
+                    acc += c;
+                    continue;
+                }
+                else if (c === '[') {
+                    inBrace = true;
+                    braceStart = i;
+                    braceNeg = false;
+                    acc += c;
+                    continue;
+                }
+                if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {
+                    ast.push(acc);
+                    acc = '';
+                    const ext = new AST(c, ast);
+                    i = AST.#parseAST(str, ext, i, opt);
+                    ast.push(ext);
+                    continue;
+                }
+                acc += c;
+            }
+            ast.push(acc);
+            return i;
+        }
+        // some kind of extglob, pos is at the (
+        // find the next | or )
+        let i = pos + 1;
+        let part = new AST(null, ast);
+        const parts = [];
+        let acc = '';
+        while (i < str.length) {
+            const c = str.charAt(i++);
+            // still accumulate escapes at this point, but we do ignore
+            // starts that are escaped
+            if (escaping || c === '\\') {
+                escaping = !escaping;
+                acc += c;
+                continue;
+            }
+            if (inBrace) {
+                if (i === braceStart + 1) {
+                    if (c === '^' || c === '!') {
+                        braceNeg = true;
+                    }
+                }
+                else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {
+                    inBrace = false;
+                }
+                acc += c;
+                continue;
+            }
+            else if (c === '[') {
+                inBrace = true;
+                braceStart = i;
+                braceNeg = false;
+                acc += c;
+                continue;
+            }
+            if (isExtglobType(c) && str.charAt(i) === '(') {
+                part.push(acc);
+                acc = '';
+                const ext = new AST(c, part);
+                part.push(ext);
+                i = AST.#parseAST(str, ext, i, opt);
+                continue;
+            }
+            if (c === '|') {
+                part.push(acc);
+                acc = '';
+                parts.push(part);
+                part = new AST(null, ast);
+                continue;
+            }
+            if (c === ')') {
+                if (acc === '' && ast.#parts.length === 0) {
+                    ast.#emptyExt = true;
+                }
+                part.push(acc);
+                acc = '';
+                ast.push(...parts, part);
+                return i;
+            }
+            acc += c;
+        }
+        // unfinished extglob
+        // if we got here, it was a malformed extglob! not an extglob, but
+        // maybe something else in there.
+        ast.type = null;
+        ast.#hasMagic = undefined;
+        ast.#parts = [str.substring(pos - 1)];
+        return i;
+    }
+    static fromGlob(pattern, options = {}) {
+        const ast = new AST(null, undefined, options);
+        AST.#parseAST(pattern, ast, 0, options);
+        return ast;
+    }
+    // returns the regular expression if there's magic, or the unescaped
+    // string if not.
+    toMMPattern() {
+        // should only be called on root
+        /* c8 ignore start */
+        if (this !== this.#root)
+            return this.#root.toMMPattern();
+        /* c8 ignore stop */
+        const glob = this.toString();
+        const [re, body, hasMagic, uflag] = this.toRegExpSource();
+        // if we're in nocase mode, and not nocaseMagicOnly, then we do
+        // still need a regular expression if we have to case-insensitively
+        // match capital/lowercase characters.
+        const anyMagic = hasMagic ||
+            this.#hasMagic ||
+            (this.#options.nocase &&
+                !this.#options.nocaseMagicOnly &&
+                glob.toUpperCase() !== glob.toLowerCase());
+        if (!anyMagic) {
+            return body;
+        }
+        const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '');
+        return Object.assign(new RegExp(`^${re}$`, flags), {
+            _src: re,
+            _glob: glob,
+        });
+    }
+    // returns the string match, the regexp source, whether there's magic
+    // in the regexp (so a regular expression is required) and whether or
+    // not the uflag is needed for the regular expression (for posix classes)
+    // TODO: instead of injecting the start/end at this point, just return
+    // the BODY of the regexp, along with the start/end portions suitable
+    // for binding the start/end in either a joined full-path makeRe context
+    // (where we bind to (^|/), or a standalone matchPart context (where
+    // we bind to ^, and not /).  Otherwise slashes get duped!
+    //
+    // In part-matching mode, the start is:
+    // - if not isStart: nothing
+    // - if traversal possible, but not allowed: ^(?!\.\.?$)
+    // - if dots allowed or not possible: ^
+    // - if dots possible and not allowed: ^(?!\.)
+    // end is:
+    // - if not isEnd(): nothing
+    // - else: $
+    //
+    // In full-path matching mode, we put the slash at the START of the
+    // pattern, so start is:
+    // - if first pattern: same as part-matching mode
+    // - if not isStart(): nothing
+    // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
+    // - if dots allowed or not possible: /
+    // - if dots possible and not allowed: /(?!\.)
+    // end is:
+    // - if last pattern, same as part-matching mode
+    // - else nothing
+    //
+    // Always put the (?:$|/) on negated tails, though, because that has to be
+    // there to bind the end of the negated pattern portion, and it's easier to
+    // just stick it in now rather than try to inject it later in the middle of
+    // the pattern.
+    //
+    // We can just always return the same end, and leave it up to the caller
+    // to know whether it's going to be used joined or in parts.
+    // And, if the start is adjusted slightly, can do the same there:
+    // - if not isStart: nothing
+    // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
+    // - if dots allowed or not possible: (?:/|^)
+    // - if dots possible and not allowed: (?:/|^)(?!\.)
+    //
+    // But it's better to have a simpler binding without a conditional, for
+    // performance, so probably better to return both start options.
+    //
+    // Then the caller just ignores the end if it's not the first pattern,
+    // and the start always gets applied.
+    //
+    // But that's always going to be $ if it's the ending pattern, or nothing,
+    // so the caller can just attach $ at the end of the pattern when building.
+    //
+    // So the todo is:
+    // - better detect what kind of start is needed
+    // - return both flavors of starting pattern
+    // - attach $ at the end of the pattern when creating the actual RegExp
+    //
+    // Ah, but wait, no, that all only applies to the root when the first pattern
+    // is not an extglob. If the first pattern IS an extglob, then we need all
+    // that dot prevention biz to live in the extglob portions, because eg
+    // +(*|.x*) can match .xy but not .yx.
+    //
+    // So, return the two flavors if it's #root and the first child is not an
+    // AST, otherwise leave it to the child AST to handle it, and there,
+    // use the (?:^|/) style of start binding.
+    //
+    // Even simplified further:
+    // - Since the start for a join is eg /(?!\.) and the start for a part
+    // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
+    // or start or whatever) and prepend ^ or / at the Regexp construction.
+    toRegExpSource(allowDot) {
+        const dot = allowDot ?? !!this.#options.dot;
+        if (this.#root === this)
+            this.#fillNegs();
+        if (!this.type) {
+            const noEmpty = this.isStart() && this.isEnd();
+            const src = this.#parts
+                .map(p => {
+                const [re, _, hasMagic, uflag] = typeof p === 'string'
+                    ? AST.#parseGlob(p, this.#hasMagic, noEmpty)
+                    : p.toRegExpSource(allowDot);
+                this.#hasMagic = this.#hasMagic || hasMagic;
+                this.#uflag = this.#uflag || uflag;
+                return re;
+            })
+                .join('');
+            let start = '';
+            if (this.isStart()) {
+                if (typeof this.#parts[0] === 'string') {
+                    // this is the string that will match the start of the pattern,
+                    // so we need to protect against dots and such.
+                    // '.' and '..' cannot match unless the pattern is that exactly,
+                    // even if it starts with . or dot:true is set.
+                    const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
+                    if (!dotTravAllowed) {
+                        const aps = addPatternStart;
+                        // check if we have a possibility of matching . or ..,
+                        // and prevent that.
+                        const needNoTrav =
+                        // dots are allowed, and the pattern starts with [ or .
+                        (dot && aps.has(src.charAt(0))) ||
+                            // the pattern starts with \., and then [ or .
+                            (src.startsWith('\\.') && aps.has(src.charAt(2))) ||
+                            // the pattern starts with \.\., and then [ or .
+                            (src.startsWith('\\.\\.') && aps.has(src.charAt(4)));
+                        // no need to prevent dots if it can't match a dot, or if a
+                        // sub-pattern will be preventing it anyway.
+                        const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
+                        start = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : '';
+                    }
+                }
+            }
+            // append the "end of path portion" pattern to negation tails
+            let end = '';
+            if (this.isEnd() &&
+                this.#root.#filledNegs &&
+                this.#parent?.type === '!') {
+                end = '(?:$|\\/)';
+            }
+            const final = start + src + end;
+            return [
+                final,
+                unescape(src),
+                (this.#hasMagic = !!this.#hasMagic),
+                this.#uflag,
+            ];
+        }
+        // We need to calculate the body *twice* if it's a repeat pattern
+        // at the start, once in nodot mode, then again in dot mode, so a
+        // pattern like *(?) can match 'x.y'
+        const repeated = this.type === '*' || this.type === '+';
+        // some kind of extglob
+        const start = this.type === '!' ? '(?:(?!(?:' : '(?:';
+        let body = this.#partsToRegExp(dot);
+        if (this.isStart() && this.isEnd() && !body && this.type !== '!') {
+            // invalid extglob, has to at least be *something* present, if it's
+            // the entire path portion.
+            const s = this.toString();
+            this.#parts = [s];
+            this.type = null;
+            this.#hasMagic = undefined;
+            return [s, unescape(this.toString()), false, false];
+        }
+        // XXX abstract out this map method
+        let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot
+            ? ''
+            : this.#partsToRegExp(true);
+        if (bodyDotAllowed === body) {
+            bodyDotAllowed = '';
+        }
+        if (bodyDotAllowed) {
+            body = `(?:${body})(?:${bodyDotAllowed})*?`;
+        }
+        // an empty !() is exactly equivalent to a starNoEmpty
+        let final = '';
+        if (this.type === '!' && this.#emptyExt) {
+            final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty;
+        }
+        else {
+            const close = this.type === '!'
+                ? // !() must match something,but !(x) can match ''
+                    '))' +
+                        (this.isStart() && !dot && !allowDot ? startNoDot : '') +
+                        star +
+                        ')'
+                : this.type === '@'
+                    ? ')'
+                    : this.type === '?'
+                        ? ')?'
+                        : this.type === '+' && bodyDotAllowed
+                            ? ')'
+                            : this.type === '*' && bodyDotAllowed
+                                ? `)?`
+                                : `)${this.type}`;
+            final = start + body + close;
+        }
+        return [
+            final,
+            unescape(body),
+            (this.#hasMagic = !!this.#hasMagic),
+            this.#uflag,
+        ];
+    }
+    #partsToRegExp(dot) {
+        return this.#parts
+            .map(p => {
+            // extglob ASTs should only contain parent ASTs
+            /* c8 ignore start */
+            if (typeof p === 'string') {
+                throw new Error('string type in extglob ast??');
+            }
+            /* c8 ignore stop */
+            // can ignore hasMagic, because extglobs are already always magic
+            const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
+            this.#uflag = this.#uflag || uflag;
+            return re;
+        })
+            .filter(p => !(this.isStart() && this.isEnd()) || !!p)
+            .join('|');
+    }
+    static #parseGlob(glob, hasMagic, noEmpty = false) {
+        let escaping = false;
+        let re = '';
+        let uflag = false;
+        for (let i = 0; i < glob.length; i++) {
+            const c = glob.charAt(i);
+            if (escaping) {
+                escaping = false;
+                re += (reSpecials.has(c) ? '\\' : '') + c;
+                continue;
+            }
+            if (c === '\\') {
+                if (i === glob.length - 1) {
+                    re += '\\\\';
+                }
+                else {
+                    escaping = true;
+                }
+                continue;
+            }
+            if (c === '[') {
+                const [src, needUflag, consumed, magic] = parseClass(glob, i);
+                if (consumed) {
+                    re += src;
+                    uflag = uflag || needUflag;
+                    i += consumed - 1;
+                    hasMagic = hasMagic || magic;
+                    continue;
+                }
+            }
+            if (c === '*') {
+                if (noEmpty && glob === '*')
+                    re += starNoEmpty;
+                else
+                    re += star;
+                hasMagic = true;
+                continue;
+            }
+            if (c === '?') {
+                re += qmark;
+                hasMagic = true;
+                continue;
+            }
+            re += regExpEscape(c);
+        }
+        return [re, unescape(glob), !!hasMagic, uflag];
+    }
+}
+//# sourceMappingURL=ast.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/brace-expressions.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/brace-expressions.js
new file mode 100644
index 00000000000000..c629d6ae816e27
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/brace-expressions.js
@@ -0,0 +1,148 @@
+// translate the various posix character classes into unicode properties
+// this works across all unicode locales
+// { : [, /u flag required, negated]
+const posixClasses = {
+    '[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true],
+    '[:alpha:]': ['\\p{L}\\p{Nl}', true],
+    '[:ascii:]': ['\\x' + '00-\\x' + '7f', false],
+    '[:blank:]': ['\\p{Zs}\\t', true],
+    '[:cntrl:]': ['\\p{Cc}', true],
+    '[:digit:]': ['\\p{Nd}', true],
+    '[:graph:]': ['\\p{Z}\\p{C}', true, true],
+    '[:lower:]': ['\\p{Ll}', true],
+    '[:print:]': ['\\p{C}', true],
+    '[:punct:]': ['\\p{P}', true],
+    '[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true],
+    '[:upper:]': ['\\p{Lu}', true],
+    '[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true],
+    '[:xdigit:]': ['A-Fa-f0-9', false],
+};
+// only need to escape a few things inside of brace expressions
+// escapes: [ \ ] -
+const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&');
+// escape all regexp magic characters
+const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+// everything has already been escaped, we just have to join
+const rangesToString = (ranges) => ranges.join('');
+// takes a glob string at a posix brace expression, and returns
+// an equivalent regular expression source, and boolean indicating
+// whether the /u flag needs to be applied, and the number of chars
+// consumed to parse the character class.
+// This also removes out of order ranges, and returns ($.) if the
+// entire class just no good.
+export const parseClass = (glob, position) => {
+    const pos = position;
+    /* c8 ignore start */
+    if (glob.charAt(pos) !== '[') {
+        throw new Error('not in a brace expression');
+    }
+    /* c8 ignore stop */
+    const ranges = [];
+    const negs = [];
+    let i = pos + 1;
+    let sawStart = false;
+    let uflag = false;
+    let escaping = false;
+    let negate = false;
+    let endPos = pos;
+    let rangeStart = '';
+    WHILE: while (i < glob.length) {
+        const c = glob.charAt(i);
+        if ((c === '!' || c === '^') && i === pos + 1) {
+            negate = true;
+            i++;
+            continue;
+        }
+        if (c === ']' && sawStart && !escaping) {
+            endPos = i + 1;
+            break;
+        }
+        sawStart = true;
+        if (c === '\\') {
+            if (!escaping) {
+                escaping = true;
+                i++;
+                continue;
+            }
+            // escaped \ char, fall through and treat like normal char
+        }
+        if (c === '[' && !escaping) {
+            // either a posix class, a collation equivalent, or just a [
+            for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
+                if (glob.startsWith(cls, i)) {
+                    // invalid, [a-[] is fine, but not [a-[:alpha]]
+                    if (rangeStart) {
+                        return ['$.', false, glob.length - pos, true];
+                    }
+                    i += cls.length;
+                    if (neg)
+                        negs.push(unip);
+                    else
+                        ranges.push(unip);
+                    uflag = uflag || u;
+                    continue WHILE;
+                }
+            }
+        }
+        // now it's just a normal character, effectively
+        escaping = false;
+        if (rangeStart) {
+            // throw this range away if it's not valid, but others
+            // can still match.
+            if (c > rangeStart) {
+                ranges.push(braceEscape(rangeStart) + '-' + braceEscape(c));
+            }
+            else if (c === rangeStart) {
+                ranges.push(braceEscape(c));
+            }
+            rangeStart = '';
+            i++;
+            continue;
+        }
+        // now might be the start of a range.
+        // can be either c-d or c-] or c] or c] at this point
+        if (glob.startsWith('-]', i + 1)) {
+            ranges.push(braceEscape(c + '-'));
+            i += 2;
+            continue;
+        }
+        if (glob.startsWith('-', i + 1)) {
+            rangeStart = c;
+            i += 2;
+            continue;
+        }
+        // not the start of a range, just a single character
+        ranges.push(braceEscape(c));
+        i++;
+    }
+    if (endPos < i) {
+        // didn't see the end of the class, not a valid class,
+        // but might still be valid as a literal match.
+        return ['', false, 0, false];
+    }
+    // if we got no ranges and no negates, then we have a range that
+    // cannot possibly match anything, and that poisons the whole glob
+    if (!ranges.length && !negs.length) {
+        return ['$.', false, glob.length - pos, true];
+    }
+    // if we got one positive range, and it's a single character, then that's
+    // not actually a magic pattern, it's just that one literal character.
+    // we should not treat that as "magic", we should just return the literal
+    // character. [_] is a perfectly valid way to escape glob magic chars.
+    if (negs.length === 0 &&
+        ranges.length === 1 &&
+        /^\\?.$/.test(ranges[0]) &&
+        !negate) {
+        const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
+        return [regexpEscape(r), false, endPos - pos, false];
+    }
+    const sranges = '[' + (negate ? '^' : '') + rangesToString(ranges) + ']';
+    const snegs = '[' + (negate ? '' : '^') + rangesToString(negs) + ']';
+    const comb = ranges.length && negs.length
+        ? '(' + sranges + '|' + snegs + ')'
+        : ranges.length
+            ? sranges
+            : snegs;
+    return [comb, uflag, endPos - pos, true];
+};
+//# sourceMappingURL=brace-expressions.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/escape.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/escape.js
new file mode 100644
index 00000000000000..16f7c8c7bdc646
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/escape.js
@@ -0,0 +1,18 @@
+/**
+ * Escape all magic characters in a glob pattern.
+ *
+ * If the {@link windowsPathsNoEscape | GlobOptions.windowsPathsNoEscape}
+ * option is used, then characters are escaped by wrapping in `[]`, because
+ * a magic character wrapped in a character class can only be satisfied by
+ * that exact character.  In this mode, `\` is _not_ escaped, because it is
+ * not interpreted as a magic character, but instead as a path separator.
+ */
+export const escape = (s, { windowsPathsNoEscape = false, } = {}) => {
+    // don't need to escape +@! because we escape the parens
+    // that make those magic, and escaping ! as [!] isn't valid,
+    // because [!]] is a valid glob class meaning not ']'.
+    return windowsPathsNoEscape
+        ? s.replace(/[?*()[\]]/g, '[$&]')
+        : s.replace(/[?*()[\]\\]/g, '\\$&');
+};
+//# sourceMappingURL=escape.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/index.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/index.js
new file mode 100644
index 00000000000000..831b6a67f63fb4
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/index.js
@@ -0,0 +1,995 @@
+import expand from 'brace-expansion';
+import { assertValidPattern } from './assert-valid-pattern.js';
+import { AST } from './ast.js';
+import { escape } from './escape.js';
+import { unescape } from './unescape.js';
+export const minimatch = (p, pattern, options = {}) => {
+    assertValidPattern(pattern);
+    // shortcut: comments match nothing.
+    if (!options.nocomment && pattern.charAt(0) === '#') {
+        return false;
+    }
+    return new Minimatch(pattern, options).match(p);
+};
+// Optimized checking for the most common glob patterns.
+const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
+const starDotExtTest = (ext) => (f) => !f.startsWith('.') && f.endsWith(ext);
+const starDotExtTestDot = (ext) => (f) => f.endsWith(ext);
+const starDotExtTestNocase = (ext) => {
+    ext = ext.toLowerCase();
+    return (f) => !f.startsWith('.') && f.toLowerCase().endsWith(ext);
+};
+const starDotExtTestNocaseDot = (ext) => {
+    ext = ext.toLowerCase();
+    return (f) => f.toLowerCase().endsWith(ext);
+};
+const starDotStarRE = /^\*+\.\*+$/;
+const starDotStarTest = (f) => !f.startsWith('.') && f.includes('.');
+const starDotStarTestDot = (f) => f !== '.' && f !== '..' && f.includes('.');
+const dotStarRE = /^\.\*+$/;
+const dotStarTest = (f) => f !== '.' && f !== '..' && f.startsWith('.');
+const starRE = /^\*+$/;
+const starTest = (f) => f.length !== 0 && !f.startsWith('.');
+const starTestDot = (f) => f.length !== 0 && f !== '.' && f !== '..';
+const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
+const qmarksTestNocase = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExt([$0]);
+    if (!ext)
+        return noext;
+    ext = ext.toLowerCase();
+    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
+};
+const qmarksTestNocaseDot = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExtDot([$0]);
+    if (!ext)
+        return noext;
+    ext = ext.toLowerCase();
+    return (f) => noext(f) && f.toLowerCase().endsWith(ext);
+};
+const qmarksTestDot = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExtDot([$0]);
+    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
+};
+const qmarksTest = ([$0, ext = '']) => {
+    const noext = qmarksTestNoExt([$0]);
+    return !ext ? noext : (f) => noext(f) && f.endsWith(ext);
+};
+const qmarksTestNoExt = ([$0]) => {
+    const len = $0.length;
+    return (f) => f.length === len && !f.startsWith('.');
+};
+const qmarksTestNoExtDot = ([$0]) => {
+    const len = $0.length;
+    return (f) => f.length === len && f !== '.' && f !== '..';
+};
+/* c8 ignore start */
+const defaultPlatform = (typeof process === 'object' && process
+    ? (typeof process.env === 'object' &&
+        process.env &&
+        process.env.__MINIMATCH_TESTING_PLATFORM__) ||
+        process.platform
+    : 'posix');
+const path = {
+    win32: { sep: '\\' },
+    posix: { sep: '/' },
+};
+/* c8 ignore stop */
+export const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep;
+minimatch.sep = sep;
+export const GLOBSTAR = Symbol('globstar **');
+minimatch.GLOBSTAR = GLOBSTAR;
+// any single thing other than /
+// don't need to escape / when using new RegExp()
+const qmark = '[^/]';
+// * => any number of characters
+const star = qmark + '*?';
+// ** when dots are allowed.  Anything goes, except .. and .
+// not (^ or / followed by one or two dots followed by $ or /),
+// followed by anything, any number of times.
+const twoStarDot = '(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?';
+// not a ^ or / followed by a dot,
+// followed by anything, any number of times.
+const twoStarNoDot = '(?:(?!(?:\\/|^)\\.).)*?';
+export const filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
+minimatch.filter = filter;
+const ext = (a, b = {}) => Object.assign({}, a, b);
+export const defaults = (def) => {
+    if (!def || typeof def !== 'object' || !Object.keys(def).length) {
+        return minimatch;
+    }
+    const orig = minimatch;
+    const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
+    return Object.assign(m, {
+        Minimatch: class Minimatch extends orig.Minimatch {
+            constructor(pattern, options = {}) {
+                super(pattern, ext(def, options));
+            }
+            static defaults(options) {
+                return orig.defaults(ext(def, options)).Minimatch;
+            }
+        },
+        AST: class AST extends orig.AST {
+            /* c8 ignore start */
+            constructor(type, parent, options = {}) {
+                super(type, parent, ext(def, options));
+            }
+            /* c8 ignore stop */
+            static fromGlob(pattern, options = {}) {
+                return orig.AST.fromGlob(pattern, ext(def, options));
+            }
+        },
+        unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
+        escape: (s, options = {}) => orig.escape(s, ext(def, options)),
+        filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
+        defaults: (options) => orig.defaults(ext(def, options)),
+        makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
+        braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
+        match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
+        sep: orig.sep,
+        GLOBSTAR: GLOBSTAR,
+    });
+};
+minimatch.defaults = defaults;
+// Brace expansion:
+// a{b,c}d -> abd acd
+// a{b,}c -> abc ac
+// a{0..3}d -> a0d a1d a2d a3d
+// a{b,c{d,e}f}g -> abg acdfg acefg
+// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
+//
+// Invalid sets are not expanded.
+// a{2..}b -> a{2..}b
+// a{b}c -> a{b}c
+export const braceExpand = (pattern, options = {}) => {
+    assertValidPattern(pattern);
+    // Thanks to Yeting Li  for
+    // improving this regexp to avoid a ReDOS vulnerability.
+    if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
+        // shortcut. no need to expand.
+        return [pattern];
+    }
+    return expand(pattern);
+};
+minimatch.braceExpand = braceExpand;
+// parse a component of the expanded set.
+// At this point, no pattern may contain "/" in it
+// so we're going to return a 2d array, where each entry is the full
+// pattern, split on '/', and then turned into a regular expression.
+// A regexp is made at the end which joins each array with an
+// escaped /, and another full one which joins each regexp with |.
+//
+// Following the lead of Bash 4.1, note that "**" only has special meaning
+// when it is the *only* thing in a path portion.  Otherwise, any series
+// of * is equivalent to a single *.  Globstar behavior is enabled by
+// default, and can be disabled by setting options.noglobstar.
+export const makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
+minimatch.makeRe = makeRe;
+export const match = (list, pattern, options = {}) => {
+    const mm = new Minimatch(pattern, options);
+    list = list.filter(f => mm.match(f));
+    if (mm.options.nonull && !list.length) {
+        list.push(pattern);
+    }
+    return list;
+};
+minimatch.match = match;
+// replace stuff like \* with *
+const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
+const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
+export class Minimatch {
+    options;
+    set;
+    pattern;
+    windowsPathsNoEscape;
+    nonegate;
+    negate;
+    comment;
+    empty;
+    preserveMultipleSlashes;
+    partial;
+    globSet;
+    globParts;
+    nocase;
+    isWindows;
+    platform;
+    windowsNoMagicRoot;
+    regexp;
+    constructor(pattern, options = {}) {
+        assertValidPattern(pattern);
+        options = options || {};
+        this.options = options;
+        this.pattern = pattern;
+        this.platform = options.platform || defaultPlatform;
+        this.isWindows = this.platform === 'win32';
+        this.windowsPathsNoEscape =
+            !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
+        if (this.windowsPathsNoEscape) {
+            this.pattern = this.pattern.replace(/\\/g, '/');
+        }
+        this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
+        this.regexp = null;
+        this.negate = false;
+        this.nonegate = !!options.nonegate;
+        this.comment = false;
+        this.empty = false;
+        this.partial = !!options.partial;
+        this.nocase = !!this.options.nocase;
+        this.windowsNoMagicRoot =
+            options.windowsNoMagicRoot !== undefined
+                ? options.windowsNoMagicRoot
+                : !!(this.isWindows && this.nocase);
+        this.globSet = [];
+        this.globParts = [];
+        this.set = [];
+        // make the set of regexps etc.
+        this.make();
+    }
+    hasMagic() {
+        if (this.options.magicalBraces && this.set.length > 1) {
+            return true;
+        }
+        for (const pattern of this.set) {
+            for (const part of pattern) {
+                if (typeof part !== 'string')
+                    return true;
+            }
+        }
+        return false;
+    }
+    debug(..._) { }
+    make() {
+        const pattern = this.pattern;
+        const options = this.options;
+        // empty patterns and comments match nothing.
+        if (!options.nocomment && pattern.charAt(0) === '#') {
+            this.comment = true;
+            return;
+        }
+        if (!pattern) {
+            this.empty = true;
+            return;
+        }
+        // step 1: figure out negation, etc.
+        this.parseNegate();
+        // step 2: expand braces
+        this.globSet = [...new Set(this.braceExpand())];
+        if (options.debug) {
+            this.debug = (...args) => console.error(...args);
+        }
+        this.debug(this.pattern, this.globSet);
+        // step 3: now we have a set, so turn each one into a series of
+        // path-portion matching patterns.
+        // These will be regexps, except in the case of "**", which is
+        // set to the GLOBSTAR object for globstar behavior,
+        // and will not contain any / characters
+        //
+        // First, we preprocess to make the glob pattern sets a bit simpler
+        // and deduped.  There are some perf-killing patterns that can cause
+        // problems with a glob walk, but we can simplify them down a bit.
+        const rawGlobParts = this.globSet.map(s => this.slashSplit(s));
+        this.globParts = this.preprocess(rawGlobParts);
+        this.debug(this.pattern, this.globParts);
+        // glob --> regexps
+        let set = this.globParts.map((s, _, __) => {
+            if (this.isWindows && this.windowsNoMagicRoot) {
+                // check if it's a drive or unc path.
+                const isUNC = s[0] === '' &&
+                    s[1] === '' &&
+                    (s[2] === '?' || !globMagic.test(s[2])) &&
+                    !globMagic.test(s[3]);
+                const isDrive = /^[a-z]:/i.test(s[0]);
+                if (isUNC) {
+                    return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))];
+                }
+                else if (isDrive) {
+                    return [s[0], ...s.slice(1).map(ss => this.parse(ss))];
+                }
+            }
+            return s.map(ss => this.parse(ss));
+        });
+        this.debug(this.pattern, set);
+        // filter out everything that didn't compile properly.
+        this.set = set.filter(s => s.indexOf(false) === -1);
+        // do not treat the ? in UNC paths as magic
+        if (this.isWindows) {
+            for (let i = 0; i < this.set.length; i++) {
+                const p = this.set[i];
+                if (p[0] === '' &&
+                    p[1] === '' &&
+                    this.globParts[i][2] === '?' &&
+                    typeof p[3] === 'string' &&
+                    /^[a-z]:$/i.test(p[3])) {
+                    p[2] = '?';
+                }
+            }
+        }
+        this.debug(this.pattern, this.set);
+    }
+    // various transforms to equivalent pattern sets that are
+    // faster to process in a filesystem walk.  The goal is to
+    // eliminate what we can, and push all ** patterns as far
+    // to the right as possible, even if it increases the number
+    // of patterns that we have to process.
+    preprocess(globParts) {
+        // if we're not in globstar mode, then turn all ** into *
+        if (this.options.noglobstar) {
+            for (let i = 0; i < globParts.length; i++) {
+                for (let j = 0; j < globParts[i].length; j++) {
+                    if (globParts[i][j] === '**') {
+                        globParts[i][j] = '*';
+                    }
+                }
+            }
+        }
+        const { optimizationLevel = 1 } = this.options;
+        if (optimizationLevel >= 2) {
+            // aggressive optimization for the purpose of fs walking
+            globParts = this.firstPhasePreProcess(globParts);
+            globParts = this.secondPhasePreProcess(globParts);
+        }
+        else if (optimizationLevel >= 1) {
+            // just basic optimizations to remove some .. parts
+            globParts = this.levelOneOptimize(globParts);
+        }
+        else {
+            globParts = this.adjascentGlobstarOptimize(globParts);
+        }
+        return globParts;
+    }
+    // just get rid of adjascent ** portions
+    adjascentGlobstarOptimize(globParts) {
+        return globParts.map(parts => {
+            let gs = -1;
+            while (-1 !== (gs = parts.indexOf('**', gs + 1))) {
+                let i = gs;
+                while (parts[i + 1] === '**') {
+                    i++;
+                }
+                if (i !== gs) {
+                    parts.splice(gs, i - gs);
+                }
+            }
+            return parts;
+        });
+    }
+    // get rid of adjascent ** and resolve .. portions
+    levelOneOptimize(globParts) {
+        return globParts.map(parts => {
+            parts = parts.reduce((set, part) => {
+                const prev = set[set.length - 1];
+                if (part === '**' && prev === '**') {
+                    return set;
+                }
+                if (part === '..') {
+                    if (prev && prev !== '..' && prev !== '.' && prev !== '**') {
+                        set.pop();
+                        return set;
+                    }
+                }
+                set.push(part);
+                return set;
+            }, []);
+            return parts.length === 0 ? [''] : parts;
+        });
+    }
+    levelTwoFileOptimize(parts) {
+        if (!Array.isArray(parts)) {
+            parts = this.slashSplit(parts);
+        }
+        let didSomething = false;
+        do {
+            didSomething = false;
+            // 
// -> 
/
+            if (!this.preserveMultipleSlashes) {
+                for (let i = 1; i < parts.length - 1; i++) {
+                    const p = parts[i];
+                    // don't squeeze out UNC patterns
+                    if (i === 1 && p === '' && parts[0] === '')
+                        continue;
+                    if (p === '.' || p === '') {
+                        didSomething = true;
+                        parts.splice(i, 1);
+                        i--;
+                    }
+                }
+                if (parts[0] === '.' &&
+                    parts.length === 2 &&
+                    (parts[1] === '.' || parts[1] === '')) {
+                    didSomething = true;
+                    parts.pop();
+                }
+            }
+            // 
/

/../ ->

/
+            let dd = 0;
+            while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                const p = parts[dd - 1];
+                if (p && p !== '.' && p !== '..' && p !== '**') {
+                    didSomething = true;
+                    parts.splice(dd - 1, 2);
+                    dd -= 2;
+                }
+            }
+        } while (didSomething);
+        return parts.length === 0 ? [''] : parts;
+    }
+    // First phase: single-pattern processing
+    // 
 is 1 or more portions
+    //  is 1 or more portions
+    // 

is any portion other than ., .., '', or ** + // is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + //

/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + //

// -> 
/
+    // 
/

/../ ->

/
+    // **/**/ -> **/
+    //
+    // **/*/ -> */**/ <== not valid because ** doesn't follow
+    // this WOULD be allowed if ** did follow symlinks, or * didn't
+    firstPhasePreProcess(globParts) {
+        let didSomething = false;
+        do {
+            didSomething = false;
+            // 
/**/../

/

/ -> {

/../

/

/,

/**/

/

/} + for (let parts of globParts) { + let gs = -1; + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let gss = gs; + while (parts[gss + 1] === '**') { + //

/**/**/ -> 
/**/
+                        gss++;
+                    }
+                    // eg, if gs is 2 and gss is 4, that means we have 3 **
+                    // parts, and can remove 2 of them.
+                    if (gss > gs) {
+                        parts.splice(gs + 1, gss - gs);
+                    }
+                    let next = parts[gs + 1];
+                    const p = parts[gs + 2];
+                    const p2 = parts[gs + 3];
+                    if (next !== '..')
+                        continue;
+                    if (!p ||
+                        p === '.' ||
+                        p === '..' ||
+                        !p2 ||
+                        p2 === '.' ||
+                        p2 === '..') {
+                        continue;
+                    }
+                    didSomething = true;
+                    // edit parts in place, and push the new one
+                    parts.splice(gs, 1);
+                    const other = parts.slice(0);
+                    other[gs] = '**';
+                    globParts.push(other);
+                    gs--;
+                }
+                // 
// -> 
/
+                if (!this.preserveMultipleSlashes) {
+                    for (let i = 1; i < parts.length - 1; i++) {
+                        const p = parts[i];
+                        // don't squeeze out UNC patterns
+                        if (i === 1 && p === '' && parts[0] === '')
+                            continue;
+                        if (p === '.' || p === '') {
+                            didSomething = true;
+                            parts.splice(i, 1);
+                            i--;
+                        }
+                    }
+                    if (parts[0] === '.' &&
+                        parts.length === 2 &&
+                        (parts[1] === '.' || parts[1] === '')) {
+                        didSomething = true;
+                        parts.pop();
+                    }
+                }
+                // 
/

/../ ->

/
+                let dd = 0;
+                while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+                    const p = parts[dd - 1];
+                    if (p && p !== '.' && p !== '..' && p !== '**') {
+                        didSomething = true;
+                        const needDot = dd === 1 && parts[dd + 1] === '**';
+                        const splin = needDot ? ['.'] : [];
+                        parts.splice(dd - 1, 2, ...splin);
+                        if (parts.length === 0)
+                            parts.push('');
+                        dd -= 2;
+                    }
+                }
+            }
+        } while (didSomething);
+        return globParts;
+    }
+    // second phase: multi-pattern dedupes
+    // {
/*/,
/

/} ->

/*/
+    // {
/,
/} -> 
/
+    // {
/**/,
/} -> 
/**/
+    //
+    // {
/**/,
/**/

/} ->

/**/
+    // ^-- not valid because ** doens't follow symlinks
+    secondPhasePreProcess(globParts) {
+        for (let i = 0; i < globParts.length - 1; i++) {
+            for (let j = i + 1; j < globParts.length; j++) {
+                const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
+                if (!matched)
+                    continue;
+                globParts[i] = matched;
+                globParts[j] = [];
+            }
+        }
+        return globParts.filter(gs => gs.length);
+    }
+    partsMatch(a, b, emptyGSMatch = false) {
+        let ai = 0;
+        let bi = 0;
+        let result = [];
+        let which = '';
+        while (ai < a.length && bi < b.length) {
+            if (a[ai] === b[bi]) {
+                result.push(which === 'b' ? b[bi] : a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (emptyGSMatch && a[ai] === '**' && b[bi] === a[ai + 1]) {
+                result.push(a[ai]);
+                ai++;
+            }
+            else if (emptyGSMatch && b[bi] === '**' && a[ai] === b[bi + 1]) {
+                result.push(b[bi]);
+                bi++;
+            }
+            else if (a[ai] === '*' &&
+                b[bi] &&
+                (this.options.dot || !b[bi].startsWith('.')) &&
+                b[bi] !== '**') {
+                if (which === 'b')
+                    return false;
+                which = 'a';
+                result.push(a[ai]);
+                ai++;
+                bi++;
+            }
+            else if (b[bi] === '*' &&
+                a[ai] &&
+                (this.options.dot || !a[ai].startsWith('.')) &&
+                a[ai] !== '**') {
+                if (which === 'a')
+                    return false;
+                which = 'b';
+                result.push(b[bi]);
+                ai++;
+                bi++;
+            }
+            else {
+                return false;
+            }
+        }
+        // if we fall out of the loop, it means they two are identical
+        // as long as their lengths match
+        return a.length === b.length && result;
+    }
+    parseNegate() {
+        if (this.nonegate)
+            return;
+        const pattern = this.pattern;
+        let negate = false;
+        let negateOffset = 0;
+        for (let i = 0; i < pattern.length && pattern.charAt(i) === '!'; i++) {
+            negate = !negate;
+            negateOffset++;
+        }
+        if (negateOffset)
+            this.pattern = pattern.slice(negateOffset);
+        this.negate = negate;
+    }
+    // set partial to true to test if, for example,
+    // "/a/b" matches the start of "/*/b/*/d"
+    // Partial means, if you run out of file before you run
+    // out of pattern, then that's fine, as long as all
+    // the parts match.
+    matchOne(file, pattern, partial = false) {
+        const options = this.options;
+        // UNC paths like //?/X:/... can match X:/... and vice versa
+        // Drive letters in absolute drive or unc paths are always compared
+        // case-insensitively.
+        if (this.isWindows) {
+            const fileDrive = typeof file[0] === 'string' && /^[a-z]:$/i.test(file[0]);
+            const fileUNC = !fileDrive &&
+                file[0] === '' &&
+                file[1] === '' &&
+                file[2] === '?' &&
+                /^[a-z]:$/i.test(file[3]);
+            const patternDrive = typeof pattern[0] === 'string' && /^[a-z]:$/i.test(pattern[0]);
+            const patternUNC = !patternDrive &&
+                pattern[0] === '' &&
+                pattern[1] === '' &&
+                pattern[2] === '?' &&
+                typeof pattern[3] === 'string' &&
+                /^[a-z]:$/i.test(pattern[3]);
+            const fdi = fileUNC ? 3 : fileDrive ? 0 : undefined;
+            const pdi = patternUNC ? 3 : patternDrive ? 0 : undefined;
+            if (typeof fdi === 'number' && typeof pdi === 'number') {
+                const [fd, pd] = [file[fdi], pattern[pdi]];
+                if (fd.toLowerCase() === pd.toLowerCase()) {
+                    pattern[pdi] = fd;
+                    if (pdi > fdi) {
+                        pattern = pattern.slice(pdi);
+                    }
+                    else if (fdi > pdi) {
+                        file = file.slice(fdi);
+                    }
+                }
+            }
+        }
+        // resolve and reduce . and .. portions in the file as well.
+        // dont' need to do the second phase, because it's only one string[]
+        const { optimizationLevel = 1 } = this.options;
+        if (optimizationLevel >= 2) {
+            file = this.levelTwoFileOptimize(file);
+        }
+        this.debug('matchOne', this, { file, pattern });
+        this.debug('matchOne', file.length, pattern.length);
+        for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
+            this.debug('matchOne loop');
+            var p = pattern[pi];
+            var f = file[fi];
+            this.debug(pattern, p, f);
+            // should be impossible.
+            // some invalid regexp stuff in the set.
+            /* c8 ignore start */
+            if (p === false) {
+                return false;
+            }
+            /* c8 ignore stop */
+            if (p === GLOBSTAR) {
+                this.debug('GLOBSTAR', [pattern, p, f]);
+                // "**"
+                // a/**/b/**/c would match the following:
+                // a/b/x/y/z/c
+                // a/x/y/z/b/c
+                // a/b/x/b/x/c
+                // a/b/c
+                // To do this, take the rest of the pattern after
+                // the **, and see if it would match the file remainder.
+                // If so, return success.
+                // If not, the ** "swallows" a segment, and try again.
+                // This is recursively awful.
+                //
+                // a/**/b/**/c matching a/b/x/y/z/c
+                // - a matches a
+                // - doublestar
+                //   - matchOne(b/x/y/z/c, b/**/c)
+                //     - b matches b
+                //     - doublestar
+                //       - matchOne(x/y/z/c, c) -> no
+                //       - matchOne(y/z/c, c) -> no
+                //       - matchOne(z/c, c) -> no
+                //       - matchOne(c, c) yes, hit
+                var fr = fi;
+                var pr = pi + 1;
+                if (pr === pl) {
+                    this.debug('** at the end');
+                    // a ** at the end will just swallow the rest.
+                    // We have found a match.
+                    // however, it will not swallow /.x, unless
+                    // options.dot is set.
+                    // . and .. are *never* matched by **, for explosively
+                    // exponential reasons.
+                    for (; fi < fl; fi++) {
+                        if (file[fi] === '.' ||
+                            file[fi] === '..' ||
+                            (!options.dot && file[fi].charAt(0) === '.'))
+                            return false;
+                    }
+                    return true;
+                }
+                // ok, let's see if we can swallow whatever we can.
+                while (fr < fl) {
+                    var swallowee = file[fr];
+                    this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
+                    // XXX remove this slice.  Just pass the start index.
+                    if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
+                        this.debug('globstar found match!', fr, fl, swallowee);
+                        // found a match.
+                        return true;
+                    }
+                    else {
+                        // can't swallow "." or ".." ever.
+                        // can only swallow ".foo" when explicitly asked.
+                        if (swallowee === '.' ||
+                            swallowee === '..' ||
+                            (!options.dot && swallowee.charAt(0) === '.')) {
+                            this.debug('dot detected!', file, fr, pattern, pr);
+                            break;
+                        }
+                        // ** swallows a segment, and continue.
+                        this.debug('globstar swallow a segment, and continue');
+                        fr++;
+                    }
+                }
+                // no match was found.
+                // However, in partial mode, we can't say this is necessarily over.
+                /* c8 ignore start */
+                if (partial) {
+                    // ran out of file
+                    this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
+                    if (fr === fl) {
+                        return true;
+                    }
+                }
+                /* c8 ignore stop */
+                return false;
+            }
+            // something other than **
+            // non-magic patterns just have to match exactly
+            // patterns with magic have been turned into regexps.
+            let hit;
+            if (typeof p === 'string') {
+                hit = f === p;
+                this.debug('string match', p, f, hit);
+            }
+            else {
+                hit = p.test(f);
+                this.debug('pattern match', p, f, hit);
+            }
+            if (!hit)
+                return false;
+        }
+        // Note: ending in / means that we'll get a final ""
+        // at the end of the pattern.  This can only match a
+        // corresponding "" at the end of the file.
+        // If the file ends in /, then it can only match a
+        // a pattern that ends in /, unless the pattern just
+        // doesn't have any more for it. But, a/b/ should *not*
+        // match "a/b/*", even though "" matches against the
+        // [^/]*? pattern, except in partial mode, where it might
+        // simply not be reached yet.
+        // However, a/b/ should still satisfy a/*
+        // now either we fell off the end of the pattern, or we're done.
+        if (fi === fl && pi === pl) {
+            // ran out of pattern and filename at the same time.
+            // an exact hit!
+            return true;
+        }
+        else if (fi === fl) {
+            // ran out of file, but still had pattern left.
+            // this is ok if we're doing the match as part of
+            // a glob fs traversal.
+            return partial;
+        }
+        else if (pi === pl) {
+            // ran out of pattern, still have file left.
+            // this is only acceptable if we're on the very last
+            // empty segment of a file with a trailing slash.
+            // a/* should match a/b/
+            return fi === fl - 1 && file[fi] === '';
+            /* c8 ignore start */
+        }
+        else {
+            // should be unreachable.
+            throw new Error('wtf?');
+        }
+        /* c8 ignore stop */
+    }
+    braceExpand() {
+        return braceExpand(this.pattern, this.options);
+    }
+    parse(pattern) {
+        assertValidPattern(pattern);
+        const options = this.options;
+        // shortcuts
+        if (pattern === '**')
+            return GLOBSTAR;
+        if (pattern === '')
+            return '';
+        // far and away, the most common glob pattern parts are
+        // *, *.*, and *.  Add a fast check method for those.
+        let m;
+        let fastTest = null;
+        if ((m = pattern.match(starRE))) {
+            fastTest = options.dot ? starTestDot : starTest;
+        }
+        else if ((m = pattern.match(starDotExtRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? starDotExtTestNocaseDot
+                    : starDotExtTestNocase
+                : options.dot
+                    ? starDotExtTestDot
+                    : starDotExtTest)(m[1]);
+        }
+        else if ((m = pattern.match(qmarksRE))) {
+            fastTest = (options.nocase
+                ? options.dot
+                    ? qmarksTestNocaseDot
+                    : qmarksTestNocase
+                : options.dot
+                    ? qmarksTestDot
+                    : qmarksTest)(m);
+        }
+        else if ((m = pattern.match(starDotStarRE))) {
+            fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
+        }
+        else if ((m = pattern.match(dotStarRE))) {
+            fastTest = dotStarTest;
+        }
+        const re = AST.fromGlob(pattern, this.options).toMMPattern();
+        return fastTest ? Object.assign(re, { test: fastTest }) : re;
+    }
+    makeRe() {
+        if (this.regexp || this.regexp === false)
+            return this.regexp;
+        // at this point, this.set is a 2d array of partial
+        // pattern strings, or "**".
+        //
+        // It's better to use .match().  This function shouldn't
+        // be used, really, but it's pretty convenient sometimes,
+        // when you just want to work with a regex.
+        const set = this.set;
+        if (!set.length) {
+            this.regexp = false;
+            return this.regexp;
+        }
+        const options = this.options;
+        const twoStar = options.noglobstar
+            ? star
+            : options.dot
+                ? twoStarDot
+                : twoStarNoDot;
+        const flags = new Set(options.nocase ? ['i'] : []);
+        // regexpify non-globstar patterns
+        // if ** is only item, then we just do one twoStar
+        // if ** is first, and there are more, prepend (\/|twoStar\/)? to next
+        // if ** is last, append (\/twoStar|) to previous
+        // if ** is in the middle, append (\/|\/twoStar\/) to previous
+        // then filter out GLOBSTAR symbols
+        let re = set
+            .map(pattern => {
+            const pp = pattern.map(p => {
+                if (p instanceof RegExp) {
+                    for (const f of p.flags.split(''))
+                        flags.add(f);
+                }
+                return typeof p === 'string'
+                    ? regExpEscape(p)
+                    : p === GLOBSTAR
+                        ? GLOBSTAR
+                        : p._src;
+            });
+            pp.forEach((p, i) => {
+                const next = pp[i + 1];
+                const prev = pp[i - 1];
+                if (p !== GLOBSTAR || prev === GLOBSTAR) {
+                    return;
+                }
+                if (prev === undefined) {
+                    if (next !== undefined && next !== GLOBSTAR) {
+                        pp[i + 1] = '(?:\\/|' + twoStar + '\\/)?' + next;
+                    }
+                    else {
+                        pp[i] = twoStar;
+                    }
+                }
+                else if (next === undefined) {
+                    pp[i - 1] = prev + '(?:\\/|' + twoStar + ')?';
+                }
+                else if (next !== GLOBSTAR) {
+                    pp[i - 1] = prev + '(?:\\/|\\/' + twoStar + '\\/)' + next;
+                    pp[i + 1] = GLOBSTAR;
+                }
+            });
+            return pp.filter(p => p !== GLOBSTAR).join('/');
+        })
+            .join('|');
+        // need to wrap in parens if we had more than one thing with |,
+        // otherwise only the first will be anchored to ^ and the last to $
+        const [open, close] = set.length > 1 ? ['(?:', ')'] : ['', ''];
+        // must match entire pattern
+        // ending in a * or ** will make it less strict.
+        re = '^' + open + re + close + '$';
+        // can match anything, as long as it's not this.
+        if (this.negate)
+            re = '^(?!' + re + ').+$';
+        try {
+            this.regexp = new RegExp(re, [...flags].join(''));
+            /* c8 ignore start */
+        }
+        catch (ex) {
+            // should be impossible
+            this.regexp = false;
+        }
+        /* c8 ignore stop */
+        return this.regexp;
+    }
+    slashSplit(p) {
+        // if p starts with // on windows, we preserve that
+        // so that UNC paths aren't broken.  Otherwise, any number of
+        // / characters are coalesced into one, unless
+        // preserveMultipleSlashes is set to true.
+        if (this.preserveMultipleSlashes) {
+            return p.split('/');
+        }
+        else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
+            // add an extra '' for the one we lose
+            return ['', ...p.split(/\/+/)];
+        }
+        else {
+            return p.split(/\/+/);
+        }
+    }
+    match(f, partial = this.partial) {
+        this.debug('match', f, this.pattern);
+        // short-circuit in the case of busted things.
+        // comments, etc.
+        if (this.comment) {
+            return false;
+        }
+        if (this.empty) {
+            return f === '';
+        }
+        if (f === '/' && partial) {
+            return true;
+        }
+        const options = this.options;
+        // windows: need to use /, not \
+        if (this.isWindows) {
+            f = f.split('\\').join('/');
+        }
+        // treat the test path as a set of pathparts.
+        const ff = this.slashSplit(f);
+        this.debug(this.pattern, 'split', ff);
+        // just ONE of the pattern sets in this.set needs to match
+        // in order for it to be valid.  If negating, then just one
+        // match means that we have failed.
+        // Either way, return on the first hit.
+        const set = this.set;
+        this.debug(this.pattern, 'set', set);
+        // Find the basename of the path by looking for the last non-empty segment
+        let filename = ff[ff.length - 1];
+        if (!filename) {
+            for (let i = ff.length - 2; !filename && i >= 0; i--) {
+                filename = ff[i];
+            }
+        }
+        for (let i = 0; i < set.length; i++) {
+            const pattern = set[i];
+            let file = ff;
+            if (options.matchBase && pattern.length === 1) {
+                file = [filename];
+            }
+            const hit = this.matchOne(file, pattern, partial);
+            if (hit) {
+                if (options.flipNegate) {
+                    return true;
+                }
+                return !this.negate;
+            }
+        }
+        // didn't get any hits.  this is success if it's a negative
+        // pattern, failure otherwise.
+        if (options.flipNegate) {
+            return false;
+        }
+        return this.negate;
+    }
+    static defaults(def) {
+        return minimatch.defaults(def).Minimatch;
+    }
+}
+/* c8 ignore start */
+export { AST } from './ast.js';
+export { escape } from './escape.js';
+export { unescape } from './unescape.js';
+/* c8 ignore stop */
+minimatch.AST = AST;
+minimatch.Minimatch = Minimatch;
+minimatch.escape = escape;
+minimatch.unescape = unescape;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/package.json b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/package.json
new file mode 100644
index 00000000000000..3dbc1ca591c055
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "module"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/unescape.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/unescape.js
new file mode 100644
index 00000000000000..0faf9a2b7306f7
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/dist/mjs/unescape.js
@@ -0,0 +1,20 @@
+/**
+ * Un-escape a string that has been escaped with {@link escape}.
+ *
+ * If the {@link windowsPathsNoEscape} option is used, then square-brace
+ * escapes are removed, but not backslash escapes.  For example, it will turn
+ * the string `'[*]'` into `*`, but it will not turn `'\\*'` into `'*'`,
+ * becuase `\` is a path separator in `windowsPathsNoEscape` mode.
+ *
+ * When `windowsPathsNoEscape` is not set, then both brace escapes and
+ * backslash escapes are removed.
+ *
+ * Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
+ * or unescaped.
+ */
+export const unescape = (s, { windowsPathsNoEscape = false, } = {}) => {
+    return windowsPathsNoEscape
+        ? s.replace(/\[([^\/\\])\]/g, '$1')
+        : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, '$1$2').replace(/\\([^\/])/g, '$1');
+};
+//# sourceMappingURL=unescape.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/package.json b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/package.json
new file mode 100644
index 00000000000000..061c3b9f343306
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minimatch/package.json
@@ -0,0 +1,86 @@
+{
+  "author": "Isaac Z. Schlueter  (http://blog.izs.me)",
+  "name": "minimatch",
+  "description": "a glob matcher in javascript",
+  "version": "9.0.3",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/minimatch.git"
+  },
+  "main": "./dist/cjs/index.js",
+  "module": "./dist/mjs/index.js",
+  "types": "./dist/cjs/index.d.ts",
+  "exports": {
+    ".": {
+      "import": {
+        "types": "./dist/mjs/index.d.ts",
+        "default": "./dist/mjs/index.js"
+      },
+      "require": {
+        "types": "./dist/cjs/index.d.ts",
+        "default": "./dist/cjs/index.js"
+      }
+    }
+  },
+  "files": [
+    "dist"
+  ],
+  "scripts": {
+    "preversion": "npm test",
+    "postversion": "npm publish",
+    "prepublishOnly": "git push origin --follow-tags",
+    "preprepare": "rm -rf dist",
+    "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json",
+    "postprepare": "bash fixup.sh",
+    "pretest": "npm run prepare",
+    "presnap": "npm run prepare",
+    "test": "c8 tap",
+    "snap": "c8 tap",
+    "format": "prettier --write . --loglevel warn",
+    "benchmark": "node benchmark/index.js",
+    "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts"
+  },
+  "prettier": {
+    "semi": false,
+    "printWidth": 80,
+    "tabWidth": 2,
+    "useTabs": false,
+    "singleQuote": true,
+    "jsxSingleQuote": false,
+    "bracketSameLine": true,
+    "arrowParens": "avoid",
+    "endOfLine": "lf"
+  },
+  "engines": {
+    "node": ">=16 || 14 >=14.17"
+  },
+  "dependencies": {
+    "brace-expansion": "^2.0.1"
+  },
+  "devDependencies": {
+    "@types/brace-expansion": "^1.1.0",
+    "@types/node": "^18.15.11",
+    "@types/tap": "^15.0.8",
+    "c8": "^7.12.0",
+    "eslint-config-prettier": "^8.6.0",
+    "mkdirp": "1",
+    "prettier": "^2.8.2",
+    "tap": "^16.3.7",
+    "ts-node": "^10.9.1",
+    "typedoc": "^0.23.21",
+    "typescript": "^4.9.3"
+  },
+  "tap": {
+    "coverage": false,
+    "node-arg": [
+      "--no-warnings",
+      "--loader",
+      "ts-node/esm"
+    ],
+    "ts": false
+  },
+  "funding": {
+    "url": "https://github.com/sponsors/isaacs"
+  },
+  "license": "ISC"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/LICENSE
new file mode 100644
index 00000000000000..97f8e32ed82e4c
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/cjs/index.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/cjs/index.js
new file mode 100644
index 00000000000000..b6cdae8eb514b8
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/cjs/index.js
@@ -0,0 +1,1028 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Minipass = exports.isWritable = exports.isReadable = exports.isStream = void 0;
+const proc = typeof process === 'object' && process
+    ? process
+    : {
+        stdout: null,
+        stderr: null,
+    };
+const events_1 = require("events");
+const stream_1 = __importDefault(require("stream"));
+const string_decoder_1 = require("string_decoder");
+/**
+ * Return true if the argument is a Minipass stream, Node stream, or something
+ * else that Minipass can interact with.
+ */
+const isStream = (s) => !!s &&
+    typeof s === 'object' &&
+    (s instanceof Minipass ||
+        s instanceof stream_1.default ||
+        (0, exports.isReadable)(s) ||
+        (0, exports.isWritable)(s));
+exports.isStream = isStream;
+/**
+ * Return true if the argument is a valid {@link Minipass.Readable}
+ */
+const isReadable = (s) => !!s &&
+    typeof s === 'object' &&
+    s instanceof events_1.EventEmitter &&
+    typeof s.pipe === 'function' &&
+    // node core Writable streams have a pipe() method, but it throws
+    s.pipe !== stream_1.default.Writable.prototype.pipe;
+exports.isReadable = isReadable;
+/**
+ * Return true if the argument is a valid {@link Minipass.Writable}
+ */
+const isWritable = (s) => !!s &&
+    typeof s === 'object' &&
+    s instanceof events_1.EventEmitter &&
+    typeof s.write === 'function' &&
+    typeof s.end === 'function';
+exports.isWritable = isWritable;
+const EOF = Symbol('EOF');
+const MAYBE_EMIT_END = Symbol('maybeEmitEnd');
+const EMITTED_END = Symbol('emittedEnd');
+const EMITTING_END = Symbol('emittingEnd');
+const EMITTED_ERROR = Symbol('emittedError');
+const CLOSED = Symbol('closed');
+const READ = Symbol('read');
+const FLUSH = Symbol('flush');
+const FLUSHCHUNK = Symbol('flushChunk');
+const ENCODING = Symbol('encoding');
+const DECODER = Symbol('decoder');
+const FLOWING = Symbol('flowing');
+const PAUSED = Symbol('paused');
+const RESUME = Symbol('resume');
+const BUFFER = Symbol('buffer');
+const PIPES = Symbol('pipes');
+const BUFFERLENGTH = Symbol('bufferLength');
+const BUFFERPUSH = Symbol('bufferPush');
+const BUFFERSHIFT = Symbol('bufferShift');
+const OBJECTMODE = Symbol('objectMode');
+// internal event when stream is destroyed
+const DESTROYED = Symbol('destroyed');
+// internal event when stream has an error
+const ERROR = Symbol('error');
+const EMITDATA = Symbol('emitData');
+const EMITEND = Symbol('emitEnd');
+const EMITEND2 = Symbol('emitEnd2');
+const ASYNC = Symbol('async');
+const ABORT = Symbol('abort');
+const ABORTED = Symbol('aborted');
+const SIGNAL = Symbol('signal');
+const DATALISTENERS = Symbol('dataListeners');
+const DISCARDED = Symbol('discarded');
+const defer = (fn) => Promise.resolve().then(fn);
+const nodefer = (fn) => fn();
+const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish';
+const isArrayBufferLike = (b) => b instanceof ArrayBuffer ||
+    (!!b &&
+        typeof b === 'object' &&
+        b.constructor &&
+        b.constructor.name === 'ArrayBuffer' &&
+        b.byteLength >= 0);
+const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);
+/**
+ * Internal class representing a pipe to a destination stream.
+ *
+ * @internal
+ */
+class Pipe {
+    src;
+    dest;
+    opts;
+    ondrain;
+    constructor(src, dest, opts) {
+        this.src = src;
+        this.dest = dest;
+        this.opts = opts;
+        this.ondrain = () => src[RESUME]();
+        this.dest.on('drain', this.ondrain);
+    }
+    unpipe() {
+        this.dest.removeListener('drain', this.ondrain);
+    }
+    // only here for the prototype
+    /* c8 ignore start */
+    proxyErrors(_er) { }
+    /* c8 ignore stop */
+    end() {
+        this.unpipe();
+        if (this.opts.end)
+            this.dest.end();
+    }
+}
+/**
+ * Internal class representing a pipe to a destination stream where
+ * errors are proxied.
+ *
+ * @internal
+ */
+class PipeProxyErrors extends Pipe {
+    unpipe() {
+        this.src.removeListener('error', this.proxyErrors);
+        super.unpipe();
+    }
+    constructor(src, dest, opts) {
+        super(src, dest, opts);
+        this.proxyErrors = er => dest.emit('error', er);
+        src.on('error', this.proxyErrors);
+    }
+}
+const isObjectModeOptions = (o) => !!o.objectMode;
+const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer';
+/**
+ * Main export, the Minipass class
+ *
+ * `RType` is the type of data emitted, defaults to Buffer
+ *
+ * `WType` is the type of data to be written, if RType is buffer or string,
+ * then any {@link Minipass.ContiguousData} is allowed.
+ *
+ * `Events` is the set of event handler signatures that this object
+ * will emit, see {@link Minipass.Events}
+ */
+class Minipass extends events_1.EventEmitter {
+    [FLOWING] = false;
+    [PAUSED] = false;
+    [PIPES] = [];
+    [BUFFER] = [];
+    [OBJECTMODE];
+    [ENCODING];
+    [ASYNC];
+    [DECODER];
+    [EOF] = false;
+    [EMITTED_END] = false;
+    [EMITTING_END] = false;
+    [CLOSED] = false;
+    [EMITTED_ERROR] = null;
+    [BUFFERLENGTH] = 0;
+    [DESTROYED] = false;
+    [SIGNAL];
+    [ABORTED] = false;
+    [DATALISTENERS] = 0;
+    [DISCARDED] = false;
+    /**
+     * true if the stream can be written
+     */
+    writable = true;
+    /**
+     * true if the stream can be read
+     */
+    readable = true;
+    /**
+     * If `RType` is Buffer, then options do not need to be provided.
+     * Otherwise, an options object must be provided to specify either
+     * {@link Minipass.SharedOptions.objectMode} or
+     * {@link Minipass.SharedOptions.encoding}, as appropriate.
+     */
+    constructor(...args) {
+        const options = (args[0] ||
+            {});
+        super();
+        if (options.objectMode && typeof options.encoding === 'string') {
+            throw new TypeError('Encoding and objectMode may not be used together');
+        }
+        if (isObjectModeOptions(options)) {
+            this[OBJECTMODE] = true;
+            this[ENCODING] = null;
+        }
+        else if (isEncodingOptions(options)) {
+            this[ENCODING] = options.encoding;
+            this[OBJECTMODE] = false;
+        }
+        else {
+            this[OBJECTMODE] = false;
+            this[ENCODING] = null;
+        }
+        this[ASYNC] = !!options.async;
+        this[DECODER] = this[ENCODING]
+            ? new string_decoder_1.StringDecoder(this[ENCODING])
+            : null;
+        //@ts-ignore - private option for debugging and testing
+        if (options && options.debugExposeBuffer === true) {
+            Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] });
+        }
+        //@ts-ignore - private option for debugging and testing
+        if (options && options.debugExposePipes === true) {
+            Object.defineProperty(this, 'pipes', { get: () => this[PIPES] });
+        }
+        const { signal } = options;
+        if (signal) {
+            this[SIGNAL] = signal;
+            if (signal.aborted) {
+                this[ABORT]();
+            }
+            else {
+                signal.addEventListener('abort', () => this[ABORT]());
+            }
+        }
+    }
+    /**
+     * The amount of data stored in the buffer waiting to be read.
+     *
+     * For Buffer strings, this will be the total byte length.
+     * For string encoding streams, this will be the string character length,
+     * according to JavaScript's `string.length` logic.
+     * For objectMode streams, this is a count of the items waiting to be
+     * emitted.
+     */
+    get bufferLength() {
+        return this[BUFFERLENGTH];
+    }
+    /**
+     * The `BufferEncoding` currently in use, or `null`
+     */
+    get encoding() {
+        return this[ENCODING];
+    }
+    /**
+     * @deprecated - This is a read only property
+     */
+    set encoding(_enc) {
+        throw new Error('Encoding must be set at instantiation time');
+    }
+    /**
+     * @deprecated - Encoding may only be set at instantiation time
+     */
+    setEncoding(_enc) {
+        throw new Error('Encoding must be set at instantiation time');
+    }
+    /**
+     * True if this is an objectMode stream
+     */
+    get objectMode() {
+        return this[OBJECTMODE];
+    }
+    /**
+     * @deprecated - This is a read-only property
+     */
+    set objectMode(_om) {
+        throw new Error('objectMode must be set at instantiation time');
+    }
+    /**
+     * true if this is an async stream
+     */
+    get ['async']() {
+        return this[ASYNC];
+    }
+    /**
+     * Set to true to make this stream async.
+     *
+     * Once set, it cannot be unset, as this would potentially cause incorrect
+     * behavior.  Ie, a sync stream can be made async, but an async stream
+     * cannot be safely made sync.
+     */
+    set ['async'](a) {
+        this[ASYNC] = this[ASYNC] || !!a;
+    }
+    // drop everything and get out of the flow completely
+    [ABORT]() {
+        this[ABORTED] = true;
+        this.emit('abort', this[SIGNAL]?.reason);
+        this.destroy(this[SIGNAL]?.reason);
+    }
+    /**
+     * True if the stream has been aborted.
+     */
+    get aborted() {
+        return this[ABORTED];
+    }
+    /**
+     * No-op setter. Stream aborted status is set via the AbortSignal provided
+     * in the constructor options.
+     */
+    set aborted(_) { }
+    write(chunk, encoding, cb) {
+        if (this[ABORTED])
+            return false;
+        if (this[EOF])
+            throw new Error('write after end');
+        if (this[DESTROYED]) {
+            this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' }));
+            return true;
+        }
+        if (typeof encoding === 'function') {
+            cb = encoding;
+            encoding = 'utf8';
+        }
+        if (!encoding)
+            encoding = 'utf8';
+        const fn = this[ASYNC] ? defer : nodefer;
+        // convert array buffers and typed array views into buffers
+        // at some point in the future, we may want to do the opposite!
+        // leave strings and buffers as-is
+        // anything is only allowed if in object mode, so throw
+        if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
+            if (isArrayBufferView(chunk)) {
+                //@ts-ignore - sinful unsafe type changing
+                chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
+            }
+            else if (isArrayBufferLike(chunk)) {
+                //@ts-ignore - sinful unsafe type changing
+                chunk = Buffer.from(chunk);
+            }
+            else if (typeof chunk !== 'string') {
+                throw new Error('Non-contiguous data written to non-objectMode stream');
+            }
+        }
+        // handle object mode up front, since it's simpler
+        // this yields better performance, fewer checks later.
+        if (this[OBJECTMODE]) {
+            // maybe impossible?
+            /* c8 ignore start */
+            if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
+                this[FLUSH](true);
+            /* c8 ignore stop */
+            if (this[FLOWING])
+                this.emit('data', chunk);
+            else
+                this[BUFFERPUSH](chunk);
+            if (this[BUFFERLENGTH] !== 0)
+                this.emit('readable');
+            if (cb)
+                fn(cb);
+            return this[FLOWING];
+        }
+        // at this point the chunk is a buffer or string
+        // don't buffer it up or send it to the decoder
+        if (!chunk.length) {
+            if (this[BUFFERLENGTH] !== 0)
+                this.emit('readable');
+            if (cb)
+                fn(cb);
+            return this[FLOWING];
+        }
+        // fast-path writing strings of same encoding to a stream with
+        // an empty buffer, skipping the buffer/decoder dance
+        if (typeof chunk === 'string' &&
+            // unless it is a string already ready for us to use
+            !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) {
+            //@ts-ignore - sinful unsafe type change
+            chunk = Buffer.from(chunk, encoding);
+        }
+        if (Buffer.isBuffer(chunk) && this[ENCODING]) {
+            //@ts-ignore - sinful unsafe type change
+            chunk = this[DECODER].write(chunk);
+        }
+        // Note: flushing CAN potentially switch us into not-flowing mode
+        if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
+            this[FLUSH](true);
+        if (this[FLOWING])
+            this.emit('data', chunk);
+        else
+            this[BUFFERPUSH](chunk);
+        if (this[BUFFERLENGTH] !== 0)
+            this.emit('readable');
+        if (cb)
+            fn(cb);
+        return this[FLOWING];
+    }
+    /**
+     * Low-level explicit read method.
+     *
+     * In objectMode, the argument is ignored, and one item is returned if
+     * available.
+     *
+     * `n` is the number of bytes (or in the case of encoding streams,
+     * characters) to consume. If `n` is not provided, then the entire buffer
+     * is returned, or `null` is returned if no data is available.
+     *
+     * If `n` is greater that the amount of data in the internal buffer,
+     * then `null` is returned.
+     */
+    read(n) {
+        if (this[DESTROYED])
+            return null;
+        this[DISCARDED] = false;
+        if (this[BUFFERLENGTH] === 0 ||
+            n === 0 ||
+            (n && n > this[BUFFERLENGTH])) {
+            this[MAYBE_EMIT_END]();
+            return null;
+        }
+        if (this[OBJECTMODE])
+            n = null;
+        if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {
+            // not object mode, so if we have an encoding, then RType is string
+            // otherwise, must be Buffer
+            this[BUFFER] = [
+                (this[ENCODING]
+                    ? this[BUFFER].join('')
+                    : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])),
+            ];
+        }
+        const ret = this[READ](n || null, this[BUFFER][0]);
+        this[MAYBE_EMIT_END]();
+        return ret;
+    }
+    [READ](n, chunk) {
+        if (this[OBJECTMODE])
+            this[BUFFERSHIFT]();
+        else {
+            const c = chunk;
+            if (n === c.length || n === null)
+                this[BUFFERSHIFT]();
+            else if (typeof c === 'string') {
+                this[BUFFER][0] = c.slice(n);
+                chunk = c.slice(0, n);
+                this[BUFFERLENGTH] -= n;
+            }
+            else {
+                this[BUFFER][0] = c.subarray(n);
+                chunk = c.subarray(0, n);
+                this[BUFFERLENGTH] -= n;
+            }
+        }
+        this.emit('data', chunk);
+        if (!this[BUFFER].length && !this[EOF])
+            this.emit('drain');
+        return chunk;
+    }
+    end(chunk, encoding, cb) {
+        if (typeof chunk === 'function') {
+            cb = chunk;
+            chunk = undefined;
+        }
+        if (typeof encoding === 'function') {
+            cb = encoding;
+            encoding = 'utf8';
+        }
+        if (chunk !== undefined)
+            this.write(chunk, encoding);
+        if (cb)
+            this.once('end', cb);
+        this[EOF] = true;
+        this.writable = false;
+        // if we haven't written anything, then go ahead and emit,
+        // even if we're not reading.
+        // we'll re-emit if a new 'end' listener is added anyway.
+        // This makes MP more suitable to write-only use cases.
+        if (this[FLOWING] || !this[PAUSED])
+            this[MAYBE_EMIT_END]();
+        return this;
+    }
+    // don't let the internal resume be overwritten
+    [RESUME]() {
+        if (this[DESTROYED])
+            return;
+        if (!this[DATALISTENERS] && !this[PIPES].length) {
+            this[DISCARDED] = true;
+        }
+        this[PAUSED] = false;
+        this[FLOWING] = true;
+        this.emit('resume');
+        if (this[BUFFER].length)
+            this[FLUSH]();
+        else if (this[EOF])
+            this[MAYBE_EMIT_END]();
+        else
+            this.emit('drain');
+    }
+    /**
+     * Resume the stream if it is currently in a paused state
+     *
+     * If called when there are no pipe destinations or `data` event listeners,
+     * this will place the stream in a "discarded" state, where all data will
+     * be thrown away. The discarded state is removed if a pipe destination or
+     * data handler is added, if pause() is called, or if any synchronous or
+     * asynchronous iteration is started.
+     */
+    resume() {
+        return this[RESUME]();
+    }
+    /**
+     * Pause the stream
+     */
+    pause() {
+        this[FLOWING] = false;
+        this[PAUSED] = true;
+        this[DISCARDED] = false;
+    }
+    /**
+     * true if the stream has been forcibly destroyed
+     */
+    get destroyed() {
+        return this[DESTROYED];
+    }
+    /**
+     * true if the stream is currently in a flowing state, meaning that
+     * any writes will be immediately emitted.
+     */
+    get flowing() {
+        return this[FLOWING];
+    }
+    /**
+     * true if the stream is currently in a paused state
+     */
+    get paused() {
+        return this[PAUSED];
+    }
+    [BUFFERPUSH](chunk) {
+        if (this[OBJECTMODE])
+            this[BUFFERLENGTH] += 1;
+        else
+            this[BUFFERLENGTH] += chunk.length;
+        this[BUFFER].push(chunk);
+    }
+    [BUFFERSHIFT]() {
+        if (this[OBJECTMODE])
+            this[BUFFERLENGTH] -= 1;
+        else
+            this[BUFFERLENGTH] -= this[BUFFER][0].length;
+        return this[BUFFER].shift();
+    }
+    [FLUSH](noDrain = false) {
+        do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) &&
+            this[BUFFER].length);
+        if (!noDrain && !this[BUFFER].length && !this[EOF])
+            this.emit('drain');
+    }
+    [FLUSHCHUNK](chunk) {
+        this.emit('data', chunk);
+        return this[FLOWING];
+    }
+    /**
+     * Pipe all data emitted by this stream into the destination provided.
+     *
+     * Triggers the flow of data.
+     */
+    pipe(dest, opts) {
+        if (this[DESTROYED])
+            return dest;
+        this[DISCARDED] = false;
+        const ended = this[EMITTED_END];
+        opts = opts || {};
+        if (dest === proc.stdout || dest === proc.stderr)
+            opts.end = false;
+        else
+            opts.end = opts.end !== false;
+        opts.proxyErrors = !!opts.proxyErrors;
+        // piping an ended stream ends immediately
+        if (ended) {
+            if (opts.end)
+                dest.end();
+        }
+        else {
+            // "as" here just ignores the WType, which pipes don't care about,
+            // since they're only consuming from us, and writing to the dest
+            this[PIPES].push(!opts.proxyErrors
+                ? new Pipe(this, dest, opts)
+                : new PipeProxyErrors(this, dest, opts));
+            if (this[ASYNC])
+                defer(() => this[RESUME]());
+            else
+                this[RESUME]();
+        }
+        return dest;
+    }
+    /**
+     * Fully unhook a piped destination stream.
+     *
+     * If the destination stream was the only consumer of this stream (ie,
+     * there are no other piped destinations or `'data'` event listeners)
+     * then the flow of data will stop until there is another consumer or
+     * {@link Minipass#resume} is explicitly called.
+     */
+    unpipe(dest) {
+        const p = this[PIPES].find(p => p.dest === dest);
+        if (p) {
+            if (this[PIPES].length === 1) {
+                if (this[FLOWING] && this[DATALISTENERS] === 0) {
+                    this[FLOWING] = false;
+                }
+                this[PIPES] = [];
+            }
+            else
+                this[PIPES].splice(this[PIPES].indexOf(p), 1);
+            p.unpipe();
+        }
+    }
+    /**
+     * Alias for {@link Minipass#on}
+     */
+    addListener(ev, handler) {
+        return this.on(ev, handler);
+    }
+    /**
+     * Mostly identical to `EventEmitter.on`, with the following
+     * behavior differences to prevent data loss and unnecessary hangs:
+     *
+     * - Adding a 'data' event handler will trigger the flow of data
+     *
+     * - Adding a 'readable' event handler when there is data waiting to be read
+     *   will cause 'readable' to be emitted immediately.
+     *
+     * - Adding an 'endish' event handler ('end', 'finish', etc.) which has
+     *   already passed will cause the event to be emitted immediately and all
+     *   handlers removed.
+     *
+     * - Adding an 'error' event handler after an error has been emitted will
+     *   cause the event to be re-emitted immediately with the error previously
+     *   raised.
+     */
+    on(ev, handler) {
+        const ret = super.on(ev, handler);
+        if (ev === 'data') {
+            this[DISCARDED] = false;
+            this[DATALISTENERS]++;
+            if (!this[PIPES].length && !this[FLOWING]) {
+                this[RESUME]();
+            }
+        }
+        else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) {
+            super.emit('readable');
+        }
+        else if (isEndish(ev) && this[EMITTED_END]) {
+            super.emit(ev);
+            this.removeAllListeners(ev);
+        }
+        else if (ev === 'error' && this[EMITTED_ERROR]) {
+            const h = handler;
+            if (this[ASYNC])
+                defer(() => h.call(this, this[EMITTED_ERROR]));
+            else
+                h.call(this, this[EMITTED_ERROR]);
+        }
+        return ret;
+    }
+    /**
+     * Alias for {@link Minipass#off}
+     */
+    removeListener(ev, handler) {
+        return this.off(ev, handler);
+    }
+    /**
+     * Mostly identical to `EventEmitter.off`
+     *
+     * If a 'data' event handler is removed, and it was the last consumer
+     * (ie, there are no pipe destinations or other 'data' event listeners),
+     * then the flow of data will stop until there is another consumer or
+     * {@link Minipass#resume} is explicitly called.
+     */
+    off(ev, handler) {
+        const ret = super.off(ev, handler);
+        // if we previously had listeners, and now we don't, and we don't
+        // have any pipes, then stop the flow, unless it's been explicitly
+        // put in a discarded flowing state via stream.resume().
+        if (ev === 'data') {
+            this[DATALISTENERS] = this.listeners('data').length;
+            if (this[DATALISTENERS] === 0 &&
+                !this[DISCARDED] &&
+                !this[PIPES].length) {
+                this[FLOWING] = false;
+            }
+        }
+        return ret;
+    }
+    /**
+     * Mostly identical to `EventEmitter.removeAllListeners`
+     *
+     * If all 'data' event handlers are removed, and they were the last consumer
+     * (ie, there are no pipe destinations), then the flow of data will stop
+     * until there is another consumer or {@link Minipass#resume} is explicitly
+     * called.
+     */
+    removeAllListeners(ev) {
+        const ret = super.removeAllListeners(ev);
+        if (ev === 'data' || ev === undefined) {
+            this[DATALISTENERS] = 0;
+            if (!this[DISCARDED] && !this[PIPES].length) {
+                this[FLOWING] = false;
+            }
+        }
+        return ret;
+    }
+    /**
+     * true if the 'end' event has been emitted
+     */
+    get emittedEnd() {
+        return this[EMITTED_END];
+    }
+    [MAYBE_EMIT_END]() {
+        if (!this[EMITTING_END] &&
+            !this[EMITTED_END] &&
+            !this[DESTROYED] &&
+            this[BUFFER].length === 0 &&
+            this[EOF]) {
+            this[EMITTING_END] = true;
+            this.emit('end');
+            this.emit('prefinish');
+            this.emit('finish');
+            if (this[CLOSED])
+                this.emit('close');
+            this[EMITTING_END] = false;
+        }
+    }
+    /**
+     * Mostly identical to `EventEmitter.emit`, with the following
+     * behavior differences to prevent data loss and unnecessary hangs:
+     *
+     * If the stream has been destroyed, and the event is something other
+     * than 'close' or 'error', then `false` is returned and no handlers
+     * are called.
+     *
+     * If the event is 'end', and has already been emitted, then the event
+     * is ignored. If the stream is in a paused or non-flowing state, then
+     * the event will be deferred until data flow resumes. If the stream is
+     * async, then handlers will be called on the next tick rather than
+     * immediately.
+     *
+     * If the event is 'close', and 'end' has not yet been emitted, then
+     * the event will be deferred until after 'end' is emitted.
+     *
+     * If the event is 'error', and an AbortSignal was provided for the stream,
+     * and there are no listeners, then the event is ignored, matching the
+     * behavior of node core streams in the presense of an AbortSignal.
+     *
+     * If the event is 'finish' or 'prefinish', then all listeners will be
+     * removed after emitting the event, to prevent double-firing.
+     */
+    emit(ev, ...args) {
+        const data = args[0];
+        // error and close are only events allowed after calling destroy()
+        if (ev !== 'error' &&
+            ev !== 'close' &&
+            ev !== DESTROYED &&
+            this[DESTROYED]) {
+            return false;
+        }
+        else if (ev === 'data') {
+            return !this[OBJECTMODE] && !data
+                ? false
+                : this[ASYNC]
+                    ? (defer(() => this[EMITDATA](data)), true)
+                    : this[EMITDATA](data);
+        }
+        else if (ev === 'end') {
+            return this[EMITEND]();
+        }
+        else if (ev === 'close') {
+            this[CLOSED] = true;
+            // don't emit close before 'end' and 'finish'
+            if (!this[EMITTED_END] && !this[DESTROYED])
+                return false;
+            const ret = super.emit('close');
+            this.removeAllListeners('close');
+            return ret;
+        }
+        else if (ev === 'error') {
+            this[EMITTED_ERROR] = data;
+            super.emit(ERROR, data);
+            const ret = !this[SIGNAL] || this.listeners('error').length
+                ? super.emit('error', data)
+                : false;
+            this[MAYBE_EMIT_END]();
+            return ret;
+        }
+        else if (ev === 'resume') {
+            const ret = super.emit('resume');
+            this[MAYBE_EMIT_END]();
+            return ret;
+        }
+        else if (ev === 'finish' || ev === 'prefinish') {
+            const ret = super.emit(ev);
+            this.removeAllListeners(ev);
+            return ret;
+        }
+        // Some other unknown event
+        const ret = super.emit(ev, ...args);
+        this[MAYBE_EMIT_END]();
+        return ret;
+    }
+    [EMITDATA](data) {
+        for (const p of this[PIPES]) {
+            if (p.dest.write(data) === false)
+                this.pause();
+        }
+        const ret = this[DISCARDED] ? false : super.emit('data', data);
+        this[MAYBE_EMIT_END]();
+        return ret;
+    }
+    [EMITEND]() {
+        if (this[EMITTED_END])
+            return false;
+        this[EMITTED_END] = true;
+        this.readable = false;
+        return this[ASYNC]
+            ? (defer(() => this[EMITEND2]()), true)
+            : this[EMITEND2]();
+    }
+    [EMITEND2]() {
+        if (this[DECODER]) {
+            const data = this[DECODER].end();
+            if (data) {
+                for (const p of this[PIPES]) {
+                    p.dest.write(data);
+                }
+                if (!this[DISCARDED])
+                    super.emit('data', data);
+            }
+        }
+        for (const p of this[PIPES]) {
+            p.end();
+        }
+        const ret = super.emit('end');
+        this.removeAllListeners('end');
+        return ret;
+    }
+    /**
+     * Return a Promise that resolves to an array of all emitted data once
+     * the stream ends.
+     */
+    async collect() {
+        const buf = Object.assign([], {
+            dataLength: 0,
+        });
+        if (!this[OBJECTMODE])
+            buf.dataLength = 0;
+        // set the promise first, in case an error is raised
+        // by triggering the flow here.
+        const p = this.promise();
+        this.on('data', c => {
+            buf.push(c);
+            if (!this[OBJECTMODE])
+                buf.dataLength += c.length;
+        });
+        await p;
+        return buf;
+    }
+    /**
+     * Return a Promise that resolves to the concatenation of all emitted data
+     * once the stream ends.
+     *
+     * Not allowed on objectMode streams.
+     */
+    async concat() {
+        if (this[OBJECTMODE]) {
+            throw new Error('cannot concat in objectMode');
+        }
+        const buf = await this.collect();
+        return (this[ENCODING]
+            ? buf.join('')
+            : Buffer.concat(buf, buf.dataLength));
+    }
+    /**
+     * Return a void Promise that resolves once the stream ends.
+     */
+    async promise() {
+        return new Promise((resolve, reject) => {
+            this.on(DESTROYED, () => reject(new Error('stream destroyed')));
+            this.on('error', er => reject(er));
+            this.on('end', () => resolve());
+        });
+    }
+    /**
+     * Asynchronous `for await of` iteration.
+     *
+     * This will continue emitting all chunks until the stream terminates.
+     */
+    [Symbol.asyncIterator]() {
+        // set this up front, in case the consumer doesn't call next()
+        // right away.
+        this[DISCARDED] = false;
+        let stopped = false;
+        const stop = async () => {
+            this.pause();
+            stopped = true;
+            return { value: undefined, done: true };
+        };
+        const next = () => {
+            if (stopped)
+                return stop();
+            const res = this.read();
+            if (res !== null)
+                return Promise.resolve({ done: false, value: res });
+            if (this[EOF])
+                return stop();
+            let resolve;
+            let reject;
+            const onerr = (er) => {
+                this.off('data', ondata);
+                this.off('end', onend);
+                this.off(DESTROYED, ondestroy);
+                stop();
+                reject(er);
+            };
+            const ondata = (value) => {
+                this.off('error', onerr);
+                this.off('end', onend);
+                this.off(DESTROYED, ondestroy);
+                this.pause();
+                resolve({ value, done: !!this[EOF] });
+            };
+            const onend = () => {
+                this.off('error', onerr);
+                this.off('data', ondata);
+                this.off(DESTROYED, ondestroy);
+                stop();
+                resolve({ done: true, value: undefined });
+            };
+            const ondestroy = () => onerr(new Error('stream destroyed'));
+            return new Promise((res, rej) => {
+                reject = rej;
+                resolve = res;
+                this.once(DESTROYED, ondestroy);
+                this.once('error', onerr);
+                this.once('end', onend);
+                this.once('data', ondata);
+            });
+        };
+        return {
+            next,
+            throw: stop,
+            return: stop,
+            [Symbol.asyncIterator]() {
+                return this;
+            },
+        };
+    }
+    /**
+     * Synchronous `for of` iteration.
+     *
+     * The iteration will terminate when the internal buffer runs out, even
+     * if the stream has not yet terminated.
+     */
+    [Symbol.iterator]() {
+        // set this up front, in case the consumer doesn't call next()
+        // right away.
+        this[DISCARDED] = false;
+        let stopped = false;
+        const stop = () => {
+            this.pause();
+            this.off(ERROR, stop);
+            this.off(DESTROYED, stop);
+            this.off('end', stop);
+            stopped = true;
+            return { done: true, value: undefined };
+        };
+        const next = () => {
+            if (stopped)
+                return stop();
+            const value = this.read();
+            return value === null ? stop() : { done: false, value };
+        };
+        this.once('end', stop);
+        this.once(ERROR, stop);
+        this.once(DESTROYED, stop);
+        return {
+            next,
+            throw: stop,
+            return: stop,
+            [Symbol.iterator]() {
+                return this;
+            },
+        };
+    }
+    /**
+     * Destroy a stream, preventing it from being used for any further purpose.
+     *
+     * If the stream has a `close()` method, then it will be called on
+     * destruction.
+     *
+     * After destruction, any attempt to write data, read data, or emit most
+     * events will be ignored.
+     *
+     * If an error argument is provided, then it will be emitted in an
+     * 'error' event.
+     */
+    destroy(er) {
+        if (this[DESTROYED]) {
+            if (er)
+                this.emit('error', er);
+            else
+                this.emit(DESTROYED);
+            return this;
+        }
+        this[DESTROYED] = true;
+        this[DISCARDED] = true;
+        // throw away all buffered data, it's never coming out
+        this[BUFFER].length = 0;
+        this[BUFFERLENGTH] = 0;
+        const wc = this;
+        if (typeof wc.close === 'function' && !this[CLOSED])
+            wc.close();
+        if (er)
+            this.emit('error', er);
+        // if no error to emit, still reject pending promises
+        else
+            this.emit(DESTROYED);
+        return this;
+    }
+    /**
+     * Alias for {@link isStream}
+     *
+     * Former export location, maintained for backwards compatibility.
+     *
+     * @deprecated
+     */
+    static get isStream() {
+        return exports.isStream;
+    }
+}
+exports.Minipass = Minipass;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/cjs/package.json b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/cjs/package.json
new file mode 100644
index 00000000000000..5bbefffbabee39
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/cjs/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "commonjs"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/mjs/index.js b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/mjs/index.js
new file mode 100644
index 00000000000000..b65fafbae43a4e
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/mjs/index.js
@@ -0,0 +1,1018 @@
+const proc = typeof process === 'object' && process
+    ? process
+    : {
+        stdout: null,
+        stderr: null,
+    };
+import { EventEmitter } from 'events';
+import Stream from 'stream';
+import { StringDecoder } from 'string_decoder';
+/**
+ * Return true if the argument is a Minipass stream, Node stream, or something
+ * else that Minipass can interact with.
+ */
+export const isStream = (s) => !!s &&
+    typeof s === 'object' &&
+    (s instanceof Minipass ||
+        s instanceof Stream ||
+        isReadable(s) ||
+        isWritable(s));
+/**
+ * Return true if the argument is a valid {@link Minipass.Readable}
+ */
+export const isReadable = (s) => !!s &&
+    typeof s === 'object' &&
+    s instanceof EventEmitter &&
+    typeof s.pipe === 'function' &&
+    // node core Writable streams have a pipe() method, but it throws
+    s.pipe !== Stream.Writable.prototype.pipe;
+/**
+ * Return true if the argument is a valid {@link Minipass.Writable}
+ */
+export const isWritable = (s) => !!s &&
+    typeof s === 'object' &&
+    s instanceof EventEmitter &&
+    typeof s.write === 'function' &&
+    typeof s.end === 'function';
+const EOF = Symbol('EOF');
+const MAYBE_EMIT_END = Symbol('maybeEmitEnd');
+const EMITTED_END = Symbol('emittedEnd');
+const EMITTING_END = Symbol('emittingEnd');
+const EMITTED_ERROR = Symbol('emittedError');
+const CLOSED = Symbol('closed');
+const READ = Symbol('read');
+const FLUSH = Symbol('flush');
+const FLUSHCHUNK = Symbol('flushChunk');
+const ENCODING = Symbol('encoding');
+const DECODER = Symbol('decoder');
+const FLOWING = Symbol('flowing');
+const PAUSED = Symbol('paused');
+const RESUME = Symbol('resume');
+const BUFFER = Symbol('buffer');
+const PIPES = Symbol('pipes');
+const BUFFERLENGTH = Symbol('bufferLength');
+const BUFFERPUSH = Symbol('bufferPush');
+const BUFFERSHIFT = Symbol('bufferShift');
+const OBJECTMODE = Symbol('objectMode');
+// internal event when stream is destroyed
+const DESTROYED = Symbol('destroyed');
+// internal event when stream has an error
+const ERROR = Symbol('error');
+const EMITDATA = Symbol('emitData');
+const EMITEND = Symbol('emitEnd');
+const EMITEND2 = Symbol('emitEnd2');
+const ASYNC = Symbol('async');
+const ABORT = Symbol('abort');
+const ABORTED = Symbol('aborted');
+const SIGNAL = Symbol('signal');
+const DATALISTENERS = Symbol('dataListeners');
+const DISCARDED = Symbol('discarded');
+const defer = (fn) => Promise.resolve().then(fn);
+const nodefer = (fn) => fn();
+const isEndish = (ev) => ev === 'end' || ev === 'finish' || ev === 'prefinish';
+const isArrayBufferLike = (b) => b instanceof ArrayBuffer ||
+    (!!b &&
+        typeof b === 'object' &&
+        b.constructor &&
+        b.constructor.name === 'ArrayBuffer' &&
+        b.byteLength >= 0);
+const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);
+/**
+ * Internal class representing a pipe to a destination stream.
+ *
+ * @internal
+ */
+class Pipe {
+    src;
+    dest;
+    opts;
+    ondrain;
+    constructor(src, dest, opts) {
+        this.src = src;
+        this.dest = dest;
+        this.opts = opts;
+        this.ondrain = () => src[RESUME]();
+        this.dest.on('drain', this.ondrain);
+    }
+    unpipe() {
+        this.dest.removeListener('drain', this.ondrain);
+    }
+    // only here for the prototype
+    /* c8 ignore start */
+    proxyErrors(_er) { }
+    /* c8 ignore stop */
+    end() {
+        this.unpipe();
+        if (this.opts.end)
+            this.dest.end();
+    }
+}
+/**
+ * Internal class representing a pipe to a destination stream where
+ * errors are proxied.
+ *
+ * @internal
+ */
+class PipeProxyErrors extends Pipe {
+    unpipe() {
+        this.src.removeListener('error', this.proxyErrors);
+        super.unpipe();
+    }
+    constructor(src, dest, opts) {
+        super(src, dest, opts);
+        this.proxyErrors = er => dest.emit('error', er);
+        src.on('error', this.proxyErrors);
+    }
+}
+const isObjectModeOptions = (o) => !!o.objectMode;
+const isEncodingOptions = (o) => !o.objectMode && !!o.encoding && o.encoding !== 'buffer';
+/**
+ * Main export, the Minipass class
+ *
+ * `RType` is the type of data emitted, defaults to Buffer
+ *
+ * `WType` is the type of data to be written, if RType is buffer or string,
+ * then any {@link Minipass.ContiguousData} is allowed.
+ *
+ * `Events` is the set of event handler signatures that this object
+ * will emit, see {@link Minipass.Events}
+ */
+export class Minipass extends EventEmitter {
+    [FLOWING] = false;
+    [PAUSED] = false;
+    [PIPES] = [];
+    [BUFFER] = [];
+    [OBJECTMODE];
+    [ENCODING];
+    [ASYNC];
+    [DECODER];
+    [EOF] = false;
+    [EMITTED_END] = false;
+    [EMITTING_END] = false;
+    [CLOSED] = false;
+    [EMITTED_ERROR] = null;
+    [BUFFERLENGTH] = 0;
+    [DESTROYED] = false;
+    [SIGNAL];
+    [ABORTED] = false;
+    [DATALISTENERS] = 0;
+    [DISCARDED] = false;
+    /**
+     * true if the stream can be written
+     */
+    writable = true;
+    /**
+     * true if the stream can be read
+     */
+    readable = true;
+    /**
+     * If `RType` is Buffer, then options do not need to be provided.
+     * Otherwise, an options object must be provided to specify either
+     * {@link Minipass.SharedOptions.objectMode} or
+     * {@link Minipass.SharedOptions.encoding}, as appropriate.
+     */
+    constructor(...args) {
+        const options = (args[0] ||
+            {});
+        super();
+        if (options.objectMode && typeof options.encoding === 'string') {
+            throw new TypeError('Encoding and objectMode may not be used together');
+        }
+        if (isObjectModeOptions(options)) {
+            this[OBJECTMODE] = true;
+            this[ENCODING] = null;
+        }
+        else if (isEncodingOptions(options)) {
+            this[ENCODING] = options.encoding;
+            this[OBJECTMODE] = false;
+        }
+        else {
+            this[OBJECTMODE] = false;
+            this[ENCODING] = null;
+        }
+        this[ASYNC] = !!options.async;
+        this[DECODER] = this[ENCODING]
+            ? new StringDecoder(this[ENCODING])
+            : null;
+        //@ts-ignore - private option for debugging and testing
+        if (options && options.debugExposeBuffer === true) {
+            Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] });
+        }
+        //@ts-ignore - private option for debugging and testing
+        if (options && options.debugExposePipes === true) {
+            Object.defineProperty(this, 'pipes', { get: () => this[PIPES] });
+        }
+        const { signal } = options;
+        if (signal) {
+            this[SIGNAL] = signal;
+            if (signal.aborted) {
+                this[ABORT]();
+            }
+            else {
+                signal.addEventListener('abort', () => this[ABORT]());
+            }
+        }
+    }
+    /**
+     * The amount of data stored in the buffer waiting to be read.
+     *
+     * For Buffer strings, this will be the total byte length.
+     * For string encoding streams, this will be the string character length,
+     * according to JavaScript's `string.length` logic.
+     * For objectMode streams, this is a count of the items waiting to be
+     * emitted.
+     */
+    get bufferLength() {
+        return this[BUFFERLENGTH];
+    }
+    /**
+     * The `BufferEncoding` currently in use, or `null`
+     */
+    get encoding() {
+        return this[ENCODING];
+    }
+    /**
+     * @deprecated - This is a read only property
+     */
+    set encoding(_enc) {
+        throw new Error('Encoding must be set at instantiation time');
+    }
+    /**
+     * @deprecated - Encoding may only be set at instantiation time
+     */
+    setEncoding(_enc) {
+        throw new Error('Encoding must be set at instantiation time');
+    }
+    /**
+     * True if this is an objectMode stream
+     */
+    get objectMode() {
+        return this[OBJECTMODE];
+    }
+    /**
+     * @deprecated - This is a read-only property
+     */
+    set objectMode(_om) {
+        throw new Error('objectMode must be set at instantiation time');
+    }
+    /**
+     * true if this is an async stream
+     */
+    get ['async']() {
+        return this[ASYNC];
+    }
+    /**
+     * Set to true to make this stream async.
+     *
+     * Once set, it cannot be unset, as this would potentially cause incorrect
+     * behavior.  Ie, a sync stream can be made async, but an async stream
+     * cannot be safely made sync.
+     */
+    set ['async'](a) {
+        this[ASYNC] = this[ASYNC] || !!a;
+    }
+    // drop everything and get out of the flow completely
+    [ABORT]() {
+        this[ABORTED] = true;
+        this.emit('abort', this[SIGNAL]?.reason);
+        this.destroy(this[SIGNAL]?.reason);
+    }
+    /**
+     * True if the stream has been aborted.
+     */
+    get aborted() {
+        return this[ABORTED];
+    }
+    /**
+     * No-op setter. Stream aborted status is set via the AbortSignal provided
+     * in the constructor options.
+     */
+    set aborted(_) { }
+    write(chunk, encoding, cb) {
+        if (this[ABORTED])
+            return false;
+        if (this[EOF])
+            throw new Error('write after end');
+        if (this[DESTROYED]) {
+            this.emit('error', Object.assign(new Error('Cannot call write after a stream was destroyed'), { code: 'ERR_STREAM_DESTROYED' }));
+            return true;
+        }
+        if (typeof encoding === 'function') {
+            cb = encoding;
+            encoding = 'utf8';
+        }
+        if (!encoding)
+            encoding = 'utf8';
+        const fn = this[ASYNC] ? defer : nodefer;
+        // convert array buffers and typed array views into buffers
+        // at some point in the future, we may want to do the opposite!
+        // leave strings and buffers as-is
+        // anything is only allowed if in object mode, so throw
+        if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
+            if (isArrayBufferView(chunk)) {
+                //@ts-ignore - sinful unsafe type changing
+                chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
+            }
+            else if (isArrayBufferLike(chunk)) {
+                //@ts-ignore - sinful unsafe type changing
+                chunk = Buffer.from(chunk);
+            }
+            else if (typeof chunk !== 'string') {
+                throw new Error('Non-contiguous data written to non-objectMode stream');
+            }
+        }
+        // handle object mode up front, since it's simpler
+        // this yields better performance, fewer checks later.
+        if (this[OBJECTMODE]) {
+            // maybe impossible?
+            /* c8 ignore start */
+            if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
+                this[FLUSH](true);
+            /* c8 ignore stop */
+            if (this[FLOWING])
+                this.emit('data', chunk);
+            else
+                this[BUFFERPUSH](chunk);
+            if (this[BUFFERLENGTH] !== 0)
+                this.emit('readable');
+            if (cb)
+                fn(cb);
+            return this[FLOWING];
+        }
+        // at this point the chunk is a buffer or string
+        // don't buffer it up or send it to the decoder
+        if (!chunk.length) {
+            if (this[BUFFERLENGTH] !== 0)
+                this.emit('readable');
+            if (cb)
+                fn(cb);
+            return this[FLOWING];
+        }
+        // fast-path writing strings of same encoding to a stream with
+        // an empty buffer, skipping the buffer/decoder dance
+        if (typeof chunk === 'string' &&
+            // unless it is a string already ready for us to use
+            !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) {
+            //@ts-ignore - sinful unsafe type change
+            chunk = Buffer.from(chunk, encoding);
+        }
+        if (Buffer.isBuffer(chunk) && this[ENCODING]) {
+            //@ts-ignore - sinful unsafe type change
+            chunk = this[DECODER].write(chunk);
+        }
+        // Note: flushing CAN potentially switch us into not-flowing mode
+        if (this[FLOWING] && this[BUFFERLENGTH] !== 0)
+            this[FLUSH](true);
+        if (this[FLOWING])
+            this.emit('data', chunk);
+        else
+            this[BUFFERPUSH](chunk);
+        if (this[BUFFERLENGTH] !== 0)
+            this.emit('readable');
+        if (cb)
+            fn(cb);
+        return this[FLOWING];
+    }
+    /**
+     * Low-level explicit read method.
+     *
+     * In objectMode, the argument is ignored, and one item is returned if
+     * available.
+     *
+     * `n` is the number of bytes (or in the case of encoding streams,
+     * characters) to consume. If `n` is not provided, then the entire buffer
+     * is returned, or `null` is returned if no data is available.
+     *
+     * If `n` is greater that the amount of data in the internal buffer,
+     * then `null` is returned.
+     */
+    read(n) {
+        if (this[DESTROYED])
+            return null;
+        this[DISCARDED] = false;
+        if (this[BUFFERLENGTH] === 0 ||
+            n === 0 ||
+            (n && n > this[BUFFERLENGTH])) {
+            this[MAYBE_EMIT_END]();
+            return null;
+        }
+        if (this[OBJECTMODE])
+            n = null;
+        if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {
+            // not object mode, so if we have an encoding, then RType is string
+            // otherwise, must be Buffer
+            this[BUFFER] = [
+                (this[ENCODING]
+                    ? this[BUFFER].join('')
+                    : Buffer.concat(this[BUFFER], this[BUFFERLENGTH])),
+            ];
+        }
+        const ret = this[READ](n || null, this[BUFFER][0]);
+        this[MAYBE_EMIT_END]();
+        return ret;
+    }
+    [READ](n, chunk) {
+        if (this[OBJECTMODE])
+            this[BUFFERSHIFT]();
+        else {
+            const c = chunk;
+            if (n === c.length || n === null)
+                this[BUFFERSHIFT]();
+            else if (typeof c === 'string') {
+                this[BUFFER][0] = c.slice(n);
+                chunk = c.slice(0, n);
+                this[BUFFERLENGTH] -= n;
+            }
+            else {
+                this[BUFFER][0] = c.subarray(n);
+                chunk = c.subarray(0, n);
+                this[BUFFERLENGTH] -= n;
+            }
+        }
+        this.emit('data', chunk);
+        if (!this[BUFFER].length && !this[EOF])
+            this.emit('drain');
+        return chunk;
+    }
+    end(chunk, encoding, cb) {
+        if (typeof chunk === 'function') {
+            cb = chunk;
+            chunk = undefined;
+        }
+        if (typeof encoding === 'function') {
+            cb = encoding;
+            encoding = 'utf8';
+        }
+        if (chunk !== undefined)
+            this.write(chunk, encoding);
+        if (cb)
+            this.once('end', cb);
+        this[EOF] = true;
+        this.writable = false;
+        // if we haven't written anything, then go ahead and emit,
+        // even if we're not reading.
+        // we'll re-emit if a new 'end' listener is added anyway.
+        // This makes MP more suitable to write-only use cases.
+        if (this[FLOWING] || !this[PAUSED])
+            this[MAYBE_EMIT_END]();
+        return this;
+    }
+    // don't let the internal resume be overwritten
+    [RESUME]() {
+        if (this[DESTROYED])
+            return;
+        if (!this[DATALISTENERS] && !this[PIPES].length) {
+            this[DISCARDED] = true;
+        }
+        this[PAUSED] = false;
+        this[FLOWING] = true;
+        this.emit('resume');
+        if (this[BUFFER].length)
+            this[FLUSH]();
+        else if (this[EOF])
+            this[MAYBE_EMIT_END]();
+        else
+            this.emit('drain');
+    }
+    /**
+     * Resume the stream if it is currently in a paused state
+     *
+     * If called when there are no pipe destinations or `data` event listeners,
+     * this will place the stream in a "discarded" state, where all data will
+     * be thrown away. The discarded state is removed if a pipe destination or
+     * data handler is added, if pause() is called, or if any synchronous or
+     * asynchronous iteration is started.
+     */
+    resume() {
+        return this[RESUME]();
+    }
+    /**
+     * Pause the stream
+     */
+    pause() {
+        this[FLOWING] = false;
+        this[PAUSED] = true;
+        this[DISCARDED] = false;
+    }
+    /**
+     * true if the stream has been forcibly destroyed
+     */
+    get destroyed() {
+        return this[DESTROYED];
+    }
+    /**
+     * true if the stream is currently in a flowing state, meaning that
+     * any writes will be immediately emitted.
+     */
+    get flowing() {
+        return this[FLOWING];
+    }
+    /**
+     * true if the stream is currently in a paused state
+     */
+    get paused() {
+        return this[PAUSED];
+    }
+    [BUFFERPUSH](chunk) {
+        if (this[OBJECTMODE])
+            this[BUFFERLENGTH] += 1;
+        else
+            this[BUFFERLENGTH] += chunk.length;
+        this[BUFFER].push(chunk);
+    }
+    [BUFFERSHIFT]() {
+        if (this[OBJECTMODE])
+            this[BUFFERLENGTH] -= 1;
+        else
+            this[BUFFERLENGTH] -= this[BUFFER][0].length;
+        return this[BUFFER].shift();
+    }
+    [FLUSH](noDrain = false) {
+        do { } while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) &&
+            this[BUFFER].length);
+        if (!noDrain && !this[BUFFER].length && !this[EOF])
+            this.emit('drain');
+    }
+    [FLUSHCHUNK](chunk) {
+        this.emit('data', chunk);
+        return this[FLOWING];
+    }
+    /**
+     * Pipe all data emitted by this stream into the destination provided.
+     *
+     * Triggers the flow of data.
+     */
+    pipe(dest, opts) {
+        if (this[DESTROYED])
+            return dest;
+        this[DISCARDED] = false;
+        const ended = this[EMITTED_END];
+        opts = opts || {};
+        if (dest === proc.stdout || dest === proc.stderr)
+            opts.end = false;
+        else
+            opts.end = opts.end !== false;
+        opts.proxyErrors = !!opts.proxyErrors;
+        // piping an ended stream ends immediately
+        if (ended) {
+            if (opts.end)
+                dest.end();
+        }
+        else {
+            // "as" here just ignores the WType, which pipes don't care about,
+            // since they're only consuming from us, and writing to the dest
+            this[PIPES].push(!opts.proxyErrors
+                ? new Pipe(this, dest, opts)
+                : new PipeProxyErrors(this, dest, opts));
+            if (this[ASYNC])
+                defer(() => this[RESUME]());
+            else
+                this[RESUME]();
+        }
+        return dest;
+    }
+    /**
+     * Fully unhook a piped destination stream.
+     *
+     * If the destination stream was the only consumer of this stream (ie,
+     * there are no other piped destinations or `'data'` event listeners)
+     * then the flow of data will stop until there is another consumer or
+     * {@link Minipass#resume} is explicitly called.
+     */
+    unpipe(dest) {
+        const p = this[PIPES].find(p => p.dest === dest);
+        if (p) {
+            if (this[PIPES].length === 1) {
+                if (this[FLOWING] && this[DATALISTENERS] === 0) {
+                    this[FLOWING] = false;
+                }
+                this[PIPES] = [];
+            }
+            else
+                this[PIPES].splice(this[PIPES].indexOf(p), 1);
+            p.unpipe();
+        }
+    }
+    /**
+     * Alias for {@link Minipass#on}
+     */
+    addListener(ev, handler) {
+        return this.on(ev, handler);
+    }
+    /**
+     * Mostly identical to `EventEmitter.on`, with the following
+     * behavior differences to prevent data loss and unnecessary hangs:
+     *
+     * - Adding a 'data' event handler will trigger the flow of data
+     *
+     * - Adding a 'readable' event handler when there is data waiting to be read
+     *   will cause 'readable' to be emitted immediately.
+     *
+     * - Adding an 'endish' event handler ('end', 'finish', etc.) which has
+     *   already passed will cause the event to be emitted immediately and all
+     *   handlers removed.
+     *
+     * - Adding an 'error' event handler after an error has been emitted will
+     *   cause the event to be re-emitted immediately with the error previously
+     *   raised.
+     */
+    on(ev, handler) {
+        const ret = super.on(ev, handler);
+        if (ev === 'data') {
+            this[DISCARDED] = false;
+            this[DATALISTENERS]++;
+            if (!this[PIPES].length && !this[FLOWING]) {
+                this[RESUME]();
+            }
+        }
+        else if (ev === 'readable' && this[BUFFERLENGTH] !== 0) {
+            super.emit('readable');
+        }
+        else if (isEndish(ev) && this[EMITTED_END]) {
+            super.emit(ev);
+            this.removeAllListeners(ev);
+        }
+        else if (ev === 'error' && this[EMITTED_ERROR]) {
+            const h = handler;
+            if (this[ASYNC])
+                defer(() => h.call(this, this[EMITTED_ERROR]));
+            else
+                h.call(this, this[EMITTED_ERROR]);
+        }
+        return ret;
+    }
+    /**
+     * Alias for {@link Minipass#off}
+     */
+    removeListener(ev, handler) {
+        return this.off(ev, handler);
+    }
+    /**
+     * Mostly identical to `EventEmitter.off`
+     *
+     * If a 'data' event handler is removed, and it was the last consumer
+     * (ie, there are no pipe destinations or other 'data' event listeners),
+     * then the flow of data will stop until there is another consumer or
+     * {@link Minipass#resume} is explicitly called.
+     */
+    off(ev, handler) {
+        const ret = super.off(ev, handler);
+        // if we previously had listeners, and now we don't, and we don't
+        // have any pipes, then stop the flow, unless it's been explicitly
+        // put in a discarded flowing state via stream.resume().
+        if (ev === 'data') {
+            this[DATALISTENERS] = this.listeners('data').length;
+            if (this[DATALISTENERS] === 0 &&
+                !this[DISCARDED] &&
+                !this[PIPES].length) {
+                this[FLOWING] = false;
+            }
+        }
+        return ret;
+    }
+    /**
+     * Mostly identical to `EventEmitter.removeAllListeners`
+     *
+     * If all 'data' event handlers are removed, and they were the last consumer
+     * (ie, there are no pipe destinations), then the flow of data will stop
+     * until there is another consumer or {@link Minipass#resume} is explicitly
+     * called.
+     */
+    removeAllListeners(ev) {
+        const ret = super.removeAllListeners(ev);
+        if (ev === 'data' || ev === undefined) {
+            this[DATALISTENERS] = 0;
+            if (!this[DISCARDED] && !this[PIPES].length) {
+                this[FLOWING] = false;
+            }
+        }
+        return ret;
+    }
+    /**
+     * true if the 'end' event has been emitted
+     */
+    get emittedEnd() {
+        return this[EMITTED_END];
+    }
+    [MAYBE_EMIT_END]() {
+        if (!this[EMITTING_END] &&
+            !this[EMITTED_END] &&
+            !this[DESTROYED] &&
+            this[BUFFER].length === 0 &&
+            this[EOF]) {
+            this[EMITTING_END] = true;
+            this.emit('end');
+            this.emit('prefinish');
+            this.emit('finish');
+            if (this[CLOSED])
+                this.emit('close');
+            this[EMITTING_END] = false;
+        }
+    }
+    /**
+     * Mostly identical to `EventEmitter.emit`, with the following
+     * behavior differences to prevent data loss and unnecessary hangs:
+     *
+     * If the stream has been destroyed, and the event is something other
+     * than 'close' or 'error', then `false` is returned and no handlers
+     * are called.
+     *
+     * If the event is 'end', and has already been emitted, then the event
+     * is ignored. If the stream is in a paused or non-flowing state, then
+     * the event will be deferred until data flow resumes. If the stream is
+     * async, then handlers will be called on the next tick rather than
+     * immediately.
+     *
+     * If the event is 'close', and 'end' has not yet been emitted, then
+     * the event will be deferred until after 'end' is emitted.
+     *
+     * If the event is 'error', and an AbortSignal was provided for the stream,
+     * and there are no listeners, then the event is ignored, matching the
+     * behavior of node core streams in the presense of an AbortSignal.
+     *
+     * If the event is 'finish' or 'prefinish', then all listeners will be
+     * removed after emitting the event, to prevent double-firing.
+     */
+    emit(ev, ...args) {
+        const data = args[0];
+        // error and close are only events allowed after calling destroy()
+        if (ev !== 'error' &&
+            ev !== 'close' &&
+            ev !== DESTROYED &&
+            this[DESTROYED]) {
+            return false;
+        }
+        else if (ev === 'data') {
+            return !this[OBJECTMODE] && !data
+                ? false
+                : this[ASYNC]
+                    ? (defer(() => this[EMITDATA](data)), true)
+                    : this[EMITDATA](data);
+        }
+        else if (ev === 'end') {
+            return this[EMITEND]();
+        }
+        else if (ev === 'close') {
+            this[CLOSED] = true;
+            // don't emit close before 'end' and 'finish'
+            if (!this[EMITTED_END] && !this[DESTROYED])
+                return false;
+            const ret = super.emit('close');
+            this.removeAllListeners('close');
+            return ret;
+        }
+        else if (ev === 'error') {
+            this[EMITTED_ERROR] = data;
+            super.emit(ERROR, data);
+            const ret = !this[SIGNAL] || this.listeners('error').length
+                ? super.emit('error', data)
+                : false;
+            this[MAYBE_EMIT_END]();
+            return ret;
+        }
+        else if (ev === 'resume') {
+            const ret = super.emit('resume');
+            this[MAYBE_EMIT_END]();
+            return ret;
+        }
+        else if (ev === 'finish' || ev === 'prefinish') {
+            const ret = super.emit(ev);
+            this.removeAllListeners(ev);
+            return ret;
+        }
+        // Some other unknown event
+        const ret = super.emit(ev, ...args);
+        this[MAYBE_EMIT_END]();
+        return ret;
+    }
+    [EMITDATA](data) {
+        for (const p of this[PIPES]) {
+            if (p.dest.write(data) === false)
+                this.pause();
+        }
+        const ret = this[DISCARDED] ? false : super.emit('data', data);
+        this[MAYBE_EMIT_END]();
+        return ret;
+    }
+    [EMITEND]() {
+        if (this[EMITTED_END])
+            return false;
+        this[EMITTED_END] = true;
+        this.readable = false;
+        return this[ASYNC]
+            ? (defer(() => this[EMITEND2]()), true)
+            : this[EMITEND2]();
+    }
+    [EMITEND2]() {
+        if (this[DECODER]) {
+            const data = this[DECODER].end();
+            if (data) {
+                for (const p of this[PIPES]) {
+                    p.dest.write(data);
+                }
+                if (!this[DISCARDED])
+                    super.emit('data', data);
+            }
+        }
+        for (const p of this[PIPES]) {
+            p.end();
+        }
+        const ret = super.emit('end');
+        this.removeAllListeners('end');
+        return ret;
+    }
+    /**
+     * Return a Promise that resolves to an array of all emitted data once
+     * the stream ends.
+     */
+    async collect() {
+        const buf = Object.assign([], {
+            dataLength: 0,
+        });
+        if (!this[OBJECTMODE])
+            buf.dataLength = 0;
+        // set the promise first, in case an error is raised
+        // by triggering the flow here.
+        const p = this.promise();
+        this.on('data', c => {
+            buf.push(c);
+            if (!this[OBJECTMODE])
+                buf.dataLength += c.length;
+        });
+        await p;
+        return buf;
+    }
+    /**
+     * Return a Promise that resolves to the concatenation of all emitted data
+     * once the stream ends.
+     *
+     * Not allowed on objectMode streams.
+     */
+    async concat() {
+        if (this[OBJECTMODE]) {
+            throw new Error('cannot concat in objectMode');
+        }
+        const buf = await this.collect();
+        return (this[ENCODING]
+            ? buf.join('')
+            : Buffer.concat(buf, buf.dataLength));
+    }
+    /**
+     * Return a void Promise that resolves once the stream ends.
+     */
+    async promise() {
+        return new Promise((resolve, reject) => {
+            this.on(DESTROYED, () => reject(new Error('stream destroyed')));
+            this.on('error', er => reject(er));
+            this.on('end', () => resolve());
+        });
+    }
+    /**
+     * Asynchronous `for await of` iteration.
+     *
+     * This will continue emitting all chunks until the stream terminates.
+     */
+    [Symbol.asyncIterator]() {
+        // set this up front, in case the consumer doesn't call next()
+        // right away.
+        this[DISCARDED] = false;
+        let stopped = false;
+        const stop = async () => {
+            this.pause();
+            stopped = true;
+            return { value: undefined, done: true };
+        };
+        const next = () => {
+            if (stopped)
+                return stop();
+            const res = this.read();
+            if (res !== null)
+                return Promise.resolve({ done: false, value: res });
+            if (this[EOF])
+                return stop();
+            let resolve;
+            let reject;
+            const onerr = (er) => {
+                this.off('data', ondata);
+                this.off('end', onend);
+                this.off(DESTROYED, ondestroy);
+                stop();
+                reject(er);
+            };
+            const ondata = (value) => {
+                this.off('error', onerr);
+                this.off('end', onend);
+                this.off(DESTROYED, ondestroy);
+                this.pause();
+                resolve({ value, done: !!this[EOF] });
+            };
+            const onend = () => {
+                this.off('error', onerr);
+                this.off('data', ondata);
+                this.off(DESTROYED, ondestroy);
+                stop();
+                resolve({ done: true, value: undefined });
+            };
+            const ondestroy = () => onerr(new Error('stream destroyed'));
+            return new Promise((res, rej) => {
+                reject = rej;
+                resolve = res;
+                this.once(DESTROYED, ondestroy);
+                this.once('error', onerr);
+                this.once('end', onend);
+                this.once('data', ondata);
+            });
+        };
+        return {
+            next,
+            throw: stop,
+            return: stop,
+            [Symbol.asyncIterator]() {
+                return this;
+            },
+        };
+    }
+    /**
+     * Synchronous `for of` iteration.
+     *
+     * The iteration will terminate when the internal buffer runs out, even
+     * if the stream has not yet terminated.
+     */
+    [Symbol.iterator]() {
+        // set this up front, in case the consumer doesn't call next()
+        // right away.
+        this[DISCARDED] = false;
+        let stopped = false;
+        const stop = () => {
+            this.pause();
+            this.off(ERROR, stop);
+            this.off(DESTROYED, stop);
+            this.off('end', stop);
+            stopped = true;
+            return { done: true, value: undefined };
+        };
+        const next = () => {
+            if (stopped)
+                return stop();
+            const value = this.read();
+            return value === null ? stop() : { done: false, value };
+        };
+        this.once('end', stop);
+        this.once(ERROR, stop);
+        this.once(DESTROYED, stop);
+        return {
+            next,
+            throw: stop,
+            return: stop,
+            [Symbol.iterator]() {
+                return this;
+            },
+        };
+    }
+    /**
+     * Destroy a stream, preventing it from being used for any further purpose.
+     *
+     * If the stream has a `close()` method, then it will be called on
+     * destruction.
+     *
+     * After destruction, any attempt to write data, read data, or emit most
+     * events will be ignored.
+     *
+     * If an error argument is provided, then it will be emitted in an
+     * 'error' event.
+     */
+    destroy(er) {
+        if (this[DESTROYED]) {
+            if (er)
+                this.emit('error', er);
+            else
+                this.emit(DESTROYED);
+            return this;
+        }
+        this[DESTROYED] = true;
+        this[DISCARDED] = true;
+        // throw away all buffered data, it's never coming out
+        this[BUFFER].length = 0;
+        this[BUFFERLENGTH] = 0;
+        const wc = this;
+        if (typeof wc.close === 'function' && !this[CLOSED])
+            wc.close();
+        if (er)
+            this.emit('error', er);
+        // if no error to emit, still reject pending promises
+        else
+            this.emit(DESTROYED);
+        return this;
+    }
+    /**
+     * Alias for {@link isStream}
+     *
+     * Former export location, maintained for backwards compatibility.
+     *
+     * @deprecated
+     */
+    static get isStream() {
+        return isStream;
+    }
+}
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/mjs/package.json b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/mjs/package.json
new file mode 100644
index 00000000000000..3dbc1ca591c055
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/dist/mjs/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "module"
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/package.json b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/package.json
new file mode 100644
index 00000000000000..6faaa247a5bc66
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/node_modules/minipass/package.json
@@ -0,0 +1,82 @@
+{
+  "name": "minipass",
+  "version": "7.0.3",
+  "description": "minimal implementation of a PassThrough stream",
+  "main": "./dist/cjs/index.js",
+  "module": "./dist/mjs/index.js",
+  "types": "./dist/cjs/index.js",
+  "exports": {
+    ".": {
+      "import": {
+        "types": "./dist/mjs/index.d.ts",
+        "default": "./dist/mjs/index.js"
+      },
+      "require": {
+        "types": "./dist/cjs/index.d.ts",
+        "default": "./dist/cjs/index.js"
+      }
+    },
+    "./package.json": "./package.json"
+  },
+  "files": [
+    "dist"
+  ],
+  "scripts": {
+    "preversion": "npm test",
+    "postversion": "npm publish",
+    "prepublishOnly": "git push origin --follow-tags",
+    "preprepare": "rm -rf dist",
+    "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json && bash ./scripts/fixup.sh",
+    "pretest": "npm run prepare",
+    "presnap": "npm run prepare",
+    "test": "c8 tap",
+    "snap": "c8 tap",
+    "format": "prettier --write . --loglevel warn",
+    "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts"
+  },
+  "tap": {
+    "coverage": false,
+    "node-arg": [
+      "--enable-source-maps",
+      "--no-warnings",
+      "--loader",
+      "ts-node/esm"
+    ],
+    "ts": false
+  },
+  "prettier": {
+    "semi": false,
+    "printWidth": 75,
+    "tabWidth": 2,
+    "useTabs": false,
+    "singleQuote": true,
+    "jsxSingleQuote": false,
+    "bracketSameLine": true,
+    "arrowParens": "avoid",
+    "endOfLine": "lf"
+  },
+  "devDependencies": {
+    "@types/node": "^20.1.2",
+    "@types/tap": "^15.0.8",
+    "c8": "^7.13.0",
+    "prettier": "^2.6.2",
+    "tap": "^16.3.0",
+    "ts-node": "^10.9.1",
+    "typedoc": "^0.24.8",
+    "typescript": "^5.1.3",
+    "end-of-stream": "^1.4.0",
+    "node-abort-controller": "^3.1.1",
+    "sync-content": "^1.0.2",
+    "through2": "^2.0.3"
+  },
+  "repository": "https://github.com/isaacs/minipass",
+  "keywords": [
+    "passthrough",
+    "stream"
+  ],
+  "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
+  "license": "ISC",
+  "engines": {
+    "node": ">=16 || 14 >=14.17"
+  }
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/cacache/package.json b/deps/npm/node_modules/node-gyp/node_modules/cacache/package.json
new file mode 100644
index 00000000000000..ab58cb8b7c50f4
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/cacache/package.json
@@ -0,0 +1,82 @@
+{
+  "name": "cacache",
+  "version": "17.1.4",
+  "cache-version": {
+    "content": "2",
+    "index": "5"
+  },
+  "description": "Fast, fault-tolerant, cross-platform, disk-based, data-agnostic, content-addressable cache.",
+  "main": "lib/index.js",
+  "files": [
+    "bin/",
+    "lib/"
+  ],
+  "scripts": {
+    "test": "tap",
+    "snap": "tap",
+    "coverage": "tap",
+    "test-docker": "docker run -it --rm --name pacotest -v \"$PWD\":/tmp -w /tmp node:latest npm test",
+    "lint": "eslint \"**/*.js\"",
+    "npmclilint": "npmcli-lint",
+    "lintfix": "npm run lint -- --fix",
+    "postsnap": "npm run lintfix --",
+    "postlint": "template-oss-check",
+    "posttest": "npm run lint",
+    "template-oss-apply": "template-oss-apply --force"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/npm/cacache.git"
+  },
+  "keywords": [
+    "cache",
+    "caching",
+    "content-addressable",
+    "sri",
+    "sri hash",
+    "subresource integrity",
+    "cache",
+    "storage",
+    "store",
+    "file store",
+    "filesystem",
+    "disk cache",
+    "disk storage"
+  ],
+  "license": "ISC",
+  "dependencies": {
+    "@npmcli/fs": "^3.1.0",
+    "fs-minipass": "^3.0.0",
+    "glob": "^10.2.2",
+    "lru-cache": "^7.7.1",
+    "minipass": "^7.0.3",
+    "minipass-collect": "^1.0.2",
+    "minipass-flush": "^1.0.5",
+    "minipass-pipeline": "^1.2.4",
+    "p-map": "^4.0.0",
+    "ssri": "^10.0.0",
+    "tar": "^6.1.11",
+    "unique-filename": "^3.0.0"
+  },
+  "devDependencies": {
+    "@npmcli/eslint-config": "^4.0.0",
+    "@npmcli/template-oss": "4.18.0",
+    "tap": "^16.0.0"
+  },
+  "engines": {
+    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+  },
+  "templateOSS": {
+    "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
+    "windowsCI": false,
+    "version": "4.18.0",
+    "publish": "true"
+  },
+  "author": "GitHub Inc.",
+  "tap": {
+    "nyc-arg": [
+      "--exclude",
+      "tap-snapshots/**"
+    ]
+  }
+}
diff --git a/deps/npm/node_modules/path-scurry/node_modules/lru-cache/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/lru-cache/LICENSE
similarity index 100%
rename from deps/npm/node_modules/path-scurry/node_modules/lru-cache/LICENSE
rename to deps/npm/node_modules/node-gyp/node_modules/lru-cache/LICENSE
diff --git a/deps/npm/node_modules/lru-cache/index.js b/deps/npm/node_modules/node-gyp/node_modules/lru-cache/index.js
similarity index 100%
rename from deps/npm/node_modules/lru-cache/index.js
rename to deps/npm/node_modules/node-gyp/node_modules/lru-cache/index.js
diff --git a/deps/npm/node_modules/lru-cache/index.mjs b/deps/npm/node_modules/node-gyp/node_modules/lru-cache/index.mjs
similarity index 100%
rename from deps/npm/node_modules/lru-cache/index.mjs
rename to deps/npm/node_modules/node-gyp/node_modules/lru-cache/index.mjs
diff --git a/deps/npm/node_modules/path-scurry/node_modules/lru-cache/package.json b/deps/npm/node_modules/node-gyp/node_modules/lru-cache/package.json
similarity index 55%
rename from deps/npm/node_modules/path-scurry/node_modules/lru-cache/package.json
rename to deps/npm/node_modules/node-gyp/node_modules/lru-cache/package.json
index 69a20582ff9b6f..9684991727e7a2 100644
--- a/deps/npm/node_modules/path-scurry/node_modules/lru-cache/package.json
+++ b/deps/npm/node_modules/node-gyp/node_modules/lru-cache/package.json
@@ -1,7 +1,7 @@
 {
   "name": "lru-cache",
   "description": "A cache object that deletes the least-recently-used items.",
-  "version": "9.1.1",
+  "version": "7.18.3",
   "author": "Isaac Z. Schlueter ",
   "keywords": [
     "mru",
@@ -11,47 +11,34 @@
   "sideEffects": false,
   "scripts": {
     "build": "npm run prepare",
-    "preprepare": "rm -rf dist",
-    "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json",
-    "postprepare": "bash fixup.sh",
     "pretest": "npm run prepare",
     "presnap": "npm run prepare",
-    "test": "c8 tap",
-    "snap": "c8 tap",
+    "prepare": "node ./scripts/transpile-to-esm.js",
+    "size": "size-limit",
+    "test": "tap",
+    "snap": "tap",
     "preversion": "npm test",
     "postversion": "npm publish",
     "prepublishOnly": "git push origin --follow-tags",
     "format": "prettier --write .",
-    "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts",
-    "benchmark-results-typedoc": "bash scripts/benchmark-results-typedoc.sh",
-    "prebenchmark": "npm run prepare",
-    "benchmark": "make -C benchmark",
-    "preprofile": "npm run prepare",
-    "profile": "make -C benchmark profile"
+    "typedoc": "typedoc ./index.d.ts"
   },
-  "main": "./dist/cjs/index.js",
-  "module": "./dist/mjs/index.js",
+  "type": "commonjs",
+  "main": "./index.js",
+  "module": "./index.mjs",
+  "types": "./index.d.ts",
   "exports": {
-    "./min": {
-      "import": {
-        "types": "./dist/mjs/index.d.ts",
-        "default": "./dist/mjs/index.min.js"
-      },
-      "require": {
-        "types": "./dist/cjs/index.d.ts",
-        "default": "./dist/cjs/index.min.js"
-      }
-    },
     ".": {
       "import": {
-        "types": "./dist/mjs/index.d.ts",
-        "default": "./dist/mjs/index.js"
+        "types": "./index.d.ts",
+        "default": "./index.mjs"
       },
       "require": {
-        "types": "./dist/cjs/index.d.ts",
-        "default": "./dist/cjs/index.js"
+        "types": "./index.d.ts",
+        "default": "./index.js"
       }
-    }
+    },
+    "./package.json": "./package.json"
   },
   "repository": "git://github.com/isaacs/node-lru-cache.git",
   "devDependencies": {
@@ -61,10 +48,7 @@
     "benchmark": "^2.1.4",
     "c8": "^7.11.2",
     "clock-mock": "^1.0.6",
-    "esbuild": "^0.17.11",
     "eslint-config-prettier": "^8.5.0",
-    "marked": "^4.2.12",
-    "mkdirp": "^2.1.5",
     "prettier": "^2.6.2",
     "size-limit": "^7.0.8",
     "tap": "^16.3.4",
@@ -75,10 +59,12 @@
   },
   "license": "ISC",
   "files": [
-    "dist"
+    "index.js",
+    "index.mjs",
+    "index.d.ts"
   ],
   "engines": {
-    "node": "14 || >=16.14"
+    "node": ">=12"
   },
   "prettier": {
     "semi": false,
@@ -92,18 +78,19 @@
     "endOfLine": "lf"
   },
   "tap": {
-    "coverage": false,
+    "nyc-arg": [
+      "--include=index.js"
+    ],
     "node-arg": [
       "--expose-gc",
-      "--no-warnings",
-      "--loader",
-      "ts-node/esm"
+      "--require",
+      "ts-node/register"
     ],
     "ts": false
   },
   "size-limit": [
     {
-      "path": "./dist/mjs/index.js"
+      "path": "./index.js"
     }
   ]
 }
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/LICENSE
new file mode 100644
index 00000000000000..1808eb2844231c
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/LICENSE
@@ -0,0 +1,16 @@
+ISC License
+
+Copyright 2017-2022 (c) npm, Inc.
+
+Permission to use, copy, modify, and/or distribute this software for
+any purpose with or without fee is hereby granted, provided that the
+above copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE COPYRIGHT HOLDER DISCLAIMS
+ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
+USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/deps/npm/node_modules/make-fetch-happen/lib/agent.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/agent.js
similarity index 100%
rename from deps/npm/node_modules/make-fetch-happen/lib/agent.js
rename to deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/agent.js
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/entry.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/entry.js
new file mode 100644
index 00000000000000..45141095074ecb
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/entry.js
@@ -0,0 +1,469 @@
+const { Request, Response } = require('minipass-fetch')
+const { Minipass } = require('minipass')
+const MinipassFlush = require('minipass-flush')
+const cacache = require('cacache')
+const url = require('url')
+
+const CachingMinipassPipeline = require('../pipeline.js')
+const CachePolicy = require('./policy.js')
+const cacheKey = require('./key.js')
+const remote = require('../remote.js')
+
+const hasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
+
+// allow list for request headers that will be written to the cache index
+// note: we will also store any request headers
+// that are named in a response's vary header
+const KEEP_REQUEST_HEADERS = [
+  'accept-charset',
+  'accept-encoding',
+  'accept-language',
+  'accept',
+  'cache-control',
+]
+
+// allow list for response headers that will be written to the cache index
+// note: we must not store the real response's age header, or when we load
+// a cache policy based on the metadata it will think the cached response
+// is always stale
+const KEEP_RESPONSE_HEADERS = [
+  'cache-control',
+  'content-encoding',
+  'content-language',
+  'content-type',
+  'date',
+  'etag',
+  'expires',
+  'last-modified',
+  'link',
+  'location',
+  'pragma',
+  'vary',
+]
+
+// return an object containing all metadata to be written to the index
+const getMetadata = (request, response, options) => {
+  const metadata = {
+    time: Date.now(),
+    url: request.url,
+    reqHeaders: {},
+    resHeaders: {},
+
+    // options on which we must match the request and vary the response
+    options: {
+      compress: options.compress != null ? options.compress : request.compress,
+    },
+  }
+
+  // only save the status if it's not a 200 or 304
+  if (response.status !== 200 && response.status !== 304) {
+    metadata.status = response.status
+  }
+
+  for (const name of KEEP_REQUEST_HEADERS) {
+    if (request.headers.has(name)) {
+      metadata.reqHeaders[name] = request.headers.get(name)
+    }
+  }
+
+  // if the request's host header differs from the host in the url
+  // we need to keep it, otherwise it's just noise and we ignore it
+  const host = request.headers.get('host')
+  const parsedUrl = new url.URL(request.url)
+  if (host && parsedUrl.host !== host) {
+    metadata.reqHeaders.host = host
+  }
+
+  // if the response has a vary header, make sure
+  // we store the relevant request headers too
+  if (response.headers.has('vary')) {
+    const vary = response.headers.get('vary')
+    // a vary of "*" means every header causes a different response.
+    // in that scenario, we do not include any additional headers
+    // as the freshness check will always fail anyway and we don't
+    // want to bloat the cache indexes
+    if (vary !== '*') {
+      // copy any other request headers that will vary the response
+      const varyHeaders = vary.trim().toLowerCase().split(/\s*,\s*/)
+      for (const name of varyHeaders) {
+        if (request.headers.has(name)) {
+          metadata.reqHeaders[name] = request.headers.get(name)
+        }
+      }
+    }
+  }
+
+  for (const name of KEEP_RESPONSE_HEADERS) {
+    if (response.headers.has(name)) {
+      metadata.resHeaders[name] = response.headers.get(name)
+    }
+  }
+
+  for (const name of options.cacheAdditionalHeaders) {
+    if (response.headers.has(name)) {
+      metadata.resHeaders[name] = response.headers.get(name)
+    }
+  }
+
+  return metadata
+}
+
+// symbols used to hide objects that may be lazily evaluated in a getter
+const _request = Symbol('request')
+const _response = Symbol('response')
+const _policy = Symbol('policy')
+
+class CacheEntry {
+  constructor ({ entry, request, response, options }) {
+    if (entry) {
+      this.key = entry.key
+      this.entry = entry
+      // previous versions of this module didn't write an explicit timestamp in
+      // the metadata, so fall back to the entry's timestamp. we can't use the
+      // entry timestamp to determine staleness because cacache will update it
+      // when it verifies its data
+      this.entry.metadata.time = this.entry.metadata.time || this.entry.time
+    } else {
+      this.key = cacheKey(request)
+    }
+
+    this.options = options
+
+    // these properties are behind getters that lazily evaluate
+    this[_request] = request
+    this[_response] = response
+    this[_policy] = null
+  }
+
+  // returns a CacheEntry instance that satisfies the given request
+  // or undefined if no existing entry satisfies
+  static async find (request, options) {
+    try {
+      // compacts the index and returns an array of unique entries
+      var matches = await cacache.index.compact(options.cachePath, cacheKey(request), (A, B) => {
+        const entryA = new CacheEntry({ entry: A, options })
+        const entryB = new CacheEntry({ entry: B, options })
+        return entryA.policy.satisfies(entryB.request)
+      }, {
+        validateEntry: (entry) => {
+          // clean out entries with a buggy content-encoding value
+          if (entry.metadata &&
+              entry.metadata.resHeaders &&
+              entry.metadata.resHeaders['content-encoding'] === null) {
+            return false
+          }
+
+          // if an integrity is null, it needs to have a status specified
+          if (entry.integrity === null) {
+            return !!(entry.metadata && entry.metadata.status)
+          }
+
+          return true
+        },
+      })
+    } catch (err) {
+      // if the compact request fails, ignore the error and return
+      return
+    }
+
+    // a cache mode of 'reload' means to behave as though we have no cache
+    // on the way to the network. return undefined to allow cacheFetch to
+    // create a brand new request no matter what.
+    if (options.cache === 'reload') {
+      return
+    }
+
+    // find the specific entry that satisfies the request
+    let match
+    for (const entry of matches) {
+      const _entry = new CacheEntry({
+        entry,
+        options,
+      })
+
+      if (_entry.policy.satisfies(request)) {
+        match = _entry
+        break
+      }
+    }
+
+    return match
+  }
+
+  // if the user made a PUT/POST/PATCH then we invalidate our
+  // cache for the same url by deleting the index entirely
+  static async invalidate (request, options) {
+    const key = cacheKey(request)
+    try {
+      await cacache.rm.entry(options.cachePath, key, { removeFully: true })
+    } catch (err) {
+      // ignore errors
+    }
+  }
+
+  get request () {
+    if (!this[_request]) {
+      this[_request] = new Request(this.entry.metadata.url, {
+        method: 'GET',
+        headers: this.entry.metadata.reqHeaders,
+        ...this.entry.metadata.options,
+      })
+    }
+
+    return this[_request]
+  }
+
+  get response () {
+    if (!this[_response]) {
+      this[_response] = new Response(null, {
+        url: this.entry.metadata.url,
+        counter: this.options.counter,
+        status: this.entry.metadata.status || 200,
+        headers: {
+          ...this.entry.metadata.resHeaders,
+          'content-length': this.entry.size,
+        },
+      })
+    }
+
+    return this[_response]
+  }
+
+  get policy () {
+    if (!this[_policy]) {
+      this[_policy] = new CachePolicy({
+        entry: this.entry,
+        request: this.request,
+        response: this.response,
+        options: this.options,
+      })
+    }
+
+    return this[_policy]
+  }
+
+  // wraps the response in a pipeline that stores the data
+  // in the cache while the user consumes it
+  async store (status) {
+    // if we got a status other than 200, 301, or 308,
+    // or the CachePolicy forbid storage, append the
+    // cache status header and return it untouched
+    if (
+      this.request.method !== 'GET' ||
+      ![200, 301, 308].includes(this.response.status) ||
+      !this.policy.storable()
+    ) {
+      this.response.headers.set('x-local-cache-status', 'skip')
+      return this.response
+    }
+
+    const size = this.response.headers.get('content-length')
+    const cacheOpts = {
+      algorithms: this.options.algorithms,
+      metadata: getMetadata(this.request, this.response, this.options),
+      size,
+      integrity: this.options.integrity,
+      integrityEmitter: this.response.body.hasIntegrityEmitter && this.response.body,
+    }
+
+    let body = null
+    // we only set a body if the status is a 200, redirects are
+    // stored as metadata only
+    if (this.response.status === 200) {
+      let cacheWriteResolve, cacheWriteReject
+      const cacheWritePromise = new Promise((resolve, reject) => {
+        cacheWriteResolve = resolve
+        cacheWriteReject = reject
+      })
+
+      body = new CachingMinipassPipeline({ events: ['integrity', 'size'] }, new MinipassFlush({
+        flush () {
+          return cacheWritePromise
+        },
+      }))
+      // this is always true since if we aren't reusing the one from the remote fetch, we
+      // are using the one from cacache
+      body.hasIntegrityEmitter = true
+
+      const onResume = () => {
+        const tee = new Minipass()
+        const cacheStream = cacache.put.stream(this.options.cachePath, this.key, cacheOpts)
+        // re-emit the integrity and size events on our new response body so they can be reused
+        cacheStream.on('integrity', i => body.emit('integrity', i))
+        cacheStream.on('size', s => body.emit('size', s))
+        // stick a flag on here so downstream users will know if they can expect integrity events
+        tee.pipe(cacheStream)
+        // TODO if the cache write fails, log a warning but return the response anyway
+        // eslint-disable-next-line promise/catch-or-return
+        cacheStream.promise().then(cacheWriteResolve, cacheWriteReject)
+        body.unshift(tee)
+        body.unshift(this.response.body)
+      }
+
+      body.once('resume', onResume)
+      body.once('end', () => body.removeListener('resume', onResume))
+    } else {
+      await cacache.index.insert(this.options.cachePath, this.key, null, cacheOpts)
+    }
+
+    // note: we do not set the x-local-cache-hash header because we do not know
+    // the hash value until after the write to the cache completes, which doesn't
+    // happen until after the response has been sent and it's too late to write
+    // the header anyway
+    this.response.headers.set('x-local-cache', encodeURIComponent(this.options.cachePath))
+    this.response.headers.set('x-local-cache-key', encodeURIComponent(this.key))
+    this.response.headers.set('x-local-cache-mode', 'stream')
+    this.response.headers.set('x-local-cache-status', status)
+    this.response.headers.set('x-local-cache-time', new Date().toISOString())
+    const newResponse = new Response(body, {
+      url: this.response.url,
+      status: this.response.status,
+      headers: this.response.headers,
+      counter: this.options.counter,
+    })
+    return newResponse
+  }
+
+  // use the cached data to create a response and return it
+  async respond (method, options, status) {
+    let response
+    if (method === 'HEAD' || [301, 308].includes(this.response.status)) {
+      // if the request is a HEAD, or the response is a redirect,
+      // then the metadata in the entry already includes everything
+      // we need to build a response
+      response = this.response
+    } else {
+      // we're responding with a full cached response, so create a body
+      // that reads from cacache and attach it to a new Response
+      const body = new Minipass()
+      const headers = { ...this.policy.responseHeaders() }
+
+      const onResume = () => {
+        const cacheStream = cacache.get.stream.byDigest(
+          this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize }
+        )
+        cacheStream.on('error', async (err) => {
+          cacheStream.pause()
+          if (err.code === 'EINTEGRITY') {
+            await cacache.rm.content(
+              this.options.cachePath, this.entry.integrity, { memoize: this.options.memoize }
+            )
+          }
+          if (err.code === 'ENOENT' || err.code === 'EINTEGRITY') {
+            await CacheEntry.invalidate(this.request, this.options)
+          }
+          body.emit('error', err)
+          cacheStream.resume()
+        })
+        // emit the integrity and size events based on our metadata so we're consistent
+        body.emit('integrity', this.entry.integrity)
+        body.emit('size', Number(headers['content-length']))
+        cacheStream.pipe(body)
+      }
+
+      body.once('resume', onResume)
+      body.once('end', () => body.removeListener('resume', onResume))
+      response = new Response(body, {
+        url: this.entry.metadata.url,
+        counter: options.counter,
+        status: 200,
+        headers,
+      })
+    }
+
+    response.headers.set('x-local-cache', encodeURIComponent(this.options.cachePath))
+    response.headers.set('x-local-cache-hash', encodeURIComponent(this.entry.integrity))
+    response.headers.set('x-local-cache-key', encodeURIComponent(this.key))
+    response.headers.set('x-local-cache-mode', 'stream')
+    response.headers.set('x-local-cache-status', status)
+    response.headers.set('x-local-cache-time', new Date(this.entry.metadata.time).toUTCString())
+    return response
+  }
+
+  // use the provided request along with this cache entry to
+  // revalidate the stored response. returns a response, either
+  // from the cache or from the update
+  async revalidate (request, options) {
+    const revalidateRequest = new Request(request, {
+      headers: this.policy.revalidationHeaders(request),
+    })
+
+    try {
+      // NOTE: be sure to remove the headers property from the
+      // user supplied options, since we have already defined
+      // them on the new request object. if they're still in the
+      // options then those will overwrite the ones from the policy
+      var response = await remote(revalidateRequest, {
+        ...options,
+        headers: undefined,
+      })
+    } catch (err) {
+      // if the network fetch fails, return the stale
+      // cached response unless it has a cache-control
+      // of 'must-revalidate'
+      if (!this.policy.mustRevalidate) {
+        return this.respond(request.method, options, 'stale')
+      }
+
+      throw err
+    }
+
+    if (this.policy.revalidated(revalidateRequest, response)) {
+      // we got a 304, write a new index to the cache and respond from cache
+      const metadata = getMetadata(request, response, options)
+      // 304 responses do not include headers that are specific to the response data
+      // since they do not include a body, so we copy values for headers that were
+      // in the old cache entry to the new one, if the new metadata does not already
+      // include that header
+      for (const name of KEEP_RESPONSE_HEADERS) {
+        if (
+          !hasOwnProperty(metadata.resHeaders, name) &&
+          hasOwnProperty(this.entry.metadata.resHeaders, name)
+        ) {
+          metadata.resHeaders[name] = this.entry.metadata.resHeaders[name]
+        }
+      }
+
+      for (const name of options.cacheAdditionalHeaders) {
+        const inMeta = hasOwnProperty(metadata.resHeaders, name)
+        const inEntry = hasOwnProperty(this.entry.metadata.resHeaders, name)
+        const inPolicy = hasOwnProperty(this.policy.response.headers, name)
+
+        // if the header is in the existing entry, but it is not in the metadata
+        // then we need to write it to the metadata as this will refresh the on-disk cache
+        if (!inMeta && inEntry) {
+          metadata.resHeaders[name] = this.entry.metadata.resHeaders[name]
+        }
+        // if the header is in the metadata, but not in the policy, then we need to set
+        // it in the policy so that it's included in the immediate response. future
+        // responses will load a new cache entry, so we don't need to change that
+        if (!inPolicy && inMeta) {
+          this.policy.response.headers[name] = metadata.resHeaders[name]
+        }
+      }
+
+      try {
+        await cacache.index.insert(options.cachePath, this.key, this.entry.integrity, {
+          size: this.entry.size,
+          metadata,
+        })
+      } catch (err) {
+        // if updating the cache index fails, we ignore it and
+        // respond anyway
+      }
+      return this.respond(request.method, options, 'revalidated')
+    }
+
+    // if we got a modified response, create a new entry based on it
+    const newEntry = new CacheEntry({
+      request,
+      response,
+      options,
+    })
+
+    // respond with the new entry while writing it to the cache
+    return newEntry.store('updated')
+  }
+}
+
+module.exports = CacheEntry
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/errors.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/errors.js
new file mode 100644
index 00000000000000..67a66573bebe66
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/errors.js
@@ -0,0 +1,11 @@
+class NotCachedError extends Error {
+  constructor (url) {
+    /* eslint-disable-next-line max-len */
+    super(`request to ${url} failed: cache mode is 'only-if-cached' but no cached response is available.`)
+    this.code = 'ENOTCACHED'
+  }
+}
+
+module.exports = {
+  NotCachedError,
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/index.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/index.js
new file mode 100644
index 00000000000000..0de49d23fb9336
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/index.js
@@ -0,0 +1,49 @@
+const { NotCachedError } = require('./errors.js')
+const CacheEntry = require('./entry.js')
+const remote = require('../remote.js')
+
+// do whatever is necessary to get a Response and return it
+const cacheFetch = async (request, options) => {
+  // try to find a cached entry that satisfies this request
+  const entry = await CacheEntry.find(request, options)
+  if (!entry) {
+    // no cached result, if the cache mode is 'only-if-cached' that's a failure
+    if (options.cache === 'only-if-cached') {
+      throw new NotCachedError(request.url)
+    }
+
+    // otherwise, we make a request, store it and return it
+    const response = await remote(request, options)
+    const newEntry = new CacheEntry({ request, response, options })
+    return newEntry.store('miss')
+  }
+
+  // we have a cached response that satisfies this request, however if the cache
+  // mode is 'no-cache' then we send the revalidation request no matter what
+  if (options.cache === 'no-cache') {
+    return entry.revalidate(request, options)
+  }
+
+  // if the cached entry is not stale, or if the cache mode is 'force-cache' or
+  // 'only-if-cached' we can respond with the cached entry. set the status
+  // based on the result of needsRevalidation and respond
+  const _needsRevalidation = entry.policy.needsRevalidation(request)
+  if (options.cache === 'force-cache' ||
+      options.cache === 'only-if-cached' ||
+      !_needsRevalidation) {
+    return entry.respond(request.method, options, _needsRevalidation ? 'stale' : 'hit')
+  }
+
+  // if we got here, the cache entry is stale so revalidate it
+  return entry.revalidate(request, options)
+}
+
+cacheFetch.invalidate = async (request, options) => {
+  if (!options.cachePath) {
+    return
+  }
+
+  return CacheEntry.invalidate(request, options)
+}
+
+module.exports = cacheFetch
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/key.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/key.js
new file mode 100644
index 00000000000000..f7684d562b7fae
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/key.js
@@ -0,0 +1,17 @@
+const { URL, format } = require('url')
+
+// options passed to url.format() when generating a key
+const formatOptions = {
+  auth: false,
+  fragment: false,
+  search: true,
+  unicode: false,
+}
+
+// returns a string to be used as the cache key for the Request
+const cacheKey = (request) => {
+  const parsed = new URL(request.url)
+  return `make-fetch-happen:request-cache:${format(parsed, formatOptions)}`
+}
+
+module.exports = cacheKey
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/policy.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/policy.js
new file mode 100644
index 00000000000000..ada3c8600dae92
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/cache/policy.js
@@ -0,0 +1,161 @@
+const CacheSemantics = require('http-cache-semantics')
+const Negotiator = require('negotiator')
+const ssri = require('ssri')
+
+// options passed to http-cache-semantics constructor
+const policyOptions = {
+  shared: false,
+  ignoreCargoCult: true,
+}
+
+// a fake empty response, used when only testing the
+// request for storability
+const emptyResponse = { status: 200, headers: {} }
+
+// returns a plain object representation of the Request
+const requestObject = (request) => {
+  const _obj = {
+    method: request.method,
+    url: request.url,
+    headers: {},
+    compress: request.compress,
+  }
+
+  request.headers.forEach((value, key) => {
+    _obj.headers[key] = value
+  })
+
+  return _obj
+}
+
+// returns a plain object representation of the Response
+const responseObject = (response) => {
+  const _obj = {
+    status: response.status,
+    headers: {},
+  }
+
+  response.headers.forEach((value, key) => {
+    _obj.headers[key] = value
+  })
+
+  return _obj
+}
+
+class CachePolicy {
+  constructor ({ entry, request, response, options }) {
+    this.entry = entry
+    this.request = requestObject(request)
+    this.response = responseObject(response)
+    this.options = options
+    this.policy = new CacheSemantics(this.request, this.response, policyOptions)
+
+    if (this.entry) {
+      // if we have an entry, copy the timestamp to the _responseTime
+      // this is necessary because the CacheSemantics constructor forces
+      // the value to Date.now() which means a policy created from a
+      // cache entry is likely to always identify itself as stale
+      this.policy._responseTime = this.entry.metadata.time
+    }
+  }
+
+  // static method to quickly determine if a request alone is storable
+  static storable (request, options) {
+    // no cachePath means no caching
+    if (!options.cachePath) {
+      return false
+    }
+
+    // user explicitly asked not to cache
+    if (options.cache === 'no-store') {
+      return false
+    }
+
+    // we only cache GET and HEAD requests
+    if (!['GET', 'HEAD'].includes(request.method)) {
+      return false
+    }
+
+    // otherwise, let http-cache-semantics make the decision
+    // based on the request's headers
+    const policy = new CacheSemantics(requestObject(request), emptyResponse, policyOptions)
+    return policy.storable()
+  }
+
+  // returns true if the policy satisfies the request
+  satisfies (request) {
+    const _req = requestObject(request)
+    if (this.request.headers.host !== _req.headers.host) {
+      return false
+    }
+
+    if (this.request.compress !== _req.compress) {
+      return false
+    }
+
+    const negotiatorA = new Negotiator(this.request)
+    const negotiatorB = new Negotiator(_req)
+
+    if (JSON.stringify(negotiatorA.mediaTypes()) !== JSON.stringify(negotiatorB.mediaTypes())) {
+      return false
+    }
+
+    if (JSON.stringify(negotiatorA.languages()) !== JSON.stringify(negotiatorB.languages())) {
+      return false
+    }
+
+    if (JSON.stringify(negotiatorA.encodings()) !== JSON.stringify(negotiatorB.encodings())) {
+      return false
+    }
+
+    if (this.options.integrity) {
+      return ssri.parse(this.options.integrity).match(this.entry.integrity)
+    }
+
+    return true
+  }
+
+  // returns true if the request and response allow caching
+  storable () {
+    return this.policy.storable()
+  }
+
+  // NOTE: this is a hack to avoid parsing the cache-control
+  // header ourselves, it returns true if the response's
+  // cache-control contains must-revalidate
+  get mustRevalidate () {
+    return !!this.policy._rescc['must-revalidate']
+  }
+
+  // returns true if the cached response requires revalidation
+  // for the given request
+  needsRevalidation (request) {
+    const _req = requestObject(request)
+    // force method to GET because we only cache GETs
+    // but can serve a HEAD from a cached GET
+    _req.method = 'GET'
+    return !this.policy.satisfiesWithoutRevalidation(_req)
+  }
+
+  responseHeaders () {
+    return this.policy.responseHeaders()
+  }
+
+  // returns a new object containing the appropriate headers
+  // to send a revalidation request
+  revalidationHeaders (request) {
+    const _req = requestObject(request)
+    return this.policy.revalidationHeaders(_req)
+  }
+
+  // returns true if the request/response was revalidated
+  // successfully. returns false if a new response was received
+  revalidated (request, response) {
+    const _req = requestObject(request)
+    const _res = responseObject(response)
+    const policy = this.policy.revalidatedPolicy(_req, _res)
+    return !policy.modified
+  }
+}
+
+module.exports = CachePolicy
diff --git a/deps/npm/node_modules/make-fetch-happen/lib/dns.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/dns.js
similarity index 100%
rename from deps/npm/node_modules/make-fetch-happen/lib/dns.js
rename to deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/dns.js
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/fetch.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/fetch.js
new file mode 100644
index 00000000000000..233ba67e165502
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/fetch.js
@@ -0,0 +1,118 @@
+'use strict'
+
+const { FetchError, Request, isRedirect } = require('minipass-fetch')
+const url = require('url')
+
+const CachePolicy = require('./cache/policy.js')
+const cache = require('./cache/index.js')
+const remote = require('./remote.js')
+
+// given a Request, a Response and user options
+// return true if the response is a redirect that
+// can be followed. we throw errors that will result
+// in the fetch being rejected if the redirect is
+// possible but invalid for some reason
+const canFollowRedirect = (request, response, options) => {
+  if (!isRedirect(response.status)) {
+    return false
+  }
+
+  if (options.redirect === 'manual') {
+    return false
+  }
+
+  if (options.redirect === 'error') {
+    throw new FetchError(`redirect mode is set to error: ${request.url}`,
+      'no-redirect', { code: 'ENOREDIRECT' })
+  }
+
+  if (!response.headers.has('location')) {
+    throw new FetchError(`redirect location header missing for: ${request.url}`,
+      'no-location', { code: 'EINVALIDREDIRECT' })
+  }
+
+  if (request.counter >= request.follow) {
+    throw new FetchError(`maximum redirect reached at: ${request.url}`,
+      'max-redirect', { code: 'EMAXREDIRECT' })
+  }
+
+  return true
+}
+
+// given a Request, a Response, and the user's options return an object
+// with a new Request and a new options object that will be used for
+// following the redirect
+const getRedirect = (request, response, options) => {
+  const _opts = { ...options }
+  const location = response.headers.get('location')
+  const redirectUrl = new url.URL(location, /^https?:/.test(location) ? undefined : request.url)
+  // Comment below is used under the following license:
+  /**
+   * @license
+   * Copyright (c) 2010-2012 Mikeal Rogers
+   * Licensed under the Apache License, Version 2.0 (the "License");
+   * you may not use this file except in compliance with the License.
+   * You may obtain a copy of the License at
+   * http://www.apache.org/licenses/LICENSE-2.0
+   * Unless required by applicable law or agreed to in writing,
+   * software distributed under the License is distributed on an "AS
+   * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+   * express or implied. See the License for the specific language
+   * governing permissions and limitations under the License.
+   */
+
+  // Remove authorization if changing hostnames (but not if just
+  // changing ports or protocols).  This matches the behavior of request:
+  // https://github.com/request/request/blob/b12a6245/lib/redirect.js#L134-L138
+  if (new url.URL(request.url).hostname !== redirectUrl.hostname) {
+    request.headers.delete('authorization')
+    request.headers.delete('cookie')
+  }
+
+  // for POST request with 301/302 response, or any request with 303 response,
+  // use GET when following redirect
+  if (
+    response.status === 303 ||
+    (request.method === 'POST' && [301, 302].includes(response.status))
+  ) {
+    _opts.method = 'GET'
+    _opts.body = null
+    request.headers.delete('content-length')
+  }
+
+  _opts.headers = {}
+  request.headers.forEach((value, key) => {
+    _opts.headers[key] = value
+  })
+
+  _opts.counter = ++request.counter
+  const redirectReq = new Request(url.format(redirectUrl), _opts)
+  return {
+    request: redirectReq,
+    options: _opts,
+  }
+}
+
+const fetch = async (request, options) => {
+  const response = CachePolicy.storable(request, options)
+    ? await cache(request, options)
+    : await remote(request, options)
+
+  // if the request wasn't a GET or HEAD, and the response
+  // status is between 200 and 399 inclusive, invalidate the
+  // request url
+  if (!['GET', 'HEAD'].includes(request.method) &&
+      response.status >= 200 &&
+      response.status <= 399) {
+    await cache.invalidate(request, options)
+  }
+
+  if (!canFollowRedirect(request, response, options)) {
+    return response
+  }
+
+  const redirect = getRedirect(request, response, options)
+  return fetch(redirect.request, redirect.options)
+}
+
+module.exports = fetch
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/index.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/index.js
new file mode 100644
index 00000000000000..2f12e8e1b61131
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/index.js
@@ -0,0 +1,41 @@
+const { FetchError, Headers, Request, Response } = require('minipass-fetch')
+
+const configureOptions = require('./options.js')
+const fetch = require('./fetch.js')
+
+const makeFetchHappen = (url, opts) => {
+  const options = configureOptions(opts)
+
+  const request = new Request(url, options)
+  return fetch(request, options)
+}
+
+makeFetchHappen.defaults = (defaultUrl, defaultOptions = {}, wrappedFetch = makeFetchHappen) => {
+  if (typeof defaultUrl === 'object') {
+    defaultOptions = defaultUrl
+    defaultUrl = null
+  }
+
+  const defaultedFetch = (url, options = {}) => {
+    const finalUrl = url || defaultUrl
+    const finalOptions = {
+      ...defaultOptions,
+      ...options,
+      headers: {
+        ...defaultOptions.headers,
+        ...options.headers,
+      },
+    }
+    return wrappedFetch(finalUrl, finalOptions)
+  }
+
+  defaultedFetch.defaults = (defaultUrl1, defaultOptions1 = {}) =>
+    makeFetchHappen.defaults(defaultUrl1, defaultOptions1, defaultedFetch)
+  return defaultedFetch
+}
+
+module.exports = makeFetchHappen
+module.exports.FetchError = FetchError
+module.exports.Headers = Headers
+module.exports.Request = Request
+module.exports.Response = Response
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/options.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/options.js
new file mode 100644
index 00000000000000..f77511279f831d
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/options.js
@@ -0,0 +1,54 @@
+const dns = require('dns')
+
+const conditionalHeaders = [
+  'if-modified-since',
+  'if-none-match',
+  'if-unmodified-since',
+  'if-match',
+  'if-range',
+]
+
+const configureOptions = (opts) => {
+  const { strictSSL, ...options } = { ...opts }
+  options.method = options.method ? options.method.toUpperCase() : 'GET'
+  options.rejectUnauthorized = strictSSL !== false
+
+  if (!options.retry) {
+    options.retry = { retries: 0 }
+  } else if (typeof options.retry === 'string') {
+    const retries = parseInt(options.retry, 10)
+    if (isFinite(retries)) {
+      options.retry = { retries }
+    } else {
+      options.retry = { retries: 0 }
+    }
+  } else if (typeof options.retry === 'number') {
+    options.retry = { retries: options.retry }
+  } else {
+    options.retry = { retries: 0, ...options.retry }
+  }
+
+  options.dns = { ttl: 5 * 60 * 1000, lookup: dns.lookup, ...options.dns }
+
+  options.cache = options.cache || 'default'
+  if (options.cache === 'default') {
+    const hasConditionalHeader = Object.keys(options.headers || {}).some((name) => {
+      return conditionalHeaders.includes(name.toLowerCase())
+    })
+    if (hasConditionalHeader) {
+      options.cache = 'no-store'
+    }
+  }
+
+  options.cacheAdditionalHeaders = options.cacheAdditionalHeaders || []
+
+  // cacheManager is deprecated, but if it's set and
+  // cachePath is not we should copy it to the new field
+  if (options.cacheManager && !options.cachePath) {
+    options.cachePath = options.cacheManager
+  }
+
+  return options
+}
+
+module.exports = configureOptions
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/pipeline.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/pipeline.js
new file mode 100644
index 00000000000000..b1d221b2d0ce31
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/pipeline.js
@@ -0,0 +1,41 @@
+'use strict'
+
+const MinipassPipeline = require('minipass-pipeline')
+
+class CachingMinipassPipeline extends MinipassPipeline {
+  #events = []
+  #data = new Map()
+
+  constructor (opts, ...streams) {
+    // CRITICAL: do NOT pass the streams to the call to super(), this will start
+    // the flow of data and potentially cause the events we need to catch to emit
+    // before we've finished our own setup. instead we call super() with no args,
+    // finish our setup, and then push the streams into ourselves to start the
+    // data flow
+    super()
+    this.#events = opts.events
+
+    /* istanbul ignore next - coverage disabled because this is pointless to test here */
+    if (streams.length) {
+      this.push(...streams)
+    }
+  }
+
+  on (event, handler) {
+    if (this.#events.includes(event) && this.#data.has(event)) {
+      return handler(...this.#data.get(event))
+    }
+
+    return super.on(event, handler)
+  }
+
+  emit (event, ...data) {
+    if (this.#events.includes(event)) {
+      this.#data.set(event, data)
+    }
+
+    return super.emit(event, ...data)
+  }
+}
+
+module.exports = CachingMinipassPipeline
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/remote.js b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/remote.js
new file mode 100644
index 00000000000000..bdbcc79cad908d
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/lib/remote.js
@@ -0,0 +1,121 @@
+const { Minipass } = require('minipass')
+const fetch = require('minipass-fetch')
+const promiseRetry = require('promise-retry')
+const ssri = require('ssri')
+
+const CachingMinipassPipeline = require('./pipeline.js')
+const getAgent = require('./agent.js')
+const pkg = require('../package.json')
+
+const USER_AGENT = `${pkg.name}/${pkg.version} (+https://npm.im/${pkg.name})`
+
+const RETRY_ERRORS = [
+  'ECONNRESET', // remote socket closed on us
+  'ECONNREFUSED', // remote host refused to open connection
+  'EADDRINUSE', // failed to bind to a local port (proxy?)
+  'ETIMEDOUT', // someone in the transaction is WAY TOO SLOW
+  'ERR_SOCKET_TIMEOUT', // same as above, but this one comes from agentkeepalive
+  // Known codes we do NOT retry on:
+  // ENOTFOUND (getaddrinfo failure. Either bad hostname, or offline)
+]
+
+const RETRY_TYPES = [
+  'request-timeout',
+]
+
+// make a request directly to the remote source,
+// retrying certain classes of errors as well as
+// following redirects (through the cache if necessary)
+// and verifying response integrity
+const remoteFetch = (request, options) => {
+  const agent = getAgent(request.url, options)
+  if (!request.headers.has('connection')) {
+    request.headers.set('connection', agent ? 'keep-alive' : 'close')
+  }
+
+  if (!request.headers.has('user-agent')) {
+    request.headers.set('user-agent', USER_AGENT)
+  }
+
+  // keep our own options since we're overriding the agent
+  // and the redirect mode
+  const _opts = {
+    ...options,
+    agent,
+    redirect: 'manual',
+  }
+
+  return promiseRetry(async (retryHandler, attemptNum) => {
+    const req = new fetch.Request(request, _opts)
+    try {
+      let res = await fetch(req, _opts)
+      if (_opts.integrity && res.status === 200) {
+        // we got a 200 response and the user has specified an expected
+        // integrity value, so wrap the response in an ssri stream to verify it
+        const integrityStream = ssri.integrityStream({
+          algorithms: _opts.algorithms,
+          integrity: _opts.integrity,
+          size: _opts.size,
+        })
+        const pipeline = new CachingMinipassPipeline({
+          events: ['integrity', 'size'],
+        }, res.body, integrityStream)
+        // we also propagate the integrity and size events out to the pipeline so we can use
+        // this new response body as an integrityEmitter for cacache
+        integrityStream.on('integrity', i => pipeline.emit('integrity', i))
+        integrityStream.on('size', s => pipeline.emit('size', s))
+        res = new fetch.Response(pipeline, res)
+        // set an explicit flag so we know if our response body will emit integrity and size
+        res.body.hasIntegrityEmitter = true
+      }
+
+      res.headers.set('x-fetch-attempts', attemptNum)
+
+      // do not retry POST requests, or requests with a streaming body
+      // do retry requests with a 408, 420, 429 or 500+ status in the response
+      const isStream = Minipass.isStream(req.body)
+      const isRetriable = req.method !== 'POST' &&
+          !isStream &&
+          ([408, 420, 429].includes(res.status) || res.status >= 500)
+
+      if (isRetriable) {
+        if (typeof options.onRetry === 'function') {
+          options.onRetry(res)
+        }
+
+        return retryHandler(res)
+      }
+
+      return res
+    } catch (err) {
+      const code = (err.code === 'EPROMISERETRY')
+        ? err.retried.code
+        : err.code
+
+      // err.retried will be the thing that was thrown from above
+      // if it's a response, we just got a bad status code and we
+      // can re-throw to allow the retry
+      const isRetryError = err.retried instanceof fetch.Response ||
+        (RETRY_ERRORS.includes(code) && RETRY_TYPES.includes(err.type))
+
+      if (req.method === 'POST' || isRetryError) {
+        throw err
+      }
+
+      if (typeof options.onRetry === 'function') {
+        options.onRetry(err)
+      }
+
+      return retryHandler(err)
+    }
+  }, options.retry).catch((err) => {
+    // don't reject for http errors, just return them
+    if (err.status >= 400 && err.type !== 'system') {
+      return err
+    }
+
+    throw err
+  })
+}
+
+module.exports = remoteFetch
diff --git a/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/package.json b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/package.json
new file mode 100644
index 00000000000000..fd415dc9966faa
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/make-fetch-happen/package.json
@@ -0,0 +1,78 @@
+{
+  "name": "make-fetch-happen",
+  "version": "11.1.1",
+  "description": "Opinionated, caching, retrying fetch client",
+  "main": "lib/index.js",
+  "files": [
+    "bin/",
+    "lib/"
+  ],
+  "scripts": {
+    "test": "tap",
+    "posttest": "npm run lint",
+    "eslint": "eslint",
+    "lint": "eslint \"**/*.js\"",
+    "lintfix": "npm run lint -- --fix",
+    "postlint": "template-oss-check",
+    "snap": "tap",
+    "template-oss-apply": "template-oss-apply --force"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/npm/make-fetch-happen.git"
+  },
+  "keywords": [
+    "http",
+    "request",
+    "fetch",
+    "mean girls",
+    "caching",
+    "cache",
+    "subresource integrity"
+  ],
+  "author": "GitHub Inc.",
+  "license": "ISC",
+  "dependencies": {
+    "agentkeepalive": "^4.2.1",
+    "cacache": "^17.0.0",
+    "http-cache-semantics": "^4.1.1",
+    "http-proxy-agent": "^5.0.0",
+    "https-proxy-agent": "^5.0.0",
+    "is-lambda": "^1.0.1",
+    "lru-cache": "^7.7.1",
+    "minipass": "^5.0.0",
+    "minipass-fetch": "^3.0.0",
+    "minipass-flush": "^1.0.5",
+    "minipass-pipeline": "^1.2.4",
+    "negotiator": "^0.6.3",
+    "promise-retry": "^2.0.1",
+    "socks-proxy-agent": "^7.0.0",
+    "ssri": "^10.0.0"
+  },
+  "devDependencies": {
+    "@npmcli/eslint-config": "^4.0.0",
+    "@npmcli/template-oss": "4.14.1",
+    "nock": "^13.2.4",
+    "safe-buffer": "^5.2.1",
+    "standard-version": "^9.3.2",
+    "tap": "^16.0.0"
+  },
+  "engines": {
+    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+  },
+  "tap": {
+    "color": 1,
+    "files": "test/*.js",
+    "check-coverage": true,
+    "timeout": 60,
+    "nyc-arg": [
+      "--exclude",
+      "tap-snapshots/**"
+    ]
+  },
+  "templateOSS": {
+    "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
+    "version": "4.14.1",
+    "publish": "true"
+  }
+}
diff --git a/deps/npm/node_modules/node-gyp/node_modules/minipass/LICENSE b/deps/npm/node_modules/node-gyp/node_modules/minipass/LICENSE
new file mode 100644
index 00000000000000..97f8e32ed82e4c
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/minipass/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/deps/npm/node_modules/minipass/index.js b/deps/npm/node_modules/node-gyp/node_modules/minipass/index.js
similarity index 100%
rename from deps/npm/node_modules/minipass/index.js
rename to deps/npm/node_modules/node-gyp/node_modules/minipass/index.js
diff --git a/deps/npm/node_modules/minipass/index.mjs b/deps/npm/node_modules/node-gyp/node_modules/minipass/index.mjs
similarity index 99%
rename from deps/npm/node_modules/minipass/index.mjs
rename to deps/npm/node_modules/node-gyp/node_modules/minipass/index.mjs
index d1be109c9fc063..89b3fbf1a4d445 100644
--- a/deps/npm/node_modules/minipass/index.mjs
+++ b/deps/npm/node_modules/node-gyp/node_modules/minipass/index.mjs
@@ -698,4 +698,3 @@ export class Minipass extends Stream {
     )
   }
 }
-
diff --git a/deps/npm/node_modules/node-gyp/node_modules/minipass/package.json b/deps/npm/node_modules/node-gyp/node_modules/minipass/package.json
new file mode 100644
index 00000000000000..0e20e988047f23
--- /dev/null
+++ b/deps/npm/node_modules/node-gyp/node_modules/minipass/package.json
@@ -0,0 +1,76 @@
+{
+  "name": "minipass",
+  "version": "5.0.0",
+  "description": "minimal implementation of a PassThrough stream",
+  "main": "./index.js",
+  "module": "./index.mjs",
+  "types": "./index.d.ts",
+  "exports": {
+    ".": {
+      "import": {
+        "types": "./index.d.ts",
+        "default": "./index.mjs"
+      },
+      "require": {
+        "types": "./index.d.ts",
+        "default": "./index.js"
+      }
+    },
+    "./package.json": "./package.json"
+  },
+  "devDependencies": {
+    "@types/node": "^17.0.41",
+    "end-of-stream": "^1.4.0",
+    "node-abort-controller": "^3.1.1",
+    "prettier": "^2.6.2",
+    "tap": "^16.2.0",
+    "through2": "^2.0.3",
+    "ts-node": "^10.8.1",
+    "typedoc": "^0.23.24",
+    "typescript": "^4.7.3"
+  },
+  "scripts": {
+    "pretest": "npm run prepare",
+    "presnap": "npm run prepare",
+    "prepare": "node ./scripts/transpile-to-esm.js",
+    "snap": "tap",
+    "test": "tap",
+    "preversion": "npm test",
+    "postversion": "npm publish",
+    "postpublish": "git push origin --follow-tags",
+    "typedoc": "typedoc ./index.d.ts",
+    "format": "prettier --write . --loglevel warn"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/isaacs/minipass.git"
+  },
+  "keywords": [
+    "passthrough",
+    "stream"
+  ],
+  "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
+  "license": "ISC",
+  "files": [
+    "index.d.ts",
+    "index.js",
+    "index.mjs"
+  ],
+  "tap": {
+    "check-coverage": true
+  },
+  "engines": {
+    "node": ">=8"
+  },
+  "prettier": {
+    "semi": false,
+    "printWidth": 80,
+    "tabWidth": 2,
+    "useTabs": false,
+    "singleQuote": true,
+    "jsxSingleQuote": false,
+    "bracketSameLine": true,
+    "arrowParens": "avoid",
+    "endOfLine": "lf"
+  }
+}
diff --git a/deps/npm/node_modules/normalize-package-data/package.json b/deps/npm/node_modules/normalize-package-data/package.json
index ec2773bfbe6bf8..48d2371d4a66b5 100644
--- a/deps/npm/node_modules/normalize-package-data/package.json
+++ b/deps/npm/node_modules/normalize-package-data/package.json
@@ -1,6 +1,6 @@
 {
   "name": "normalize-package-data",
-  "version": "5.0.0",
+  "version": "6.0.0",
   "author": "GitHub Inc.",
   "description": "Normalizes data that can be found in package.json files.",
   "license": "BSD-2-Clause",
@@ -21,14 +21,14 @@
     "template-oss-apply": "template-oss-apply --force"
   },
   "dependencies": {
-    "hosted-git-info": "^6.0.0",
+    "hosted-git-info": "^7.0.0",
     "is-core-module": "^2.8.1",
     "semver": "^7.3.5",
     "validate-npm-package-license": "^3.0.4"
   },
   "devDependencies": {
-    "@npmcli/eslint-config": "^3.0.1",
-    "@npmcli/template-oss": "4.5.1",
+    "@npmcli/eslint-config": "^4.0.0",
+    "@npmcli/template-oss": "4.18.0",
     "tap": "^16.0.1"
   },
   "files": [
@@ -36,11 +36,18 @@
     "lib/"
   ],
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.5.1"
+    "version": "4.18.0",
+    "publish": "true",
+    "ciVersions": [
+      "16.14.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ]
   },
   "tap": {
     "branches": 86,
diff --git a/deps/npm/node_modules/npm-install-checks/lib/index.js b/deps/npm/node_modules/npm-install-checks/lib/index.js
index fa5f593aaac647..f0ba2c07ad0812 100644
--- a/deps/npm/node_modules/npm-install-checks/lib/index.js
+++ b/deps/npm/node_modules/npm-install-checks/lib/index.js
@@ -22,13 +22,13 @@ const checkEngine = (target, npmVer, nodeVer, force = false) => {
 
 const isMusl = (file) => file.includes('libc.musl-') || file.includes('ld-musl-')
 
-const checkPlatform = (target, force = false) => {
+const checkPlatform = (target, force = false, environment = {}) => {
   if (force) {
     return
   }
 
-  const platform = process.platform
-  const arch = process.arch
+  const platform = environment.os || process.platform
+  const arch = environment.cpu || process.arch
   const osOk = target.os ? checkList(platform, target.os) : true
   const cpuOk = target.cpu ? checkList(arch, target.cpu) : true
 
diff --git a/deps/npm/node_modules/npm-install-checks/package.json b/deps/npm/node_modules/npm-install-checks/package.json
index 192cf68837146f..50378808d75d08 100644
--- a/deps/npm/node_modules/npm-install-checks/package.json
+++ b/deps/npm/node_modules/npm-install-checks/package.json
@@ -1,6 +1,6 @@
 {
   "name": "npm-install-checks",
-  "version": "6.1.1",
+  "version": "6.2.0",
   "description": "Check the engines and platform fields in package.json",
   "main": "lib/index.js",
   "dependencies": {
@@ -8,7 +8,7 @@
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.13.0",
+    "@npmcli/template-oss": "4.18.0",
     "tap": "^16.0.1"
   },
   "scripts": {
@@ -39,7 +39,7 @@
   "author": "GitHub Inc.",
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.13.0",
+    "version": "4.18.0",
     "publish": "true"
   },
   "tap": {
diff --git a/deps/npm/node_modules/npm-package-arg/lib/npa.js b/deps/npm/node_modules/npm-package-arg/lib/npa.js
index 36bd18cd9f9a6e..f5ede2326e7b47 100644
--- a/deps/npm/node_modules/npm-package-arg/lib/npa.js
+++ b/deps/npm/node_modules/npm-package-arg/lib/npa.js
@@ -257,40 +257,23 @@ function fromFile (res, where) {
     })
   }
 
-  // environment switch for testing
-  if (process.env.NPM_PACKAGE_ARG_8909_STRICT !== '1') {
-    // XXX backwards compatibility lack of compliance with 8909
-    // Remove when we want a breaking change to come into RFC compliance.
-    if (resolvedUrl.host && resolvedUrl.host !== 'localhost') {
-      const rawSpec = res.rawSpec.replace(/^file:\/\//, 'file:///')
-      resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`)
-      specUrl = new url.URL(rawSpec)
-      rawNoPrefix = rawSpec.replace(/^file:/, '')
-    }
-    // turn file:/../foo into file:../foo
-    // for 1, 2 or 3 leading slashes since we attempted
-    // in the previous step to make it a file protocol url with a leading slash
-    if (/^\/{1,3}\.\.?(\/|$)/.test(rawNoPrefix)) {
-      const rawSpec = res.rawSpec.replace(/^file:\/{1,3}/, 'file:')
-      resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`)
-      specUrl = new url.URL(rawSpec)
-      rawNoPrefix = rawSpec.replace(/^file:/, '')
-    }
-    // XXX end 8909 violation backwards compatibility section
-  }
-
-  // file:foo - relative url to ./foo
-  // file:/foo - absolute path /foo
-  // file:///foo - absolute path to /foo, no authority host
-  // file://localhost/foo - absolute path to /foo, on localhost
-  // file://foo - absolute path to / on foo host (error!)
+  // XXX backwards compatibility lack of compliance with RFC 8909
   if (resolvedUrl.host && resolvedUrl.host !== 'localhost') {
-    const msg = `Invalid file: URL, must be absolute if // present`
-    throw Object.assign(new Error(msg), {
-      raw: res.rawSpec,
-      parsed: resolvedUrl,
-    })
+    const rawSpec = res.rawSpec.replace(/^file:\/\//, 'file:///')
+    resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`)
+    specUrl = new url.URL(rawSpec)
+    rawNoPrefix = rawSpec.replace(/^file:/, '')
+  }
+  // turn file:/../foo into file:../foo
+  // for 1, 2 or 3 leading slashes since we attempted
+  // in the previous step to make it a file protocol url with a leading slash
+  if (/^\/{1,3}\.\.?(\/|$)/.test(rawNoPrefix)) {
+    const rawSpec = res.rawSpec.replace(/^file:\/{1,3}/, 'file:')
+    resolvedUrl = new url.URL(rawSpec, `file://${path.resolve(where)}/`)
+    specUrl = new url.URL(rawSpec)
+    rawNoPrefix = rawSpec.replace(/^file:/, '')
   }
+  // XXX end RFC 8909 violation backwards compatibility section
 
   // turn /C:/blah into just C:/blah on windows
   let specPath = decodeURIComponent(specUrl.pathname)
diff --git a/deps/npm/node_modules/npm-package-arg/package.json b/deps/npm/node_modules/npm-package-arg/package.json
index bb9e71b258a939..9ba1d135f3ebf0 100644
--- a/deps/npm/node_modules/npm-package-arg/package.json
+++ b/deps/npm/node_modules/npm-package-arg/package.json
@@ -1,6 +1,6 @@
 {
   "name": "npm-package-arg",
-  "version": "10.1.0",
+  "version": "11.0.0",
   "description": "Parse the things that can be arguments to `npm install`",
   "main": "./lib/npa.js",
   "directories": {
@@ -11,14 +11,14 @@
     "lib/"
   ],
   "dependencies": {
-    "hosted-git-info": "^6.0.0",
+    "hosted-git-info": "^7.0.0",
     "proc-log": "^3.0.0",
     "semver": "^7.3.5",
     "validate-npm-package-name": "^5.0.0"
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.10.0",
+    "@npmcli/template-oss": "4.18.0",
     "tap": "^16.0.1"
   },
   "scripts": {
@@ -43,7 +43,7 @@
   },
   "homepage": "https://github.com/npm/npm-package-arg",
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   },
   "tap": {
     "branches": 97,
@@ -54,6 +54,13 @@
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.10.0"
+    "version": "4.18.0",
+    "publish": true,
+    "ciVersions": [
+      "16.14.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ]
   }
 }
diff --git a/deps/npm/node_modules/npm-packlist/lib/index.js b/deps/npm/node_modules/npm-packlist/lib/index.js
index 887018bd7d424c..7577cba0b865d4 100644
--- a/deps/npm/node_modules/npm-packlist/lib/index.js
+++ b/deps/npm/node_modules/npm-packlist/lib/index.js
@@ -38,13 +38,22 @@ const defaults = [
 ]
 
 const strictDefaults = [
-  // these are forcibly included at all levels
+  // these are forcibly excluded
+  '/.git',
+]
+
+const allLevels = [
+  // these are included by default but can be excluded by package.json files array
   '!/readme{,.*[^~$]}',
   '!/copying{,.*[^~$]}',
   '!/license{,.*[^~$]}',
   '!/licence{,.*[^~$]}',
-  // these are forcibly excluded
-  '/.git',
+]
+
+const rootOnly = [
+  /^!.*readme/i,
+  /^!.*copying/i,
+  /^!.*licen[sc]e/i,
 ]
 
 const normalizePath = (path) => path.split('\\').join('/')
@@ -132,6 +141,7 @@ class PackWalker extends IgnoreWalker {
       // known required files for this directory
       this.injectRules(strictRules, [
         ...strictDefaults,
+        ...allLevels,
         ...this.requiredFiles.map((file) => `!${file}`),
       ])
     }
@@ -284,6 +294,7 @@ class PackWalker extends IgnoreWalker {
     const ignores = []
     const strict = [
       ...strictDefaults,
+      ...allLevels,
       '!/package.json',
       '/.git',
       '/node_modules',
@@ -304,6 +315,9 @@ class PackWalker extends IgnoreWalker {
           file = file.slice(0, -2)
         }
         const inverse = `!${file}`
+
+        this.excludeNonRoot(file)
+
         try {
           // if an entry in the files array is a specific file, then we need to include it as a
           // strict requirement for this package. if it's a directory or a pattern, it's a default
@@ -352,6 +366,20 @@ class PackWalker extends IgnoreWalker {
     this.injectRules(strictRules, strict, callback)
   }
 
+  // excludes non root files by checking if elements from the files array in
+  // package.json contain an ! and readme/license/licence/copying, and then
+  // removing readme/license/licence/copying accordingly from strict defaults
+  excludeNonRoot (file) {
+    // Find the pattern
+    const matchingPattern = rootOnly.find(regex => regex.test(file))
+
+    if (matchingPattern) {
+      // Find which index matches the pattern and remove it from allLevels
+      const indexToRemove = allLevels.findIndex(element => matchingPattern.test(element))
+      allLevels.splice(indexToRemove, 1)
+    }
+  }
+
   // custom method: after we've finished gathering the files for the root package, we call this
   // before emitting the 'done' event in order to gather all of the files for bundled deps
   async gatherBundles () {
diff --git a/deps/npm/node_modules/npm-packlist/package.json b/deps/npm/node_modules/npm-packlist/package.json
index 6023ad34df3b42..460ca7e30ad23f 100644
--- a/deps/npm/node_modules/npm-packlist/package.json
+++ b/deps/npm/node_modules/npm-packlist/package.json
@@ -1,6 +1,6 @@
 {
   "name": "npm-packlist",
-  "version": "7.0.4",
+  "version": "8.0.0",
   "description": "Get a list of the files to add from a folder into an npm package",
   "directories": {
     "test": "test"
@@ -18,7 +18,7 @@
   "devDependencies": {
     "@npmcli/arborist": "^6.0.0 || ^6.0.0-pre.0",
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.10.0",
+    "@npmcli/template-oss": "4.18.0",
     "mutate-fs": "^2.1.1",
     "tap": "^16.0.1"
   },
@@ -55,6 +55,7 @@
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.10.0"
+    "version": "4.18.0",
+    "publish": true
   }
 }
diff --git a/deps/npm/node_modules/npm-pick-manifest/lib/index.js b/deps/npm/node_modules/npm-pick-manifest/lib/index.js
index f2934e9ca1822a..8dbd2721c89963 100644
--- a/deps/npm/node_modules/npm-pick-manifest/lib/index.js
+++ b/deps/npm/node_modules/npm-pick-manifest/lib/index.js
@@ -210,7 +210,7 @@ module.exports = (packument, wanted, opts = {}) => {
     code,
     type: npa.resolve(packument.name, wanted).type,
     wanted,
-    versions: Object.keys(packument.versions),
+    versions: Object.keys(packument.versions ?? {}),
     name,
     distTags: packument['dist-tags'],
     defaultTag,
diff --git a/deps/npm/node_modules/npm-pick-manifest/package.json b/deps/npm/node_modules/npm-pick-manifest/package.json
index 89ff8966f1a39b..e30c2cfe341fc6 100644
--- a/deps/npm/node_modules/npm-pick-manifest/package.json
+++ b/deps/npm/node_modules/npm-pick-manifest/package.json
@@ -1,6 +1,6 @@
 {
   "name": "npm-pick-manifest",
-  "version": "8.0.1",
+  "version": "9.0.0",
   "description": "Resolves a matching manifest from a package metadata document according to standard npm semver resolution rules.",
   "main": "./lib",
   "files": [
@@ -31,12 +31,12 @@
   "dependencies": {
     "npm-install-checks": "^6.0.0",
     "npm-normalize-package-bin": "^3.0.0",
-    "npm-package-arg": "^10.0.0",
+    "npm-package-arg": "^11.0.0",
     "semver": "^7.3.5"
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.6.1",
+    "@npmcli/template-oss": "4.18.0",
     "tap": "^16.0.1"
   },
   "tap": {
@@ -47,10 +47,17 @@
     ]
   },
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.6.1"
+    "version": "4.18.0",
+    "publish": true,
+    "ciVersions": [
+      "16.14.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ]
   }
 }
diff --git a/deps/npm/node_modules/npm-profile/package.json b/deps/npm/node_modules/npm-profile/package.json
index 9c0b77b8a6dd5d..af57e9e73509c3 100644
--- a/deps/npm/node_modules/npm-profile/package.json
+++ b/deps/npm/node_modules/npm-profile/package.json
@@ -1,12 +1,12 @@
 {
   "name": "npm-profile",
-  "version": "7.0.1",
+  "version": "9.0.0",
   "description": "Library for updating an npmjs.com profile",
   "keywords": [],
   "author": "GitHub Inc.",
   "license": "ISC",
   "dependencies": {
-    "npm-registry-fetch": "^14.0.0",
+    "npm-registry-fetch": "^16.0.0",
     "proc-log": "^3.0.0"
   },
   "main": "./lib/index.js",
@@ -20,7 +20,7 @@
   ],
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.5.1",
+    "@npmcli/template-oss": "4.18.0",
     "nock": "^13.2.4",
     "tap": "^16.0.1"
   },
@@ -41,10 +41,17 @@
     ]
   },
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.5.1"
+    "version": "4.18.0",
+    "ciVersions": [
+      "16.14.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ],
+    "publish": true
   }
 }
diff --git a/deps/npm/node_modules/npm-registry-fetch/package.json b/deps/npm/node_modules/npm-registry-fetch/package.json
index 63a44725886ccf..2afadf939743b8 100644
--- a/deps/npm/node_modules/npm-registry-fetch/package.json
+++ b/deps/npm/node_modules/npm-registry-fetch/package.json
@@ -1,6 +1,6 @@
 {
   "name": "npm-registry-fetch",
-  "version": "14.0.5",
+  "version": "16.0.0",
   "description": "Fetch-based http client for use with npm registry APIs",
   "main": "lib",
   "files": [
@@ -31,18 +31,18 @@
   "author": "GitHub Inc.",
   "license": "ISC",
   "dependencies": {
-    "make-fetch-happen": "^11.0.0",
-    "minipass": "^5.0.0",
+    "make-fetch-happen": "^13.0.0",
+    "minipass": "^7.0.2",
     "minipass-fetch": "^3.0.0",
     "minipass-json-stream": "^1.0.1",
     "minizlib": "^2.1.2",
-    "npm-package-arg": "^10.0.0",
+    "npm-package-arg": "^11.0.0",
     "proc-log": "^3.0.0"
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.14.1",
-    "cacache": "^17.0.0",
+    "@npmcli/template-oss": "4.18.0",
+    "cacache": "^18.0.0",
     "nock": "^13.2.4",
     "require-inject": "^1.4.4",
     "ssri": "^10.0.0",
@@ -57,11 +57,17 @@
     ]
   },
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.14.1",
-    "publish": "true"
+    "version": "4.18.0",
+    "publish": "true",
+    "ciVersions": [
+      "16.14.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ]
   }
 }
diff --git a/deps/npm/node_modules/pacote/lib/registry.js b/deps/npm/node_modules/pacote/lib/registry.js
index 34d9b2b87f3f3d..993fd3f08a6d91 100644
--- a/deps/npm/node_modules/pacote/lib/registry.js
+++ b/deps/npm/node_modules/pacote/lib/registry.js
@@ -8,7 +8,7 @@ const pickManifest = require('npm-pick-manifest')
 const ssri = require('ssri')
 const crypto = require('crypto')
 const npa = require('npm-package-arg')
-const { sigstore } = require('sigstore')
+const sigstore = require('sigstore')
 
 // Corgis are cute. 🐕🐶
 const corgiDoc = 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*'
@@ -299,7 +299,7 @@ class RegistryFetcher extends Fetcher {
                 tufCachePath: this.tufCache,
                 keySelector: publicKey ? () => publicKey.pemkey : undefined,
               }
-              await sigstore.verify(bundle, null, options)
+              await sigstore.verify(bundle, options)
             } catch (e) {
               throw Object.assign(new Error(
                 `${mani._id} failed to verify attestation: ${e.message}`
diff --git a/deps/npm/node_modules/pacote/package.json b/deps/npm/node_modules/pacote/package.json
index bc8d984704af5b..4654b03d988c32 100644
--- a/deps/npm/node_modules/pacote/package.json
+++ b/deps/npm/node_modules/pacote/package.json
@@ -1,6 +1,6 @@
 {
   "name": "pacote",
-  "version": "15.2.0",
+  "version": "17.0.4",
   "description": "JavaScript package downloader",
   "author": "GitHub Inc.",
   "bin": {
@@ -27,8 +27,8 @@
   "devDependencies": {
     "@npmcli/arborist": "^6.0.0 || ^6.0.0-pre.0",
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.14.1",
-    "hosted-git-info": "^6.0.0",
+    "@npmcli/template-oss": "4.18.0",
+    "hosted-git-info": "^7.0.0",
     "mutate-fs": "^2.1.1",
     "nock": "^13.2.4",
     "npm-registry-mock": "^1.3.2",
@@ -44,27 +44,27 @@
     "git"
   ],
   "dependencies": {
-    "@npmcli/git": "^4.0.0",
+    "@npmcli/git": "^5.0.0",
     "@npmcli/installed-package-contents": "^2.0.1",
-    "@npmcli/promise-spawn": "^6.0.1",
-    "@npmcli/run-script": "^6.0.0",
-    "cacache": "^17.0.0",
+    "@npmcli/promise-spawn": "^7.0.0",
+    "@npmcli/run-script": "^7.0.0",
+    "cacache": "^18.0.0",
     "fs-minipass": "^3.0.0",
-    "minipass": "^5.0.0",
-    "npm-package-arg": "^10.0.0",
-    "npm-packlist": "^7.0.0",
-    "npm-pick-manifest": "^8.0.0",
-    "npm-registry-fetch": "^14.0.0",
+    "minipass": "^7.0.2",
+    "npm-package-arg": "^11.0.0",
+    "npm-packlist": "^8.0.0",
+    "npm-pick-manifest": "^9.0.0",
+    "npm-registry-fetch": "^16.0.0",
     "proc-log": "^3.0.0",
     "promise-retry": "^2.0.1",
-    "read-package-json": "^6.0.0",
+    "read-package-json": "^7.0.0",
     "read-package-json-fast": "^3.0.0",
-    "sigstore": "^1.3.0",
+    "sigstore": "^2.0.0",
     "ssri": "^10.0.0",
     "tar": "^6.1.11"
   },
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   },
   "repository": {
     "type": "git",
@@ -72,7 +72,13 @@
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.14.1",
+    "ciVersions": [
+      "16.14.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ],
+    "version": "4.18.0",
     "windowsCI": false,
     "publish": "true"
   }
diff --git a/deps/npm/node_modules/path-scurry/dist/cjs/index.js b/deps/npm/node_modules/path-scurry/dist/cjs/index.js
index 8044c7e581d2e4..23eb5b0853ff28 100644
--- a/deps/npm/node_modules/path-scurry/dist/cjs/index.js
+++ b/deps/npm/node_modules/path-scurry/dist/cjs/index.js
@@ -521,6 +521,29 @@ class PathBase {
     isUnknown() {
         return (this.#type & IFMT) === UNKNOWN;
     }
+    isType(type) {
+        return this[`is${type}`]();
+    }
+    getType() {
+        return this.isUnknown()
+            ? 'Unknown'
+            : this.isDirectory()
+                ? 'Directory'
+                : this.isFile()
+                    ? 'File'
+                    : this.isSymbolicLink()
+                        ? 'SymbolicLink'
+                        : this.isFIFO()
+                            ? 'FIFO'
+                            : this.isCharacterDevice()
+                                ? 'CharacterDevice'
+                                : this.isBlockDevice()
+                                    ? 'BlockDevice'
+                                    : /* c8 ignore start */ this.isSocket()
+                                        ? 'Socket'
+                                        : 'Unknown';
+        /* c8 ignore stop */
+    }
     /**
      * Is the Path a regular file?
      */
diff --git a/deps/npm/node_modules/path-scurry/dist/mjs/index.js b/deps/npm/node_modules/path-scurry/dist/mjs/index.js
index 957f087c865147..079253a6aee967 100644
--- a/deps/npm/node_modules/path-scurry/dist/mjs/index.js
+++ b/deps/npm/node_modules/path-scurry/dist/mjs/index.js
@@ -493,6 +493,29 @@ export class PathBase {
     isUnknown() {
         return (this.#type & IFMT) === UNKNOWN;
     }
+    isType(type) {
+        return this[`is${type}`]();
+    }
+    getType() {
+        return this.isUnknown()
+            ? 'Unknown'
+            : this.isDirectory()
+                ? 'Directory'
+                : this.isFile()
+                    ? 'File'
+                    : this.isSymbolicLink()
+                        ? 'SymbolicLink'
+                        : this.isFIFO()
+                            ? 'FIFO'
+                            : this.isCharacterDevice()
+                                ? 'CharacterDevice'
+                                : this.isBlockDevice()
+                                    ? 'BlockDevice'
+                                    : /* c8 ignore start */ this.isSocket()
+                                        ? 'Socket'
+                                        : 'Unknown';
+        /* c8 ignore stop */
+    }
     /**
      * Is the Path a regular file?
      */
diff --git a/deps/npm/node_modules/path-scurry/node_modules/lru-cache/dist/cjs/index.min.js b/deps/npm/node_modules/path-scurry/node_modules/lru-cache/dist/cjs/index.min.js
deleted file mode 100644
index d854bf570d346c..00000000000000
--- a/deps/npm/node_modules/path-scurry/node_modules/lru-cache/dist/cjs/index.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-"use strict";var x=(o,t,e)=>{if(!t.has(o))throw TypeError("Cannot "+e)};var j=(o,t,e)=>(x(o,t,"read from private field"),e?e.call(o):t.get(o)),I=(o,t,e)=>{if(t.has(o))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(o):t.set(o,e)},D=(o,t,e,i)=>(x(o,t,"write to private field"),i?i.call(o,e):t.set(o,e),e);Object.defineProperty(exports,"__esModule",{value:!0});exports.LRUCache=void 0;var v=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,N=new Set,L=typeof process=="object"&&process?process:{},P=(o,t,e,i)=>{typeof L.emitWarning=="function"?L.emitWarning(o,t,e,i):console.error(`[${e}] ${t}: ${o}`)},W=globalThis.AbortController,M=globalThis.AbortSignal;if(typeof W>"u"){M=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(i,s){this._onabort.push(s)}},W=class{constructor(){t()}signal=new M;abort(i){if(!this.signal.aborted){this.signal.reason=i,this.signal.aborted=!0;for(let s of this.signal._onabort)s(i);this.signal.onabort?.(i)}}};let o=L.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",t=()=>{o&&(o=!1,P("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.","NO_ABORT_CONTROLLER","ENOTSUP",t))}}var V=o=>!N.has(o),Y=Symbol("type"),m=o=>o&&o===Math.floor(o)&&o>0&&isFinite(o),k=o=>m(o)?o<=Math.pow(2,8)?Uint8Array:o<=Math.pow(2,16)?Uint16Array:o<=Math.pow(2,32)?Uint32Array:o<=Number.MAX_SAFE_INTEGER?z:null:null,z=class extends Array{constructor(t){super(t),this.fill(0)}},E,T=class{heap;length;static create(t){let e=k(t);if(!e)return[];D(T,E,!0);let i=new T(t,e);return D(T,E,!1),i}constructor(t,e){if(!j(T,E))throw new TypeError("instantiate Stack using Stack.create(n)");this.heap=new e(t),this.length=0}push(t){this.heap[this.length++]=t}pop(){return this.heap[--this.length]}},R=T;E=new WeakMap,I(R,E,!1);var C=class{#d;#f;#_;#g;#C;ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#s;#p;#n;#i;#t;#l;#c;#o;#h;#w;#r;#m;#F;#S;#b;#T;#a;static unsafeExposeInternals(t){return{starts:t.#F,ttls:t.#S,sizes:t.#m,keyMap:t.#n,keyList:t.#i,valList:t.#t,next:t.#l,prev:t.#c,get head(){return t.#o},get tail(){return t.#h},free:t.#w,isBackgroundFetch:e=>t.#e(e),backgroundFetch:(e,i,s,n)=>t.#D(e,i,s,n),moveToTail:e=>t.#v(e),indexes:e=>t.#y(e),rindexes:e=>t.#A(e),isStale:e=>t.#u(e)}}get max(){return this.#d}get maxSize(){return this.#f}get calculatedSize(){return this.#p}get size(){return this.#s}get fetchMethod(){return this.#C}get dispose(){return this.#_}get disposeAfter(){return this.#g}constructor(t){let{max:e=0,ttl:i,ttlResolution:s=1,ttlAutopurge:n,updateAgeOnGet:h,updateAgeOnHas:a,allowStale:r,dispose:u,disposeAfter:b,noDisposeOnSet:f,noUpdateTTL:d,maxSize:p=0,maxEntrySize:F=0,sizeCalculation:c,fetchMethod:w,noDeleteOnFetchRejection:l,noDeleteOnStaleGet:S,allowStaleOnFetchRejection:y,allowStaleOnFetchAbort:g,ignoreFetchAbort:_}=t;if(e!==0&&!m(e))throw new TypeError("max option must be a nonnegative integer");let O=e?k(e):Array;if(!O)throw new Error("invalid max value: "+e);if(this.#d=e,this.#f=p,this.maxEntrySize=F||this.#f,this.sizeCalculation=c,this.sizeCalculation){if(!this.#f&&!this.maxEntrySize)throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");if(typeof this.sizeCalculation!="function")throw new TypeError("sizeCalculation set to non-function")}if(w!==void 0&&typeof w!="function")throw new TypeError("fetchMethod must be a function if specified");if(this.#C=w,this.#T=!!w,this.#n=new Map,this.#i=new Array(e).fill(void 0),this.#t=new Array(e).fill(void 0),this.#l=new O(e),this.#c=new O(e),this.#o=0,this.#h=0,this.#w=R.create(e),this.#s=0,this.#p=0,typeof u=="function"&&(this.#_=u),typeof b=="function"?(this.#g=b,this.#r=[]):(this.#g=void 0,this.#r=void 0),this.#b=!!this.#_,this.#a=!!this.#g,this.noDisposeOnSet=!!f,this.noUpdateTTL=!!d,this.noDeleteOnFetchRejection=!!l,this.allowStaleOnFetchRejection=!!y,this.allowStaleOnFetchAbort=!!g,this.ignoreFetchAbort=!!_,this.maxEntrySize!==0){if(this.#f!==0&&!m(this.#f))throw new TypeError("maxSize must be a positive integer if specified");if(!m(this.maxEntrySize))throw new TypeError("maxEntrySize must be a positive integer if specified");this.#I()}if(this.allowStale=!!r,this.noDeleteOnStaleGet=!!S,this.updateAgeOnGet=!!h,this.updateAgeOnHas=!!a,this.ttlResolution=m(s)||s===0?s:1,this.ttlAutopurge=!!n,this.ttl=i||0,this.ttl){if(!m(this.ttl))throw new TypeError("ttl must be a positive integer if specified");this.#L()}if(this.#d===0&&this.ttl===0&&this.#f===0)throw new TypeError("At least one of max, maxSize, or ttl is required");if(!this.ttlAutopurge&&!this.#d&&!this.#f){let A="LRU_CACHE_UNBOUNDED";V(A)&&(N.add(A),P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.","UnboundedCacheWarning",A,C))}}getRemainingTTL(t){return this.#n.has(t)?1/0:0}#L(){let t=new z(this.#d),e=new z(this.#d);this.#S=t,this.#F=e,this.#U=(n,h,a=v.now())=>{if(e[n]=h!==0?a:0,t[n]=h,h!==0&&this.ttlAutopurge){let r=setTimeout(()=>{this.#u(n)&&this.delete(this.#i[n])},h+1);r.unref&&r.unref()}},this.#z=n=>{e[n]=t[n]!==0?v.now():0},this.#O=(n,h)=>{if(t[h]){let a=t[h],r=e[h];n.ttl=a,n.start=r,n.now=i||s();let u=n.now-r;n.remainingTTL=a-u}};let i=0,s=()=>{let n=v.now();if(this.ttlResolution>0){i=n;let h=setTimeout(()=>i=0,this.ttlResolution);h.unref&&h.unref()}return n};this.getRemainingTTL=n=>{let h=this.#n.get(n);if(h===void 0)return 0;let a=t[h],r=e[h];if(a===0||r===0)return 1/0;let u=(i||s())-r;return a-u},this.#u=n=>t[n]!==0&&e[n]!==0&&(i||s())-e[n]>t[n]}#z=()=>{};#O=()=>{};#U=()=>{};#u=()=>!1;#I(){let t=new z(this.#d);this.#p=0,this.#m=t,this.#E=e=>{this.#p-=t[e],t[e]=0},this.#G=(e,i,s,n)=>{if(this.#e(i))return 0;if(!m(s))if(n){if(typeof n!="function")throw new TypeError("sizeCalculation must be a function");if(s=n(i,e),!m(s))throw new TypeError("sizeCalculation return invalid (expect positive integer)")}else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");return s},this.#R=(e,i,s)=>{if(t[e]=i,this.#f){let n=this.#f-t[e];for(;this.#p>n;)this.#W(!0)}this.#p+=t[e],s&&(s.entrySize=i,s.totalCalculatedSize=this.#p)}}#E=t=>{};#R=(t,e,i)=>{};#G=(t,e,i,s)=>{if(i||s)throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");return 0};*#y({allowStale:t=this.allowStale}={}){if(this.#s)for(let e=this.#h;!(!this.#x(e)||((t||!this.#u(e))&&(yield e),e===this.#o));)e=this.#c[e]}*#A({allowStale:t=this.allowStale}={}){if(this.#s)for(let e=this.#o;!(!this.#x(e)||((t||!this.#u(e))&&(yield e),e===this.#h));)e=this.#l[e]}#x(t){return t!==void 0&&this.#n.get(this.#i[t])===t}*entries(){for(let t of this.#y())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*rentries(){for(let t of this.#A())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*keys(){for(let t of this.#y()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*rkeys(){for(let t of this.#A()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*values(){for(let t of this.#y())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}*rvalues(){for(let t of this.#A())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}[Symbol.iterator](){return this.entries()}find(t,e={}){for(let i of this.#y()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;if(n!==void 0&&t(n,this.#i[i],this))return this.get(this.#i[i],e)}}forEach(t,e=this){for(let i of this.#y()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}rforEach(t,e=this){for(let i of this.#A()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}purgeStale(){let t=!1;for(let e of this.#A({allowStale:!0}))this.#u(e)&&(this.delete(this.#i[e]),t=!0);return t}dump(){let t=[];for(let e of this.#y({allowStale:!0})){let i=this.#i[e],s=this.#t[e],n=this.#e(s)?s.__staleWhileFetching:s;if(n===void 0||i===void 0)continue;let h={value:n};if(this.#S&&this.#F){h.ttl=this.#S[e];let a=v.now()-this.#F[e];h.start=Math.floor(Date.now()-a)}this.#m&&(h.size=this.#m[e]),t.unshift([i,h])}return t}load(t){this.clear();for(let[e,i]of t){if(i.start){let s=Date.now()-i.start;i.start=v.now()-s}this.set(e,i.value,i)}}set(t,e,i={}){if(e===void 0)return this.delete(t),this;let{ttl:s=this.ttl,start:n,noDisposeOnSet:h=this.noDisposeOnSet,sizeCalculation:a=this.sizeCalculation,status:r}=i,{noUpdateTTL:u=this.noUpdateTTL}=i,b=this.#G(t,e,i.size||0,a);if(this.maxEntrySize&&b>this.maxEntrySize)return r&&(r.set="miss",r.maxEntrySizeExceeded=!0),this.delete(t),this;let f=this.#s===0?void 0:this.#n.get(t);if(f===void 0)f=this.#s===0?this.#h:this.#w.length!==0?this.#w.pop():this.#s===this.#d?this.#W(!1):this.#s,this.#i[f]=t,this.#t[f]=e,this.#n.set(t,f),this.#l[this.#h]=f,this.#c[f]=this.#h,this.#h=f,this.#s++,this.#R(f,b,r),r&&(r.set="add"),u=!1;else{this.#v(f);let d=this.#t[f];if(e!==d){if(this.#T&&this.#e(d)?d.__abortController.abort(new Error("replaced")):h||(this.#b&&this.#_?.(d,t,"set"),this.#a&&this.#r?.push([d,t,"set"])),this.#E(f),this.#R(f,b,r),this.#t[f]=e,r){r.set="replace";let p=d&&this.#e(d)?d.__staleWhileFetching:d;p!==void 0&&(r.oldValue=p)}}else r&&(r.set="update")}if(s!==0&&!this.#S&&this.#L(),this.#S&&(u||this.#U(f,s,n),r&&this.#O(r,f)),!h&&this.#a&&this.#r){let d=this.#r,p;for(;p=d?.shift();)this.#g?.(...p)}return this}pop(){try{for(;this.#s;){let t=this.#t[this.#o];if(this.#W(!0),this.#e(t)){if(t.__staleWhileFetching)return t.__staleWhileFetching}else if(t!==void 0)return t}}finally{if(this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#g?.(...e)}}}#W(t){let e=this.#o,i=this.#i[e],s=this.#t[e];return this.#T&&this.#e(s)?s.__abortController.abort(new Error("evicted")):(this.#b||this.#a)&&(this.#b&&this.#_?.(s,i,"evict"),this.#a&&this.#r?.push([s,i,"evict"])),this.#E(e),t&&(this.#i[e]=void 0,this.#t[e]=void 0,this.#w.push(e)),this.#s===1?(this.#o=this.#h=0,this.#w.length=0):this.#o=this.#l[e],this.#n.delete(i),this.#s--,e}has(t,e={}){let{updateAgeOnHas:i=this.updateAgeOnHas,status:s}=e,n=this.#n.get(t);if(n!==void 0){let h=this.#t[n];if(this.#e(h)&&h.__staleWhileFetching===void 0)return!1;if(this.#u(n))s&&(s.has="stale",this.#O(s,n));else return i&&this.#z(n),s&&(s.has="hit",this.#O(s,n)),!0}else s&&(s.has="miss");return!1}peek(t,e={}){let{allowStale:i=this.allowStale}=e,s=this.#n.get(t);if(s!==void 0&&(i||!this.#u(s))){let n=this.#t[s];return this.#e(n)?n.__staleWhileFetching:n}}#D(t,e,i,s){let n=e===void 0?void 0:this.#t[e];if(this.#e(n))return n;let h=new W,{signal:a}=i;a?.addEventListener("abort",()=>h.abort(a.reason),{signal:h.signal});let r={signal:h.signal,options:i,context:s},u=(c,w=!1)=>{let{aborted:l}=h.signal,S=i.ignoreFetchAbort&&c!==void 0;if(i.status&&(l&&!w?(i.status.fetchAborted=!0,i.status.fetchError=h.signal.reason,S&&(i.status.fetchAbortIgnored=!0)):i.status.fetchResolved=!0),l&&!S&&!w)return f(h.signal.reason);let y=p;return this.#t[e]===p&&(c===void 0?y.__staleWhileFetching?this.#t[e]=y.__staleWhileFetching:this.delete(t):(i.status&&(i.status.fetchUpdated=!0),this.set(t,c,r.options))),c},b=c=>(i.status&&(i.status.fetchRejected=!0,i.status.fetchError=c),f(c)),f=c=>{let{aborted:w}=h.signal,l=w&&i.allowStaleOnFetchAbort,S=l||i.allowStaleOnFetchRejection,y=S||i.noDeleteOnFetchRejection,g=p;if(this.#t[e]===p&&(!y||g.__staleWhileFetching===void 0?this.delete(t):l||(this.#t[e]=g.__staleWhileFetching)),S)return i.status&&g.__staleWhileFetching!==void 0&&(i.status.returnedStale=!0),g.__staleWhileFetching;if(g.__returned===g)throw c},d=(c,w)=>{let l=this.#C?.(t,n,r);l&&l instanceof Promise&&l.then(S=>c(S),w),h.signal.addEventListener("abort",()=>{(!i.ignoreFetchAbort||i.allowStaleOnFetchAbort)&&(c(),i.allowStaleOnFetchAbort&&(c=S=>u(S,!0)))})};i.status&&(i.status.fetchDispatched=!0);let p=new Promise(d).then(u,b),F=Object.assign(p,{__abortController:h,__staleWhileFetching:n,__returned:void 0});return e===void 0?(this.set(t,F,{...r.options,status:void 0}),e=this.#n.get(t)):this.#t[e]=F,F}#e(t){if(!this.#T)return!1;let e=t;return!!e&&e instanceof Promise&&e.hasOwnProperty("__staleWhileFetching")&&e.__abortController instanceof W}async fetch(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,ttl:h=this.ttl,noDisposeOnSet:a=this.noDisposeOnSet,size:r=0,sizeCalculation:u=this.sizeCalculation,noUpdateTTL:b=this.noUpdateTTL,noDeleteOnFetchRejection:f=this.noDeleteOnFetchRejection,allowStaleOnFetchRejection:d=this.allowStaleOnFetchRejection,ignoreFetchAbort:p=this.ignoreFetchAbort,allowStaleOnFetchAbort:F=this.allowStaleOnFetchAbort,context:c,forceRefresh:w=!1,status:l,signal:S}=e;if(!this.#T)return l&&(l.fetch="get"),this.get(t,{allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,status:l});let y={allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,ttl:h,noDisposeOnSet:a,size:r,sizeCalculation:u,noUpdateTTL:b,noDeleteOnFetchRejection:f,allowStaleOnFetchRejection:d,allowStaleOnFetchAbort:F,ignoreFetchAbort:p,status:l,signal:S},g=this.#n.get(t);if(g===void 0){l&&(l.fetch="miss");let _=this.#D(t,g,y,c);return _.__returned=_}else{let _=this.#t[g];if(this.#e(_)){let G=i&&_.__staleWhileFetching!==void 0;return l&&(l.fetch="inflight",G&&(l.returnedStale=!0)),G?_.__staleWhileFetching:_.__returned=_}let O=this.#u(g);if(!w&&!O)return l&&(l.fetch="hit"),this.#v(g),s&&this.#z(g),l&&this.#O(l,g),_;let A=this.#D(t,g,y,c),U=A.__staleWhileFetching!==void 0&&i;return l&&(l.fetch=O?"stale":"refresh",U&&O&&(l.returnedStale=!0)),U?A.__staleWhileFetching:A.__returned=A}}get(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,status:h}=e,a=this.#n.get(t);if(a!==void 0){let r=this.#t[a],u=this.#e(r);return h&&this.#O(h,a),this.#u(a)?(h&&(h.get="stale"),u?(h&&i&&r.__staleWhileFetching!==void 0&&(h.returnedStale=!0),i?r.__staleWhileFetching:void 0):(n||this.delete(t),h&&i&&(h.returnedStale=!0),i?r:void 0)):(h&&(h.get="hit"),u?r.__staleWhileFetching:(this.#v(a),s&&this.#z(a),r))}else h&&(h.get="miss")}#j(t,e){this.#c[e]=t,this.#l[t]=e}#v(t){t!==this.#h&&(t===this.#o?this.#o=this.#l[t]:this.#j(this.#c[t],this.#l[t]),this.#j(this.#h,t),this.#h=t)}delete(t){let e=!1;if(this.#s!==0){let i=this.#n.get(t);if(i!==void 0)if(e=!0,this.#s===1)this.clear();else{this.#E(i);let s=this.#t[i];this.#e(s)?s.__abortController.abort(new Error("deleted")):(this.#b||this.#a)&&(this.#b&&this.#_?.(s,t,"delete"),this.#a&&this.#r?.push([s,t,"delete"])),this.#n.delete(t),this.#i[i]=void 0,this.#t[i]=void 0,i===this.#h?this.#h=this.#c[i]:i===this.#o?this.#o=this.#l[i]:(this.#l[this.#c[i]]=this.#l[i],this.#c[this.#l[i]]=this.#c[i]),this.#s--,this.#w.push(i)}}if(this.#a&&this.#r?.length){let i=this.#r,s;for(;s=i?.shift();)this.#g?.(...s)}return e}clear(){for(let t of this.#A({allowStale:!0})){let e=this.#t[t];if(this.#e(e))e.__abortController.abort(new Error("deleted"));else{let i=this.#i[t];this.#b&&this.#_?.(e,i,"delete"),this.#a&&this.#r?.push([e,i,"delete"])}}if(this.#n.clear(),this.#t.fill(void 0),this.#i.fill(void 0),this.#S&&this.#F&&(this.#S.fill(0),this.#F.fill(0)),this.#m&&this.#m.fill(0),this.#o=0,this.#h=0,this.#w.length=0,this.#p=0,this.#s=0,this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#g?.(...e)}}};exports.LRUCache=C;
-//# sourceMappingURL=index.min.js.map
diff --git a/deps/npm/node_modules/path-scurry/node_modules/lru-cache/dist/mjs/index.min.js b/deps/npm/node_modules/path-scurry/node_modules/lru-cache/dist/mjs/index.min.js
deleted file mode 100644
index 44bd1c23b86e74..00000000000000
--- a/deps/npm/node_modules/path-scurry/node_modules/lru-cache/dist/mjs/index.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-var U=(o,t,e)=>{if(!t.has(o))throw TypeError("Cannot "+e)};var I=(o,t,e)=>(U(o,t,"read from private field"),e?e.call(o):t.get(o)),j=(o,t,e)=>{if(t.has(o))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(o):t.set(o,e)},D=(o,t,e,i)=>(U(o,t,"write to private field"),i?i.call(o,e):t.set(o,e),e);var v=typeof performance=="object"&&performance&&typeof performance.now=="function"?performance:Date,M=new Set,L=typeof process=="object"&&process?process:{},P=(o,t,e,i)=>{typeof L.emitWarning=="function"?L.emitWarning(o,t,e,i):console.error(`[${e}] ${t}: ${o}`)},R=globalThis.AbortController,N=globalThis.AbortSignal;if(typeof R>"u"){N=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(i,s){this._onabort.push(s)}},R=class{constructor(){t()}signal=new N;abort(i){if(!this.signal.aborted){this.signal.reason=i,this.signal.aborted=!0;for(let s of this.signal._onabort)s(i);this.signal.onabort?.(i)}}};let o=L.env?.LRU_CACHE_IGNORE_AC_WARNING!=="1",t=()=>{o&&(o=!1,P("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.","NO_ABORT_CONTROLLER","ENOTSUP",t))}}var V=o=>!M.has(o),Y=Symbol("type"),m=o=>o&&o===Math.floor(o)&&o>0&&isFinite(o),k=o=>m(o)?o<=Math.pow(2,8)?Uint8Array:o<=Math.pow(2,16)?Uint16Array:o<=Math.pow(2,32)?Uint32Array:o<=Number.MAX_SAFE_INTEGER?z:null:null,z=class extends Array{constructor(t){super(t),this.fill(0)}},E,T=class{heap;length;static create(t){let e=k(t);if(!e)return[];D(T,E,!0);let i=new T(t,e);return D(T,E,!1),i}constructor(t,e){if(!I(T,E))throw new TypeError("instantiate Stack using Stack.create(n)");this.heap=new e(t),this.length=0}push(t){this.heap[this.length++]=t}pop(){return this.heap[--this.length]}},C=T;E=new WeakMap,j(C,E,!1);var W=class{#d;#f;#_;#g;#C;ttl;ttlResolution;ttlAutopurge;updateAgeOnGet;updateAgeOnHas;allowStale;noDisposeOnSet;noUpdateTTL;maxEntrySize;sizeCalculation;noDeleteOnFetchRejection;noDeleteOnStaleGet;allowStaleOnFetchAbort;allowStaleOnFetchRejection;ignoreFetchAbort;#s;#p;#n;#i;#t;#l;#c;#o;#h;#w;#r;#m;#F;#S;#b;#T;#a;static unsafeExposeInternals(t){return{starts:t.#F,ttls:t.#S,sizes:t.#m,keyMap:t.#n,keyList:t.#i,valList:t.#t,next:t.#l,prev:t.#c,get head(){return t.#o},get tail(){return t.#h},free:t.#w,isBackgroundFetch:e=>t.#e(e),backgroundFetch:(e,i,s,n)=>t.#D(e,i,s,n),moveToTail:e=>t.#v(e),indexes:e=>t.#y(e),rindexes:e=>t.#A(e),isStale:e=>t.#u(e)}}get max(){return this.#d}get maxSize(){return this.#f}get calculatedSize(){return this.#p}get size(){return this.#s}get fetchMethod(){return this.#C}get dispose(){return this.#_}get disposeAfter(){return this.#g}constructor(t){let{max:e=0,ttl:i,ttlResolution:s=1,ttlAutopurge:n,updateAgeOnGet:h,updateAgeOnHas:a,allowStale:r,dispose:u,disposeAfter:b,noDisposeOnSet:f,noUpdateTTL:d,maxSize:p=0,maxEntrySize:F=0,sizeCalculation:c,fetchMethod:w,noDeleteOnFetchRejection:l,noDeleteOnStaleGet:S,allowStaleOnFetchRejection:y,allowStaleOnFetchAbort:g,ignoreFetchAbort:_}=t;if(e!==0&&!m(e))throw new TypeError("max option must be a nonnegative integer");let O=e?k(e):Array;if(!O)throw new Error("invalid max value: "+e);if(this.#d=e,this.#f=p,this.maxEntrySize=F||this.#f,this.sizeCalculation=c,this.sizeCalculation){if(!this.#f&&!this.maxEntrySize)throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");if(typeof this.sizeCalculation!="function")throw new TypeError("sizeCalculation set to non-function")}if(w!==void 0&&typeof w!="function")throw new TypeError("fetchMethod must be a function if specified");if(this.#C=w,this.#T=!!w,this.#n=new Map,this.#i=new Array(e).fill(void 0),this.#t=new Array(e).fill(void 0),this.#l=new O(e),this.#c=new O(e),this.#o=0,this.#h=0,this.#w=C.create(e),this.#s=0,this.#p=0,typeof u=="function"&&(this.#_=u),typeof b=="function"?(this.#g=b,this.#r=[]):(this.#g=void 0,this.#r=void 0),this.#b=!!this.#_,this.#a=!!this.#g,this.noDisposeOnSet=!!f,this.noUpdateTTL=!!d,this.noDeleteOnFetchRejection=!!l,this.allowStaleOnFetchRejection=!!y,this.allowStaleOnFetchAbort=!!g,this.ignoreFetchAbort=!!_,this.maxEntrySize!==0){if(this.#f!==0&&!m(this.#f))throw new TypeError("maxSize must be a positive integer if specified");if(!m(this.maxEntrySize))throw new TypeError("maxEntrySize must be a positive integer if specified");this.#j()}if(this.allowStale=!!r,this.noDeleteOnStaleGet=!!S,this.updateAgeOnGet=!!h,this.updateAgeOnHas=!!a,this.ttlResolution=m(s)||s===0?s:1,this.ttlAutopurge=!!n,this.ttl=i||0,this.ttl){if(!m(this.ttl))throw new TypeError("ttl must be a positive integer if specified");this.#L()}if(this.#d===0&&this.ttl===0&&this.#f===0)throw new TypeError("At least one of max, maxSize, or ttl is required");if(!this.ttlAutopurge&&!this.#d&&!this.#f){let A="LRU_CACHE_UNBOUNDED";V(A)&&(M.add(A),P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.","UnboundedCacheWarning",A,W))}}getRemainingTTL(t){return this.#n.has(t)?1/0:0}#L(){let t=new z(this.#d),e=new z(this.#d);this.#S=t,this.#F=e,this.#x=(n,h,a=v.now())=>{if(e[n]=h!==0?a:0,t[n]=h,h!==0&&this.ttlAutopurge){let r=setTimeout(()=>{this.#u(n)&&this.delete(this.#i[n])},h+1);r.unref&&r.unref()}},this.#z=n=>{e[n]=t[n]!==0?v.now():0},this.#O=(n,h)=>{if(t[h]){let a=t[h],r=e[h];n.ttl=a,n.start=r,n.now=i||s();let u=n.now-r;n.remainingTTL=a-u}};let i=0,s=()=>{let n=v.now();if(this.ttlResolution>0){i=n;let h=setTimeout(()=>i=0,this.ttlResolution);h.unref&&h.unref()}return n};this.getRemainingTTL=n=>{let h=this.#n.get(n);if(h===void 0)return 0;let a=t[h],r=e[h];if(a===0||r===0)return 1/0;let u=(i||s())-r;return a-u},this.#u=n=>t[n]!==0&&e[n]!==0&&(i||s())-e[n]>t[n]}#z=()=>{};#O=()=>{};#x=()=>{};#u=()=>!1;#j(){let t=new z(this.#d);this.#p=0,this.#m=t,this.#E=e=>{this.#p-=t[e],t[e]=0},this.#G=(e,i,s,n)=>{if(this.#e(i))return 0;if(!m(s))if(n){if(typeof n!="function")throw new TypeError("sizeCalculation must be a function");if(s=n(i,e),!m(s))throw new TypeError("sizeCalculation return invalid (expect positive integer)")}else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");return s},this.#R=(e,i,s)=>{if(t[e]=i,this.#f){let n=this.#f-t[e];for(;this.#p>n;)this.#W(!0)}this.#p+=t[e],s&&(s.entrySize=i,s.totalCalculatedSize=this.#p)}}#E=t=>{};#R=(t,e,i)=>{};#G=(t,e,i,s)=>{if(i||s)throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");return 0};*#y({allowStale:t=this.allowStale}={}){if(this.#s)for(let e=this.#h;!(!this.#U(e)||((t||!this.#u(e))&&(yield e),e===this.#o));)e=this.#c[e]}*#A({allowStale:t=this.allowStale}={}){if(this.#s)for(let e=this.#o;!(!this.#U(e)||((t||!this.#u(e))&&(yield e),e===this.#h));)e=this.#l[e]}#U(t){return t!==void 0&&this.#n.get(this.#i[t])===t}*entries(){for(let t of this.#y())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*rentries(){for(let t of this.#A())this.#t[t]!==void 0&&this.#i[t]!==void 0&&!this.#e(this.#t[t])&&(yield[this.#i[t],this.#t[t]])}*keys(){for(let t of this.#y()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*rkeys(){for(let t of this.#A()){let e=this.#i[t];e!==void 0&&!this.#e(this.#t[t])&&(yield e)}}*values(){for(let t of this.#y())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}*rvalues(){for(let t of this.#A())this.#t[t]!==void 0&&!this.#e(this.#t[t])&&(yield this.#t[t])}[Symbol.iterator](){return this.entries()}find(t,e={}){for(let i of this.#y()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;if(n!==void 0&&t(n,this.#i[i],this))return this.get(this.#i[i],e)}}forEach(t,e=this){for(let i of this.#y()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}rforEach(t,e=this){for(let i of this.#A()){let s=this.#t[i],n=this.#e(s)?s.__staleWhileFetching:s;n!==void 0&&t.call(e,n,this.#i[i],this)}}purgeStale(){let t=!1;for(let e of this.#A({allowStale:!0}))this.#u(e)&&(this.delete(this.#i[e]),t=!0);return t}dump(){let t=[];for(let e of this.#y({allowStale:!0})){let i=this.#i[e],s=this.#t[e],n=this.#e(s)?s.__staleWhileFetching:s;if(n===void 0||i===void 0)continue;let h={value:n};if(this.#S&&this.#F){h.ttl=this.#S[e];let a=v.now()-this.#F[e];h.start=Math.floor(Date.now()-a)}this.#m&&(h.size=this.#m[e]),t.unshift([i,h])}return t}load(t){this.clear();for(let[e,i]of t){if(i.start){let s=Date.now()-i.start;i.start=v.now()-s}this.set(e,i.value,i)}}set(t,e,i={}){if(e===void 0)return this.delete(t),this;let{ttl:s=this.ttl,start:n,noDisposeOnSet:h=this.noDisposeOnSet,sizeCalculation:a=this.sizeCalculation,status:r}=i,{noUpdateTTL:u=this.noUpdateTTL}=i,b=this.#G(t,e,i.size||0,a);if(this.maxEntrySize&&b>this.maxEntrySize)return r&&(r.set="miss",r.maxEntrySizeExceeded=!0),this.delete(t),this;let f=this.#s===0?void 0:this.#n.get(t);if(f===void 0)f=this.#s===0?this.#h:this.#w.length!==0?this.#w.pop():this.#s===this.#d?this.#W(!1):this.#s,this.#i[f]=t,this.#t[f]=e,this.#n.set(t,f),this.#l[this.#h]=f,this.#c[f]=this.#h,this.#h=f,this.#s++,this.#R(f,b,r),r&&(r.set="add"),u=!1;else{this.#v(f);let d=this.#t[f];if(e!==d){if(this.#T&&this.#e(d)?d.__abortController.abort(new Error("replaced")):h||(this.#b&&this.#_?.(d,t,"set"),this.#a&&this.#r?.push([d,t,"set"])),this.#E(f),this.#R(f,b,r),this.#t[f]=e,r){r.set="replace";let p=d&&this.#e(d)?d.__staleWhileFetching:d;p!==void 0&&(r.oldValue=p)}}else r&&(r.set="update")}if(s!==0&&!this.#S&&this.#L(),this.#S&&(u||this.#x(f,s,n),r&&this.#O(r,f)),!h&&this.#a&&this.#r){let d=this.#r,p;for(;p=d?.shift();)this.#g?.(...p)}return this}pop(){try{for(;this.#s;){let t=this.#t[this.#o];if(this.#W(!0),this.#e(t)){if(t.__staleWhileFetching)return t.__staleWhileFetching}else if(t!==void 0)return t}}finally{if(this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#g?.(...e)}}}#W(t){let e=this.#o,i=this.#i[e],s=this.#t[e];return this.#T&&this.#e(s)?s.__abortController.abort(new Error("evicted")):(this.#b||this.#a)&&(this.#b&&this.#_?.(s,i,"evict"),this.#a&&this.#r?.push([s,i,"evict"])),this.#E(e),t&&(this.#i[e]=void 0,this.#t[e]=void 0,this.#w.push(e)),this.#s===1?(this.#o=this.#h=0,this.#w.length=0):this.#o=this.#l[e],this.#n.delete(i),this.#s--,e}has(t,e={}){let{updateAgeOnHas:i=this.updateAgeOnHas,status:s}=e,n=this.#n.get(t);if(n!==void 0){let h=this.#t[n];if(this.#e(h)&&h.__staleWhileFetching===void 0)return!1;if(this.#u(n))s&&(s.has="stale",this.#O(s,n));else return i&&this.#z(n),s&&(s.has="hit",this.#O(s,n)),!0}else s&&(s.has="miss");return!1}peek(t,e={}){let{allowStale:i=this.allowStale}=e,s=this.#n.get(t);if(s!==void 0&&(i||!this.#u(s))){let n=this.#t[s];return this.#e(n)?n.__staleWhileFetching:n}}#D(t,e,i,s){let n=e===void 0?void 0:this.#t[e];if(this.#e(n))return n;let h=new R,{signal:a}=i;a?.addEventListener("abort",()=>h.abort(a.reason),{signal:h.signal});let r={signal:h.signal,options:i,context:s},u=(c,w=!1)=>{let{aborted:l}=h.signal,S=i.ignoreFetchAbort&&c!==void 0;if(i.status&&(l&&!w?(i.status.fetchAborted=!0,i.status.fetchError=h.signal.reason,S&&(i.status.fetchAbortIgnored=!0)):i.status.fetchResolved=!0),l&&!S&&!w)return f(h.signal.reason);let y=p;return this.#t[e]===p&&(c===void 0?y.__staleWhileFetching?this.#t[e]=y.__staleWhileFetching:this.delete(t):(i.status&&(i.status.fetchUpdated=!0),this.set(t,c,r.options))),c},b=c=>(i.status&&(i.status.fetchRejected=!0,i.status.fetchError=c),f(c)),f=c=>{let{aborted:w}=h.signal,l=w&&i.allowStaleOnFetchAbort,S=l||i.allowStaleOnFetchRejection,y=S||i.noDeleteOnFetchRejection,g=p;if(this.#t[e]===p&&(!y||g.__staleWhileFetching===void 0?this.delete(t):l||(this.#t[e]=g.__staleWhileFetching)),S)return i.status&&g.__staleWhileFetching!==void 0&&(i.status.returnedStale=!0),g.__staleWhileFetching;if(g.__returned===g)throw c},d=(c,w)=>{let l=this.#C?.(t,n,r);l&&l instanceof Promise&&l.then(S=>c(S),w),h.signal.addEventListener("abort",()=>{(!i.ignoreFetchAbort||i.allowStaleOnFetchAbort)&&(c(),i.allowStaleOnFetchAbort&&(c=S=>u(S,!0)))})};i.status&&(i.status.fetchDispatched=!0);let p=new Promise(d).then(u,b),F=Object.assign(p,{__abortController:h,__staleWhileFetching:n,__returned:void 0});return e===void 0?(this.set(t,F,{...r.options,status:void 0}),e=this.#n.get(t)):this.#t[e]=F,F}#e(t){if(!this.#T)return!1;let e=t;return!!e&&e instanceof Promise&&e.hasOwnProperty("__staleWhileFetching")&&e.__abortController instanceof R}async fetch(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,ttl:h=this.ttl,noDisposeOnSet:a=this.noDisposeOnSet,size:r=0,sizeCalculation:u=this.sizeCalculation,noUpdateTTL:b=this.noUpdateTTL,noDeleteOnFetchRejection:f=this.noDeleteOnFetchRejection,allowStaleOnFetchRejection:d=this.allowStaleOnFetchRejection,ignoreFetchAbort:p=this.ignoreFetchAbort,allowStaleOnFetchAbort:F=this.allowStaleOnFetchAbort,context:c,forceRefresh:w=!1,status:l,signal:S}=e;if(!this.#T)return l&&(l.fetch="get"),this.get(t,{allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,status:l});let y={allowStale:i,updateAgeOnGet:s,noDeleteOnStaleGet:n,ttl:h,noDisposeOnSet:a,size:r,sizeCalculation:u,noUpdateTTL:b,noDeleteOnFetchRejection:f,allowStaleOnFetchRejection:d,allowStaleOnFetchAbort:F,ignoreFetchAbort:p,status:l,signal:S},g=this.#n.get(t);if(g===void 0){l&&(l.fetch="miss");let _=this.#D(t,g,y,c);return _.__returned=_}else{let _=this.#t[g];if(this.#e(_)){let G=i&&_.__staleWhileFetching!==void 0;return l&&(l.fetch="inflight",G&&(l.returnedStale=!0)),G?_.__staleWhileFetching:_.__returned=_}let O=this.#u(g);if(!w&&!O)return l&&(l.fetch="hit"),this.#v(g),s&&this.#z(g),l&&this.#O(l,g),_;let A=this.#D(t,g,y,c),x=A.__staleWhileFetching!==void 0&&i;return l&&(l.fetch=O?"stale":"refresh",x&&O&&(l.returnedStale=!0)),x?A.__staleWhileFetching:A.__returned=A}}get(t,e={}){let{allowStale:i=this.allowStale,updateAgeOnGet:s=this.updateAgeOnGet,noDeleteOnStaleGet:n=this.noDeleteOnStaleGet,status:h}=e,a=this.#n.get(t);if(a!==void 0){let r=this.#t[a],u=this.#e(r);return h&&this.#O(h,a),this.#u(a)?(h&&(h.get="stale"),u?(h&&i&&r.__staleWhileFetching!==void 0&&(h.returnedStale=!0),i?r.__staleWhileFetching:void 0):(n||this.delete(t),h&&i&&(h.returnedStale=!0),i?r:void 0)):(h&&(h.get="hit"),u?r.__staleWhileFetching:(this.#v(a),s&&this.#z(a),r))}else h&&(h.get="miss")}#I(t,e){this.#c[e]=t,this.#l[t]=e}#v(t){t!==this.#h&&(t===this.#o?this.#o=this.#l[t]:this.#I(this.#c[t],this.#l[t]),this.#I(this.#h,t),this.#h=t)}delete(t){let e=!1;if(this.#s!==0){let i=this.#n.get(t);if(i!==void 0)if(e=!0,this.#s===1)this.clear();else{this.#E(i);let s=this.#t[i];this.#e(s)?s.__abortController.abort(new Error("deleted")):(this.#b||this.#a)&&(this.#b&&this.#_?.(s,t,"delete"),this.#a&&this.#r?.push([s,t,"delete"])),this.#n.delete(t),this.#i[i]=void 0,this.#t[i]=void 0,i===this.#h?this.#h=this.#c[i]:i===this.#o?this.#o=this.#l[i]:(this.#l[this.#c[i]]=this.#l[i],this.#c[this.#l[i]]=this.#c[i]),this.#s--,this.#w.push(i)}}if(this.#a&&this.#r?.length){let i=this.#r,s;for(;s=i?.shift();)this.#g?.(...s)}return e}clear(){for(let t of this.#A({allowStale:!0})){let e=this.#t[t];if(this.#e(e))e.__abortController.abort(new Error("deleted"));else{let i=this.#i[t];this.#b&&this.#_?.(e,i,"delete"),this.#a&&this.#r?.push([e,i,"delete"])}}if(this.#n.clear(),this.#t.fill(void 0),this.#i.fill(void 0),this.#S&&this.#F&&(this.#S.fill(0),this.#F.fill(0)),this.#m&&this.#m.fill(0),this.#o=0,this.#h=0,this.#w.length=0,this.#p=0,this.#s=0,this.#a&&this.#r){let t=this.#r,e;for(;e=t?.shift();)this.#g?.(...e)}}};export{W as LRUCache};
-//# sourceMappingURL=index.min.js.map
diff --git a/deps/npm/node_modules/path-scurry/package.json b/deps/npm/node_modules/path-scurry/package.json
index 5b900825e44e00..af04f807fed2bc 100644
--- a/deps/npm/node_modules/path-scurry/package.json
+++ b/deps/npm/node_modules/path-scurry/package.json
@@ -1,6 +1,6 @@
 {
   "name": "path-scurry",
-  "version": "1.9.2",
+  "version": "1.10.1",
   "description": "walk paths fast and efficiently",
   "author": "Isaac Z. Schlueter  (https://blog.izs.me)",
   "main": "./dist/cjs/index.js",
@@ -64,7 +64,7 @@
     "eslint-config-prettier": "^8.6.0",
     "mkdirp": "^3.0.0",
     "prettier": "^2.8.3",
-    "rimraf": "^4.1.2",
+    "rimraf": "^5.0.1",
     "tap": "^16.3.4",
     "ts-node": "^10.9.1",
     "typedoc": "^0.23.24",
@@ -78,10 +78,10 @@
   },
   "repository": {
     "type": "git",
-    "url": "git+https://github.com/isaacs/path-walker"
+    "url": "git+https://github.com/isaacs/path-scurry"
   },
   "dependencies": {
-    "lru-cache": "^9.1.1",
-    "minipass": "^5.0.0 || ^6.0.2"
+    "lru-cache": "^9.1.1 || ^10.0.0",
+    "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
   }
 }
diff --git a/deps/npm/node_modules/read-package-json/package.json b/deps/npm/node_modules/read-package-json/package.json
index 90ab321d51743e..01061f2bc27921 100644
--- a/deps/npm/node_modules/read-package-json/package.json
+++ b/deps/npm/node_modules/read-package-json/package.json
@@ -1,6 +1,6 @@
 {
   "name": "read-package-json",
-  "version": "6.0.4",
+  "version": "7.0.0",
   "author": "GitHub Inc.",
   "description": "The thing npm uses to read package.json files with semantics and defaults and validation",
   "repository": {
@@ -25,12 +25,12 @@
   "dependencies": {
     "glob": "^10.2.2",
     "json-parse-even-better-errors": "^3.0.0",
-    "normalize-package-data": "^5.0.0",
+    "normalize-package-data": "^6.0.0",
     "npm-normalize-package-bin": "^3.0.0"
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.15.1",
+    "@npmcli/template-oss": "4.18.0",
     "tap": "^16.0.1"
   },
   "license": "ISC",
@@ -39,7 +39,7 @@
     "lib/"
   ],
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   },
   "tap": {
     "branches": 73,
@@ -53,7 +53,13 @@
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.15.1",
-    "publish": "true"
+    "version": "4.18.0",
+    "publish": "true",
+    "ciVersions": [
+      "16.14.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ]
   }
 }
diff --git a/deps/npm/node_modules/semver/README.md b/deps/npm/node_modules/semver/README.md
index 33c762cb225dcb..043bdaed6b5fc3 100644
--- a/deps/npm/node_modules/semver/README.md
+++ b/deps/npm/node_modules/semver/README.md
@@ -159,7 +159,9 @@ of primitive `operators` is:
 
 For example, the comparator `>=1.2.7` would match the versions
 `1.2.7`, `1.2.8`, `2.5.3`, and `1.3.9`, but not the versions `1.2.6`
-or `1.1.0`.
+or `1.1.0`. The comparator `>1` is equivalent to `>=2.0.0` and
+would match the versions `2.0.0` and `3.1.0`, but not the versions
+`1.0.1` or `1.1.0`.
 
 Comparators can be joined by whitespace to form a `comparator set`,
 which is satisfied by the **intersection** of all of the comparators
diff --git a/deps/npm/node_modules/semver/classes/range.js b/deps/npm/node_modules/semver/classes/range.js
index 53c2540fd012ef..7e7c41410cbfdd 100644
--- a/deps/npm/node_modules/semver/classes/range.js
+++ b/deps/npm/node_modules/semver/classes/range.js
@@ -38,7 +38,7 @@ class Range {
     this.set = this.raw
       .split('||')
       // map the range to a 2d array of comparators
-      .map(r => this.parseRange(r))
+      .map(r => this.parseRange(r.trim()))
       // throw out any comparator lists that are empty
       // this generally means that it was not a valid range, which is allowed
       // in loose mode, but will still throw if the WHOLE range is invalid.
@@ -98,15 +98,18 @@ class Range {
     const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE]
     range = range.replace(hr, hyphenReplace(this.options.includePrerelease))
     debug('hyphen replace', range)
+
     // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
     range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
     debug('comparator trim', range)
 
     // `~ 1.2.3` => `~1.2.3`
     range = range.replace(re[t.TILDETRIM], tildeTrimReplace)
+    debug('tilde trim', range)
 
     // `^ 1.2.3` => `^1.2.3`
     range = range.replace(re[t.CARETTRIM], caretTrimReplace)
+    debug('caret trim', range)
 
     // At this point, the range is completely trimmed and
     // ready to be split into comparators.
diff --git a/deps/npm/node_modules/semver/internal/constants.js b/deps/npm/node_modules/semver/internal/constants.js
index 25fab1ea01233b..94be1c570277a5 100644
--- a/deps/npm/node_modules/semver/internal/constants.js
+++ b/deps/npm/node_modules/semver/internal/constants.js
@@ -9,6 +9,10 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
 // Max safe segment length for coercion.
 const MAX_SAFE_COMPONENT_LENGTH = 16
 
+// Max safe length for a build identifier. The max length minus 6 characters for
+// the shortest version with a build 0.0.0+BUILD.
+const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6
+
 const RELEASE_TYPES = [
   'major',
   'premajor',
@@ -22,6 +26,7 @@ const RELEASE_TYPES = [
 module.exports = {
   MAX_LENGTH,
   MAX_SAFE_COMPONENT_LENGTH,
+  MAX_SAFE_BUILD_LENGTH,
   MAX_SAFE_INTEGER,
   RELEASE_TYPES,
   SEMVER_SPEC_VERSION,
diff --git a/deps/npm/node_modules/semver/internal/re.js b/deps/npm/node_modules/semver/internal/re.js
index f73ef1aa06263a..21150b3ec53b7d 100644
--- a/deps/npm/node_modules/semver/internal/re.js
+++ b/deps/npm/node_modules/semver/internal/re.js
@@ -1,4 +1,8 @@
-const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants')
+const {
+  MAX_SAFE_COMPONENT_LENGTH,
+  MAX_SAFE_BUILD_LENGTH,
+  MAX_LENGTH,
+} = require('./constants')
 const debug = require('./debug')
 exports = module.exports = {}
 
@@ -9,16 +13,31 @@ const src = exports.src = []
 const t = exports.t = {}
 let R = 0
 
+const LETTERDASHNUMBER = '[a-zA-Z0-9-]'
+
+// Replace some greedy regex tokens to prevent regex dos issues. These regex are
+// used internally via the safeRe object since all inputs in this library get
+// normalized first to trim and collapse all extra whitespace. The original
+// regexes are exported for userland consumption and lower level usage. A
+// future breaking change could export the safer regex only with a note that
+// all input should have extra whitespace removed.
+const safeRegexReplacements = [
+  ['\\s', 1],
+  ['\\d', MAX_LENGTH],
+  [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
+]
+
+const makeSafeRegex = (value) => {
+  for (const [token, max] of safeRegexReplacements) {
+    value = value
+      .split(`${token}*`).join(`${token}{0,${max}}`)
+      .split(`${token}+`).join(`${token}{1,${max}}`)
+  }
+  return value
+}
+
 const createToken = (name, value, isGlobal) => {
-  // Replace all greedy whitespace to prevent regex dos issues. These regex are
-  // used internally via the safeRe object since all inputs in this library get
-  // normalized first to trim and collapse all extra whitespace. The original
-  // regexes are exported for userland consumption and lower level usage. A
-  // future breaking change could export the safer regex only with a note that
-  // all input should have extra whitespace removed.
-  const safe = value
-    .split('\\s*').join('\\s{0,1}')
-    .split('\\s+').join('\\s')
+  const safe = makeSafeRegex(value)
   const index = R++
   debug(name, index, value)
   t[name] = index
@@ -34,13 +53,13 @@ const createToken = (name, value, isGlobal) => {
 // A single `0`, or a non-zero digit followed by zero or more digits.
 
 createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*')
-createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+')
+createToken('NUMERICIDENTIFIERLOOSE', '\\d+')
 
 // ## Non-numeric Identifier
 // Zero or more digits, followed by a letter or hyphen, and then zero or
 // more letters, digits, or hyphens.
 
-createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*')
+createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`)
 
 // ## Main Version
 // Three dot-separated numeric identifiers.
@@ -75,7 +94,7 @@ createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
 // ## Build Metadata Identifier
 // Any combination of digits, letters, or hyphens.
 
-createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+')
+createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`)
 
 // ## Build Metadata
 // Plus sign, followed by one or more period-separated build metadata
diff --git a/deps/npm/node_modules/semver/package.json b/deps/npm/node_modules/semver/package.json
index 7d0aff3c03c270..c145eca2f6d125 100644
--- a/deps/npm/node_modules/semver/package.json
+++ b/deps/npm/node_modules/semver/package.json
@@ -1,6 +1,6 @@
 {
   "name": "semver",
-  "version": "7.5.2",
+  "version": "7.5.4",
   "description": "The semantic version parser used by npm.",
   "main": "index.js",
   "scripts": {
@@ -14,7 +14,7 @@
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.15.1",
+    "@npmcli/template-oss": "4.17.0",
     "tap": "^16.0.0"
   },
   "license": "ISC",
@@ -53,7 +53,7 @@
   "author": "GitHub Inc.",
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.15.1",
+    "version": "4.17.0",
     "engines": ">=10",
     "ciVersions": [
       "10.0.0",
diff --git a/deps/npm/node_modules/sigstore/README.md b/deps/npm/node_modules/sigstore/README.md
deleted file mode 100644
index 2540fa808b9796..00000000000000
--- a/deps/npm/node_modules/sigstore/README.md
+++ /dev/null
@@ -1,165 +0,0 @@
-# sigstore · [![npm version](https://img.shields.io/npm/v/sigstore.svg?style=flat)](https://www.npmjs.com/package/sigstore) [![CI Status](https://github.com/sigstore/sigstore-js/workflows/CI/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/ci.yml) [![Smoke Test Status](https://github.com/sigstore/sigstore-js/workflows/smoke-test/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/smoke-test.yml)
-
-A JavaScript library for generating and verifying Sigstore signatures. One of
-the intended uses is to sign and verify npm packages but it can be used to sign
-and verify any file.
-
-## Features
-
-* Support for signing using an OpenID Connect identity
-* Support for publishing signatures to a [Rekor][1] instance
-* Support for verifying Sigstore bundles
-
-## Prerequisites
-
-- Node.js version >= 14.17.0
-
-## Installation
-
-```
-npm install sigstore
-```
-
-## Usage
-
-```javascript
-const { sigstore } = require('sigstore')
-```
-
-```javascript
-import { sigstore } from 'sigstore'
-```
-
-### sign(payload[, options])
-
-Generates a Sigstore signature for the supplied payload. Returns a
-[Sigstore bundle][2] containing the signature and the verification material
-necessary to verify the signature.
-
-* `payload` ``: The bytes of the artifact to be signed.
-* `options` ``
-  * `fulcioURL` ``: The base URL of the Fulcio instance to use for retrieving the signing certificate. Defaults to `'https://fulcio.sigstore.dev'`.
-  * `rekorURL` ``: The base URL of the Rekor instance to use when adding the signature to the transparency log. Defaults to `'https://rekor.sigstore.dev'`.
-  * `tsaServerURL` ``: The base URL of the Timestamp Authority instance to use when requesting a signed timestamp. If omitted, no timestamp will be requested.
-  * `tlogUpload` ``: Flag indicating whether or not the signature should be recorded on the Rekor transparency log. Defaults to `true`.
-  * `identityToken` ``: The OIDC token identifying the signer. If no explicit token is supplied, an attempt will be made to retrieve one from the environment. This config cannot be used with `identityProvider`.
-  * `identityProvider` ``: Object which implements `getToken: () => Promise`. The supplied provider will be used to retrieve an OIDC token. If no provider is supplied, an attempt will be made to retrieve an OIDC token from the environment. This config cannot be used with `identityToken`.
-
-### attest(payload, payloadType[, options])
-
-Generates a Sigstore signature for the supplied in-toto statement. Returns a
-[Sigstore bundle][2] containing the [DSSE][3]-wrapped statement and signature
-as well as the verification material necessary to verify the signature.
-
-* `payload` ``: The bytes of the statement to be signed.
-* `payloadType` ``: MIME or content type describing the statement to be signed.
-* `options` ``
-  * `fulcioURL` ``: The base URL of the Fulcio instance to use for retrieving the signing certificate. Defaults to `'https://fulcio.sigstore.dev'`.
-  * `rekorURL` ``: The base URL of the Rekor instance to use when adding the signature to the transparency log. Defaults to `'https://rekor.sigstore.dev'`.
-  * `tsaServerURL` ``: The base URL of the Timestamp Authority instance to use when requesting a signed timestamp. If omitted, no timestamp will be requested.
-  * `tlogUpload` ``: Flag indicating whether or not the signed statement should be recorded on the Rekor transparency log. Defaults to `true`.
-  * `identityToken` ``: The OIDC token identifying the signer. If no explicit token is supplied, an attempt will be made to retrieve one from the environment. This config cannot be used with `identityProvider`.
-  * `identityProvider` ``: Object which implements `getToken: () => Promise`. The supplied provider will be used to retrieve an OIDC token. If no provider is supplied, an attempt will be made to retrieve an OIDC token from the environment. This config cannot be used with `identityToken`.
-
-
-### verify(bundle[, payload][, options])
-
-Verifies the signature in the supplied bundle.
-
-* `bundle` ``: The Sigstore bundle containing the signature to be verified and the verification material necessary to verify the signature.
-* `payload` ``: The bytes of the artifact over which the signature was created. Only necessary when the `sign` function was used to generate the signature since the Bundle does not contain any information about the artifact which was signed. Not required when the `attest` function was used to generate the Bundle.
-* `options` ``
-  * `ctLogThreshold` ``: The number of certificate transparency logs on which the signing certificate must appear. Defaults to `1`.
-  * `tlogThreshold` ``: The number of transparency logs on which the signature must appear. Defaults to `1`.
-  * `certificateIssuer` ``: Value that must appear in the signing certificate's issuer extension (OID 1.3.6.1.4.1.57264.1.1). Not verified if no value is supplied.
-  * `certificateIdentityEmail` ``: Email address which must appear in the signing certificate's Subject Alternative Name (SAN) extension. Must be specified in conjunction with the `certificateIssuer` option. Takes precedence over the `certificateIdentityURI` option. Not verified if no value is supplied.
-  * `certificateIdentityURI` ``: URI which must appear in the signing certificate's Subject Alternative Name (SAN) extension. Must be specified in conjunction with the `certificateIssuer` option. Ignored if the `certificateIdentityEmail` option is set. Not verified if no value is supplied.
-  * `certificateOIDs` ``: A collection of OID/value pairs which must be present in the certificate's extension list. Not verified if no value is supplied.
-  * `keySelector` ``: Callback invoked to retrieve the public key (as either `string` or `Buffer`) necessary to verify the bundle signature. Not used when the signature was generated from a Fulcio-issued signing certificate.
-    * `hint` ``: The hint from the bundle used to identify the the signing key.
-
-### tuf
-
-The `tuf` object contains utility function for working with the Sigstore TUF repository.
-
-#### client([options])
-
-Returns a TUF client which can be used to retrieve targets from the Sigstore TUF repository.
-
-* `options` ``
-  * `tufMirrorURL` ``: Base URL for the Sigstore TUF repository. Defaults to `'https://tuf-repo-cdn.sigstore.dev'`
-  * `tufRootPath` ``: Path to the initial trusted root for the TUF repository. Defaults to the embedded root.
-  * `tufCachePath` ``: Absolute path to the directory to be used for caching downloaded TUF metadata and targets. Defaults to a directory named "sigstore-js" within the platform-specific application data directory.
-
-The returned object exposes a `getTarget(path)` function which returns the
-contents of the target at the specified path in the Sigstore TUF repository.
-
-#### getTarget(path[, options]) (deprecated)
-
-Returns the contents of the target at the specified path in the Sigstore TUF repository.
-This method has been deprecated and will be removed in the next major version.
-You should use the TUF `client` function to retrieve a stateful TUF client and
-then call `getTarget` against that object. This will avoid re-initializing the
-internal TUF state between requests.
-
-* `path` ``: The [path-relative-url string](https://url.spec.whatwg.org/#path-relative-url-string) that uniquely identifies the target within the Sigstore TUF repository.
-* `options` ``
-  * `tufMirrorURL` ``: Base URL for the Sigstore TUF repository. Defaults to `'https://tuf-repo-cdn.sigstore.dev'`
-  * `tufRootPath` ``: Path to the initial trusted root for the TUF repository. Defaults to the embedded root.
-  * `tufCachePath` ``: Absolute path to the directory to be used for caching downloaded TUF metadata and targets. Defaults to a directory named "sigstore-js" within the platform-specific application data directory.
-
-
-### utils
-
-The `utils` object contains a few internal utility functions. These are exposed
-to support the needs of specific `sigstore-js` consumers but should **NOT** be
-considered part of the stable public interface.
-
-## CLI
-
-The `sigstore-js` library comes packaged with a basic command line interface
-for testing and demo purposes. However, the CLI should **NOT** be considered
-part of the stable interface of the library. If you require a production-ready
-Sigstore CLI, we recommend you use [`cosign`][4].
-
-```shell
-$ npx sigstore help
-sigstore  
-
-  Usage:
-
-  sigstore sign         sign an artifact
-  sigstore attest       sign an artifact using dsse (Dead Simple Signing Envelope)
-  sigstore verify       verify an artifact
-  sigstore version      print version information
-  sigstore help         print help information
-```
-
-## Credential Sources
-
-### GitHub Actions
-
-If sigstore-js detects that it is being executed on GitHub Actions, it will use `ACTIONS_ID_TOKEN_REQUEST_URL`
-and `ACTIONS_ID_TOKEN_REQUEST_TOKEN` environment variables to request an OIDC token with the correct scope.
-
-Note: the `id_token: write` permission must be granted to the GitHub Action Job.
-
-See https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
-for more details.
-
-### Environment Variables
-
-If the `SIGSTORE_ID_TOKEN` environment variable is set, it will use this to authenticate to Fulcio.
-It is the callers responsibility to make sure that this token has the correct scopes.
-
-### Interactive Flow
-
-If sigstore-js cannot detect ambient credentials, then it will prompt the user to go through the
-interactive flow.
-
-
-
-[1]: https://github.com/sigstore/rekor
-[2]: https://github.com/sigstore/protobuf-specs/blob/9b722b68a717778ba4f11543afa4ef93205ab502/protos/sigstore_bundle.proto#L63-L84
-[3]: https://github.com/secure-systems-lab/dsse
-[4]: https://github.com/sigstore/cosign
diff --git a/deps/npm/node_modules/sigstore/dist/ca/format.d.ts b/deps/npm/node_modules/sigstore/dist/ca/format.d.ts
deleted file mode 100644
index b29f51a71f5647..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/format.d.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-/// 
-/// 
-import { KeyObject } from 'crypto';
-import type { SigningCertificateRequest } from '../external/fulcio';
-export declare function toCertificateRequest(identityToken: string, publicKey: KeyObject, challenge: Buffer): SigningCertificateRequest;
diff --git a/deps/npm/node_modules/sigstore/dist/ca/format.js b/deps/npm/node_modules/sigstore/dist/ca/format.js
deleted file mode 100644
index 6374243e80e026..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/format.js
+++ /dev/null
@@ -1,20 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.toCertificateRequest = void 0;
-function toCertificateRequest(identityToken, publicKey, challenge) {
-    return {
-        credentials: {
-            oidcIdentityToken: identityToken,
-        },
-        publicKeyRequest: {
-            publicKey: {
-                algorithm: 'ECDSA',
-                content: publicKey
-                    .export({ format: 'pem', type: 'spki' })
-                    .toString('ascii'),
-            },
-            proofOfPossession: challenge.toString('base64'),
-        },
-    };
-}
-exports.toCertificateRequest = toCertificateRequest;
diff --git a/deps/npm/node_modules/sigstore/dist/ca/index.d.ts b/deps/npm/node_modules/sigstore/dist/ca/index.d.ts
deleted file mode 100644
index 3a6347293aaa8b..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/index.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/// 
-/// 
-import { KeyObject } from 'crypto';
-import type { FetchOptions } from '../types/fetch';
-export interface CA {
-    createSigningCertificate: (identityToken: string, publicKey: KeyObject, challenge: Buffer) => Promise;
-}
-export type CAClientOptions = {
-    fulcioBaseURL: string;
-} & FetchOptions;
-export declare class CAClient implements CA {
-    private fulcio;
-    constructor(options: CAClientOptions);
-    createSigningCertificate(identityToken: string, publicKey: KeyObject, challenge: Buffer): Promise;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/ca/index.js b/deps/npm/node_modules/sigstore/dist/ca/index.js
deleted file mode 100644
index 340dd46609aad2..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.CAClient = void 0;
-const error_1 = require("../error");
-const external_1 = require("../external");
-const format_1 = require("./format");
-class CAClient {
-    constructor(options) {
-        this.fulcio = new external_1.Fulcio({
-            baseURL: options.fulcioBaseURL,
-            retry: options.retry,
-            timeout: options.timeout,
-        });
-    }
-    async createSigningCertificate(identityToken, publicKey, challenge) {
-        const request = (0, format_1.toCertificateRequest)(identityToken, publicKey, challenge);
-        try {
-            const resp = await this.fulcio.createSigningCertificate(request);
-            // Account for the fact that the response may contain either a
-            // signedCertificateEmbeddedSct or a signedCertificateDetachedSct.
-            const cert = resp.signedCertificateEmbeddedSct
-                ? resp.signedCertificateEmbeddedSct
-                : resp.signedCertificateDetachedSct;
-            // Return the first certificate in the chain, which is the signing
-            // certificate. Specifically not returning the rest of the chain to
-            // mitigate the risk of errors when verifying the certificate chain.
-            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-            return cert.chain.certificates.slice(0, 1);
-        }
-        catch (err) {
-            throw new error_1.InternalError({
-                code: 'CA_CREATE_SIGNING_CERTIFICATE_ERROR',
-                message: 'error creating signing certificate',
-                cause: err,
-            });
-        }
-    }
-}
-exports.CAClient = CAClient;
diff --git a/deps/npm/node_modules/sigstore/dist/ca/verify/chain.d.ts b/deps/npm/node_modules/sigstore/dist/ca/verify/chain.d.ts
deleted file mode 100644
index 0a79b42f714a0f..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/verify/chain.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-import { x509Certificate } from '../../x509/cert';
-export declare function verifyChain(certificate: sigstore.X509Certificate, certificateAuthorities: sigstore.CertificateAuthority[]): x509Certificate[];
diff --git a/deps/npm/node_modules/sigstore/dist/ca/verify/index.d.ts b/deps/npm/node_modules/sigstore/dist/ca/verify/index.d.ts
deleted file mode 100644
index ddf65ff6dfffd8..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/verify/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-export declare function verifySigningCertificate(bundle: sigstore.BundleWithCertificateChain, trustedRoot: sigstore.TrustedRoot, options: sigstore.CAArtifactVerificationOptions): void;
diff --git a/deps/npm/node_modules/sigstore/dist/ca/verify/sct.d.ts b/deps/npm/node_modules/sigstore/dist/ca/verify/sct.d.ts
deleted file mode 100644
index 29391a74cb65e6..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/verify/sct.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-import { x509Certificate } from '../../x509/cert';
-export declare function verifySCTs(certificateChain: x509Certificate[], ctLogs: sigstore.TransparencyLogInstance[], options: sigstore.ArtifactVerificationOptions_CtlogOptions): void;
diff --git a/deps/npm/node_modules/sigstore/dist/ca/verify/signer.d.ts b/deps/npm/node_modules/sigstore/dist/ca/verify/signer.d.ts
deleted file mode 100644
index 7241b90f6ac5c8..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/ca/verify/signer.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-import { x509Certificate } from '../../x509/cert';
-export declare function verifySignerIdentity(signingCert: x509Certificate, identities: sigstore.CertificateIdentities): void;
diff --git a/deps/npm/node_modules/sigstore/dist/ca/verify/signer.js b/deps/npm/node_modules/sigstore/dist/ca/verify/signer.js
index 51d722d7631ee0..6f47651b944c94 100644
--- a/deps/npm/node_modules/sigstore/dist/ca/verify/signer.js
+++ b/deps/npm/node_modules/sigstore/dist/ca/verify/signer.js
@@ -54,7 +54,10 @@ function verifySignerIdentity(signingCert, identities) {
     // specified identities
     const signerVerified = identities.identities.some((identity) => verifyIdentity(signingCert, identity));
     if (!signerVerified) {
-        throw new error_1.PolicyError('Certificate issued to untrusted signer');
+        throw new error_1.PolicyError({
+            code: 'UNTRUSTED_SIGNER_ERROR',
+            message: 'Certificate issued to untrusted signer',
+        });
     }
 }
 exports.verifySignerIdentity = verifySignerIdentity;
diff --git a/deps/npm/node_modules/sigstore/dist/cli/index.d.ts b/deps/npm/node_modules/sigstore/dist/cli/index.d.ts
deleted file mode 100644
index 395f0a5a69d304..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/cli/index.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export declare function processArgv(): Promise;
diff --git a/deps/npm/node_modules/sigstore/dist/cli/index.js b/deps/npm/node_modules/sigstore/dist/cli/index.js
deleted file mode 100644
index 6015cd9df74eac..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/cli/index.js
+++ /dev/null
@@ -1,125 +0,0 @@
-"use strict";
-var __importDefault = (this && this.__importDefault) || function (mod) {
-    return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.processArgv = void 0;
-/*
-Copyright 2022 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-const fs_1 = __importDefault(require("fs"));
-const index_1 = require("../index");
-const INTOTO_PAYLOAD_TYPE = 'application/vnd.in-toto+json';
-async function cli(args) {
-    switch (args[0]) {
-        case 'sign':
-            await sign(args[1]);
-            break;
-        case 'attest':
-            await attest(args[1], args[2]);
-            break;
-        case 'verify':
-            await verify(args[1], args[2]);
-            break;
-        case 'version':
-        case '-version':
-        case '--version':
-        case '-v':
-            // eslint-disable-next-line @typescript-eslint/no-var-requires
-            console.log(require('../../package.json').version);
-            break;
-        case 'help':
-        case '--help':
-        case '-h':
-        case '-?':
-            printUsage();
-            break;
-        default:
-            throw 'Unknown command';
-    }
-}
-function printUsage() {
-    console.log(`sigstore  
-
-  Usage:
-
-  sigstore sign         sign an artifact
-  sigstore attest       sign an artifact using dsse (Dead Simple Signing Envelope)
-  sigstore verify       verify an artifact
-  sigstore version      print version information
-  sigstore help         print help information
-  `);
-}
-function printRekorEntry(bundle, options) {
-    let url;
-    if (options.rekorURL === index_1.sigstore.DEFAULT_REKOR_URL) {
-        url = `https://search.sigstore.dev`;
-    }
-    else {
-        url = `${options.rekorURL}/api/v1/log/entries`;
-    }
-    const logIndex = bundle.verificationMaterial?.tlogEntries[0].logIndex;
-    console.error(`Created entry at index ${logIndex}, available at`);
-    console.error(`${url}?logIndex=${logIndex}`);
-}
-// TODO: Allow customing these options
-const signOptions = {
-    oidcClientID: 'sigstore',
-    oidcIssuer: 'https://oauth2.sigstore.dev/auth',
-    oidcRedirectURL: process.env.OIDC_REDIRECT_URL,
-    rekorURL: index_1.sigstore.DEFAULT_REKOR_URL,
-};
-async function sign(artifactPath) {
-    const buffer = fs_1.default.readFileSync(artifactPath);
-    const bundle = await index_1.sigstore.sign(buffer, signOptions);
-    printRekorEntry(bundle, signOptions);
-    console.log(JSON.stringify(bundle));
-}
-async function attest(artifactPath, payloadType = INTOTO_PAYLOAD_TYPE) {
-    const buffer = fs_1.default.readFileSync(artifactPath);
-    const bundle = await index_1.sigstore.attest(buffer, payloadType, signOptions);
-    printRekorEntry(bundle, signOptions);
-    console.log(JSON.stringify(bundle));
-}
-async function verify(bundlePath, artifactPath) {
-    let payload = undefined;
-    if (artifactPath) {
-        payload = fs_1.default.readFileSync(artifactPath);
-    }
-    const bundleFile = fs_1.default.readFileSync(bundlePath);
-    const bundle = JSON.parse(bundleFile.toString('utf-8'));
-    try {
-        await index_1.sigstore.verify(bundle, payload, {});
-        console.error('Verified OK');
-    }
-    catch (e) {
-        console.error('Verification failed');
-        if (e instanceof Error) {
-            console.error('Error: ' + e.message);
-        }
-        process.exit(1);
-    }
-}
-async function processArgv() {
-    try {
-        await cli(process.argv.slice(2));
-        process.exit(0);
-    }
-    catch (e) {
-        console.error(e);
-        process.exit(1);
-    }
-}
-exports.processArgv = processArgv;
diff --git a/deps/npm/node_modules/sigstore/dist/config.d.ts b/deps/npm/node_modules/sigstore/dist/config.d.ts
deleted file mode 100644
index 89f42038099530..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/config.d.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { CA } from './ca';
-import { Provider } from './identity';
-import { TLog } from './tlog';
-import { TSA } from './tsa';
-import * as sigstore from './types/sigstore';
-import type { FetchOptions, Retry } from './types/fetch';
-import type { KeySelector } from './verify';
-interface CAOptions {
-    fulcioURL?: string;
-}
-interface TLogOptions {
-    rekorURL?: string;
-}
-interface TSAOptions {
-    tsaServerURL?: string;
-}
-export interface IdentityProviderOptions {
-    identityToken?: string;
-    oidcIssuer?: string;
-    oidcClientID?: string;
-    oidcClientSecret?: string;
-    oidcRedirectURL?: string;
-}
-export type TUFOptions = {
-    tufMirrorURL?: string;
-    tufRootPath?: string;
-    tufCachePath?: string;
-} & FetchOptions;
-export type SignOptions = {
-    identityProvider?: Provider;
-    tlogUpload?: boolean;
-} & CAOptions & TLogOptions & TSAOptions & FetchOptions & IdentityProviderOptions;
-export type VerifyOptions = {
-    ctLogThreshold?: number;
-    tlogThreshold?: number;
-    certificateIssuer?: string;
-    certificateIdentityEmail?: string;
-    certificateIdentityURI?: string;
-    certificateOIDs?: Record;
-    keySelector?: KeySelector;
-} & TLogOptions & TUFOptions;
-export type CreateVerifierOptions = {
-    keySelector?: KeySelector;
-} & TUFOptions;
-export declare const DEFAULT_FULCIO_URL = "https://fulcio.sigstore.dev";
-export declare const DEFAULT_REKOR_URL = "https://rekor.sigstore.dev";
-export declare const DEFAULT_RETRY: Retry;
-export declare const DEFAULT_TIMEOUT = 5000;
-export declare function createCAClient(options: CAOptions & FetchOptions): CA;
-export declare function createTLogClient(options: TLogOptions & FetchOptions): TLog;
-export declare function createTSAClient(options: TSAOptions & FetchOptions): TSA | undefined;
-export declare function artifactVerificationOptions(options: VerifyOptions): sigstore.RequiredArtifactVerificationOptions;
-export declare function identityProviders(options: IdentityProviderOptions): Provider[];
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/config.js b/deps/npm/node_modules/sigstore/dist/config.js
index 1a22c5fef313b7..43c236f0eebd07 100644
--- a/deps/npm/node_modules/sigstore/dist/config.js
+++ b/deps/npm/node_modules/sigstore/dist/config.js
@@ -22,11 +22,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
     __setModuleDefault(result, mod);
     return result;
 };
-var __importDefault = (this && this.__importDefault) || function (mod) {
-    return (mod && mod.__esModule) ? mod : { "default": mod };
-};
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.identityProviders = exports.artifactVerificationOptions = exports.createTSAClient = exports.createTLogClient = exports.createCAClient = exports.DEFAULT_TIMEOUT = exports.DEFAULT_RETRY = exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = void 0;
+exports.artifactVerificationOptions = exports.createBundleBuilder = exports.DEFAULT_TIMEOUT = exports.DEFAULT_RETRY = void 0;
 /*
 Copyright 2023 The Sigstore Authors.
 
@@ -42,41 +39,72 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
-const ca_1 = require("./ca");
-const identity_1 = __importDefault(require("./identity"));
-const tlog_1 = require("./tlog");
-const tsa_1 = require("./tsa");
+const sign_1 = require("@sigstore/sign");
 const sigstore = __importStar(require("./types/sigstore"));
-exports.DEFAULT_FULCIO_URL = 'https://fulcio.sigstore.dev';
-exports.DEFAULT_REKOR_URL = 'https://rekor.sigstore.dev';
 exports.DEFAULT_RETRY = { retries: 2 };
 exports.DEFAULT_TIMEOUT = 5000;
-function createCAClient(options) {
-    return new ca_1.CAClient({
-        fulcioBaseURL: options.fulcioURL || exports.DEFAULT_FULCIO_URL,
-        retry: options.retry ?? exports.DEFAULT_RETRY,
-        timeout: options.timeout ?? exports.DEFAULT_TIMEOUT,
-    });
+function createBundleBuilder(bundleType, options) {
+    const bundlerOptions = {
+        signer: initSigner(options),
+        witnesses: initWitnesses(options),
+    };
+    switch (bundleType) {
+        case 'messageSignature':
+            return new sign_1.MessageSignatureBundleBuilder(bundlerOptions);
+        case 'dsseEnvelope':
+            return new sign_1.DSSEBundleBuilder(bundlerOptions);
+    }
 }
-exports.createCAClient = createCAClient;
-function createTLogClient(options) {
-    return new tlog_1.TLogClient({
-        rekorBaseURL: options.rekorURL || exports.DEFAULT_REKOR_URL,
+exports.createBundleBuilder = createBundleBuilder;
+// Instantiate the FulcioSigner based on the supplied options.
+function initSigner(options) {
+    return new sign_1.FulcioSigner({
+        fulcioBaseURL: options.fulcioURL,
+        identityProvider: options.identityProvider || initIdentityProvider(options),
         retry: options.retry ?? exports.DEFAULT_RETRY,
         timeout: options.timeout ?? exports.DEFAULT_TIMEOUT,
     });
 }
-exports.createTLogClient = createTLogClient;
-function createTSAClient(options) {
-    return options.tsaServerURL
-        ? new tsa_1.TSAClient({
+// Instantiate an identity provider based on the supplied options. If an
+// explicit identity token is provided, use that. Otherwise, use the CI
+// context provider.
+function initIdentityProvider(options) {
+    const token = options.identityToken;
+    if (token) {
+        return { getToken: () => Promise.resolve(token) };
+    }
+    else {
+        return new sign_1.CIContextProvider('sigstore');
+    }
+}
+// Instantiate a collection of witnesses based on the supplied options.
+function initWitnesses(options) {
+    const witnesses = [];
+    if (isRekorEnabled(options)) {
+        witnesses.push(new sign_1.RekorWitness({
+            rekorBaseURL: options.rekorURL,
+            fetchOnConflict: false,
+            retry: options.retry ?? exports.DEFAULT_RETRY,
+            timeout: options.timeout ?? exports.DEFAULT_TIMEOUT,
+        }));
+    }
+    if (isTSAEnabled(options)) {
+        witnesses.push(new sign_1.TSAWitness({
             tsaBaseURL: options.tsaServerURL,
             retry: options.retry ?? exports.DEFAULT_RETRY,
             timeout: options.timeout ?? exports.DEFAULT_TIMEOUT,
-        })
-        : undefined;
+        }));
+    }
+    return witnesses;
+}
+// Type assertion to ensure that Rekor is enabled
+function isRekorEnabled(options) {
+    return options.tlogUpload !== false;
+}
+// Type assertion to ensure that TSA is enabled
+function isTSAEnabled(options) {
+    return options.tsaServerURL !== undefined;
 }
-exports.createTSAClient = createTSAClient;
 // Assembles the AtifactVerificationOptions from the supplied VerifyOptions.
 function artifactVerificationOptions(options) {
     // The trusted signers are only used if the options contain a certificate
@@ -102,7 +130,7 @@ function artifactVerificationOptions(options) {
                 },
             };
         }
-        const oids = Object.entries(options.certificateOIDs || {}).map(([oid, value]) => ({
+        const oids = Object.entries(options.certificateOIDs || /* istanbul ignore next */ {}).map(([oid, value]) => ({
             oid: { id: oid.split('.').map((s) => parseInt(s, 10)) },
             value: Buffer.from(value),
         }));
@@ -122,41 +150,16 @@ function artifactVerificationOptions(options) {
     // Construct the artifact verification options w/ defaults
     return {
         ctlogOptions: {
-            disable: false,
-            threshold: options.ctLogThreshold || 1,
+            disable: options.ctLogThreshold === 0,
+            threshold: options.ctLogThreshold ?? 1,
             detachedSct: false,
         },
         tlogOptions: {
-            disable: false,
-            threshold: options.tlogThreshold || 1,
+            disable: options.tlogThreshold === 0,
+            threshold: options.tlogThreshold ?? 1,
             performOnlineVerification: false,
         },
         signers,
     };
 }
 exports.artifactVerificationOptions = artifactVerificationOptions;
-// Translates the IdenityProviderOptions into a list of Providers which
-// should be queried to retrieve an identity token.
-function identityProviders(options) {
-    const idps = [];
-    const token = options.identityToken;
-    // If an explicit identity token is provided, use that. Setup a dummy
-    // provider that just returns the token. Otherwise, setup the CI context
-    // provider and (optionally) the OAuth provider.
-    if (token) {
-        idps.push({ getToken: () => Promise.resolve(token) });
-    }
-    else {
-        idps.push(identity_1.default.ciContextProvider());
-        if (options.oidcIssuer && options.oidcClientID) {
-            idps.push(identity_1.default.oauthProvider({
-                issuer: options.oidcIssuer,
-                clientID: options.oidcClientID,
-                clientSecret: options.oidcClientSecret,
-                redirectURL: options.oidcRedirectURL,
-            }));
-        }
-    }
-    return idps;
-}
-exports.identityProviders = identityProviders;
diff --git a/deps/npm/node_modules/sigstore/dist/error.d.ts b/deps/npm/node_modules/sigstore/dist/error.d.ts
deleted file mode 100644
index c03bbc31697745..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/error.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-declare class BaseError extends Error {
-    cause: any | undefined;
-    constructor(message: string, cause?: any);
-}
-export declare class VerificationError extends BaseError {
-}
-export declare class ValidationError extends BaseError {
-}
-export declare class PolicyError extends BaseError {
-}
-type InternalErrorCode = 'TLOG_FETCH_ENTRY_ERROR' | 'TLOG_CREATE_ENTRY_ERROR' | 'CA_CREATE_SIGNING_CERTIFICATE_ERROR' | 'TSA_CREATE_TIMESTAMP_ERROR' | 'TUF_FIND_TARGET_ERROR' | 'TUF_REFRESH_METADATA_ERROR' | 'TUF_DOWNLOAD_TARGET_ERROR' | 'TUF_READ_TARGET_ERROR';
-export declare class InternalError extends BaseError {
-    code: InternalErrorCode;
-    constructor({ code, message, cause, }: {
-        code: InternalErrorCode;
-        message: string;
-        cause?: any;
-    });
-}
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/error.js b/deps/npm/node_modules/sigstore/dist/error.js
index cee15dff90b614..b0a7dbc83f7105 100644
--- a/deps/npm/node_modules/sigstore/dist/error.js
+++ b/deps/npm/node_modules/sigstore/dist/error.js
@@ -1,6 +1,4 @@
 "use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.InternalError = exports.PolicyError = exports.ValidationError = exports.VerificationError = void 0;
 /*
 Copyright 2023 The Sigstore Authors.
 
@@ -16,27 +14,22 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
-/* eslint-disable @typescript-eslint/no-explicit-any */
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.PolicyError = exports.VerificationError = void 0;
 class BaseError extends Error {
-    constructor(message, cause) {
+    constructor({ code, message, cause, }) {
         super(message);
         this.name = this.constructor.name;
+        this.code = code;
         this.cause = cause;
     }
 }
 class VerificationError extends BaseError {
+    constructor(message) {
+        super({ code: 'VERIFICATION_ERROR', message });
+    }
 }
 exports.VerificationError = VerificationError;
-class ValidationError extends BaseError {
-}
-exports.ValidationError = ValidationError;
 class PolicyError extends BaseError {
 }
 exports.PolicyError = PolicyError;
-class InternalError extends BaseError {
-    constructor({ code, message, cause, }) {
-        super(message, cause);
-        this.code = code;
-    }
-}
-exports.InternalError = InternalError;
diff --git a/deps/npm/node_modules/sigstore/dist/external/error.d.ts b/deps/npm/node_modules/sigstore/dist/external/error.d.ts
deleted file mode 100644
index 87a4bc5451a3de..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/external/error.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import fetch from 'make-fetch-happen';
-type Response = Awaited>;
-export declare class HTTPError extends Error {
-    response: Response;
-    statusCode: number;
-    location?: string;
-    constructor(response: Response);
-}
-export declare const checkStatus: (response: Response) => Response;
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/external/error.js b/deps/npm/node_modules/sigstore/dist/external/error.js
deleted file mode 100644
index d1e1c3df8a8787..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/external/error.js
+++ /dev/null
@@ -1,21 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.checkStatus = exports.HTTPError = void 0;
-class HTTPError extends Error {
-    constructor(response) {
-        super(`HTTP Error: ${response.status} ${response.statusText}`);
-        this.response = response;
-        this.statusCode = response.status;
-        this.location = response.headers?.get('Location') || undefined;
-    }
-}
-exports.HTTPError = HTTPError;
-const checkStatus = (response) => {
-    if (response.ok) {
-        return response;
-    }
-    else {
-        throw new HTTPError(response);
-    }
-};
-exports.checkStatus = checkStatus;
diff --git a/deps/npm/node_modules/sigstore/dist/external/fulcio.d.ts b/deps/npm/node_modules/sigstore/dist/external/fulcio.d.ts
deleted file mode 100644
index 64b0fc5e347982..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/external/fulcio.d.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { FetchOptions } from '../types/fetch';
-export type FulcioOptions = {
-    baseURL: string;
-} & FetchOptions;
-export interface SigningCertificateRequest {
-    credentials: {
-        oidcIdentityToken: string;
-    };
-    publicKeyRequest: {
-        publicKey: {
-            algorithm: string;
-            content: string;
-        };
-        proofOfPossession: string;
-    };
-}
-export interface SigningCertificateResponse {
-    signedCertificateEmbeddedSct?: {
-        chain: {
-            certificates: string[];
-        };
-    };
-    signedCertificateDetachedSct?: {
-        chain: {
-            certificates: string[];
-        };
-        signedCertificateTimestamp: string;
-    };
-}
-/**
- * Fulcio API client.
- */
-export declare class Fulcio {
-    private fetch;
-    private baseUrl;
-    constructor(options: FulcioOptions);
-    createSigningCertificate(request: SigningCertificateRequest): Promise;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/external/index.d.ts b/deps/npm/node_modules/sigstore/dist/external/index.d.ts
deleted file mode 100644
index ef28eca4a951dd..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/external/index.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export { HTTPError } from './error';
-export { Fulcio } from './fulcio';
-export { Rekor } from './rekor';
-export { TimestampAuthority } from './tsa';
diff --git a/deps/npm/node_modules/sigstore/dist/external/index.js b/deps/npm/node_modules/sigstore/dist/external/index.js
deleted file mode 100644
index f40816e9b7ca40..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/external/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.TimestampAuthority = exports.Rekor = exports.Fulcio = exports.HTTPError = void 0;
-/*
-Copyright 2022 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-var error_1 = require("./error");
-Object.defineProperty(exports, "HTTPError", { enumerable: true, get: function () { return error_1.HTTPError; } });
-var fulcio_1 = require("./fulcio");
-Object.defineProperty(exports, "Fulcio", { enumerable: true, get: function () { return fulcio_1.Fulcio; } });
-var rekor_1 = require("./rekor");
-Object.defineProperty(exports, "Rekor", { enumerable: true, get: function () { return rekor_1.Rekor; } });
-var tsa_1 = require("./tsa");
-Object.defineProperty(exports, "TimestampAuthority", { enumerable: true, get: function () { return tsa_1.TimestampAuthority; } });
diff --git a/deps/npm/node_modules/sigstore/dist/external/rekor.d.ts b/deps/npm/node_modules/sigstore/dist/external/rekor.d.ts
deleted file mode 100644
index 6729ad3e2aacf6..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/external/rekor.d.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import type { LogEntry, ProposedDSSEEntry, ProposedEntry, ProposedHashedRekordEntry, ProposedIntotoEntry, InclusionProof as RekorInclusionProof, SearchIndex, SearchLogQuery } from '@sigstore/rekor-types';
-import type { FetchOptions } from '../types/fetch';
-export type { ProposedDSSEEntry, ProposedEntry, ProposedHashedRekordEntry, ProposedIntotoEntry, RekorInclusionProof, SearchIndex, SearchLogQuery, };
-export type Entry = {
-    uuid: string;
-} & LogEntry['x'];
-export type RekorOptions = {
-    baseURL: string;
-} & FetchOptions;
-/**
- * Rekor API client.
- */
-export declare class Rekor {
-    private fetch;
-    private baseUrl;
-    constructor(options: RekorOptions);
-    /**
-     * Create a new entry in the Rekor log.
-     * @param propsedEntry {ProposedEntry} Data to create a new entry
-     * @returns {Promise} The created entry
-     */
-    createEntry(propsedEntry: ProposedEntry): Promise;
-    /**
-     * Get an entry from the Rekor log.
-     * @param uuid {string} The UUID of the entry to retrieve
-     * @returns {Promise} The retrieved entry
-     */
-    getEntry(uuid: string): Promise;
-    /**
-     * Search the Rekor log index for entries matching the given query.
-     * @param opts {SearchIndex} Options to search the Rekor log
-     * @returns {Promise} UUIDs of matching entries
-     */
-    searchIndex(opts: SearchIndex): Promise;
-    /**
-     * Search the Rekor logs for matching the given query.
-     * @param opts {SearchLogQuery} Query to search the Rekor log
-     * @returns {Promise} List of matching entries
-     */
-    searchLog(opts: SearchLogQuery): Promise;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/external/tsa.d.ts b/deps/npm/node_modules/sigstore/dist/external/tsa.d.ts
deleted file mode 100644
index 9b5f31151a83d8..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/external/tsa.d.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-/// 
-import type { FetchOptions } from '../types/fetch';
-export interface TimestampRequest {
-    artifactHash: string;
-    hashAlgorithm: string;
-    certificates?: boolean;
-    nonce?: number;
-    tsaPolicyOID?: string;
-}
-export type TimestampAuthorityOptions = {
-    baseURL: string;
-} & FetchOptions;
-export declare class TimestampAuthority {
-    private fetch;
-    private baseUrl;
-    constructor(options: TimestampAuthorityOptions);
-    createTimestamp(request: TimestampRequest): Promise;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/identity/ci.d.ts b/deps/npm/node_modules/sigstore/dist/identity/ci.d.ts
deleted file mode 100644
index 428606f26524bb..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/ci.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Provider } from './provider';
-/**
- * CIContextProvider is a composite identity provider which will iterate
- * over all of the CI-specific providers and return the token from the first
- * one that resolves.
- */
-export declare class CIContextProvider implements Provider {
-    private audience;
-    constructor(audience: string);
-    getToken(): Promise;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/identity/index.d.ts b/deps/npm/node_modules/sigstore/dist/identity/index.d.ts
deleted file mode 100644
index 3eb0b444d120ff..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/index.d.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Provider } from './provider';
-/**
- * oauthProvider returns a new Provider instance which attempts to retrieve
- * an identity token from the configured OAuth2 issuer.
- *
- * @param issuer Base URL of the issuer
- * @param clientID Client ID for the issuer
- * @param clientSecret Client secret for the issuer (optional)
- * @returns {Provider}
- */
-declare function oauthProvider(options: {
-    issuer: string;
-    clientID: string;
-    clientSecret?: string;
-    redirectURL?: string;
-}): Provider;
-/**
- * ciContextProvider returns a new Provider instance which attempts to retrieve
- * an identity token from the CI context.
- *
- * @param audience audience claim for the generated token
- * @returns {Provider}
- */
-declare function ciContextProvider(audience?: string): Provider;
-declare const _default: {
-    ciContextProvider: typeof ciContextProvider;
-    oauthProvider: typeof oauthProvider;
-};
-export default _default;
-export { Provider } from './provider';
diff --git a/deps/npm/node_modules/sigstore/dist/identity/index.js b/deps/npm/node_modules/sigstore/dist/identity/index.js
deleted file mode 100644
index 351d607106700f..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-/*
-Copyright 2022 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-const ci_1 = require("./ci");
-const issuer_1 = require("./issuer");
-const oauth_1 = require("./oauth");
-/**
- * oauthProvider returns a new Provider instance which attempts to retrieve
- * an identity token from the configured OAuth2 issuer.
- *
- * @param issuer Base URL of the issuer
- * @param clientID Client ID for the issuer
- * @param clientSecret Client secret for the issuer (optional)
- * @returns {Provider}
- */
-function oauthProvider(options) {
-    return new oauth_1.OAuthProvider({
-        issuer: new issuer_1.Issuer(options.issuer),
-        clientID: options.clientID,
-        clientSecret: options.clientSecret,
-        redirectURL: options.redirectURL,
-    });
-}
-/**
- * ciContextProvider returns a new Provider instance which attempts to retrieve
- * an identity token from the CI context.
- *
- * @param audience audience claim for the generated token
- * @returns {Provider}
- */
-function ciContextProvider(audience = 'sigstore') {
-    return new ci_1.CIContextProvider(audience);
-}
-exports.default = {
-    ciContextProvider,
-    oauthProvider,
-};
diff --git a/deps/npm/node_modules/sigstore/dist/identity/issuer.d.ts b/deps/npm/node_modules/sigstore/dist/identity/issuer.d.ts
deleted file mode 100644
index 37ad713f4d89a7..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/issuer.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * The Issuer reperesents a single OAuth2 provider.
- *
- * The Issuer is configured with a provider's base OAuth2 endpoint which is
- * used to retrieve the associated configuration information.
- */
-export declare class Issuer {
-    private baseURL;
-    private fetch;
-    private config?;
-    constructor(baseURL: string);
-    authEndpoint(): Promise;
-    tokenEndpoint(): Promise;
-    private loadOpenIDConfig;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/identity/issuer.js b/deps/npm/node_modules/sigstore/dist/identity/issuer.js
deleted file mode 100644
index 2bf6c20f34932d..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/issuer.js
+++ /dev/null
@@ -1,53 +0,0 @@
-"use strict";
-var __importDefault = (this && this.__importDefault) || function (mod) {
-    return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.Issuer = void 0;
-/*
-Copyright 2022 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
-// Standard endpoint for retrieving OpenID configuration information
-const OPENID_CONFIG_PATH = '/.well-known/openid-configuration';
-/**
- * The Issuer reperesents a single OAuth2 provider.
- *
- * The Issuer is configured with a provider's base OAuth2 endpoint which is
- * used to retrieve the associated configuration information.
- */
-class Issuer {
-    constructor(baseURL) {
-        this.baseURL = baseURL;
-        this.fetch = make_fetch_happen_1.default.defaults({ retry: 2 });
-    }
-    async authEndpoint() {
-        if (!this.config) {
-            this.config = await this.loadOpenIDConfig();
-        }
-        return this.config.authorization_endpoint;
-    }
-    async tokenEndpoint() {
-        if (!this.config) {
-            this.config = await this.loadOpenIDConfig();
-        }
-        return this.config.token_endpoint;
-    }
-    async loadOpenIDConfig() {
-        const url = `${this.baseURL}${OPENID_CONFIG_PATH}`;
-        return this.fetch(url).then((res) => res.json());
-    }
-}
-exports.Issuer = Issuer;
diff --git a/deps/npm/node_modules/sigstore/dist/identity/oauth.d.ts b/deps/npm/node_modules/sigstore/dist/identity/oauth.d.ts
deleted file mode 100644
index 3c9fae9ac15387..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/oauth.d.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Issuer } from './issuer';
-import { Provider } from './provider';
-interface OAuthProviderOptions {
-    issuer: Issuer;
-    clientID: string;
-    clientSecret?: string;
-    redirectURL?: string;
-}
-export declare class OAuthProvider implements Provider {
-    private clientID;
-    private clientSecret;
-    private issuer;
-    private codeVerifier;
-    private state;
-    private redirectURI?;
-    constructor(options: OAuthProviderOptions);
-    getToken(): Promise;
-    private initiateAuthRequest;
-    private getIDToken;
-    private getBasicAuthHeaderValue;
-    private getAuthRequestURL;
-    private getAuthRequestParams;
-    private getCodeChallenge;
-    private openURL;
-}
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/identity/oauth.js b/deps/npm/node_modules/sigstore/dist/identity/oauth.js
deleted file mode 100644
index 7cb5a00cdb6942..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/oauth.js
+++ /dev/null
@@ -1,197 +0,0 @@
-"use strict";
-var __importDefault = (this && this.__importDefault) || function (mod) {
-    return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.OAuthProvider = void 0;
-/*
-Copyright 2022 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-const assert_1 = __importDefault(require("assert"));
-const child_process_1 = __importDefault(require("child_process"));
-const http_1 = __importDefault(require("http"));
-const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
-const url_1 = require("url");
-const util_1 = require("../util");
-class OAuthProvider {
-    constructor(options) {
-        this.clientID = options.clientID;
-        this.clientSecret = options.clientSecret || '';
-        this.issuer = options.issuer;
-        this.redirectURI = options.redirectURL;
-        this.codeVerifier = generateRandomString(32);
-        this.state = generateRandomString(16);
-    }
-    async getToken() {
-        const authCode = await this.initiateAuthRequest();
-        return this.getIDToken(authCode);
-    }
-    // Initates the authorization request. This will start an HTTP server to
-    // receive the post-auth redirect and then open the user's default browser to
-    // the provider's authorization page.
-    async initiateAuthRequest() {
-        const server = http_1.default.createServer();
-        const sockets = new Set();
-        // Start server and wait till it is listening. If a redirect URL was
-        // provided, use that. Otherwise, use a random port and construct the
-        // redirect URL.
-        await new Promise((resolve) => {
-            if (this.redirectURI) {
-                const url = new url_1.URL(this.redirectURI);
-                server.listen(Number(url.port), url.hostname, resolve);
-            }
-            else {
-                server.listen(0, resolve);
-                // Get port the server is listening on and construct the server URL
-                const port = server.address().port;
-                this.redirectURI = `http://localhost:${port}`;
-            }
-        });
-        // Keep track of connections to the server so we can force a shutdown
-        server.on('connection', (socket) => {
-            sockets.add(socket);
-            socket.once('close', () => {
-                sockets.delete(socket);
-            });
-        });
-        const result = new Promise((resolve, reject) => {
-            // Set-up handler for post-auth redirect
-            server.on('request', (req, res) => {
-                if (!req.url) {
-                    reject('invalid server request');
-                    return;
-                }
-                res.writeHead(200);
-                res.end('Auth Successful');
-                // Parse incoming request URL
-                const query = new url_1.URL(req.url, this.redirectURI).searchParams;
-                // Check to see if the state matches
-                if (query.get('state') !== this.state) {
-                    reject('invalid state value');
-                    return;
-                }
-                const authCode = query.get('code');
-                // Force-close any open connections to the server so we can get a
-                // clean shutdown
-                for (const socket of sockets) {
-                    socket.destroy();
-                    sockets.delete(socket);
-                }
-                // Return auth code once we've shutdown server
-                server.close(() => {
-                    if (!authCode) {
-                        reject('authorization code not found');
-                    }
-                    else {
-                        resolve(authCode);
-                    }
-                });
-            });
-        });
-        try {
-            // Open browser to start authorization request
-            const authBaseURL = await this.issuer.authEndpoint();
-            const authURL = this.getAuthRequestURL(authBaseURL);
-            await this.openURL(authURL);
-        }
-        catch (err) {
-            // Prevent leaked server handler on error
-            server.close();
-            throw err;
-        }
-        return result;
-    }
-    // Uses the provided authorization code, to retrieve the ID token from the
-    // provider
-    async getIDToken(authCode) {
-        (0, assert_1.default)(this.redirectURI);
-        const tokenEndpointURL = await this.issuer.tokenEndpoint();
-        const params = new url_1.URLSearchParams();
-        params.append('grant_type', 'authorization_code');
-        params.append('code', authCode);
-        params.append('redirect_uri', this.redirectURI);
-        params.append('code_verifier', this.codeVerifier);
-        const response = await (0, make_fetch_happen_1.default)(tokenEndpointURL, {
-            method: 'POST',
-            headers: { Authorization: `Basic ${this.getBasicAuthHeaderValue()}` },
-            body: params,
-        }).then((r) => r.json());
-        return response.id_token;
-    }
-    // Construct the basic auth header value from the client ID and secret
-    getBasicAuthHeaderValue() {
-        return util_1.encoding.base64Encode(`${this.clientID}:${this.clientSecret}`);
-    }
-    // Generate starting URL for authorization request
-    getAuthRequestURL(baseURL) {
-        const params = this.getAuthRequestParams();
-        return `${baseURL}?${params.toString()}`;
-    }
-    // Collect parameters for authorization request
-    getAuthRequestParams() {
-        (0, assert_1.default)(this.redirectURI);
-        const codeChallenge = this.getCodeChallenge();
-        return new url_1.URLSearchParams({
-            response_type: 'code',
-            client_id: this.clientID,
-            client_secret: this.clientSecret,
-            scope: 'openid email',
-            redirect_uri: this.redirectURI,
-            code_challenge: codeChallenge,
-            code_challenge_method: 'S256',
-            state: this.state,
-            nonce: generateRandomString(16),
-        });
-    }
-    // Generate code challenge for authorization request
-    getCodeChallenge() {
-        return util_1.encoding.base64URLEscape(util_1.crypto.hash(this.codeVerifier).toString('base64'));
-    }
-    // Open the supplied URL in the user's default browser
-    async openURL(url) {
-        return new Promise((resolve, reject) => {
-            let open = null;
-            let command = `"${url}"`;
-            switch (process.platform) {
-                case 'darwin':
-                    open = 'open';
-                    break;
-                case 'linux' || 'freebsd' || 'netbsd' || 'openbsd':
-                    open = 'xdg-open';
-                    break;
-                case 'win32':
-                    open = 'start';
-                    command = `"" ${command}`;
-                    break;
-                default:
-                    return reject(`OAuth: unsupported platform: ${process.platform}`);
-            }
-            console.error(`Your browser will now be opened to: ${url}`);
-            child_process_1.default.exec(`${open} ${command}`, undefined, (err) => {
-                if (err) {
-                    reject(err);
-                }
-                else {
-                    resolve();
-                }
-            });
-        });
-    }
-}
-exports.OAuthProvider = OAuthProvider;
-// Generate random code verifier value
-function generateRandomString(len) {
-    return util_1.encoding.base64URLEscape(util_1.crypto.randomBytes(len).toString('base64'));
-}
diff --git a/deps/npm/node_modules/sigstore/dist/identity/provider.d.ts b/deps/npm/node_modules/sigstore/dist/identity/provider.d.ts
deleted file mode 100644
index 95ec03e9ffff6c..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/identity/provider.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export interface Provider {
-    getToken: () => Promise;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/index.d.ts b/deps/npm/node_modules/sigstore/dist/index.d.ts
deleted file mode 100644
index dbac0640092b04..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export type { Provider as IdentityProvider } from './identity';
-export * as sigstore from './sigstore';
diff --git a/deps/npm/node_modules/sigstore/dist/index.js b/deps/npm/node_modules/sigstore/dist/index.js
index 126fce58e45bde..341c1fa504d1e8 100644
--- a/deps/npm/node_modules/sigstore/dist/index.js
+++ b/deps/npm/node_modules/sigstore/dist/index.js
@@ -1,27 +1,34 @@
 "use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    var desc = Object.getOwnPropertyDescriptor(m, k);
-    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
-      desc = { enumerable: true, get: function() { return m[k]; } };
-    }
-    Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
-    Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
-    o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
-    if (mod && mod.__esModule) return mod;
-    var result = {};
-    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
-    __setModuleDefault(result, mod);
-    return result;
-};
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.sigstore = void 0;
-exports.sigstore = __importStar(require("./sigstore"));
+exports.verify = exports.sign = exports.createVerifier = exports.attest = exports.VerificationError = exports.PolicyError = exports.TUFError = exports.InternalError = exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = exports.ValidationError = void 0;
+/*
+Copyright 2022 The Sigstore Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+var bundle_1 = require("@sigstore/bundle");
+Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return bundle_1.ValidationError; } });
+var sign_1 = require("@sigstore/sign");
+Object.defineProperty(exports, "DEFAULT_FULCIO_URL", { enumerable: true, get: function () { return sign_1.DEFAULT_FULCIO_URL; } });
+Object.defineProperty(exports, "DEFAULT_REKOR_URL", { enumerable: true, get: function () { return sign_1.DEFAULT_REKOR_URL; } });
+Object.defineProperty(exports, "InternalError", { enumerable: true, get: function () { return sign_1.InternalError; } });
+var tuf_1 = require("@sigstore/tuf");
+Object.defineProperty(exports, "TUFError", { enumerable: true, get: function () { return tuf_1.TUFError; } });
+var error_1 = require("./error");
+Object.defineProperty(exports, "PolicyError", { enumerable: true, get: function () { return error_1.PolicyError; } });
+Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return error_1.VerificationError; } });
+var sigstore_1 = require("./sigstore");
+Object.defineProperty(exports, "attest", { enumerable: true, get: function () { return sigstore_1.attest; } });
+Object.defineProperty(exports, "createVerifier", { enumerable: true, get: function () { return sigstore_1.createVerifier; } });
+Object.defineProperty(exports, "sign", { enumerable: true, get: function () { return sigstore_1.sign; } });
+Object.defineProperty(exports, "verify", { enumerable: true, get: function () { return sigstore_1.verify; } });
diff --git a/deps/npm/node_modules/sigstore/dist/sign.d.ts b/deps/npm/node_modules/sigstore/dist/sign.d.ts
deleted file mode 100644
index 7d903c06e120a0..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/sign.d.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/// 
-import { SignerFunc } from './types/signature';
-import * as sigstore from './types/sigstore';
-import type { CA } from './ca';
-import type { Provider } from './identity';
-import type { TLog } from './tlog';
-import type { TSA } from './tsa';
-export interface SignOptions {
-    ca: CA;
-    tlog: TLog;
-    tsa?: TSA;
-    identityProviders: Provider[];
-    tlogUpload?: boolean;
-    signer?: SignerFunc;
-}
-export declare class Signer {
-    private ca;
-    private tlog;
-    private tsa?;
-    private tlogUpload;
-    private signer;
-    private identityProviders;
-    constructor(options: SignOptions);
-    signBlob(payload: Buffer): Promise;
-    signAttestation(payload: Buffer, payloadType: string): Promise;
-    private signWithEphemeralKey;
-    private getIdentityToken;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/sign.js b/deps/npm/node_modules/sigstore/dist/sign.js
deleted file mode 100644
index 96e6272750b493..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/sign.js
+++ /dev/null
@@ -1,120 +0,0 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    var desc = Object.getOwnPropertyDescriptor(m, k);
-    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
-      desc = { enumerable: true, get: function() { return m[k]; } };
-    }
-    Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
-    Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
-    o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
-    if (mod && mod.__esModule) return mod;
-    var result = {};
-    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
-    __setModuleDefault(result, mod);
-    return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.Signer = void 0;
-const sigstore = __importStar(require("./types/sigstore"));
-const util_1 = require("./util");
-class Signer {
-    constructor(options) {
-        this.identityProviders = [];
-        this.ca = options.ca;
-        this.tlog = options.tlog;
-        this.tsa = options.tsa;
-        this.identityProviders = options.identityProviders;
-        this.tlogUpload = options.tlogUpload ?? true;
-        this.signer = options.signer || this.signWithEphemeralKey.bind(this);
-    }
-    async signBlob(payload) {
-        // Get signature and verification material for payload
-        const sigMaterial = await this.signer(payload);
-        // Calculate artifact digest
-        const digest = util_1.crypto.hash(payload);
-        // Create a Rekor entry (if tlogUpload is enabled)
-        const entry = this.tlogUpload
-            ? await this.tlog.createMessageSignatureEntry(digest, sigMaterial)
-            : undefined;
-        return sigstore.toMessageSignatureBundle({
-            digest,
-            signature: sigMaterial,
-            tlogEntry: entry,
-            timestamp: this.tsa
-                ? await this.tsa.createTimestamp(sigMaterial.signature)
-                : undefined,
-        });
-    }
-    async signAttestation(payload, payloadType) {
-        // Pre-authentication encoding to be signed
-        const paeBuffer = util_1.dsse.preAuthEncoding(payloadType, payload);
-        // Get signature and verification material for pae
-        const sigMaterial = await this.signer(paeBuffer);
-        const envelope = {
-            payloadType,
-            payload: payload,
-            signatures: [
-                {
-                    keyid: sigMaterial.key?.id || '',
-                    sig: sigMaterial.signature,
-                },
-            ],
-        };
-        // Create a Rekor entry (if tlogUpload is enabled)
-        const entry = this.tlogUpload
-            ? await this.tlog.createDSSEEntry(envelope, sigMaterial)
-            : undefined;
-        return sigstore.toDSSEBundle({
-            envelope,
-            signature: sigMaterial,
-            tlogEntry: entry,
-            timestamp: this.tsa
-                ? await this.tsa.createTimestamp(sigMaterial.signature)
-                : undefined,
-        });
-    }
-    async signWithEphemeralKey(payload) {
-        // Create emphemeral key pair
-        const keypair = util_1.crypto.generateKeyPair();
-        // Retrieve identity token from one of the supplied identity providers
-        const identityToken = await this.getIdentityToken();
-        // Extract challenge claim from OIDC token
-        const subject = util_1.oidc.extractJWTSubject(identityToken);
-        // Construct challenge value by encrypting subject with private key
-        const challenge = util_1.crypto.signBlob(Buffer.from(subject), keypair.privateKey);
-        // Create signing certificate
-        const certificates = await this.ca.createSigningCertificate(identityToken, keypair.publicKey, challenge);
-        // Generate artifact signature
-        const signature = util_1.crypto.signBlob(payload, keypair.privateKey);
-        return {
-            signature,
-            certificates,
-            key: undefined,
-        };
-    }
-    async getIdentityToken() {
-        const aggErrs = [];
-        for (const provider of this.identityProviders) {
-            try {
-                const token = await provider.getToken();
-                if (token) {
-                    return token;
-                }
-            }
-            catch (err) {
-                aggErrs.push(err);
-            }
-        }
-        throw new Error(`Identity token providers failed: ${aggErrs}`);
-    }
-}
-exports.Signer = Signer;
diff --git a/deps/npm/node_modules/sigstore/dist/sigstore-utils.d.ts b/deps/npm/node_modules/sigstore/dist/sigstore-utils.d.ts
deleted file mode 100644
index 38f15dc7340d29..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/sigstore-utils.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-/// 
-import { SignOptions } from './config';
-import { SignerFunc } from './types/signature';
-import * as sigstore from './types/sigstore';
-export declare function createDSSEEnvelope(payload: Buffer, payloadType: string, options: {
-    signer: SignerFunc;
-}): Promise;
-export declare function createRekorEntry(dsseEnvelope: sigstore.SerializedEnvelope, publicKey: string, options?: SignOptions): Promise;
diff --git a/deps/npm/node_modules/sigstore/dist/sigstore-utils.js b/deps/npm/node_modules/sigstore/dist/sigstore-utils.js
deleted file mode 100644
index dc75692f40bf02..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/sigstore-utils.js
+++ /dev/null
@@ -1,80 +0,0 @@
-"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    var desc = Object.getOwnPropertyDescriptor(m, k);
-    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
-      desc = { enumerable: true, get: function() { return m[k]; } };
-    }
-    Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
-    Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
-    o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
-    if (mod && mod.__esModule) return mod;
-    var result = {};
-    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
-    __setModuleDefault(result, mod);
-    return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.createRekorEntry = exports.createDSSEEnvelope = void 0;
-/*
-Copyright 2022 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-const config_1 = require("./config");
-const signature_1 = require("./types/signature");
-const sigstore = __importStar(require("./types/sigstore"));
-const util_1 = require("./util");
-async function createDSSEEnvelope(payload, payloadType, options) {
-    // Pre-authentication encoding to be signed
-    const paeBuffer = util_1.dsse.preAuthEncoding(payloadType, payload);
-    // Get signature and verification material for pae
-    const sigMaterial = await options.signer(paeBuffer);
-    const envelope = {
-        payloadType,
-        payload,
-        signatures: [
-            {
-                keyid: sigMaterial.key?.id || '',
-                sig: sigMaterial.signature,
-            },
-        ],
-    };
-    return sigstore.Envelope.toJSON(envelope);
-}
-exports.createDSSEEnvelope = createDSSEEnvelope;
-// Accepts a signed DSSE envelope and a PEM-encoded public key to be added to the
-// transparency log. Returns a Sigstore bundle suitable for offline verification.
-async function createRekorEntry(dsseEnvelope, publicKey, options = {}) {
-    const envelope = sigstore.Envelope.fromJSON(dsseEnvelope);
-    const tlog = (0, config_1.createTLogClient)(options);
-    const sigMaterial = (0, signature_1.extractSignatureMaterial)(envelope, publicKey);
-    const entry = await tlog.createDSSEEntry(envelope, sigMaterial, {
-        fetchOnConflict: true,
-    });
-    const bundle = sigstore.toDSSEBundle({
-        envelope,
-        signature: sigMaterial,
-        tlogEntry: entry,
-    });
-    return sigstore.bundleToJSON(bundle);
-}
-exports.createRekorEntry = createRekorEntry;
diff --git a/deps/npm/node_modules/sigstore/dist/sigstore.d.ts b/deps/npm/node_modules/sigstore/dist/sigstore.d.ts
deleted file mode 100644
index 1da5e8ecc5fe5b..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/sigstore.d.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/// 
-import * as tuf from '@sigstore/tuf';
-import * as config from './config';
-import * as sigstore from './types/sigstore';
-export declare function sign(payload: Buffer, options?: config.SignOptions): Promise;
-export declare function attest(payload: Buffer, payloadType: string, options?: config.SignOptions): Promise;
-export declare function verify(bundle: sigstore.SerializedBundle, payload?: Buffer, options?: config.VerifyOptions): Promise;
-export interface BundleVerifier {
-    verify(bundle: sigstore.SerializedBundle): void;
-}
-export declare function createVerifier(options: config.CreateVerifierOptions): Promise;
-declare const tufUtils: {
-    client: (options?: config.TUFOptions) => Promise;
-    getTarget: (path: string, options?: config.TUFOptions) => Promise;
-};
-export type { TUF } from '@sigstore/tuf';
-export type { SignOptions, VerifyOptions } from './config';
-export { InternalError, PolicyError, ValidationError, VerificationError, } from './error';
-export * as utils from './sigstore-utils';
-export type { SerializedBundle as Bundle, SerializedEnvelope as Envelope, } from './types/sigstore';
-export { tufUtils as tuf };
-export declare const DEFAULT_FULCIO_URL = "https://fulcio.sigstore.dev";
-export declare const DEFAULT_REKOR_URL = "https://rekor.sigstore.dev";
diff --git a/deps/npm/node_modules/sigstore/dist/sigstore.js b/deps/npm/node_modules/sigstore/dist/sigstore.js
index dca476dd292030..24fff291ab2b7e 100644
--- a/deps/npm/node_modules/sigstore/dist/sigstore.js
+++ b/deps/npm/node_modules/sigstore/dist/sigstore.js
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
     return result;
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = exports.tuf = exports.utils = exports.VerificationError = exports.ValidationError = exports.PolicyError = exports.InternalError = exports.createVerifier = exports.verify = exports.attest = exports.sign = void 0;
+exports.createVerifier = exports.verify = exports.attest = exports.sign = void 0;
 /*
 Copyright 2023 The Sigstore Authors.
 
@@ -39,60 +39,40 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
+const bundle_1 = require("@sigstore/bundle");
 const tuf = __importStar(require("@sigstore/tuf"));
 const config = __importStar(require("./config"));
-const sign_1 = require("./sign");
-const sigstore = __importStar(require("./types/sigstore"));
 const verify_1 = require("./verify");
-async function sign(payload, options = {}) {
-    const ca = config.createCAClient(options);
-    const tlog = config.createTLogClient(options);
-    const idps = config.identityProviders(options);
-    const signer = new sign_1.Signer({
-        ca,
-        tlog,
-        identityProviders: options.identityProvider
-            ? [options.identityProvider]
-            : idps,
-        tlogUpload: options.tlogUpload,
-    });
-    const bundle = await signer.signBlob(payload);
-    return sigstore.bundleToJSON(bundle);
+async function sign(payload,
+/* istanbul ignore next */
+options = {}) {
+    const bundler = config.createBundleBuilder('messageSignature', options);
+    const bundle = await bundler.create({ data: payload });
+    return (0, bundle_1.bundleToJSON)(bundle);
 }
 exports.sign = sign;
-async function attest(payload, payloadType, options = {}) {
-    const ca = config.createCAClient(options);
-    const tlog = config.createTLogClient(options);
-    const tsa = config.createTSAClient(options);
-    const idps = config.identityProviders(options);
-    const signer = new sign_1.Signer({
-        ca,
-        tlog,
-        tsa,
-        identityProviders: options.identityProvider
-            ? [options.identityProvider]
-            : idps,
-        tlogUpload: options.tlogUpload,
-    });
-    const bundle = await signer.signAttestation(payload, payloadType);
-    return sigstore.bundleToJSON(bundle);
+async function attest(payload, payloadType,
+/* istanbul ignore next */
+options = {}) {
+    const bundler = config.createBundleBuilder('dsseEnvelope', options);
+    const bundle = await bundler.create({ data: payload, type: payloadType });
+    return (0, bundle_1.bundleToJSON)(bundle);
 }
 exports.attest = attest;
-async function verify(bundle, payload, options = {}) {
-    const trustedRoot = await tuf.getTrustedRoot({
-        mirrorURL: options.tufMirrorURL,
-        rootPath: options.tufRootPath,
-        cachePath: options.tufCachePath,
-        retry: options.retry ?? config.DEFAULT_RETRY,
-        timeout: options.timeout ?? config.DEFAULT_TIMEOUT,
-    });
-    const verifier = new verify_1.Verifier(trustedRoot, options.keySelector);
-    const deserializedBundle = sigstore.bundleFromJSON(bundle);
-    const opts = config.artifactVerificationOptions(options);
-    return verifier.verify(deserializedBundle, opts, payload);
+async function verify(bundle, dataOrOptions, options) {
+    let data;
+    if (Buffer.isBuffer(dataOrOptions)) {
+        data = dataOrOptions;
+    }
+    else {
+        options = dataOrOptions;
+    }
+    return createVerifier(options).then((verifier) => verifier.verify(bundle, data));
 }
 exports.verify = verify;
-async function createVerifier(options) {
+async function createVerifier(
+/* istanbul ignore next */
+options = {}) {
     const trustedRoot = await tuf.getTrustedRoot({
         mirrorURL: options.tufMirrorURL,
         rootPath: options.tufRootPath,
@@ -103,44 +83,10 @@ async function createVerifier(options) {
     const verifier = new verify_1.Verifier(trustedRoot, options.keySelector);
     const verifyOpts = config.artifactVerificationOptions(options);
     return {
-        verify: (bundle) => {
-            const deserializedBundle = sigstore.bundleFromJSON(bundle);
-            return verifier.verify(deserializedBundle, verifyOpts);
+        verify: (bundle, payload) => {
+            const deserializedBundle = (0, bundle_1.bundleFromJSON)(bundle);
+            return verifier.verify(deserializedBundle, verifyOpts, payload);
         },
     };
 }
 exports.createVerifier = createVerifier;
-const tufUtils = {
-    client: (options = {}) => {
-        return tuf.initTUF({
-            mirrorURL: options.tufMirrorURL,
-            rootPath: options.tufRootPath,
-            cachePath: options.tufCachePath,
-            retry: options.retry,
-            timeout: options.timeout,
-        });
-    },
-    /*
-     * @deprecated Use tufUtils.client instead.
-     */
-    getTarget: (path, options = {}) => {
-        return tuf
-            .initTUF({
-            mirrorURL: options.tufMirrorURL,
-            rootPath: options.tufRootPath,
-            cachePath: options.tufCachePath,
-            retry: options.retry,
-            timeout: options.timeout,
-        })
-            .then((t) => t.getTarget(path));
-    },
-};
-exports.tuf = tufUtils;
-var error_1 = require("./error");
-Object.defineProperty(exports, "InternalError", { enumerable: true, get: function () { return error_1.InternalError; } });
-Object.defineProperty(exports, "PolicyError", { enumerable: true, get: function () { return error_1.PolicyError; } });
-Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return error_1.ValidationError; } });
-Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return error_1.VerificationError; } });
-exports.utils = __importStar(require("./sigstore-utils"));
-exports.DEFAULT_FULCIO_URL = config.DEFAULT_FULCIO_URL;
-exports.DEFAULT_REKOR_URL = config.DEFAULT_REKOR_URL;
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/format.d.ts b/deps/npm/node_modules/sigstore/dist/tlog/format.d.ts
deleted file mode 100644
index 8a00f546b874fd..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/tlog/format.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-/// 
-import { SignatureMaterial } from '../types/signature';
-import { Envelope } from '../types/sigstore';
-import type { ProposedDSSEEntry, ProposedHashedRekordEntry, ProposedIntotoEntry } from '../external/rekor';
-export declare function toProposedDSSEEntry(envelope: Envelope, signature: SignatureMaterial, apiVersion?: string): ProposedDSSEEntry;
-export declare function toProposedHashedRekordEntry(digest: Buffer, signature: SignatureMaterial): ProposedHashedRekordEntry;
-export declare function toProposedIntotoEntry(envelope: Envelope, signature: SignatureMaterial, apiVersion?: string): ProposedIntotoEntry;
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/index.d.ts b/deps/npm/node_modules/sigstore/dist/tlog/index.d.ts
deleted file mode 100644
index 6bb7d42861dc2c..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/tlog/index.d.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/// 
-import { SignatureMaterial } from '../types/signature';
-import * as sigstore from '../types/sigstore';
-import type { Entry } from '../external/rekor';
-import type { FetchOptions } from '../types/fetch';
-interface CreateEntryOptions {
-    fetchOnConflict?: boolean;
-}
-export interface TLog {
-    createMessageSignatureEntry: (digest: Buffer, sigMaterial: SignatureMaterial) => Promise;
-    createDSSEEntry: (envelope: sigstore.Envelope, sigMaterial: SignatureMaterial, options?: CreateEntryOptions) => Promise;
-}
-export type TLogClientOptions = {
-    rekorBaseURL: string;
-} & FetchOptions;
-export declare class TLogClient implements TLog {
-    private rekor;
-    constructor(options: TLogClientOptions);
-    createMessageSignatureEntry(digest: Buffer, sigMaterial: SignatureMaterial, options?: CreateEntryOptions): Promise;
-    createDSSEEntry(envelope: sigstore.Envelope, sigMaterial: SignatureMaterial, options?: CreateEntryOptions): Promise;
-    private createEntry;
-}
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/body.d.ts b/deps/npm/node_modules/sigstore/dist/tlog/verify/body.d.ts
deleted file mode 100644
index 17de4f5c9698ab..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/tlog/verify/body.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-export declare function verifyTLogBody(entry: sigstore.VerifiableTransparencyLogEntry, bundleContent: sigstore.Bundle['content']): boolean;
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/checkpoint.js b/deps/npm/node_modules/sigstore/dist/tlog/verify/checkpoint.js
new file mode 100644
index 00000000000000..f6f35a5cad64dd
--- /dev/null
+++ b/deps/npm/node_modules/sigstore/dist/tlog/verify/checkpoint.js
@@ -0,0 +1,148 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.verifyCheckpoint = void 0;
+const error_1 = require("../../error");
+const util_1 = require("../../util");
+// Separator between the note and the signatures in a checkpoint
+const CHECKPOINT_SEPARATOR = '\n\n';
+// Checkpoint signatures are of the following form:
+// "–  \n"
+// where:
+// - the prefix is an emdash (U+2014).
+// -  gives a human-readable representation of the signing ID.
+// -  is the first 4 bytes of the SHA256 hash of the
+//   associated public key followed by the signature bytes.
+const SIGNATURE_REGEX = /\u2014 (\S+) (\S+)\n/g;
+// Verifies the checkpoint value in the given tlog entry. There are two steps
+// to the verification:
+// 1. Verify that all signatures in the checkpoint can be verified against a
+//    trusted public key
+// 2. Verify that the root hash in the checkpoint matches the root hash in the
+//    inclusion proof
+// See: https://github.com/transparency-dev/formats/blob/main/log/README.md
+function verifyCheckpoint(entry, tlogs) {
+    // Filter tlog instances to just those which were valid at the time of the
+    // entry
+    const validTLogs = filterTLogInstances(tlogs, entry.integratedTime);
+    const inclusionProof = entry.inclusionProof;
+    const signedNote = SignedNote.fromString(inclusionProof.checkpoint.envelope);
+    const checkpoint = LogCheckpoint.fromString(signedNote.note);
+    // Verify that the signatures in the checkpoint are all valid, also check
+    // that the root hash from the checkpoint matches the root hash in the
+    // inclusion proof
+    return (signedNote.verify(validTLogs) &&
+        util_1.crypto.bufferEqual(checkpoint.logHash, inclusionProof.rootHash));
+}
+exports.verifyCheckpoint = verifyCheckpoint;
+// SignedNote represents a signed note from a transparency log checkpoint. Consists
+// of a body (or note) and one more signatures calculated over the body. See
+// https://github.com/transparency-dev/formats/blob/main/log/README.md#signed-envelope
+class SignedNote {
+    constructor(note, signatures) {
+        this.note = note;
+        this.signatures = signatures;
+    }
+    // Deserialize a SignedNote from a string
+    static fromString(envelope) {
+        if (!envelope.includes(CHECKPOINT_SEPARATOR)) {
+            throw new error_1.VerificationError('malformed checkpoint: no separator');
+        }
+        // Split the note into the header and the data portions at the separator
+        const split = envelope.indexOf(CHECKPOINT_SEPARATOR);
+        const header = envelope.slice(0, split + 1);
+        const data = envelope.slice(split + CHECKPOINT_SEPARATOR.length);
+        // Find all the signature lines in the data portion
+        const matches = data.matchAll(SIGNATURE_REGEX);
+        // Parse each of the matched signature lines into the name and signature.
+        // The first four bytes of the signature are the key hint (should match the
+        // first four bytes of the log ID), and the rest is the signature itself.
+        const signatures = Array.from(matches, (match) => {
+            const [, name, signature] = match;
+            const sigBytes = Buffer.from(signature, 'base64');
+            if (sigBytes.length < 5) {
+                throw new error_1.VerificationError('malformed checkpoint: invalid signature');
+            }
+            return {
+                name,
+                keyHint: sigBytes.subarray(0, 4),
+                signature: sigBytes.subarray(4),
+            };
+        });
+        if (signatures.length === 0) {
+            throw new error_1.VerificationError('malformed checkpoint: no signatures');
+        }
+        return new SignedNote(header, signatures);
+    }
+    // Verifies the signatures in the SignedNote. For each signature, the
+    // corresponding transparency log is looked up by the key hint and the
+    // signature is verified against the public key in the transparency log.
+    // Throws an error if any of the signatures are invalid.
+    verify(tlogs) {
+        const data = Buffer.from(this.note, 'utf-8');
+        return this.signatures.every((signature) => {
+            // Find the transparency log instance with the matching key hint
+            const tlog = tlogs.find((tlog) => util_1.crypto.bufferEqual(tlog.logId.keyId.subarray(0, 4), signature.keyHint));
+            if (!tlog) {
+                return false;
+            }
+            const publicKey = util_1.crypto.createPublicKey(tlog.publicKey.rawBytes);
+            return util_1.crypto.verifyBlob(data, publicKey, signature.signature);
+        });
+    }
+}
+// LogCheckpoint represents a transparency log checkpoint. Consists of the
+// following:
+//  - origin: the name of the transparency log
+//  - logSize: the size of the log at the time of the checkpoint
+//  - logHash: the root hash of the log at the time of the checkpoint
+//  - rest: the rest of the checkpoint body, which is a list of log entries
+// See:
+// https://github.com/transparency-dev/formats/blob/main/log/README.md#checkpoint-body
+class LogCheckpoint {
+    constructor(origin, logSize, logHash, rest) {
+        this.origin = origin;
+        this.logSize = logSize;
+        this.logHash = logHash;
+        this.rest = rest;
+    }
+    static fromString(note) {
+        const lines = note.trim().split('\n');
+        if (lines.length < 4) {
+            throw new error_1.VerificationError('malformed checkpoint: too few lines in header');
+        }
+        const origin = lines[0];
+        const logSize = BigInt(lines[1]);
+        const rootHash = Buffer.from(lines[2], 'base64');
+        const rest = lines.slice(3);
+        return new LogCheckpoint(origin, logSize, rootHash, rest);
+    }
+}
+// Filter the list of tlog instances to only those which have usable public
+// keys and were valid at the given time.
+function filterTLogInstances(tlogInstances, integratedTime) {
+    const targetDate = new Date(Number(integratedTime) * 1000);
+    return tlogInstances.filter((tlog) => {
+        // Must have a log ID
+        if (!tlog.logId) {
+            return false;
+        }
+        // If the tlog doesn't have a public key, we can't use it
+        const publicKey = tlog.publicKey;
+        if (publicKey === undefined) {
+            return false;
+        }
+        // If the tlog doesn't have a rawBytes field, we can't use it
+        if (publicKey.rawBytes === undefined) {
+            return false;
+        }
+        // If the tlog doesn't have a validFor field, we don't need to check it
+        const validFor = publicKey.validFor;
+        if (validFor === undefined) {
+            return true;
+        }
+        // Check that the integrated time is within the validFor range
+        return (validFor.start !== undefined &&
+            validFor.start <= targetDate &&
+            (validFor.end === undefined || targetDate <= validFor.end));
+    });
+}
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/index.d.ts b/deps/npm/node_modules/sigstore/dist/tlog/verify/index.d.ts
deleted file mode 100644
index 4f96f820731f03..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/tlog/verify/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-export declare function verifyTLogEntries(bundle: sigstore.Bundle, trustedRoot: sigstore.TrustedRoot, options: sigstore.ArtifactVerificationOptions_TlogOptions): void;
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/index.js b/deps/npm/node_modules/sigstore/dist/tlog/verify/index.js
index cbb93133c2685f..9224feffde00b0 100644
--- a/deps/npm/node_modules/sigstore/dist/tlog/verify/index.js
+++ b/deps/npm/node_modules/sigstore/dist/tlog/verify/index.js
@@ -1,27 +1,4 @@
 "use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    var desc = Object.getOwnPropertyDescriptor(m, k);
-    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
-      desc = { enumerable: true, get: function() { return m[k]; } };
-    }
-    Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
-    Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
-    o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
-    if (mod && mod.__esModule) return mod;
-    var result = {};
-    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
-    __setModuleDefault(result, mod);
-    return result;
-};
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.verifyTLogEntries = void 0;
 /*
@@ -39,31 +16,51 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
+const bundle_1 = require("@sigstore/bundle");
 const error_1 = require("../../error");
-const sigstore = __importStar(require("../../types/sigstore"));
 const cert_1 = require("../../x509/cert");
 const body_1 = require("./body");
+const checkpoint_1 = require("./checkpoint");
+const merkle_1 = require("./merkle");
 const set_1 = require("./set");
 // Verifies that the number of tlog entries that pass offline verification
 // is greater than or equal to the threshold specified in the options.
 function verifyTLogEntries(bundle, trustedRoot, options) {
+    if (bundle.mediaType === bundle_1.BUNDLE_V01_MEDIA_TYPE) {
+        (0, bundle_1.assertBundleV01)(bundle);
+        verifyTLogEntriesForBundleV01(bundle, trustedRoot, options);
+    }
+    else {
+        (0, bundle_1.assertBundleLatest)(bundle);
+        verifyTLogEntriesForBundleLatest(bundle, trustedRoot, options);
+    }
+}
+exports.verifyTLogEntries = verifyTLogEntries;
+function verifyTLogEntriesForBundleV01(bundle, trustedRoot, options) {
     if (options.performOnlineVerification) {
         throw new error_1.VerificationError('Online verification not implemented');
     }
     // Extract the signing cert, if available
     const signingCert = signingCertificate(bundle);
     // Iterate over the tlog entries and verify each one
-    const verifiedEntries = bundle.verificationMaterial.tlogEntries.filter((entry) => verifyTLogEntryOffline(entry, bundle.content, trustedRoot.tlogs, signingCert));
+    const verifiedEntries = bundle.verificationMaterial.tlogEntries.filter((entry) => verifyTLogEntryWithInclusionPromise(entry, bundle.content, trustedRoot.tlogs, signingCert));
     if (verifiedEntries.length < options.threshold) {
         throw new error_1.VerificationError('tlog verification failed');
     }
 }
-exports.verifyTLogEntries = verifyTLogEntries;
-function verifyTLogEntryOffline(entry, bundleContent, tlogs, signingCert) {
-    // Check that the TLog entry has the fields necessary for verification
-    if (!sigstore.isVerifiableTransparencyLogEntry(entry)) {
-        return false;
+function verifyTLogEntriesForBundleLatest(bundle, trustedRoot, options) {
+    if (options.performOnlineVerification) {
+        throw new error_1.VerificationError('Online verification not implemented');
+    }
+    // Extract the signing cert, if available
+    const signingCert = signingCertificate(bundle);
+    // Iterate over the tlog entries and verify each one
+    const verifiedEntries = bundle.verificationMaterial.tlogEntries.filter((entry) => verifyTLogEntryWithInclusionProof(entry, bundle.content, trustedRoot.tlogs, signingCert));
+    if (verifiedEntries.length < options.threshold) {
+        throw new error_1.VerificationError('tlog verification failed');
     }
+}
+function verifyTLogEntryWithInclusionPromise(entry, bundleContent, tlogs, signingCert) {
     // If there is a signing certificate availble, check that the tlog integrated
     // time is within the certificate's validity period; otherwise, skip this
     // check.
@@ -74,8 +71,20 @@ function verifyTLogEntryOffline(entry, bundleContent, tlogs, signingCert) {
         (0, set_1.verifyTLogSET)(entry, tlogs) &&
         verifyTLogIntegrationTime());
 }
+function verifyTLogEntryWithInclusionProof(entry, bundleContent, tlogs, signingCert) {
+    // If there is a signing certificate availble, check that the tlog integrated
+    // time is within the certificate's validity period; otherwise, skip this
+    // check.
+    const verifyTLogIntegrationTime = signingCert
+        ? () => signingCert.validForDate(new Date(Number(entry.integratedTime) * 1000))
+        : () => true;
+    return ((0, body_1.verifyTLogBody)(entry, bundleContent) &&
+        (0, merkle_1.verifyMerkleInclusion)(entry) &&
+        (0, checkpoint_1.verifyCheckpoint)(entry, tlogs) &&
+        verifyTLogIntegrationTime());
+}
 function signingCertificate(bundle) {
-    if (!sigstore.isBundleWithCertificateChain(bundle)) {
+    if (!(0, bundle_1.isBundleWithCertificateChain)(bundle)) {
         return undefined;
     }
     const signingCert = bundle.verificationMaterial.content.x509CertificateChain.certificates[0];
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/merkle.d.ts b/deps/npm/node_modules/sigstore/dist/tlog/verify/merkle.d.ts
deleted file mode 100644
index a2c47626d01f84..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/tlog/verify/merkle.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-export declare function verifyMerkleInclusion(entry: sigstore.TransparencyLogEntry): boolean;
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/merkle.js b/deps/npm/node_modules/sigstore/dist/tlog/verify/merkle.js
index 90609cb73576fe..0f246af4a28a3b 100644
--- a/deps/npm/node_modules/sigstore/dist/tlog/verify/merkle.js
+++ b/deps/npm/node_modules/sigstore/dist/tlog/verify/merkle.js
@@ -25,9 +25,6 @@ const RFC6962_LEAF_HASH_PREFIX = Buffer.from([0x00]);
 const RFC6962_NODE_HASH_PREFIX = Buffer.from([0x01]);
 function verifyMerkleInclusion(entry) {
     const inclusionProof = entry.inclusionProof;
-    if (!inclusionProof) {
-        throw new error_1.VerificationError('tlog entry has no inclusion proof');
-    }
     const logIndex = BigInt(inclusionProof.logIndex);
     const treeSize = BigInt(inclusionProof.treeSize);
     if (logIndex < 0n || logIndex >= treeSize) {
@@ -76,13 +73,20 @@ function chainBorderRight(seed, hashes) {
     return hashes.reduce((acc, h) => hashChildren(h, acc), seed);
 }
 function innerProofSize(index, size) {
-    return (index ^ (size - BigInt(1))).toString(2).length;
+    return bitLength(index ^ (size - BigInt(1)));
 }
 // Counts the number of ones in the binary representation of the given number.
 // https://en.wikipedia.org/wiki/Hamming_weight
 function onesCount(x) {
     return x.toString(2).split('1').length - 1;
 }
+// Returns the number of bits necessary to represent an integer in binary.
+function bitLength(n) {
+    if (n === 0n) {
+        return 0;
+    }
+    return n.toString(2).length;
+}
 // Hashing logic according to RFC6962.
 // https://datatracker.ietf.org/doc/html/rfc6962#section-2
 function hashChildren(left, right) {
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/set.d.ts b/deps/npm/node_modules/sigstore/dist/tlog/verify/set.d.ts
deleted file mode 100644
index 278317489a7e49..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/tlog/verify/set.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as sigstore from '../../types/sigstore';
-export declare function verifyTLogSET(entry: sigstore.VerifiableTransparencyLogEntry, tlogs: sigstore.TransparencyLogInstance[]): boolean;
diff --git a/deps/npm/node_modules/sigstore/dist/tlog/verify/set.js b/deps/npm/node_modules/sigstore/dist/tlog/verify/set.js
index 89a544283d73d9..959cd5883f1cad 100644
--- a/deps/npm/node_modules/sigstore/dist/tlog/verify/set.js
+++ b/deps/npm/node_modules/sigstore/dist/tlog/verify/set.js
@@ -11,9 +11,6 @@ function verifyTLogSET(entry, tlogs) {
     const validTLogs = filterTLogInstances(tlogs, entry.logId.keyId, entry.integratedTime);
     // Check to see if we can verify the SET against any of the valid tlogs
     return validTLogs.some((tlog) => {
-        if (!tlog.publicKey?.rawBytes) {
-            return false;
-        }
         const publicKey = util_1.crypto.createPublicKey(tlog.publicKey.rawBytes);
         // Re-create the original Rekor verification payload
         const payload = toVerificationPayload(entry);
@@ -60,7 +57,7 @@ function filterTLogInstances(tlogInstances, logID, integratedTime) {
             return true;
         }
         // Check that the integrated time is within the validFor range
-        return (publicKey.validFor.start &&
+        return (publicKey.validFor.start !== undefined &&
             publicKey.validFor.start <= targetDate &&
             (!publicKey.validFor.end || targetDate <= publicKey.validFor.end));
     });
diff --git a/deps/npm/node_modules/sigstore/dist/tsa/index.d.ts b/deps/npm/node_modules/sigstore/dist/tsa/index.d.ts
deleted file mode 100644
index e94b20c075e557..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/tsa/index.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-/// 
-import type { FetchOptions } from '../types/fetch';
-export interface TSA {
-    createTimestamp: (signature: Buffer) => Promise;
-}
-export type TSAClientOptions = {
-    tsaBaseURL: string;
-} & FetchOptions;
-export declare class TSAClient implements TSA {
-    private tsa;
-    constructor(options: TSAClientOptions);
-    createTimestamp(signature: Buffer): Promise;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/types/fetch.d.ts b/deps/npm/node_modules/sigstore/dist/types/fetch.d.ts
deleted file mode 100644
index 510aeee6a37d72..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/fetch.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import type { MakeFetchHappenOptions } from 'make-fetch-happen';
-export type Retry = MakeFetchHappenOptions['retry'];
-export type FetchOptions = {
-    retry?: Retry;
-    timeout?: number | undefined;
-};
diff --git a/deps/npm/node_modules/sigstore/dist/types/signature.d.ts b/deps/npm/node_modules/sigstore/dist/types/signature.d.ts
deleted file mode 100644
index 40b4fbe6339ca6..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/signature.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/// 
-import { Envelope } from './sigstore';
-import { OneOf } from './utility';
-interface VerificationMaterial {
-    certificates: string[];
-    key: {
-        id?: string;
-        value: string;
-    };
-}
-export type SignatureMaterial = {
-    signature: Buffer;
-} & OneOf;
-export type SignerFunc = (payload: Buffer) => Promise;
-export declare function extractSignatureMaterial(dsseEnvelope: Envelope, publicKey: string): SignatureMaterial;
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/types/signature.js b/deps/npm/node_modules/sigstore/dist/types/signature.js
deleted file mode 100644
index 339e2a2731b413..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/signature.js
+++ /dev/null
@@ -1,15 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.extractSignatureMaterial = void 0;
-function extractSignatureMaterial(dsseEnvelope, publicKey) {
-    const signature = dsseEnvelope.signatures[0];
-    return {
-        signature: signature.sig,
-        key: {
-            id: signature.keyid,
-            value: publicKey,
-        },
-        certificates: undefined,
-    };
-}
-exports.extractSignatureMaterial = extractSignatureMaterial;
diff --git a/deps/npm/node_modules/sigstore/dist/types/sigstore.js b/deps/npm/node_modules/sigstore/dist/types/sigstore.js
new file mode 100644
index 00000000000000..36efb67e38a5eb
--- /dev/null
+++ b/deps/npm/node_modules/sigstore/dist/types/sigstore.js
@@ -0,0 +1,27 @@
+"use strict";
+/*
+Copyright 2023 The Sigstore Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.isCAVerificationOptions = exports.SubjectAlternativeNameType = void 0;
+// Enums from protobuf-specs
+var protobuf_specs_1 = require("@sigstore/protobuf-specs");
+Object.defineProperty(exports, "SubjectAlternativeNameType", { enumerable: true, get: function () { return protobuf_specs_1.SubjectAlternativeNameType; } });
+function isCAVerificationOptions(options) {
+    return (options.ctlogOptions !== undefined &&
+        (options.signers === undefined ||
+            options.signers.$case === 'certificateIdentities'));
+}
+exports.isCAVerificationOptions = isCAVerificationOptions;
diff --git a/deps/npm/node_modules/sigstore/dist/types/sigstore/index.d.ts b/deps/npm/node_modules/sigstore/dist/types/sigstore/index.d.ts
deleted file mode 100644
index 2be598d923048f..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/sigstore/index.d.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/// 
-import { SignatureMaterial } from '../signature';
-import { ValidBundle } from './validate';
-import type { ArtifactVerificationOptions, Envelope, TransparencyLogEntry, VerificationMaterial } from '@sigstore/protobuf-specs';
-import type { Entry } from '../../external/rekor';
-import type { WithRequired } from '../utility';
-import type { SerializedBundle } from './serialized';
-export { Envelope, HashAlgorithm, PublicKeyDetails, SubjectAlternativeNameType, } from '@sigstore/protobuf-specs';
-export type { ArtifactVerificationOptions, ArtifactVerificationOptions_CtlogOptions, ArtifactVerificationOptions_TlogOptions, CertificateAuthority, CertificateIdentities, CertificateIdentity, MessageSignature, ObjectIdentifierValuePair, PublicKey, PublicKeyIdentifier, RFC3161SignedTimestamp, Signature, SubjectAlternativeName, TimestampVerificationData, TransparencyLogEntry, TransparencyLogInstance, TrustedRoot, X509Certificate, X509CertificateChain, } from '@sigstore/protobuf-specs';
-export type { SerializedBundle, SerializedEnvelope } from './serialized';
-export type { ValidBundle as Bundle };
-export declare const bundleFromJSON: (obj: any) => ValidBundle;
-export declare const bundleToJSON: (bundle: ValidBundle) => SerializedBundle;
-export type BundleWithCertificateChain = ValidBundle & {
-    verificationMaterial: VerificationMaterial & {
-        content: Extract;
-    };
-};
-export declare function isBundleWithCertificateChain(bundle: ValidBundle): bundle is BundleWithCertificateChain;
-export type RequiredArtifactVerificationOptions = WithRequired;
-export type CAArtifactVerificationOptions = WithRequired & {
-    signers?: Extract;
-};
-export declare function isCAVerificationOptions(options: ArtifactVerificationOptions): options is CAArtifactVerificationOptions;
-export type VerifiableTransparencyLogEntry = WithRequired;
-export declare function isVerifiableTransparencyLogEntry(entry: TransparencyLogEntry): entry is VerifiableTransparencyLogEntry;
-export declare function toDSSEBundle({ envelope, signature, tlogEntry, timestamp, }: {
-    envelope: Envelope;
-    signature: SignatureMaterial;
-    tlogEntry?: Entry;
-    timestamp?: Buffer;
-}): ValidBundle;
-export declare function toMessageSignatureBundle({ digest, signature, tlogEntry, timestamp, }: {
-    digest: Buffer;
-    signature: SignatureMaterial;
-    tlogEntry?: Entry;
-    timestamp?: Buffer;
-}): ValidBundle;
diff --git a/deps/npm/node_modules/sigstore/dist/types/sigstore/index.js b/deps/npm/node_modules/sigstore/dist/types/sigstore/index.js
deleted file mode 100644
index 2c240c865cf37a..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/sigstore/index.js
+++ /dev/null
@@ -1,162 +0,0 @@
-"use strict";
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.toMessageSignatureBundle = exports.toDSSEBundle = exports.isVerifiableTransparencyLogEntry = exports.isCAVerificationOptions = exports.isBundleWithCertificateChain = exports.bundleToJSON = exports.bundleFromJSON = exports.SubjectAlternativeNameType = exports.PublicKeyDetails = exports.HashAlgorithm = exports.Envelope = void 0;
-/*
-Copyright 2023 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-const protobuf_specs_1 = require("@sigstore/protobuf-specs");
-const util_1 = require("../../util");
-const validate_1 = require("./validate");
-// Enums from protobuf-specs
-// TODO: Move Envelope to "type" export once @sigstore/sign is a thing
-var protobuf_specs_2 = require("@sigstore/protobuf-specs");
-Object.defineProperty(exports, "Envelope", { enumerable: true, get: function () { return protobuf_specs_2.Envelope; } });
-Object.defineProperty(exports, "HashAlgorithm", { enumerable: true, get: function () { return protobuf_specs_2.HashAlgorithm; } });
-Object.defineProperty(exports, "PublicKeyDetails", { enumerable: true, get: function () { return protobuf_specs_2.PublicKeyDetails; } });
-Object.defineProperty(exports, "SubjectAlternativeNameType", { enumerable: true, get: function () { return protobuf_specs_2.SubjectAlternativeNameType; } });
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const bundleFromJSON = (obj) => {
-    const bundle = protobuf_specs_1.Bundle.fromJSON(obj);
-    (0, validate_1.assertValidBundle)(bundle);
-    return bundle;
-};
-exports.bundleFromJSON = bundleFromJSON;
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const bundleToJSON = (bundle) => {
-    return protobuf_specs_1.Bundle.toJSON(bundle);
-};
-exports.bundleToJSON = bundleToJSON;
-const BUNDLE_MEDIA_TYPE = 'application/vnd.dev.sigstore.bundle+json;version=0.1';
-// Type guard for narrowing a Bundle to a BundleWithCertificateChain
-function isBundleWithCertificateChain(bundle) {
-    return (bundle.verificationMaterial.content !== undefined &&
-        bundle.verificationMaterial.content.$case === 'x509CertificateChain');
-}
-exports.isBundleWithCertificateChain = isBundleWithCertificateChain;
-function isCAVerificationOptions(options) {
-    return (options.ctlogOptions !== undefined &&
-        (options.signers === undefined ||
-            options.signers.$case === 'certificateIdentities'));
-}
-exports.isCAVerificationOptions = isCAVerificationOptions;
-function isVerifiableTransparencyLogEntry(entry) {
-    return (entry.logId !== undefined &&
-        entry.inclusionPromise !== undefined &&
-        entry.kindVersion !== undefined);
-}
-exports.isVerifiableTransparencyLogEntry = isVerifiableTransparencyLogEntry;
-// All of the following functions are used to construct a ValidBundle
-// from various types of input. When this code moves into the
-// @sigstore/sign package, these functions will be exported from there.
-function toDSSEBundle({ envelope, signature, tlogEntry, timestamp, }) {
-    return {
-        mediaType: BUNDLE_MEDIA_TYPE,
-        content: { $case: 'dsseEnvelope', dsseEnvelope: envelope },
-        verificationMaterial: toVerificationMaterial({
-            signature,
-            tlogEntry,
-            timestamp,
-        }),
-    };
-}
-exports.toDSSEBundle = toDSSEBundle;
-function toMessageSignatureBundle({ digest, signature, tlogEntry, timestamp, }) {
-    return {
-        mediaType: BUNDLE_MEDIA_TYPE,
-        content: {
-            $case: 'messageSignature',
-            messageSignature: {
-                messageDigest: {
-                    algorithm: protobuf_specs_1.HashAlgorithm.SHA2_256,
-                    digest: digest,
-                },
-                signature: signature.signature,
-            },
-        },
-        verificationMaterial: toVerificationMaterial({
-            signature,
-            tlogEntry,
-            timestamp,
-        }),
-    };
-}
-exports.toMessageSignatureBundle = toMessageSignatureBundle;
-function toTransparencyLogEntry(entry) {
-    const b64SET = entry.verification?.signedEntryTimestamp || '';
-    const set = Buffer.from(b64SET, 'base64');
-    const logID = Buffer.from(entry.logID, 'hex');
-    const proof = entry.verification?.inclusionProof
-        ? toInclusionProof(entry.verification.inclusionProof)
-        : undefined;
-    // Parse entry body so we can extract the kind and version.
-    const bodyJSON = util_1.encoding.base64Decode(entry.body);
-    const entryBody = JSON.parse(bodyJSON);
-    return {
-        inclusionPromise: {
-            signedEntryTimestamp: set,
-        },
-        logIndex: entry.logIndex.toString(),
-        logId: {
-            keyId: logID,
-        },
-        integratedTime: entry.integratedTime.toString(),
-        kindVersion: {
-            kind: entryBody.kind,
-            version: entryBody.apiVersion,
-        },
-        inclusionProof: proof,
-        canonicalizedBody: Buffer.from(entry.body, 'base64'),
-    };
-}
-function toInclusionProof(proof) {
-    return {
-        logIndex: proof.logIndex.toString(),
-        rootHash: Buffer.from(proof.rootHash, 'hex'),
-        treeSize: proof.treeSize.toString(),
-        checkpoint: {
-            envelope: proof.checkpoint,
-        },
-        hashes: proof.hashes.map((h) => Buffer.from(h, 'hex')),
-    };
-}
-function toVerificationMaterial({ signature, tlogEntry, timestamp, }) {
-    return {
-        content: signature.certificates
-            ? toVerificationMaterialx509CertificateChain(signature.certificates)
-            : toVerificationMaterialPublicKey(signature.key.id || ''),
-        tlogEntries: tlogEntry ? [toTransparencyLogEntry(tlogEntry)] : [],
-        timestampVerificationData: timestamp
-            ? toTimestampVerificationData(timestamp)
-            : undefined,
-    };
-}
-function toVerificationMaterialx509CertificateChain(certificates) {
-    return {
-        $case: 'x509CertificateChain',
-        x509CertificateChain: {
-            certificates: certificates.map((c) => ({
-                rawBytes: util_1.pem.toDER(c),
-            })),
-        },
-    };
-}
-function toVerificationMaterialPublicKey(hint) {
-    return { $case: 'publicKey', publicKey: { hint } };
-}
-function toTimestampVerificationData(timestamp) {
-    return {
-        rfc3161Timestamps: [{ signedTimestamp: timestamp }],
-    };
-}
diff --git a/deps/npm/node_modules/sigstore/dist/types/sigstore/serialized.d.ts b/deps/npm/node_modules/sigstore/dist/types/sigstore/serialized.d.ts
deleted file mode 100644
index 8ea3b5cff35ee9..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/sigstore/serialized.d.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { OneOf } from '../utility';
-type SerializedTLogEntry = {
-    logIndex: string;
-    logId: {
-        keyId: string;
-    };
-    kindVersion: {
-        kind: string;
-        version: string;
-    } | undefined;
-    integratedTime: string;
-    inclusionPromise: {
-        signedEntryTimestamp: string;
-    };
-    inclusionProof: {
-        logIndex: string;
-        rootHash: string;
-        treeSize: string;
-        hashes: string[];
-        checkpoint: {
-            envelope: string;
-        };
-    } | undefined;
-    canonicalizedBody: string;
-};
-type SerializedTimestampVerificationData = {
-    rfc3161Timestamps: {
-        signedTimestamp: string;
-    }[];
-};
-type SerializedMessageSignature = {
-    messageDigest: {
-        algorithm: string;
-        digest: string;
-    } | undefined;
-    signature: string;
-};
-type SerializedDSSEEnvelope = {
-    payload: string;
-    payloadType: string;
-    signatures: {
-        sig: string;
-        keyid: string;
-    }[];
-};
-export type { SerializedDSSEEnvelope as SerializedEnvelope };
-export type SerializedBundle = {
-    mediaType: string;
-    verificationMaterial: (OneOf<{
-        x509CertificateChain: {
-            certificates: {
-                rawBytes: string;
-            }[];
-        };
-        publicKey: {
-            hint: string;
-        };
-    }> | undefined) & {
-        tlogEntries: SerializedTLogEntry[];
-        timestampVerificationData: SerializedTimestampVerificationData | undefined;
-    };
-} & OneOf<{
-    dsseEnvelope: SerializedDSSEEnvelope;
-    messageSignature: SerializedMessageSignature;
-}>;
diff --git a/deps/npm/node_modules/sigstore/dist/types/sigstore/validate.d.ts b/deps/npm/node_modules/sigstore/dist/types/sigstore/validate.d.ts
deleted file mode 100644
index a6c33b3c7c0f28..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/sigstore/validate.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { WithRequired } from '../utility';
-import type { Bundle, MessageSignature, VerificationMaterial } from '@sigstore/protobuf-specs';
-export type ValidBundle = Bundle & {
-    verificationMaterial: VerificationMaterial & {
-        content: NonNullable;
-    };
-    content: (Extract & {
-        messageSignature: WithRequired;
-    }) | Extract;
-};
-export declare function assertValidBundle(b: Bundle): asserts b is ValidBundle;
diff --git a/deps/npm/node_modules/sigstore/dist/types/utility.d.ts b/deps/npm/node_modules/sigstore/dist/types/utility.d.ts
deleted file mode 100644
index df993d503f8ea1..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/types/utility.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-type ValueOf = Obj[keyof Obj];
-type OneOnly = {
-    [key in Exclude]: undefined;
-} & {
-    [key in K]: Obj[K];
-};
-type OneOfByKey = {
-    [key in keyof Obj]: OneOnly;
-};
-export type OneOf = ValueOf>;
-export type WithRequired = T & {
-    [P in K]-?: NonNullable;
-};
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/types/utility.js b/deps/npm/node_modules/sigstore/dist/types/utility.js
index 132848cd7587e7..77c91b1923ca08 100644
--- a/deps/npm/node_modules/sigstore/dist/types/utility.js
+++ b/deps/npm/node_modules/sigstore/dist/types/utility.js
@@ -14,5 +14,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
-// https://dev.to/maxime1992/implement-a-generic-oneof-type-with-typescript-22em
 Object.defineProperty(exports, "__esModule", { value: true });
diff --git a/deps/npm/node_modules/sigstore/dist/util/asn1/dump.d.ts b/deps/npm/node_modules/sigstore/dist/util/asn1/dump.d.ts
deleted file mode 100644
index 3f192dea45445c..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/asn1/dump.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-import { ASN1Obj } from './obj';
-export declare function dump(obj: ASN1Obj, indent?: number): void;
diff --git a/deps/npm/node_modules/sigstore/dist/util/asn1/error.d.ts b/deps/npm/node_modules/sigstore/dist/util/asn1/error.d.ts
deleted file mode 100644
index fcd908f47036ac..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/asn1/error.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export declare class ASN1ParseError extends Error {
-}
-export declare class ASN1TypeError extends Error {
-}
diff --git a/deps/npm/node_modules/sigstore/dist/util/asn1/index.d.ts b/deps/npm/node_modules/sigstore/dist/util/asn1/index.d.ts
deleted file mode 100644
index da45453d4eab7b..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/asn1/index.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { ASN1Obj } from './obj';
diff --git a/deps/npm/node_modules/sigstore/dist/util/asn1/length.d.ts b/deps/npm/node_modules/sigstore/dist/util/asn1/length.d.ts
deleted file mode 100644
index 97c7114af29091..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/asn1/length.d.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-/// 
-import { ByteStream } from '../stream';
-export declare function decodeLength(stream: ByteStream): number;
-export declare function encodeLength(len: number): Buffer;
diff --git a/deps/npm/node_modules/sigstore/dist/util/asn1/obj.d.ts b/deps/npm/node_modules/sigstore/dist/util/asn1/obj.d.ts
deleted file mode 100644
index de54996c87faac..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/asn1/obj.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-/// 
-import { ASN1Tag } from './tag';
-export declare class ASN1Obj {
-    readonly tag: ASN1Tag;
-    readonly subs: ASN1Obj[];
-    readonly value: Buffer;
-    constructor(tag: ASN1Tag, value: Buffer, subs: ASN1Obj[]);
-    static parseBuffer(buf: Buffer): ASN1Obj;
-    toDER(): Buffer;
-    toBoolean(): boolean;
-    toInteger(): bigint;
-    toOID(): string;
-    toDate(): Date;
-    toBitString(): number[];
-}
diff --git a/deps/npm/node_modules/sigstore/dist/util/asn1/parse.d.ts b/deps/npm/node_modules/sigstore/dist/util/asn1/parse.d.ts
deleted file mode 100644
index 35989d5510e26b..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/asn1/parse.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-/// 
-export declare function parseInteger(buf: Buffer): bigint;
-export declare function parseStringASCII(buf: Buffer): string;
-export declare function parseTime(buf: Buffer, shortYear: boolean): Date;
-export declare function parseOID(buf: Buffer): string;
-export declare function parseBoolean(buf: Buffer): boolean;
-export declare function parseBitString(buf: Buffer): number[];
diff --git a/deps/npm/node_modules/sigstore/dist/util/asn1/tag.d.ts b/deps/npm/node_modules/sigstore/dist/util/asn1/tag.d.ts
deleted file mode 100644
index cdc9a69097b380..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/asn1/tag.d.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-export declare const UNIVERSAL_TAG: {
-    BOOLEAN: number;
-    INTEGER: number;
-    BIT_STRING: number;
-    OCTET_STRING: number;
-    OBJECT_IDENTIFIER: number;
-    SEQUENCE: number;
-    SET: number;
-    PRINTABLE_STRING: number;
-    UTC_TIME: number;
-    GENERALIZED_TIME: number;
-};
-export declare class ASN1Tag {
-    readonly number: number;
-    readonly constructed: boolean;
-    readonly class: number;
-    constructor(enc: number);
-    isUniversal(): boolean;
-    isContextSpecific(num?: number): boolean;
-    isBoolean(): boolean;
-    isInteger(): boolean;
-    isBitString(): boolean;
-    isOctetString(): boolean;
-    isOID(): boolean;
-    isUTCTime(): boolean;
-    isGeneralizedTime(): boolean;
-    toDER(): number;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/util/crypto.d.ts b/deps/npm/node_modules/sigstore/dist/util/crypto.d.ts
deleted file mode 100644
index a726dd260750c3..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/crypto.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/// 
-/// 
-/// 
-import { BinaryLike, KeyLike, KeyPairKeyObjectResult } from 'crypto';
-export declare function generateKeyPair(): KeyPairKeyObjectResult;
-export declare function createPublicKey(key: string | Buffer): KeyLike;
-export declare function signBlob(data: NodeJS.ArrayBufferView, privateKey: KeyLike): Buffer;
-export declare function verifyBlob(data: Buffer, key: KeyLike, signature: Buffer, algorithm?: string): boolean;
-export declare function hash(data: BinaryLike): Buffer;
-export declare function randomBytes(count: number): Buffer;
diff --git a/deps/npm/node_modules/sigstore/dist/util/crypto.js b/deps/npm/node_modules/sigstore/dist/util/crypto.js
index 0b1e0bc62d8abb..c26de091ecdb62 100644
--- a/deps/npm/node_modules/sigstore/dist/util/crypto.js
+++ b/deps/npm/node_modules/sigstore/dist/util/crypto.js
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.randomBytes = exports.hash = exports.verifyBlob = exports.signBlob = exports.createPublicKey = exports.generateKeyPair = void 0;
+exports.bufferEqual = exports.randomBytes = exports.hash = exports.verifyBlob = exports.createPublicKey = void 0;
 /*
 Copyright 2022 The Sigstore Authors.
 
@@ -20,15 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 const crypto_1 = __importDefault(require("crypto"));
-const EC_KEYPAIR_TYPE = 'ec';
-const P256_CURVE = 'P-256';
 const SHA256_ALGORITHM = 'sha256';
-function generateKeyPair() {
-    return crypto_1.default.generateKeyPairSync(EC_KEYPAIR_TYPE, {
-        namedCurve: P256_CURVE,
-    });
-}
-exports.generateKeyPair = generateKeyPair;
 function createPublicKey(key) {
     if (typeof key === 'string') {
         return crypto_1.default.createPublicKey(key);
@@ -38,10 +30,6 @@ function createPublicKey(key) {
     }
 }
 exports.createPublicKey = createPublicKey;
-function signBlob(data, privateKey) {
-    return crypto_1.default.sign(null, data, privateKey);
-}
-exports.signBlob = signBlob;
 function verifyBlob(data, key, signature, algorithm) {
     // The try/catch is to work around an issue in Node 14.x where verify throws
     // an error in some scenarios if the signature is invalid.
@@ -49,6 +37,7 @@ function verifyBlob(data, key, signature, algorithm) {
         return crypto_1.default.verify(algorithm, data, key, signature);
     }
     catch (e) {
+        /* istanbul ignore next */
         return false;
     }
 }
@@ -62,3 +51,13 @@ function randomBytes(count) {
     return crypto_1.default.randomBytes(count);
 }
 exports.randomBytes = randomBytes;
+function bufferEqual(a, b) {
+    try {
+        return crypto_1.default.timingSafeEqual(a, b);
+    }
+    catch {
+        /* istanbul ignore next */
+        return false;
+    }
+}
+exports.bufferEqual = bufferEqual;
diff --git a/deps/npm/node_modules/sigstore/dist/util/dsse.d.ts b/deps/npm/node_modules/sigstore/dist/util/dsse.d.ts
deleted file mode 100644
index 839b9c03ce38c7..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/dsse.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-/// 
-export declare function preAuthEncoding(payloadType: string, payload: Buffer): Buffer;
diff --git a/deps/npm/node_modules/sigstore/dist/util/encoding.d.ts b/deps/npm/node_modules/sigstore/dist/util/encoding.d.ts
deleted file mode 100644
index f1347c241ed0c4..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/encoding.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export declare function base64Encode(str: string): string;
-export declare function base64Decode(str: string): string;
-export declare function base64URLEncode(str: string): string;
-export declare function base64URLDecode(str: string): string;
-export declare function base64URLEscape(str: string): string;
-export declare function base64URLUnescape(str: string): string;
diff --git a/deps/npm/node_modules/sigstore/dist/util/index.d.ts b/deps/npm/node_modules/sigstore/dist/util/index.d.ts
deleted file mode 100644
index f062a1c9d3c57d..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/index.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export * as asn1 from './asn1';
-export * as crypto from './crypto';
-export * as dsse from './dsse';
-export * as encoding from './encoding';
-export * as json from './json';
-export * as oidc from './oidc';
-export * as pem from './pem';
-export * as promise from './promise';
-export * as ua from './ua';
diff --git a/deps/npm/node_modules/sigstore/dist/util/index.js b/deps/npm/node_modules/sigstore/dist/util/index.js
index b7d6ce21aafd3b..ff4cec375af8f8 100644
--- a/deps/npm/node_modules/sigstore/dist/util/index.js
+++ b/deps/npm/node_modules/sigstore/dist/util/index.js
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
     return result;
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.ua = exports.promise = exports.pem = exports.oidc = exports.json = exports.encoding = exports.dsse = exports.crypto = exports.asn1 = void 0;
+exports.pem = exports.json = exports.encoding = exports.dsse = exports.crypto = exports.asn1 = void 0;
 /*
 Copyright 2022 The Sigstore Authors.
 
@@ -44,7 +44,4 @@ exports.crypto = __importStar(require("./crypto"));
 exports.dsse = __importStar(require("./dsse"));
 exports.encoding = __importStar(require("./encoding"));
 exports.json = __importStar(require("./json"));
-exports.oidc = __importStar(require("./oidc"));
 exports.pem = __importStar(require("./pem"));
-exports.promise = __importStar(require("./promise"));
-exports.ua = __importStar(require("./ua"));
diff --git a/deps/npm/node_modules/sigstore/dist/util/json.d.ts b/deps/npm/node_modules/sigstore/dist/util/json.d.ts
deleted file mode 100644
index ed331817ef2360..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/json.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export declare function canonicalize(object: any): string;
diff --git a/deps/npm/node_modules/sigstore/dist/util/oidc.d.ts b/deps/npm/node_modules/sigstore/dist/util/oidc.d.ts
deleted file mode 100644
index b4513891a3527f..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/oidc.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export declare function extractJWTSubject(jwt: string): string;
diff --git a/deps/npm/node_modules/sigstore/dist/util/pem.d.ts b/deps/npm/node_modules/sigstore/dist/util/pem.d.ts
deleted file mode 100644
index 6910679cae0654..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/pem.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-/// 
-export declare function toDER(certificate: string): Buffer;
-export declare function fromDER(certificate: Buffer, type?: string): string;
diff --git a/deps/npm/node_modules/sigstore/dist/util/promise.d.ts b/deps/npm/node_modules/sigstore/dist/util/promise.d.ts
deleted file mode 100644
index bbc501a85a7c60..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/promise.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export declare const promiseAny: (values: Iterable>) => Promise;
diff --git a/deps/npm/node_modules/sigstore/dist/util/promise.js b/deps/npm/node_modules/sigstore/dist/util/promise.js
deleted file mode 100644
index 8101dd47afe026..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/promise.js
+++ /dev/null
@@ -1,27 +0,0 @@
-"use strict";
-/*
-Copyright 2022 The Sigstore Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-Object.defineProperty(exports, "__esModule", { value: true });
-exports.promiseAny = void 0;
-// Implementation of Promise.any (not available until Node v15).
-// We're basically inverting the logic of Promise.all and taking advantage
-// of the fact that Promise.all will return early on the first rejection.
-// By reversing the resolve/reject logic we can use this to return early
-// on the first resolved promise.
-const promiseAny = async (values) => {
-    return Promise.all([...values].map((promise) => new Promise((resolve, reject) => promise.then(reject, resolve)))).then((errors) => Promise.reject(errors), (value) => Promise.resolve(value));
-};
-exports.promiseAny = promiseAny;
diff --git a/deps/npm/node_modules/sigstore/dist/util/stream.d.ts b/deps/npm/node_modules/sigstore/dist/util/stream.d.ts
deleted file mode 100644
index 4d509565942e14..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/stream.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/// 
-export declare class StreamError extends Error {
-}
-export declare class ByteStream {
-    private static BLOCK_SIZE;
-    private buf;
-    private view;
-    private start;
-    constructor(buffer?: ArrayBuffer);
-    get buffer(): Buffer;
-    get length(): number;
-    get position(): number;
-    seek(position: number): void;
-    slice(start: number, len: number): Buffer;
-    appendChar(char: number): void;
-    appendUint16(num: number): void;
-    appendUint24(num: number): void;
-    appendView(view: Uint8Array): void;
-    getBlock(size: number): Buffer;
-    getUint8(): number;
-    getUint16(): number;
-    private ensureCapacity;
-    private realloc;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/util/ua.d.ts b/deps/npm/node_modules/sigstore/dist/util/ua.d.ts
deleted file mode 100644
index b60e2e9c3e5374..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/util/ua.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export declare const getUserAgent: () => string;
diff --git a/deps/npm/node_modules/sigstore/dist/verify.d.ts b/deps/npm/node_modules/sigstore/dist/verify.d.ts
deleted file mode 100644
index 850d0f37f09817..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/verify.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-/// 
-import * as sigstore from './types/sigstore';
-export type KeySelector = (hint: string) => string | Buffer | undefined;
-export declare class Verifier {
-    private trustedRoot;
-    private keySelector;
-    constructor(trustedRoot: sigstore.TrustedRoot, keySelector?: KeySelector);
-    verify(bundle: sigstore.Bundle, options: sigstore.RequiredArtifactVerificationOptions, data?: Buffer): void;
-    private verifyArtifactSignature;
-    private verifySigningCertificate;
-    private verifyTLogEntries;
-    private getPublicKey;
-}
diff --git a/deps/npm/node_modules/sigstore/dist/verify.js b/deps/npm/node_modules/sigstore/dist/verify.js
index 49f63d93abb268..a3dc4b307e4953 100644
--- a/deps/npm/node_modules/sigstore/dist/verify.js
+++ b/deps/npm/node_modules/sigstore/dist/verify.js
@@ -24,6 +24,22 @@ var __importStar = (this && this.__importStar) || function (mod) {
 };
 Object.defineProperty(exports, "__esModule", { value: true });
 exports.Verifier = void 0;
+/*
+Copyright 2023 The Sigstore Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+const bundle_1 = require("@sigstore/bundle");
 const ca = __importStar(require("./ca/verify"));
 const error_1 = require("./error");
 const tlog = __importStar(require("./tlog/verify"));
@@ -38,7 +54,7 @@ class Verifier {
     // and the bundle's transparency log entries.
     verify(bundle, options, data) {
         this.verifyArtifactSignature(bundle, data);
-        if (sigstore.isBundleWithCertificateChain(bundle)) {
+        if ((0, bundle_1.isBundleWithCertificateChain)(bundle)) {
             this.verifySigningCertificate(bundle, options);
         }
         if (options.tlogOptions.disable === false) {
diff --git a/deps/npm/node_modules/sigstore/dist/x509/cert.d.ts b/deps/npm/node_modules/sigstore/dist/x509/cert.d.ts
deleted file mode 100644
index 216dbd39cb1f7d..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/x509/cert.d.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/// 
-import * as sigstore from '../types/sigstore';
-import { ASN1Obj } from '../util/asn1';
-import { x509AuthorityKeyIDExtension, x509BasicConstraintsExtension, x509Extension, x509KeyUsageExtension, x509SCTExtension, x509SubjectAlternativeNameExtension, x509SubjectKeyIDExtension } from './ext';
-interface SCTVerificationResult {
-    verified: boolean;
-    logID: Buffer;
-}
-export declare class x509Certificate {
-    root: ASN1Obj;
-    constructor(asn1: ASN1Obj);
-    static parse(cert: Buffer | string): x509Certificate;
-    get tbsCertificate(): ASN1Obj;
-    get version(): string;
-    get notBefore(): Date;
-    get notAfter(): Date;
-    get issuer(): Buffer;
-    get subject(): Buffer;
-    get publicKey(): Buffer;
-    get signatureAlgorithm(): string;
-    get signatureValue(): Buffer;
-    get extensions(): ASN1Obj[];
-    get extKeyUsage(): x509KeyUsageExtension | undefined;
-    get extBasicConstraints(): x509BasicConstraintsExtension | undefined;
-    get extSubjectAltName(): x509SubjectAlternativeNameExtension | undefined;
-    get extAuthorityKeyID(): x509AuthorityKeyIDExtension | undefined;
-    get extSubjectKeyID(): x509SubjectKeyIDExtension | undefined;
-    get extSCT(): x509SCTExtension | undefined;
-    get isCA(): boolean;
-    extension(oid: string): x509Extension | undefined;
-    verify(issuerCertificate?: x509Certificate): boolean;
-    validForDate(date: Date): boolean;
-    equals(other: x509Certificate): boolean;
-    verifySCTs(issuer: x509Certificate, logs: sigstore.TransparencyLogInstance[]): SCTVerificationResult[];
-    private clone;
-    private findExtension;
-    private checkRecognizedExtensions;
-    private get tbsCertificateObj();
-    private get signatureAlgorithmObj();
-    private get signatureValueObj();
-    private get versionObj();
-    private get issuerObj();
-    private get validityObj();
-    private get subjectObj();
-    private get subjectPublicKeyInfoObj();
-    private get extensionsObj();
-}
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/x509/ext.d.ts b/deps/npm/node_modules/sigstore/dist/x509/ext.d.ts
deleted file mode 100644
index d6285f306f6adc..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/x509/ext.d.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/// 
-import { ASN1Obj } from '../util/asn1';
-import { SignedCertificateTimestamp } from './sct';
-export declare class x509Extension {
-    protected root: ASN1Obj;
-    constructor(asn1: ASN1Obj);
-    get oid(): string;
-    get critical(): boolean;
-    get value(): Buffer;
-    get valueObj(): ASN1Obj;
-    protected get extnValueObj(): ASN1Obj;
-}
-export declare class x509BasicConstraintsExtension extends x509Extension {
-    get isCA(): boolean;
-    get pathLenConstraint(): bigint | undefined;
-    private get sequence();
-}
-export declare class x509KeyUsageExtension extends x509Extension {
-    get digitalSignature(): boolean;
-    get keyCertSign(): boolean;
-    get crlSign(): boolean;
-    private get bitString();
-}
-export declare class x509SubjectAlternativeNameExtension extends x509Extension {
-    get rfc822Name(): string | undefined;
-    get uri(): string | undefined;
-    otherName(oid: string): string | undefined;
-    private findGeneralName;
-    private get generalNames();
-}
-export declare class x509AuthorityKeyIDExtension extends x509Extension {
-    get keyIdentifier(): Buffer | undefined;
-    private findSequenceMember;
-    private get sequence();
-}
-export declare class x509SubjectKeyIDExtension extends x509Extension {
-    get keyIdentifier(): Buffer;
-}
-export declare class x509SCTExtension extends x509Extension {
-    constructor(asn1: ASN1Obj);
-    get signedCertificateTimestamps(): SignedCertificateTimestamp[];
-}
diff --git a/deps/npm/node_modules/sigstore/dist/x509/sct.d.ts b/deps/npm/node_modules/sigstore/dist/x509/sct.d.ts
deleted file mode 100644
index 076a532984c6b8..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/x509/sct.d.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/// 
-import * as sigstore from '../types/sigstore';
-interface SCTOptions {
-    version: number;
-    logID: Buffer;
-    timestamp: Buffer;
-    extensions: Buffer;
-    hashAlgorithm: number;
-    signatureAlgorithm: number;
-    signature: Buffer;
-}
-export declare class SignedCertificateTimestamp {
-    readonly version: number;
-    readonly logID: Buffer;
-    readonly timestamp: Buffer;
-    readonly extensions: Buffer;
-    readonly hashAlgorithm: number;
-    readonly signatureAlgorithm: number;
-    readonly signature: Buffer;
-    constructor(options: SCTOptions);
-    get datetime(): Date;
-    get algorithm(): string;
-    verify(preCert: Buffer, logs: sigstore.TransparencyLogInstance[]): boolean;
-    static parse(buf: Buffer): SignedCertificateTimestamp;
-}
-export {};
diff --git a/deps/npm/node_modules/sigstore/dist/x509/verify.d.ts b/deps/npm/node_modules/sigstore/dist/x509/verify.d.ts
deleted file mode 100644
index b12594adb2ea88..00000000000000
--- a/deps/npm/node_modules/sigstore/dist/x509/verify.d.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { x509Certificate } from './cert';
-interface VerifyCertificateChainOptions {
-    trustedCerts: x509Certificate[];
-    untrustedCert: x509Certificate;
-    validAt?: Date;
-}
-export declare function verifyCertificateChain(opts: VerifyCertificateChainOptions): x509Certificate[];
-export {};
diff --git a/deps/npm/node_modules/sigstore/package.json b/deps/npm/node_modules/sigstore/package.json
index 02655a6c79bc81..daf50ba601884c 100644
--- a/deps/npm/node_modules/sigstore/package.json
+++ b/deps/npm/node_modules/sigstore/package.json
@@ -1,6 +1,6 @@
 {
   "name": "sigstore",
-  "version": "1.7.0",
+  "version": "2.1.0",
   "description": "code-signing for npm packages",
   "main": "dist/index.js",
   "types": "dist/index.d.ts",
@@ -9,9 +9,6 @@
     "build": "tsc --build",
     "test": "jest"
   },
-  "bin": {
-    "sigstore": "bin/sigstore.js"
-  },
   "files": [
     "dist",
     "store"
@@ -30,17 +27,19 @@
     "provenance": true
   },
   "devDependencies": {
-    "@sigstore/rekor-types": "^1.0.0",
+    "@sigstore/rekor-types": "^2.0.0",
     "@sigstore/jest": "^0.0.0",
-    "@tufjs/repo-mock": "^1.1.0",
+    "@sigstore/mock": "^0.4.0",
+    "@tufjs/repo-mock": "^2.0.0",
     "@types/make-fetch-happen": "^10.0.0"
   },
   "dependencies": {
-    "@sigstore/protobuf-specs": "^0.1.0",
-    "@sigstore/tuf": "^1.0.1",
-    "make-fetch-happen": "^11.0.1"
+    "@sigstore/bundle": "^2.1.0",
+    "@sigstore/protobuf-specs": "^0.2.1",
+    "@sigstore/sign": "^2.1.0",
+    "@sigstore/tuf": "^2.1.0"
   },
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   }
 }
diff --git a/deps/npm/node_modules/ssri/package.json b/deps/npm/node_modules/ssri/package.json
index 815c7f3ed03ae9..8750bd744d28bd 100644
--- a/deps/npm/node_modules/ssri/package.json
+++ b/deps/npm/node_modules/ssri/package.json
@@ -1,6 +1,6 @@
 {
   "name": "ssri",
-  "version": "10.0.4",
+  "version": "10.0.5",
   "description": "Standard Subresource Integrity library -- parses, serializes, generates, and verifies integrity metadata according to the SRI spec.",
   "main": "lib/index.js",
   "files": [
@@ -47,11 +47,11 @@
   "author": "GitHub Inc.",
   "license": "ISC",
   "dependencies": {
-    "minipass": "^5.0.0"
+    "minipass": "^7.0.3"
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.14.1",
+    "@npmcli/template-oss": "4.18.0",
     "tap": "^16.0.1"
   },
   "engines": {
@@ -59,7 +59,7 @@
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.14.1",
+    "version": "4.18.0",
     "publish": "true"
   }
 }
diff --git a/deps/npm/node_modules/supports-color/index.js b/deps/npm/node_modules/supports-color/index.js
index ca95e9f2202a6f..4ce0a2da8d2242 100644
--- a/deps/npm/node_modules/supports-color/index.js
+++ b/deps/npm/node_modules/supports-color/index.js
@@ -112,7 +112,7 @@ function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
 	}
 
 	if ('CI' in env) {
-		if ('GITHUB_ACTIONS' in env) {
+		if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) {
 			return 3;
 		}
 
diff --git a/deps/npm/node_modules/supports-color/package.json b/deps/npm/node_modules/supports-color/package.json
index eb6011c6bcdc64..738684722643c9 100644
--- a/deps/npm/node_modules/supports-color/package.json
+++ b/deps/npm/node_modules/supports-color/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "supports-color",
-	"version": "9.3.1",
+	"version": "9.4.0",
 	"description": "Detect whether a terminal supports color",
 	"license": "MIT",
 	"repository": "chalk/supports-color",
@@ -20,7 +20,7 @@
 	},
 	"scripts": {
 		"//test": "xo && ava && tsd",
-		"test": "xo && tsd"
+		"test": "tsd"
 	},
 	"files": [
 		"index.js",
@@ -51,11 +51,10 @@
 		"16m"
 	],
 	"devDependencies": {
-		"@types/node": "^16.11.7",
-		"ava": "^3.15.0",
+		"@types/node": "^20.3.2",
+		"ava": "^5.3.1",
 		"import-fresh": "^3.3.0",
 		"tsd": "^0.18.0",
-		"typescript": "^4.4.3",
-		"xo": "^0.49.0"
+		"xo": "^0.54.2"
 	}
 }
diff --git a/deps/npm/node_modules/tar/node_modules/minipass/LICENSE b/deps/npm/node_modules/tar/node_modules/minipass/LICENSE
new file mode 100644
index 00000000000000..97f8e32ed82e4c
--- /dev/null
+++ b/deps/npm/node_modules/tar/node_modules/minipass/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/deps/npm/node_modules/tar/node_modules/minipass/index.js b/deps/npm/node_modules/tar/node_modules/minipass/index.js
new file mode 100644
index 00000000000000..ed07c17acd97b7
--- /dev/null
+++ b/deps/npm/node_modules/tar/node_modules/minipass/index.js
@@ -0,0 +1,702 @@
+'use strict'
+const proc =
+  typeof process === 'object' && process
+    ? process
+    : {
+        stdout: null,
+        stderr: null,
+      }
+const EE = require('events')
+const Stream = require('stream')
+const stringdecoder = require('string_decoder')
+const SD = stringdecoder.StringDecoder
+
+const EOF = Symbol('EOF')
+const MAYBE_EMIT_END = Symbol('maybeEmitEnd')
+const EMITTED_END = Symbol('emittedEnd')
+const EMITTING_END = Symbol('emittingEnd')
+const EMITTED_ERROR = Symbol('emittedError')
+const CLOSED = Symbol('closed')
+const READ = Symbol('read')
+const FLUSH = Symbol('flush')
+const FLUSHCHUNK = Symbol('flushChunk')
+const ENCODING = Symbol('encoding')
+const DECODER = Symbol('decoder')
+const FLOWING = Symbol('flowing')
+const PAUSED = Symbol('paused')
+const RESUME = Symbol('resume')
+const BUFFER = Symbol('buffer')
+const PIPES = Symbol('pipes')
+const BUFFERLENGTH = Symbol('bufferLength')
+const BUFFERPUSH = Symbol('bufferPush')
+const BUFFERSHIFT = Symbol('bufferShift')
+const OBJECTMODE = Symbol('objectMode')
+// internal event when stream is destroyed
+const DESTROYED = Symbol('destroyed')
+// internal event when stream has an error
+const ERROR = Symbol('error')
+const EMITDATA = Symbol('emitData')
+const EMITEND = Symbol('emitEnd')
+const EMITEND2 = Symbol('emitEnd2')
+const ASYNC = Symbol('async')
+const ABORT = Symbol('abort')
+const ABORTED = Symbol('aborted')
+const SIGNAL = Symbol('signal')
+
+const defer = fn => Promise.resolve().then(fn)
+
+// TODO remove when Node v8 support drops
+const doIter = global._MP_NO_ITERATOR_SYMBOLS_ !== '1'
+const ASYNCITERATOR =
+  (doIter && Symbol.asyncIterator) || Symbol('asyncIterator not implemented')
+const ITERATOR =
+  (doIter && Symbol.iterator) || Symbol('iterator not implemented')
+
+// events that mean 'the stream is over'
+// these are treated specially, and re-emitted
+// if they are listened for after emitting.
+const isEndish = ev => ev === 'end' || ev === 'finish' || ev === 'prefinish'
+
+const isArrayBuffer = b =>
+  b instanceof ArrayBuffer ||
+  (typeof b === 'object' &&
+    b.constructor &&
+    b.constructor.name === 'ArrayBuffer' &&
+    b.byteLength >= 0)
+
+const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b)
+
+class Pipe {
+  constructor(src, dest, opts) {
+    this.src = src
+    this.dest = dest
+    this.opts = opts
+    this.ondrain = () => src[RESUME]()
+    dest.on('drain', this.ondrain)
+  }
+  unpipe() {
+    this.dest.removeListener('drain', this.ondrain)
+  }
+  // istanbul ignore next - only here for the prototype
+  proxyErrors() {}
+  end() {
+    this.unpipe()
+    if (this.opts.end) this.dest.end()
+  }
+}
+
+class PipeProxyErrors extends Pipe {
+  unpipe() {
+    this.src.removeListener('error', this.proxyErrors)
+    super.unpipe()
+  }
+  constructor(src, dest, opts) {
+    super(src, dest, opts)
+    this.proxyErrors = er => dest.emit('error', er)
+    src.on('error', this.proxyErrors)
+  }
+}
+
+class Minipass extends Stream {
+  constructor(options) {
+    super()
+    this[FLOWING] = false
+    // whether we're explicitly paused
+    this[PAUSED] = false
+    this[PIPES] = []
+    this[BUFFER] = []
+    this[OBJECTMODE] = (options && options.objectMode) || false
+    if (this[OBJECTMODE]) this[ENCODING] = null
+    else this[ENCODING] = (options && options.encoding) || null
+    if (this[ENCODING] === 'buffer') this[ENCODING] = null
+    this[ASYNC] = (options && !!options.async) || false
+    this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null
+    this[EOF] = false
+    this[EMITTED_END] = false
+    this[EMITTING_END] = false
+    this[CLOSED] = false
+    this[EMITTED_ERROR] = null
+    this.writable = true
+    this.readable = true
+    this[BUFFERLENGTH] = 0
+    this[DESTROYED] = false
+    if (options && options.debugExposeBuffer === true) {
+      Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] })
+    }
+    if (options && options.debugExposePipes === true) {
+      Object.defineProperty(this, 'pipes', { get: () => this[PIPES] })
+    }
+    this[SIGNAL] = options && options.signal
+    this[ABORTED] = false
+    if (this[SIGNAL]) {
+      this[SIGNAL].addEventListener('abort', () => this[ABORT]())
+      if (this[SIGNAL].aborted) {
+        this[ABORT]()
+      }
+    }
+  }
+
+  get bufferLength() {
+    return this[BUFFERLENGTH]
+  }
+
+  get encoding() {
+    return this[ENCODING]
+  }
+  set encoding(enc) {
+    if (this[OBJECTMODE]) throw new Error('cannot set encoding in objectMode')
+
+    if (
+      this[ENCODING] &&
+      enc !== this[ENCODING] &&
+      ((this[DECODER] && this[DECODER].lastNeed) || this[BUFFERLENGTH])
+    )
+      throw new Error('cannot change encoding')
+
+    if (this[ENCODING] !== enc) {
+      this[DECODER] = enc ? new SD(enc) : null
+      if (this[BUFFER].length)
+        this[BUFFER] = this[BUFFER].map(chunk => this[DECODER].write(chunk))
+    }
+
+    this[ENCODING] = enc
+  }
+
+  setEncoding(enc) {
+    this.encoding = enc
+  }
+
+  get objectMode() {
+    return this[OBJECTMODE]
+  }
+  set objectMode(om) {
+    this[OBJECTMODE] = this[OBJECTMODE] || !!om
+  }
+
+  get ['async']() {
+    return this[ASYNC]
+  }
+  set ['async'](a) {
+    this[ASYNC] = this[ASYNC] || !!a
+  }
+
+  // drop everything and get out of the flow completely
+  [ABORT]() {
+    this[ABORTED] = true
+    this.emit('abort', this[SIGNAL].reason)
+    this.destroy(this[SIGNAL].reason)
+  }
+
+  get aborted() {
+    return this[ABORTED]
+  }
+  set aborted(_) {}
+
+  write(chunk, encoding, cb) {
+    if (this[ABORTED]) return false
+    if (this[EOF]) throw new Error('write after end')
+
+    if (this[DESTROYED]) {
+      this.emit(
+        'error',
+        Object.assign(
+          new Error('Cannot call write after a stream was destroyed'),
+          { code: 'ERR_STREAM_DESTROYED' }
+        )
+      )
+      return true
+    }
+
+    if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8')
+
+    if (!encoding) encoding = 'utf8'
+
+    const fn = this[ASYNC] ? defer : f => f()
+
+    // convert array buffers and typed array views into buffers
+    // at some point in the future, we may want to do the opposite!
+    // leave strings and buffers as-is
+    // anything else switches us into object mode
+    if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
+      if (isArrayBufferView(chunk))
+        chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength)
+      else if (isArrayBuffer(chunk)) chunk = Buffer.from(chunk)
+      else if (typeof chunk !== 'string')
+        // use the setter so we throw if we have encoding set
+        this.objectMode = true
+    }
+
+    // handle object mode up front, since it's simpler
+    // this yields better performance, fewer checks later.
+    if (this[OBJECTMODE]) {
+      /* istanbul ignore if - maybe impossible? */
+      if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true)
+
+      if (this.flowing) this.emit('data', chunk)
+      else this[BUFFERPUSH](chunk)
+
+      if (this[BUFFERLENGTH] !== 0) this.emit('readable')
+
+      if (cb) fn(cb)
+
+      return this.flowing
+    }
+
+    // at this point the chunk is a buffer or string
+    // don't buffer it up or send it to the decoder
+    if (!chunk.length) {
+      if (this[BUFFERLENGTH] !== 0) this.emit('readable')
+      if (cb) fn(cb)
+      return this.flowing
+    }
+
+    // fast-path writing strings of same encoding to a stream with
+    // an empty buffer, skipping the buffer/decoder dance
+    if (
+      typeof chunk === 'string' &&
+      // unless it is a string already ready for us to use
+      !(encoding === this[ENCODING] && !this[DECODER].lastNeed)
+    ) {
+      chunk = Buffer.from(chunk, encoding)
+    }
+
+    if (Buffer.isBuffer(chunk) && this[ENCODING])
+      chunk = this[DECODER].write(chunk)
+
+    // Note: flushing CAN potentially switch us into not-flowing mode
+    if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true)
+
+    if (this.flowing) this.emit('data', chunk)
+    else this[BUFFERPUSH](chunk)
+
+    if (this[BUFFERLENGTH] !== 0) this.emit('readable')
+
+    if (cb) fn(cb)
+
+    return this.flowing
+  }
+
+  read(n) {
+    if (this[DESTROYED]) return null
+
+    if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) {
+      this[MAYBE_EMIT_END]()
+      return null
+    }
+
+    if (this[OBJECTMODE]) n = null
+
+    if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {
+      if (this.encoding) this[BUFFER] = [this[BUFFER].join('')]
+      else this[BUFFER] = [Buffer.concat(this[BUFFER], this[BUFFERLENGTH])]
+    }
+
+    const ret = this[READ](n || null, this[BUFFER][0])
+    this[MAYBE_EMIT_END]()
+    return ret
+  }
+
+  [READ](n, chunk) {
+    if (n === chunk.length || n === null) this[BUFFERSHIFT]()
+    else {
+      this[BUFFER][0] = chunk.slice(n)
+      chunk = chunk.slice(0, n)
+      this[BUFFERLENGTH] -= n
+    }
+
+    this.emit('data', chunk)
+
+    if (!this[BUFFER].length && !this[EOF]) this.emit('drain')
+
+    return chunk
+  }
+
+  end(chunk, encoding, cb) {
+    if (typeof chunk === 'function') (cb = chunk), (chunk = null)
+    if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8')
+    if (chunk) this.write(chunk, encoding)
+    if (cb) this.once('end', cb)
+    this[EOF] = true
+    this.writable = false
+
+    // if we haven't written anything, then go ahead and emit,
+    // even if we're not reading.
+    // we'll re-emit if a new 'end' listener is added anyway.
+    // This makes MP more suitable to write-only use cases.
+    if (this.flowing || !this[PAUSED]) this[MAYBE_EMIT_END]()
+    return this
+  }
+
+  // don't let the internal resume be overwritten
+  [RESUME]() {
+    if (this[DESTROYED]) return
+
+    this[PAUSED] = false
+    this[FLOWING] = true
+    this.emit('resume')
+    if (this[BUFFER].length) this[FLUSH]()
+    else if (this[EOF]) this[MAYBE_EMIT_END]()
+    else this.emit('drain')
+  }
+
+  resume() {
+    return this[RESUME]()
+  }
+
+  pause() {
+    this[FLOWING] = false
+    this[PAUSED] = true
+  }
+
+  get destroyed() {
+    return this[DESTROYED]
+  }
+
+  get flowing() {
+    return this[FLOWING]
+  }
+
+  get paused() {
+    return this[PAUSED]
+  }
+
+  [BUFFERPUSH](chunk) {
+    if (this[OBJECTMODE]) this[BUFFERLENGTH] += 1
+    else this[BUFFERLENGTH] += chunk.length
+    this[BUFFER].push(chunk)
+  }
+
+  [BUFFERSHIFT]() {
+    if (this[OBJECTMODE]) this[BUFFERLENGTH] -= 1
+    else this[BUFFERLENGTH] -= this[BUFFER][0].length
+    return this[BUFFER].shift()
+  }
+
+  [FLUSH](noDrain) {
+    do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length)
+
+    if (!noDrain && !this[BUFFER].length && !this[EOF]) this.emit('drain')
+  }
+
+  [FLUSHCHUNK](chunk) {
+    this.emit('data', chunk)
+    return this.flowing
+  }
+
+  pipe(dest, opts) {
+    if (this[DESTROYED]) return
+
+    const ended = this[EMITTED_END]
+    opts = opts || {}
+    if (dest === proc.stdout || dest === proc.stderr) opts.end = false
+    else opts.end = opts.end !== false
+    opts.proxyErrors = !!opts.proxyErrors
+
+    // piping an ended stream ends immediately
+    if (ended) {
+      if (opts.end) dest.end()
+    } else {
+      this[PIPES].push(
+        !opts.proxyErrors
+          ? new Pipe(this, dest, opts)
+          : new PipeProxyErrors(this, dest, opts)
+      )
+      if (this[ASYNC]) defer(() => this[RESUME]())
+      else this[RESUME]()
+    }
+
+    return dest
+  }
+
+  unpipe(dest) {
+    const p = this[PIPES].find(p => p.dest === dest)
+    if (p) {
+      this[PIPES].splice(this[PIPES].indexOf(p), 1)
+      p.unpipe()
+    }
+  }
+
+  addListener(ev, fn) {
+    return this.on(ev, fn)
+  }
+
+  on(ev, fn) {
+    const ret = super.on(ev, fn)
+    if (ev === 'data' && !this[PIPES].length && !this.flowing) this[RESUME]()
+    else if (ev === 'readable' && this[BUFFERLENGTH] !== 0)
+      super.emit('readable')
+    else if (isEndish(ev) && this[EMITTED_END]) {
+      super.emit(ev)
+      this.removeAllListeners(ev)
+    } else if (ev === 'error' && this[EMITTED_ERROR]) {
+      if (this[ASYNC]) defer(() => fn.call(this, this[EMITTED_ERROR]))
+      else fn.call(this, this[EMITTED_ERROR])
+    }
+    return ret
+  }
+
+  get emittedEnd() {
+    return this[EMITTED_END]
+  }
+
+  [MAYBE_EMIT_END]() {
+    if (
+      !this[EMITTING_END] &&
+      !this[EMITTED_END] &&
+      !this[DESTROYED] &&
+      this[BUFFER].length === 0 &&
+      this[EOF]
+    ) {
+      this[EMITTING_END] = true
+      this.emit('end')
+      this.emit('prefinish')
+      this.emit('finish')
+      if (this[CLOSED]) this.emit('close')
+      this[EMITTING_END] = false
+    }
+  }
+
+  emit(ev, data, ...extra) {
+    // error and close are only events allowed after calling destroy()
+    if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED])
+      return
+    else if (ev === 'data') {
+      return !this[OBJECTMODE] && !data
+        ? false
+        : this[ASYNC]
+        ? defer(() => this[EMITDATA](data))
+        : this[EMITDATA](data)
+    } else if (ev === 'end') {
+      return this[EMITEND]()
+    } else if (ev === 'close') {
+      this[CLOSED] = true
+      // don't emit close before 'end' and 'finish'
+      if (!this[EMITTED_END] && !this[DESTROYED]) return
+      const ret = super.emit('close')
+      this.removeAllListeners('close')
+      return ret
+    } else if (ev === 'error') {
+      this[EMITTED_ERROR] = data
+      super.emit(ERROR, data)
+      const ret =
+        !this[SIGNAL] || this.listeners('error').length
+          ? super.emit('error', data)
+          : false
+      this[MAYBE_EMIT_END]()
+      return ret
+    } else if (ev === 'resume') {
+      const ret = super.emit('resume')
+      this[MAYBE_EMIT_END]()
+      return ret
+    } else if (ev === 'finish' || ev === 'prefinish') {
+      const ret = super.emit(ev)
+      this.removeAllListeners(ev)
+      return ret
+    }
+
+    // Some other unknown event
+    const ret = super.emit(ev, data, ...extra)
+    this[MAYBE_EMIT_END]()
+    return ret
+  }
+
+  [EMITDATA](data) {
+    for (const p of this[PIPES]) {
+      if (p.dest.write(data) === false) this.pause()
+    }
+    const ret = super.emit('data', data)
+    this[MAYBE_EMIT_END]()
+    return ret
+  }
+
+  [EMITEND]() {
+    if (this[EMITTED_END]) return
+
+    this[EMITTED_END] = true
+    this.readable = false
+    if (this[ASYNC]) defer(() => this[EMITEND2]())
+    else this[EMITEND2]()
+  }
+
+  [EMITEND2]() {
+    if (this[DECODER]) {
+      const data = this[DECODER].end()
+      if (data) {
+        for (const p of this[PIPES]) {
+          p.dest.write(data)
+        }
+        super.emit('data', data)
+      }
+    }
+
+    for (const p of this[PIPES]) {
+      p.end()
+    }
+    const ret = super.emit('end')
+    this.removeAllListeners('end')
+    return ret
+  }
+
+  // const all = await stream.collect()
+  collect() {
+    const buf = []
+    if (!this[OBJECTMODE]) buf.dataLength = 0
+    // set the promise first, in case an error is raised
+    // by triggering the flow here.
+    const p = this.promise()
+    this.on('data', c => {
+      buf.push(c)
+      if (!this[OBJECTMODE]) buf.dataLength += c.length
+    })
+    return p.then(() => buf)
+  }
+
+  // const data = await stream.concat()
+  concat() {
+    return this[OBJECTMODE]
+      ? Promise.reject(new Error('cannot concat in objectMode'))
+      : this.collect().then(buf =>
+          this[OBJECTMODE]
+            ? Promise.reject(new Error('cannot concat in objectMode'))
+            : this[ENCODING]
+            ? buf.join('')
+            : Buffer.concat(buf, buf.dataLength)
+        )
+  }
+
+  // stream.promise().then(() => done, er => emitted error)
+  promise() {
+    return new Promise((resolve, reject) => {
+      this.on(DESTROYED, () => reject(new Error('stream destroyed')))
+      this.on('error', er => reject(er))
+      this.on('end', () => resolve())
+    })
+  }
+
+  // for await (let chunk of stream)
+  [ASYNCITERATOR]() {
+    let stopped = false
+    const stop = () => {
+      this.pause()
+      stopped = true
+      return Promise.resolve({ done: true })
+    }
+    const next = () => {
+      if (stopped) return stop()
+      const res = this.read()
+      if (res !== null) return Promise.resolve({ done: false, value: res })
+
+      if (this[EOF]) return stop()
+
+      let resolve = null
+      let reject = null
+      const onerr = er => {
+        this.removeListener('data', ondata)
+        this.removeListener('end', onend)
+        this.removeListener(DESTROYED, ondestroy)
+        stop()
+        reject(er)
+      }
+      const ondata = value => {
+        this.removeListener('error', onerr)
+        this.removeListener('end', onend)
+        this.removeListener(DESTROYED, ondestroy)
+        this.pause()
+        resolve({ value: value, done: !!this[EOF] })
+      }
+      const onend = () => {
+        this.removeListener('error', onerr)
+        this.removeListener('data', ondata)
+        this.removeListener(DESTROYED, ondestroy)
+        stop()
+        resolve({ done: true })
+      }
+      const ondestroy = () => onerr(new Error('stream destroyed'))
+      return new Promise((res, rej) => {
+        reject = rej
+        resolve = res
+        this.once(DESTROYED, ondestroy)
+        this.once('error', onerr)
+        this.once('end', onend)
+        this.once('data', ondata)
+      })
+    }
+
+    return {
+      next,
+      throw: stop,
+      return: stop,
+      [ASYNCITERATOR]() {
+        return this
+      },
+    }
+  }
+
+  // for (let chunk of stream)
+  [ITERATOR]() {
+    let stopped = false
+    const stop = () => {
+      this.pause()
+      this.removeListener(ERROR, stop)
+      this.removeListener(DESTROYED, stop)
+      this.removeListener('end', stop)
+      stopped = true
+      return { done: true }
+    }
+
+    const next = () => {
+      if (stopped) return stop()
+      const value = this.read()
+      return value === null ? stop() : { value }
+    }
+    this.once('end', stop)
+    this.once(ERROR, stop)
+    this.once(DESTROYED, stop)
+
+    return {
+      next,
+      throw: stop,
+      return: stop,
+      [ITERATOR]() {
+        return this
+      },
+    }
+  }
+
+  destroy(er) {
+    if (this[DESTROYED]) {
+      if (er) this.emit('error', er)
+      else this.emit(DESTROYED)
+      return this
+    }
+
+    this[DESTROYED] = true
+
+    // throw away all buffered data, it's never coming out
+    this[BUFFER].length = 0
+    this[BUFFERLENGTH] = 0
+
+    if (typeof this.close === 'function' && !this[CLOSED]) this.close()
+
+    if (er) this.emit('error', er)
+    // if no error to emit, still reject pending promises
+    else this.emit(DESTROYED)
+
+    return this
+  }
+
+  static isStream(s) {
+    return (
+      !!s &&
+      (s instanceof Minipass ||
+        s instanceof Stream ||
+        (s instanceof EE &&
+          // readable
+          (typeof s.pipe === 'function' ||
+            // writable
+            (typeof s.write === 'function' && typeof s.end === 'function'))))
+    )
+  }
+}
+
+exports.Minipass = Minipass
diff --git a/deps/npm/node_modules/tar/node_modules/minipass/index.mjs b/deps/npm/node_modules/tar/node_modules/minipass/index.mjs
new file mode 100644
index 00000000000000..89b3fbf1a4d445
--- /dev/null
+++ b/deps/npm/node_modules/tar/node_modules/minipass/index.mjs
@@ -0,0 +1,700 @@
+'use strict'
+const proc =
+  typeof process === 'object' && process
+    ? process
+    : {
+        stdout: null,
+        stderr: null,
+      }
+import EE from 'events'
+import Stream from 'stream'
+import stringdecoder from 'string_decoder'
+const SD = stringdecoder.StringDecoder
+
+const EOF = Symbol('EOF')
+const MAYBE_EMIT_END = Symbol('maybeEmitEnd')
+const EMITTED_END = Symbol('emittedEnd')
+const EMITTING_END = Symbol('emittingEnd')
+const EMITTED_ERROR = Symbol('emittedError')
+const CLOSED = Symbol('closed')
+const READ = Symbol('read')
+const FLUSH = Symbol('flush')
+const FLUSHCHUNK = Symbol('flushChunk')
+const ENCODING = Symbol('encoding')
+const DECODER = Symbol('decoder')
+const FLOWING = Symbol('flowing')
+const PAUSED = Symbol('paused')
+const RESUME = Symbol('resume')
+const BUFFER = Symbol('buffer')
+const PIPES = Symbol('pipes')
+const BUFFERLENGTH = Symbol('bufferLength')
+const BUFFERPUSH = Symbol('bufferPush')
+const BUFFERSHIFT = Symbol('bufferShift')
+const OBJECTMODE = Symbol('objectMode')
+// internal event when stream is destroyed
+const DESTROYED = Symbol('destroyed')
+// internal event when stream has an error
+const ERROR = Symbol('error')
+const EMITDATA = Symbol('emitData')
+const EMITEND = Symbol('emitEnd')
+const EMITEND2 = Symbol('emitEnd2')
+const ASYNC = Symbol('async')
+const ABORT = Symbol('abort')
+const ABORTED = Symbol('aborted')
+const SIGNAL = Symbol('signal')
+
+const defer = fn => Promise.resolve().then(fn)
+
+// TODO remove when Node v8 support drops
+const doIter = global._MP_NO_ITERATOR_SYMBOLS_ !== '1'
+const ASYNCITERATOR =
+  (doIter && Symbol.asyncIterator) || Symbol('asyncIterator not implemented')
+const ITERATOR =
+  (doIter && Symbol.iterator) || Symbol('iterator not implemented')
+
+// events that mean 'the stream is over'
+// these are treated specially, and re-emitted
+// if they are listened for after emitting.
+const isEndish = ev => ev === 'end' || ev === 'finish' || ev === 'prefinish'
+
+const isArrayBuffer = b =>
+  b instanceof ArrayBuffer ||
+  (typeof b === 'object' &&
+    b.constructor &&
+    b.constructor.name === 'ArrayBuffer' &&
+    b.byteLength >= 0)
+
+const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b)
+
+class Pipe {
+  constructor(src, dest, opts) {
+    this.src = src
+    this.dest = dest
+    this.opts = opts
+    this.ondrain = () => src[RESUME]()
+    dest.on('drain', this.ondrain)
+  }
+  unpipe() {
+    this.dest.removeListener('drain', this.ondrain)
+  }
+  // istanbul ignore next - only here for the prototype
+  proxyErrors() {}
+  end() {
+    this.unpipe()
+    if (this.opts.end) this.dest.end()
+  }
+}
+
+class PipeProxyErrors extends Pipe {
+  unpipe() {
+    this.src.removeListener('error', this.proxyErrors)
+    super.unpipe()
+  }
+  constructor(src, dest, opts) {
+    super(src, dest, opts)
+    this.proxyErrors = er => dest.emit('error', er)
+    src.on('error', this.proxyErrors)
+  }
+}
+
+export class Minipass extends Stream {
+  constructor(options) {
+    super()
+    this[FLOWING] = false
+    // whether we're explicitly paused
+    this[PAUSED] = false
+    this[PIPES] = []
+    this[BUFFER] = []
+    this[OBJECTMODE] = (options && options.objectMode) || false
+    if (this[OBJECTMODE]) this[ENCODING] = null
+    else this[ENCODING] = (options && options.encoding) || null
+    if (this[ENCODING] === 'buffer') this[ENCODING] = null
+    this[ASYNC] = (options && !!options.async) || false
+    this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null
+    this[EOF] = false
+    this[EMITTED_END] = false
+    this[EMITTING_END] = false
+    this[CLOSED] = false
+    this[EMITTED_ERROR] = null
+    this.writable = true
+    this.readable = true
+    this[BUFFERLENGTH] = 0
+    this[DESTROYED] = false
+    if (options && options.debugExposeBuffer === true) {
+      Object.defineProperty(this, 'buffer', { get: () => this[BUFFER] })
+    }
+    if (options && options.debugExposePipes === true) {
+      Object.defineProperty(this, 'pipes', { get: () => this[PIPES] })
+    }
+    this[SIGNAL] = options && options.signal
+    this[ABORTED] = false
+    if (this[SIGNAL]) {
+      this[SIGNAL].addEventListener('abort', () => this[ABORT]())
+      if (this[SIGNAL].aborted) {
+        this[ABORT]()
+      }
+    }
+  }
+
+  get bufferLength() {
+    return this[BUFFERLENGTH]
+  }
+
+  get encoding() {
+    return this[ENCODING]
+  }
+  set encoding(enc) {
+    if (this[OBJECTMODE]) throw new Error('cannot set encoding in objectMode')
+
+    if (
+      this[ENCODING] &&
+      enc !== this[ENCODING] &&
+      ((this[DECODER] && this[DECODER].lastNeed) || this[BUFFERLENGTH])
+    )
+      throw new Error('cannot change encoding')
+
+    if (this[ENCODING] !== enc) {
+      this[DECODER] = enc ? new SD(enc) : null
+      if (this[BUFFER].length)
+        this[BUFFER] = this[BUFFER].map(chunk => this[DECODER].write(chunk))
+    }
+
+    this[ENCODING] = enc
+  }
+
+  setEncoding(enc) {
+    this.encoding = enc
+  }
+
+  get objectMode() {
+    return this[OBJECTMODE]
+  }
+  set objectMode(om) {
+    this[OBJECTMODE] = this[OBJECTMODE] || !!om
+  }
+
+  get ['async']() {
+    return this[ASYNC]
+  }
+  set ['async'](a) {
+    this[ASYNC] = this[ASYNC] || !!a
+  }
+
+  // drop everything and get out of the flow completely
+  [ABORT]() {
+    this[ABORTED] = true
+    this.emit('abort', this[SIGNAL].reason)
+    this.destroy(this[SIGNAL].reason)
+  }
+
+  get aborted() {
+    return this[ABORTED]
+  }
+  set aborted(_) {}
+
+  write(chunk, encoding, cb) {
+    if (this[ABORTED]) return false
+    if (this[EOF]) throw new Error('write after end')
+
+    if (this[DESTROYED]) {
+      this.emit(
+        'error',
+        Object.assign(
+          new Error('Cannot call write after a stream was destroyed'),
+          { code: 'ERR_STREAM_DESTROYED' }
+        )
+      )
+      return true
+    }
+
+    if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8')
+
+    if (!encoding) encoding = 'utf8'
+
+    const fn = this[ASYNC] ? defer : f => f()
+
+    // convert array buffers and typed array views into buffers
+    // at some point in the future, we may want to do the opposite!
+    // leave strings and buffers as-is
+    // anything else switches us into object mode
+    if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
+      if (isArrayBufferView(chunk))
+        chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength)
+      else if (isArrayBuffer(chunk)) chunk = Buffer.from(chunk)
+      else if (typeof chunk !== 'string')
+        // use the setter so we throw if we have encoding set
+        this.objectMode = true
+    }
+
+    // handle object mode up front, since it's simpler
+    // this yields better performance, fewer checks later.
+    if (this[OBJECTMODE]) {
+      /* istanbul ignore if - maybe impossible? */
+      if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true)
+
+      if (this.flowing) this.emit('data', chunk)
+      else this[BUFFERPUSH](chunk)
+
+      if (this[BUFFERLENGTH] !== 0) this.emit('readable')
+
+      if (cb) fn(cb)
+
+      return this.flowing
+    }
+
+    // at this point the chunk is a buffer or string
+    // don't buffer it up or send it to the decoder
+    if (!chunk.length) {
+      if (this[BUFFERLENGTH] !== 0) this.emit('readable')
+      if (cb) fn(cb)
+      return this.flowing
+    }
+
+    // fast-path writing strings of same encoding to a stream with
+    // an empty buffer, skipping the buffer/decoder dance
+    if (
+      typeof chunk === 'string' &&
+      // unless it is a string already ready for us to use
+      !(encoding === this[ENCODING] && !this[DECODER].lastNeed)
+    ) {
+      chunk = Buffer.from(chunk, encoding)
+    }
+
+    if (Buffer.isBuffer(chunk) && this[ENCODING])
+      chunk = this[DECODER].write(chunk)
+
+    // Note: flushing CAN potentially switch us into not-flowing mode
+    if (this.flowing && this[BUFFERLENGTH] !== 0) this[FLUSH](true)
+
+    if (this.flowing) this.emit('data', chunk)
+    else this[BUFFERPUSH](chunk)
+
+    if (this[BUFFERLENGTH] !== 0) this.emit('readable')
+
+    if (cb) fn(cb)
+
+    return this.flowing
+  }
+
+  read(n) {
+    if (this[DESTROYED]) return null
+
+    if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) {
+      this[MAYBE_EMIT_END]()
+      return null
+    }
+
+    if (this[OBJECTMODE]) n = null
+
+    if (this[BUFFER].length > 1 && !this[OBJECTMODE]) {
+      if (this.encoding) this[BUFFER] = [this[BUFFER].join('')]
+      else this[BUFFER] = [Buffer.concat(this[BUFFER], this[BUFFERLENGTH])]
+    }
+
+    const ret = this[READ](n || null, this[BUFFER][0])
+    this[MAYBE_EMIT_END]()
+    return ret
+  }
+
+  [READ](n, chunk) {
+    if (n === chunk.length || n === null) this[BUFFERSHIFT]()
+    else {
+      this[BUFFER][0] = chunk.slice(n)
+      chunk = chunk.slice(0, n)
+      this[BUFFERLENGTH] -= n
+    }
+
+    this.emit('data', chunk)
+
+    if (!this[BUFFER].length && !this[EOF]) this.emit('drain')
+
+    return chunk
+  }
+
+  end(chunk, encoding, cb) {
+    if (typeof chunk === 'function') (cb = chunk), (chunk = null)
+    if (typeof encoding === 'function') (cb = encoding), (encoding = 'utf8')
+    if (chunk) this.write(chunk, encoding)
+    if (cb) this.once('end', cb)
+    this[EOF] = true
+    this.writable = false
+
+    // if we haven't written anything, then go ahead and emit,
+    // even if we're not reading.
+    // we'll re-emit if a new 'end' listener is added anyway.
+    // This makes MP more suitable to write-only use cases.
+    if (this.flowing || !this[PAUSED]) this[MAYBE_EMIT_END]()
+    return this
+  }
+
+  // don't let the internal resume be overwritten
+  [RESUME]() {
+    if (this[DESTROYED]) return
+
+    this[PAUSED] = false
+    this[FLOWING] = true
+    this.emit('resume')
+    if (this[BUFFER].length) this[FLUSH]()
+    else if (this[EOF]) this[MAYBE_EMIT_END]()
+    else this.emit('drain')
+  }
+
+  resume() {
+    return this[RESUME]()
+  }
+
+  pause() {
+    this[FLOWING] = false
+    this[PAUSED] = true
+  }
+
+  get destroyed() {
+    return this[DESTROYED]
+  }
+
+  get flowing() {
+    return this[FLOWING]
+  }
+
+  get paused() {
+    return this[PAUSED]
+  }
+
+  [BUFFERPUSH](chunk) {
+    if (this[OBJECTMODE]) this[BUFFERLENGTH] += 1
+    else this[BUFFERLENGTH] += chunk.length
+    this[BUFFER].push(chunk)
+  }
+
+  [BUFFERSHIFT]() {
+    if (this[OBJECTMODE]) this[BUFFERLENGTH] -= 1
+    else this[BUFFERLENGTH] -= this[BUFFER][0].length
+    return this[BUFFER].shift()
+  }
+
+  [FLUSH](noDrain) {
+    do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]()) && this[BUFFER].length)
+
+    if (!noDrain && !this[BUFFER].length && !this[EOF]) this.emit('drain')
+  }
+
+  [FLUSHCHUNK](chunk) {
+    this.emit('data', chunk)
+    return this.flowing
+  }
+
+  pipe(dest, opts) {
+    if (this[DESTROYED]) return
+
+    const ended = this[EMITTED_END]
+    opts = opts || {}
+    if (dest === proc.stdout || dest === proc.stderr) opts.end = false
+    else opts.end = opts.end !== false
+    opts.proxyErrors = !!opts.proxyErrors
+
+    // piping an ended stream ends immediately
+    if (ended) {
+      if (opts.end) dest.end()
+    } else {
+      this[PIPES].push(
+        !opts.proxyErrors
+          ? new Pipe(this, dest, opts)
+          : new PipeProxyErrors(this, dest, opts)
+      )
+      if (this[ASYNC]) defer(() => this[RESUME]())
+      else this[RESUME]()
+    }
+
+    return dest
+  }
+
+  unpipe(dest) {
+    const p = this[PIPES].find(p => p.dest === dest)
+    if (p) {
+      this[PIPES].splice(this[PIPES].indexOf(p), 1)
+      p.unpipe()
+    }
+  }
+
+  addListener(ev, fn) {
+    return this.on(ev, fn)
+  }
+
+  on(ev, fn) {
+    const ret = super.on(ev, fn)
+    if (ev === 'data' && !this[PIPES].length && !this.flowing) this[RESUME]()
+    else if (ev === 'readable' && this[BUFFERLENGTH] !== 0)
+      super.emit('readable')
+    else if (isEndish(ev) && this[EMITTED_END]) {
+      super.emit(ev)
+      this.removeAllListeners(ev)
+    } else if (ev === 'error' && this[EMITTED_ERROR]) {
+      if (this[ASYNC]) defer(() => fn.call(this, this[EMITTED_ERROR]))
+      else fn.call(this, this[EMITTED_ERROR])
+    }
+    return ret
+  }
+
+  get emittedEnd() {
+    return this[EMITTED_END]
+  }
+
+  [MAYBE_EMIT_END]() {
+    if (
+      !this[EMITTING_END] &&
+      !this[EMITTED_END] &&
+      !this[DESTROYED] &&
+      this[BUFFER].length === 0 &&
+      this[EOF]
+    ) {
+      this[EMITTING_END] = true
+      this.emit('end')
+      this.emit('prefinish')
+      this.emit('finish')
+      if (this[CLOSED]) this.emit('close')
+      this[EMITTING_END] = false
+    }
+  }
+
+  emit(ev, data, ...extra) {
+    // error and close are only events allowed after calling destroy()
+    if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED])
+      return
+    else if (ev === 'data') {
+      return !this[OBJECTMODE] && !data
+        ? false
+        : this[ASYNC]
+        ? defer(() => this[EMITDATA](data))
+        : this[EMITDATA](data)
+    } else if (ev === 'end') {
+      return this[EMITEND]()
+    } else if (ev === 'close') {
+      this[CLOSED] = true
+      // don't emit close before 'end' and 'finish'
+      if (!this[EMITTED_END] && !this[DESTROYED]) return
+      const ret = super.emit('close')
+      this.removeAllListeners('close')
+      return ret
+    } else if (ev === 'error') {
+      this[EMITTED_ERROR] = data
+      super.emit(ERROR, data)
+      const ret =
+        !this[SIGNAL] || this.listeners('error').length
+          ? super.emit('error', data)
+          : false
+      this[MAYBE_EMIT_END]()
+      return ret
+    } else if (ev === 'resume') {
+      const ret = super.emit('resume')
+      this[MAYBE_EMIT_END]()
+      return ret
+    } else if (ev === 'finish' || ev === 'prefinish') {
+      const ret = super.emit(ev)
+      this.removeAllListeners(ev)
+      return ret
+    }
+
+    // Some other unknown event
+    const ret = super.emit(ev, data, ...extra)
+    this[MAYBE_EMIT_END]()
+    return ret
+  }
+
+  [EMITDATA](data) {
+    for (const p of this[PIPES]) {
+      if (p.dest.write(data) === false) this.pause()
+    }
+    const ret = super.emit('data', data)
+    this[MAYBE_EMIT_END]()
+    return ret
+  }
+
+  [EMITEND]() {
+    if (this[EMITTED_END]) return
+
+    this[EMITTED_END] = true
+    this.readable = false
+    if (this[ASYNC]) defer(() => this[EMITEND2]())
+    else this[EMITEND2]()
+  }
+
+  [EMITEND2]() {
+    if (this[DECODER]) {
+      const data = this[DECODER].end()
+      if (data) {
+        for (const p of this[PIPES]) {
+          p.dest.write(data)
+        }
+        super.emit('data', data)
+      }
+    }
+
+    for (const p of this[PIPES]) {
+      p.end()
+    }
+    const ret = super.emit('end')
+    this.removeAllListeners('end')
+    return ret
+  }
+
+  // const all = await stream.collect()
+  collect() {
+    const buf = []
+    if (!this[OBJECTMODE]) buf.dataLength = 0
+    // set the promise first, in case an error is raised
+    // by triggering the flow here.
+    const p = this.promise()
+    this.on('data', c => {
+      buf.push(c)
+      if (!this[OBJECTMODE]) buf.dataLength += c.length
+    })
+    return p.then(() => buf)
+  }
+
+  // const data = await stream.concat()
+  concat() {
+    return this[OBJECTMODE]
+      ? Promise.reject(new Error('cannot concat in objectMode'))
+      : this.collect().then(buf =>
+          this[OBJECTMODE]
+            ? Promise.reject(new Error('cannot concat in objectMode'))
+            : this[ENCODING]
+            ? buf.join('')
+            : Buffer.concat(buf, buf.dataLength)
+        )
+  }
+
+  // stream.promise().then(() => done, er => emitted error)
+  promise() {
+    return new Promise((resolve, reject) => {
+      this.on(DESTROYED, () => reject(new Error('stream destroyed')))
+      this.on('error', er => reject(er))
+      this.on('end', () => resolve())
+    })
+  }
+
+  // for await (let chunk of stream)
+  [ASYNCITERATOR]() {
+    let stopped = false
+    const stop = () => {
+      this.pause()
+      stopped = true
+      return Promise.resolve({ done: true })
+    }
+    const next = () => {
+      if (stopped) return stop()
+      const res = this.read()
+      if (res !== null) return Promise.resolve({ done: false, value: res })
+
+      if (this[EOF]) return stop()
+
+      let resolve = null
+      let reject = null
+      const onerr = er => {
+        this.removeListener('data', ondata)
+        this.removeListener('end', onend)
+        this.removeListener(DESTROYED, ondestroy)
+        stop()
+        reject(er)
+      }
+      const ondata = value => {
+        this.removeListener('error', onerr)
+        this.removeListener('end', onend)
+        this.removeListener(DESTROYED, ondestroy)
+        this.pause()
+        resolve({ value: value, done: !!this[EOF] })
+      }
+      const onend = () => {
+        this.removeListener('error', onerr)
+        this.removeListener('data', ondata)
+        this.removeListener(DESTROYED, ondestroy)
+        stop()
+        resolve({ done: true })
+      }
+      const ondestroy = () => onerr(new Error('stream destroyed'))
+      return new Promise((res, rej) => {
+        reject = rej
+        resolve = res
+        this.once(DESTROYED, ondestroy)
+        this.once('error', onerr)
+        this.once('end', onend)
+        this.once('data', ondata)
+      })
+    }
+
+    return {
+      next,
+      throw: stop,
+      return: stop,
+      [ASYNCITERATOR]() {
+        return this
+      },
+    }
+  }
+
+  // for (let chunk of stream)
+  [ITERATOR]() {
+    let stopped = false
+    const stop = () => {
+      this.pause()
+      this.removeListener(ERROR, stop)
+      this.removeListener(DESTROYED, stop)
+      this.removeListener('end', stop)
+      stopped = true
+      return { done: true }
+    }
+
+    const next = () => {
+      if (stopped) return stop()
+      const value = this.read()
+      return value === null ? stop() : { value }
+    }
+    this.once('end', stop)
+    this.once(ERROR, stop)
+    this.once(DESTROYED, stop)
+
+    return {
+      next,
+      throw: stop,
+      return: stop,
+      [ITERATOR]() {
+        return this
+      },
+    }
+  }
+
+  destroy(er) {
+    if (this[DESTROYED]) {
+      if (er) this.emit('error', er)
+      else this.emit(DESTROYED)
+      return this
+    }
+
+    this[DESTROYED] = true
+
+    // throw away all buffered data, it's never coming out
+    this[BUFFER].length = 0
+    this[BUFFERLENGTH] = 0
+
+    if (typeof this.close === 'function' && !this[CLOSED]) this.close()
+
+    if (er) this.emit('error', er)
+    // if no error to emit, still reject pending promises
+    else this.emit(DESTROYED)
+
+    return this
+  }
+
+  static isStream(s) {
+    return (
+      !!s &&
+      (s instanceof Minipass ||
+        s instanceof Stream ||
+        (s instanceof EE &&
+          // readable
+          (typeof s.pipe === 'function' ||
+            // writable
+            (typeof s.write === 'function' && typeof s.end === 'function'))))
+    )
+  }
+}
diff --git a/deps/npm/node_modules/tar/node_modules/minipass/package.json b/deps/npm/node_modules/tar/node_modules/minipass/package.json
new file mode 100644
index 00000000000000..0e20e988047f23
--- /dev/null
+++ b/deps/npm/node_modules/tar/node_modules/minipass/package.json
@@ -0,0 +1,76 @@
+{
+  "name": "minipass",
+  "version": "5.0.0",
+  "description": "minimal implementation of a PassThrough stream",
+  "main": "./index.js",
+  "module": "./index.mjs",
+  "types": "./index.d.ts",
+  "exports": {
+    ".": {
+      "import": {
+        "types": "./index.d.ts",
+        "default": "./index.mjs"
+      },
+      "require": {
+        "types": "./index.d.ts",
+        "default": "./index.js"
+      }
+    },
+    "./package.json": "./package.json"
+  },
+  "devDependencies": {
+    "@types/node": "^17.0.41",
+    "end-of-stream": "^1.4.0",
+    "node-abort-controller": "^3.1.1",
+    "prettier": "^2.6.2",
+    "tap": "^16.2.0",
+    "through2": "^2.0.3",
+    "ts-node": "^10.8.1",
+    "typedoc": "^0.23.24",
+    "typescript": "^4.7.3"
+  },
+  "scripts": {
+    "pretest": "npm run prepare",
+    "presnap": "npm run prepare",
+    "prepare": "node ./scripts/transpile-to-esm.js",
+    "snap": "tap",
+    "test": "tap",
+    "preversion": "npm test",
+    "postversion": "npm publish",
+    "postpublish": "git push origin --follow-tags",
+    "typedoc": "typedoc ./index.d.ts",
+    "format": "prettier --write . --loglevel warn"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/isaacs/minipass.git"
+  },
+  "keywords": [
+    "passthrough",
+    "stream"
+  ],
+  "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
+  "license": "ISC",
+  "files": [
+    "index.d.ts",
+    "index.js",
+    "index.mjs"
+  ],
+  "tap": {
+    "check-coverage": true
+  },
+  "engines": {
+    "node": ">=8"
+  },
+  "prettier": {
+    "semi": false,
+    "printWidth": 80,
+    "tabWidth": 2,
+    "useTabs": false,
+    "singleQuote": true,
+    "jsxSingleQuote": false,
+    "bracketSameLine": true,
+    "arrowParens": "avoid",
+    "endOfLine": "lf"
+  }
+}
diff --git a/deps/npm/node_modules/tuf-js/dist/config.js b/deps/npm/node_modules/tuf-js/dist/config.js
index c2d970e2562449..bafb33a8a1bf7c 100644
--- a/deps/npm/node_modules/tuf-js/dist/config.js
+++ b/deps/npm/node_modules/tuf-js/dist/config.js
@@ -10,5 +10,6 @@ exports.defaultConfig = {
     targetsMaxLength: 5000000,
     prefixTargetsWithHash: true,
     fetchTimeout: 100000,
-    fetchRetries: 2,
+    fetchRetries: undefined,
+    fetchRetry: 2,
 };
diff --git a/deps/npm/node_modules/tuf-js/dist/fetcher.js b/deps/npm/node_modules/tuf-js/dist/fetcher.js
index d3dcf53eeb8697..f966ce1bb0cdc6 100644
--- a/deps/npm/node_modules/tuf-js/dist/fetcher.js
+++ b/deps/npm/node_modules/tuf-js/dist/fetcher.js
@@ -57,13 +57,13 @@ class DefaultFetcher extends BaseFetcher {
     constructor(options = {}) {
         super();
         this.timeout = options.timeout;
-        this.retries = options.retries;
+        this.retry = options.retry;
     }
     async fetch(url) {
         log('GET %s', url);
         const response = await (0, make_fetch_happen_1.default)(url, {
             timeout: this.timeout,
-            retry: this.retries,
+            retry: this.retry,
         });
         if (!response.ok || !response?.body) {
             throw new error_1.DownloadHTTPError('Failed to download', response.status);
diff --git a/deps/npm/node_modules/tuf-js/dist/updater.js b/deps/npm/node_modules/tuf-js/dist/updater.js
index 2aba48d24affd5..2d0c769c7af647 100644
--- a/deps/npm/node_modules/tuf-js/dist/updater.js
+++ b/deps/npm/node_modules/tuf-js/dist/updater.js
@@ -51,7 +51,7 @@ class Updater {
             fetcher ||
                 new fetcher_1.DefaultFetcher({
                     timeout: this.config.fetchTimeout,
-                    retries: this.config.fetchRetries,
+                    retry: this.config.fetchRetries ?? this.config.fetchRetry,
                 });
     }
     // refresh and load the metadata before downloading the target
@@ -306,7 +306,7 @@ class Updater {
         const filePath = encodeURIComponent(targetInfo.path);
         return path.join(this.targetDir, filePath);
     }
-    async persistMetadata(metaDataName, bytesData) {
+    persistMetadata(metaDataName, bytesData) {
         try {
             const filePath = path.join(this.dir, `${metaDataName}.json`);
             log('WRITE %s', filePath);
diff --git a/deps/npm/node_modules/tuf-js/package.json b/deps/npm/node_modules/tuf-js/package.json
index 9187d88083272c..c757d6a00d7008 100644
--- a/deps/npm/node_modules/tuf-js/package.json
+++ b/deps/npm/node_modules/tuf-js/package.json
@@ -1,6 +1,6 @@
 {
   "name": "tuf-js",
-  "version": "1.1.7",
+  "version": "2.1.0",
   "description": "JavaScript implementation of The Update Framework (TUF)",
   "main": "dist/index.js",
   "types": "dist/index.d.ts",
@@ -28,19 +28,16 @@
   },
   "homepage": "https://github.com/theupdateframework/tuf-js/tree/main/packages/client#readme",
   "devDependencies": {
-    "@tufjs/repo-mock": "1.3.1",
+    "@tufjs/repo-mock": "2.0.0",
     "@types/debug": "^4.1.8",
-    "@types/make-fetch-happen": "^10.0.1",
-    "@types/node": "^20.2.5",
-    "nock": "^13.3.1",
-    "typescript": "^5.1.3"
+    "@types/make-fetch-happen": "^10.0.1"
   },
   "dependencies": {
-    "@tufjs/models": "1.0.4",
+    "@tufjs/models": "2.0.0",
     "debug": "^4.3.4",
-    "make-fetch-happen": "^11.1.1"
+    "make-fetch-happen": "^13.0.0"
   },
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.14.0 || >=18.0.0"
   }
 }
diff --git a/deps/npm/node_modules/which/lib/index.js b/deps/npm/node_modules/which/lib/index.js
index 52e9ea62377e74..2fd358baf888fd 100644
--- a/deps/npm/node_modules/which/lib/index.js
+++ b/deps/npm/node_modules/which/lib/index.js
@@ -1,4 +1,4 @@
-const isexe = require('isexe')
+const { isexe, sync: isexeSync } = require('isexe')
 const { join, delimiter, sep, posix } = require('path')
 
 const isWindows = process.platform === 'win32'
@@ -31,11 +31,7 @@ const getPathInfo = (cmd, {
   if (isWindows) {
     const pathExtExe = optPathExt ||
       ['.EXE', '.CMD', '.BAT', '.COM'].join(optDelimiter)
-    const pathExt = pathExtExe.split(optDelimiter).reduce((acc, item) => {
-      acc.push(item)
-      acc.push(item.toLowerCase())
-      return acc
-    }, [])
+    const pathExt = pathExtExe.split(optDelimiter).flatMap((item) => [item, item.toLowerCase()])
     if (cmd.includes('.') && pathExt[0] !== '') {
       pathExt.unshift('')
     }
@@ -90,7 +86,7 @@ const whichSync = (cmd, opt = {}) => {
 
     for (const ext of pathExt) {
       const withExt = p + ext
-      const is = isexe.sync(withExt, { pathExt: pathExtExe, ignoreErrors: true })
+      const is = isexeSync(withExt, { pathExt: pathExtExe, ignoreErrors: true })
       if (is) {
         if (!opt.all) {
           return withExt
diff --git a/deps/npm/node_modules/which/node_modules/isexe/LICENSE b/deps/npm/node_modules/which/node_modules/isexe/LICENSE
new file mode 100644
index 00000000000000..c925dbe826b670
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) 2016-2022 Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/index.js b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/index.js
new file mode 100644
index 00000000000000..cefcb66b5c5434
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/index.js
@@ -0,0 +1,46 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    var desc = Object.getOwnPropertyDescriptor(m, k);
+    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+      desc = { enumerable: true, get: function() { return m[k]; } };
+    }
+    Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+    Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+    o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+    if (mod && mod.__esModule) return mod;
+    var result = {};
+    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+    __setModuleDefault(result, mod);
+    return result;
+};
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.sync = exports.isexe = exports.posix = exports.win32 = void 0;
+const posix = __importStar(require("./posix.js"));
+exports.posix = posix;
+const win32 = __importStar(require("./win32.js"));
+exports.win32 = win32;
+__exportStar(require("./options.js"), exports);
+const platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform;
+const impl = platform === 'win32' ? win32 : posix;
+/**
+ * Determine whether a path is executable on the current platform.
+ */
+exports.isexe = impl.isexe;
+/**
+ * Synchronously determine whether a path is executable on the
+ * current platform.
+ */
+exports.sync = impl.sync;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/options.js b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/options.js
new file mode 100644
index 00000000000000..0dfad0762cc32c
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/options.js
@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=options.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/package.json b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/package.json
new file mode 100644
index 00000000000000..5bbefffbabee39
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "commonjs"
+}
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/posix.js b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/posix.js
new file mode 100644
index 00000000000000..3bc5e79d7007e9
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/posix.js
@@ -0,0 +1,67 @@
+"use strict";
+/**
+ * This is the Posix implementation of isexe, which uses the file
+ * mode and uid/gid values.
+ *
+ * @module
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.sync = exports.isexe = void 0;
+const fs_1 = require("fs");
+const promises_1 = require("fs/promises");
+/**
+ * Determine whether a path is executable according to the mode and
+ * current (or specified) user and group IDs.
+ */
+const isexe = async (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat(await (0, promises_1.stat)(path), options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+exports.isexe = isexe;
+/**
+ * Synchronously determine whether a path is executable according to
+ * the mode and current (or specified) user and group IDs.
+ */
+const sync = (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat((0, fs_1.statSync)(path), options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+exports.sync = sync;
+const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options);
+const checkMode = (stat, options) => {
+    const myUid = options.uid ?? process.getuid?.();
+    const myGroups = options.groups ?? process.getgroups?.() ?? [];
+    const myGid = options.gid ?? process.getgid?.() ?? myGroups[0];
+    if (myUid === undefined || myGid === undefined) {
+        throw new Error('cannot get uid or gid');
+    }
+    const groups = new Set([myGid, ...myGroups]);
+    const mod = stat.mode;
+    const uid = stat.uid;
+    const gid = stat.gid;
+    const u = parseInt('100', 8);
+    const g = parseInt('010', 8);
+    const o = parseInt('001', 8);
+    const ug = u | g;
+    return !!(mod & o ||
+        (mod & g && groups.has(gid)) ||
+        (mod & u && uid === myUid) ||
+        (mod & ug && myUid === 0));
+};
+//# sourceMappingURL=posix.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/win32.js b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/win32.js
new file mode 100644
index 00000000000000..fa7a4d2f7d240d
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/cjs/win32.js
@@ -0,0 +1,62 @@
+"use strict";
+/**
+ * This is the Windows implementation of isexe, which uses the file
+ * extension and PATHEXT setting.
+ *
+ * @module
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.sync = exports.isexe = void 0;
+const fs_1 = require("fs");
+const promises_1 = require("fs/promises");
+/**
+ * Determine whether a path is executable based on the file extension
+ * and PATHEXT environment variable (or specified pathExt option)
+ */
+const isexe = async (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat(await (0, promises_1.stat)(path), path, options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+exports.isexe = isexe;
+/**
+ * Synchronously determine whether a path is executable based on the file
+ * extension and PATHEXT environment variable (or specified pathExt option)
+ */
+const sync = (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat((0, fs_1.statSync)(path), path, options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+exports.sync = sync;
+const checkPathExt = (path, options) => {
+    const { pathExt = process.env.PATHEXT || '' } = options;
+    const peSplit = pathExt.split(';');
+    if (peSplit.indexOf('') !== -1) {
+        return true;
+    }
+    for (let i = 0; i < peSplit.length; i++) {
+        const p = peSplit[i].toLowerCase();
+        const ext = path.substring(path.length - p.length).toLowerCase();
+        if (p && ext === p) {
+            return true;
+        }
+    }
+    return false;
+};
+const checkStat = (stat, path, options) => stat.isFile() && checkPathExt(path, options);
+//# sourceMappingURL=win32.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/index.js b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/index.js
new file mode 100644
index 00000000000000..1e309acd7355ec
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/index.js
@@ -0,0 +1,16 @@
+import * as posix from './posix.js';
+import * as win32 from './win32.js';
+export * from './options.js';
+export { win32, posix };
+const platform = process.env._ISEXE_TEST_PLATFORM_ || process.platform;
+const impl = platform === 'win32' ? win32 : posix;
+/**
+ * Determine whether a path is executable on the current platform.
+ */
+export const isexe = impl.isexe;
+/**
+ * Synchronously determine whether a path is executable on the
+ * current platform.
+ */
+export const sync = impl.sync;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/options.js b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/options.js
new file mode 100644
index 00000000000000..e9ded40bd5b2cd
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/options.js
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=options.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/package.json b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/package.json
new file mode 100644
index 00000000000000..3dbc1ca591c055
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/package.json
@@ -0,0 +1,3 @@
+{
+  "type": "module"
+}
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/posix.js b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/posix.js
new file mode 100644
index 00000000000000..c453776c0452f7
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/posix.js
@@ -0,0 +1,62 @@
+/**
+ * This is the Posix implementation of isexe, which uses the file
+ * mode and uid/gid values.
+ *
+ * @module
+ */
+import { statSync } from 'fs';
+import { stat } from 'fs/promises';
+/**
+ * Determine whether a path is executable according to the mode and
+ * current (or specified) user and group IDs.
+ */
+export const isexe = async (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat(await stat(path), options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+/**
+ * Synchronously determine whether a path is executable according to
+ * the mode and current (or specified) user and group IDs.
+ */
+export const sync = (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat(statSync(path), options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+const checkStat = (stat, options) => stat.isFile() && checkMode(stat, options);
+const checkMode = (stat, options) => {
+    const myUid = options.uid ?? process.getuid?.();
+    const myGroups = options.groups ?? process.getgroups?.() ?? [];
+    const myGid = options.gid ?? process.getgid?.() ?? myGroups[0];
+    if (myUid === undefined || myGid === undefined) {
+        throw new Error('cannot get uid or gid');
+    }
+    const groups = new Set([myGid, ...myGroups]);
+    const mod = stat.mode;
+    const uid = stat.uid;
+    const gid = stat.gid;
+    const u = parseInt('100', 8);
+    const g = parseInt('010', 8);
+    const o = parseInt('001', 8);
+    const ug = u | g;
+    return !!(mod & o ||
+        (mod & g && groups.has(gid)) ||
+        (mod & u && uid === myUid) ||
+        (mod & ug && myUid === 0));
+};
+//# sourceMappingURL=posix.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/win32.js b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/win32.js
new file mode 100644
index 00000000000000..a354ee2a5115c7
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/dist/mjs/win32.js
@@ -0,0 +1,57 @@
+/**
+ * This is the Windows implementation of isexe, which uses the file
+ * extension and PATHEXT setting.
+ *
+ * @module
+ */
+import { statSync } from 'fs';
+import { stat } from 'fs/promises';
+/**
+ * Determine whether a path is executable based on the file extension
+ * and PATHEXT environment variable (or specified pathExt option)
+ */
+export const isexe = async (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat(await stat(path), path, options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+/**
+ * Synchronously determine whether a path is executable based on the file
+ * extension and PATHEXT environment variable (or specified pathExt option)
+ */
+export const sync = (path, options = {}) => {
+    const { ignoreErrors = false } = options;
+    try {
+        return checkStat(statSync(path), path, options);
+    }
+    catch (e) {
+        const er = e;
+        if (ignoreErrors || er.code === 'EACCES')
+            return false;
+        throw er;
+    }
+};
+const checkPathExt = (path, options) => {
+    const { pathExt = process.env.PATHEXT || '' } = options;
+    const peSplit = pathExt.split(';');
+    if (peSplit.indexOf('') !== -1) {
+        return true;
+    }
+    for (let i = 0; i < peSplit.length; i++) {
+        const p = peSplit[i].toLowerCase();
+        const ext = path.substring(path.length - p.length).toLowerCase();
+        if (p && ext === p) {
+            return true;
+        }
+    }
+    return false;
+};
+const checkStat = (stat, path, options) => stat.isFile() && checkPathExt(path, options);
+//# sourceMappingURL=win32.js.map
\ No newline at end of file
diff --git a/deps/npm/node_modules/which/node_modules/isexe/package.json b/deps/npm/node_modules/which/node_modules/isexe/package.json
new file mode 100644
index 00000000000000..a0e2cd04bfdbfe
--- /dev/null
+++ b/deps/npm/node_modules/which/node_modules/isexe/package.json
@@ -0,0 +1,96 @@
+{
+  "name": "isexe",
+  "version": "3.1.1",
+  "description": "Minimal module to check if a file is executable.",
+  "main": "./dist/cjs/index.js",
+  "module": "./dist/mjs/index.js",
+  "types": "./dist/cjs/index.js",
+  "files": [
+    "dist"
+  ],
+  "exports": {
+    ".": {
+      "import": {
+        "types": "./dist/mjs/index.d.ts",
+        "default": "./dist/mjs/index.js"
+      },
+      "require": {
+        "types": "./dist/cjs/index.d.ts",
+        "default": "./dist/cjs/index.js"
+      }
+    },
+    "./posix": {
+      "import": {
+        "types": "./dist/mjs/posix.d.ts",
+        "default": "./dist/mjs/posix.js"
+      },
+      "require": {
+        "types": "./dist/cjs/posix.d.ts",
+        "default": "./dist/cjs/posix.js"
+      }
+    },
+    "./win32": {
+      "import": {
+        "types": "./dist/mjs/win32.d.ts",
+        "default": "./dist/mjs/win32.js"
+      },
+      "require": {
+        "types": "./dist/cjs/win32.d.ts",
+        "default": "./dist/cjs/win32.js"
+      }
+    },
+    "./package.json": "./package.json"
+  },
+  "devDependencies": {
+    "@types/node": "^20.4.5",
+    "@types/tap": "^15.0.8",
+    "c8": "^8.0.1",
+    "mkdirp": "^0.5.1",
+    "prettier": "^2.8.8",
+    "rimraf": "^2.5.0",
+    "sync-content": "^1.0.2",
+    "tap": "^16.3.8",
+    "ts-node": "^10.9.1",
+    "typedoc": "^0.24.8",
+    "typescript": "^5.1.6"
+  },
+  "scripts": {
+    "preversion": "npm test",
+    "postversion": "npm publish",
+    "prepublishOnly": "git push origin --follow-tags",
+    "prepare": "tsc -p tsconfig/cjs.json && tsc -p tsconfig/esm.json && bash ./scripts/fixup.sh",
+    "pretest": "npm run prepare",
+    "presnap": "npm run prepare",
+    "test": "c8 tap",
+    "snap": "c8 tap",
+    "format": "prettier --write . --loglevel warn --ignore-path ../../.prettierignore --cache",
+    "typedoc": "typedoc --tsconfig tsconfig/esm.json ./src/*.ts"
+  },
+  "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
+  "license": "ISC",
+  "tap": {
+    "coverage": false,
+    "node-arg": [
+      "--enable-source-maps",
+      "--no-warnings",
+      "--loader",
+      "ts-node/esm"
+    ],
+    "ts": false
+  },
+  "prettier": {
+    "semi": false,
+    "printWidth": 75,
+    "tabWidth": 2,
+    "useTabs": false,
+    "singleQuote": true,
+    "jsxSingleQuote": false,
+    "bracketSameLine": true,
+    "arrowParens": "avoid",
+    "endOfLine": "lf"
+  },
+  "repository": "https://github.com/isaacs/isexe",
+  "engines": {
+    "node": ">=16"
+  }
+}
diff --git a/deps/npm/node_modules/which/package.json b/deps/npm/node_modules/which/package.json
index 989e01c9a36830..515bfb22ca0e1e 100644
--- a/deps/npm/node_modules/which/package.json
+++ b/deps/npm/node_modules/which/package.json
@@ -2,7 +2,7 @@
   "author": "GitHub Inc.",
   "name": "which",
   "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
-  "version": "3.0.1",
+  "version": "4.0.0",
   "repository": {
     "type": "git",
     "url": "https://github.com/npm/node-which.git"
@@ -13,11 +13,11 @@
   },
   "license": "ISC",
   "dependencies": {
-    "isexe": "^2.0.0"
+    "isexe": "^3.1.1"
   },
   "devDependencies": {
     "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/template-oss": "4.14.1",
+    "@npmcli/template-oss": "4.18.0",
     "tap": "^16.3.0"
   },
   "scripts": {
@@ -41,11 +41,17 @@
     ]
   },
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^16.13.0 || >=18.0.0"
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.14.1",
+    "ciVersions": [
+      "16.13.0",
+      "16.x",
+      "18.0.0",
+      "18.x"
+    ],
+    "version": "4.18.0",
     "publish": "true"
   }
 }
diff --git a/deps/npm/package.json b/deps/npm/package.json
index c6ab8029946fd1..a95496f1a3eb01 100644
--- a/deps/npm/package.json
+++ b/deps/npm/package.json
@@ -1,5 +1,5 @@
 {
-  "version": "9.8.0",
+  "version": "10.1.0",
   "name": "npm",
   "description": "a package manager for JavaScript",
   "workspaces": [
@@ -52,79 +52,84 @@
   },
   "dependencies": {
     "@isaacs/string-locale-compare": "^1.1.0",
-    "@npmcli/arborist": "^6.3.0",
-    "@npmcli/config": "^6.2.1",
+    "@npmcli/arborist": "^7.1.0",
+    "@npmcli/config": "^7.2.0",
+    "@npmcli/fs": "^3.1.0",
     "@npmcli/map-workspaces": "^3.0.4",
-    "@npmcli/package-json": "^4.0.0",
-    "@npmcli/run-script": "^6.0.2",
+    "@npmcli/package-json": "^5.0.0",
+    "@npmcli/promise-spawn": "^7.0.0",
+    "@npmcli/run-script": "^7.0.1",
+    "@sigstore/tuf": "^2.1.0",
     "abbrev": "^2.0.0",
     "archy": "~1.0.0",
-    "cacache": "^17.1.3",
-    "chalk": "^5.2.0",
+    "cacache": "^18.0.0",
+    "chalk": "^5.3.0",
     "ci-info": "^3.8.0",
     "cli-columns": "^4.0.0",
     "cli-table3": "^0.6.3",
     "columnify": "^1.6.0",
     "fastest-levenshtein": "^1.0.16",
-    "fs-minipass": "^3.0.2",
-    "glob": "^10.2.7",
+    "fs-minipass": "^3.0.3",
+    "glob": "^10.3.3",
     "graceful-fs": "^4.2.11",
-    "hosted-git-info": "^6.1.1",
+    "hosted-git-info": "^7.0.0",
     "ini": "^4.1.1",
-    "init-package-json": "^5.0.0",
+    "init-package-json": "^6.0.0",
     "is-cidr": "^4.0.2",
     "json-parse-even-better-errors": "^3.0.0",
-    "libnpmaccess": "^7.0.2",
-    "libnpmdiff": "^5.0.19",
-    "libnpmexec": "^6.0.2",
-    "libnpmfund": "^4.0.19",
-    "libnpmhook": "^9.0.3",
-    "libnpmorg": "^5.0.4",
-    "libnpmpack": "^5.0.19",
-    "libnpmpublish": "^7.5.0",
-    "libnpmsearch": "^6.0.2",
-    "libnpmteam": "^5.0.3",
-    "libnpmversion": "^4.0.2",
-    "make-fetch-happen": "^11.1.1",
-    "minimatch": "^9.0.0",
-    "minipass": "^5.0.0",
+    "libnpmaccess": "^8.0.0",
+    "libnpmdiff": "^6.0.1",
+    "libnpmexec": "^7.0.1",
+    "libnpmfund": "^4.1.1",
+    "libnpmhook": "^10.0.0",
+    "libnpmorg": "^6.0.0",
+    "libnpmpack": "^6.0.1",
+    "libnpmpublish": "^9.0.0",
+    "libnpmsearch": "^7.0.0",
+    "libnpmteam": "^6.0.0",
+    "libnpmversion": "^5.0.0",
+    "make-fetch-happen": "^13.0.0",
+    "minimatch": "^9.0.3",
+    "minipass": "^7.0.3",
     "minipass-pipeline": "^1.2.4",
     "ms": "^2.1.2",
     "node-gyp": "^9.4.0",
     "nopt": "^7.2.0",
     "npm-audit-report": "^5.0.0",
-    "npm-install-checks": "^6.1.1",
-    "npm-package-arg": "^10.1.0",
-    "npm-pick-manifest": "^8.0.1",
-    "npm-profile": "^7.0.1",
-    "npm-registry-fetch": "^14.0.5",
+    "npm-install-checks": "^6.2.0",
+    "npm-package-arg": "^11.0.0",
+    "npm-pick-manifest": "^9.0.0",
+    "npm-profile": "^9.0.0",
+    "npm-registry-fetch": "^16.0.0",
     "npm-user-validate": "^2.0.0",
     "npmlog": "^7.0.1",
     "p-map": "^4.0.0",
-    "pacote": "^15.2.0",
+    "pacote": "^17.0.4",
     "parse-conflict-json": "^3.0.1",
     "proc-log": "^3.0.0",
     "qrcode-terminal": "^0.12.0",
     "read": "^2.1.0",
-    "semver": "^7.5.2",
-    "sigstore": "^1.7.0",
-    "ssri": "^10.0.4",
-    "supports-color": "^9.3.1",
+    "semver": "^7.5.4",
+    "ssri": "^10.0.5",
+    "supports-color": "^9.4.0",
     "tar": "^6.1.15",
     "text-table": "~0.2.0",
     "tiny-relative-date": "^1.3.0",
     "treeverse": "^3.0.0",
     "validate-npm-package-name": "^5.0.0",
-    "which": "^3.0.1",
+    "which": "^4.0.0",
     "write-file-atomic": "^5.0.1"
   },
   "bundleDependencies": [
     "@isaacs/string-locale-compare",
     "@npmcli/arborist",
     "@npmcli/config",
+    "@npmcli/fs",
     "@npmcli/map-workspaces",
     "@npmcli/package-json",
+    "@npmcli/promise-spawn",
     "@npmcli/run-script",
+    "@sigstore/tuf",
     "abbrev",
     "archy",
     "cacache",
@@ -175,7 +180,6 @@
     "qrcode-terminal",
     "read",
     "semver",
-    "sigstore",
     "ssri",
     "supports-color",
     "tar",
@@ -188,23 +192,21 @@
   ],
   "devDependencies": {
     "@npmcli/docs": "^1.0.0",
-    "@npmcli/eslint-config": "^4.0.0",
-    "@npmcli/fs": "^3.1.0",
-    "@npmcli/git": "^4.1.0",
+    "@npmcli/eslint-config": "^4.0.2",
+    "@npmcli/git": "^5.0.3",
     "@npmcli/mock-globals": "^1.0.0",
     "@npmcli/mock-registry": "^1.0.0",
-    "@npmcli/promise-spawn": "^6.0.2",
-    "@npmcli/template-oss": "4.14.1",
-    "@tufjs/repo-mock": "^1.3.1",
+    "@npmcli/template-oss": "4.18.0",
+    "@tufjs/repo-mock": "^2.0.0",
     "diff": "^5.1.0",
     "licensee": "^10.0.0",
-    "nock": "^13.3.0",
-    "npm-packlist": "^7.0.4",
+    "nock": "^13.3.3",
+    "npm-packlist": "^8.0.0",
     "remark": "^14.0.2",
     "remark-gfm": "^3.0.1",
     "remark-github": "^11.2.4",
     "spawk": "^1.7.1",
-    "tap": "^16.3.4"
+    "tap": "^16.3.8"
   },
   "scripts": {
     "dependencies": "node scripts/bundle-and-gitignore-deps.js && node scripts/dependency-graph.js",
@@ -247,11 +249,11 @@
   },
   "templateOSS": {
     "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
-    "version": "4.14.1",
+    "version": "4.18.0",
     "content": "./scripts/template-oss/root.js"
   },
   "license": "Artistic-2.0",
   "engines": {
-    "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+    "node": "^18.17.0 || >=20.5.0"
   }
 }
diff --git a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
index af600062c980e7..3001c98b3e03d8 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
@@ -30,10 +30,11 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna
   "cafile": null,
   "call": "",
   "cert": null,
-  "ci-name": null,
   "cidr": null,
   "color": true,
   "commit-hooks": true,
+  "cpu": null,
+  "os": null,
   "depth": null,
   "description": true,
   "dev": false,
@@ -147,7 +148,6 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna
   "tag": "latest",
   "tag-version-prefix": "v",
   "timing": false,
-  "tmp": "{TMP}",
   "umask": 0,
   "unicode": false,
   "update-notifier": true,
@@ -161,8 +161,7 @@ exports[`test/lib/commands/config.js TAP config list --json > output matches sna
   "workspaces": null,
   "workspaces-update": true,
   "yes": null,
-  "npm-version": "{NPM-VERSION}",
-  "metrics-registry": "https://registry.npmjs.org/"
+  "npm-version": "{NPM-VERSION}"
 }
 `
 
@@ -187,10 +186,10 @@ cache-min = 0
 cafile = null
 call = ""
 cert = null
-ci-name = null
 cidr = null
 color = true
 commit-hooks = true
+cpu = null
 depth = null
 description = true
 dev = false
@@ -254,7 +253,6 @@ logs-max = 10
 ; long = false ; overridden by cli
 maxsockets = 15
 message = "%s"
-metrics-registry = "https://registry.npmjs.org/"
 node-options = null
 noproxy = [""]
 npm-version = "{NPM-VERSION}"
@@ -263,6 +261,7 @@ omit = []
 omit-lockfile-registry-resolved = false
 only = null
 optional = null
+os = null
 otp = null
 pack-destination = "."
 package = []
@@ -306,7 +305,6 @@ strict-ssl = true
 tag = "latest"
 tag-version-prefix = "v"
 timing = false
-tmp = "{TMP}"
 umask = 0
 unicode = false
 update-notifier = true
diff --git a/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs
index b7ea39ac4de0ef..98d10c2bb5d4bb 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs
@@ -180,9 +180,9 @@ Object {
 
 exports[`test/lib/commands/doctor.js TAP bad proxy > output 1`] = `
 Check                               Value   Recommendation/Notes
-npm ping                            not ok  unsupported proxy protocol: 'ssh:'
-npm -v                              not ok  Error: unsupported proxy protocol: 'ssh:'
-node -v                             not ok  Error: unsupported proxy protocol: 'ssh:'
+npm ping                            not ok  Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\`
+npm -v                              not ok  Error: Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\`
+node -v                             not ok  Error: Invalid protocol \`ssh:\` connecting to proxy \`npmjs.org\`
 npm config get registry             ok      using default registry (https://registry.npmjs.org/)
 git executable in PATH              ok      /path/to/git
 global bin folder in PATH           ok      {CWD}/global/bin
diff --git a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs
index d88244d7a15460..7a5c2ddcc3882b 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/publish.js.test.cjs
@@ -245,6 +245,17 @@ exports[`test/lib/commands/publish.js TAP no auth dry-run > must match snapshot
 
 exports[`test/lib/commands/publish.js TAP no auth dry-run > warns about auth being needed 1`] = `
 Array [
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+    ),
+  ],
   Array [
     "",
     "This command requires you to be logged in to https://registry.npmjs.org/ (dry-run)",
@@ -416,6 +427,53 @@ exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > al
 
 exports[`test/lib/commands/publish.js TAP workspaces all workspaces - color > warns about skipped private workspace in color 1`] = `
 Array [
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+      "repository" was changed from a string to an object
+    ),
+  ],
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+      "repository" was changed from a string to an object
+      "repository.url" was normalized to "git+https://github.com/npm/workspace-b.git"
+    ),
+  ],
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+    ),
+  ],
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+    ),
+  ],
   Array [
     "publish",
     "Skipping workspace \\u001b[32mworkspace-p\\u001b[39m, marked as \\u001b[1mprivate\\u001b[22m",
@@ -431,6 +489,53 @@ exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color >
 
 exports[`test/lib/commands/publish.js TAP workspaces all workspaces - no color > warns about skipped private workspace 1`] = `
 Array [
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+      "repository" was changed from a string to an object
+    ),
+  ],
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+      "repository" was changed from a string to an object
+      "repository.url" was normalized to "git+https://github.com/npm/workspace-b.git"
+    ),
+  ],
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+    ),
+  ],
+  Array [
+    "publish",
+    "npm auto-corrected some errors in your package.json when publishing.  Please run \\"npm pkg fix\\" to address these errors.",
+  ],
+  Array [
+    "publish",
+    String(
+      errors corrected:
+      Removed invalid "scripts"
+    ),
+  ],
   Array [
     "publish",
     "Skipping workspace workspace-p, marked as private",
diff --git a/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs
index bfa4b42182e1ea..a47cdba22003fe 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/search.js.test.cjs
@@ -24,6 +24,7 @@ NAME                      | DESCRIPTION          | AUTHOR          | DATE
 @npmcli/map-workspaces    | Retrieves a…         | =nlf…           | 2020-09-30 | 1.0.1    | npm npmcli libnpm cli workspaces map-workspaces
 libnpmversion             | library to do the…   | =nlf…           | 2020-11-04 | 1.0.7    |
 @types/libnpmsearch       | TypeScript…          | =types          | 2019-09-26 | 2.0.1    |
+pkg-no-desc               |                      | =lukekarrys     | 2019-09-26 | 1.0.0    |
 `
 
 exports[`test/lib/commands/search.js TAP search  --color > should have expected search results with color 1`] = `
@@ -41,6 +42,7 @@ NAME                      | DESCRIPTION          | AUTHOR          | DATE
 @npmcli/map-workspaces    | Retrieves a…         | =nlf…           | 2020-09-30 | 1.0.1    | npm npmcli libnpm cli workspaces map-workspaces
 libnpmversion             | library to do the…   | =nlf…           | 2020-11-04 | 1.0.7    | 
 @types/libnpmsearch       | TypeScript…          | =types          | 2019-09-26 | 2.0.1    | 
+pkg-no-desc               |                      | =lukekarrys     | 2019-09-26 | 1.0.0    | 
 `
 
 exports[`test/lib/commands/search.js TAP search  --parseable > should have expected search results as parseable 1`] = `
@@ -57,6 +59,7 @@ libnpmfund	Programmatic API for npm fund	=nlf =ruyadorno =darcyclarke =isaacs	20
 @npmcli/map-workspaces	Retrieves a name:pathname Map for a given workspaces config	=nlf =ruyadorno =darcyclarke =isaacs	2020-09-30 	1.0.1	npm npmcli libnpm cli workspaces map-workspaces
 libnpmversion	library to do the things that 'npm version' does	=nlf =ruyadorno =darcyclarke =isaacs	2020-11-04 	1.0.7
 @types/libnpmsearch	TypeScript definitions for libnpmsearch	=types	2019-09-26 	2.0.1
+pkg-no-desc		=lukekarrys	2019-09-26 	1.0.0
 `
 
 exports[`test/lib/commands/search.js TAP search  > should have filtered expected search results 1`] = `
@@ -80,6 +83,7 @@ libnpmfund                | Programmatic API…    | =nlf…           | 2020-12
 @npmcli/map-workspaces    | Retrieves a…         | =nlf…           | 2020-09-30 | 1.0.1    | npm npmcli libnpm cli workspaces map-workspaces
 libnpmversion             | library to do the…   | =nlf…           | 2020-11-04 | 1.0.7    |
 @types/libnpmsearch       | TypeScript…          | =types          | 2019-09-26 | 2.0.1    |
+pkg-no-desc               |                      | =lukekarrys     | 2019-09-26 | 1.0.0    |
 `
 
 exports[`test/lib/commands/search.js TAP search exclude forward slash > results should not have libnpmversion 1`] = `
@@ -96,6 +100,7 @@ libnpmpublish             | Programmatic API…    | =nlf…           | 2020-11
 libnpmfund                | Programmatic API…    | =nlf…           | 2020-12-08 | 1.0.2    | npm npmcli libnpm cli git fund gitfund
 @npmcli/map-workspaces    | Retrieves a…         | =nlf…           | 2020-09-30 | 1.0.1    | npm npmcli libnpm cli workspaces map-workspaces
 @types/libnpmsearch       | TypeScript…          | =types          | 2019-09-26 | 2.0.1    |
+pkg-no-desc               |                      | =lukekarrys     | 2019-09-26 | 1.0.0    |
 `
 
 exports[`test/lib/commands/search.js TAP search exclude regex > results should not have libnpmversion 1`] = `
@@ -112,6 +117,7 @@ libnpmpublish             | Programmatic API…    | =nlf…           | 2020-11
 libnpmfund                | Programmatic API…    | =nlf…           | 2020-12-08 | 1.0.2    | npm npmcli libnpm cli git fund gitfund
 @npmcli/map-workspaces    | Retrieves a…         | =nlf…           | 2020-09-30 | 1.0.1    | npm npmcli libnpm cli workspaces map-workspaces
 @types/libnpmsearch       | TypeScript…          | =types          | 2019-09-26 | 2.0.1    |
+pkg-no-desc               |                      | =lukekarrys     | 2019-09-26 | 1.0.0    |
 `
 
 exports[`test/lib/commands/search.js TAP search exclude string > results should not have libnpmversion 1`] = `
@@ -128,6 +134,7 @@ libnpmpublish             | Programmatic API…    | =nlf…           | 2020-11
 libnpmfund                | Programmatic API…    | =nlf…           | 2020-12-08 | 1.0.2    | npm npmcli libnpm cli git fund gitfund
 @npmcli/map-workspaces    | Retrieves a…         | =nlf…           | 2020-09-30 | 1.0.1    | npm npmcli libnpm cli workspaces map-workspaces
 @types/libnpmsearch       | TypeScript…          | =types          | 2019-09-26 | 2.0.1    |
+pkg-no-desc               |                      | =lukekarrys     | 2019-09-26 | 1.0.0    |
 `
 
 exports[`test/lib/commands/search.js TAP search exclude username with upper case letters > results should not have nlf 1`] = `
@@ -135,4 +142,5 @@ NAME                      | DESCRIPTION          | AUTHOR          | DATE
 @evocateur/libnpmaccess   | programmatic…        | =evocateur      | 2019-07-16 | 3.1.2    |
 @evocateur/libnpmpublish  | Programmatic API…    | =evocateur      | 2019-07-16 | 1.2.2    |
 @types/libnpmsearch       | TypeScript…          | =types          | 2019-09-26 | 2.0.1    |
+pkg-no-desc               |                      | =lukekarrys     | 2019-09-26 | 1.0.0    |
 `
diff --git a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs
index 4875ebae6952b2..a7e3e6f665af18 100644
--- a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs
@@ -392,6 +392,16 @@ Run git commit hooks when using the \`npm version\` command.
 
 
 
+#### \`cpu\`
+
+* Default: null
+* Type: null or String
+
+Override CPU architecture of native modules to install. Acceptable values
+are same as \`cpu\` field of package.json, which comes from \`process.arch\`.
+
+
+
 #### \`depth\`
 
 * Default: \`Infinity\` if \`--all\` is set, otherwise \`1\`
@@ -1085,6 +1095,16 @@ time.
 
 
 
+#### \`os\`
+
+* Default: null
+* Type: null or String
+
+Override OS of native modules to install. Acceptable values are same as \`os\`
+field of package.json, which comes from \`process.platform\`.
+
+
+
 #### \`otp\`
 
 * Default: null
@@ -1822,20 +1842,6 @@ registry-scoped "certfile" path like
 
 
 
-#### \`ci-name\`
-
-* Default: The name of the current CI system, or \`null\` when not on a known CI
-  platform.
-* Type: null or String
-* DEPRECATED: This config is deprecated and will not be changeable in future
-  version of npm.
-
-The name of a continuous integration system. If not set explicitly, npm will
-detect the current CI environment using the
-[\`ci-info\`](http://npm.im/ci-info) module.
-
-
-
 #### \`dev\`
 
 * Default: false
@@ -1995,20 +2001,6 @@ Alias for \`--omit=dev\`
 Alias for --package-lock
 
 
-
-#### \`tmp\`
-
-* Default: The value returned by the Node.js \`os.tmpdir()\` method
-  
-* Type: Path
-* DEPRECATED: This setting is no longer used. npm stores temporary files in a
-  special location in the cache, and they are managed by
-  [\`cacache\`](http://npm.im/cacache).
-
-Historically, the location where temporary files were stored. No longer
-relevant.
-
-
 `
 
 exports[`test/lib/docs.js TAP config > all keys 1`] = `
@@ -2031,10 +2023,11 @@ Array [
   "cafile",
   "call",
   "cert",
-  "ci-name",
   "cidr",
   "color",
   "commit-hooks",
+  "cpu",
+  "os",
   "depth",
   "description",
   "dev",
@@ -2148,7 +2141,6 @@ Array [
   "tag",
   "tag-version-prefix",
   "timing",
-  "tmp",
   "umask",
   "unicode",
   "update-notifier",
@@ -2186,10 +2178,11 @@ Array [
   "cafile",
   "call",
   "cert",
-  "ci-name",
   "cidr",
   "color",
   "commit-hooks",
+  "cpu",
+  "os",
   "depth",
   "description",
   "dev",
@@ -2314,7 +2307,6 @@ Array [
   "node-options",
   "prefix",
   "timing",
-  "tmp",
   "update-notifier",
   "usage",
   "userconfig",
@@ -2343,9 +2335,9 @@ Object {
   "call": "",
   "cert": null,
   "cidr": null,
-  "ciName": "{ci}",
   "color": false,
   "commitHooks": true,
+  "cpu": null,
   "defaultTag": "latest",
   "depth": null,
   "diff": Array [],
@@ -2367,7 +2359,6 @@ Object {
   "gitTagVersion": true,
   "global": false,
   "globalconfig": "{CWD}/global/etc/npmrc",
-  "hashAlgorithm": "sha1",
   "heading": "npm",
   "httpsProxy": null,
   "ifPresent": false,
@@ -2388,13 +2379,14 @@ Object {
   "nodeBin": "{NODE}",
   "nodeVersion": "2.2.2",
   "noProxy": "",
-  "npmBin": "{CWD}/{TESTDIR}/docs.js",
+  "npmBin": "{CWD}/other/bin/npm-cli.js",
   "npmCommand": "version",
   "npmVersion": "3.3.3",
   "npxCache": "{CWD}/cache/_npx",
   "offline": false,
   "omit": Array [],
   "omitLockfileRegistryResolved": false,
+  "os": null,
   "otp": null,
   "package": Array [],
   "packageLock": true,
@@ -3204,7 +3196,7 @@ Options:
 [--global-style] [--omit  [--omit  ...]]
 [--strict-peer-deps] [--prefer-dedupe] [--no-package-lock] [--package-lock-only]
 [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links]
-[--no-fund] [--dry-run]
+[--no-fund] [--dry-run] [--cpu ] [--os ]
 [-w|--workspace  [-w|--workspace  ...]]
 [-ws|--workspaces] [--include-workspace-root] [--install-links]
 
@@ -3235,6 +3227,8 @@ aliases: add, i, in, ins, inst, insta, instal, isnt, isnta, isntal, isntall
 #### \`bin-links\`
 #### \`fund\`
 #### \`dry-run\`
+#### \`cpu\`
+#### \`os\`
 #### \`workspace\`
 #### \`workspaces\`
 #### \`include-workspace-root\`
@@ -3295,7 +3289,7 @@ Options:
 [--global-style] [--omit  [--omit  ...]]
 [--strict-peer-deps] [--prefer-dedupe] [--no-package-lock] [--package-lock-only]
 [--foreground-scripts] [--ignore-scripts] [--no-audit] [--no-bin-links]
-[--no-fund] [--dry-run]
+[--no-fund] [--dry-run] [--cpu ] [--os ]
 [-w|--workspace  [-w|--workspace  ...]]
 [-ws|--workspaces] [--include-workspace-root] [--install-links]
 
@@ -3326,6 +3320,8 @@ alias: it
 #### \`bin-links\`
 #### \`fund\`
 #### \`dry-run\`
+#### \`cpu\`
+#### \`os\`
 #### \`workspace\`
 #### \`workspaces\`
 #### \`include-workspace-root\`
diff --git a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
index 93711275392339..3e7bc4570dd4ad 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
@@ -63,4 +63,5 @@ verbose exit 1
 timing npm Completed in {TIME}ms
 verbose code 1
 error  A complete log of this run can be found in: {CWD}/cache/_logs/{DATE}-debug-0.log
+silly logfile done cleaning log files
 `
diff --git a/deps/npm/test/fixtures/libnpmsearch-stream-result.js b/deps/npm/test/fixtures/libnpmsearch-stream-result.js
index 1ec8b7b113d6b8..ac792b1c087c8f 100644
--- a/deps/npm/test/fixtures/libnpmsearch-stream-result.js
+++ b/deps/npm/test/fixtures/libnpmsearch-stream-result.js
@@ -275,4 +275,11 @@ module.exports = [
     publisher: { username: 'types', email: 'ts-npm-types@microsoft.com' },
     maintainers: [{ username: 'types', email: 'ts-npm-types@microsoft.com' }],
   },
+  {
+    name: 'pkg-no-desc',
+    scope: 'unscoped',
+    version: '1.0.0',
+    date: '2019-09-26T22:24:28.713Z',
+    maintainers: [{ username: 'lukekarrys', email: 'lukekarrys' }],
+  },
 ]
diff --git a/deps/npm/test/fixtures/sandbox.js b/deps/npm/test/fixtures/sandbox.js
index 2c4e5c2968a38c..5be02fcf80c1eb 100644
--- a/deps/npm/test/fixtures/sandbox.js
+++ b/deps/npm/test/fixtures/sandbox.js
@@ -42,11 +42,6 @@ const _get = Symbol('sandbox.proxy.get')
 const _set = Symbol('sandbox.proxy.set')
 const _logs = Symbol('sandbox.logs')
 
-// these config keys can be redacted widely
-const redactedDefaults = [
-  'tmp',
-]
-
 // we can't just replace these values everywhere because they're known to be
 // very short strings that could be present all over the place, so we only
 // replace them if they're located within quotes for now
@@ -161,12 +156,6 @@ class Sandbox extends EventEmitter {
     // and we replaced the node version first, the real execPath we're trying
     // to replace would no longer be represented, and be missed.
     if (this[_npm]) {
-      // replace default config values with placeholders
-      for (const name of redactedDefaults) {
-        const value = this[_npm].config.defaults[name]
-        clean = clean.split(normalize(value)).join(`{${name.toUpperCase()}}`)
-      }
-
       // replace vague default config values that are present within quotes
       // with placeholders
       for (const name of vagueRedactedDefaults) {
diff --git a/deps/npm/test/lib/commands/audit.js b/deps/npm/test/lib/commands/audit.js
index 4014e733873519..4a776e89bd9e9c 100644
--- a/deps/npm/test/lib/commands/audit.js
+++ b/deps/npm/test/lib/commands/audit.js
@@ -1699,16 +1699,12 @@ t.test('audit signatures', async t => {
     const { npm } = await loadMockNpm(t, {
       prefixDir: installWithMultipleDeps,
       mocks: {
-        sigstore: {
-          sigstore: {
-            tuf: {
-              client: async () => ({
-                getTarget: async () => {
-                  throw new Error('error refreshing TUF metadata')
-                },
-              }),
+        '@sigstore/tuf': {
+          initTUF: async () => ({
+            getTarget: async () => {
+              throw new Error('error refreshing TUF metadata')
             },
-          },
+          }),
         },
       },
     })
@@ -1877,9 +1873,7 @@ t.test('audit signatures', async t => {
       prefixDir: installWithValidAttestations,
       mocks: {
         pacote: t.mock('pacote', {
-          sigstore: {
-            sigstore: { verify: async () => true },
-          },
+          sigstore: { verify: async () => true },
         }),
       },
     })
@@ -1904,9 +1898,7 @@ t.test('audit signatures', async t => {
       prefixDir: installWithMultipleValidAttestations,
       mocks: {
         pacote: t.mock('pacote', {
-          sigstore: {
-            sigstore: { verify: async () => true },
-          },
+          sigstore: { verify: async () => true },
         }),
       },
     })
@@ -1937,10 +1929,8 @@ t.test('audit signatures', async t => {
       mocks: {
         pacote: t.mock('pacote', {
           sigstore: {
-            sigstore: {
-              verify: async () => {
-                throw new Error(`artifact signature verification failed`)
-              },
+            verify: async () => {
+              throw new Error(`artifact signature verification failed`)
             },
           },
         }),
@@ -1974,10 +1964,8 @@ t.test('audit signatures', async t => {
       mocks: {
         pacote: t.mock('pacote', {
           sigstore: {
-            sigstore: {
-              verify: async () => {
-                throw new Error(`artifact signature verification failed`)
-              },
+            verify: async () => {
+              throw new Error(`artifact signature verification failed`)
             },
           },
         }),
@@ -2005,10 +1993,8 @@ t.test('audit signatures', async t => {
       mocks: {
         pacote: t.mock('pacote', {
           sigstore: {
-            sigstore: {
-              verify: async () => {
-                throw new Error(`artifact signature verification failed`)
-              },
+            verify: async () => {
+              throw new Error(`artifact signature verification failed`)
             },
           },
         }),
diff --git a/deps/npm/test/lib/commands/exec.js b/deps/npm/test/lib/commands/exec.js
index 2fd11f40379f1f..07a3e6ebd8ed95 100644
--- a/deps/npm/test/lib/commands/exec.js
+++ b/deps/npm/test/lib/commands/exec.js
@@ -129,3 +129,38 @@ t.test('workspaces', async t => {
   const exists = await fs.stat(path.join(npm.prefix, 'workspace-a', 'npm-exec-test-success'))
   t.ok(exists.isFile(), 'bin ran, creating file inside workspace')
 })
+
+t.test('npx --no-install @npmcli/npx-test', async t => {
+  const registry = new MockRegistry({
+    tap: t,
+    registry: 'https://registry.npmjs.org/',
+  })
+
+  const manifest = registry.manifest({ name: '@npmcli/npx-test' })
+  manifest.versions['1.0.0'].bin = { 'npx-test': 'index.js' }
+
+  const { npm } = await loadMockNpm(t, {
+    config: {
+      audit: false,
+      yes: false,
+    },
+    prefixDir: {
+      'npm-exec-test': {
+        'package.json': JSON.stringify(manifest),
+        'index.js': `#!/usr/bin/env node
+  require('fs').writeFileSync('npm-exec-test-success', '')`,
+      },
+    },
+  })
+
+  try {
+    await npm.exec('exec', ['@npmcli/npx-test'])
+    t.fail('Expected error was not thrown')
+  } catch (error) {
+    t.match(
+      error.message,
+      'npx canceled due to missing packages and no YES option: ',
+      'Expected error message thrown'
+    )
+  }
+})
diff --git a/deps/npm/test/lib/commands/run-script.js b/deps/npm/test/lib/commands/run-script.js
index cb54a7f51e9002..24f51400e8dfc3 100644
--- a/deps/npm/test/lib/commands/run-script.js
+++ b/deps/npm/test/lib/commands/run-script.js
@@ -781,12 +781,7 @@ t.test('workspaces', async t => {
   t.test('missing scripts in all workspaces', async t => {
     const { runScript, RUN_SCRIPTS, cleanLogs } = await mockWorkspaces(t, { exec: null })
 
-    await t.rejects(
-      runScript.exec(['missing-script']),
-      /Missing script: missing-script/,
-      'should throw missing script error'
-    )
-
+    await runScript.exec(['missing-script'])
     t.match(RUN_SCRIPTS(), [])
     t.strictSame(
       cleanLogs(),
diff --git a/deps/npm/test/lib/utils/exit-handler.js b/deps/npm/test/lib/utils/exit-handler.js
index f553e1a2ea518d..3eb5840985b8f5 100644
--- a/deps/npm/test/lib/utils/exit-handler.js
+++ b/deps/npm/test/lib/utils/exit-handler.js
@@ -132,6 +132,8 @@ t.test('handles unknown error with logs and debug file', async (t) => {
   const { exitHandler, debugFile, logs } = await mockExitHandler(t)
 
   await exitHandler(err('Unknown error', 'ECODE'))
+  // force logfile cleaning logs to happen since those are purposefully not awaited
+  await require('timers/promises').setTimeout(200)
 
   const fileLogs = await debugFile()
   const fileLines = fileLogs.split('\n')
@@ -141,14 +143,19 @@ t.test('handles unknown error with logs and debug file', async (t) => {
 
   t.equal(process.exitCode, 1)
 
+  let skippedLogs = 0
   logs.forEach((logItem, i) => {
     const logLines = format(i, ...logItem).trim().split(os.EOL)
-    logLines.forEach((line) => {
+    for (const line of logLines) {
+      if (line.includes('logfile') && line.includes('cleaning')) {
+        skippedLogs++
+        continue
+      }
       t.match(fileLogs.trim(), line, 'log appears in debug file')
-    })
+    }
   })
 
-  t.equal(logs.length, parseInt(lastLog) + 1)
+  t.equal(logs.length - skippedLogs, parseInt(lastLog) + 1)
   t.match(logs.error, [
     ['code', 'ECODE'],
     ['ERR SUMMARY', 'Unknown error'],
diff --git a/deps/openssl/config/archs/BSD-x86/asm/configdata.pm b/deps/openssl/config/archs/BSD-x86/asm/configdata.pm
index f7f8b5656dfcbc..667d9eb6c472cd 100644
--- a/deps/openssl/config/archs/BSD-x86/asm/configdata.pm
+++ b/deps/openssl/config/archs/BSD-x86/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -203,7 +203,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -255,11 +255,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "BSD-x86",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1596,6 +1596,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1643,7 +1644,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h
index a5c1149cf4ef69..c83c080bcb3ade 100644
--- a/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/BSD-x86/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: BSD-x86"
-#define DATE "built on: Fri Jun  9 11:58:46 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:25:19 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/BSD-x86/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/BSD-x86/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/BSD-x86/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/BSD-x86/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/BSD-x86/asm/openssl-cl.gypi b/deps/openssl/config/archs/BSD-x86/asm/openssl-cl.gypi
index aa119eb5fd57c9..4380305593acd1 100644
--- a/deps/openssl/config/archs/BSD-x86/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/BSD-x86/asm/openssl-cl.gypi
@@ -17,6 +17,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86/asm/openssl.gypi b/deps/openssl/config/archs/BSD-x86/asm/openssl.gypi
index 2a4a7ba93b93d2..c984f3e0f752ca 100644
--- a/deps/openssl/config/archs/BSD-x86/asm/openssl.gypi
+++ b/deps/openssl/config/archs/BSD-x86/asm/openssl.gypi
@@ -993,6 +993,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm b/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm
index fe8c42f5c72614..d21a502b43b514 100644
--- a/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/BSD-x86/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -203,7 +203,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -255,11 +255,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "BSD-x86",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1596,6 +1596,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1643,7 +1644,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h
index bacd1f1db009eb..b3e839decc98ce 100644
--- a/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/BSD-x86/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: BSD-x86"
-#define DATE "built on: Fri Jun  9 11:59:07 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:25:40 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/BSD-x86/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/BSD-x86/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/BSD-x86/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/BSD-x86/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl-cl.gypi
index 806e39e55f9863..dc324536e46ce0 100644
--- a/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl-cl.gypi
@@ -17,6 +17,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl.gypi b/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl.gypi
index f4392fdfa2727d..60512e2b588cfc 100644
--- a/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/BSD-x86/asm_avx2/openssl.gypi
@@ -993,6 +993,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm b/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm
index f304aeafc1f071..df06e22c5669e8 100644
--- a/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/BSD-x86/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -202,7 +202,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -255,11 +255,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "BSD-x86",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h
index 0385ea99f117a7..0b2dc3af6c4db6 100644
--- a/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/BSD-x86/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: BSD-x86"
-#define DATE "built on: Fri Jun  9 11:59:26 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:26:00 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/BSD-x86/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/BSD-x86/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/BSD-x86/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/BSD-x86/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm b/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm
index 94053117f2bca1..f3476682006a8a 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm
+++ b/deps/openssl/config/archs/BSD-x86_64/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -203,7 +203,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -255,11 +255,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "BSD-x86_64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1598,6 +1598,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1649,7 +1650,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h
index 030011ddd329d1..8220828c4d379e 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/BSD-x86_64/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: BSD-x86_64"
-#define DATE "built on: Fri Jun  9 11:59:45 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:26:19 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/BSD-x86_64/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/BSD-x86_64/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm/openssl-cl.gypi b/deps/openssl/config/archs/BSD-x86_64/asm/openssl-cl.gypi
index 7a4fc80cc44f5a..bfe296a44f604b 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/BSD-x86_64/asm/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm/openssl.gypi b/deps/openssl/config/archs/BSD-x86_64/asm/openssl.gypi
index d666f1d87ab6ee..7a468bd82eca92 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm/openssl.gypi
+++ b/deps/openssl/config/archs/BSD-x86_64/asm/openssl.gypi
@@ -1007,6 +1007,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm
index 8ee8ba6f5f209c..07333980e3d535 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -203,7 +203,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -255,11 +255,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "BSD-x86_64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1598,6 +1598,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1649,7 +1650,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h
index e51610d0ee444a..0141bc595c4669 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: BSD-x86_64"
-#define DATE "built on: Fri Jun  9 12:00:09 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:26:43 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl-cl.gypi
index 42d807726ccf63..108012655aa24f 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl.gypi b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl.gypi
index e5835b13683008..6de0252f4666f3 100644
--- a/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/BSD-x86_64/asm_avx2/openssl.gypi
@@ -1007,6 +1007,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm b/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm
index fe6faf48fe717b..daa479b8c190aa 100644
--- a/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/BSD-x86_64/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -202,7 +202,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -255,11 +255,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "BSD-x86_64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h
index 76c3d4c52a8c42..f1fbc792476400 100644
--- a/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/BSD-x86_64/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: BSD-x86_64"
-#define DATE "built on: Fri Jun  9 12:00:34 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:27:07 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/BSD-x86_64/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/BSD-x86_64/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/BSD-x86_64/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/BSD-x86_64/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm b/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm
index 5f342faf4fe565..ca62a99b20e7e9 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm
+++ b/deps/openssl/config/archs/VC-WIN32/asm/configdata.pm
@@ -165,7 +165,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -216,7 +216,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -268,11 +268,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "VC-WIN32",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "lib",
@@ -287,7 +287,7 @@ our %target = (
     "LDFLAGS" => "/nologo /debug",
     "MT" => "mt",
     "MTFLAGS" => "-nologo",
-    "RANLIB" => "CODE(0x55fe658edb00)",
+    "RANLIB" => "CODE(0x55c06cf5ea80)",
     "RC" => "rc",
     "_conf_fname_int" => [
         "Configurations/00-base-templates.conf",
@@ -1644,6 +1644,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1691,7 +1692,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h
index db23ff982f9c84..b4978c23fed544 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/VC-WIN32/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: "
-#define DATE "built on: Fri Jun  9 12:15:22 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:43:26 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/VC-WIN32/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/VC-WIN32/asm/include/openssl/opensslv.h
index 874d53c931fc8a..38b44f1054ad3d 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/VC-WIN32/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/VC-WIN32/asm/openssl-cl.gypi b/deps/openssl/config/archs/VC-WIN32/asm/openssl-cl.gypi
index 8f32c2e84d2e5e..b0f6b78e59e0d9 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/VC-WIN32/asm/openssl-cl.gypi
@@ -22,6 +22,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN32/asm/openssl.gypi b/deps/openssl/config/archs/VC-WIN32/asm/openssl.gypi
index 07b539779f9fe1..7a415cb3da09cb 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm/openssl.gypi
+++ b/deps/openssl/config/archs/VC-WIN32/asm/openssl.gypi
@@ -995,6 +995,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm b/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm
index 489b9a56592a91..62ccddd60f494f 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/VC-WIN32/asm_avx2/configdata.pm
@@ -165,7 +165,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -216,7 +216,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -268,11 +268,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "VC-WIN32",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "lib",
@@ -287,7 +287,7 @@ our %target = (
     "LDFLAGS" => "/nologo /debug",
     "MT" => "mt",
     "MTFLAGS" => "-nologo",
-    "RANLIB" => "CODE(0x55d85b90f3a0)",
+    "RANLIB" => "CODE(0x55b8a711a640)",
     "RC" => "rc",
     "_conf_fname_int" => [
         "Configurations/00-base-templates.conf",
@@ -1644,6 +1644,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1691,7 +1692,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h
index 81c4bb130a934e..00774a2a9b5c85 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/VC-WIN32/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: "
-#define DATE "built on: Fri Jun  9 12:15:41 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:43:47 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/VC-WIN32/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/VC-WIN32/asm_avx2/include/openssl/opensslv.h
index 874d53c931fc8a..38b44f1054ad3d 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/VC-WIN32/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl-cl.gypi
index adeaadc5e80a03..487571baf1b020 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl-cl.gypi
@@ -22,6 +22,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl.gypi b/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl.gypi
index 607341683d0b56..0eb291c5b04f91 100644
--- a/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/VC-WIN32/asm_avx2/openssl.gypi
@@ -995,6 +995,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm b/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm
index 95f445562af65d..9a5d93c30fa1ab 100644
--- a/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/VC-WIN32/no-asm/configdata.pm
@@ -163,7 +163,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -215,7 +215,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -268,11 +268,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "VC-WIN32",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "lib",
@@ -287,7 +287,7 @@ our %target = (
     "LDFLAGS" => "/nologo /debug",
     "MT" => "mt",
     "MTFLAGS" => "-nologo",
-    "RANLIB" => "CODE(0x563faaebacb8)",
+    "RANLIB" => "CODE(0x55ac94d0db28)",
     "RC" => "rc",
     "_conf_fname_int" => [
         "Configurations/00-base-templates.conf",
diff --git a/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h
index e5d99ffb1f85e4..b19b8b48b13928 100644
--- a/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/VC-WIN32/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: "
-#define DATE "built on: Fri Jun  9 12:16:00 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:44:09 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/VC-WIN32/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/VC-WIN32/no-asm/include/openssl/opensslv.h
index 874d53c931fc8a..38b44f1054ad3d 100644
--- a/deps/openssl/config/archs/VC-WIN32/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/VC-WIN32/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm
index 326aee8a214bfc..4c747db9cfb5c7 100644
--- a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/configdata.pm
@@ -163,7 +163,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -213,7 +213,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -266,11 +266,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "VC-WIN64-ARM",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "lib",
@@ -283,7 +283,7 @@ our %target = (
     "LDFLAGS" => "/nologo /debug",
     "MT" => "mt",
     "MTFLAGS" => "-nologo",
-    "RANLIB" => "CODE(0x556dc7ce0ba8)",
+    "RANLIB" => "CODE(0x56025ddf3078)",
     "RC" => "rc",
     "_conf_fname_int" => [
         "Configurations/00-base-templates.conf",
diff --git a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h
index 8d5b5a0265ca60..f32efe5d98eca3 100644
--- a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: VC-WIN64-ARM"
-#define DATE "built on: Fri Jun  9 12:16:18 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:44:29 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/include/openssl/opensslv.h
index 874d53c931fc8a..38b44f1054ad3d 100644
--- a/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/VC-WIN64-ARM/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm b/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm
index 772e2a57e368e9..80443a734d38e4 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm
+++ b/deps/openssl/config/archs/VC-WIN64A/asm/configdata.pm
@@ -168,7 +168,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -219,7 +219,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -271,11 +271,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "VC-WIN64A",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "lib",
@@ -290,7 +290,7 @@ our %target = (
     "LDFLAGS" => "/nologo /debug",
     "MT" => "mt",
     "MTFLAGS" => "-nologo",
-    "RANLIB" => "CODE(0x55a5434b2770)",
+    "RANLIB" => "CODE(0x56532d60fad0)",
     "RC" => "rc",
     "_conf_fname_int" => [
         "Configurations/00-base-templates.conf",
@@ -1649,6 +1649,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1700,7 +1701,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h
index 75f69ed990b56e..06a91884502b77 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/VC-WIN64A/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: "
-#define DATE "built on: Fri Jun  9 12:14:15 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:42:10 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/VC-WIN64A/asm/include/openssl/opensslv.h
index 874d53c931fc8a..38b44f1054ad3d 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/VC-WIN64A/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm/openssl-cl.gypi b/deps/openssl/config/archs/VC-WIN64A/asm/openssl-cl.gypi
index dc54c7aa2c78fb..9b7e878e1c497d 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/VC-WIN64A/asm/openssl-cl.gypi
@@ -23,6 +23,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm/openssl.gypi b/deps/openssl/config/archs/VC-WIN64A/asm/openssl.gypi
index c1fe444ecbef8d..5afa3d7541147c 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm/openssl.gypi
+++ b/deps/openssl/config/archs/VC-WIN64A/asm/openssl.gypi
@@ -1009,6 +1009,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm
index cbc250155f4bd0..08fdeedbf613bf 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/configdata.pm
@@ -168,7 +168,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -219,7 +219,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -271,11 +271,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "VC-WIN64A",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "lib",
@@ -290,7 +290,7 @@ our %target = (
     "LDFLAGS" => "/nologo /debug",
     "MT" => "mt",
     "MTFLAGS" => "-nologo",
-    "RANLIB" => "CODE(0x5590b4594db0)",
+    "RANLIB" => "CODE(0x56478be29bd0)",
     "RC" => "rc",
     "_conf_fname_int" => [
         "Configurations/00-base-templates.conf",
@@ -1649,6 +1649,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1700,7 +1701,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h
index c4f414e265d1f9..196661655556bf 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: "
-#define DATE "built on: Fri Jun  9 12:14:40 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:42:38 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/include/openssl/opensslv.h
index 874d53c931fc8a..38b44f1054ad3d 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl-cl.gypi
index 1b37356b4c3fc7..5eafa74db33530 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl-cl.gypi
@@ -23,6 +23,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl.gypi b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl.gypi
index d7fd83a46e3910..582f8c93a5b10f 100644
--- a/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/VC-WIN64A/asm_avx2/openssl.gypi
@@ -1009,6 +1009,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm b/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm
index 5e12aa14fe94ad..37fe7ad1554464 100644
--- a/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/VC-WIN64A/no-asm/configdata.pm
@@ -166,7 +166,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -218,7 +218,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -271,11 +271,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "VC-WIN64A",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "lib",
@@ -290,7 +290,7 @@ our %target = (
     "LDFLAGS" => "/nologo /debug",
     "MT" => "mt",
     "MTFLAGS" => "-nologo",
-    "RANLIB" => "CODE(0x559ab9a64278)",
+    "RANLIB" => "CODE(0x55ad7db3afe8)",
     "RC" => "rc",
     "_conf_fname_int" => [
         "Configurations/00-base-templates.conf",
diff --git a/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h
index 51a79f2842b4d2..f0e9d087e2267d 100644
--- a/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/VC-WIN64A/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: "
-#define DATE "built on: Fri Jun  9 12:15:04 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:43:05 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/VC-WIN64A/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/VC-WIN64A/no-asm/include/openssl/opensslv.h
index 874d53c931fc8a..38b44f1054ad3d 100644
--- a/deps/openssl/config/archs/VC-WIN64A/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/VC-WIN64A/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/aix64-gcc-as/asm/configdata.pm b/deps/openssl/config/archs/aix64-gcc-as/asm/configdata.pm
index 45f66d88bec8bd..ca05289b718d86 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/asm/configdata.pm
+++ b/deps/openssl/config/archs/aix64-gcc-as/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "aix64-gcc-as",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar -X64",
diff --git a/deps/openssl/config/archs/aix64-gcc-as/asm/crypto/buildinf.h b/deps/openssl/config/archs/aix64-gcc-as/asm/crypto/buildinf.h
index d13a70519f2a29..3f01432e2b1840 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/aix64-gcc-as/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: aix64-gcc-as"
-#define DATE "built on: Fri Jun  9 11:57:48 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:24:21 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/aix64-gcc-as/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/aix64-gcc-as/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/aix64-gcc-as/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/configdata.pm b/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/configdata.pm
index 8b3a1f0ee5f0bb..a8d6fc77f0ac2d 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "aix64-gcc-as",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar -X64",
diff --git a/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/crypto/buildinf.h
index b49627c01c44a0..ec624a65971b4b 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: aix64-gcc-as"
-#define DATE "built on: Fri Jun  9 11:58:08 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:24:41 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/aix64-gcc-as/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/aix64-gcc-as/no-asm/configdata.pm b/deps/openssl/config/archs/aix64-gcc-as/no-asm/configdata.pm
index c43b955a97f1fa..fdfbcce8adc844 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/aix64-gcc-as/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -205,7 +205,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "aix64-gcc-as",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar -X64",
diff --git a/deps/openssl/config/archs/aix64-gcc-as/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/aix64-gcc-as/no-asm/crypto/buildinf.h
index 087f6580773805..83233146a50c97 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/aix64-gcc-as/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: aix64-gcc-as"
-#define DATE "built on: Fri Jun  9 11:58:27 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:25:01 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/aix64-gcc-as/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/aix64-gcc-as/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/aix64-gcc-as/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/aix64-gcc-as/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm b/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm
index dd2e698e0ccc04..ba53b9f9cea130 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin-i386-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1598,6 +1598,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1645,7 +1646,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h
index 88afb06bbc114d..e98ef7735cb4ed 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin-i386-cc"
-#define DATE "built on: Fri Jun  9 12:01:57 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:28:31 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin-i386-cc/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm/openssl-cl.gypi b/deps/openssl/config/archs/darwin-i386-cc/asm/openssl-cl.gypi
index fa640617e063e8..eeb54ba669b40a 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm/openssl-cl.gypi
@@ -17,6 +17,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm/openssl.gypi b/deps/openssl/config/archs/darwin-i386-cc/asm/openssl.gypi
index cf331ff9355043..1fac08080709a0 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm/openssl.gypi
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm/openssl.gypi
@@ -990,6 +990,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm
index 0236d99d33a9a7..a1999fe03a4772 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin-i386-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1598,6 +1598,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1645,7 +1646,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h
index db1463ebd9208a..76159a1731d678 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin-i386-cc"
-#define DATE "built on: Fri Jun  9 12:02:18 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:28:51 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl-cl.gypi
index 41086e27bb8150..235d0cac01e4c0 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl-cl.gypi
@@ -17,6 +17,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl.gypi b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl.gypi
index 09d5fd91d86031..0f428fdfbb5bd7 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/darwin-i386-cc/asm_avx2/openssl.gypi
@@ -990,6 +990,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm b/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm
index face9f022762e9..97fab50db92bdf 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/darwin-i386-cc/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -205,7 +205,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin-i386-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h
index cd966a1098c64c..67ace143c5c393 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin-i386-cc/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin-i386-cc"
-#define DATE "built on: Fri Jun  9 12:02:39 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:29:11 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin-i386-cc/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin-i386-cc/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin-i386-cc/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin-i386-cc/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/asm/configdata.pm b/deps/openssl/config/archs/darwin64-arm64-cc/asm/configdata.pm
index f857559a756c8c..9b51a15ef51371 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/asm/configdata.pm
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin64-arm64-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-arm64-cc/asm/crypto/buildinf.h
index c8ae0aa7190e5b..2e38ca1fc8f695 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin64-arm64-cc"
-#define DATE "built on: Fri Jun  9 12:02:57 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:29:30 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin64-arm64-cc/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/configdata.pm b/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/configdata.pm
index 051e75f55a534a..a465039cbfa855 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin64-arm64-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/crypto/buildinf.h
index 7e1526a94e38f5..513091049d0260 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin64-arm64-cc"
-#define DATE "built on: Fri Jun  9 12:03:16 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:29:49 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/configdata.pm b/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/configdata.pm
index 2b2d5f67b14150..6519d8eb5ee0d2 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -205,7 +205,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin64-arm64-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/crypto/buildinf.h
index 4d475f83e339a0..bf5b5aecd602cd 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin64-arm64-cc"
-#define DATE "built on: Fri Jun  9 12:03:36 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:30:09 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin64-arm64-cc/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm
index 5a0805d8dea9b8..8f523192cad9d4 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin64-x86_64-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1599,6 +1599,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1650,7 +1651,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h
index 6fd9893b8e143e..2c108157902d0c 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin64-x86_64-cc"
-#define DATE "built on: Fri Jun  9 12:00:52 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:27:25 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl-cl.gypi b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl-cl.gypi
index 22e4d3d9cad4fe..6fc980121a0b7e 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl.gypi b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl.gypi
index 14a4210edba15c..454a35a31ecd9a 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl.gypi
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm/openssl.gypi
@@ -1004,6 +1004,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm
index be4cf2a3bf2879..d036b582d78c68 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin64-x86_64-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1599,6 +1599,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1650,7 +1651,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h
index 84dffeb542dd42..994cec42e962cd 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin64-x86_64-cc"
-#define DATE "built on: Fri Jun  9 12:01:16 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:27:49 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl-cl.gypi
index 0b8979e20eb300..b4fdd2479ed704 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl.gypi b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl.gypi
index cb4fc2bf7ab75f..b6218392f74489 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/asm_avx2/openssl.gypi
@@ -1004,6 +1004,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm
index 6f7fd736109dc9..e85b222e7d012d 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -205,7 +205,7 @@ our %config = (
     ],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -258,11 +258,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "darwin64-x86_64-cc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h
index 368c58965bb070..fb875ca7f85df2 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: darwin64-x86_64-cc"
-#define DATE "built on: Fri Jun  9 12:01:39 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:28:13 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/darwin64-x86_64-cc/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm b/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm
index 029caf8c119fcf..8d48c4016f8c8b 100644
--- a/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-aarch64/asm/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-aarch64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h
index 8b8d370ee5f7f1..59ce7dfcd536af 100644
--- a/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-aarch64/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-aarch64"
-#define DATE "built on: Fri Jun  9 12:03:54 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:30:30 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-aarch64/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-aarch64/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-aarch64/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-aarch64/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm
index 7c4e9d65f86317..9d498a04297dd0 100644
--- a/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux-aarch64/asm_avx2/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-aarch64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h
index 0e97659b1b9b54..8044c52de8534f 100644
--- a/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-aarch64/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-aarch64"
-#define DATE "built on: Fri Jun  9 12:04:14 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:30:52 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-aarch64/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-aarch64/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-aarch64/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-aarch64/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm b/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm
index 6fa7cbd666927f..31514639fa12cd 100644
--- a/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-aarch64/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-aarch64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h
index 6312c75141ff39..2c556e7c636514 100644
--- a/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-aarch64/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-aarch64"
-#define DATE "built on: Fri Jun  9 12:04:34 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:31:14 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-aarch64/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-aarch64/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-aarch64/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-aarch64/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-armv4/asm/configdata.pm b/deps/openssl/config/archs/linux-armv4/asm/configdata.pm
index c8549b716ed284..b6536beee0911a 100644
--- a/deps/openssl/config/archs/linux-armv4/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-armv4/asm/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-armv4",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h
index 5483148e0d9fa3..16acd7cb38014e 100644
--- a/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-armv4/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-armv4"
-#define DATE "built on: Fri Jun  9 12:04:54 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:31:35 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-armv4/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-armv4/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-armv4/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-armv4/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm
index 203ca2516c4476..2d6713a69fe77a 100644
--- a/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux-armv4/asm_avx2/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-armv4",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h
index d0aa130324d6ba..2ee5795e784c20 100644
--- a/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-armv4/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-armv4"
-#define DATE "built on: Fri Jun  9 12:05:16 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:31:58 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-armv4/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-armv4/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-armv4/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-armv4/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm b/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm
index ce3e0a42c34881..bee312afe923a3 100644
--- a/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-armv4/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-armv4",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h
index d5645c2e250669..37415a157b7a5a 100644
--- a/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-armv4/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-armv4"
-#define DATE "built on: Fri Jun  9 12:05:35 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:32:20 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-armv4/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-armv4/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-armv4/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-armv4/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-elf/asm/configdata.pm b/deps/openssl/config/archs/linux-elf/asm/configdata.pm
index 35521a3b9a8248..fe754b5ea008b5 100644
--- a/deps/openssl/config/archs/linux-elf/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-elf/asm/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-elf",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1604,6 +1604,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1651,7 +1652,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h
index 2833ceecca2d7a..f58e1b3b022376 100644
--- a/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-elf/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-elf"
-#define DATE "built on: Fri Jun  9 12:05:54 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:32:41 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-elf/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-elf/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-elf/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-elf/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-elf/asm/openssl-cl.gypi b/deps/openssl/config/archs/linux-elf/asm/openssl-cl.gypi
index 412214ff027bec..8f021d5c21263e 100644
--- a/deps/openssl/config/archs/linux-elf/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux-elf/asm/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux-elf/asm/openssl.gypi b/deps/openssl/config/archs/linux-elf/asm/openssl.gypi
index f8bb8061186381..0cf7d926c47e93 100644
--- a/deps/openssl/config/archs/linux-elf/asm/openssl.gypi
+++ b/deps/openssl/config/archs/linux-elf/asm/openssl.gypi
@@ -993,6 +993,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm
index f1c5d3bdc01ed4..083f6bc78525da 100644
--- a/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux-elf/asm_avx2/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-elf",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1604,6 +1604,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1651,7 +1652,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h
index f17e29484d2840..cfff344f504f1f 100644
--- a/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-elf/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-elf"
-#define DATE "built on: Fri Jun  9 12:06:15 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:33:04 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-elf/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-elf/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-elf/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-elf/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-elf/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/linux-elf/asm_avx2/openssl-cl.gypi
index 2e818082b7baac..4e2c60206e2c21 100644
--- a/deps/openssl/config/archs/linux-elf/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux-elf/asm_avx2/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux-elf/asm_avx2/openssl.gypi b/deps/openssl/config/archs/linux-elf/asm_avx2/openssl.gypi
index 31ae85eee1e27f..4ca065ef163fd8 100644
--- a/deps/openssl/config/archs/linux-elf/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/linux-elf/asm_avx2/openssl.gypi
@@ -993,6 +993,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm b/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm
index 69069353323851..a5e1137b149e7a 100644
--- a/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-elf/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-elf",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h
index 8289ac097f3f28..0dd30616b28e66 100644
--- a/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-elf/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-elf"
-#define DATE "built on: Fri Jun  9 12:06:35 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:33:27 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-elf/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-elf/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-elf/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-elf/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm b/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm
index ba849aab6ad85e..f979f6f060f9b6 100644
--- a/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-ppc64le/asm/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-ppc64le",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h
index 02933f6dcf4c97..c45299350be3f9 100644
--- a/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-ppc64le/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-ppc64le"
-#define DATE "built on: Fri Jun  9 12:08:05 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:35:08 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-ppc64le/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-ppc64le/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-ppc64le/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-ppc64le/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm
index be99b4e22f7b01..08080140eb2e78 100644
--- a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-ppc64le",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h
index adf8760ec18c50..2395cef1030cd0 100644
--- a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-ppc64le"
-#define DATE "built on: Fri Jun  9 12:08:25 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:35:31 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-ppc64le/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-ppc64le/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm b/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm
index 8e3ad7b5776a38..189ada48854119 100644
--- a/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-ppc64le/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-ppc64le",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h
index b77a7e069c3273..bf4a292031de3f 100644
--- a/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-ppc64le/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-ppc64le"
-#define DATE "built on: Fri Jun  9 12:08:46 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:35:54 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-ppc64le/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-ppc64le/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-ppc64le/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-ppc64le/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm b/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm
index c2f948fe7636b2..133c99bdb8379f 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-x86_64/asm/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-x86_64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1607,6 +1607,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1658,7 +1659,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h
index b79059d5f8a546..13c3b4c33b64c4 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-x86_64/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-x86_64"
-#define DATE "built on: Fri Jun  9 12:06:54 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:33:49 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-x86_64/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-x86_64/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-x86_64/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-x86_64/asm/openssl-cl.gypi b/deps/openssl/config/archs/linux-x86_64/asm/openssl-cl.gypi
index f2859f81db38a1..cae54ea439244b 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux-x86_64/asm/openssl-cl.gypi
@@ -19,6 +19,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/linux-x86_64/asm/openssl.gypi b/deps/openssl/config/archs/linux-x86_64/asm/openssl.gypi
index 0f35968566e11d..14bcd8e7f8fbed 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm/openssl.gypi
+++ b/deps/openssl/config/archs/linux-x86_64/asm/openssl.gypi
@@ -1007,6 +1007,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm
index 44a4cc40e82632..682f020891c38e 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux-x86_64/asm_avx2/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-x86_64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1607,6 +1607,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1658,7 +1659,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h
index 7309b9400bf53d..1d83deffde45f4 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-x86_64/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-x86_64"
-#define DATE "built on: Fri Jun  9 12:07:21 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:34:19 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-x86_64/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-x86_64/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-x86_64/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl-cl.gypi
index b69ffe3bcb391b..e6e8d9052b1633 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl-cl.gypi
@@ -19,6 +19,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl.gypi b/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl.gypi
index f65991fee158c8..20c248d53cc144 100644
--- a/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/linux-x86_64/asm_avx2/openssl.gypi
@@ -1007,6 +1007,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm b/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm
index 29376e60ea0182..3beffa26651377 100644
--- a/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux-x86_64/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux-x86_64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h
index 1a65c33e1a42c7..c3499dd469d71a 100644
--- a/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux-x86_64/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux-x86_64"
-#define DATE "built on: Fri Jun  9 12:07:46 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:34:48 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux-x86_64/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux-x86_64/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux-x86_64/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux-x86_64/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm b/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm
index 9c834e7af9f81f..b4729ad28f92ae 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux32-s390x/asm/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux32-s390x",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1601,6 +1601,7 @@ our %unified_info = (
             "OPENSSL_BN_ASM_MONT",
             "OPENSSL_CPUID_OBJ",
             "POLY1305_ASM",
+            "RC4_ASM",
             "S390X_EC_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1640,6 +1641,9 @@ our %unified_info = (
             "SHA256_ASM",
             "SHA512_ASM"
         ],
+        "providers/liblegacy.a" => [
+            "RC4_ASM"
+        ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
         ],
diff --git a/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h
index e90bf206b73b2d..210dcc63df0ff1 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux32-s390x/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux32-s390x"
-#define DATE "built on: Fri Jun  9 12:09:05 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:36:17 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux32-s390x/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux32-s390x/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux32-s390x/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux32-s390x/asm/openssl-cl.gypi b/deps/openssl/config/archs/linux32-s390x/asm/openssl-cl.gypi
index bc25c5dffbba90..0333449e35d511 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux32-s390x/asm/openssl-cl.gypi
@@ -14,6 +14,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux32-s390x/asm/openssl.gypi b/deps/openssl/config/archs/linux32-s390x/asm/openssl.gypi
index 21816e45dad68b..5815f28914db57 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm/openssl.gypi
+++ b/deps/openssl/config/archs/linux32-s390x/asm/openssl.gypi
@@ -986,6 +986,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm
index e2a285be53885d..e3ec7d01486663 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux32-s390x/asm_avx2/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux32-s390x",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1601,6 +1601,7 @@ our %unified_info = (
             "OPENSSL_BN_ASM_MONT",
             "OPENSSL_CPUID_OBJ",
             "POLY1305_ASM",
+            "RC4_ASM",
             "S390X_EC_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1640,6 +1641,9 @@ our %unified_info = (
             "SHA256_ASM",
             "SHA512_ASM"
         ],
+        "providers/liblegacy.a" => [
+            "RC4_ASM"
+        ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
         ],
diff --git a/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h
index 5c8bda117c2ed5..e689eb7c7734ff 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux32-s390x/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux32-s390x"
-#define DATE "built on: Fri Jun  9 12:09:25 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:36:40 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux32-s390x/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux32-s390x/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux32-s390x/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl-cl.gypi
index 37d3f6b82bf84e..ea32a6d1e63987 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl-cl.gypi
@@ -14,6 +14,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl.gypi b/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl.gypi
index a036ce3acab1ae..9cebf7a2e7764c 100644
--- a/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/linux32-s390x/asm_avx2/openssl.gypi
@@ -986,6 +986,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm b/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm
index 278f09a8eb2d28..a71b8dcf839746 100644
--- a/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux32-s390x/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux32-s390x",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h
index e96f91eeb354f0..7c01ad4e90df3b 100644
--- a/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux32-s390x/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux32-s390x"
-#define DATE "built on: Fri Jun  9 12:09:46 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:37:03 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux32-s390x/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux32-s390x/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux32-s390x/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux32-s390x/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-loongarch64/no-asm/configdata.pm b/deps/openssl/config/archs/linux64-loongarch64/no-asm/configdata.pm
index 0cce7c2cd8bc69..9576c99c906303 100644
--- a/deps/openssl/config/archs/linux64-loongarch64/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux64-loongarch64/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-loongarch64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux64-loongarch64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-loongarch64/no-asm/crypto/buildinf.h
index 2a82a356209006..4e95343a9fb4cd 100644
--- a/deps/openssl/config/archs/linux64-loongarch64/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-loongarch64/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-loongarch64"
-#define DATE "built on: Fri Jun  9 12:16:55 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:45:10 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-loongarch64/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-loongarch64/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-loongarch64/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-loongarch64/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm b/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm
index 15b1926241b516..dbfc0d2736f05a 100644
--- a/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux64-mips64/asm/configdata.pm
@@ -162,7 +162,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -210,7 +210,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -262,11 +262,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-mips64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h
index 2d223c9b46e7d0..6b70def08e855a 100644
--- a/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-mips64/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-mips64"
-#define DATE "built on: Fri Jun  9 12:11:06 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:38:36 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-mips64/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-mips64/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-mips64/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-mips64/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm
index 7c704ad5c61386..3b8e66e40539e8 100644
--- a/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux64-mips64/asm_avx2/configdata.pm
@@ -162,7 +162,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -210,7 +210,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -262,11 +262,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-mips64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h
index 1143c2dce57b12..594e838897cbbb 100644
--- a/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-mips64/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-mips64"
-#define DATE "built on: Fri Jun  9 12:11:25 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:38:59 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-mips64/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-mips64/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-mips64/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-mips64/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm b/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm
index 7b25eb874e412e..01bb1010d678bf 100644
--- a/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux64-mips64/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-mips64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h
index 4303c5e7f82648..1c1ffc1c348702 100644
--- a/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-mips64/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-mips64"
-#define DATE "built on: Fri Jun  9 12:11:45 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:39:21 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-mips64/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-mips64/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-mips64/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-mips64/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-riscv64/no-asm/configdata.pm b/deps/openssl/config/archs/linux64-riscv64/no-asm/configdata.pm
index 76fc8399a00801..2618989ca8c17c 100644
--- a/deps/openssl/config/archs/linux64-riscv64/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux64-riscv64/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-riscv64",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux64-riscv64/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-riscv64/no-asm/crypto/buildinf.h
index 5a857cbdc61f87..f8ee87111d60b3 100644
--- a/deps/openssl/config/archs/linux64-riscv64/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-riscv64/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-riscv64"
-#define DATE "built on: Fri Jun  9 12:16:36 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:44:48 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-riscv64/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-riscv64/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-riscv64/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-riscv64/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm b/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm
index bd313bf90b2e1a..31e57b928cac04 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm
+++ b/deps/openssl/config/archs/linux64-s390x/asm/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-s390x",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1602,6 +1602,7 @@ our %unified_info = (
             "OPENSSL_BN_ASM_MONT",
             "OPENSSL_CPUID_OBJ",
             "POLY1305_ASM",
+            "RC4_ASM",
             "S390X_EC_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1641,6 +1642,9 @@ our %unified_info = (
             "SHA256_ASM",
             "SHA512_ASM"
         ],
+        "providers/liblegacy.a" => [
+            "RC4_ASM"
+        ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
         ],
diff --git a/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h
index 53de14744e5bbc..b10344ae3019e1 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-s390x/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-s390x"
-#define DATE "built on: Fri Jun  9 12:10:05 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:37:26 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-s390x/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-s390x/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-s390x/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-s390x/asm/openssl-cl.gypi b/deps/openssl/config/archs/linux64-s390x/asm/openssl-cl.gypi
index 944f5b6c795ad1..37cfcb1c40ef2c 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux64-s390x/asm/openssl-cl.gypi
@@ -14,6 +14,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux64-s390x/asm/openssl.gypi b/deps/openssl/config/archs/linux64-s390x/asm/openssl.gypi
index 5598e6a54b4a35..0e033968bf85be 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm/openssl.gypi
+++ b/deps/openssl/config/archs/linux64-s390x/asm/openssl.gypi
@@ -985,6 +985,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm b/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm
index 529ed98264331d..f7a270be6046c4 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/linux64-s390x/asm_avx2/configdata.pm
@@ -159,7 +159,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -207,7 +207,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-s390x",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1602,6 +1602,7 @@ our %unified_info = (
             "OPENSSL_BN_ASM_MONT",
             "OPENSSL_CPUID_OBJ",
             "POLY1305_ASM",
+            "RC4_ASM",
             "S390X_EC_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1641,6 +1642,9 @@ our %unified_info = (
             "SHA256_ASM",
             "SHA512_ASM"
         ],
+        "providers/liblegacy.a" => [
+            "RC4_ASM"
+        ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
         ],
diff --git a/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h
index 8708546f4b92ea..c602e1eed19db4 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-s390x/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-s390x"
-#define DATE "built on: Fri Jun  9 12:10:26 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:37:50 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-s390x/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-s390x/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-s390x/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl-cl.gypi
index 670ed2d6eb3b08..0ef49ef3c4e5be 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl-cl.gypi
@@ -14,6 +14,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl.gypi b/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl.gypi
index 4c8db95c0c4788..d3994ecfaeb3e9 100644
--- a/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/linux64-s390x/asm_avx2/openssl.gypi
@@ -985,6 +985,7 @@
       'OPENSSL_BN_ASM_MONT',
       'OPENSSL_CPUID_OBJ',
       'POLY1305_ASM',
+      'RC4_ASM',
       'S390X_EC_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm b/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm
index 6973e7b5daf869..a44e5d6c7ea1d1 100644
--- a/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/linux64-s390x/no-asm/configdata.pm
@@ -157,7 +157,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -206,7 +206,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -259,11 +259,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned char",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "linux64-s390x",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h
index 8e157bc6576140..6d7b9134d30329 100644
--- a/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/linux64-s390x/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: linux64-s390x"
-#define DATE "built on: Fri Jun  9 12:10:47 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:38:14 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/linux64-s390x/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/linux64-s390x/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/linux64-s390x/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/linux64-s390x/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm b/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm
index f399600323b9e1..d60b22c0286e85 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -204,7 +204,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -256,11 +256,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "solaris-x86-gcc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1597,6 +1597,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1644,7 +1645,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h
index 93ad98d61cce58..6c58b044ea9707 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: solaris-x86-gcc"
-#define DATE "built on: Fri Jun  9 12:12:04 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:39:44 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/solaris-x86-gcc/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl-cl.gypi b/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl-cl.gypi
index 92ea04165d00ac..1c53ac3e17c4ed 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl.gypi b/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl.gypi
index 883e7f68eef574..2037cbe79e9b30 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl.gypi
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm/openssl.gypi
@@ -993,6 +993,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm
index b06229aff138ff..ec632ff0f28c57 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -204,7 +204,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -256,11 +256,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "solaris-x86-gcc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1597,6 +1597,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "RMD160_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
@@ -1644,7 +1645,8 @@ our %unified_info = (
             "VPAES_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h
index f0a50817f4335a..01fe3449426840 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: solaris-x86-gcc"
-#define DATE "built on: Fri Jun  9 12:12:25 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:40:07 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl-cl.gypi
index 2e8a0bb6f09bdf..eb4c8f67d2d882 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl-cl.gypi
@@ -18,6 +18,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl.gypi b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl.gypi
index 62eff30b7c26e6..2f0dea41efd200 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/solaris-x86-gcc/asm_avx2/openssl.gypi
@@ -993,6 +993,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'RMD160_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm
index 03ef078f0f9784..5dc7107bb26bbd 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -203,7 +203,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -256,11 +256,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "solaris-x86-gcc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h
index c3e3d1195709e1..d9d8f29beefec3 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: solaris-x86-gcc"
-#define DATE "built on: Fri Jun  9 12:12:46 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:40:30 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/solaris-x86-gcc/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/solaris-x86-gcc/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm
index 9c98dc83a1170f..199dee44226d9f 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -204,7 +204,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -256,11 +256,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "solaris64-x86_64-gcc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1599,6 +1599,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1650,7 +1651,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h
index 5a27ac2232180c..45e22d76fd5e66 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: solaris64-x86_64-gcc"
-#define DATE "built on: Fri Jun  9 12:13:05 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:40:52 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/include/openssl/opensslv.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl-cl.gypi b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl-cl.gypi
index 73d5bf11bfe78e..aad5fc68f347e0 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl-cl.gypi
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl-cl.gypi
@@ -19,6 +19,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl.gypi b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl.gypi
index 875d3bd1ac265f..24d9ad0e5c0bee 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl.gypi
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm/openssl.gypi
@@ -1007,6 +1007,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm
index df0e95e3192755..df9f4cc099ead6 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/configdata.pm
@@ -156,7 +156,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -204,7 +204,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -256,11 +256,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "solaris64-x86_64-gcc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
@@ -1599,6 +1599,7 @@ our %unified_info = (
             "OPENSSL_IA32_SSE2",
             "PADLOCK_ASM",
             "POLY1305_ASM",
+            "RC4_ASM",
             "SHA1_ASM",
             "SHA256_ASM",
             "SHA512_ASM",
@@ -1650,7 +1651,8 @@ our %unified_info = (
             "X25519_ASM"
         ],
         "providers/liblegacy.a" => [
-            "MD5_ASM"
+            "MD5_ASM",
+            "RC4_ASM"
         ],
         "test/provider_internal_test" => [
             "PROVIDER_INIT_FUNCTION_NAME=p_test_init"
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h
index 6d870e373a7b98..9bff7519bf2417 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: solaris64-x86_64-gcc"
-#define DATE "built on: Fri Jun  9 12:13:30 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:41:20 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/include/openssl/opensslv.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl-cl.gypi b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl-cl.gypi
index b11daee664094f..5e955a3c57c9f6 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl-cl.gypi
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl-cl.gypi
@@ -19,6 +19,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl.gypi b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl.gypi
index 902e4549ddfb52..5bab94f70bb82a 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl.gypi
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/asm_avx2/openssl.gypi
@@ -1007,6 +1007,7 @@
       'OPENSSL_IA32_SSE2',
       'PADLOCK_ASM',
       'POLY1305_ASM',
+      'RC4_ASM',
       'SHA1_ASM',
       'SHA256_ASM',
       'SHA512_ASM',
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm
index 46bbb88086a196..a15e817f8966e5 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/configdata.pm
@@ -154,7 +154,7 @@ our %config = (
     ],
     "dynamic_engines" => "0",
     "ex_libs" => [],
-    "full_version" => "3.0.9+quic",
+    "full_version" => "3.0.10+quic",
     "includes" => [],
     "lflags" => [],
     "lib_defines" => [
@@ -203,7 +203,7 @@ our %config = (
     "openssl_sys_defines" => [],
     "openssldir" => "",
     "options" => "enable-ssl-trace enable-fips no-afalgeng no-asan no-asm no-buildtest-c++ no-comp no-crypto-mdebug no-crypto-mdebug-backtrace no-devcryptoeng no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-external-tests no-fuzz-afl no-fuzz-libfuzzer no-ktls no-loadereng no-md2 no-msan no-rc5 no-sctp no-shared no-ssl3 no-ssl3-method no-trace no-ubsan no-unit-test no-uplink no-weak-ssl-ciphers no-zlib no-zlib-dynamic",
-    "patch" => "9",
+    "patch" => "10",
     "perl_archname" => "x86_64-linux-gnu-thread-multi",
     "perl_cmd" => "/usr/bin/perl",
     "perl_version" => "5.34.0",
@@ -256,11 +256,11 @@ our %config = (
     "prerelease" => "",
     "processor" => "",
     "rc4_int" => "unsigned int",
-    "release_date" => "30 May 2023",
+    "release_date" => "1 Aug 2023",
     "shlib_version" => "81.3",
     "sourcedir" => ".",
     "target" => "solaris64-x86_64-gcc",
-    "version" => "3.0.9"
+    "version" => "3.0.10"
 );
 our %target = (
     "AR" => "ar",
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h
index 525c1b8631c4b4..c9d1cb2473635d 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/crypto/buildinf.h
@@ -11,7 +11,7 @@
  */
 
 #define PLATFORM "platform: solaris64-x86_64-gcc"
-#define DATE "built on: Fri Jun  9 12:13:56 2023 UTC"
+#define DATE "built on: Sun Aug  6 00:41:48 2023 UTC"
 
 /*
  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/include/openssl/opensslv.h b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/include/openssl/opensslv.h
index 1b938a927c7d59..06ba6600ff29ce 100644
--- a/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/include/openssl/opensslv.h
+++ b/deps/openssl/config/archs/solaris64-x86_64-gcc/no-asm/include/openssl/opensslv.h
@@ -29,7 +29,7 @@ extern "C" {
  */
 # define OPENSSL_VERSION_MAJOR  3
 # define OPENSSL_VERSION_MINOR  0
-# define OPENSSL_VERSION_PATCH  9
+# define OPENSSL_VERSION_PATCH  10
 
 /*
  * Additional version information
@@ -74,21 +74,21 @@ extern "C" {
  * longer variant with OPENSSL_VERSION_PRE_RELEASE_STR and
  * OPENSSL_VERSION_BUILD_METADATA_STR appended.
  */
-# define OPENSSL_VERSION_STR "3.0.9"
-# define OPENSSL_FULL_VERSION_STR "3.0.9+quic"
+# define OPENSSL_VERSION_STR "3.0.10"
+# define OPENSSL_FULL_VERSION_STR "3.0.10+quic"
 
 /*
  * SECTION 3: ADDITIONAL METADATA
  *
  * These strings are defined separately to allow them to be parsable.
  */
-# define OPENSSL_RELEASE_DATE "30 May 2023"
+# define OPENSSL_RELEASE_DATE "1 Aug 2023"
 
 /*
  * SECTION 4: BACKWARD COMPATIBILITY
  */
 
-# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.9+quic 30 May 2023"
+# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.10+quic 1 Aug 2023"
 
 /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */
 # ifdef OPENSSL_VERSION_PRE_RELEASE
diff --git a/deps/openssl/openssl/CHANGES.md b/deps/openssl/openssl/CHANGES.md
index 289e44cee499b7..374fdc662cb94c 100644
--- a/deps/openssl/openssl/CHANGES.md
+++ b/deps/openssl/openssl/CHANGES.md
@@ -28,9 +28,70 @@ breaking changes, and mappings for the large list of deprecated functions.
 
 [Migration guide]: https://github.com/openssl/openssl/tree/master/doc/man7/migration_guide.pod
 
-### Changes between 3.0.9 and 3.0.9+quic [30 May 2023]
- * Add QUIC API support from BoringSSL
+### Changes between 3.0.10 and 3.0.10+quic [1 Aug 2023]
+
+* Add QUIC API support from BoringSSL
+
    *Todd Short*
+
+### Changes between 3.0.9 and 3.0.10 [1 Aug 2023]
+
+ * Fix excessive time spent checking DH q parameter value.
+
+   The function DH_check() performs various checks on DH parameters. After
+   fixing CVE-2023-3446 it was discovered that a large q parameter value can
+   also trigger an overly long computation during some of these checks.
+   A correct q value, if present, cannot be larger than the modulus p
+   parameter, thus it is unnecessary to perform these checks if q is larger
+   than p.
+
+   If DH_check() is called with such q parameter value,
+   DH_CHECK_INVALID_Q_VALUE return flag is set and the computationally
+   intensive checks are skipped.
+
+   ([CVE-2023-3817])
+
+   *Tomáš Mráz*
+
+ * Fix DH_check() excessive time with over sized modulus.
+
+   The function DH_check() performs various checks on DH parameters. One of
+   those checks confirms that the modulus ("p" parameter) is not too large.
+   Trying to use a very large modulus is slow and OpenSSL will not normally use
+   a modulus which is over 10,000 bits in length.
+
+   However the DH_check() function checks numerous aspects of the key or
+   parameters that have been supplied. Some of those checks use the supplied
+   modulus value even if it has already been found to be too large.
+
+   A new limit has been added to DH_check of 32,768 bits. Supplying a
+   key/parameters with a modulus over this size will simply cause DH_check() to
+   fail.
+
+   ([CVE-2023-3446])
+
+   *Matt Caswell*
+
+ * Do not ignore empty associated data entries with AES-SIV.
+
+   The AES-SIV algorithm allows for authentication of multiple associated
+   data entries along with the encryption. To authenticate empty data the
+   application has to call `EVP_EncryptUpdate()` (or `EVP_CipherUpdate()`)
+   with NULL pointer as the output buffer and 0 as the input buffer length.
+   The AES-SIV implementation in OpenSSL just returns success for such call
+   instead of performing the associated data authentication operation.
+   The empty data thus will not be authenticated. ([CVE-2023-2975])
+
+   Thanks to Juerg Wullschleger (Google) for discovering the issue.
+
+   The fix changes the authentication tag value and the ciphertext for
+   applications that use empty associated data entries with AES-SIV.
+   To decrypt data encrypted with previous versions of OpenSSL the application
+   has to skip calls to `EVP_DecryptUpdate()` for empty associated data
+   entries.
+
+   *Tomáš Mráz*
+
 ### Changes between 3.0.8 and 3.0.9 [30 May 2023]
 
  * Mitigate for the time it takes for `OBJ_obj2txt` to translate gigantic
@@ -45,7 +106,7 @@ breaking changes, and mappings for the large list of deprecated functions.
    IDENTIFIER to canonical numeric text form if the size of that OBJECT
    IDENTIFIER is 586 bytes or less, and fail otherwise.
 
-   The basis for this restriction is RFC 2578 (STD 58), section 3.5. OBJECT
+   The basis for this restriction is [RFC 2578 (STD 58), section 3.5]. OBJECT
    IDENTIFIER values, which stipulates that OBJECT IDENTIFIERS may have at
    most 128 sub-identifiers, and that the maximum value that each sub-
    identifier may have is 2^32-1 (4294967295 decimal).
@@ -55,8 +116,6 @@ breaking changes, and mappings for the large list of deprecated functions.
    these restrictions may occupy is 32 * 128 / 7, which is approximately 586
    bytes.
 
-   Ref: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
-
    *Richard Levitte*
 
  * Fixed buffer overread in AES-XTS decryption on ARM 64 bit platforms which
@@ -19655,6 +19714,10 @@ ndif
 
 
 
+[CVE-2023-3817]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3817
+[CVE-2023-3446]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3446
+[CVE-2023-2975]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2975
+[RFC 2578 (STD 58), section 3.5]: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5
 [CVE-2023-2650]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2650
 [CVE-2023-1255]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-1255
 [CVE-2023-0466]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0466
diff --git a/deps/openssl/openssl/Configure b/deps/openssl/openssl/Configure
index 8c0e683688db6e..63440170287d5a 100755
--- a/deps/openssl/openssl/Configure
+++ b/deps/openssl/openssl/Configure
@@ -599,8 +599,7 @@ my @disable_cascades = (
 
     "crypto-mdebug"     => [ "crypto-mdebug-backtrace" ],
 
-    # If no modules, then no dynamic engines either
-    "module"            => [ "dynamic-engine" ],
+    "module"            => [ "dynamic-engine", "fips" ],
 
     # Without shared libraries, dynamic engines aren't possible.
     # This is due to them having to link with libcrypto and register features
@@ -618,8 +617,6 @@ my @disable_cascades = (
     # or modules.
     "pic"               => [ "shared", "module" ],
 
-    "module"            => [ "fips", "dso" ],
-
     "engine"            => [ "dynamic-engine", grep(/eng$/, @disablables) ],
     "dynamic-engine"    => [ "loadereng" ],
     "hw"                => [ "padlockeng" ],
diff --git a/deps/openssl/openssl/INSTALL.md b/deps/openssl/openssl/INSTALL.md
index 59d7d869e982d0..fbcebe17e62c9a 100644
--- a/deps/openssl/openssl/INSTALL.md
+++ b/deps/openssl/openssl/INSTALL.md
@@ -796,14 +796,22 @@ By default OpenSSL will attempt to stay in memory until the process exits.
 This is so that libcrypto and libssl can be properly cleaned up automatically
 via an `atexit()` handler.  The handler is registered by libcrypto and cleans
 up both libraries.  On some platforms the `atexit()` handler will run on unload of
-libcrypto (if it has been dynamically loaded) rather than at process exit.  This
-option can be used to stop OpenSSL from attempting to stay in memory until the
+libcrypto (if it has been dynamically loaded) rather than at process exit.
+
+This option can be used to stop OpenSSL from attempting to stay in memory until the
 process exits.  This could lead to crashes if either libcrypto or libssl have
 already been unloaded at the point that the atexit handler is invoked, e.g.  on a
 platform which calls `atexit()` on unload of the library, and libssl is unloaded
-before libcrypto then a crash is likely to happen.  Applications can suppress
-running of the `atexit()` handler at run time by using the
-`OPENSSL_INIT_NO_ATEXIT` option to `OPENSSL_init_crypto()`.
+before libcrypto then a crash is likely to happen.
+
+Note that shared library pinning is not automatically disabled for static builds,
+i.e., `no-shared` does not imply `no-pinshared`. This may come as a surprise when
+linking libcrypto statically into a shared third-party library, because in this
+case the shared library will be pinned. To prevent this behaviour, you need to
+configure the static build using `no-shared` and `no-pinshared` together.
+
+Applications can suppress running of the `atexit()` handler at run time by
+using the `OPENSSL_INIT_NO_ATEXIT` option to `OPENSSL_init_crypto()`.
 See the man page for it for further details.
 
 ### no-posix-io
diff --git a/deps/openssl/openssl/NEWS.md b/deps/openssl/openssl/NEWS.md
index 10fbf5c9481c04..feed9026976013 100644
--- a/deps/openssl/openssl/NEWS.md
+++ b/deps/openssl/openssl/NEWS.md
@@ -18,6 +18,12 @@ OpenSSL Releases
 OpenSSL 3.0
 -----------
 
+### Major changes between OpenSSL 3.0.9 and OpenSSL 3.0.10 [1 Aug 2023]
+
+  * Fix excessive time spent checking DH q parameter value ([CVE-2023-3817])
+  * Fix DH_check() excessive time with over sized modulus ([CVE-2023-3446])
+  * Do not ignore empty associated data entries with AES-SIV ([CVE-2023-2975])
+
 ### Major changes between OpenSSL 3.0.8 and OpenSSL 3.0.9 [30 May 2023]
 
   * Mitigate for very slow `OBJ_obj2txt()` performance with gigantic OBJECT
@@ -1442,6 +1448,9 @@ OpenSSL 0.9.x
 
 
 
+[CVE-2023-3817]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3817
+[CVE-2023-3446]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-3446
+[CVE-2023-2975]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2975
 [CVE-2023-2650]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-2650
 [CVE-2023-1255]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-1255
 [CVE-2023-0466]: https://www.openssl.org/news/vulnerabilities.html#CVE-2023-0466
diff --git a/deps/openssl/openssl/README-FIPS.md b/deps/openssl/openssl/README-FIPS.md
index ba88ff2c4e98fe..c79552b2d8ad66 100644
--- a/deps/openssl/openssl/README-FIPS.md
+++ b/deps/openssl/openssl/README-FIPS.md
@@ -2,7 +2,7 @@ OpenSSL FIPS support
 ====================
 
 This release of OpenSSL includes a cryptographic module that can be
-FIPS 140-2 validated. The module is implemented as an OpenSSL provider.
+FIPS validated. The module is implemented as an OpenSSL provider.
 A provider is essentially a dynamically loadable module which implements
 cryptographic algorithms, see the [README-PROVIDERS](README-PROVIDERS.md) file
 for further details.
@@ -28,8 +28,16 @@ resp. `fips.dll` (on Windows). The FIPS provider does not get built and
 installed automatically. To enable it, you need to configure OpenSSL using
 the `enable-fips` option.
 
-Installing the FIPS module
-==========================
+Installing the FIPS provider
+============================
+
+In order to be FIPS compliant you must only use FIPS validated source code.
+Refer to  for information related to
+which versions are FIPS validated. The instructions given below build OpenSSL
+just using the FIPS validated source code.
+
+If you want to use a validated FIPS provider, but also want to use the latest
+OpenSSL release to build everything else, then refer to the next section.
 
 The following is only a guide.
 Please read the Security Policy for up to date installation instructions.
@@ -63,11 +71,12 @@ the installation by doing the following two things:
 
 - Runs the FIPS module self tests
 - Generates the so-called FIPS module configuration file containing information
-  about the module such as the self test status, and the module checksum.
+  about the module such as the module checksum (and for OpenSSL 3.0 the
+  self test status).
 
 The FIPS module must have the self tests run, and the FIPS module config file
-output generated on every machine that it is to be used on. You must not copy
-the FIPS module config file output data from one machine to another.
+output generated on every machine that it is to be used on. For OpenSSL 3.0,
+you must not copy the FIPS module config file output data from one machine to another.
 
 On Unix the `openssl fipsinstall` command will be invoked as follows by default:
 
@@ -75,7 +84,80 @@ On Unix the `openssl fipsinstall` command will be invoked as follows by default:
 
 If you configured OpenSSL to be installed to a different location, the paths will
 vary accordingly. In the rare case that you need to install the fipsmodule.cnf
-to non-standard location, you can execute the `openssl fipsinstall` command manually.
+to a non-standard location, you can execute the `openssl fipsinstall` command manually.
+
+Installing the FIPS provider and using it with the latest release
+=================================================================
+
+This normally requires you to download 2 copies of the OpenSSL source code.
+
+Download and build a validated FIPS provider
+--------------------------------------------
+
+Refer to  for information related to
+which versions are FIPS validated. For this example we use OpenSSL 3.0.0.
+
+    $ wget https://www.openssl.org/source/openssl-3.0.0.tar.gz
+    $ tar -xf openssl-3.0.0.tar.gz
+    $ cd openssl-3.0.0
+    $ ./Configure enable-fips
+    $ make
+    $ cd ..
+
+Download and build the latest release of OpenSSL
+------------------------------------------------
+
+We use OpenSSL 3.1.0 here, (but you could also use the latest 3.0.X)
+
+    $ wget https://www.openssl.org/source/openssl-3.1.0.tar.gz
+    $ tar -xf openssl-3.1.0.tar.gz
+    $ cd openssl-3.1.0
+    $ ./Configure enable-fips
+    $ make
+
+Use the OpenSSL FIPS provider for testing
+-----------------------------------------
+
+We do this by replacing the artifact for the OpenSSL 3.1.0 FIPS provider.
+Note that the OpenSSL 3.1.0 FIPS provider has not been validated
+so it must not be used for FIPS purposes.
+
+    $ cp ../openssl-3.0.0/providers/fips.so providers/.
+    $ cp ../openssl-3.0.0/providers/fipsmodule.cnf providers/.
+    // Note that for OpenSSL 3.0 that the `fipsmodule.cnf` file should not
+    // be copied across multiple machines if it contains an entry for
+    // `install-status`. (Otherwise the self tests would be skipped).
+
+    // Validate the output of the following to make sure we are using the
+    // OpenSSL 3.0.0 FIPS provider
+    $ ./util/wrap.pl -fips apps/openssl list -provider-path providers \
+    -provider fips -providers
+
+    // Now run the current tests using the OpenSSL 3.0 FIPS provider.
+    $ make tests
+
+Copy the FIPS provider artifacts (`fips.so` & `fipsmodule.cnf`) to known locations
+-------------------------------------------------------------------------------------
+
+    $ cd ../openssl-3.0.0
+    $ sudo make install_fips
+
+Check that the correct FIPS provider is being used
+--------------------------------------------------
+
+    $./util/wrap.pl -fips apps/openssl list -provider-path providers \
+    -provider fips -providers
+
+    // This should produce the following output
+    Providers:
+      base
+        name: OpenSSL Base Provider
+        version: 3.1.0
+        status: active
+      fips
+        name: OpenSSL FIPS Provider
+        version: 3.0.0
+        status: active
 
 Using the FIPS Module in applications
 =====================================
diff --git a/deps/openssl/openssl/README.md b/deps/openssl/openssl/README.md
index 0a76794507312a..80090a262c0502 100644
--- a/deps/openssl/openssl/README.md
+++ b/deps/openssl/openssl/README.md
@@ -4,7 +4,7 @@ What This Is
 This is a fork of [OpenSSL](https://www.openssl.org) to enable QUIC. In addition
 to the website, the official source distribution is at
 . The OpenSSL `README` can be found at
-[README-OpenSSL.md](https://github.com/quictls/openssl/blob/openssl-3.0.9%2Bquic/README-OpenSSL.md)
+[README-OpenSSL.md](https://github.com/quictls/openssl/blob/openssl-3.0.10%2Bquic/README-OpenSSL.md)
 
 This fork adds APIs that can be used by QUIC implementations for connection
 handshakes. Quoting the IETF Working group
diff --git a/deps/openssl/openssl/VERSION.dat b/deps/openssl/openssl/VERSION.dat
index 124f93e4b03e73..3388a2ac907c8f 100644
--- a/deps/openssl/openssl/VERSION.dat
+++ b/deps/openssl/openssl/VERSION.dat
@@ -1,7 +1,7 @@
 MAJOR=3
 MINOR=0
-PATCH=9
+PATCH=10
 PRE_RELEASE_TAG=
 BUILD_METADATA=quic
-RELEASE_DATE="30 May 2023"
+RELEASE_DATE="1 Aug 2023"
 SHLIB_VERSION=81.3
diff --git a/deps/openssl/openssl/apps/ca.c b/deps/openssl/openssl/apps/ca.c
index e14a5cff78023c..a7a5ab1ecefb4b 100644
--- a/deps/openssl/openssl/apps/ca.c
+++ b/deps/openssl/openssl/apps/ca.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -628,6 +628,8 @@ int ca_main(int argc, char **argv)
 
     f = NCONF_get_string(conf, section, ENV_NAMEOPT);
 
+    if (f == NULL)
+        ERR_clear_error();
     if (f != NULL) {
         if (!set_nameopt(f)) {
             BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
@@ -785,8 +787,10 @@ int ca_main(int argc, char **argv)
         /* We can have sections in the ext file */
         if (extensions == NULL) {
             extensions = NCONF_get_string(extfile_conf, "default", "extensions");
-            if (extensions == NULL)
+            if (extensions == NULL) {
+                ERR_clear_error();
                 extensions = "default";
+            }
         }
     }
 
@@ -802,15 +806,20 @@ int ca_main(int argc, char **argv)
     /*
      * EVP_PKEY_get_default_digest_name() returns 2 if the digest is
      * mandatory for this algorithm.
+     *
+     * That call may give back the name "UNDEF", which has these meanings:
+     *
+     * when def_ret == 2: the user MUST leave the digest unspecified
+     * when def_ret == 1: the user MAY leave the digest unspecified
      */
     if (def_ret == 2 && strcmp(def_dgst, "UNDEF") == 0) {
-        /* The signing algorithm requires there to be no digest */
         dgst = NULL;
     } else if (dgst == NULL
-               && (dgst = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL) {
+               && (dgst = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL
+               && strcmp(def_dgst, "UNDEF") != 0) {
         goto end;
     } else {
-        if (strcmp(dgst, "default") == 0) {
+        if (strcmp(dgst, "default") == 0 || strcmp(def_dgst, "UNDEF") == 0) {
             if (def_ret <= 0) {
                 BIO_puts(bio_err, "no default digest\n");
                 goto end;
@@ -824,6 +833,8 @@ int ca_main(int argc, char **argv)
             char *tmp_email_dn = NULL;
 
             tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN);
+            if (tmp_email_dn == NULL)
+                ERR_clear_error();
             if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
                 email_dn = 0;
         }
@@ -839,6 +850,7 @@ int ca_main(int argc, char **argv)
         if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) {
             rand_ser = 1;
         } else {
+            ERR_clear_error();
             serialfile = lookup_conf(conf, section, ENV_SERIAL);
             if (serialfile == NULL)
                 goto end;
@@ -908,8 +920,10 @@ int ca_main(int argc, char **argv)
         }
 
         if (days == 0) {
-            if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days))
+            if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days)) {
+                ERR_clear_error();
                 days = 0;
+            }
         }
         if (enddate == NULL && days == 0) {
             BIO_printf(bio_err, "cannot lookup how many days to certify for\n");
@@ -1034,7 +1048,7 @@ int ca_main(int argc, char **argv)
             }
         }
         /*
-         * we have a stack of newly certified certificates and a data base
+         * we have a stack of newly certified certificates and a database
          * and serial number that need updating
          */
 
@@ -1135,7 +1149,7 @@ int ca_main(int argc, char **argv)
             if (!rotate_index(dbfile, "new", "old"))
                 goto end;
 
-            BIO_printf(bio_err, "Data Base Updated\n");
+            BIO_printf(bio_err, "Database updated\n");
         }
     }
 
@@ -1161,22 +1175,28 @@ int ca_main(int argc, char **argv)
             }
         }
 
-        if ((crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER))
-            != NULL)
+        crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER);
+        if (crlnumberfile != NULL) {
             if ((crlnumber = load_serial(crlnumberfile, NULL, 0, NULL))
                 == NULL) {
                 BIO_printf(bio_err, "error while loading CRL number\n");
                 goto end;
             }
+        } else {
+            ERR_clear_error();
+        }
 
         if (!crldays && !crlhours && !crlsec) {
             if (!NCONF_get_number(conf, section,
-                                  ENV_DEFAULT_CRL_DAYS, &crldays))
+                                  ENV_DEFAULT_CRL_DAYS, &crldays)) {
+                ERR_clear_error();
                 crldays = 0;
+            }
             if (!NCONF_get_number(conf, section,
-                                  ENV_DEFAULT_CRL_HOURS, &crlhours))
+                                  ENV_DEFAULT_CRL_HOURS, &crlhours)) {
+                ERR_clear_error();
                 crlhours = 0;
-            ERR_clear_error();
+            }
         }
         if ((crl_nextupdate == NULL) &&
                 (crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
@@ -1316,7 +1336,7 @@ int ca_main(int argc, char **argv)
             if (!rotate_index(dbfile, "new", "old"))
                 goto end;
 
-            BIO_printf(bio_err, "Data Base Updated\n");
+            BIO_printf(bio_err, "Database updated\n");
         }
     }
     ret = 0;
@@ -1758,7 +1778,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
 
     if (verbose)
         BIO_printf(bio_err,
-                   "The subject name appears to be ok, checking data base for clashes\n");
+                   "The subject name appears to be ok, checking database for clashes\n");
 
     /* Build the correct Subject if no e-mail is wanted in the subject. */
     if (!email_dn) {
@@ -1847,7 +1867,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
         else if (rrow[DB_type][0] == DB_TYPE_VAL)
             p = "Valid";
         else
-            p = "\ninvalid type, Data base error\n";
+            p = "\ninvalid type, Database error\n";
         BIO_printf(bio_err, "Type          :%s\n", p);;
         if (rrow[DB_type][0] == DB_TYPE_REV) {
             p = rrow[DB_exp_date];
diff --git a/deps/openssl/openssl/apps/cmp.c b/deps/openssl/openssl/apps/cmp.c
index 3463579c24fb74..a317fdb0bf3ed4 100644
--- a/deps/openssl/openssl/apps/cmp.c
+++ b/deps/openssl/openssl/apps/cmp.c
@@ -2115,7 +2115,7 @@ static const char *prev_item(const char *opt, const char *end)
     beg = end;
     while (beg > opt) {
         --beg;
-        if (beg[0] == ',' || isspace(beg[0])) {
+        if (beg[0] == ',' || isspace(_UC(beg[0]))) {
             ++beg;
             break;
         }
@@ -2130,7 +2130,7 @@ static const char *prev_item(const char *opt, const char *end)
     opt_item[len] = '\0';
     while (beg > opt) {
         --beg;
-        if (beg[0] != ',' && !isspace(beg[0])) {
+        if (beg[0] != ',' && !isspace(_UC(beg[0]))) {
             ++beg;
             break;
         }
@@ -2148,6 +2148,7 @@ static char *conf_get_string(const CONF *src_conf, const char *groups,
     while ((end = prev_item(groups, end)) != NULL) {
         if ((res = NCONF_get_string(src_conf, opt_item, name)) != NULL)
             return res;
+        ERR_clear_error();
     }
     return res;
 }
diff --git a/deps/openssl/openssl/apps/cms.c b/deps/openssl/openssl/apps/cms.c
index 76c7896719376f..0d1730c56fbb07 100644
--- a/deps/openssl/openssl/apps/cms.c
+++ b/deps/openssl/openssl/apps/cms.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -796,6 +796,9 @@ int cms_main(int argc, char **argv)
     if ((operation & SMIME_IP) == 0 && contfile != NULL)
         BIO_printf(bio_err,
                    "Warning: -contfile option is ignored for the given operation\n");
+    if (operation != SMIME_ENCRYPT && *argv != NULL)
+        BIO_printf(bio_err,
+                   "Warning: recipient certificate file parameters ignored for operation other than -encrypt\n");
 
     if ((flags & CMS_BINARY) != 0) {
         if (!(operation & SMIME_OP))
@@ -823,19 +826,13 @@ int cms_main(int argc, char **argv)
             goto end;
         }
 
-        if (*argv != NULL) {
-            if (operation == SMIME_ENCRYPT) {
-                for (; *argv != NULL; argv++) {
-                    cert = load_cert(*argv, FORMAT_UNDEF,
-                                     "recipient certificate file");
-                    if (cert == NULL)
-                        goto end;
-                    sk_X509_push(encerts, cert);
-                    cert = NULL;
-                }
-            } else {
-                BIO_printf(bio_err, "Warning: recipient certificate file parameters ignored for operation other than -encrypt\n");
-            }
+        for (; *argv != NULL; argv++) {
+            cert = load_cert(*argv, FORMAT_UNDEF,
+                             "recipient certificate file");
+            if (cert == NULL)
+                goto end;
+            sk_X509_push(encerts, cert);
+            cert = NULL;
         }
     }
 
diff --git a/deps/openssl/openssl/apps/lib/apps.c b/deps/openssl/openssl/apps/lib/apps.c
index 79afa1deab9922..4baeb352fedfb3 100644
--- a/deps/openssl/openssl/apps/lib/apps.c
+++ b/deps/openssl/openssl/apps/lib/apps.c
@@ -638,13 +638,13 @@ void *app_malloc(size_t sz, const char *what)
 char *next_item(char *opt) /* in list separated by comma and/or space */
 {
     /* advance to separator (comma or whitespace), if any */
-    while (*opt != ',' && !isspace(*opt) && *opt != '\0')
+    while (*opt != ',' && !isspace(_UC(*opt)) && *opt != '\0')
         opt++;
     if (*opt != '\0') {
         /* terminate current item */
         *opt++ = '\0';
         /* skip over any whitespace after separator */
-        while (isspace(*opt))
+        while (isspace(_UC(*opt)))
             opt++;
     }
     return *opt == '\0' ? NULL : opt; /* NULL indicates end of input */
@@ -1679,7 +1679,10 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
         char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
         if (p) {
             retdb->attributes.unique_subject = parse_yesno(p, 1);
+        } else {
+            ERR_clear_error();
         }
+
     }
 
     retdb->dbfname = OPENSSL_strdup(dbfile);
@@ -2008,7 +2011,8 @@ int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
             BIO_free(mem);
             return -1;
         }
-        maxlen -= len;
+        if (maxlen != -1)
+            maxlen -= len;
 
         if (maxlen == 0)
             break;
diff --git a/deps/openssl/openssl/apps/pkeyutl.c b/deps/openssl/openssl/apps/pkeyutl.c
index 518a74166153fd..3c9f9025a1609d 100644
--- a/deps/openssl/openssl/apps/pkeyutl.c
+++ b/deps/openssl/openssl/apps/pkeyutl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -421,7 +421,7 @@ int pkeyutl_main(int argc, char **argv)
     /* Raw input data is handled elsewhere */
     if (in != NULL && !rawin) {
         /* Read the input data */
-        buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
+        buf_inlen = bio_to_mem(&buf_in, -1, in);
         if (buf_inlen < 0) {
             BIO_printf(bio_err, "Error reading input Data\n");
             goto end;
diff --git a/deps/openssl/openssl/apps/req.c b/deps/openssl/openssl/apps/req.c
index 23757044ab7f46..73b320a7098cf0 100644
--- a/deps/openssl/openssl/apps/req.c
+++ b/deps/openssl/openssl/apps/req.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -199,7 +199,7 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
 
     /* Check syntax. */
     /* Skip leading whitespace, make a copy. */
-    while (*kv && isspace(*kv))
+    while (*kv && isspace(_UC(*kv)))
         if (*++kv == '\0')
             return 1;
     if ((p = strchr(kv, '=')) == NULL)
@@ -210,7 +210,7 @@ static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
 
     /* Skip trailing space before the equal sign. */
     for (p = kv + off; p > kv; --p)
-        if (!isspace(p[-1]))
+        if (!isspace(_UC(p[-1])))
             break;
     if (p == kv) {
         OPENSSL_free(kv);
@@ -635,8 +635,10 @@ int req_main(int argc, char **argv)
     if (newreq && pkey == NULL) {
         app_RAND_load_conf(req_conf, section);
 
-        if (!NCONF_get_number(req_conf, section, BITS, &newkey_len))
+        if (!NCONF_get_number(req_conf, section, BITS, &newkey_len)) {
+            ERR_clear_error();
             newkey_len = DEFAULT_KEY_LENGTH;
+        }
 
         genctx = set_keygen_ctx(keyalg, &keyalgstr, &newkey_len, gen_eng);
         if (genctx == NULL)
diff --git a/deps/openssl/openssl/apps/s_client.c b/deps/openssl/openssl/apps/s_client.c
index a9142386428de0..efa2879ca0e703 100644
--- a/deps/openssl/openssl/apps/s_client.c
+++ b/deps/openssl/openssl/apps/s_client.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright 2005 Nokia. All rights reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -2271,7 +2271,7 @@ int s_client_main(int argc, char **argv)
             do {
                 mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
             }
-            while (mbuf_len > 3 && (!isdigit(mbuf[0]) || !isdigit(mbuf[1]) || !isdigit(mbuf[2]) || mbuf[3] != ' '));
+            while (mbuf_len > 3 && (!isdigit((unsigned char)mbuf[0]) || !isdigit((unsigned char)mbuf[1]) || !isdigit((unsigned char)mbuf[2]) || mbuf[3] != ' '));
             (void)BIO_flush(fbio);
             BIO_pop(fbio);
             BIO_free(fbio);
diff --git a/deps/openssl/openssl/apps/speed.c b/deps/openssl/openssl/apps/speed.c
index addf7e32137f56..f30435704d19ce 100644
--- a/deps/openssl/openssl/apps/speed.c
+++ b/deps/openssl/openssl/apps/speed.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -1005,6 +1005,13 @@ static int EdDSA_sign_loop(void *args)
     int ret, count;
 
     for (count = 0; COND(eddsa_c[testnum][0]); count++) {
+        ret = EVP_DigestSignInit(edctx[testnum], NULL, NULL, NULL, NULL);
+        if (ret == 0) {
+            BIO_printf(bio_err, "EdDSA sign init failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
         ret = EVP_DigestSign(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
         if (ret == 0) {
             BIO_printf(bio_err, "EdDSA sign failure\n");
@@ -1026,6 +1033,13 @@ static int EdDSA_verify_loop(void *args)
     int ret, count;
 
     for (count = 0; COND(eddsa_c[testnum][1]); count++) {
+        ret = EVP_DigestVerifyInit(edctx[testnum], NULL, NULL, NULL, NULL);
+        if (ret == 0) {
+            BIO_printf(bio_err, "EdDSA verify init failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
         ret = EVP_DigestVerify(edctx[testnum], eddsasig, eddsasigsize, buf, 20);
         if (ret != 1) {
             BIO_printf(bio_err, "EdDSA verify failure\n");
@@ -3133,12 +3147,22 @@ int speed_main(int argc, char **argv)
     }
 
     for (k = 0; k < ALGOR_NUM; k++) {
+        const char *alg_name = names[k];
+
         if (!doit[k])
             continue;
+
+        if (k == D_EVP) {
+            if (evp_cipher == NULL)
+                alg_name = evp_md_name;
+            else if ((alg_name = EVP_CIPHER_get0_name(evp_cipher)) == NULL)
+                app_bail_out("failed to get name of cipher '%s'\n", evp_cipher);
+        }
+
         if (mr)
-            printf("+F:%u:%s", k, names[k]);
+            printf("+F:%u:%s", k, alg_name);
         else
-            printf("%-13s", names[k]);
+            printf("%-13s", alg_name);
         for (testnum = 0; testnum < size_num; testnum++) {
             if (results[k][testnum] > 10000 && !mr)
                 printf(" %11.2fk", results[k][testnum] / 1e3);
diff --git a/deps/openssl/openssl/crypto/LPdir_unix.c b/deps/openssl/openssl/crypto/LPdir_unix.c
index bc0e924e46a741..b6dda7bce2eca4 100644
--- a/deps/openssl/openssl/crypto/LPdir_unix.c
+++ b/deps/openssl/openssl/crypto/LPdir_unix.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -137,7 +137,7 @@ const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
     if ((*ctx)->expect_file_generations) {
         char *p = (*ctx)->entry_name + strlen((*ctx)->entry_name);
 
-        while(p > (*ctx)->entry_name && isdigit(p[-1]))
+        while (p > (*ctx)->entry_name && isdigit((unsigned char)p[-1]))
             p--;
         if (p > (*ctx)->entry_name && p[-1] == ';')
             p[-1] = '\0';
diff --git a/deps/openssl/openssl/crypto/asn1/asn_mime.c b/deps/openssl/openssl/crypto/asn1/asn_mime.c
index b44b0f36858bd6..9fc52d0476264a 100644
--- a/deps/openssl/openssl/crypto/asn1/asn_mime.c
+++ b/deps/openssl/openssl/crypto/asn1/asn_mime.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2008-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -516,6 +516,12 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
     int len;
     char linebuf[MAX_SMLEN];
     int ret;
+
+    if (in == NULL || out == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
     /*
      * Buffer output so we don't write one line at a time. This is useful
      * when streaming as we don't end up with one OCTET STRING per line.
diff --git a/deps/openssl/openssl/crypto/bn/bn_recp.c b/deps/openssl/openssl/crypto/bn/bn_recp.c
index 96a6b19ab0da2a..3a2c812ac66638 100644
--- a/deps/openssl/openssl/crypto/bn/bn_recp.c
+++ b/deps/openssl/openssl/crypto/bn/bn_recp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -44,7 +44,7 @@ void BN_RECP_CTX_free(BN_RECP_CTX *recp)
 
 int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
 {
-    if (!BN_copy(&(recp->N), d))
+    if (BN_is_zero(d) || !BN_copy(&(recp->N), d))
         return 0;
     BN_zero(&(recp->Nr));
     recp->num_bits = BN_num_bits(d);
diff --git a/deps/openssl/openssl/crypto/cms/cms_env.c b/deps/openssl/openssl/crypto/cms/cms_env.c
index 3105d37726a599..bd1f3e7345d400 100644
--- a/deps/openssl/openssl/crypto/cms/cms_env.c
+++ b/deps/openssl/openssl/crypto/cms/cms_env.c
@@ -142,10 +142,12 @@ CMS_EncryptedContentInfo *ossl_cms_get0_env_enc_content(const CMS_ContentInfo *c
 {
     switch (cms_get_enveloped_type(cms)) {
     case CMS_ENVELOPED_STANDARD:
-        return cms->d.envelopedData->encryptedContentInfo;
+        return cms->d.envelopedData == NULL ? NULL
+            : cms->d.envelopedData->encryptedContentInfo;
 
     case CMS_ENVELOPED_AUTH:
-        return cms->d.authEnvelopedData->authEncryptedContentInfo;
+        return cms->d.authEnvelopedData == NULL ? NULL
+            : cms->d.authEnvelopedData->authEncryptedContentInfo;
 
     default:
         return NULL;
diff --git a/deps/openssl/openssl/crypto/cms/cms_lib.c b/deps/openssl/openssl/crypto/cms/cms_lib.c
index 0738da3da280e9..1d2c5bc42288a0 100644
--- a/deps/openssl/openssl/crypto/cms/cms_lib.c
+++ b/deps/openssl/openssl/crypto/cms/cms_lib.c
@@ -76,6 +76,10 @@ CMS_ContentInfo *CMS_ContentInfo_new(void)
 void CMS_ContentInfo_free(CMS_ContentInfo *cms)
 {
     if (cms != NULL) {
+        CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cms);
+
+        if (ec != NULL)
+            OPENSSL_clear_free(ec->key, ec->keylen);
         OPENSSL_free(cms->ctx.propq);
         ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo));
     }
diff --git a/deps/openssl/openssl/crypto/cms/cms_rsa.c b/deps/openssl/openssl/crypto/cms/cms_rsa.c
index 997567fdbfac0d..61fd43fb54d051 100644
--- a/deps/openssl/openssl/crypto/cms/cms_rsa.c
+++ b/deps/openssl/openssl/crypto/cms/cms_rsa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -13,6 +13,7 @@
 #include 
 #include "crypto/asn1.h"
 #include "crypto/rsa.h"
+#include "crypto/evp.h"
 #include "cms_local.h"
 
 static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg)
@@ -210,6 +211,16 @@ static int rsa_cms_sign(CMS_SignerInfo *si)
     if (pad_mode != RSA_PKCS1_PSS_PADDING)
         return 0;
 
+    if (evp_pkey_ctx_is_legacy(pkctx)) {
+        /* No provider -> we cannot query it for algorithm ID. */
+        ASN1_STRING *os = NULL;
+
+        os = ossl_rsa_ctx_to_pss_string(pkctx);
+        if (os == NULL)
+            return 0;
+        return X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os);
+    }
+
     params[0] = OSSL_PARAM_construct_octet_string(
         OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid));
     params[1] = OSSL_PARAM_construct_end();
diff --git a/deps/openssl/openssl/crypto/conf/conf_mod.c b/deps/openssl/openssl/crypto/conf/conf_mod.c
index 17bbbf7a27475a..1ea32648e9f9f9 100644
--- a/deps/openssl/openssl/crypto/conf/conf_mod.c
+++ b/deps/openssl/openssl/crypto/conf/conf_mod.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -184,15 +184,21 @@ int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename,
     CONF *conf = NULL;
     int ret = 0, diagnostics = 0;
 
+    ERR_set_mark();
+
     if (filename == NULL) {
         file = CONF_get1_default_config_file();
         if (file == NULL)
             goto err;
+        if (*file == '\0') {
+            /* Do not try to load an empty file name but do not error out */
+            ret = 1;
+            goto err;
+        }
     } else {
         file = (char *)filename;
     }
 
-    ERR_set_mark();
     conf = NCONF_new_ex(libctx, NULL);
     if (conf == NULL)
         goto err;
diff --git a/deps/openssl/openssl/crypto/conf/conf_sap.c b/deps/openssl/openssl/crypto/conf/conf_sap.c
index 39efcdbf90fa3a..513f8bfc1fb94c 100644
--- a/deps/openssl/openssl/crypto/conf/conf_sap.c
+++ b/deps/openssl/openssl/crypto/conf/conf_sap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -66,6 +66,8 @@ int ossl_config_int(const OPENSSL_INIT_SETTINGS *settings)
 
 #ifndef OPENSSL_SYS_UEFI
     ret = CONF_modules_load_file(filename, appname, flags);
+#else
+    ret = 1;
 #endif
     openssl_configured = 1;
     return ret;
diff --git a/deps/openssl/openssl/crypto/core_namemap.c b/deps/openssl/openssl/crypto/core_namemap.c
index 7e11ab1c8845d9..ebf7ed5eb165a8 100644
--- a/deps/openssl/openssl/crypto/core_namemap.c
+++ b/deps/openssl/openssl/crypto/core_namemap.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -142,6 +142,9 @@ int ossl_namemap_doall_names(const OSSL_NAMEMAP *namemap, int number,
     cbdata.number = number;
     cbdata.found = 0;
 
+    if (namemap == NULL)
+        return 0;
+
     /*
      * We collect all the names first under a read lock. Subsequently we call
      * the user function, so that we're not holding the read lock when in user
diff --git a/deps/openssl/openssl/crypto/dh/dh_check.c b/deps/openssl/openssl/crypto/dh/dh_check.c
index 0b391910d6b37c..f4173e21371e01 100644
--- a/deps/openssl/openssl/crypto/dh/dh_check.c
+++ b/deps/openssl/openssl/crypto/dh/dh_check.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -143,7 +143,7 @@ int DH_check(const DH *dh, int *ret)
 #ifdef FIPS_MODULE
     return DH_check_params(dh, ret);
 #else
-    int ok = 0, r;
+    int ok = 0, r, q_good = 0;
     BN_CTX *ctx = NULL;
     BIGNUM *t1 = NULL, *t2 = NULL;
     int nid = DH_get_nid((DH *)dh);
@@ -152,6 +152,13 @@ int DH_check(const DH *dh, int *ret)
     if (nid != NID_undef)
         return 1;
 
+    /* Don't do any checks at all with an excessively large modulus */
+    if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) {
+        ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
+        *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_P_NOT_PRIME;
+        return 0;
+    }
+
     if (!DH_check_params(dh, ret))
         return 0;
 
@@ -165,6 +172,13 @@ int DH_check(const DH *dh, int *ret)
         goto err;
 
     if (dh->params.q != NULL) {
+        if (BN_ucmp(dh->params.p, dh->params.q) > 0)
+            q_good = 1;
+        else
+            *ret |= DH_CHECK_INVALID_Q_VALUE;
+    }
+
+    if (q_good) {
         if (BN_cmp(dh->params.g, BN_value_one()) <= 0)
             *ret |= DH_NOT_SUITABLE_GENERATOR;
         else if (BN_cmp(dh->params.g, dh->params.p) >= 0)
diff --git a/deps/openssl/openssl/crypto/err/openssl.txt b/deps/openssl/openssl/crypto/err/openssl.txt
index 48eb77f56ebb0d..d3ac1b19063272 100644
--- a/deps/openssl/openssl/crypto/err/openssl.txt
+++ b/deps/openssl/openssl/crypto/err/openssl.txt
@@ -1678,6 +1678,7 @@ X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed
 X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table
 X509_R_CRL_ALREADY_DELTA:127:crl already delta
 X509_R_CRL_VERIFY_FAILURE:131:crl verify failure
+X509_R_DUPLICATE_ATTRIBUTE:140:duplicate attribute
 X509_R_ERROR_GETTING_MD_BY_NID:141:error getting md by nid
 X509_R_ERROR_USING_SIGINF_SET:142:error using siginf set
 X509_R_IDP_MISMATCH:128:idp mismatch
diff --git a/deps/openssl/openssl/crypto/evp/ctrl_params_translate.c b/deps/openssl/openssl/crypto/evp/ctrl_params_translate.c
index ccafdfddd58f63..b28875037c7281 100644
--- a/deps/openssl/openssl/crypto/evp/ctrl_params_translate.c
+++ b/deps/openssl/openssl/crypto/evp/ctrl_params_translate.c
@@ -636,8 +636,8 @@ static int default_fixup_args(enum state state,
                                                       ctx->p2, ctx->sz);
                 case OSSL_PARAM_OCTET_STRING:
                     return OSSL_PARAM_get_octet_string(ctx->params,
-                                                       ctx->p2, ctx->sz,
-                                                       &ctx->sz);
+                                                       &ctx->p2, ctx->sz,
+                                                       (size_t *)&ctx->p1);
                 case OSSL_PARAM_OCTET_PTR:
                     return OSSL_PARAM_get_octet_ptr(ctx->params,
                                                     ctx->p2, &ctx->sz);
@@ -685,7 +685,7 @@ static int default_fixup_args(enum state state,
                     return OSSL_PARAM_set_octet_string(ctx->params, ctx->p2,
                                                        size);
                 case OSSL_PARAM_OCTET_PTR:
-                    return OSSL_PARAM_set_octet_ptr(ctx->params, ctx->p2,
+                    return OSSL_PARAM_set_octet_ptr(ctx->params, *(void **)ctx->p2,
                                                     size);
                 default:
                     ERR_raise_data(ERR_LIB_EVP, ERR_R_UNSUPPORTED,
@@ -695,6 +695,9 @@ static int default_fixup_args(enum state state,
                                    translation->param_data_type);
                     return 0;
                 }
+            } else if (state == PRE_PARAMS_TO_CTRL && ctx->action_type == GET) {
+                if (translation->param_data_type == OSSL_PARAM_OCTET_PTR)
+                    ctx->p2 = &ctx->bufp;
             }
         }
         /* Any other combination is simply pass-through */
@@ -2254,7 +2257,7 @@ static const struct translation_st evp_pkey_ctx_translations[] = {
       OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_STRING, NULL },
     { GET, EVP_PKEY_RSA, 0, EVP_PKEY_OP_TYPE_CRYPT,
       EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, NULL, NULL,
-      OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_STRING, NULL },
+      OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_PTR, NULL },
 
     { SET, EVP_PKEY_RSA_PSS, 0, EVP_PKEY_OP_TYPE_GEN,
       EVP_PKEY_CTRL_MD, "rsa_pss_keygen_md", NULL,
diff --git a/deps/openssl/openssl/crypto/evp/p5_crpt2.c b/deps/openssl/openssl/crypto/evp/p5_crpt2.c
index b7455be1cf0ac0..35617390233429 100644
--- a/deps/openssl/openssl/crypto/evp/p5_crpt2.c
+++ b/deps/openssl/openssl/crypto/evp/p5_crpt2.c
@@ -231,13 +231,16 @@ int PKCS5_v2_PBKDF2_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
         goto err;
     }
 
+    (void)ERR_set_mark();
     prfmd = prfmd_fetch = EVP_MD_fetch(libctx, OBJ_nid2sn(hmac_md_nid), propq);
     if (prfmd == NULL)
         prfmd = EVP_get_digestbynid(hmac_md_nid);
     if (prfmd == NULL) {
+        (void)ERR_clear_last_mark();
         ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF);
         goto err;
     }
+    (void)ERR_pop_to_mark();
 
     if (kdf->salt->type != V_ASN1_OCTET_STRING) {
         ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_SALT_TYPE);
diff --git a/deps/openssl/openssl/crypto/evp/p_lib.c b/deps/openssl/openssl/crypto/evp/p_lib.c
index f6acb5b47effcb..aa6ec31dab6e9e 100644
--- a/deps/openssl/openssl/crypto/evp/p_lib.c
+++ b/deps/openssl/openssl/crypto/evp/p_lib.c
@@ -722,6 +722,7 @@ static void detect_foreign_key(EVP_PKEY *pkey)
         break;
 #  ifndef OPENSSL_NO_EC
     case EVP_PKEY_SM2:
+        break;
     case EVP_PKEY_EC:
         pkey->foreign = pkey->pkey.ec != NULL
                         && ossl_ec_key_is_foreign(pkey->pkey.ec);
diff --git a/deps/openssl/openssl/crypto/http/http_lib.c b/deps/openssl/openssl/crypto/http/http_lib.c
index ec24e0dc488e58..e45f60b7228746 100644
--- a/deps/openssl/openssl/crypto/http/http_lib.c
+++ b/deps/openssl/openssl/crypto/http/http_lib.c
@@ -22,6 +22,13 @@ static void init_pstring(char **pstr)
     }
 }
 
+static void init_pint(int *pint)
+{
+    if (pint != NULL) {
+        *pint = 0;
+    }
+}
+
 static int copy_substring(char **dest, const char *start, const char *end)
 {
     return dest == NULL
@@ -54,6 +61,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
     init_pstring(puser);
     init_pstring(phost);
     init_pstring(pport);
+    init_pint(pport_num);
     init_pstring(ppath);
     init_pstring(pfrag);
     init_pstring(pquery);
diff --git a/deps/openssl/openssl/crypto/params.c b/deps/openssl/openssl/crypto/params.c
index 5fd1e0028da917..4d85b5943c71e8 100644
--- a/deps/openssl/openssl/crypto/params.c
+++ b/deps/openssl/openssl/crypto/params.c
@@ -14,6 +14,7 @@
 #include "internal/numbers.h"
 #include "internal/endian.h"
 
+#ifndef OPENSSL_SYS_UEFI
 /*
  * Return the number of bits in the mantissa of a double.  This is used to
  * shift a larger integral value to determine if it will exactly fit into a
@@ -23,6 +24,7 @@ static unsigned int real_shift(void)
 {
     return sizeof(double) == 4 ? 24 : 53;
 }
+#endif
 
 OSSL_PARAM *OSSL_PARAM_locate(OSSL_PARAM *p, const char *key)
 {
@@ -342,8 +344,6 @@ OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf)
 
 int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
 {
-    double d;
-
     if (val == NULL || p == NULL )
         return 0;
 
@@ -391,6 +391,9 @@ int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
         return general_get_int(p, val, sizeof(*val));
 
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
+        double d;
+
         switch (p->data_size) {
         case sizeof(double):
             d = *(const double *)p->data;
@@ -400,6 +403,7 @@ int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
             }
             break;
         }
+#endif
     }
     return 0;
 }
@@ -442,6 +446,7 @@ int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val)
 #endif
         return general_set_int(p, &val, sizeof(val));
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
         p->return_size = sizeof(double);
         if (p->data == NULL)
             return 1;
@@ -450,6 +455,7 @@ int OSSL_PARAM_set_int32(OSSL_PARAM *p, int32_t val)
             *(double *)p->data = (double)val;
             return 1;
         }
+#endif
     }
     return 0;
 }
@@ -462,8 +468,6 @@ OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf)
 
 int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
 {
-    double d;
-
     if (val == NULL || p == NULL)
         return 0;
 
@@ -509,6 +513,9 @@ int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
 #endif
         return general_get_uint(p, val, sizeof(*val));
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
+        double d;
+
         switch (p->data_size) {
         case sizeof(double):
             d = *(const double *)p->data;
@@ -518,6 +525,7 @@ int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
             }
             break;
         }
+#endif
     }
     return 0;
 }
@@ -564,6 +572,7 @@ int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val)
 #endif
         return general_set_uint(p, &val, sizeof(val));
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
         p->return_size = sizeof(double);
         if (p->data == NULL)
             return 1;
@@ -572,6 +581,7 @@ int OSSL_PARAM_set_uint32(OSSL_PARAM *p, uint32_t val)
             *(double *)p->data = (double)val;
             return 1;
         }
+#endif
     }
     return 0;
 }
@@ -584,8 +594,6 @@ OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf)
 
 int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
 {
-    double d;
-
     if (val == NULL || p == NULL )
         return 0;
 
@@ -620,6 +628,9 @@ int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
 #endif
         return general_get_int(p, val, sizeof(*val));
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
+        double d;
+
         switch (p->data_size) {
         case sizeof(double):
             d = *(const double *)p->data;
@@ -636,14 +647,13 @@ int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
             }
             break;
         }
+#endif
     }
     return 0;
 }
 
 int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val)
 {
-    uint64_t u64;
-
     if (p == NULL)
         return 0;
     p->return_size = 0;
@@ -686,6 +696,9 @@ int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val)
 #endif
         return general_set_int(p, &val, sizeof(val));
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
+        uint64_t u64;
+
         p->return_size = sizeof(double);
         if (p->data == NULL)
             return 1;
@@ -698,6 +711,7 @@ int OSSL_PARAM_set_int64(OSSL_PARAM *p, int64_t val)
             }
             break;
         }
+#endif
     }
     return 0;
 }
@@ -709,8 +723,6 @@ OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf)
 
 int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
 {
-    double d;
-
     if (val == NULL || p == NULL)
         return 0;
 
@@ -750,6 +762,9 @@ int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
 #endif
         return general_get_uint(p, val, sizeof(*val));
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
+        double d;
+
         switch (p->data_size) {
         case sizeof(double):
             d = *(const double *)p->data;
@@ -766,6 +781,7 @@ int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
             }
             break;
         }
+#endif
     }
     return 0;
 }
@@ -818,6 +834,7 @@ int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val)
 #endif
         return general_set_uint(p, &val, sizeof(val));
     } else if (p->data_type == OSSL_PARAM_REAL) {
+#ifndef OPENSSL_SYS_UEFI
         p->return_size = sizeof(double);
         switch (p->data_size) {
         case sizeof(double):
@@ -827,6 +844,7 @@ int OSSL_PARAM_set_uint64(OSSL_PARAM *p, uint64_t val)
             }
             break;
         }
+#endif
     }
     return 0;
 }
@@ -953,6 +971,7 @@ OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
                                 buf, bsize);
 }
 
+#ifndef OPENSSL_SYS_UEFI
 int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
 {
     int64_t i64;
@@ -1073,6 +1092,7 @@ OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf)
 {
     return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double));
 }
+#endif
 
 static int get_string_internal(const OSSL_PARAM *p, void **val,
                                size_t *max_len, size_t *used_len,
diff --git a/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c b/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c
index afdb8d688ba336..67a885a45f89e0 100644
--- a/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c
+++ b/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -108,15 +108,20 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
     X509_ALGOR_get0(&macoid, NULL, NULL, macalg);
     if (OBJ_obj2txt(md_name, sizeof(md_name), macoid, 0) < 0)
         return 0;
+
+    (void)ERR_set_mark();
     md = md_fetch = EVP_MD_fetch(p12->authsafes->ctx.libctx, md_name,
                                  p12->authsafes->ctx.propq);
     if (md == NULL)
         md = EVP_get_digestbynid(OBJ_obj2nid(macoid));
 
     if (md == NULL) {
+        (void)ERR_clear_last_mark();
         ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
         return 0;
     }
+    (void)ERR_pop_to_mark();
+
     md_size = EVP_MD_get_size(md);
     md_nid = EVP_MD_get_type(md);
     if (md_size < 0)
diff --git a/deps/openssl/openssl/crypto/rand/rand_lib.c b/deps/openssl/openssl/crypto/rand/rand_lib.c
index 0fcf4fe3bc1ef7..5fde214448f3be 100644
--- a/deps/openssl/openssl/crypto/rand/rand_lib.c
+++ b/deps/openssl/openssl/crypto/rand/rand_lib.c
@@ -120,6 +120,8 @@ void RAND_keep_random_devices_open(int keep)
  */
 int RAND_poll(void)
 {
+    static const char salt[] = "polling";
+
 # ifndef OPENSSL_NO_DEPRECATED_3_0
     const RAND_METHOD *meth = RAND_get_rand_method();
     int ret = meth == RAND_OpenSSL();
@@ -148,14 +150,12 @@ int RAND_poll(void)
         ret = 1;
      err:
         ossl_rand_pool_free(pool);
+        return ret;
     }
-    return ret;
-# else
-    static const char salt[] = "polling";
+# endif
 
     RAND_seed(salt, sizeof(salt));
     return 1;
-# endif
 }
 
 # ifndef OPENSSL_NO_DEPRECATED_3_0
diff --git a/deps/openssl/openssl/crypto/rc4/build.info b/deps/openssl/openssl/crypto/rc4/build.info
index 68b3c73f55b04f..c9c81f87dabf8a 100644
--- a/deps/openssl/openssl/crypto/rc4/build.info
+++ b/deps/openssl/openssl/crypto/rc4/build.info
@@ -21,10 +21,15 @@ SOURCE[../../libcrypto]=$RC4ASM
 
 # When all deprecated symbols are removed, libcrypto doesn't export the
 # rc4 functions, so we must include them directly in liblegacy.a
-IF[{- $disabled{'deprecated-3.0'} && !$disabled{module} && !$disabled{shared} -}]
+IF[{- !$disabled{module} && !$disabled{shared} -}]
   SOURCE[../../providers/liblegacy.a]=$RC4ASM
 ENDIF
 
+# Implementations are now spread across several libraries, so the defines
+# need to be applied to all affected libraries and modules.
+DEFINE[../../libcrypto]=$RC4DEF
+DEFINE[../../providers/liblegacy.a]=$RC4DEF
+
 GENERATE[rc4-586.S]=asm/rc4-586.pl
 DEPEND[rc4-586.S]=../perlasm/x86asm.pl
 
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_ameth.c b/deps/openssl/openssl/crypto/rsa/rsa_ameth.c
index 61ec53d4244ca6..e819780e7d9439 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_ameth.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_ameth.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -641,6 +641,36 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn,
         size_t aid_len = 0;
         OSSL_PARAM params[2];
 
+        if (evp_pkey_ctx_is_legacy(pkctx)) {
+            /* No provider -> we cannot query it for algorithm ID. */
+            ASN1_STRING *os1 = NULL;
+
+            os1 = ossl_rsa_ctx_to_pss_string(pkctx);
+            if (os1 == NULL)
+                return 0;
+            /* Duplicate parameters if we have to */
+            if (alg2 != NULL) {
+                ASN1_STRING *os2 = ASN1_STRING_dup(os1);
+
+                if (os2 == NULL) {
+                    ASN1_STRING_free(os1);
+                    return 0;
+                }
+                if (!X509_ALGOR_set0(alg2, OBJ_nid2obj(EVP_PKEY_RSA_PSS),
+                                     V_ASN1_SEQUENCE, os2)) {
+                    ASN1_STRING_free(os1);
+                    ASN1_STRING_free(os2);
+                    return 0;
+                }
+            }
+            if (!X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_RSA_PSS),
+                                 V_ASN1_SEQUENCE, os1)) {
+                    ASN1_STRING_free(os1);
+                    return 0;
+            }
+            return 3;
+        }
+
         params[0] = OSSL_PARAM_construct_octet_string(
             OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid));
         params[1] = OSSL_PARAM_construct_end();
@@ -652,11 +682,13 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn,
 
         if (alg1 != NULL) {
             const unsigned char *pp = aid;
+
             if (d2i_X509_ALGOR(&alg1, &pp, aid_len) == NULL)
                 return 0;
         }
         if (alg2 != NULL) {
             const unsigned char *pp = aid;
+
             if (d2i_X509_ALGOR(&alg2, &pp, aid_len) == NULL)
                 return 0;
         }
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c
index 44c819a5c3ce7a..0bf5ac098ac080 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -584,6 +584,10 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
             ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE);
             return -2;
         }
+        if (p2 == NULL) {
+            ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
+            return 0;
+        }
         *(unsigned char **)p2 = rctx->oaep_label;
         return rctx->oaep_labellen;
 
diff --git a/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx2.pl b/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx2.pl
index 84682289bf7a71..864066533445a6 100755
--- a/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx2.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx2.pl
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -432,6 +432,7 @@
 	ret
 .size	SHA3_squeeze,.-SHA3_squeeze
 
+.section .rodata
 .align	64
 rhotates_left:
 	.quad	3,	18,	36,	41	# [2][0] [4][0] [1][0] [3][0]
diff --git a/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512.pl b/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512.pl
index 85d6e7ffe424aa..efc32545c35625 100755
--- a/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512.pl
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -486,6 +486,7 @@
 	ret
 .size	SHA3_squeeze,.-SHA3_squeeze
 
+.section .rodata
 .align	64
 theta_perm:
 	.quad	0, 1, 2, 3, 4, 5, 6, 7		# [not used]
diff --git a/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512vl.pl b/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512vl.pl
index 73e75f363f2041..f941556b42a8b7 100755
--- a/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512vl.pl
+++ b/deps/openssl/openssl/crypto/sha/asm/keccak1600-avx512vl.pl
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
-# Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.
 #
 # Licensed under the Apache License 2.0 (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
@@ -349,6 +349,7 @@
 	ret
 .size	SHA3_squeeze,.-SHA3_squeeze
 
+.section .rodata
 .align	64
 rhotates_left:
 	.quad	3,	18,	36,	41	# [2][0] [4][0] [1][0] [3][0]
diff --git a/deps/openssl/openssl/crypto/store/store_result.c b/deps/openssl/openssl/crypto/store/store_result.c
index 96d31199074d6b..bbc8f6fef265dc 100644
--- a/deps/openssl/openssl/crypto/store/store_result.c
+++ b/deps/openssl/openssl/crypto/store/store_result.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -553,8 +553,10 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v,
 
             ok = 0;              /* Assume decryption or parse error */
 
-            if (PKCS12_verify_mac(p12, "", 0)
+            if (!PKCS12_mac_present(p12)
                 || PKCS12_verify_mac(p12, NULL, 0)) {
+                pass = NULL;
+            } else if (PKCS12_verify_mac(p12, "", 0)) {
                 pass = "";
             } else {
                 static char prompt_info[] = "PKCS12 import pass phrase";
diff --git a/deps/openssl/openssl/crypto/x509/by_dir.c b/deps/openssl/openssl/crypto/x509/by_dir.c
index cb40c7737f72f8..ad871966aa6e30 100644
--- a/deps/openssl/openssl/crypto/x509/by_dir.c
+++ b/deps/openssl/openssl/crypto/x509/by_dir.c
@@ -348,7 +348,8 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
         /*
          * we have added it to the cache so now pull it out again
          */
-        X509_STORE_lock(xl->store_ctx);
+        if (!X509_STORE_lock(xl->store_ctx))
+            goto finish;
         j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp);
         tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
         X509_STORE_unlock(xl->store_ctx);
diff --git a/deps/openssl/openssl/crypto/x509/v3_ist.c b/deps/openssl/openssl/crypto/x509/v3_ist.c
index 0de281f6687122..e6fef0153c8eb2 100644
--- a/deps/openssl/openssl/crypto/x509/v3_ist.c
+++ b/deps/openssl/openssl/crypto/x509/v3_ist.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -50,43 +50,38 @@ static ISSUER_SIGN_TOOL *v2i_issuer_sign_tool(X509V3_EXT_METHOD *method, X509V3_
         }
         if (strcmp(cnf->name, "signTool") == 0) {
             ist->signTool = ASN1_UTF8STRING_new();
-            if (ist->signTool == NULL) {
-                ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
-                ISSUER_SIGN_TOOL_free(ist);
-                return NULL;
+            if (ist->signTool == NULL || !ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value))) {
+                ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
+                goto err;
             }
-            ASN1_STRING_set(ist->signTool, cnf->value, strlen(cnf->value));
         } else if (strcmp(cnf->name, "cATool") == 0) {
             ist->cATool = ASN1_UTF8STRING_new();
-            if (ist->cATool == NULL) {
-                ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
-                ISSUER_SIGN_TOOL_free(ist);
-                return NULL;
+            if (ist->cATool == NULL || !ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value))) {
+                ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
+                goto err;
             }
-            ASN1_STRING_set(ist->cATool, cnf->value, strlen(cnf->value));
         } else if (strcmp(cnf->name, "signToolCert") == 0) {
             ist->signToolCert = ASN1_UTF8STRING_new();
-            if (ist->signToolCert == NULL) {
-                ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
-                ISSUER_SIGN_TOOL_free(ist);
-                return NULL;
+            if (ist->signToolCert == NULL || !ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value))) {
+                ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
+                goto err;
             }
-            ASN1_STRING_set(ist->signToolCert, cnf->value, strlen(cnf->value));
         } else if (strcmp(cnf->name, "cAToolCert") == 0) {
             ist->cAToolCert = ASN1_UTF8STRING_new();
-            if (ist->cAToolCert == NULL) {
-                ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
-                ISSUER_SIGN_TOOL_free(ist);
-                return NULL;
+            if (ist->cAToolCert == NULL || !ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value))) {
+                ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
+                goto err;
             }
-            ASN1_STRING_set(ist->cAToolCert, cnf->value, strlen(cnf->value));
         } else {
             ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_INVALID_ARGUMENT);
-            ISSUER_SIGN_TOOL_free(ist);
-            return NULL;
+            goto err;
         }
     }
     return ist;
+
+err:
+    ISSUER_SIGN_TOOL_free(ist);
+    return NULL;
 }
 
 static int i2r_issuer_sign_tool(X509V3_EXT_METHOD *method,
diff --git a/deps/openssl/openssl/crypto/x509/v3_purp.c b/deps/openssl/openssl/crypto/x509/v3_purp.c
index a6ebbd5f94f6a6..6461189179f468 100644
--- a/deps/openssl/openssl/crypto/x509/v3_purp.c
+++ b/deps/openssl/openssl/crypto/x509/v3_purp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -438,7 +438,7 @@ int ossl_x509v3_cache_extensions(X509 *x)
              * in case ctx->param->flags & X509_V_FLAG_X509_STRICT
              */
             if (bs->pathlen->type == V_ASN1_NEG_INTEGER) {
-                ERR_raise(ERR_LIB_X509, X509V3_R_NEGATIVE_PATHLEN);
+                ERR_raise(ERR_LIB_X509V3, X509V3_R_NEGATIVE_PATHLEN);
                 x->ex_flags |= EXFLAG_INVALID;
             } else {
                 x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
@@ -479,7 +479,7 @@ int ossl_x509v3_cache_extensions(X509 *x)
         ASN1_BIT_STRING_free(usage);
         /* Check for empty key usage according to RFC 5280 section 4.2.1.3 */
         if (x->ex_kusage == 0) {
-            ERR_raise(ERR_LIB_X509, X509V3_R_EMPTY_KEY_USAGE);
+            ERR_raise(ERR_LIB_X509V3, X509V3_R_EMPTY_KEY_USAGE);
             x->ex_flags |= EXFLAG_INVALID;
         }
     } else if (i != -1) {
@@ -632,7 +632,7 @@ int ossl_x509v3_cache_extensions(X509 *x)
         return 1;
     }
     if ((x->ex_flags & EXFLAG_INVALID) != 0)
-        ERR_raise(ERR_LIB_X509, X509V3_R_INVALID_CERTIFICATE);
+        ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_CERTIFICATE);
     /* If computing sha1_hash failed the error queue already reflects this. */
 
  err:
diff --git a/deps/openssl/openssl/crypto/x509/x509_att.c b/deps/openssl/openssl/crypto/x509/x509_att.c
index 73ac59454d1f70..d9fe7a3791d1fa 100644
--- a/deps/openssl/openssl/crypto/x509/x509_att.c
+++ b/deps/openssl/openssl/crypto/x509/x509_att.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -82,6 +82,11 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
         return NULL;
     }
 
+    if (*x != NULL && X509at_get_attr_by_OBJ(*x, attr->object, -1) != -1) {
+        ERR_raise(ERR_LIB_X509, X509_R_DUPLICATE_ATTRIBUTE);
+        return NULL;
+    }
+
     if (*x == NULL) {
         if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
             goto err;
diff --git a/deps/openssl/openssl/crypto/x509/x509_cmp.c b/deps/openssl/openssl/crypto/x509/x509_cmp.c
index 5c9d91f4073d74..1027bed82e69da 100644
--- a/deps/openssl/openssl/crypto/x509/x509_cmp.c
+++ b/deps/openssl/openssl/crypto/x509/x509_cmp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -277,11 +277,11 @@ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
     if (ret == 0 && a->canon_enclen == 0)
         return 0;
 
-    if (a->canon_enc == NULL || b->canon_enc == NULL)
-        return -2;
-
-    if (ret == 0)
+    if (ret == 0) {
+        if (a->canon_enc == NULL || b->canon_enc == NULL)
+            return -2;
         ret = memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
+    }
 
     return ret < 0 ? -1 : ret > 0;
 }
diff --git a/deps/openssl/openssl/crypto/x509/x509_err.c b/deps/openssl/openssl/crypto/x509/x509_err.c
index a933aeef351fc5..37467935c99786 100644
--- a/deps/openssl/openssl/crypto/x509/x509_err.c
+++ b/deps/openssl/openssl/crypto/x509/x509_err.c
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -28,6 +28,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = {
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE),
     "crl verify failure"},
+    {ERR_PACK(ERR_LIB_X509, 0, X509_R_DUPLICATE_ATTRIBUTE),
+    "duplicate attribute"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_GETTING_MD_BY_NID),
     "error getting md by nid"},
     {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_USING_SIGINF_SET),
diff --git a/deps/openssl/openssl/crypto/x509/x509_vpm.c b/deps/openssl/openssl/crypto/x509/x509_vpm.c
index b4f4c45998befe..998ce8ac1ba14e 100644
--- a/deps/openssl/openssl/crypto/x509/x509_vpm.c
+++ b/deps/openssl/openssl/crypto/x509/x509_vpm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -337,7 +337,10 @@ int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
         if (param->policies == NULL)
             return 0;
     }
-    return sk_ASN1_OBJECT_push(param->policies, policy);
+
+    if (sk_ASN1_OBJECT_push(param->policies, policy) <= 0)
+        return 0;
+    return 1;
 }
 
 int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
@@ -592,7 +595,10 @@ int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
             X509_VERIFY_PARAM_free(ptmp);
         }
     }
-    return sk_X509_VERIFY_PARAM_push(param_table, param);
+
+    if (sk_X509_VERIFY_PARAM_push(param_table, param) <= 0)
+        return 0;
+    return 1;
 }
 
 int X509_VERIFY_PARAM_get_count(void)
diff --git a/deps/openssl/openssl/doc/man1/openssl-dhparam.pod.in b/deps/openssl/openssl/doc/man1/openssl-dhparam.pod.in
index d358ba95dcf3f3..7865e3b25b9d5b 100644
--- a/deps/openssl/openssl/doc/man1/openssl-dhparam.pod.in
+++ b/deps/openssl/openssl/doc/man1/openssl-dhparam.pod.in
@@ -88,7 +88,7 @@ I. It must be the last option. If this option is present then
 the input file is ignored and parameters are generated instead. If
 this option is not present but a generator (B<-2>, B<-3> or B<-5>) is
 present, parameters are generated with a default length of 2048 bits.
-The minimim length is 512 bits. The maximum length is 10000 bits.
+The minimum length is 512 bits. The maximum length is 10000 bits.
 
 =item B<-noout>
 
@@ -126,7 +126,7 @@ The B<-C> option was removed in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man1/openssl-genpkey.pod.in b/deps/openssl/openssl/doc/man1/openssl-genpkey.pod.in
index 181530670836c3..8f139d147f9273 100644
--- a/deps/openssl/openssl/doc/man1/openssl-genpkey.pod.in
+++ b/deps/openssl/openssl/doc/man1/openssl-genpkey.pod.in
@@ -278,7 +278,7 @@ RFC5114 names "dh_1024_160", "dh_2048_224", "dh_2048_256".
 
 If this option is set, then the appropriate RFC5114 parameters are used
 instead of generating new parameters. The value I can be one of
-1, 2 or 3 that are equivalant to using the option B with one of
+1, 2 or 3 that are equivalent to using the option B with one of
 "dh_1024_160", "dh_2048_224" or "dh_2048_256".
 All other options will be ignored if this value is set.
 
@@ -333,7 +333,7 @@ The B option must be B<"DH">.
 =item "default"
 
 Selects a default type based on the B. This is used by the
-OpenSSL default provider to set the type for backwards compatability.
+OpenSSL default provider to set the type for backwards compatibility.
 If B is B<"DH"> then B<"generator"> is used.
 If B is B<"DHX"> then B<"fips186_2"> is used.
 
@@ -494,7 +494,7 @@ The B<-engine> option was deprecated in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man1/openssl-genrsa.pod.in b/deps/openssl/openssl/doc/man1/openssl-genrsa.pod.in
index 62964096151734..db1cab6e41a308 100644
--- a/deps/openssl/openssl/doc/man1/openssl-genrsa.pod.in
+++ b/deps/openssl/openssl/doc/man1/openssl-genrsa.pod.in
@@ -35,9 +35,6 @@ B B
 
 =head1 DESCRIPTION
 
-This command has been deprecated.
-The L command should be used instead.
-
 This command generates an RSA private key.
 
 =head1 OPTIONS
@@ -118,13 +115,9 @@ L,
 L,
 L
 
-=head1 HISTORY
-
-This command was deprecated in OpenSSL 3.0.
-
 =head1 COPYRIGHT
 
-Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man1/openssl-kdf.pod.in b/deps/openssl/openssl/doc/man1/openssl-kdf.pod.in
index 23776378a1be30..6eed74d70d4c86 100644
--- a/deps/openssl/openssl/doc/man1/openssl-kdf.pod.in
+++ b/deps/openssl/openssl/doc/man1/openssl-kdf.pod.in
@@ -66,8 +66,7 @@ cases.
 =item B<-kdfopt> I:I
 
 Passes options to the KDF algorithm.
-A comprehensive list of parameters can be found in the EVP_KDF_CTX
-implementation documentation.
+A comprehensive list of parameters can be found in L.
 Common parameter names used by EVP_KDF_CTX_set_params() are:
 
 =over 4
@@ -81,9 +80,8 @@ A key must be specified for most KDF algorithms.
 
 =item BI
 
-Specifies the secret key in hexadecimal form (two hex digits per byte).
-The key length must conform to any restrictions of the KDF algorithm.
-A key must be specified for most KDF algorithms.
+Alternative to the B option where
+the secret key is specified in hexadecimal form (two hex digits per byte).
 
 =item BI
 
@@ -93,8 +91,35 @@ The password must be specified for PBKDF2 and scrypt.
 
 =item BI
 
-Specifies the password in hexadecimal form (two hex digits per byte).
-The password must be specified for PBKDF2 and scrypt.
+Alternative to the B option where
+the password is specified in hexadecimal form (two hex digits per byte).
+
+=item BI
+
+Specifies a non-secret unique cryptographic salt as an alphanumeric string
+(use if it contains printable characters only).
+The length must conform to any restrictions of the KDF algorithm.
+A salt parameter is required for several KDF algorithms,
+such as L.
+
+=item BI
+
+Alternative to the B option where
+the salt is specified in hexadecimal form (two hex digits per byte).
+
+=item BI
+
+Some KDF implementations, such as L, take an 'info' parameter
+for binding the derived key material
+to application- and context-specific information.
+Specifies the info, fixed info, other info or shared info argument
+as an alphanumeric string (use if it contains printable characters only).
+The length must conform to any restrictions of the KDF algorithm.
+
+=item BI
+
+Alternative to the B option where
+the info is specified in hexadecimal form (two hex digits per byte).
 
 =item BI
 
@@ -195,7 +220,7 @@ Added in OpenSSL 3.0
 
 =head1 COPYRIGHT
 
-Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man1/openssl-rsautl.pod.in b/deps/openssl/openssl/doc/man1/openssl-rsautl.pod.in
index 186e49e5e49b89..0a32fd965bf193 100644
--- a/deps/openssl/openssl/doc/man1/openssl-rsautl.pod.in
+++ b/deps/openssl/openssl/doc/man1/openssl-rsautl.pod.in
@@ -99,7 +99,7 @@ Encrypt the input data using an RSA public key.
 
 Decrypt the input data using an RSA private key.
 
-=item B<-pkcs>, B<-oaep>, B<-x931> B<-raw>
+=item B<-pkcs>, B<-oaep>, B<-x931>, B<-raw>
 
 The padding to use: PKCS#1 v1.5 (the default), PKCS#1 OAEP,
 ANSI X9.31, or no padding, respectively.
@@ -232,7 +232,7 @@ The B<-engine> option was deprecated in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man1/openssl-s_client.pod.in b/deps/openssl/openssl/doc/man1/openssl-s_client.pod.in
index c921e3b4a25f38..4b7b58b72d5537 100644
--- a/deps/openssl/openssl/doc/man1/openssl-s_client.pod.in
+++ b/deps/openssl/openssl/doc/man1/openssl-s_client.pod.in
@@ -274,7 +274,7 @@ See L for details.
 
 =item B<-pass> I
 
-the private key and certifiate file password source.
+the private key and certificate file password source.
 For more information about the format of I
 see L.
 
@@ -910,7 +910,7 @@ The B<-engine> option was deprecated in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man1/openssl-verification-options.pod b/deps/openssl/openssl/doc/man1/openssl-verification-options.pod
index 5fa3907c2801a8..4998e452b54957 100644
--- a/deps/openssl/openssl/doc/man1/openssl-verification-options.pod
+++ b/deps/openssl/openssl/doc/man1/openssl-verification-options.pod
@@ -92,7 +92,7 @@ It does not have a negative trust attribute rejecting the given use.
 =item *
 
 It has a positive trust attribute accepting the given use
-or (by default) one of the following compatibilty conditions apply:
+or (by default) one of the following compatibility conditions apply:
 It is self-signed or the B<-partial_chain> option is given
 (which corresponds to the B flag being set).
 
@@ -686,7 +686,7 @@ The checks enabled by B<-x509_strict> have been extended in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man1/openssl-x509.pod.in b/deps/openssl/openssl/doc/man1/openssl-x509.pod.in
index dd8f17154af966..5a120287a84534 100644
--- a/deps/openssl/openssl/doc/man1/openssl-x509.pod.in
+++ b/deps/openssl/openssl/doc/man1/openssl-x509.pod.in
@@ -478,7 +478,7 @@ unless the B<-new> option is given, which generates a certificate from scratch.
 
 =item B<-CAform> B|B|B,
 
-The format for the CA certificate; unspecifed by default.
+The format for the CA certificate; unspecified by default.
 See L for details.
 
 =item B<-CAkey> I|I
@@ -784,7 +784,7 @@ The B<-C> option was removed in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man3/ASN1_aux_cb.pod b/deps/openssl/openssl/doc/man3/ASN1_aux_cb.pod
index 12f7ddf82d6467..f87b51d5efac26 100644
--- a/deps/openssl/openssl/doc/man3/ASN1_aux_cb.pod
+++ b/deps/openssl/openssl/doc/man3/ASN1_aux_cb.pod
@@ -3,7 +3,7 @@
 =head1 NAME
 
 ASN1_AUX, ASN1_PRINT_ARG, ASN1_STREAM_ARG, ASN1_aux_cb, ASN1_aux_const_cb
-- ASN.1 auxilliary data
+- ASN.1 auxiliary data
 
 =head1 SYNOPSIS
 
@@ -45,7 +45,7 @@ ASN.1 data structures can be associated with an B object to supply
 additional information about the ASN.1 structure. An B structure is
 associated with the structure during the definition of the ASN.1 template. For
 example an B structure will be associated by using one of the various
-ASN.1 template definition macros that supply auxilliary information such as
+ASN.1 template definition macros that supply auxiliary information such as
 ASN1_SEQUENCE_enc(), ASN1_SEQUENCE_ref(), ASN1_SEQUENCE_cb_const_cb(),
 ASN1_SEQUENCE_const_cb(), ASN1_SEQUENCE_cb() or ASN1_NDEF_SEQUENCE_cb().
 
@@ -274,7 +274,7 @@ B operation types were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man3/ASN1_item_sign.pod b/deps/openssl/openssl/doc/man3/ASN1_item_sign.pod
index 407268bf1779bc..2716bd30ccd45e 100644
--- a/deps/openssl/openssl/doc/man3/ASN1_item_sign.pod
+++ b/deps/openssl/openssl/doc/man3/ASN1_item_sign.pod
@@ -62,7 +62,7 @@ I are ignored if they are NULL.
 ASN1_item_sign() is similar to ASN1_item_sign_ex() but uses default values of
 NULL for the I, I and I.
 
-ASN1_item_sign_ctx() is similiar to ASN1_item_sign() but uses the parameters
+ASN1_item_sign_ctx() is similar to ASN1_item_sign() but uses the parameters
 contained in digest context I.
 
 ASN1_item_verify_ex() is used to verify the signature I of internal
@@ -77,7 +77,7 @@ See EVP_PKEY_CTX_set1_id() for further info.
 ASN1_item_verify() is similar to ASN1_item_verify_ex() but uses default values of
 NULL for the I, I and I.
 
-ASN1_item_verify_ctx() is similiar to ASN1_item_verify() but uses the parameters
+ASN1_item_verify_ctx() is similar to ASN1_item_verify() but uses the parameters
 contained in digest context I.
 
 
@@ -216,7 +216,7 @@ ASN1_item_sign_ex() and ASN1_item_verify_ex() were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man3/ASYNC_WAIT_CTX_new.pod b/deps/openssl/openssl/doc/man3/ASYNC_WAIT_CTX_new.pod
index 328af9e53a6419..7621a8b3a166b1 100644
--- a/deps/openssl/openssl/doc/man3/ASYNC_WAIT_CTX_new.pod
+++ b/deps/openssl/openssl/doc/man3/ASYNC_WAIT_CTX_new.pod
@@ -83,7 +83,7 @@ will be populated with the list of added and deleted fds respectively. Similarly
 to ASYNC_WAIT_CTX_get_all_fds() either of these can be NULL, but if they are not
 NULL then the caller is responsible for ensuring sufficient memory is allocated.
 
-Implementors of async aware code (e.g. engines) are encouraged to return a
+Implementers of async aware code (e.g. engines) are encouraged to return a
 stable fd for the lifetime of the B in order to reduce the
 "churn" of regularly changing fds - although no guarantees of this are provided
 to applications.
@@ -216,7 +216,7 @@ were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man3/BIO_s_core.pod b/deps/openssl/openssl/doc/man3/BIO_s_core.pod
index fbcd0b5c9c07f6..0b9aefe91e540f 100644
--- a/deps/openssl/openssl/doc/man3/BIO_s_core.pod
+++ b/deps/openssl/openssl/doc/man3/BIO_s_core.pod
@@ -22,7 +22,7 @@ libcrypto into a provider supply an OSSL_CORE_BIO parameter. This represents
 a BIO within libcrypto, but cannot be used directly by a provider. Instead it
 should be wrapped using a BIO_s_core().
 
-Once a BIO is contructed based on BIO_s_core(), the associated OSSL_CORE_BIO
+Once a BIO is constructed based on BIO_s_core(), the associated OSSL_CORE_BIO
 object should be set on it using BIO_set_data(3). Note that the BIO will only
 operate correctly if it is associated with a library context constructed using
 OSSL_LIB_CTX_new_from_dispatch(3). To associate the BIO with a library context
@@ -62,7 +62,7 @@ Create a core BIO and write some data to it:
 
 =head1 COPYRIGHT
 
-Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man3/BN_rand.pod b/deps/openssl/openssl/doc/man3/BN_rand.pod
index aebad1e72eb2c2..0ad76d6af7e753 100644
--- a/deps/openssl/openssl/doc/man3/BN_rand.pod
+++ b/deps/openssl/openssl/doc/man3/BN_rand.pod
@@ -59,7 +59,7 @@ BN_rand() is the same as BN_rand_ex() except that the default library context
 is always used.
 
 BN_rand_range_ex() generates a cryptographically strong pseudo-random
-number I, of security stength at least I bits,
+number I, of security strength at least I bits,
 in the range 0 E= I E I using the random number
 generator for the library context associated with I. The parameter I
 may be NULL in which case the default library context is used.
@@ -119,7 +119,7 @@ BN_priv_rand_range_ex() functions were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man3/CONF_modules_load_file.pod b/deps/openssl/openssl/doc/man3/CONF_modules_load_file.pod
index f96d9a12938a68..620bbfd8986194 100644
--- a/deps/openssl/openssl/doc/man3/CONF_modules_load_file.pod
+++ b/deps/openssl/openssl/doc/man3/CONF_modules_load_file.pod
@@ -34,7 +34,7 @@ as determined by calling CONF_get1_default_config_file().
 If B is NULL the standard OpenSSL application name B is
 used.
 The behaviour can be customized using B. Note that, the error suppressing
-can be overriden by B as described in L.
+can be overridden by B as described in L.
 
 CONF_modules_load_file() is the same as CONF_modules_load_file_ex() but
 has a NULL library context.
@@ -154,7 +154,7 @@ L
 
 =head1 COPYRIGHT
 
-Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved.
 
 Licensed under the Apache License 2.0 (the "License").  You may not use
 this file except in compliance with the License.  You can obtain a copy
diff --git a/deps/openssl/openssl/doc/man3/DH_get0_pqg.pod b/deps/openssl/openssl/doc/man3/DH_get0_pqg.pod
index 2afc35c77f865d..6e5b301f6c6ea6 100644
--- a/deps/openssl/openssl/doc/man3/DH_get0_pqg.pod
+++ b/deps/openssl/openssl/doc/man3/DH_get0_pqg.pod
@@ -40,7 +40,7 @@ see L:
 
 All of the functions described on this page are deprecated.
 Applications should instead use L for any methods that
-return a B. Refer to L for more infomation.
+return a B. Refer to L for more information.
 
 A DH object contains the parameters I

, I and I. Note that the I parameter is optional. It also contains a public key (I) and @@ -141,7 +141,7 @@ All of these functions were deprecated in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_EncryptInit.pod b/deps/openssl/openssl/doc/man3/EVP_EncryptInit.pod index e469f28a7b5423..886cbdfbd3f5f9 100644 --- a/deps/openssl/openssl/doc/man3/EVP_EncryptInit.pod +++ b/deps/openssl/openssl/doc/man3/EVP_EncryptInit.pod @@ -665,7 +665,7 @@ Note that the block size for a cipher may be different to the block size for the underlying encryption/decryption primitive. For example AES in CTR mode has a block size of 1 (because it operates like a stream cipher), even though AES has a block size of 16. -Use EVP_CIPHER_get_block_size() to retreive the cached value. +Use EVP_CIPHER_get_block_size() to retrieve the cached value. =item "aead" (B) @@ -1192,10 +1192,11 @@ EVP_DecryptFinal_ex() returns 0 if the decrypt failed or 1 for success. EVP_CipherInit_ex2() and EVP_CipherUpdate() return 1 for success and 0 for failure. EVP_CipherFinal_ex() returns 0 for a decryption failure or 1 for success. -EVP_Cipher() returns the amount of encrypted / decrypted bytes, or -1 -on failure if the flag B is set for the -cipher. EVP_Cipher() returns 1 on success or 0 on failure, if the flag +EVP_Cipher() returns 1 on success or 0 on failure, if the flag B is not set for the cipher. +EVP_Cipher() returns the number of bytes written to I for encryption / decryption, or +the number of bytes authenticated in a call specifying AAD for an AEAD cipher, if the flag +B is set for the cipher. EVP_CIPHER_CTX_reset() returns 1 for success and 0 for failure. @@ -1266,7 +1267,8 @@ depending on the mode specified. To specify additional authenticated data (AAD), a call to EVP_CipherUpdate(), EVP_EncryptUpdate() or EVP_DecryptUpdate() should be made with the output -parameter I set to B. +parameter I set to B. In this case, on success, the parameter +I is set to the number of bytes authenticated. When decrypting, the return value of EVP_DecryptFinal() or EVP_CipherFinal() indicates whether the operation was successful. If it does not indicate success, diff --git a/deps/openssl/openssl/doc/man3/EVP_KDF.pod b/deps/openssl/openssl/doc/man3/EVP_KDF.pod index 3b4e2b79aa1458..31d61b2a3df0a7 100644 --- a/deps/openssl/openssl/doc/man3/EVP_KDF.pod +++ b/deps/openssl/openssl/doc/man3/EVP_KDF.pod @@ -191,7 +191,7 @@ For those KDF implementations that support it, this parameter sets the password. =item "salt" (B) -Some KDF implementations can take a salt. +Some KDF implementations can take a non-secret unique cryptographic salt. For those KDF implementations that support it, this parameter sets the salt. The default value, if any, is implementation dependent. @@ -227,6 +227,15 @@ Some KDF implementations require a key. For those KDF implementations that support it, this octet string parameter sets the key. +=item "info" (B) + +Some KDF implementations, such as L, take an 'info' parameter +for binding the derived key material +to application- and context-specific information. +This parameter sets the info, fixed info, other info or shared info argument. +You can specify this parameter multiple times, and each instance will +be concatenated to form the final value. + =item "maclen" (B) Used by implementations that use a MAC with a variable output size (KMAC). @@ -295,7 +304,7 @@ This functionality was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_KEYMGMT.pod b/deps/openssl/openssl/doc/man3/EVP_KEYMGMT.pod index f81fc9efb00b93..455ffadce5ec64 100644 --- a/deps/openssl/openssl/doc/man3/EVP_KEYMGMT.pod +++ b/deps/openssl/openssl/doc/man3/EVP_KEYMGMT.pod @@ -123,7 +123,7 @@ otherwise 0. EVP_KEYMGMT_get0_name() returns the algorithm name, or NULL on error. -EVP_KEYMGMT_get0_description() returns a pointer to a decription, or NULL if +EVP_KEYMGMT_get0_description() returns a pointer to a description, or NULL if there isn't one. EVP_KEYMGMT_gettable_params(), EVP_KEYMGMT_settable_params() and @@ -140,7 +140,7 @@ The functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY2PKCS8.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY2PKCS8.pod index 290a3ba3593e61..1129a5c75c4bea 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY2PKCS8.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY2PKCS8.pod @@ -21,7 +21,7 @@ EVP_PKEY2PKCS8() converts a private key I into a returned PKCS8 object. EVP_PKCS82PKEY_ex() converts a PKCS8 object I into a returned private key. It uses I and I when fetching algorithms. -EVP_PKCS82PKEY() is similiar to EVP_PKCS82PKEY_ex() but uses default values of +EVP_PKCS82PKEY() is similar to EVP_PKCS82PKEY_ex() but uses default values of NULL for the I and I. =head1 RETURN VALUES @@ -37,7 +37,7 @@ L, =head1 COPYRIGHT -Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY_decapsulate.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY_decapsulate.pod index 529e318f9eba01..819291627bb8b8 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY_decapsulate.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY_decapsulate.pod @@ -3,7 +3,7 @@ =head1 NAME EVP_PKEY_decapsulate_init, EVP_PKEY_decapsulate -- Key decapsulation using a private key algorithm +- Key decapsulation using a KEM algorithm with a private key =head1 SYNOPSIS @@ -11,7 +11,7 @@ EVP_PKEY_decapsulate_init, EVP_PKEY_decapsulate int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]); int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, - unsigned char *secret, size_t *secretlen, + unsigned char *unwrapped, size_t *unwrappedlen, const unsigned char *wrapped, size_t wrappedlen); =head1 DESCRIPTION @@ -19,18 +19,20 @@ EVP_PKEY_decapsulate_init, EVP_PKEY_decapsulate The EVP_PKEY_decapsulate_init() function initializes a private key algorithm context I for a decapsulation operation and then sets the I on the context in the same way as calling L. +Note that I usually is produced using L, +specifying the private key to use. The EVP_PKEY_decapsulate() function performs a private key decapsulation operation using I. The data to be decapsulated is specified using the I and I parameters. -If I is I then the maximum size of the output secret buffer -is written to the I<*secretlen> parameter. If I is not B and the -call is successful then the decapsulated secret data is written to I and -the amount of data written to I. +If I is NULL then the maximum size of the output secret buffer +is written to I<*unwrappedlen>. If I is not NULL and the +call is successful then the decapsulated secret data is written to I +and the amount of data written to I<*unwrappedlen>. =head1 NOTES -After the call to EVP_PKEY_decapsulate_init() algorithm specific parameters +After the call to EVP_PKEY_decapsulate_init() algorithm-specific parameters for the operation may be set or modified using L. =head1 RETURN VALUES @@ -79,7 +81,7 @@ Decapsulate data using RSA: =head1 SEE ALSO -L, +L, L, L, @@ -89,7 +91,7 @@ These functions were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY_derive.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY_derive.pod index d61bb5512f62ed..bfbe14b1ffff44 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY_derive.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY_derive.pod @@ -32,7 +32,7 @@ EVP_PKEY_derive_set_peer_ex() sets the peer key: this will normally be a public key. The I will validate the public key if this value is non zero. -EVP_PKEY_derive_set_peer() is similiar to EVP_PKEY_derive_set_peer_ex() with +EVP_PKEY_derive_set_peer() is similar to EVP_PKEY_derive_set_peer_ex() with I set to 1. EVP_PKEY_derive() derives a shared secret using I. @@ -114,7 +114,7 @@ added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY_encapsulate.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY_encapsulate.pod index 9baf88d07beffc..0ee7d627904d13 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY_encapsulate.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY_encapsulate.pod @@ -3,7 +3,7 @@ =head1 NAME EVP_PKEY_encapsulate_init, EVP_PKEY_encapsulate -- Key encapsulation using a public key algorithm +- Key encapsulation using a KEM algorithm with a public key =head1 SYNOPSIS @@ -11,7 +11,7 @@ EVP_PKEY_encapsulate_init, EVP_PKEY_encapsulate int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]); int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, + unsigned char *wrappedkey, size_t *wrappedkeylen, unsigned char *genkey, size_t *genkeylen); =head1 DESCRIPTION @@ -19,19 +19,27 @@ EVP_PKEY_encapsulate_init, EVP_PKEY_encapsulate The EVP_PKEY_encapsulate_init() function initializes a public key algorithm context I for an encapsulation operation and then sets the I on the context in the same way as calling L. +Note that I is usually is produced using L, +specifying the public key to use. The EVP_PKEY_encapsulate() function performs a public key encapsulation -operation using I with the name I. -If I is B then the maximum size of the output buffer is written to the -I<*outlen> parameter and the maximum size of the generated key buffer is written -to I<*genkeylen>. If I is not B and the call is successful then the +operation using I. +The symmetric secret generated in I can be used as key material. +The ciphertext in I is its encapsulated form, which can be sent +to another party, who can use L to retrieve it +using their private key. +If I is NULL then the maximum size of the output buffer +is written to the I<*wrappedkeylen> parameter unless I is NULL +and the maximum size of the generated key buffer is written to I<*genkeylen> +unless I is NULL. +If I is not NULL and the call is successful then the internally generated key is written to I and its size is written to I<*genkeylen>. The encapsulated version of the generated key is written to -I and its size is written to I<*outlen>. +I and its size is written to I<*wrappedkeylen>. =head1 NOTES -After the call to EVP_PKEY_encapsulate_init() algorithm specific parameters +After the call to EVP_PKEY_encapsulate_init() algorithm-specific parameters for the operation may be set or modified using L. =head1 RETURN VALUES @@ -82,7 +90,7 @@ Encapsulate an RSASVE key (for RSA keys). =head1 SEE ALSO -L, +L, L, L, @@ -92,7 +100,7 @@ These functions were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY_get_default_digest_nid.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY_get_default_digest_nid.pod index ddabac8ff8e413..e22a3e7b4717c1 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY_get_default_digest_nid.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY_get_default_digest_nid.pod @@ -18,8 +18,8 @@ EVP_PKEY_get_default_digest_nid, EVP_PKEY_get_default_digest_name EVP_PKEY_get_default_digest_name() fills in the default message digest name for the public key signature operations associated with key I into I, up to at most I bytes including the -ending NUL byte. The name could be C<"UNDEF">, signifying that no digest -should be used. +ending NUL byte. The name could be C<"UNDEF">, signifying that a digest +must (for return value 2) or may (for return value 1) be left unspecified. EVP_PKEY_get_default_digest_nid() sets I to the default message digest NID for the public key signature operations associated with key @@ -57,7 +57,7 @@ This function was added in OpenSSL 1.0.0. =head1 COPYRIGHT -Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY_gettable_params.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY_gettable_params.pod index b51e4c4de1859d..acf20b54e554aa 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY_gettable_params.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY_gettable_params.pod @@ -60,7 +60,7 @@ is allocated by the method. EVP_PKEY_get_utf8_string_param() get a key I UTF8 string value into a buffer I of maximum size I associated with a name of -I. The maximum size must be large enough to accomodate the string +I. The maximum size must be large enough to accommodate the string value including a terminating NUL byte, or this function will fail. If I is not NULL, I<*out_len> is set to the length of the string not including the terminating NUL byte. The required buffer size not including @@ -125,7 +125,7 @@ These functions were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY_new.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY_new.pod index 0ea7062f0182aa..1c75c7571994b3 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY_new.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY_new.pod @@ -62,7 +62,7 @@ see L: B is a generic structure to hold diverse types of asymmetric keys (also known as "key pairs"), and can be used for diverse operations, like signing, verifying signatures, key derivation, etc. The asymmetric keys -themselves are often refered to as the "internal key", and are handled by +themselves are often referred to as the "internal key", and are handled by backends, such as providers (through L) or Bs. Conceptually, an B internal key may hold a private key, a public @@ -210,7 +210,7 @@ previously implied to be disallowed. =head1 COPYRIGHT -Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_PKEY_todata.pod b/deps/openssl/openssl/doc/man3/EVP_PKEY_todata.pod index dedfb1b0cf8ae8..71867236f98706 100644 --- a/deps/openssl/openssl/doc/man3/EVP_PKEY_todata.pod +++ b/deps/openssl/openssl/doc/man3/EVP_PKEY_todata.pod @@ -23,7 +23,7 @@ I is described in L. L should be used to free the returned parameters in I<*params>. -EVP_PKEY_export() is similiar to EVP_PKEY_todata() but uses a callback +EVP_PKEY_export() is similar to EVP_PKEY_todata() but uses a callback I that gets passed the value of I. See L for more information about the callback. Note that the L array that is passed to the callback is not persistent after the @@ -53,7 +53,7 @@ These functions were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/EVP_chacha20.pod b/deps/openssl/openssl/doc/man3/EVP_chacha20.pod index 28ab25bf718891..683faa326e1453 100644 --- a/deps/openssl/openssl/doc/man3/EVP_chacha20.pod +++ b/deps/openssl/openssl/doc/man3/EVP_chacha20.pod @@ -22,10 +22,10 @@ The ChaCha20 stream cipher for EVP. =item EVP_chacha20() The ChaCha20 stream cipher. The key length is 256 bits, the IV is 128 bits long. -The first 32 bits consists of a counter in little-endian order followed by a 96 +The first 64 bits consists of a counter in little-endian order followed by a 64 bit nonce. For example a nonce of: -000000000000000000000002 +0000000000000002 With an initial counter of 42 (2a in hex) would be expressed as: @@ -47,6 +47,9 @@ calling these functions multiple times and should consider using L instead. See L for further information. +L +uses a 32 bit counter and a 96 bit nonce for the IV. + =head1 RETURN VALUES These functions return an B structure that contains the diff --git a/deps/openssl/openssl/doc/man3/OCSP_resp_find_status.pod b/deps/openssl/openssl/doc/man3/OCSP_resp_find_status.pod index f4afddcdefe9d1..0fa1a3cf249a06 100644 --- a/deps/openssl/openssl/doc/man3/OCSP_resp_find_status.pod +++ b/deps/openssl/openssl/doc/man3/OCSP_resp_find_status.pod @@ -131,7 +131,7 @@ in L. If I contains B it ignores all certificates in I and in I, else it takes them as untrusted intermediate CA certificates and uses them for constructing the validation path for the signer certificate. -Certicate revocation status checks using CRLs is disabled during path validation +Certificate revocation status checks using CRLs is disabled during path validation if the signer certificate contains the B extension. After successful path validation the function returns success if the B flag is set. @@ -210,7 +210,7 @@ L =head1 COPYRIGHT -Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OCSP_sendreq_new.pod b/deps/openssl/openssl/doc/man3/OCSP_sendreq_new.pod index 6e4c8110f1f038..ce2749ed1ba686 100644 --- a/deps/openssl/openssl/doc/man3/OCSP_sendreq_new.pod +++ b/deps/openssl/openssl/doc/man3/OCSP_sendreq_new.pod @@ -40,7 +40,7 @@ These functions perform an OCSP POST request / response transfer over HTTP, using the HTTP request functions described in L. The function OCSP_sendreq_new() builds a complete B structure -with the B I to be used for requests and reponse, the URL path I, +with the B I to be used for requests and response, the URL path I, optionally the OCSP request I, and a response header maximum line length of I. If I is zero a default value of 4KiB is used. The I may be set to NULL and provided later using OCSP_REQ_CTX_set1_req() @@ -115,7 +115,7 @@ were deprecated in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_CMP_CTX_new.pod b/deps/openssl/openssl/doc/man3/OSSL_CMP_CTX_new.pod index c0c41a226bfeb2..e81fb08b00d613 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_CMP_CTX_new.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_CMP_CTX_new.pod @@ -627,7 +627,7 @@ OSSL_CMP_CTX_set_certConf_cb_arg(), or NULL if unset. OSSL_CMP_CTX_get_status() returns for client contexts the PKIstatus from the last received CertRepMessage or Revocation Response or error message: -=item B on sucessful receipt of a GENP message: +=item B on successful receipt of a GENP message: =over 4 diff --git a/deps/openssl/openssl/doc/man3/OSSL_CMP_log_open.pod b/deps/openssl/openssl/doc/man3/OSSL_CMP_log_open.pod index 9a55370e3c0cc0..f540c193829777 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_CMP_log_open.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_CMP_log_open.pod @@ -89,7 +89,7 @@ As long as neither if the two is used any logging output is ignored. OSSL_CMP_log_close() may be called when all activities are finished to flush any pending CMP-specific log output and deallocate related resources. -It may be called multiple times. It does get called at OpenSSL stutdown. +It may be called multiple times. It does get called at OpenSSL shutdown. OSSL_CMP_print_to_bio() prints the given component info, filename, line number, severity level, and log message or error queue message to the given I. @@ -114,7 +114,7 @@ The OpenSSL CMP support was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_DECODER.pod b/deps/openssl/openssl/doc/man3/OSSL_DECODER.pod index 334f955e16f99a..dcfd72bf973847 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_DECODER.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_DECODER.pod @@ -116,7 +116,7 @@ multiple synonyms associated with it. In this case the first name from the algorithm definition is returned. Ownership of the returned string is retained by the I object and should not be freed by the caller. -OSSL_DECODER_get0_description() returns a pointer to a decription, or NULL if +OSSL_DECODER_get0_description() returns a pointer to a description, or NULL if there isn't one. OSSL_DECODER_names_do_all() returns 1 if the callback was called for all @@ -180,7 +180,7 @@ The functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_DECODER_CTX_new_for_pkey.pod b/deps/openssl/openssl/doc/man3/OSSL_DECODER_CTX_new_for_pkey.pod index 213791404c778e..acb04bc3762379 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_DECODER_CTX_new_for_pkey.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_DECODER_CTX_new_for_pkey.pod @@ -41,7 +41,7 @@ them up, so all the caller has to do next is call functions like L. The caller may use the optional I, I, I and I to specify what the input is expected to contain. The I must reference an B variable -that will be set to the newly created B on succesfull decoding. +that will be set to the newly created B on successful decoding. The referenced variable must be initialized to NULL before calling the function. @@ -135,7 +135,7 @@ The functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_ENCODER.pod b/deps/openssl/openssl/doc/man3/OSSL_ENCODER.pod index cfabba2e1d025f..06d8f80f881225 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_ENCODER.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_ENCODER.pod @@ -117,7 +117,7 @@ multiple synonyms associated with it. In this case the first name from the algorithm definition is returned. Ownership of the returned string is retained by the I object and should not be freed by the caller. -OSSL_ENCODER_get0_description() returns a pointer to a decription, or NULL if +OSSL_ENCODER_get0_description() returns a pointer to a description, or NULL if there isn't one. OSSL_ENCODER_names_do_all() returns 1 if the callback was called for all @@ -134,7 +134,7 @@ The functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_ENCODER_CTX.pod b/deps/openssl/openssl/doc/man3/OSSL_ENCODER_CTX.pod index 2d7a6a298f852b..7f3915fda88236 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_ENCODER_CTX.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_ENCODER_CTX.pod @@ -80,7 +80,7 @@ as DER to PEM, as well as more specialized encoders like RSA to DER. The final output type must be given, and a chain of encoders must end with an implementation that produces that output type. -At the beginning of the encoding process, a contructor provided by the +At the beginning of the encoding process, a constructor provided by the caller is called to ensure that there is an appropriate provider-side object to start with. The constructor is set with OSSL_ENCODER_CTX_set_construct(). @@ -148,7 +148,7 @@ The pointer that was set with OSSL_ENCODE_CTX_set_construct_data(). The constructor is expected to return a valid (non-NULL) pointer to a provider-native object that can be used as first input of an encoding chain, -or NULL to indicate that an error has occured. +or NULL to indicate that an error has occurred. These utility functions may be used by a constructor: @@ -211,7 +211,7 @@ The functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_ESS_check_signing_certs.pod b/deps/openssl/openssl/doc/man3/OSSL_ESS_check_signing_certs.pod index bff26193d75831..24145ead1728f8 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_ESS_check_signing_certs.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_ESS_check_signing_certs.pod @@ -46,7 +46,7 @@ while the list contained in I is of type B. As far as these lists are present, they must be nonempty. The certificate identified by their first entry must be the first element of I, i.e. the signer certificate. -Any further certficates referenced in the list must also be found in I. +Any further certificates referenced in the list must also be found in I. The matching is done using the given certificate hash algorithm and value. In addition to the checks required by RFCs 2624 and 5035, if the B field is included in an B or B @@ -78,7 +78,7 @@ OSSL_ESS_check_signing_certs() were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_HTTP_REQ_CTX.pod b/deps/openssl/openssl/doc/man3/OSSL_HTTP_REQ_CTX.pod index fbe1a152b80c25..ee61034aa731a7 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_HTTP_REQ_CTX.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_HTTP_REQ_CTX.pod @@ -133,7 +133,7 @@ The function may need to be called again if its result is -1, which indicates L. In such a case it is advisable to sleep a little in between, using L on the read BIO to prevent a busy loop. -OSSL_HTTP_REQ_CTX_nbio_d2i() is like OSSL_HTTP_REQ_CTX_nbio() but on successs +OSSL_HTTP_REQ_CTX_nbio_d2i() is like OSSL_HTTP_REQ_CTX_nbio() but on success in addition parses the response, which must be a DER-encoded ASN.1 structure, using the ASN.1 template I and places the result in I<*pval>. @@ -256,7 +256,7 @@ The functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_HTTP_parse_url.pod b/deps/openssl/openssl/doc/man3/OSSL_HTTP_parse_url.pod index 945e981a73fa14..768f0acdb14c72 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_HTTP_parse_url.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_HTTP_parse_url.pod @@ -57,7 +57,7 @@ The path component is also optional and defaults to C. Each non-NULL result pointer argument I, I, I, I, I, I, and I, is assigned the respective url component. On success, they are guaranteed to contain non-NULL string pointers, else NULL. -It is the reponsibility of the caller to free them using L. +It is the responsibility of the caller to free them using L. If I is NULL, any given query component is handled as part of the path. A string returned via I<*ppath> is guaranteed to begin with a C character. For absent scheme, userinfo, port, query, and fragment components @@ -97,7 +97,7 @@ OCSP_parse_url() was deprecated in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_PARAM.pod b/deps/openssl/openssl/doc/man3/OSSL_PARAM.pod index 3939ddc742968d..1e5bf06cf767a7 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_PARAM.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_PARAM.pod @@ -108,7 +108,7 @@ B in relation to C strings. When setting parameters, the size should be set to the length of the string, not counting the terminating NUL byte. When requesting parameters, the size should be set to the size of the buffer to be populated, which -should accomodate enough space for a terminating NUL byte. +should accommodate enough space for a terminating NUL byte. When I, it's acceptable for I to be NULL. This can be used by the I to figure out dynamically exactly diff --git a/deps/openssl/openssl/doc/man3/OSSL_PARAM_int.pod b/deps/openssl/openssl/doc/man3/OSSL_PARAM_int.pod index c03e30f839652a..d357818ff14bd9 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_PARAM_int.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_PARAM_int.pod @@ -241,7 +241,7 @@ will be assigned the size the parameter's I buffer should have. OSSL_PARAM_get_utf8_string() retrieves a UTF8 string from the parameter pointed to by I

. The string is stored into I<*val> with a size limit of I, -which must be large enough to accomodate a terminating NUL byte, +which must be large enough to accommodate a terminating NUL byte, otherwise this function will fail. If I<*val> is NULL, memory is allocated for the string (including the terminating NUL byte) and I is ignored. @@ -250,14 +250,14 @@ If memory is allocated by this function, it must be freed by the caller. OSSL_PARAM_set_utf8_string() sets a UTF8 string from the parameter pointed to by I

to the value referenced by I. If the parameter's I field isn't NULL, its I must indicate -that the buffer is large enough to accomodate the string that I points at, +that the buffer is large enough to accommodate the string that I points at, not including the terminating NUL byte, or this function will fail. A terminating NUL byte is added only if the parameter's I indicates the buffer is longer than the string length, otherwise the string will not be NUL terminated. If the parameter's I field is NULL, then only its I field will be assigned the minimum size the parameter's I buffer should have -to accomodate the string, not including a terminating NUL byte. +to accommodate the string, not including a terminating NUL byte. OSSL_PARAM_get_octet_string() retrieves an OCTET string from the parameter pointed to by I

. diff --git a/deps/openssl/openssl/doc/man3/OSSL_PROVIDER.pod b/deps/openssl/openssl/doc/man3/OSSL_PROVIDER.pod index 9710469e07f2c4..40a4ea1005725e 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_PROVIDER.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_PROVIDER.pod @@ -90,8 +90,8 @@ the environment variable OPENSSL_MODULES if set. OSSL_PROVIDER_try_load() functions like OSSL_PROVIDER_load(), except that it does not disable the fallback providers if the provider cannot be -loaded and initialized or if I is zero. -If the provider loads successfully and I is nonzero, the +loaded and initialized or if I is nonzero. +If the provider loads successfully and I is zero, the fallback providers are disabled. OSSL_PROVIDER_unload() unloads the given provider. @@ -213,7 +213,7 @@ The type and functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_SELF_TEST_new.pod b/deps/openssl/openssl/doc/man3/OSSL_SELF_TEST_new.pod index 5fe838351908b5..4c4b10fca96ad0 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_SELF_TEST_new.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_SELF_TEST_new.pod @@ -22,7 +22,7 @@ OSSL_SELF_TEST_onend - functionality to trigger a callback during a self test =head1 DESCRIPTION -These methods are intended for use by provider implementors, to display +These methods are intended for use by provider implementers, to display diagnostic information during self testing. OSSL_SELF_TEST_new() allocates an opaque B object that has a @@ -165,7 +165,7 @@ The functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_STORE_LOADER.pod b/deps/openssl/openssl/doc/man3/OSSL_STORE_LOADER.pod index b1d838604badc8..9cd016be158a9a 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_STORE_LOADER.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_STORE_LOADER.pod @@ -327,7 +327,7 @@ definition string, or NULL on error. OSSL_STORE_LOADER_is_a() returns 1 if I was identifiable, otherwise 0. -OSSL_STORE_LOADER_get0_description() returns a pointer to a decription, or NULL if +OSSL_STORE_LOADER_get0_description() returns a pointer to a description, or NULL if there isn't one. The functions with the types B, @@ -380,7 +380,7 @@ were added in OpenSSL 1.1.1, and became deprecated in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/OSSL_trace_set_channel.pod b/deps/openssl/openssl/doc/man3/OSSL_trace_set_channel.pod index 3b9c64e5412f7f..f93242643c406a 100644 --- a/deps/openssl/openssl/doc/man3/OSSL_trace_set_channel.pod +++ b/deps/openssl/openssl/doc/man3/OSSL_trace_set_channel.pod @@ -48,7 +48,7 @@ so the caller must not free it directly. OSSL_trace_set_prefix() and OSSL_trace_set_suffix() can be used to add an extra line for each channel, to be output before and after group of tracing output. -What constitues an output group is decided by the code that produces +What constitutes an output group is decided by the code that produces the output. The lines given here are considered immutable; for more dynamic tracing prefixes, consider setting a callback with diff --git a/deps/openssl/openssl/doc/man3/PKCS12_decrypt_skey.pod b/deps/openssl/openssl/doc/man3/PKCS12_decrypt_skey.pod index 7a41b2b06c2f7e..97c6823a3c746b 100644 --- a/deps/openssl/openssl/doc/man3/PKCS12_decrypt_skey.pod +++ b/deps/openssl/openssl/doc/man3/PKCS12_decrypt_skey.pod @@ -21,7 +21,7 @@ decrypt functions PKCS12_decrypt_skey() Decrypt the PKCS#8 shrouded keybag contained within I using the supplied password I of length I. -PKCS12_decrypt_skey_ex() is similar to the above but allows for a library contex +PKCS12_decrypt_skey_ex() is similar to the above but allows for a library context I and property query I to be used to select algorithm implementations. =head1 RETURN VALUES @@ -45,7 +45,7 @@ PKCS12_decrypt_skey_ex() was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/PKCS12_gen_mac.pod b/deps/openssl/openssl/doc/man3/PKCS12_gen_mac.pod index 53b55e8703030d..37bcd572d841ce 100644 --- a/deps/openssl/openssl/doc/man3/PKCS12_gen_mac.pod +++ b/deps/openssl/openssl/doc/man3/PKCS12_gen_mac.pod @@ -21,7 +21,7 @@ PKCS12_verify_mac - Functions to create and manipulate a PKCS#12 structure =head1 DESCRIPTION PKCS12_gen_mac() generates an HMAC over the entire PKCS#12 object using the -supplied password along with a set of already configured paramters. +supplied password along with a set of already configured parameters. PKCS12_verify_mac() verifies the PKCS#12 object's HMAC using the supplied password. @@ -62,7 +62,7 @@ L =head1 COPYRIGHT -Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/RAND_bytes.pod b/deps/openssl/openssl/doc/man3/RAND_bytes.pod index ee7ed4af860c81..8440a731856438 100644 --- a/deps/openssl/openssl/doc/man3/RAND_bytes.pod +++ b/deps/openssl/openssl/doc/man3/RAND_bytes.pod @@ -37,7 +37,7 @@ and L. RAND_bytes_ex() and RAND_priv_bytes_ex() are the same as RAND_bytes() and RAND_priv_bytes() except that they both take additional I and -I parameters. The bytes genreated will have a security strength of at +I parameters. The bytes generated will have a security strength of at least I bits. The DRBG used for the operation is the public or private DRBG associated with the specified I. The parameter can be NULL, in which case @@ -101,7 +101,7 @@ The RAND_bytes_ex() and RAND_priv_bytes_ex() functions were added in OpenSSL 3.0 =head1 COPYRIGHT -Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/RSA_get0_key.pod b/deps/openssl/openssl/doc/man3/RSA_get0_key.pod index 0a0f79125a3281..1c1fa5bfcda35c 100644 --- a/deps/openssl/openssl/doc/man3/RSA_get0_key.pod +++ b/deps/openssl/openssl/doc/man3/RSA_get0_key.pod @@ -54,7 +54,7 @@ see L: All of the functions described on this page are deprecated. Applications should instead use L for any methods that -return a B. Refer to L for more infomation. +return a B. Refer to L for more information. An RSA object contains the components for the public and private key, B, B, B, B

, B, B, B and B. B is @@ -184,7 +184,7 @@ All of these functions were deprecated in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/SSL_CTX_new.pod b/deps/openssl/openssl/doc/man3/SSL_CTX_new.pod index 61de1a655164ad..f467f93659b575 100644 --- a/deps/openssl/openssl/doc/man3/SSL_CTX_new.pod +++ b/deps/openssl/openssl/doc/man3/SSL_CTX_new.pod @@ -100,7 +100,7 @@ provide serialization of access for these cases. =head1 NOTES -On session estabilishment, by default, no peer credentials verification is done. +On session establishment, by default, no peer credentials verification is done. This must be explicitly requested, typically using L. For verifying peer certificates many options can be set using various functions such as L and L. @@ -249,7 +249,7 @@ SSL_CTX_new_ex() was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/SSL_CTX_set_tmp_dh_callback.pod b/deps/openssl/openssl/doc/man3/SSL_CTX_set_tmp_dh_callback.pod index 4daf78b8d3341e..0c6694d4c6a7ca 100644 --- a/deps/openssl/openssl/doc/man3/SSL_CTX_set_tmp_dh_callback.pod +++ b/deps/openssl/openssl/doc/man3/SSL_CTX_set_tmp_dh_callback.pod @@ -73,9 +73,9 @@ the built-in parameter support described above. Applications wishing to supply their own DH parameters should call SSL_CTX_set0_tmp_dh_pkey() or SSL_set0_tmp_dh_pkey() to supply the parameters for the B or B respectively. The parameters should be supplied in the I argument as -an B containg DH parameters. Ownership of the I value is +an B containing DH parameters. Ownership of the I value is passed to the B or B object as a result of this call, and so the -caller should not free it if the function call is succesful. +caller should not free it if the function call is successful. The deprecated macros SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() do the same thing as SSL_CTX_set0_tmp_dh_pkey() and SSL_set0_tmp_dh_pkey() except that the @@ -112,7 +112,7 @@ L, L =head1 COPYRIGHT -Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/SSL_get_verify_result.pod b/deps/openssl/openssl/doc/man3/SSL_get_verify_result.pod index ac37408748b25e..08c46c0576ba2b 100644 --- a/deps/openssl/openssl/doc/man3/SSL_get_verify_result.pod +++ b/deps/openssl/openssl/doc/man3/SSL_get_verify_result.pod @@ -22,6 +22,13 @@ of a certificate can fail because of many reasons at the same time. Only the last verification error that occurred during the processing is available from SSL_get_verify_result(). +Sometimes there can be a sequence of errors leading to the verification +failure as reported by SSL_get_verify_result(). +To get the errors, it is necessary to setup a verify callback via +L or L and retrieve the errors +from the error stack there, because once L returns, +these errors may no longer be available. + The verification result is part of the established session and is restored when a session is reused. @@ -56,7 +63,7 @@ L =head1 COPYRIGHT -Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/X509_STORE_CTX_new.pod b/deps/openssl/openssl/doc/man3/X509_STORE_CTX_new.pod index 2319012a98e161..c508a1d3fc1b88 100644 --- a/deps/openssl/openssl/doc/man3/X509_STORE_CTX_new.pod +++ b/deps/openssl/openssl/doc/man3/X509_STORE_CTX_new.pod @@ -177,7 +177,7 @@ administrator might only trust it for the former. An X.509 certificate extension exists that can record extended key usage information to supplement the purpose information described above. This extended mechanism is arbitrarily extensible and not well suited for a generic library API; applications that need to -validate extended key usage information in certifiates will need to define a +validate extended key usage information in certificates will need to define a custom "purpose" (see below) or supply a nondefault verification callback (L). @@ -273,7 +273,7 @@ There is no need to call X509_STORE_CTX_cleanup() explicitly since OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2009-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2009-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/deps/openssl/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod index 43c1900bca787a..4627206174a508 100644 --- a/deps/openssl/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod +++ b/deps/openssl/openssl/doc/man3/X509_VERIFY_PARAM_set_flags.pod @@ -223,7 +223,7 @@ X509_VERIFY_PARAM_set1_ip_asc() return 1 for success and 0 for failure. X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(), and -X509_VERIFY_PARAM_get1_ip_asc(), return the string pointers pecified above +X509_VERIFY_PARAM_get1_ip_asc(), return the string pointer specified above or NULL if the respective value has not been set or on error. X509_VERIFY_PARAM_get_flags() returns the current verification flags. diff --git a/deps/openssl/openssl/doc/man3/X509_add_cert.pod b/deps/openssl/openssl/doc/man3/X509_add_cert.pod index 1512d81701b8be..907164e9710ef9 100644 --- a/deps/openssl/openssl/doc/man3/X509_add_cert.pod +++ b/deps/openssl/openssl/doc/man3/X509_add_cert.pod @@ -31,7 +31,7 @@ The value B, which equals 0, means no special semantics. If B is set then the reference counts of those certificates added successfully are increased. -If B is set then the certifcates are prepended to I. +If B is set then the certificates are prepended to I. By default they are appended to I. In both cases the original order of the added certificates is preserved. @@ -66,7 +66,7 @@ were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/X509_digest.pod b/deps/openssl/openssl/doc/man3/X509_digest.pod index f4921dbc187bf5..29cce96370c69e 100644 --- a/deps/openssl/openssl/doc/man3/X509_digest.pod +++ b/deps/openssl/openssl/doc/man3/X509_digest.pod @@ -44,9 +44,9 @@ X509_digest_sig() calculates a digest of the given certificate I using the same hash algorithm as in its signature, if the digest is an integral part of the certificate signature algorithm identifier. Otherwise, a fallback hash algorithm is determined as follows: -SHA512 if the signature alorithm is ED25519, +SHA512 if the signature algorithm is ED25519, SHAKE256 if it is ED448, otherwise SHA256. -The output parmeters are assigned as follows. +The output parameters are assigned as follows. Unless I is NULL, the hash algorithm used is provided in I<*md_used> and must be freed by the caller (if it is not NULL). Unless I is NULL, @@ -81,7 +81,7 @@ The X509_digest_sig() function was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man3/X509_dup.pod b/deps/openssl/openssl/doc/man3/X509_dup.pod index 9fc355c7ce3478..1c9e4b95bc7b87 100644 --- a/deps/openssl/openssl/doc/man3/X509_dup.pod +++ b/deps/openssl/openssl/doc/man3/X509_dup.pod @@ -350,7 +350,7 @@ to generate the function bodies. B_new>() allocates an empty object of the indicated type. The object returned must be released by calling B_free>(). -B_new_ex>() is similiar to B_new>() but also passes the +B_new_ex>() is similar to B_new>() but also passes the library context I and the property query I to use when retrieving algorithms from providers. This created object can then be used when loading binary data using B>(). @@ -383,7 +383,7 @@ deprecated in 3.0. =head1 COPYRIGHT -Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man5/config.pod b/deps/openssl/openssl/doc/man5/config.pod index a78ff4dc065770..8d312c661fa099 100644 --- a/deps/openssl/openssl/doc/man5/config.pod +++ b/deps/openssl/openssl/doc/man5/config.pod @@ -415,7 +415,7 @@ For example: =head2 Random Configuration The name B in the initialization section names the section -containing the random number generater settings. +containing the random number generator settings. Within the random section, the following names have meaning: diff --git a/deps/openssl/openssl/doc/man7/EVP_PKEY-EC.pod b/deps/openssl/openssl/doc/man7/EVP_PKEY-EC.pod index 4b6dec35862c68..3b14e256721b79 100644 --- a/deps/openssl/openssl/doc/man7/EVP_PKEY-EC.pod +++ b/deps/openssl/openssl/doc/man7/EVP_PKEY-EC.pod @@ -15,7 +15,7 @@ The B keytype is implemented in OpenSSL's default provider. The normal way of specifying domain parameters for an EC curve is via the curve name "group". For curves with no curve name, explicit parameters can be used that specify "field-type", "p", "a", "b", "generator" and "order". -Explicit parameters are supported for backwards compability reasons, but they +Explicit parameters are supported for backwards compatibility reasons, but they are not compliant with multiple standards (including RFC5915) which only allow named curves. @@ -70,7 +70,7 @@ I multiplied by the I gives the number of points on the curve. =item "decoded-from-explicit" (B) -Gets a flag indicating wether the key or parameters were decoded from explicit +Gets a flag indicating whether the key or parameters were decoded from explicit curve parameters. Set to 1 if so or 0 if a named curve was used. =item "use-cofactor-flag" (B) @@ -99,7 +99,7 @@ point_conversion_forms please see L. Valid values are Sets or Gets the type of group check done when EVP_PKEY_param_check() is called. Valid values are "default", "named" and "named-nist". The "named" type checks that the domain parameters match the inbuilt curve parameters, -"named-nist" is similiar but also checks that the named curve is a nist curve. +"named-nist" is similar but also checks that the named curve is a nist curve. The "default" type does domain parameter validation for the OpenSSL default provider, but is equivalent to "named-nist" for the OpenSSL FIPS provider. diff --git a/deps/openssl/openssl/doc/man7/EVP_PKEY-RSA.pod b/deps/openssl/openssl/doc/man7/EVP_PKEY-RSA.pod index f1141a364b8616..161e9d4d71d16d 100644 --- a/deps/openssl/openssl/doc/man7/EVP_PKEY-RSA.pod +++ b/deps/openssl/openssl/doc/man7/EVP_PKEY-RSA.pod @@ -189,7 +189,7 @@ both return 1 unconditionally. For RSA keys, L conforms to the SP800-56Br1 I when the OpenSSL FIPS provider is used. The OpenSSL default provider -performs similiar tests but relaxes the keysize restrictions for backwards +performs similar tests but relaxes the keysize restrictions for backwards compatibility. For RSA keys, L is the same as diff --git a/deps/openssl/openssl/doc/man7/OSSL_PROVIDER-FIPS.pod b/deps/openssl/openssl/doc/man7/OSSL_PROVIDER-FIPS.pod index 2f34866d998bf0..66165bdb0cc3f7 100644 --- a/deps/openssl/openssl/doc/man7/OSSL_PROVIDER-FIPS.pod +++ b/deps/openssl/openssl/doc/man7/OSSL_PROVIDER-FIPS.pod @@ -408,6 +408,19 @@ A simple self test callback is shown below for illustrative purposes. return ret; } +=head1 NOTES + +Some released versions of OpenSSL do not include a validated +FIPS provider. To determine which versions have undergone +the validation process, please refer to the +L. If you +require FIPS-approved functionality, it is essential to build your FIPS +provider using one of the validated versions listed there. Normally, +it is possible to utilize a FIPS provider constructed from one of the +validated versions alongside F and F compiled from any +release within the same major release series. This flexibility enables +you to address bug fixes and CVEs that fall outside the FIPS boundary. + =head1 SEE ALSO L, @@ -417,7 +430,8 @@ L, L, L, L, -L +L, +L =head1 HISTORY diff --git a/deps/openssl/openssl/doc/man7/crypto.pod b/deps/openssl/openssl/doc/man7/crypto.pod index ea81c91d3affed..c31e10ac29a53b 100644 --- a/deps/openssl/openssl/doc/man7/crypto.pod +++ b/deps/openssl/openssl/doc/man7/crypto.pod @@ -207,7 +207,7 @@ If anything in this step fails, the next step is used as a fallback. As a fallback, try to fetch the operation type implementation from the same provider as the original L's L, still using the -propery string from the B. +property string from the B. =back diff --git a/deps/openssl/openssl/doc/man7/fips_module.pod b/deps/openssl/openssl/doc/man7/fips_module.pod index b1d67ca61b43d9..d0861a9dceccda 100644 --- a/deps/openssl/openssl/doc/man7/fips_module.pod +++ b/deps/openssl/openssl/doc/man7/fips_module.pod @@ -14,6 +14,9 @@ This guide details different ways that OpenSSL can be used in conjunction with the FIPS module. Which is the correct approach to use will depend on your own specific circumstances and what you are attempting to achieve. +For information related to installing the FIPS module see +L. + Note that the old functions FIPS_mode() and FIPS_mode_set() are no longer present so you must remove them from your application if you use them. @@ -92,7 +95,7 @@ Obviously the include file location above should match the path and name of the FIPS module config file that you installed earlier. See L. -For FIPS usage, it is recommened that the B option is +For FIPS usage, it is recommended that the B option is enabled to prevent accidental use of non-FIPS validated algorithms via broken or mistaken configuration. See L. @@ -456,9 +459,23 @@ use L. To extract the name from the B, use L. +=head1 NOTES + +Some released versions of OpenSSL do not include a validated +FIPS provider. To determine which versions have undergone +the validation process, please refer to the +L. If you +require FIPS-approved functionality, it is essential to build your FIPS +provider using one of the validated versions listed there. Normally, +it is possible to utilize a FIPS provider constructed from one of the +validated versions alongside F and F compiled from any +release within the same major release series. This flexibility enables +you to address bug fixes and CVEs that fall outside the FIPS boundary. + =head1 SEE ALSO -L, L, L +L, L, L, +L =head1 HISTORY @@ -467,7 +484,7 @@ in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man7/life_cycle-pkey.pod b/deps/openssl/openssl/doc/man7/life_cycle-pkey.pod index 6768750f481991..a9dc06b934d55f 100644 --- a/deps/openssl/openssl/doc/man7/life_cycle-pkey.pod +++ b/deps/openssl/openssl/doc/man7/life_cycle-pkey.pod @@ -22,7 +22,7 @@ This state represents the PKEY after it has been allocated. =item decapsulate This state represents the PKEY when it is ready to perform a private key decapsulation -opeartion. +operation. =item decrypt @@ -40,7 +40,7 @@ operation. =item encapsulate This state represents the PKEY when it is ready to perform a public key encapsulation -opeartion. +operation. =item encrypt @@ -703,7 +703,7 @@ The provider PKEY interface was introduced in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man7/migration_guide.pod b/deps/openssl/openssl/doc/man7/migration_guide.pod index 9eb4a031aa32f3..1847e9813cbbaf 100644 --- a/deps/openssl/openssl/doc/man7/migration_guide.pod +++ b/deps/openssl/openssl/doc/man7/migration_guide.pod @@ -130,7 +130,7 @@ New algorithms provided via engines will still work. Engine-backed keys can be loaded via custom B implementation. In this case the B objects created via L -will be concidered legacy and will continue to work. +will be considered legacy and will continue to work. To ensure the future compatibility, the engines should be turned to providers. To prefer the provider-based hardware offload, you can specify the default @@ -641,7 +641,7 @@ set up with the default library context. Use L, L, L and L if a library context is required. -All functions listed below with a I have a replacment function I +All functions listed below with a I have a replacement function I that takes B as an additional argument. Functions that have other mappings are listed along with the respective name. @@ -999,7 +999,7 @@ that refer to these categories. Any accessor that uses an ENGINE is deprecated (such as EVP_PKEY_set1_engine()). Applications using engines should instead use providers. -Before providers were added algorithms were overriden by changing the methods +Before providers were added algorithms were overridden by changing the methods used by algorithms. All these methods such as RSA_new_method() and RSA_meth_new() are now deprecated and can be replaced by using providers instead. @@ -1548,7 +1548,7 @@ See L EC_KEY_set_flags(), EC_KEY_get_flags(), EC_KEY_clear_flags() -See L which handles flags as seperate +See L which handles flags as separate parameters for B, B, B, B and diff --git a/deps/openssl/openssl/doc/man7/openssl-glossary.pod b/deps/openssl/openssl/doc/man7/openssl-glossary.pod index b112b375ac2019..54c8de93a058ba 100644 --- a/deps/openssl/openssl/doc/man7/openssl-glossary.pod +++ b/deps/openssl/openssl/doc/man7/openssl-glossary.pod @@ -12,7 +12,7 @@ openssl-glossary - An OpenSSL Glossary =item Algorithm -Cryptograpic primitives such as the SHA256 digest, or AES encryption are +Cryptographic primitives such as the SHA256 digest, or AES encryption are referred to in OpenSSL as "algorithms". There can be more than one implementation for any given algorithm available for use. @@ -45,7 +45,7 @@ L =item Default Provider -An OpenSSL Provider that contains the most commmon OpenSSL algorithm +An OpenSSL Provider that contains the most common OpenSSL algorithm implementations. It is loaded by default if no other provider is available. All the algorithm implementations in the Base Provider are also available in the Default Provider. @@ -81,7 +81,7 @@ Fetching is the process of looking through the available algorithm implementations, applying selection criteria (via a property query string), and finally choosing the implementation that will be used. -Also see Explicit Fetching and Implict Fetching. +Also see Explicit Fetching and Implicit Fetching. L @@ -221,7 +221,7 @@ This glossary was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man7/provider-kdf.pod b/deps/openssl/openssl/doc/man7/provider-kdf.pod index ad80869ebea7c3..51362a7cccdc11 100644 --- a/deps/openssl/openssl/doc/man7/provider-kdf.pod +++ b/deps/openssl/openssl/doc/man7/provider-kdf.pod @@ -198,7 +198,7 @@ Sets the mode in the associated KDF ctx. =item "pkcs5" (B) -Enables or diables the SP800-132 compliance checks. +Enables or disables the SP800-132 compliance checks. A mode of 0 enables the compliance checks. The checks performed are: @@ -349,7 +349,7 @@ The provider KDF interface was introduced in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/doc/man7/provider-object.pod b/deps/openssl/openssl/doc/man7/provider-object.pod index 1088e035510f75..022d14d768fbdb 100644 --- a/deps/openssl/openssl/doc/man7/provider-object.pod +++ b/deps/openssl/openssl/doc/man7/provider-object.pod @@ -164,7 +164,7 @@ A human readable text that describes extra details on the object. =back -When a provider-native object abtraction is used, it I contain object +When a provider-native object abstraction is used, it I contain object data in at least one form (object data I, i.e. the "data" item, or object data I, i.e. the "reference" item). Both may be present at once, in which case the OpenSSL library code that @@ -184,7 +184,7 @@ introduced in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/engines/e_loader_attic.c b/deps/openssl/openssl/engines/e_loader_attic.c index eba7ab14b8e30d..a20e04da1a5b47 100644 --- a/deps/openssl/openssl/engines/e_loader_attic.c +++ b/deps/openssl/openssl/engines/e_loader_attic.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1486,9 +1486,9 @@ static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name) * Last, check that the rest of the extension is a decimal number, at * least one digit long. */ - if (!isdigit(*p)) + if (!isdigit((unsigned char)*p)) return 0; - while (isdigit(*p)) + while (isdigit((unsigned char)*p)) p++; #ifdef __VMS diff --git a/deps/openssl/openssl/include/crypto/x509err.h b/deps/openssl/openssl/include/crypto/x509err.h index 53f567d92e249a..0a67975bd050f0 100644 --- a/deps/openssl/openssl/include/crypto/x509err.h +++ b/deps/openssl/openssl/include/crypto/x509err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/deps/openssl/openssl/include/openssl/dh.h b/deps/openssl/openssl/include/openssl/dh.h index b97871eca7faa5..6533260f20272f 100644 --- a/deps/openssl/openssl/include/openssl/dh.h +++ b/deps/openssl/openssl/include/openssl/dh.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -89,7 +89,11 @@ int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); # include # ifndef OPENSSL_DH_MAX_MODULUS_BITS -# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# ifndef OPENSSL_DH_CHECK_MAX_MODULUS_BITS +# define OPENSSL_DH_CHECK_MAX_MODULUS_BITS 32768 # endif # define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 diff --git a/deps/openssl/openssl/include/openssl/x509err.h b/deps/openssl/openssl/include/openssl/x509err.h index a56facd46bf978..34ead4b81acf89 100644 --- a/deps/openssl/openssl/include/openssl/x509err.h +++ b/deps/openssl/openssl/include/openssl/x509err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -30,6 +30,7 @@ # define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 # define X509_R_CRL_ALREADY_DELTA 127 # define X509_R_CRL_VERIFY_FAILURE 131 +# define X509_R_DUPLICATE_ATTRIBUTE 140 # define X509_R_ERROR_GETTING_MD_BY_NID 141 # define X509_R_ERROR_USING_SIGINF_SET 142 # define X509_R_IDP_MISMATCH 128 diff --git a/deps/openssl/openssl/providers/common/securitycheck.c b/deps/openssl/openssl/providers/common/securitycheck.c index 699ada7c529f30..0d3acdbe56e2ff 100644 --- a/deps/openssl/openssl/providers/common/securitycheck.c +++ b/deps/openssl/openssl/providers/common/securitycheck.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -167,17 +167,25 @@ int ossl_dsa_check_key(OSSL_LIB_CTX *ctx, const DSA *dsa, int sign) /* * For Digital signature verification DSA keys with < 112 bits of - * security strength (i.e L < 2048 bits), are still allowed for legacy - * use. The bounds given in SP800 131Ar2 - Table 2 are - * (512 <= L < 2048 and 160 <= N < 224) + * security strength, are still allowed for legacy + * use. The bounds given in SP 800-131Ar2 - Table 2 are + * (512 <= L < 2048 or 160 <= N < 224). + * + * We are a little stricter and insist that both minimums are met. + * For example a L = 256, N = 160 key *would* be allowed by SP 800-131Ar2 + * but we don't. */ - if (!sign && L < 2048) - return (L >= 512 && N >= 160 && N < 224); + if (!sign) { + if (L < 512 || N < 160) + return 0; + if (L < 2048 || N < 224) + return 1; + } /* Valid sizes for both sign and verify */ - if (L == 2048 && (N == 224 || N == 256)) + if (L == 2048 && (N == 224 || N == 256)) /* 112 bits */ return 1; - return (L == 3072 && N == 256); + return (L == 3072 && N == 256); /* 128 bits */ } # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ return 1; diff --git a/deps/openssl/openssl/providers/fips-sources.checksums b/deps/openssl/openssl/providers/fips-sources.checksums index dea6ef04e23db6..42785c33a0d2e0 100644 --- a/deps/openssl/openssl/providers/fips-sources.checksums +++ b/deps/openssl/openssl/providers/fips-sources.checksums @@ -93,7 +93,7 @@ f60f3d49b183b04bcdf9b82f7c961b8c1bcb00e68a2c1166fe9edd95a783356e crypto/bn/bn_m c6760a724d696b7209f0a71f8483fabcf4f081f7e93e2628284c32ef78f69365 crypto/bn/bn_prime.c c56ad3073108a0de21c5820a48beae2bccdbf5aa8075ec21738878222eb9adc3 crypto/bn/bn_prime.h 628419eabdb88b265823e43a7a1c88fdfecef79771180836f6089050dc9eadb1 crypto/bn/bn_rand.c -1f6e13da1d9965b341f81bc0842a987a7db9b7de0fa7f7040d49be01b92d282b crypto/bn/bn_recp.c +4df8f204c8a06de2b4395be613ca0b9943613c523586e2005876d5c7bb891c75 crypto/bn/bn_recp.c a5c5c9f99961a5a7f22a3dcdce964c8a330f822be17f08652223a20fed747d0a crypto/bn/bn_rsa_fips186_4.c 704b0b4723e5c9e9bae5f3e35f9ae8ae8dca3383929e954de9e5169845abfdb2 crypto/bn/bn_shift.c 622e90766b29e0d25f46474429aebda8eba2246835b9e85dc26da7cdbd49334f crypto/bn/bn_sqr.c @@ -109,7 +109,7 @@ c39334b70e1394e43f378ae8d31b6e6dc125e4d9181e6536d38e649c4eaadb75 crypto/buffer/ ff9be205d6d7ff00b0e64508f0eb8d9ec0415fbabc0948d26e308212b3f7b2d8 crypto/context.c c309d81ea991ddf5be4337afad2fd132169f7443c76f863349d3f3c82f3374e4 crypto/core_algorithm.c f0fd9eb38bf7f196bbb4d26ce8fdf86d0a4f9db219157e66b2c0ffefb4f42005 crypto/core_fetch.c -02670d631bf0f34cca1e3477079d7fe5de4e03c391cf3992986f44f55319597c crypto/core_namemap.c +799c84d224639c6760c5c28e0e287500a973ca6d0c3d7c1bdcd61b0da4018b3c crypto/core_namemap.c 469e2f53b5f76cd487a60d3d4c44c8fc3a6c4d08405597ba664661ba485508d3 crypto/cpuid.c 71f0fff881eb4c5505fb17662f0ea4bbff24c6858c045a013ad8f786b07da5c4 crypto/cryptlib.c 66dbfc58916709d5a6913777346083247942a8d9458ee9b2bf443f0ea4988d64 crypto/ctype.c @@ -253,7 +253,7 @@ e55a816c356b2d526bc6e40c8b81afa02576e4d44c7d7b6bbe444fb8b01aad41 crypto/modes/w 8ddbbdf43131c10dcd4428aef0eff2b1e98b0410accada0fad41a4925868beef crypto/packet.c a20bfd927d69737c86ca95d3cf636afa8cefd8fe23412d1a3897644a0da21211 crypto/param_build.c c2fe815fb3fd5efe9a6544cae55f9469063a0f6fb728361737b927f6182ae0bb crypto/param_build_set.c -06e67fdd2a308bf355c8dae2e0acd9af94f6e53d428a7d31966311eb5c0aebc1 crypto/params.c +0e4a5388a92fabbe5a540176c0b4c5ce258b78dc9168ecc2e805352a06aaf0ba crypto/params.c 4fda13f6af05d80b0ab89ec4f5813c274a21a9b4565be958a02d006236cef05c crypto/params_dup.c a0097ff2da8955fe15ba204cb54f3fd48a06f846e2b9826f507b26acf65715c3 crypto/params_from_text.c 97cb7414dc2f165d5849ee3b46cdfff0afb067729435d9c01a747e0ca41e230c crypto/ppccap.c @@ -292,9 +292,9 @@ f01af62704dbf9457e2669c3e7c1d4d740f0388faa49df93611b987a8aa2bf11 crypto/rsa/rsa 5fa59240ca885cbc0c1cd026934b226d44fc9c3fdf0c2e7e3a7bd7f4963ca2e5 crypto/self_test_core.c 05c533fde7fdba0c76103e97d881b7224c8427451b453e2f6413552996063e31 crypto/sha/asm/keccak1600-armv4.pl ca3b2b654f9a8c4bc2fa2538c1f19d17acd4a6b9e0df6a4b81df04efa697e67e crypto/sha/asm/keccak1600-armv8.pl -ef575a7fb4956cc3be4ef10a6aeaa10702eadfc92c86167880690320ce942b26 crypto/sha/asm/keccak1600-avx2.pl -f1dcf75789dfb0c5d7cd35988cb8046f60097bbaf1fbdab32a9269fa5492214c crypto/sha/asm/keccak1600-avx512.pl -63e547b100562d1142512d5b54e16efc276ecb6c743c27873dbcdd7cb917c828 crypto/sha/asm/keccak1600-avx512vl.pl +12b7acce2fba0bc0e1ca07842ec84be6a022f141c86e077abb42c864af1d8d9c crypto/sha/asm/keccak1600-avx2.pl +faf0cccb685d5abc807e08db194f847c67b940da2fc3c235c210dc31d73a5334 crypto/sha/asm/keccak1600-avx512.pl +be1e7dd9998e3f31cfa6e1b17bc198aeec584a8b76820e38f71d51b05f8a9f2a crypto/sha/asm/keccak1600-avx512vl.pl 33bdcc6f7668460c3bdf779633e43bfad62b937042a73acb007b462fc5b0a034 crypto/sha/asm/keccak1600-c64x.pl 09fc831dd39bd90a701e9b16d9e9987cc215252a22e1e0355f5da6c495fca35a crypto/sha/asm/keccak1600-mmx.pl ce4a58129e5ee3ac4c9dfec5ecc010440570ebf7bf869e3e9977f2121a64b27a crypto/sha/asm/keccak1600-ppc64.pl @@ -419,7 +419,7 @@ cbd9d7855ca3ba4240207fc025c22bbfef7411116446ff63511e336a0559bed0 include/openss 1d1697bd3e35920ff9eaec23c29472d727a7fc4d108150957f41f6f5ecf80f1a include/openssl/cryptoerr.h bbc82260cbcadd406091f39b9e3b5ea63146d9a4822623ead16fa12c43ab9fc6 include/openssl/cryptoerr_legacy.h fa3e6b6c2e6222424b9cd7005e3c5499a2334c831cd5d6a29256ce945be8cb1d include/openssl/des.h -3a57eceec58ab781d79cb0458c2251a233f45ba0ef8f414d148c55ac2dff1bc8 include/openssl/dh.h +75fba45d6fc66e3aaef216959327157613f08070935aae4a5260e740184f031f include/openssl/dh.h 836130f5a32bbdce51b97b34758ed1b03a9d06065c187418eaf323dca6adfc6d include/openssl/dherr.h 92ae2c907fd56859e3ae28a085071611be5c9245879305cdf8bad027219e64b6 include/openssl/dsa.h 276d1f6e111ba933bc708e6a0670047cbe0d0b67aabe31807abbbc231de4d8cf include/openssl/dsaerr.h @@ -492,11 +492,11 @@ e1ef8b2be828a54312d6561b37751a5b6e9d5ebdb6c3e63589728c3d8adca7dc providers/comm a8b73b10ab0100942dd2bc45f2fc9c9238b70bec0e49708ba113bc7479c8b92a providers/common/provider_err.c 9eae3e2cac89c7b63d091fdca1b6d80c5c5d52aa79c8ba4ce0158c5437ad62f3 providers/common/provider_seeding.c eec462d685dd3b4764b076a3c18ecd9dd254350a0b78ddc2f8a60587829e1ce3 providers/common/provider_util.c -ba345b0d71f74c9e3d752579e16d11cc70b4b00faa329cc674bc43dd2620e044 providers/common/securitycheck.c +5b94312727ca33e4f5c038f4caaae8417bf584cfde22df83d91f3c55c30c81ee providers/common/securitycheck.c 527eda471e26763a5fcf123b2d290234d5c836de7b8ef6eef2166ef439919d82 providers/common/securitycheck_fips.c abd5997bc33b681a4ab275978b92aebca0806a4a3f0c2f41dacf11b3b6f4e101 providers/fips/fips_entry.c 0f761a26c8fa6ad8d5a15c817afe1741352b21769b2164a2eb7dd50e1f6fe04f providers/fips/fipsprov.c -52b48aece6aa3592593c94b53326410c75efb95ac480697ce414679446b49943 providers/fips/self_test.c +5d24ba30f9cc7ca48546fb85dc285bd68590f3a604a0bd471bcb0c2a61169591 providers/fips/self_test.c f822a03138e8b83ccaa910b89d72f31691da6778bf6638181f993ec7ae1167e3 providers/fips/self_test.h d3c95c9c6cc4e3b1a5e4b2bfb2ae735a4109d763bcda7b1e9b8f9eb253f79820 providers/fips/self_test_data.inc 629f619ad055723e42624230c08430a3ef53e17ab405dc0fd35499e9ca4e389c providers/fips/self_test_kats.c diff --git a/deps/openssl/openssl/providers/fips.checksum b/deps/openssl/openssl/providers/fips.checksum index 077e225c6d9309..ec1978c7fedec1 100644 --- a/deps/openssl/openssl/providers/fips.checksum +++ b/deps/openssl/openssl/providers/fips.checksum @@ -1 +1 @@ -d4b8aaf04173ffd7bdd7d64e823002a988146d85c193a4bb8217dc8225583169 providers/fips-sources.checksums +f07990ec634ec6ea3c8c42a664768debcf92a1b0c39bde7041c24df33dd7f052 providers/fips-sources.checksums diff --git a/deps/openssl/openssl/providers/fips/self_test.c b/deps/openssl/openssl/providers/fips/self_test.c index 80d048a847b081..ca5b3b585bd31a 100644 --- a/deps/openssl/openssl/providers/fips/self_test.c +++ b/deps/openssl/openssl/providers/fips/self_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,6 +16,7 @@ #include #include #include "e_os.h" +#include "internal/tsan_assist.h" #include "prov/providercommon.h" /* @@ -47,7 +48,6 @@ static int FIPS_conditional_error_check = 1; static CRYPTO_RWLOCK *self_test_lock = NULL; -static CRYPTO_RWLOCK *fips_state_lock = NULL; static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS }; static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT; @@ -59,7 +59,6 @@ DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init) * platform then we just leak it deliberately. */ self_test_lock = CRYPTO_THREAD_lock_new(); - fips_state_lock = CRYPTO_THREAD_lock_new(); return self_test_lock != NULL; } @@ -155,12 +154,12 @@ void __TERM__cleanup(void) { # define DEP_INITIAL_STATE FIPS_STATE_SELFTEST #endif -static int FIPS_state = DEP_INITIAL_STATE; +static TSAN_QUALIFIER int FIPS_state = DEP_INITIAL_STATE; #if defined(DEP_INIT_ATTRIBUTE) DEP_INIT_ATTRIBUTE void init(void) { - FIPS_state = FIPS_STATE_SELFTEST; + tsan_store(&FIPS_state, FIPS_STATE_SELFTEST); } #endif @@ -168,7 +167,6 @@ DEP_INIT_ATTRIBUTE void init(void) DEP_FINI_ATTRIBUTE void cleanup(void) { CRYPTO_THREAD_lock_free(self_test_lock); - CRYPTO_THREAD_lock_free(fips_state_lock); } #endif @@ -229,10 +227,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex static void set_fips_state(int state) { - if (ossl_assert(CRYPTO_THREAD_write_lock(fips_state_lock) != 0)) { - FIPS_state = state; - CRYPTO_THREAD_unlock(fips_state_lock); - } + tsan_store(&FIPS_state, state); } /* This API is triggered either on loading of the FIPS module or on demand */ @@ -250,10 +245,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init)) return 0; - if (!CRYPTO_THREAD_read_lock(fips_state_lock)) - return 0; - loclstate = FIPS_state; - CRYPTO_THREAD_unlock(fips_state_lock); + loclstate = tsan_load(&FIPS_state); if (loclstate == FIPS_STATE_RUNNING) { if (!on_demand_test) @@ -265,24 +257,17 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) if (!CRYPTO_THREAD_write_lock(self_test_lock)) return 0; - if (!CRYPTO_THREAD_read_lock(fips_state_lock)) { - CRYPTO_THREAD_unlock(self_test_lock); - return 0; - } - if (FIPS_state == FIPS_STATE_RUNNING) { - CRYPTO_THREAD_unlock(fips_state_lock); + loclstate = tsan_load(&FIPS_state); + if (loclstate == FIPS_STATE_RUNNING) { if (!on_demand_test) { CRYPTO_THREAD_unlock(self_test_lock); return 1; } set_fips_state(FIPS_STATE_SELFTEST); - } else if (FIPS_state != FIPS_STATE_SELFTEST) { - CRYPTO_THREAD_unlock(fips_state_lock); + } else if (loclstate != FIPS_STATE_SELFTEST) { CRYPTO_THREAD_unlock(self_test_lock); ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE); return 0; - } else { - CRYPTO_THREAD_unlock(fips_state_lock); } if (st == NULL @@ -393,20 +378,13 @@ void ossl_set_error_state(const char *type) int ossl_prov_is_running(void) { - int res; - static unsigned int rate_limit = 0; + int res, loclstate; + static TSAN_QUALIFIER unsigned int rate_limit = 0; - if (!CRYPTO_THREAD_read_lock(fips_state_lock)) - return 0; - res = FIPS_state == FIPS_STATE_RUNNING - || FIPS_state == FIPS_STATE_SELFTEST; - if (FIPS_state == FIPS_STATE_ERROR) { - CRYPTO_THREAD_unlock(fips_state_lock); - if (!CRYPTO_THREAD_write_lock(fips_state_lock)) - return 0; - if (rate_limit++ < FIPS_ERROR_REPORTING_RATE_LIMIT) + loclstate = tsan_load(&FIPS_state); + res = loclstate == FIPS_STATE_RUNNING || loclstate == FIPS_STATE_SELFTEST; + if (loclstate == FIPS_STATE_ERROR) + if (tsan_counter(&rate_limit) < FIPS_ERROR_REPORTING_RATE_LIMIT) ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE); - } - CRYPTO_THREAD_unlock(fips_state_lock); return res; } diff --git a/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_siv.c b/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_siv.c index 45010b90db2af8..bdc896e8f7e403 100644 --- a/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_siv.c +++ b/deps/openssl/openssl/providers/implementations/ciphers/cipher_aes_siv.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -120,14 +120,18 @@ static int siv_cipher(void *vctx, unsigned char *out, size_t *outl, if (!ossl_prov_is_running()) return 0; - if (inl == 0) { - *outl = 0; - return 1; - } + /* Ignore just empty encryption/decryption call and not AAD. */ + if (out != NULL) { + if (inl == 0) { + if (outl != NULL) + *outl = 0; + return 1; + } - if (outsize < inl) { - ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); - return 0; + if (outsize < inl) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } } if (ctx->hw->cipher(ctx, out, in, inl) <= 0) diff --git a/deps/openssl/openssl/providers/implementations/ciphers/cipher_rc4_hmac_md5.h b/deps/openssl/openssl/providers/implementations/ciphers/cipher_rc4_hmac_md5.h index 1697aabbf39bcb..4a1d154a7ceb1c 100644 --- a/deps/openssl/openssl/providers/implementations/ciphers/cipher_rc4_hmac_md5.h +++ b/deps/openssl/openssl/providers/implementations/ciphers/cipher_rc4_hmac_md5.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,3 +31,6 @@ typedef struct prov_cipher_hw_rc4_hmac_md5_st { } PROV_CIPHER_HW_RC4_HMAC_MD5; const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc4_hmac_md5(size_t keybits); + +void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, + MD5_CTX *ctx, const void *inp, size_t blocks); diff --git a/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c b/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c index 6d6312659beac1..bb8b2ab8625a1e 100644 --- a/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c +++ b/deps/openssl/openssl/providers/implementations/storemgmt/file_store.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -612,9 +612,9 @@ static int file_name_check(struct file_ctx_st *ctx, const char *name) * Last, check that the rest of the extension is a decimal number, at * least one digit long. */ - if (!isdigit(*p)) + if (!isdigit((unsigned char)*p)) return 0; - while (isdigit(*p)) + while (isdigit((unsigned char)*p)) p++; #ifdef __VMS @@ -623,7 +623,7 @@ static int file_name_check(struct file_ctx_st *ctx, const char *name) */ if (*p == ';') for (p++; *p != '\0'; p++) - if (!ossl_isdigit(*p)) + if (!ossl_isdigit((unsigned char)*p)) break; #endif diff --git a/deps/openssl/openssl/ssl/statem/extensions.c b/deps/openssl/openssl/ssl/statem/extensions.c index 2f8b80fb6f8891..d686bd6dba8a9b 100644 --- a/deps/openssl/openssl/ssl/statem/extensions.c +++ b/deps/openssl/openssl/ssl/statem/extensions.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1420,7 +1420,11 @@ static int final_key_share(SSL *s, unsigned int context, int sent) group_id = pgroups[i]; if (check_in_list(s, group_id, clntgroups, clnt_num_groups, - 1)) + 1) + && tls_group_allowed(s, group_id, + SSL_SECOP_CURVE_SUPPORTED) + && tls_valid_group(s, group_id, TLS1_3_VERSION, + TLS1_3_VERSION, 0, NULL)) break; } diff --git a/deps/openssl/openssl/ssl/statem/statem_lib.c b/deps/openssl/openssl/ssl/statem/statem_lib.c index 8053bbc86b69fb..cb31835265ff76 100644 --- a/deps/openssl/openssl/ssl/statem/statem_lib.c +++ b/deps/openssl/openssl/ssl/statem/statem_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -67,7 +67,8 @@ int ssl3_do_write(SSL *s, int type) #endif ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], s->init_num, &written); - if (ret < 0) + + if (ret <= 0) return -1; if (type == SSL3_RT_HANDSHAKE) /* diff --git a/deps/openssl/openssl/ssl/t1_lib.c b/deps/openssl/openssl/ssl/t1_lib.c index e6f4bcc04533ce..8be00a4f340598 100644 --- a/deps/openssl/openssl/ssl/t1_lib.c +++ b/deps/openssl/openssl/ssl/t1_lib.c @@ -23,6 +23,7 @@ #include "internal/nelem.h" #include "internal/sizes.h" #include "internal/tlsgroups.h" +#include "internal/cryptlib.h" #include "ssl_local.h" #include @@ -600,6 +601,7 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) const uint16_t *pref, *supp; size_t num_pref, num_supp, i; int k; + SSL_CTX *ctx = s->ctx; /* Can't do anything on client side */ if (s->server == 0) @@ -636,10 +638,29 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) for (k = 0, i = 0; i < num_pref; i++) { uint16_t id = pref[i]; + const TLS_GROUP_INFO *inf; if (!tls1_in_list(id, supp, num_supp) - || !tls_group_allowed(s, id, SSL_SECOP_CURVE_SHARED)) - continue; + || !tls_group_allowed(s, id, SSL_SECOP_CURVE_SHARED)) + continue; + inf = tls1_group_id_lookup(ctx, id); + if (!ossl_assert(inf != NULL)) + return 0; + if (SSL_IS_DTLS(s)) { + if (inf->maxdtls == -1) + continue; + if ((inf->mindtls != 0 && DTLS_VERSION_LT(s->version, inf->mindtls)) + || (inf->maxdtls != 0 + && DTLS_VERSION_GT(s->version, inf->maxdtls))) + continue; + } else { + if (inf->maxtls == -1) + continue; + if ((inf->mintls != 0 && s->version < inf->mintls) + || (inf->maxtls != 0 && s->version > inf->maxtls)) + continue; + } + if (nmatch == k) return id; k++; diff --git a/deps/openssl/openssl/test/build.info b/deps/openssl/openssl/test/build.info index a5c1c65ddd03e8..75846e05acbc01 100644 --- a/deps/openssl/openssl/test/build.info +++ b/deps/openssl/openssl/test/build.info @@ -41,8 +41,6 @@ IF[{- !$disabled{tests} -}] evp_pkey_provided_test evp_test evp_extra_test evp_extra_test2 \ evp_fetch_prov_test evp_libctx_test ossl_store_test \ v3nametest v3ext punycode_test \ - evp_pkey_provided_test evp_test evp_extra_test evp_extra_test2 \ - evp_fetch_prov_test v3nametest v3ext \ crltest danetest bad_dtls_test lhash_test sparse_array_test \ conf_include_test params_api_test params_conversion_test \ constant_time_test verify_extra_test clienthellotest \ diff --git a/deps/openssl/openssl/test/certs/sm2-pub.key b/deps/openssl/openssl/test/certs/sm2-pub.key new file mode 100644 index 00000000000000..ecb6b5c2d68e77 --- /dev/null +++ b/deps/openssl/openssl/test/certs/sm2-pub.key @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEMKnjZFqe34rtSmZ7g5ALnKTPKYhM +xEy9cpq3Kzgb7/JoTTZHm9tGrG1oBUCNszq0jPff7Fxp/azNv7rDPzJXGg== +-----END PUBLIC KEY----- diff --git a/deps/openssl/openssl/test/dhtest.c b/deps/openssl/openssl/test/dhtest.c index 7b587f3cfa8fad..000dd5b6980572 100644 --- a/deps/openssl/openssl/test/dhtest.c +++ b/deps/openssl/openssl/test/dhtest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -73,7 +73,7 @@ static int dh_test(void) goto err1; /* check fails, because p is way too small */ - if (!DH_check(dh, &i)) + if (!TEST_true(DH_check(dh, &i))) goto err2; i ^= DH_MODULUS_TOO_SMALL; if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) @@ -124,6 +124,29 @@ static int dh_test(void) /* We'll have a stale error on the queue from the above test so clear it */ ERR_clear_error(); + if (!TEST_ptr(BN_copy(q, p)) || !TEST_true(BN_add(q, q, BN_value_one()))) + goto err3; + + if (!TEST_true(DH_check(dh, &i))) + goto err3; + if (!TEST_true(i & DH_CHECK_INVALID_Q_VALUE) + || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)) + goto err3; + + /* Modulus of size: dh check max modulus bits + 1 */ + if (!TEST_true(BN_set_word(p, 1)) + || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS))) + goto err3; + + /* + * We expect no checks at all for an excessively large modulus + */ + if (!TEST_false(DH_check(dh, &i))) + goto err3; + + /* We'll have a stale error on the queue from the above test so clear it */ + ERR_clear_error(); + /* * II) key generation */ @@ -138,7 +161,7 @@ static int dh_test(void) goto err3; /* ... and check whether it is valid */ - if (!DH_check(a, &i)) + if (!TEST_true(DH_check(a, &i))) goto err3; if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME) diff --git a/deps/openssl/openssl/test/evp_test.c b/deps/openssl/openssl/test/evp_test.c index 19cabd6dce1425..c781f65b3ed177 100644 --- a/deps/openssl/openssl/test/evp_test.c +++ b/deps/openssl/openssl/test/evp_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -3683,11 +3683,11 @@ static int prov_available(char *providers) int more = 1; while (more) { - for (; isspace(*providers); providers++) + for (; isspace((unsigned char)(*providers)); providers++) continue; if (*providers == '\0') break; /* End of the road */ - for (p = providers; *p != '\0' && !isspace(*p); p++) + for (p = providers; *p != '\0' && !isspace((unsigned char)(*p)); p++) continue; if (*p == '\0') more = 0; diff --git a/deps/openssl/openssl/test/helpers/ssltestlib.c b/deps/openssl/openssl/test/helpers/ssltestlib.c index 02e9c27e5ffcc8..ef4a6177aa7ddc 100644 --- a/deps/openssl/openssl/test/helpers/ssltestlib.c +++ b/deps/openssl/openssl/test/helpers/ssltestlib.c @@ -42,6 +42,7 @@ static int tls_dump_puts(BIO *bp, const char *str); static BIO_METHOD *method_tls_dump = NULL; static BIO_METHOD *meth_mem = NULL; static BIO_METHOD *meth_always_retry = NULL; +static int retry_err = -1; /* Note: Not thread safe! */ const BIO_METHOD *bio_f_tls_dump_filter(void) @@ -760,16 +761,21 @@ static int always_retry_free(BIO *bio) return 1; } +void set_always_retry_err_val(int err) +{ + retry_err = err; +} + static int always_retry_read(BIO *bio, char *out, int outl) { BIO_set_retry_read(bio); - return -1; + return retry_err; } static int always_retry_write(BIO *bio, const char *in, int inl) { BIO_set_retry_write(bio); - return -1; + return retry_err; } static long always_retry_ctrl(BIO *bio, int cmd, long num, void *ptr) @@ -795,13 +801,13 @@ static long always_retry_ctrl(BIO *bio, int cmd, long num, void *ptr) static int always_retry_gets(BIO *bio, char *buf, int size) { BIO_set_retry_read(bio); - return -1; + return retry_err; } static int always_retry_puts(BIO *bio, const char *str) { BIO_set_retry_write(bio); - return -1; + return retry_err; } int create_ssl_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, diff --git a/deps/openssl/openssl/test/helpers/ssltestlib.h b/deps/openssl/openssl/test/helpers/ssltestlib.h index 50ae27995009bb..8e9daa5601d3ea 100644 --- a/deps/openssl/openssl/test/helpers/ssltestlib.h +++ b/deps/openssl/openssl/test/helpers/ssltestlib.h @@ -35,6 +35,7 @@ void bio_s_mempacket_test_free(void); const BIO_METHOD *bio_s_always_retry(void); void bio_s_always_retry_free(void); +void set_always_retry_err_val(int err); /* Packet types - value 0 is reserved */ #define INJECT_PACKET 1 diff --git a/deps/openssl/openssl/test/recipes/20-test_cli_fips.t b/deps/openssl/openssl/test/recipes/20-test_cli_fips.t index 6d3c5ba1bb01c5..d4b4d4ca51c68f 100644 --- a/deps/openssl/openssl/test/recipes/20-test_cli_fips.t +++ b/deps/openssl/openssl/test/recipes/20-test_cli_fips.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -109,65 +109,70 @@ sub tsignverify { $ENV{OPENSSL_CONF} = $defaultconf; - $sigfile = $nonfips_sigfile; - $testtext = $prefix.': '. - 'Sign something with a non-FIPS key'. - ' with the default provider'; - ok(run(app(['openssl', 'dgst', '-sha256', - '-sign', $nonfips_key, - '-out', $sigfile, - $tbs_data])), - $testtext); + SKIP : { + skip "FIPS failure testing", 6 + if ($nonfips_key eq ''); + + $sigfile = $nonfips_sigfile; + $testtext = $prefix.': '. + 'Sign something with a non-FIPS key'. + ' with the default provider'; + ok(run(app(['openssl', 'dgst', '-sha256', + '-sign', $nonfips_key, + '-out', $sigfile, + $tbs_data])), + $testtext); - $testtext = $prefix.': '. - 'Verify something with a non-FIPS key'. - ' with the default provider'; - ok(run(app(['openssl', 'dgst', '-sha256', - '-verify', $nonfips_pub_key, - '-signature', $sigfile, - $tbs_data])), - $testtext); + $testtext = $prefix.': '. + 'Verify something with a non-FIPS key'. + ' with the default provider'; + ok(run(app(['openssl', 'dgst', '-sha256', + '-verify', $nonfips_pub_key, + '-signature', $sigfile, + $tbs_data])), + $testtext); - $ENV{OPENSSL_CONF} = $fipsconf; + $ENV{OPENSSL_CONF} = $fipsconf; - $testtext = $prefix.': '. - 'Sign something with a non-FIPS key'. - ' (should fail)'; - ok(!run(app(['openssl', 'dgst', '-sha256', - '-sign', $nonfips_key, - '-out', $prefix.'.nonfips.fail.sig', - $tbs_data])), - $testtext); + $testtext = $prefix.': '. + 'Sign something with a non-FIPS key'. + ' (should fail)'; + ok(!run(app(['openssl', 'dgst', '-sha256', + '-sign', $nonfips_key, + '-out', $prefix.'.nonfips.fail.sig', + $tbs_data])), + $testtext); - $testtext = $prefix.': '. - 'Verify something with a non-FIPS key'. - ' (should fail)'; - ok(!run(app(['openssl', 'dgst', '-sha256', - '-verify', $nonfips_pub_key, - '-signature', $sigfile, - $tbs_data])), - $testtext); + $testtext = $prefix.': '. + 'Verify something with a non-FIPS key'. + ' (should fail)'; + ok(!run(app(['openssl', 'dgst', '-sha256', + '-verify', $nonfips_pub_key, + '-signature', $sigfile, + $tbs_data])), + $testtext); - $testtext = $prefix.': '. - 'Verify something with a non-FIPS key'. - ' in FIPS mode but with a non-FIPS property query'; - ok(run(app(['openssl', 'dgst', - '-provider', 'default', - '-propquery', '?fips!=yes', - '-sha256', - '-verify', $nonfips_pub_key, - '-signature', $sigfile, - $tbs_data])), - $testtext); + $testtext = $prefix.': '. + 'Verify something with a non-FIPS key'. + ' in FIPS mode but with a non-FIPS property query'; + ok(run(app(['openssl', 'dgst', + '-provider', 'default', + '-propquery', '?fips!=yes', + '-sha256', + '-verify', $nonfips_pub_key, + '-signature', $sigfile, + $tbs_data])), + $testtext); - $testtext = $prefix.': '. - 'Verify a valid signature against the wrong data with a non-FIPS key'. - ' (should fail)'; - ok(!run(app(['openssl', 'dgst', '-sha256', - '-verify', $nonfips_pub_key, - '-signature', $sigfile, - $bogus_data])), - $testtext); + $testtext = $prefix.': '. + 'Verify a valid signature against the wrong data with a non-FIPS key'. + ' (should fail)'; + ok(!run(app(['openssl', 'dgst', '-sha256', + '-verify', $nonfips_pub_key, + '-signature', $sigfile, + $bogus_data])), + $testtext); + } } SKIP : { @@ -395,7 +400,6 @@ SKIP : { '-out', $testtext_prefix.'.fail.priv.pem'])), $testtext); - tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key, - $nonfips_pub_key); + tsignverify($testtext_prefix, $fips_key, $fips_pub_key, '', ''); }; } diff --git a/deps/openssl/openssl/test/recipes/20-test_pkeyutl.t b/deps/openssl/openssl/test/recipes/20-test_pkeyutl.t index 5492baa551389b..2c9540b70f935f 100644 --- a/deps/openssl/openssl/test/recipes/20-test_pkeyutl.t +++ b/deps/openssl/openssl/test/recipes/20-test_pkeyutl.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -13,15 +13,16 @@ use File::Spec; use File::Basename; use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips/; use OpenSSL::Test::Utils; +use File::Compare qw/compare_text/; setup("test_pkeyutl"); -plan tests => 12; +plan tests => 14; # For the tests below we use the cert itself as the TBS file SKIP: { - skip "Skipping tests that require EC, SM2 or SM3", 2 + skip "Skipping tests that require EC, SM2 or SM3", 4 if disabled("ec") || disabled("sm2") || disabled("sm3"); # SM2 @@ -38,6 +39,18 @@ SKIP: { '-sigfile', 'sm2.sig', '-rawin', '-digest', 'sm3', '-pkeyopt', 'distid:someid']))), "Verify an SM2 signature against a piece of data"); + ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-encrypt', + '-in', srctop_file('test', 'data2.bin'), + '-inkey', srctop_file('test', 'certs', 'sm2-pub.key'), + '-pubin', '-out', 'sm2.enc']))), + "Encrypt a piece of data using SM2"); + ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-decrypt', + '-in', 'sm2.enc', + '-inkey', srctop_file('test', 'certs', 'sm2.key'), + '-out', 'sm2.dat']))) + && compare_text('sm2.dat', + srctop_file('test', 'data2.bin')) == 0, + "Decrypt a piece of data using SM2"); } SKIP: { diff --git a/deps/openssl/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt b/deps/openssl/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt index a78a49158d5159..ab7f2b6f6aa28a 100644 --- a/deps/openssl/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt +++ b/deps/openssl/openssl/test/recipes/30-test_evp_data/evpciph_aes_siv.txt @@ -1,5 +1,5 @@ # -# Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,19 @@ Tag = 85632d07c6e8f37f950acd320a2ecc93 Plaintext = 112233445566778899aabbccddee Ciphertext = 40c02b9690c4dc04daef7f6afe5c +Cipher = aes-128-siv +Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +Tag = f1c5fdeac1f15a26779c1501f9fb7588 +Plaintext = 112233445566778899aabbccddee +Ciphertext = 27e946c669088ab06da58c5c831c + +Cipher = aes-128-siv +Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff +AAD = +Tag = d1022f5b3664e5a4dfaf90f85be6f28a +Plaintext = 112233445566778899aabbccddee +Ciphertext = b66cff6b8eca0b79f083b39a0901 + Cipher = aes-128-siv Key = 7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f AAD = 00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100 @@ -29,6 +42,24 @@ Tag = 7bdb6e3b432667eb06f4d14bff2fbd0f Plaintext = 7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553 Ciphertext = cb900f2fddbe404326601965c889bf17dba77ceb094fa663b7a3f748ba8af829ea64ad544a272e9c485b62a3fd5c0d +Cipher = aes-128-siv +Key = 7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f +AAD = 00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100 +AAD = +AAD = 09f911029d74e35bd84156c5635688c0 +Tag = 83ce6593a8fa67eb6fcd2819cedfc011 +Plaintext = 7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553 +Ciphertext = 30d937b42f71f71f93fc2d8d702d3eac8dc7651eefcd81120081ff29d626f97f3de17f2969b691c91b69b652bf3a6d + +Cipher = aes-128-siv +Key = 7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f +AAD = +AAD = 00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100 +AAD = 09f911029d74e35bd84156c5635688c0 +Tag = 77dd4a44f5a6b41302121ee7f378de25 +Plaintext = 7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553 +Ciphertext = 0fcd664c922464c88939d71fad7aefb864e501b0848a07d39201c1067a7288f3dadf0131a823a0bc3d588e8564a5fe + Cipher = aes-192-siv Key = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfefffffefdfcfbfaf9f8f7f6f5f4f3f2f1f0 AAD = 101112131415161718191a1b1c1d1e1f2021222324252627 diff --git a/deps/openssl/openssl/test/recipes/30-test_evp_data/evppkey_dsa.txt b/deps/openssl/openssl/test/recipes/30-test_evp_data/evppkey_dsa.txt index 8e3743b9fd7bf9..debd62bca84cbc 100644 --- a/deps/openssl/openssl/test/recipes/30-test_evp_data/evppkey_dsa.txt +++ b/deps/openssl/openssl/test/recipes/30-test_evp_data/evppkey_dsa.txt @@ -1,5 +1,5 @@ # -# Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2001-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -142,6 +142,23 @@ Kr2KShQB0FlSgvcCDTX7g8eJ/UuIWo6wX4hSdHDhBB4CHAdVVg1m5ikOICUBo37Y /TqkTaCFsMDwcDc20Jg= -----END PRIVATE KEY----- +PrivateKey = DSA-2048-160 +-----BEGIN PRIVATE KEY----- +MIICTAIBADCCAi0GByqGSM44BAEwggIgAoIBAQCOypCJyAO7uNZSPSNGalSkyjQC +xdFVIGfMJKjEXzJnH4g3ts0UqUyO8126REDJEXDeMi22841xsSvzz0ZJeT5YvMLW +t1BtSTiYg2QOar1qEGJunHgjsWKJbVzIqWNw60ZP7pNKmlR7PKa3WDaPhdeVP8zJ +PEMeUHOSprO5Jk/Hjr8jxV0znIIixb9L9PgJAwxiM7rkRHS2Oz1FCYDmNmuFhQDh +Cb3wY9t1AcAHZ05uZ4PtNjdRPwFLPeVdckPj0ntApvOrH18xPWBmwcVeHAH1SV2k +7LPK7wILHVzcKm74ubX/s1wKysyyXyKM+oCgG9jvfh09VQJcHTHaVS643ohZAhUA +uQMLDZqMQbh9TYlm9xYCEBaeVs0CggEAcum3PgEQIRfukytMQ7gKMyfxHqhMmJ6t +RolRhgMrSfl99dmMoqJV+sdSjYvZSkwl71N1Y4Al8GcJB1SzTSb8qGRzM+43pa4k +SyQZ62WA8w5gaIQJ85JUrWiT8C6SgwAbruS5BVHRbQD6FxZwro9+s8uPnLesMTQX +p4maNSQaqYX7tqGl6Z7Wo0PsEwuDRvBlI6sl97gl4q3FQPByCq/64UW/eF6Illo1 +dpfbiWCszsp8oczXCEuP+2Y67WUIj3LjFA7WM/R8K4SfdMQ/VXY/cyRhlUqQl8Qe +ndBVKe0IeSdqvMcLNoUip7DGcOXW2ogZl+wgeP4xL3pdo8uS025kjwQWAhRfutAE +r/MlbdGMvcA7l0XmzzY85w== +-----END PRIVATE KEY----- + PrivateKey = DSA-2048-224 -----BEGIN PRIVATE KEY----- MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQDVjuiHR3XA9yAjToNQOmdg2rN9 @@ -249,9 +266,16 @@ bDfJavyQoCWW6EF260m2+rWtl6ILGhhWIbDN5KfXBhrOPvxvHQQiAiBZM1KxUjGw h2C/91Z0b0Xg4QYNOtVUbfqQTJQAqEpaRg== -----END PRIVATE KEY----- - Title = FIPS Tests (using different key sizes and digests) +# Test sign with a 2048 bit key with N == 160 is not allowed in fips mode +Availablein = fips +DigestSign = SHA256 +Key = DSA-2048-160 +Input = "Hello" +Output = 00 +Result = DIGESTSIGNINIT_ERROR + # Test sign with a 2048 bit key with N == 224 is allowed in fips mode DigestSign = SHA256 Key = DSA-2048-224 @@ -289,6 +313,13 @@ Key = DSA-1024 Input = "Hello " Output = 302c0214602d21ed37e46051bb3d06cc002adddeb4cdb3bd02144f39f75587b286588862d06366b2f29bddaf8cf6 +# Test verify with a 2048/160 bit key is allowed in fips mode +FIPSversion = >3.1.1 +DigestVerify = SHA256 +Key = DSA-2048-160 +Input = "Hello" +Output = 302e021500a51ca7f70ae206f221dc9b805bb04bfc07d6e448021500b16e45f9dac8aff04e115f96c00f4237d0fced41 + Title = Fips Negative Tests (using different key sizes and digests) # Test sign with a 1024 bit key is not allowed in fips mode diff --git a/deps/openssl/openssl/test/recipes/70-test_tls13hrr.t b/deps/openssl/openssl/test/recipes/70-test_tls13hrr.t index faf7302e424097..9d0694c3d6ecd1 100644 --- a/deps/openssl/openssl/test/recipes/70-test_tls13hrr.t +++ b/deps/openssl/openssl/test/recipes/70-test_tls13hrr.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -38,7 +38,8 @@ my $proxy = TLSProxy::Proxy->new( use constant { CHANGE_HRR_CIPHERSUITE => 0, CHANGE_CH1_CIPHERSUITE => 1, - DUPLICATE_HRR => 2 + DUPLICATE_HRR => 2, + INVALID_GROUP => 3 }; #Test 1: A client should fail if the server changes the ciphersuite between the @@ -51,7 +52,7 @@ if (disabled("ec")) { } my $testtype = CHANGE_HRR_CIPHERSUITE; $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 3; +plan tests => 4; ok(TLSProxy::Message->fail(), "Server ciphersuite changes"); #Test 2: It is an error if the client changes the offered ciphersuites so that @@ -80,6 +81,24 @@ $testtype = DUPLICATE_HRR; $proxy->start(); ok($fatal_alert, "Server duplicated HRR"); +#Test 4: If the client sends a group that is in the supported_groups list but +# otherwise not valid (e.g. not suitable for TLSv1.3) we should reject it +# and not consider it when sending the HRR. We send brainpoolP512r1 in +# the ClientHello, which is acceptable to the server but is not valid in +# TLSv1.3. We expect the server to select X25519 in the HRR and the +# handshake to complete successfully +SKIP: { + skip "EC/TLSv1.2 is disabled in this build", 1 + if disabled("ec") || disabled("tls1_2"); + + $proxy->clear(); + $proxy->clientflags("-groups P-256:brainpoolP512r1:X25519"); + $proxy->serverflags("-groups brainpoolP512r1:X25519"); + $testtype = INVALID_GROUP; + $proxy->start(); + ok(TLSProxy::Message->success(), "Invalid group with HRR"); +} + sub hrr_filter { my $proxy = shift; @@ -133,16 +152,25 @@ sub hrr_filter return; } - # CHANGE_CH1_CIPHERSUITE if ($proxy->flight != 0) { return; } my $ch1 = ${$proxy->message_list}[0]; - # The server will always pick TLS_AES_256_GCM_SHA384 - my @ciphersuites = (TLSProxy::Message::CIPHER_TLS13_AES_128_GCM_SHA256); - $ch1->ciphersuite_len(2 * scalar @ciphersuites); - $ch1->ciphersuites(\@ciphersuites); + if ($testtype == CHANGE_CH1_CIPHERSUITE) { + # The server will always pick TLS_AES_256_GCM_SHA384 + my @ciphersuites = (TLSProxy::Message::CIPHER_TLS13_AES_128_GCM_SHA256); + $ch1->ciphersuite_len(2 * scalar @ciphersuites); + $ch1->ciphersuites(\@ciphersuites); + } elsif ($testtype == INVALID_GROUP) { + # INVALID_GROUP + my $ext = pack "C7", + 0x00, 0x05, #List Length + 0x00, 0x1c, #brainpoolP512r1 (not compatible with TLSv1.3) + 0x00, 0x01, 0xff; #key_exchange data + $ch1->set_extension( + TLSProxy::Message::EXT_KEY_SHARE, $ext); + } $ch1->repack(); } diff --git a/deps/openssl/openssl/test/recipes/90-test_store_cases.t b/deps/openssl/openssl/test/recipes/90-test_store_cases.t new file mode 100644 index 00000000000000..05b00e6b4eb13f --- /dev/null +++ b/deps/openssl/openssl/test/recipes/90-test_store_cases.t @@ -0,0 +1,36 @@ +#! /usr/bin/env perl +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# This collects specific use cases, and tests our handling + +use File::Spec::Functions; +use File::Copy; +use MIME::Base64; +use OpenSSL::Test qw(:DEFAULT srctop_file srctop_dir bldtop_file bldtop_dir + data_file); +use OpenSSL::Test::Utils; + +my $test_name = "test_store_cases"; +setup($test_name); + +plan tests => 2; + +my $stderr; + +# The case of the garbage PKCS#12 DER file where a passphrase was +# prompted for. That should not have happened. +$stderr = 'garbage-pkcs12.stderr.txt'; +ok(!run(app(['openssl', 'storeutl', '-passin', 'pass:invalidapass', + data_file('garbage-pkcs12.p12')], + stderr => $stderr)), + "checking that storeutl fails when given a garbage pkcs12 file"); +open DATA, $stderr; +@match = grep /try_pkcs12:.*?:maybe wrong password$/, ; +close DATA; +ok(scalar @match > 0 ? 0 : 1, + "checking that storeutl didn't ask for a passphrase"); diff --git a/deps/openssl/openssl/test/recipes/90-test_store_cases_data/garbage-pkcs12.p12 b/deps/openssl/openssl/test/recipes/90-test_store_cases_data/garbage-pkcs12.p12 new file mode 100644 index 00000000000000..1a9f2578f33fcb --- /dev/null +++ b/deps/openssl/openssl/test/recipes/90-test_store_cases_data/garbage-pkcs12.p12 @@ -0,0 +1 @@ +0[0 *H801 0 UUS10 Upo \ No newline at end of file diff --git a/deps/openssl/openssl/test/ssl-tests/14-curves.cnf b/deps/openssl/openssl/test/ssl-tests/14-curves.cnf index bafa4a65cd3535..75635d29bd0f7a 100644 --- a/deps/openssl/openssl/test/ssl-tests/14-curves.cnf +++ b/deps/openssl/openssl/test/ssl-tests/14-curves.cnf @@ -1,87 +1,102 @@ # Generated with generate_ssl_tests.pl -num_tests = 80 +num_tests = 95 test-0 = 0-curve-prime256v1 test-1 = 1-curve-secp384r1 test-2 = 2-curve-secp521r1 test-3 = 3-curve-X25519 test-4 = 4-curve-X448 -test-5 = 5-curve-sect233k1 -test-6 = 6-curve-sect233r1 -test-7 = 7-curve-sect283k1 -test-8 = 8-curve-sect283r1 -test-9 = 9-curve-sect409k1 -test-10 = 10-curve-sect409r1 -test-11 = 11-curve-sect571k1 -test-12 = 12-curve-sect571r1 -test-13 = 13-curve-secp224r1 -test-14 = 14-curve-sect163k1 -test-15 = 15-curve-sect163r2 -test-16 = 16-curve-prime192v1 -test-17 = 17-curve-sect163r1 -test-18 = 18-curve-sect193r1 -test-19 = 19-curve-sect193r2 -test-20 = 20-curve-sect239k1 -test-21 = 21-curve-secp160k1 -test-22 = 22-curve-secp160r1 -test-23 = 23-curve-secp160r2 -test-24 = 24-curve-secp192k1 -test-25 = 25-curve-secp224k1 -test-26 = 26-curve-secp256k1 -test-27 = 27-curve-brainpoolP256r1 -test-28 = 28-curve-brainpoolP384r1 -test-29 = 29-curve-brainpoolP512r1 -test-30 = 30-curve-sect233k1-tls12-in-tls13 -test-31 = 31-curve-sect233r1-tls12-in-tls13 -test-32 = 32-curve-sect283k1-tls12-in-tls13 -test-33 = 33-curve-sect283r1-tls12-in-tls13 -test-34 = 34-curve-sect409k1-tls12-in-tls13 -test-35 = 35-curve-sect409r1-tls12-in-tls13 -test-36 = 36-curve-sect571k1-tls12-in-tls13 -test-37 = 37-curve-sect571r1-tls12-in-tls13 -test-38 = 38-curve-secp224r1-tls12-in-tls13 -test-39 = 39-curve-sect163k1-tls12-in-tls13 -test-40 = 40-curve-sect163r2-tls12-in-tls13 -test-41 = 41-curve-prime192v1-tls12-in-tls13 -test-42 = 42-curve-sect163r1-tls12-in-tls13 -test-43 = 43-curve-sect193r1-tls12-in-tls13 -test-44 = 44-curve-sect193r2-tls12-in-tls13 -test-45 = 45-curve-sect239k1-tls12-in-tls13 -test-46 = 46-curve-secp160k1-tls12-in-tls13 -test-47 = 47-curve-secp160r1-tls12-in-tls13 -test-48 = 48-curve-secp160r2-tls12-in-tls13 -test-49 = 49-curve-secp192k1-tls12-in-tls13 -test-50 = 50-curve-secp224k1-tls12-in-tls13 -test-51 = 51-curve-secp256k1-tls12-in-tls13 -test-52 = 52-curve-brainpoolP256r1-tls12-in-tls13 -test-53 = 53-curve-brainpoolP384r1-tls12-in-tls13 -test-54 = 54-curve-brainpoolP512r1-tls12-in-tls13 -test-55 = 55-curve-sect233k1-tls13 -test-56 = 56-curve-sect233r1-tls13 -test-57 = 57-curve-sect283k1-tls13 -test-58 = 58-curve-sect283r1-tls13 -test-59 = 59-curve-sect409k1-tls13 -test-60 = 60-curve-sect409r1-tls13 -test-61 = 61-curve-sect571k1-tls13 -test-62 = 62-curve-sect571r1-tls13 -test-63 = 63-curve-secp224r1-tls13 -test-64 = 64-curve-sect163k1-tls13 -test-65 = 65-curve-sect163r2-tls13 -test-66 = 66-curve-prime192v1-tls13 -test-67 = 67-curve-sect163r1-tls13 -test-68 = 68-curve-sect193r1-tls13 -test-69 = 69-curve-sect193r2-tls13 -test-70 = 70-curve-sect239k1-tls13 -test-71 = 71-curve-secp160k1-tls13 -test-72 = 72-curve-secp160r1-tls13 -test-73 = 73-curve-secp160r2-tls13 -test-74 = 74-curve-secp192k1-tls13 -test-75 = 75-curve-secp224k1-tls13 -test-76 = 76-curve-secp256k1-tls13 -test-77 = 77-curve-brainpoolP256r1-tls13 -test-78 = 78-curve-brainpoolP384r1-tls13 -test-79 = 79-curve-brainpoolP512r1-tls13 +test-5 = 5-curve-ffdhe2048 +test-6 = 6-curve-ffdhe3072 +test-7 = 7-curve-ffdhe4096 +test-8 = 8-curve-ffdhe6144 +test-9 = 9-curve-ffdhe8192 +test-10 = 10-curve-sect233k1 +test-11 = 11-curve-sect233r1 +test-12 = 12-curve-sect283k1 +test-13 = 13-curve-sect283r1 +test-14 = 14-curve-sect409k1 +test-15 = 15-curve-sect409r1 +test-16 = 16-curve-sect571k1 +test-17 = 17-curve-sect571r1 +test-18 = 18-curve-secp224r1 +test-19 = 19-curve-sect163k1 +test-20 = 20-curve-sect163r2 +test-21 = 21-curve-prime192v1 +test-22 = 22-curve-sect163r1 +test-23 = 23-curve-sect193r1 +test-24 = 24-curve-sect193r2 +test-25 = 25-curve-sect239k1 +test-26 = 26-curve-secp160k1 +test-27 = 27-curve-secp160r1 +test-28 = 28-curve-secp160r2 +test-29 = 29-curve-secp192k1 +test-30 = 30-curve-secp224k1 +test-31 = 31-curve-secp256k1 +test-32 = 32-curve-brainpoolP256r1 +test-33 = 33-curve-brainpoolP384r1 +test-34 = 34-curve-brainpoolP512r1 +test-35 = 35-curve-sect233k1-tls12-in-tls13 +test-36 = 36-curve-sect233r1-tls12-in-tls13 +test-37 = 37-curve-sect283k1-tls12-in-tls13 +test-38 = 38-curve-sect283r1-tls12-in-tls13 +test-39 = 39-curve-sect409k1-tls12-in-tls13 +test-40 = 40-curve-sect409r1-tls12-in-tls13 +test-41 = 41-curve-sect571k1-tls12-in-tls13 +test-42 = 42-curve-sect571r1-tls12-in-tls13 +test-43 = 43-curve-secp224r1-tls12-in-tls13 +test-44 = 44-curve-sect163k1-tls12-in-tls13 +test-45 = 45-curve-sect163r2-tls12-in-tls13 +test-46 = 46-curve-prime192v1-tls12-in-tls13 +test-47 = 47-curve-sect163r1-tls12-in-tls13 +test-48 = 48-curve-sect193r1-tls12-in-tls13 +test-49 = 49-curve-sect193r2-tls12-in-tls13 +test-50 = 50-curve-sect239k1-tls12-in-tls13 +test-51 = 51-curve-secp160k1-tls12-in-tls13 +test-52 = 52-curve-secp160r1-tls12-in-tls13 +test-53 = 53-curve-secp160r2-tls12-in-tls13 +test-54 = 54-curve-secp192k1-tls12-in-tls13 +test-55 = 55-curve-secp224k1-tls12-in-tls13 +test-56 = 56-curve-secp256k1-tls12-in-tls13 +test-57 = 57-curve-brainpoolP256r1-tls12-in-tls13 +test-58 = 58-curve-brainpoolP384r1-tls12-in-tls13 +test-59 = 59-curve-brainpoolP512r1-tls12-in-tls13 +test-60 = 60-curve-sect233k1-tls13 +test-61 = 61-curve-sect233r1-tls13 +test-62 = 62-curve-sect283k1-tls13 +test-63 = 63-curve-sect283r1-tls13 +test-64 = 64-curve-sect409k1-tls13 +test-65 = 65-curve-sect409r1-tls13 +test-66 = 66-curve-sect571k1-tls13 +test-67 = 67-curve-sect571r1-tls13 +test-68 = 68-curve-secp224r1-tls13 +test-69 = 69-curve-sect163k1-tls13 +test-70 = 70-curve-sect163r2-tls13 +test-71 = 71-curve-prime192v1-tls13 +test-72 = 72-curve-sect163r1-tls13 +test-73 = 73-curve-sect193r1-tls13 +test-74 = 74-curve-sect193r2-tls13 +test-75 = 75-curve-sect239k1-tls13 +test-76 = 76-curve-secp160k1-tls13 +test-77 = 77-curve-secp160r1-tls13 +test-78 = 78-curve-secp160r2-tls13 +test-79 = 79-curve-secp192k1-tls13 +test-80 = 80-curve-secp224k1-tls13 +test-81 = 81-curve-secp256k1-tls13 +test-82 = 82-curve-brainpoolP256r1-tls13 +test-83 = 83-curve-brainpoolP384r1-tls13 +test-84 = 84-curve-brainpoolP512r1-tls13 +test-85 = 85-curve-ffdhe2048-tls13-in-tls12 +test-86 = 86-curve-ffdhe2048-tls13-in-tls12-2 +test-87 = 87-curve-ffdhe3072-tls13-in-tls12 +test-88 = 88-curve-ffdhe3072-tls13-in-tls12-2 +test-89 = 89-curve-ffdhe4096-tls13-in-tls12 +test-90 = 90-curve-ffdhe4096-tls13-in-tls12-2 +test-91 = 91-curve-ffdhe6144-tls13-in-tls12 +test-92 = 92-curve-ffdhe6144-tls13-in-tls12-2 +test-93 = 93-curve-ffdhe8192-tls13-in-tls12 +test-94 = 94-curve-ffdhe8192-tls13-in-tls12-2 # =========================================================== [0-curve-prime256v1] @@ -229,28 +244,173 @@ ExpectedTmpKeyType = X448 # =========================================================== -[5-curve-sect233k1] -ssl_conf = 5-curve-sect233k1-ssl +[5-curve-ffdhe2048] +ssl_conf = 5-curve-ffdhe2048-ssl -[5-curve-sect233k1-ssl] -server = 5-curve-sect233k1-server -client = 5-curve-sect233k1-client +[5-curve-ffdhe2048-ssl] +server = 5-curve-ffdhe2048-server +client = 5-curve-ffdhe2048-client -[5-curve-sect233k1-server] +[5-curve-ffdhe2048-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Curves = ffdhe2048 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[5-curve-ffdhe2048-client] +CipherString = ECDHE +Curves = ffdhe2048 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-5] +ExpectedProtocol = TLSv1.3 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[6-curve-ffdhe3072] +ssl_conf = 6-curve-ffdhe3072-ssl + +[6-curve-ffdhe3072-ssl] +server = 6-curve-ffdhe3072-server +client = 6-curve-ffdhe3072-client + +[6-curve-ffdhe3072-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Curves = ffdhe3072 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[6-curve-ffdhe3072-client] +CipherString = ECDHE +Curves = ffdhe3072 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-6] +ExpectedProtocol = TLSv1.3 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[7-curve-ffdhe4096] +ssl_conf = 7-curve-ffdhe4096-ssl + +[7-curve-ffdhe4096-ssl] +server = 7-curve-ffdhe4096-server +client = 7-curve-ffdhe4096-client + +[7-curve-ffdhe4096-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Curves = ffdhe4096 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[7-curve-ffdhe4096-client] +CipherString = ECDHE +Curves = ffdhe4096 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-7] +ExpectedProtocol = TLSv1.3 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[8-curve-ffdhe6144] +ssl_conf = 8-curve-ffdhe6144-ssl + +[8-curve-ffdhe6144-ssl] +server = 8-curve-ffdhe6144-server +client = 8-curve-ffdhe6144-client + +[8-curve-ffdhe6144-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Curves = ffdhe6144 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[8-curve-ffdhe6144-client] +CipherString = ECDHE +Curves = ffdhe6144 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-8] +ExpectedProtocol = TLSv1.3 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[9-curve-ffdhe8192] +ssl_conf = 9-curve-ffdhe8192-ssl + +[9-curve-ffdhe8192-ssl] +server = 9-curve-ffdhe8192-server +client = 9-curve-ffdhe8192-client + +[9-curve-ffdhe8192-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Curves = ffdhe8192 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[9-curve-ffdhe8192-client] +CipherString = ECDHE +Curves = ffdhe8192 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-9] +ExpectedProtocol = TLSv1.3 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[10-curve-sect233k1] +ssl_conf = 10-curve-sect233k1-ssl + +[10-curve-sect233k1-ssl] +server = 10-curve-sect233k1-server +client = 10-curve-sect233k1-client + +[10-curve-sect233k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect233k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[5-curve-sect233k1-client] +[10-curve-sect233k1-client] CipherString = ECDHE Curves = sect233k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-5] +[test-10] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect233k1 @@ -258,28 +418,28 @@ ExpectedTmpKeyType = sect233k1 # =========================================================== -[6-curve-sect233r1] -ssl_conf = 6-curve-sect233r1-ssl +[11-curve-sect233r1] +ssl_conf = 11-curve-sect233r1-ssl -[6-curve-sect233r1-ssl] -server = 6-curve-sect233r1-server -client = 6-curve-sect233r1-client +[11-curve-sect233r1-ssl] +server = 11-curve-sect233r1-server +client = 11-curve-sect233r1-client -[6-curve-sect233r1-server] +[11-curve-sect233r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect233r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[6-curve-sect233r1-client] +[11-curve-sect233r1-client] CipherString = ECDHE Curves = sect233r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-6] +[test-11] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect233r1 @@ -287,28 +447,28 @@ ExpectedTmpKeyType = sect233r1 # =========================================================== -[7-curve-sect283k1] -ssl_conf = 7-curve-sect283k1-ssl +[12-curve-sect283k1] +ssl_conf = 12-curve-sect283k1-ssl -[7-curve-sect283k1-ssl] -server = 7-curve-sect283k1-server -client = 7-curve-sect283k1-client +[12-curve-sect283k1-ssl] +server = 12-curve-sect283k1-server +client = 12-curve-sect283k1-client -[7-curve-sect283k1-server] +[12-curve-sect283k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect283k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[7-curve-sect283k1-client] +[12-curve-sect283k1-client] CipherString = ECDHE Curves = sect283k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-7] +[test-12] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect283k1 @@ -316,28 +476,28 @@ ExpectedTmpKeyType = sect283k1 # =========================================================== -[8-curve-sect283r1] -ssl_conf = 8-curve-sect283r1-ssl +[13-curve-sect283r1] +ssl_conf = 13-curve-sect283r1-ssl -[8-curve-sect283r1-ssl] -server = 8-curve-sect283r1-server -client = 8-curve-sect283r1-client +[13-curve-sect283r1-ssl] +server = 13-curve-sect283r1-server +client = 13-curve-sect283r1-client -[8-curve-sect283r1-server] +[13-curve-sect283r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect283r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[8-curve-sect283r1-client] +[13-curve-sect283r1-client] CipherString = ECDHE Curves = sect283r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-8] +[test-13] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect283r1 @@ -345,28 +505,28 @@ ExpectedTmpKeyType = sect283r1 # =========================================================== -[9-curve-sect409k1] -ssl_conf = 9-curve-sect409k1-ssl +[14-curve-sect409k1] +ssl_conf = 14-curve-sect409k1-ssl -[9-curve-sect409k1-ssl] -server = 9-curve-sect409k1-server -client = 9-curve-sect409k1-client +[14-curve-sect409k1-ssl] +server = 14-curve-sect409k1-server +client = 14-curve-sect409k1-client -[9-curve-sect409k1-server] +[14-curve-sect409k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect409k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[9-curve-sect409k1-client] +[14-curve-sect409k1-client] CipherString = ECDHE Curves = sect409k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-9] +[test-14] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect409k1 @@ -374,28 +534,28 @@ ExpectedTmpKeyType = sect409k1 # =========================================================== -[10-curve-sect409r1] -ssl_conf = 10-curve-sect409r1-ssl +[15-curve-sect409r1] +ssl_conf = 15-curve-sect409r1-ssl -[10-curve-sect409r1-ssl] -server = 10-curve-sect409r1-server -client = 10-curve-sect409r1-client +[15-curve-sect409r1-ssl] +server = 15-curve-sect409r1-server +client = 15-curve-sect409r1-client -[10-curve-sect409r1-server] +[15-curve-sect409r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect409r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[10-curve-sect409r1-client] +[15-curve-sect409r1-client] CipherString = ECDHE Curves = sect409r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-10] +[test-15] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect409r1 @@ -403,28 +563,28 @@ ExpectedTmpKeyType = sect409r1 # =========================================================== -[11-curve-sect571k1] -ssl_conf = 11-curve-sect571k1-ssl +[16-curve-sect571k1] +ssl_conf = 16-curve-sect571k1-ssl -[11-curve-sect571k1-ssl] -server = 11-curve-sect571k1-server -client = 11-curve-sect571k1-client +[16-curve-sect571k1-ssl] +server = 16-curve-sect571k1-server +client = 16-curve-sect571k1-client -[11-curve-sect571k1-server] +[16-curve-sect571k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect571k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[11-curve-sect571k1-client] +[16-curve-sect571k1-client] CipherString = ECDHE Curves = sect571k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-11] +[test-16] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect571k1 @@ -432,28 +592,28 @@ ExpectedTmpKeyType = sect571k1 # =========================================================== -[12-curve-sect571r1] -ssl_conf = 12-curve-sect571r1-ssl +[17-curve-sect571r1] +ssl_conf = 17-curve-sect571r1-ssl -[12-curve-sect571r1-ssl] -server = 12-curve-sect571r1-server -client = 12-curve-sect571r1-client +[17-curve-sect571r1-ssl] +server = 17-curve-sect571r1-server +client = 17-curve-sect571r1-client -[12-curve-sect571r1-server] +[17-curve-sect571r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect571r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[12-curve-sect571r1-client] +[17-curve-sect571r1-client] CipherString = ECDHE Curves = sect571r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-12] +[test-17] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect571r1 @@ -461,28 +621,28 @@ ExpectedTmpKeyType = sect571r1 # =========================================================== -[13-curve-secp224r1] -ssl_conf = 13-curve-secp224r1-ssl +[18-curve-secp224r1] +ssl_conf = 18-curve-secp224r1-ssl -[13-curve-secp224r1-ssl] -server = 13-curve-secp224r1-server -client = 13-curve-secp224r1-client +[18-curve-secp224r1-ssl] +server = 18-curve-secp224r1-server +client = 18-curve-secp224r1-client -[13-curve-secp224r1-server] +[18-curve-secp224r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp224r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[13-curve-secp224r1-client] +[18-curve-secp224r1-client] CipherString = ECDHE Curves = secp224r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-13] +[test-18] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp224r1 @@ -490,28 +650,28 @@ ExpectedTmpKeyType = secp224r1 # =========================================================== -[14-curve-sect163k1] -ssl_conf = 14-curve-sect163k1-ssl +[19-curve-sect163k1] +ssl_conf = 19-curve-sect163k1-ssl -[14-curve-sect163k1-ssl] -server = 14-curve-sect163k1-server -client = 14-curve-sect163k1-client +[19-curve-sect163k1-ssl] +server = 19-curve-sect163k1-server +client = 19-curve-sect163k1-client -[14-curve-sect163k1-server] +[19-curve-sect163k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect163k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[14-curve-sect163k1-client] +[19-curve-sect163k1-client] CipherString = ECDHE Curves = sect163k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-14] +[test-19] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect163k1 @@ -519,28 +679,28 @@ ExpectedTmpKeyType = sect163k1 # =========================================================== -[15-curve-sect163r2] -ssl_conf = 15-curve-sect163r2-ssl +[20-curve-sect163r2] +ssl_conf = 20-curve-sect163r2-ssl -[15-curve-sect163r2-ssl] -server = 15-curve-sect163r2-server -client = 15-curve-sect163r2-client +[20-curve-sect163r2-ssl] +server = 20-curve-sect163r2-server +client = 20-curve-sect163r2-client -[15-curve-sect163r2-server] +[20-curve-sect163r2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect163r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[15-curve-sect163r2-client] +[20-curve-sect163r2-client] CipherString = ECDHE Curves = sect163r2 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-15] +[test-20] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect163r2 @@ -548,28 +708,28 @@ ExpectedTmpKeyType = sect163r2 # =========================================================== -[16-curve-prime192v1] -ssl_conf = 16-curve-prime192v1-ssl +[21-curve-prime192v1] +ssl_conf = 21-curve-prime192v1-ssl -[16-curve-prime192v1-ssl] -server = 16-curve-prime192v1-server -client = 16-curve-prime192v1-client +[21-curve-prime192v1-ssl] +server = 21-curve-prime192v1-server +client = 21-curve-prime192v1-client -[16-curve-prime192v1-server] +[21-curve-prime192v1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = prime192v1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[16-curve-prime192v1-client] +[21-curve-prime192v1-client] CipherString = ECDHE Curves = prime192v1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-16] +[test-21] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = prime192v1 @@ -577,28 +737,28 @@ ExpectedTmpKeyType = prime192v1 # =========================================================== -[17-curve-sect163r1] -ssl_conf = 17-curve-sect163r1-ssl +[22-curve-sect163r1] +ssl_conf = 22-curve-sect163r1-ssl -[17-curve-sect163r1-ssl] -server = 17-curve-sect163r1-server -client = 17-curve-sect163r1-client +[22-curve-sect163r1-ssl] +server = 22-curve-sect163r1-server +client = 22-curve-sect163r1-client -[17-curve-sect163r1-server] +[22-curve-sect163r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect163r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[17-curve-sect163r1-client] +[22-curve-sect163r1-client] CipherString = ECDHE Curves = sect163r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-17] +[test-22] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect163r1 @@ -606,28 +766,28 @@ ExpectedTmpKeyType = sect163r1 # =========================================================== -[18-curve-sect193r1] -ssl_conf = 18-curve-sect193r1-ssl +[23-curve-sect193r1] +ssl_conf = 23-curve-sect193r1-ssl -[18-curve-sect193r1-ssl] -server = 18-curve-sect193r1-server -client = 18-curve-sect193r1-client +[23-curve-sect193r1-ssl] +server = 23-curve-sect193r1-server +client = 23-curve-sect193r1-client -[18-curve-sect193r1-server] +[23-curve-sect193r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect193r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[18-curve-sect193r1-client] +[23-curve-sect193r1-client] CipherString = ECDHE Curves = sect193r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-18] +[test-23] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect193r1 @@ -635,28 +795,28 @@ ExpectedTmpKeyType = sect193r1 # =========================================================== -[19-curve-sect193r2] -ssl_conf = 19-curve-sect193r2-ssl +[24-curve-sect193r2] +ssl_conf = 24-curve-sect193r2-ssl -[19-curve-sect193r2-ssl] -server = 19-curve-sect193r2-server -client = 19-curve-sect193r2-client +[24-curve-sect193r2-ssl] +server = 24-curve-sect193r2-server +client = 24-curve-sect193r2-client -[19-curve-sect193r2-server] +[24-curve-sect193r2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect193r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[19-curve-sect193r2-client] +[24-curve-sect193r2-client] CipherString = ECDHE Curves = sect193r2 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-19] +[test-24] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect193r2 @@ -664,28 +824,28 @@ ExpectedTmpKeyType = sect193r2 # =========================================================== -[20-curve-sect239k1] -ssl_conf = 20-curve-sect239k1-ssl +[25-curve-sect239k1] +ssl_conf = 25-curve-sect239k1-ssl -[20-curve-sect239k1-ssl] -server = 20-curve-sect239k1-server -client = 20-curve-sect239k1-client +[25-curve-sect239k1-ssl] +server = 25-curve-sect239k1-server +client = 25-curve-sect239k1-client -[20-curve-sect239k1-server] +[25-curve-sect239k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect239k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[20-curve-sect239k1-client] +[25-curve-sect239k1-client] CipherString = ECDHE Curves = sect239k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-20] +[test-25] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect239k1 @@ -693,28 +853,28 @@ ExpectedTmpKeyType = sect239k1 # =========================================================== -[21-curve-secp160k1] -ssl_conf = 21-curve-secp160k1-ssl +[26-curve-secp160k1] +ssl_conf = 26-curve-secp160k1-ssl -[21-curve-secp160k1-ssl] -server = 21-curve-secp160k1-server -client = 21-curve-secp160k1-client +[26-curve-secp160k1-ssl] +server = 26-curve-secp160k1-server +client = 26-curve-secp160k1-client -[21-curve-secp160k1-server] +[26-curve-secp160k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp160k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[21-curve-secp160k1-client] +[26-curve-secp160k1-client] CipherString = ECDHE Curves = secp160k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-21] +[test-26] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp160k1 @@ -722,28 +882,28 @@ ExpectedTmpKeyType = secp160k1 # =========================================================== -[22-curve-secp160r1] -ssl_conf = 22-curve-secp160r1-ssl +[27-curve-secp160r1] +ssl_conf = 27-curve-secp160r1-ssl -[22-curve-secp160r1-ssl] -server = 22-curve-secp160r1-server -client = 22-curve-secp160r1-client +[27-curve-secp160r1-ssl] +server = 27-curve-secp160r1-server +client = 27-curve-secp160r1-client -[22-curve-secp160r1-server] +[27-curve-secp160r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp160r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[22-curve-secp160r1-client] +[27-curve-secp160r1-client] CipherString = ECDHE Curves = secp160r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-22] +[test-27] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp160r1 @@ -751,28 +911,28 @@ ExpectedTmpKeyType = secp160r1 # =========================================================== -[23-curve-secp160r2] -ssl_conf = 23-curve-secp160r2-ssl +[28-curve-secp160r2] +ssl_conf = 28-curve-secp160r2-ssl -[23-curve-secp160r2-ssl] -server = 23-curve-secp160r2-server -client = 23-curve-secp160r2-client +[28-curve-secp160r2-ssl] +server = 28-curve-secp160r2-server +client = 28-curve-secp160r2-client -[23-curve-secp160r2-server] +[28-curve-secp160r2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp160r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[23-curve-secp160r2-client] +[28-curve-secp160r2-client] CipherString = ECDHE Curves = secp160r2 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-23] +[test-28] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp160r2 @@ -780,28 +940,28 @@ ExpectedTmpKeyType = secp160r2 # =========================================================== -[24-curve-secp192k1] -ssl_conf = 24-curve-secp192k1-ssl +[29-curve-secp192k1] +ssl_conf = 29-curve-secp192k1-ssl -[24-curve-secp192k1-ssl] -server = 24-curve-secp192k1-server -client = 24-curve-secp192k1-client +[29-curve-secp192k1-ssl] +server = 29-curve-secp192k1-server +client = 29-curve-secp192k1-client -[24-curve-secp192k1-server] +[29-curve-secp192k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp192k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[24-curve-secp192k1-client] +[29-curve-secp192k1-client] CipherString = ECDHE Curves = secp192k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-24] +[test-29] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp192k1 @@ -809,28 +969,28 @@ ExpectedTmpKeyType = secp192k1 # =========================================================== -[25-curve-secp224k1] -ssl_conf = 25-curve-secp224k1-ssl +[30-curve-secp224k1] +ssl_conf = 30-curve-secp224k1-ssl -[25-curve-secp224k1-ssl] -server = 25-curve-secp224k1-server -client = 25-curve-secp224k1-client +[30-curve-secp224k1-ssl] +server = 30-curve-secp224k1-server +client = 30-curve-secp224k1-client -[25-curve-secp224k1-server] +[30-curve-secp224k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp224k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[25-curve-secp224k1-client] +[30-curve-secp224k1-client] CipherString = ECDHE Curves = secp224k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-25] +[test-30] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp224k1 @@ -838,28 +998,28 @@ ExpectedTmpKeyType = secp224k1 # =========================================================== -[26-curve-secp256k1] -ssl_conf = 26-curve-secp256k1-ssl +[31-curve-secp256k1] +ssl_conf = 31-curve-secp256k1-ssl -[26-curve-secp256k1-ssl] -server = 26-curve-secp256k1-server -client = 26-curve-secp256k1-client +[31-curve-secp256k1-ssl] +server = 31-curve-secp256k1-server +client = 31-curve-secp256k1-client -[26-curve-secp256k1-server] +[31-curve-secp256k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp256k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[26-curve-secp256k1-client] +[31-curve-secp256k1-client] CipherString = ECDHE Curves = secp256k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-26] +[test-31] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp256k1 @@ -867,28 +1027,28 @@ ExpectedTmpKeyType = secp256k1 # =========================================================== -[27-curve-brainpoolP256r1] -ssl_conf = 27-curve-brainpoolP256r1-ssl +[32-curve-brainpoolP256r1] +ssl_conf = 32-curve-brainpoolP256r1-ssl -[27-curve-brainpoolP256r1-ssl] -server = 27-curve-brainpoolP256r1-server -client = 27-curve-brainpoolP256r1-client +[32-curve-brainpoolP256r1-ssl] +server = 32-curve-brainpoolP256r1-server +client = 32-curve-brainpoolP256r1-client -[27-curve-brainpoolP256r1-server] +[32-curve-brainpoolP256r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = brainpoolP256r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[27-curve-brainpoolP256r1-client] +[32-curve-brainpoolP256r1-client] CipherString = ECDHE Curves = brainpoolP256r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-27] +[test-32] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = brainpoolP256r1 @@ -896,28 +1056,28 @@ ExpectedTmpKeyType = brainpoolP256r1 # =========================================================== -[28-curve-brainpoolP384r1] -ssl_conf = 28-curve-brainpoolP384r1-ssl +[33-curve-brainpoolP384r1] +ssl_conf = 33-curve-brainpoolP384r1-ssl -[28-curve-brainpoolP384r1-ssl] -server = 28-curve-brainpoolP384r1-server -client = 28-curve-brainpoolP384r1-client +[33-curve-brainpoolP384r1-ssl] +server = 33-curve-brainpoolP384r1-server +client = 33-curve-brainpoolP384r1-client -[28-curve-brainpoolP384r1-server] +[33-curve-brainpoolP384r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = brainpoolP384r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[28-curve-brainpoolP384r1-client] +[33-curve-brainpoolP384r1-client] CipherString = ECDHE Curves = brainpoolP384r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-28] +[test-33] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = brainpoolP384r1 @@ -925,28 +1085,28 @@ ExpectedTmpKeyType = brainpoolP384r1 # =========================================================== -[29-curve-brainpoolP512r1] -ssl_conf = 29-curve-brainpoolP512r1-ssl +[34-curve-brainpoolP512r1] +ssl_conf = 34-curve-brainpoolP512r1-ssl -[29-curve-brainpoolP512r1-ssl] -server = 29-curve-brainpoolP512r1-server -client = 29-curve-brainpoolP512r1-client +[34-curve-brainpoolP512r1-ssl] +server = 34-curve-brainpoolP512r1-server +client = 34-curve-brainpoolP512r1-client -[29-curve-brainpoolP512r1-server] +[34-curve-brainpoolP512r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = brainpoolP512r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[29-curve-brainpoolP512r1-client] +[34-curve-brainpoolP512r1-client] CipherString = ECDHE Curves = brainpoolP512r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-29] +[test-34] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = brainpoolP512r1 @@ -954,21 +1114,21 @@ ExpectedTmpKeyType = brainpoolP512r1 # =========================================================== -[30-curve-sect233k1-tls12-in-tls13] -ssl_conf = 30-curve-sect233k1-tls12-in-tls13-ssl +[35-curve-sect233k1-tls12-in-tls13] +ssl_conf = 35-curve-sect233k1-tls12-in-tls13-ssl -[30-curve-sect233k1-tls12-in-tls13-ssl] -server = 30-curve-sect233k1-tls12-in-tls13-server -client = 30-curve-sect233k1-tls12-in-tls13-client +[35-curve-sect233k1-tls12-in-tls13-ssl] +server = 35-curve-sect233k1-tls12-in-tls13-server +client = 35-curve-sect233k1-tls12-in-tls13-client -[30-curve-sect233k1-tls12-in-tls13-server] +[35-curve-sect233k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[30-curve-sect233k1-tls12-in-tls13-client] +[35-curve-sect233k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233k1:P-256 MaxProtocol = TLSv1.3 @@ -976,7 +1136,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-30] +[test-35] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -984,21 +1144,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[31-curve-sect233r1-tls12-in-tls13] -ssl_conf = 31-curve-sect233r1-tls12-in-tls13-ssl +[36-curve-sect233r1-tls12-in-tls13] +ssl_conf = 36-curve-sect233r1-tls12-in-tls13-ssl -[31-curve-sect233r1-tls12-in-tls13-ssl] -server = 31-curve-sect233r1-tls12-in-tls13-server -client = 31-curve-sect233r1-tls12-in-tls13-client +[36-curve-sect233r1-tls12-in-tls13-ssl] +server = 36-curve-sect233r1-tls12-in-tls13-server +client = 36-curve-sect233r1-tls12-in-tls13-client -[31-curve-sect233r1-tls12-in-tls13-server] +[36-curve-sect233r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[31-curve-sect233r1-tls12-in-tls13-client] +[36-curve-sect233r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233r1:P-256 MaxProtocol = TLSv1.3 @@ -1006,7 +1166,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-31] +[test-36] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1014,21 +1174,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[32-curve-sect283k1-tls12-in-tls13] -ssl_conf = 32-curve-sect283k1-tls12-in-tls13-ssl +[37-curve-sect283k1-tls12-in-tls13] +ssl_conf = 37-curve-sect283k1-tls12-in-tls13-ssl -[32-curve-sect283k1-tls12-in-tls13-ssl] -server = 32-curve-sect283k1-tls12-in-tls13-server -client = 32-curve-sect283k1-tls12-in-tls13-client +[37-curve-sect283k1-tls12-in-tls13-ssl] +server = 37-curve-sect283k1-tls12-in-tls13-server +client = 37-curve-sect283k1-tls12-in-tls13-client -[32-curve-sect283k1-tls12-in-tls13-server] +[37-curve-sect283k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[32-curve-sect283k1-tls12-in-tls13-client] +[37-curve-sect283k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283k1:P-256 MaxProtocol = TLSv1.3 @@ -1036,7 +1196,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-32] +[test-37] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1044,21 +1204,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[33-curve-sect283r1-tls12-in-tls13] -ssl_conf = 33-curve-sect283r1-tls12-in-tls13-ssl +[38-curve-sect283r1-tls12-in-tls13] +ssl_conf = 38-curve-sect283r1-tls12-in-tls13-ssl -[33-curve-sect283r1-tls12-in-tls13-ssl] -server = 33-curve-sect283r1-tls12-in-tls13-server -client = 33-curve-sect283r1-tls12-in-tls13-client +[38-curve-sect283r1-tls12-in-tls13-ssl] +server = 38-curve-sect283r1-tls12-in-tls13-server +client = 38-curve-sect283r1-tls12-in-tls13-client -[33-curve-sect283r1-tls12-in-tls13-server] +[38-curve-sect283r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[33-curve-sect283r1-tls12-in-tls13-client] +[38-curve-sect283r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283r1:P-256 MaxProtocol = TLSv1.3 @@ -1066,7 +1226,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-33] +[test-38] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1074,21 +1234,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[34-curve-sect409k1-tls12-in-tls13] -ssl_conf = 34-curve-sect409k1-tls12-in-tls13-ssl +[39-curve-sect409k1-tls12-in-tls13] +ssl_conf = 39-curve-sect409k1-tls12-in-tls13-ssl -[34-curve-sect409k1-tls12-in-tls13-ssl] -server = 34-curve-sect409k1-tls12-in-tls13-server -client = 34-curve-sect409k1-tls12-in-tls13-client +[39-curve-sect409k1-tls12-in-tls13-ssl] +server = 39-curve-sect409k1-tls12-in-tls13-server +client = 39-curve-sect409k1-tls12-in-tls13-client -[34-curve-sect409k1-tls12-in-tls13-server] +[39-curve-sect409k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[34-curve-sect409k1-tls12-in-tls13-client] +[39-curve-sect409k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409k1:P-256 MaxProtocol = TLSv1.3 @@ -1096,7 +1256,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-34] +[test-39] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1104,21 +1264,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[35-curve-sect409r1-tls12-in-tls13] -ssl_conf = 35-curve-sect409r1-tls12-in-tls13-ssl +[40-curve-sect409r1-tls12-in-tls13] +ssl_conf = 40-curve-sect409r1-tls12-in-tls13-ssl -[35-curve-sect409r1-tls12-in-tls13-ssl] -server = 35-curve-sect409r1-tls12-in-tls13-server -client = 35-curve-sect409r1-tls12-in-tls13-client +[40-curve-sect409r1-tls12-in-tls13-ssl] +server = 40-curve-sect409r1-tls12-in-tls13-server +client = 40-curve-sect409r1-tls12-in-tls13-client -[35-curve-sect409r1-tls12-in-tls13-server] +[40-curve-sect409r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[35-curve-sect409r1-tls12-in-tls13-client] +[40-curve-sect409r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409r1:P-256 MaxProtocol = TLSv1.3 @@ -1126,7 +1286,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-35] +[test-40] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1134,21 +1294,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[36-curve-sect571k1-tls12-in-tls13] -ssl_conf = 36-curve-sect571k1-tls12-in-tls13-ssl +[41-curve-sect571k1-tls12-in-tls13] +ssl_conf = 41-curve-sect571k1-tls12-in-tls13-ssl -[36-curve-sect571k1-tls12-in-tls13-ssl] -server = 36-curve-sect571k1-tls12-in-tls13-server -client = 36-curve-sect571k1-tls12-in-tls13-client +[41-curve-sect571k1-tls12-in-tls13-ssl] +server = 41-curve-sect571k1-tls12-in-tls13-server +client = 41-curve-sect571k1-tls12-in-tls13-client -[36-curve-sect571k1-tls12-in-tls13-server] +[41-curve-sect571k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[36-curve-sect571k1-tls12-in-tls13-client] +[41-curve-sect571k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571k1:P-256 MaxProtocol = TLSv1.3 @@ -1156,7 +1316,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-36] +[test-41] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1164,21 +1324,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[37-curve-sect571r1-tls12-in-tls13] -ssl_conf = 37-curve-sect571r1-tls12-in-tls13-ssl +[42-curve-sect571r1-tls12-in-tls13] +ssl_conf = 42-curve-sect571r1-tls12-in-tls13-ssl -[37-curve-sect571r1-tls12-in-tls13-ssl] -server = 37-curve-sect571r1-tls12-in-tls13-server -client = 37-curve-sect571r1-tls12-in-tls13-client +[42-curve-sect571r1-tls12-in-tls13-ssl] +server = 42-curve-sect571r1-tls12-in-tls13-server +client = 42-curve-sect571r1-tls12-in-tls13-client -[37-curve-sect571r1-tls12-in-tls13-server] +[42-curve-sect571r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[37-curve-sect571r1-tls12-in-tls13-client] +[42-curve-sect571r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571r1:P-256 MaxProtocol = TLSv1.3 @@ -1186,7 +1346,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-37] +[test-42] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1194,21 +1354,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[38-curve-secp224r1-tls12-in-tls13] -ssl_conf = 38-curve-secp224r1-tls12-in-tls13-ssl +[43-curve-secp224r1-tls12-in-tls13] +ssl_conf = 43-curve-secp224r1-tls12-in-tls13-ssl -[38-curve-secp224r1-tls12-in-tls13-ssl] -server = 38-curve-secp224r1-tls12-in-tls13-server -client = 38-curve-secp224r1-tls12-in-tls13-client +[43-curve-secp224r1-tls12-in-tls13-ssl] +server = 43-curve-secp224r1-tls12-in-tls13-server +client = 43-curve-secp224r1-tls12-in-tls13-client -[38-curve-secp224r1-tls12-in-tls13-server] +[43-curve-secp224r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[38-curve-secp224r1-tls12-in-tls13-client] +[43-curve-secp224r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224r1:P-256 MaxProtocol = TLSv1.3 @@ -1216,7 +1376,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-38] +[test-43] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1224,21 +1384,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[39-curve-sect163k1-tls12-in-tls13] -ssl_conf = 39-curve-sect163k1-tls12-in-tls13-ssl +[44-curve-sect163k1-tls12-in-tls13] +ssl_conf = 44-curve-sect163k1-tls12-in-tls13-ssl -[39-curve-sect163k1-tls12-in-tls13-ssl] -server = 39-curve-sect163k1-tls12-in-tls13-server -client = 39-curve-sect163k1-tls12-in-tls13-client +[44-curve-sect163k1-tls12-in-tls13-ssl] +server = 44-curve-sect163k1-tls12-in-tls13-server +client = 44-curve-sect163k1-tls12-in-tls13-client -[39-curve-sect163k1-tls12-in-tls13-server] +[44-curve-sect163k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[39-curve-sect163k1-tls12-in-tls13-client] +[44-curve-sect163k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163k1:P-256 MaxProtocol = TLSv1.3 @@ -1246,7 +1406,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-39] +[test-44] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1254,21 +1414,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[40-curve-sect163r2-tls12-in-tls13] -ssl_conf = 40-curve-sect163r2-tls12-in-tls13-ssl +[45-curve-sect163r2-tls12-in-tls13] +ssl_conf = 45-curve-sect163r2-tls12-in-tls13-ssl -[40-curve-sect163r2-tls12-in-tls13-ssl] -server = 40-curve-sect163r2-tls12-in-tls13-server -client = 40-curve-sect163r2-tls12-in-tls13-client +[45-curve-sect163r2-tls12-in-tls13-ssl] +server = 45-curve-sect163r2-tls12-in-tls13-server +client = 45-curve-sect163r2-tls12-in-tls13-client -[40-curve-sect163r2-tls12-in-tls13-server] +[45-curve-sect163r2-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r2:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[40-curve-sect163r2-tls12-in-tls13-client] +[45-curve-sect163r2-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r2:P-256 MaxProtocol = TLSv1.3 @@ -1276,7 +1436,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-40] +[test-45] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1284,21 +1444,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[41-curve-prime192v1-tls12-in-tls13] -ssl_conf = 41-curve-prime192v1-tls12-in-tls13-ssl +[46-curve-prime192v1-tls12-in-tls13] +ssl_conf = 46-curve-prime192v1-tls12-in-tls13-ssl -[41-curve-prime192v1-tls12-in-tls13-ssl] -server = 41-curve-prime192v1-tls12-in-tls13-server -client = 41-curve-prime192v1-tls12-in-tls13-client +[46-curve-prime192v1-tls12-in-tls13-ssl] +server = 46-curve-prime192v1-tls12-in-tls13-server +client = 46-curve-prime192v1-tls12-in-tls13-client -[41-curve-prime192v1-tls12-in-tls13-server] +[46-curve-prime192v1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = prime192v1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[41-curve-prime192v1-tls12-in-tls13-client] +[46-curve-prime192v1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = prime192v1:P-256 MaxProtocol = TLSv1.3 @@ -1306,7 +1466,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-41] +[test-46] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1314,21 +1474,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[42-curve-sect163r1-tls12-in-tls13] -ssl_conf = 42-curve-sect163r1-tls12-in-tls13-ssl +[47-curve-sect163r1-tls12-in-tls13] +ssl_conf = 47-curve-sect163r1-tls12-in-tls13-ssl -[42-curve-sect163r1-tls12-in-tls13-ssl] -server = 42-curve-sect163r1-tls12-in-tls13-server -client = 42-curve-sect163r1-tls12-in-tls13-client +[47-curve-sect163r1-tls12-in-tls13-ssl] +server = 47-curve-sect163r1-tls12-in-tls13-server +client = 47-curve-sect163r1-tls12-in-tls13-client -[42-curve-sect163r1-tls12-in-tls13-server] +[47-curve-sect163r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[42-curve-sect163r1-tls12-in-tls13-client] +[47-curve-sect163r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r1:P-256 MaxProtocol = TLSv1.3 @@ -1336,7 +1496,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-42] +[test-47] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1344,21 +1504,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[43-curve-sect193r1-tls12-in-tls13] -ssl_conf = 43-curve-sect193r1-tls12-in-tls13-ssl +[48-curve-sect193r1-tls12-in-tls13] +ssl_conf = 48-curve-sect193r1-tls12-in-tls13-ssl -[43-curve-sect193r1-tls12-in-tls13-ssl] -server = 43-curve-sect193r1-tls12-in-tls13-server -client = 43-curve-sect193r1-tls12-in-tls13-client +[48-curve-sect193r1-tls12-in-tls13-ssl] +server = 48-curve-sect193r1-tls12-in-tls13-server +client = 48-curve-sect193r1-tls12-in-tls13-client -[43-curve-sect193r1-tls12-in-tls13-server] +[48-curve-sect193r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[43-curve-sect193r1-tls12-in-tls13-client] +[48-curve-sect193r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r1:P-256 MaxProtocol = TLSv1.3 @@ -1366,7 +1526,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-43] +[test-48] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1374,21 +1534,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[44-curve-sect193r2-tls12-in-tls13] -ssl_conf = 44-curve-sect193r2-tls12-in-tls13-ssl +[49-curve-sect193r2-tls12-in-tls13] +ssl_conf = 49-curve-sect193r2-tls12-in-tls13-ssl -[44-curve-sect193r2-tls12-in-tls13-ssl] -server = 44-curve-sect193r2-tls12-in-tls13-server -client = 44-curve-sect193r2-tls12-in-tls13-client +[49-curve-sect193r2-tls12-in-tls13-ssl] +server = 49-curve-sect193r2-tls12-in-tls13-server +client = 49-curve-sect193r2-tls12-in-tls13-client -[44-curve-sect193r2-tls12-in-tls13-server] +[49-curve-sect193r2-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r2:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[44-curve-sect193r2-tls12-in-tls13-client] +[49-curve-sect193r2-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r2:P-256 MaxProtocol = TLSv1.3 @@ -1396,7 +1556,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-44] +[test-49] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1404,21 +1564,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[45-curve-sect239k1-tls12-in-tls13] -ssl_conf = 45-curve-sect239k1-tls12-in-tls13-ssl +[50-curve-sect239k1-tls12-in-tls13] +ssl_conf = 50-curve-sect239k1-tls12-in-tls13-ssl -[45-curve-sect239k1-tls12-in-tls13-ssl] -server = 45-curve-sect239k1-tls12-in-tls13-server -client = 45-curve-sect239k1-tls12-in-tls13-client +[50-curve-sect239k1-tls12-in-tls13-ssl] +server = 50-curve-sect239k1-tls12-in-tls13-server +client = 50-curve-sect239k1-tls12-in-tls13-client -[45-curve-sect239k1-tls12-in-tls13-server] +[50-curve-sect239k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect239k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[45-curve-sect239k1-tls12-in-tls13-client] +[50-curve-sect239k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect239k1:P-256 MaxProtocol = TLSv1.3 @@ -1426,7 +1586,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-45] +[test-50] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1434,21 +1594,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[46-curve-secp160k1-tls12-in-tls13] -ssl_conf = 46-curve-secp160k1-tls12-in-tls13-ssl +[51-curve-secp160k1-tls12-in-tls13] +ssl_conf = 51-curve-secp160k1-tls12-in-tls13-ssl -[46-curve-secp160k1-tls12-in-tls13-ssl] -server = 46-curve-secp160k1-tls12-in-tls13-server -client = 46-curve-secp160k1-tls12-in-tls13-client +[51-curve-secp160k1-tls12-in-tls13-ssl] +server = 51-curve-secp160k1-tls12-in-tls13-server +client = 51-curve-secp160k1-tls12-in-tls13-client -[46-curve-secp160k1-tls12-in-tls13-server] +[51-curve-secp160k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[46-curve-secp160k1-tls12-in-tls13-client] +[51-curve-secp160k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160k1:P-256 MaxProtocol = TLSv1.3 @@ -1456,7 +1616,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-46] +[test-51] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1464,21 +1624,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[47-curve-secp160r1-tls12-in-tls13] -ssl_conf = 47-curve-secp160r1-tls12-in-tls13-ssl +[52-curve-secp160r1-tls12-in-tls13] +ssl_conf = 52-curve-secp160r1-tls12-in-tls13-ssl -[47-curve-secp160r1-tls12-in-tls13-ssl] -server = 47-curve-secp160r1-tls12-in-tls13-server -client = 47-curve-secp160r1-tls12-in-tls13-client +[52-curve-secp160r1-tls12-in-tls13-ssl] +server = 52-curve-secp160r1-tls12-in-tls13-server +client = 52-curve-secp160r1-tls12-in-tls13-client -[47-curve-secp160r1-tls12-in-tls13-server] +[52-curve-secp160r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[47-curve-secp160r1-tls12-in-tls13-client] +[52-curve-secp160r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r1:P-256 MaxProtocol = TLSv1.3 @@ -1486,7 +1646,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-47] +[test-52] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1494,21 +1654,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[48-curve-secp160r2-tls12-in-tls13] -ssl_conf = 48-curve-secp160r2-tls12-in-tls13-ssl +[53-curve-secp160r2-tls12-in-tls13] +ssl_conf = 53-curve-secp160r2-tls12-in-tls13-ssl -[48-curve-secp160r2-tls12-in-tls13-ssl] -server = 48-curve-secp160r2-tls12-in-tls13-server -client = 48-curve-secp160r2-tls12-in-tls13-client +[53-curve-secp160r2-tls12-in-tls13-ssl] +server = 53-curve-secp160r2-tls12-in-tls13-server +client = 53-curve-secp160r2-tls12-in-tls13-client -[48-curve-secp160r2-tls12-in-tls13-server] +[53-curve-secp160r2-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r2:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[48-curve-secp160r2-tls12-in-tls13-client] +[53-curve-secp160r2-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r2:P-256 MaxProtocol = TLSv1.3 @@ -1516,7 +1676,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-48] +[test-53] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1524,21 +1684,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[49-curve-secp192k1-tls12-in-tls13] -ssl_conf = 49-curve-secp192k1-tls12-in-tls13-ssl +[54-curve-secp192k1-tls12-in-tls13] +ssl_conf = 54-curve-secp192k1-tls12-in-tls13-ssl -[49-curve-secp192k1-tls12-in-tls13-ssl] -server = 49-curve-secp192k1-tls12-in-tls13-server -client = 49-curve-secp192k1-tls12-in-tls13-client +[54-curve-secp192k1-tls12-in-tls13-ssl] +server = 54-curve-secp192k1-tls12-in-tls13-server +client = 54-curve-secp192k1-tls12-in-tls13-client -[49-curve-secp192k1-tls12-in-tls13-server] +[54-curve-secp192k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp192k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[49-curve-secp192k1-tls12-in-tls13-client] +[54-curve-secp192k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp192k1:P-256 MaxProtocol = TLSv1.3 @@ -1546,7 +1706,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-49] +[test-54] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1554,21 +1714,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[50-curve-secp224k1-tls12-in-tls13] -ssl_conf = 50-curve-secp224k1-tls12-in-tls13-ssl +[55-curve-secp224k1-tls12-in-tls13] +ssl_conf = 55-curve-secp224k1-tls12-in-tls13-ssl -[50-curve-secp224k1-tls12-in-tls13-ssl] -server = 50-curve-secp224k1-tls12-in-tls13-server -client = 50-curve-secp224k1-tls12-in-tls13-client +[55-curve-secp224k1-tls12-in-tls13-ssl] +server = 55-curve-secp224k1-tls12-in-tls13-server +client = 55-curve-secp224k1-tls12-in-tls13-client -[50-curve-secp224k1-tls12-in-tls13-server] +[55-curve-secp224k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[50-curve-secp224k1-tls12-in-tls13-client] +[55-curve-secp224k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224k1:P-256 MaxProtocol = TLSv1.3 @@ -1576,7 +1736,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-50] +[test-55] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1584,21 +1744,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[51-curve-secp256k1-tls12-in-tls13] -ssl_conf = 51-curve-secp256k1-tls12-in-tls13-ssl +[56-curve-secp256k1-tls12-in-tls13] +ssl_conf = 56-curve-secp256k1-tls12-in-tls13-ssl -[51-curve-secp256k1-tls12-in-tls13-ssl] -server = 51-curve-secp256k1-tls12-in-tls13-server -client = 51-curve-secp256k1-tls12-in-tls13-client +[56-curve-secp256k1-tls12-in-tls13-ssl] +server = 56-curve-secp256k1-tls12-in-tls13-server +client = 56-curve-secp256k1-tls12-in-tls13-client -[51-curve-secp256k1-tls12-in-tls13-server] +[56-curve-secp256k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp256k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[51-curve-secp256k1-tls12-in-tls13-client] +[56-curve-secp256k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp256k1:P-256 MaxProtocol = TLSv1.3 @@ -1606,7 +1766,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-51] +[test-56] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1614,21 +1774,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[52-curve-brainpoolP256r1-tls12-in-tls13] -ssl_conf = 52-curve-brainpoolP256r1-tls12-in-tls13-ssl +[57-curve-brainpoolP256r1-tls12-in-tls13] +ssl_conf = 57-curve-brainpoolP256r1-tls12-in-tls13-ssl -[52-curve-brainpoolP256r1-tls12-in-tls13-ssl] -server = 52-curve-brainpoolP256r1-tls12-in-tls13-server -client = 52-curve-brainpoolP256r1-tls12-in-tls13-client +[57-curve-brainpoolP256r1-tls12-in-tls13-ssl] +server = 57-curve-brainpoolP256r1-tls12-in-tls13-server +client = 57-curve-brainpoolP256r1-tls12-in-tls13-client -[52-curve-brainpoolP256r1-tls12-in-tls13-server] +[57-curve-brainpoolP256r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP256r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[52-curve-brainpoolP256r1-tls12-in-tls13-client] +[57-curve-brainpoolP256r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP256r1:P-256 MaxProtocol = TLSv1.3 @@ -1636,7 +1796,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-52] +[test-57] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1644,21 +1804,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[53-curve-brainpoolP384r1-tls12-in-tls13] -ssl_conf = 53-curve-brainpoolP384r1-tls12-in-tls13-ssl +[58-curve-brainpoolP384r1-tls12-in-tls13] +ssl_conf = 58-curve-brainpoolP384r1-tls12-in-tls13-ssl -[53-curve-brainpoolP384r1-tls12-in-tls13-ssl] -server = 53-curve-brainpoolP384r1-tls12-in-tls13-server -client = 53-curve-brainpoolP384r1-tls12-in-tls13-client +[58-curve-brainpoolP384r1-tls12-in-tls13-ssl] +server = 58-curve-brainpoolP384r1-tls12-in-tls13-server +client = 58-curve-brainpoolP384r1-tls12-in-tls13-client -[53-curve-brainpoolP384r1-tls12-in-tls13-server] +[58-curve-brainpoolP384r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP384r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[53-curve-brainpoolP384r1-tls12-in-tls13-client] +[58-curve-brainpoolP384r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP384r1:P-256 MaxProtocol = TLSv1.3 @@ -1666,7 +1826,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-53] +[test-58] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1674,21 +1834,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[54-curve-brainpoolP512r1-tls12-in-tls13] -ssl_conf = 54-curve-brainpoolP512r1-tls12-in-tls13-ssl +[59-curve-brainpoolP512r1-tls12-in-tls13] +ssl_conf = 59-curve-brainpoolP512r1-tls12-in-tls13-ssl -[54-curve-brainpoolP512r1-tls12-in-tls13-ssl] -server = 54-curve-brainpoolP512r1-tls12-in-tls13-server -client = 54-curve-brainpoolP512r1-tls12-in-tls13-client +[59-curve-brainpoolP512r1-tls12-in-tls13-ssl] +server = 59-curve-brainpoolP512r1-tls12-in-tls13-server +client = 59-curve-brainpoolP512r1-tls12-in-tls13-client -[54-curve-brainpoolP512r1-tls12-in-tls13-server] +[59-curve-brainpoolP512r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP512r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[54-curve-brainpoolP512r1-tls12-in-tls13-client] +[59-curve-brainpoolP512r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP512r1:P-256 MaxProtocol = TLSv1.3 @@ -1696,7 +1856,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-54] +[test-59] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1704,676 +1864,946 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[55-curve-sect233k1-tls13] -ssl_conf = 55-curve-sect233k1-tls13-ssl +[60-curve-sect233k1-tls13] +ssl_conf = 60-curve-sect233k1-tls13-ssl -[55-curve-sect233k1-tls13-ssl] -server = 55-curve-sect233k1-tls13-server -client = 55-curve-sect233k1-tls13-client +[60-curve-sect233k1-tls13-ssl] +server = 60-curve-sect233k1-tls13-server +client = 60-curve-sect233k1-tls13-client -[55-curve-sect233k1-tls13-server] +[60-curve-sect233k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect233k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[55-curve-sect233k1-tls13-client] +[60-curve-sect233k1-tls13-client] CipherString = ECDHE Curves = sect233k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-55] +[test-60] ExpectedResult = ClientFail # =========================================================== -[56-curve-sect233r1-tls13] -ssl_conf = 56-curve-sect233r1-tls13-ssl +[61-curve-sect233r1-tls13] +ssl_conf = 61-curve-sect233r1-tls13-ssl -[56-curve-sect233r1-tls13-ssl] -server = 56-curve-sect233r1-tls13-server -client = 56-curve-sect233r1-tls13-client +[61-curve-sect233r1-tls13-ssl] +server = 61-curve-sect233r1-tls13-server +client = 61-curve-sect233r1-tls13-client -[56-curve-sect233r1-tls13-server] +[61-curve-sect233r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect233r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[56-curve-sect233r1-tls13-client] +[61-curve-sect233r1-tls13-client] CipherString = ECDHE Curves = sect233r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-56] +[test-61] ExpectedResult = ClientFail # =========================================================== -[57-curve-sect283k1-tls13] -ssl_conf = 57-curve-sect283k1-tls13-ssl +[62-curve-sect283k1-tls13] +ssl_conf = 62-curve-sect283k1-tls13-ssl -[57-curve-sect283k1-tls13-ssl] -server = 57-curve-sect283k1-tls13-server -client = 57-curve-sect283k1-tls13-client +[62-curve-sect283k1-tls13-ssl] +server = 62-curve-sect283k1-tls13-server +client = 62-curve-sect283k1-tls13-client -[57-curve-sect283k1-tls13-server] +[62-curve-sect283k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect283k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[57-curve-sect283k1-tls13-client] +[62-curve-sect283k1-tls13-client] CipherString = ECDHE Curves = sect283k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-57] +[test-62] ExpectedResult = ClientFail # =========================================================== -[58-curve-sect283r1-tls13] -ssl_conf = 58-curve-sect283r1-tls13-ssl +[63-curve-sect283r1-tls13] +ssl_conf = 63-curve-sect283r1-tls13-ssl -[58-curve-sect283r1-tls13-ssl] -server = 58-curve-sect283r1-tls13-server -client = 58-curve-sect283r1-tls13-client +[63-curve-sect283r1-tls13-ssl] +server = 63-curve-sect283r1-tls13-server +client = 63-curve-sect283r1-tls13-client -[58-curve-sect283r1-tls13-server] +[63-curve-sect283r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect283r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[58-curve-sect283r1-tls13-client] +[63-curve-sect283r1-tls13-client] CipherString = ECDHE Curves = sect283r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-58] +[test-63] ExpectedResult = ClientFail # =========================================================== -[59-curve-sect409k1-tls13] -ssl_conf = 59-curve-sect409k1-tls13-ssl +[64-curve-sect409k1-tls13] +ssl_conf = 64-curve-sect409k1-tls13-ssl -[59-curve-sect409k1-tls13-ssl] -server = 59-curve-sect409k1-tls13-server -client = 59-curve-sect409k1-tls13-client +[64-curve-sect409k1-tls13-ssl] +server = 64-curve-sect409k1-tls13-server +client = 64-curve-sect409k1-tls13-client -[59-curve-sect409k1-tls13-server] +[64-curve-sect409k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect409k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[59-curve-sect409k1-tls13-client] +[64-curve-sect409k1-tls13-client] CipherString = ECDHE Curves = sect409k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-59] +[test-64] ExpectedResult = ClientFail # =========================================================== -[60-curve-sect409r1-tls13] -ssl_conf = 60-curve-sect409r1-tls13-ssl +[65-curve-sect409r1-tls13] +ssl_conf = 65-curve-sect409r1-tls13-ssl -[60-curve-sect409r1-tls13-ssl] -server = 60-curve-sect409r1-tls13-server -client = 60-curve-sect409r1-tls13-client +[65-curve-sect409r1-tls13-ssl] +server = 65-curve-sect409r1-tls13-server +client = 65-curve-sect409r1-tls13-client -[60-curve-sect409r1-tls13-server] +[65-curve-sect409r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect409r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[60-curve-sect409r1-tls13-client] +[65-curve-sect409r1-tls13-client] CipherString = ECDHE Curves = sect409r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-60] +[test-65] ExpectedResult = ClientFail # =========================================================== -[61-curve-sect571k1-tls13] -ssl_conf = 61-curve-sect571k1-tls13-ssl +[66-curve-sect571k1-tls13] +ssl_conf = 66-curve-sect571k1-tls13-ssl -[61-curve-sect571k1-tls13-ssl] -server = 61-curve-sect571k1-tls13-server -client = 61-curve-sect571k1-tls13-client +[66-curve-sect571k1-tls13-ssl] +server = 66-curve-sect571k1-tls13-server +client = 66-curve-sect571k1-tls13-client -[61-curve-sect571k1-tls13-server] +[66-curve-sect571k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect571k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[61-curve-sect571k1-tls13-client] +[66-curve-sect571k1-tls13-client] CipherString = ECDHE Curves = sect571k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-61] +[test-66] ExpectedResult = ClientFail # =========================================================== -[62-curve-sect571r1-tls13] -ssl_conf = 62-curve-sect571r1-tls13-ssl +[67-curve-sect571r1-tls13] +ssl_conf = 67-curve-sect571r1-tls13-ssl -[62-curve-sect571r1-tls13-ssl] -server = 62-curve-sect571r1-tls13-server -client = 62-curve-sect571r1-tls13-client +[67-curve-sect571r1-tls13-ssl] +server = 67-curve-sect571r1-tls13-server +client = 67-curve-sect571r1-tls13-client -[62-curve-sect571r1-tls13-server] +[67-curve-sect571r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect571r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[62-curve-sect571r1-tls13-client] +[67-curve-sect571r1-tls13-client] CipherString = ECDHE Curves = sect571r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-62] +[test-67] ExpectedResult = ClientFail # =========================================================== -[63-curve-secp224r1-tls13] -ssl_conf = 63-curve-secp224r1-tls13-ssl +[68-curve-secp224r1-tls13] +ssl_conf = 68-curve-secp224r1-tls13-ssl -[63-curve-secp224r1-tls13-ssl] -server = 63-curve-secp224r1-tls13-server -client = 63-curve-secp224r1-tls13-client +[68-curve-secp224r1-tls13-ssl] +server = 68-curve-secp224r1-tls13-server +client = 68-curve-secp224r1-tls13-client -[63-curve-secp224r1-tls13-server] +[68-curve-secp224r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp224r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[63-curve-secp224r1-tls13-client] +[68-curve-secp224r1-tls13-client] CipherString = ECDHE Curves = secp224r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-63] +[test-68] ExpectedResult = ClientFail # =========================================================== -[64-curve-sect163k1-tls13] -ssl_conf = 64-curve-sect163k1-tls13-ssl +[69-curve-sect163k1-tls13] +ssl_conf = 69-curve-sect163k1-tls13-ssl -[64-curve-sect163k1-tls13-ssl] -server = 64-curve-sect163k1-tls13-server -client = 64-curve-sect163k1-tls13-client +[69-curve-sect163k1-tls13-ssl] +server = 69-curve-sect163k1-tls13-server +client = 69-curve-sect163k1-tls13-client -[64-curve-sect163k1-tls13-server] +[69-curve-sect163k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect163k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[64-curve-sect163k1-tls13-client] +[69-curve-sect163k1-tls13-client] CipherString = ECDHE Curves = sect163k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-64] +[test-69] ExpectedResult = ClientFail # =========================================================== -[65-curve-sect163r2-tls13] -ssl_conf = 65-curve-sect163r2-tls13-ssl +[70-curve-sect163r2-tls13] +ssl_conf = 70-curve-sect163r2-tls13-ssl -[65-curve-sect163r2-tls13-ssl] -server = 65-curve-sect163r2-tls13-server -client = 65-curve-sect163r2-tls13-client +[70-curve-sect163r2-tls13-ssl] +server = 70-curve-sect163r2-tls13-server +client = 70-curve-sect163r2-tls13-client -[65-curve-sect163r2-tls13-server] +[70-curve-sect163r2-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect163r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[65-curve-sect163r2-tls13-client] +[70-curve-sect163r2-tls13-client] CipherString = ECDHE Curves = sect163r2 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-65] +[test-70] ExpectedResult = ClientFail # =========================================================== -[66-curve-prime192v1-tls13] -ssl_conf = 66-curve-prime192v1-tls13-ssl +[71-curve-prime192v1-tls13] +ssl_conf = 71-curve-prime192v1-tls13-ssl -[66-curve-prime192v1-tls13-ssl] -server = 66-curve-prime192v1-tls13-server -client = 66-curve-prime192v1-tls13-client +[71-curve-prime192v1-tls13-ssl] +server = 71-curve-prime192v1-tls13-server +client = 71-curve-prime192v1-tls13-client -[66-curve-prime192v1-tls13-server] +[71-curve-prime192v1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = prime192v1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[66-curve-prime192v1-tls13-client] +[71-curve-prime192v1-tls13-client] CipherString = ECDHE Curves = prime192v1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-66] +[test-71] ExpectedResult = ClientFail # =========================================================== -[67-curve-sect163r1-tls13] -ssl_conf = 67-curve-sect163r1-tls13-ssl +[72-curve-sect163r1-tls13] +ssl_conf = 72-curve-sect163r1-tls13-ssl -[67-curve-sect163r1-tls13-ssl] -server = 67-curve-sect163r1-tls13-server -client = 67-curve-sect163r1-tls13-client +[72-curve-sect163r1-tls13-ssl] +server = 72-curve-sect163r1-tls13-server +client = 72-curve-sect163r1-tls13-client -[67-curve-sect163r1-tls13-server] +[72-curve-sect163r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect163r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[67-curve-sect163r1-tls13-client] +[72-curve-sect163r1-tls13-client] CipherString = ECDHE Curves = sect163r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-67] +[test-72] ExpectedResult = ClientFail # =========================================================== -[68-curve-sect193r1-tls13] -ssl_conf = 68-curve-sect193r1-tls13-ssl +[73-curve-sect193r1-tls13] +ssl_conf = 73-curve-sect193r1-tls13-ssl -[68-curve-sect193r1-tls13-ssl] -server = 68-curve-sect193r1-tls13-server -client = 68-curve-sect193r1-tls13-client +[73-curve-sect193r1-tls13-ssl] +server = 73-curve-sect193r1-tls13-server +client = 73-curve-sect193r1-tls13-client -[68-curve-sect193r1-tls13-server] +[73-curve-sect193r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect193r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[68-curve-sect193r1-tls13-client] +[73-curve-sect193r1-tls13-client] CipherString = ECDHE Curves = sect193r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-68] +[test-73] ExpectedResult = ClientFail # =========================================================== -[69-curve-sect193r2-tls13] -ssl_conf = 69-curve-sect193r2-tls13-ssl +[74-curve-sect193r2-tls13] +ssl_conf = 74-curve-sect193r2-tls13-ssl -[69-curve-sect193r2-tls13-ssl] -server = 69-curve-sect193r2-tls13-server -client = 69-curve-sect193r2-tls13-client +[74-curve-sect193r2-tls13-ssl] +server = 74-curve-sect193r2-tls13-server +client = 74-curve-sect193r2-tls13-client -[69-curve-sect193r2-tls13-server] +[74-curve-sect193r2-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect193r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[69-curve-sect193r2-tls13-client] +[74-curve-sect193r2-tls13-client] CipherString = ECDHE Curves = sect193r2 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-69] +[test-74] ExpectedResult = ClientFail # =========================================================== -[70-curve-sect239k1-tls13] -ssl_conf = 70-curve-sect239k1-tls13-ssl +[75-curve-sect239k1-tls13] +ssl_conf = 75-curve-sect239k1-tls13-ssl -[70-curve-sect239k1-tls13-ssl] -server = 70-curve-sect239k1-tls13-server -client = 70-curve-sect239k1-tls13-client +[75-curve-sect239k1-tls13-ssl] +server = 75-curve-sect239k1-tls13-server +client = 75-curve-sect239k1-tls13-client -[70-curve-sect239k1-tls13-server] +[75-curve-sect239k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = sect239k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[70-curve-sect239k1-tls13-client] +[75-curve-sect239k1-tls13-client] CipherString = ECDHE Curves = sect239k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-70] +[test-75] ExpectedResult = ClientFail # =========================================================== -[71-curve-secp160k1-tls13] -ssl_conf = 71-curve-secp160k1-tls13-ssl +[76-curve-secp160k1-tls13] +ssl_conf = 76-curve-secp160k1-tls13-ssl -[71-curve-secp160k1-tls13-ssl] -server = 71-curve-secp160k1-tls13-server -client = 71-curve-secp160k1-tls13-client +[76-curve-secp160k1-tls13-ssl] +server = 76-curve-secp160k1-tls13-server +client = 76-curve-secp160k1-tls13-client -[71-curve-secp160k1-tls13-server] +[76-curve-secp160k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp160k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[71-curve-secp160k1-tls13-client] +[76-curve-secp160k1-tls13-client] CipherString = ECDHE Curves = secp160k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-71] +[test-76] ExpectedResult = ClientFail # =========================================================== -[72-curve-secp160r1-tls13] -ssl_conf = 72-curve-secp160r1-tls13-ssl +[77-curve-secp160r1-tls13] +ssl_conf = 77-curve-secp160r1-tls13-ssl -[72-curve-secp160r1-tls13-ssl] -server = 72-curve-secp160r1-tls13-server -client = 72-curve-secp160r1-tls13-client +[77-curve-secp160r1-tls13-ssl] +server = 77-curve-secp160r1-tls13-server +client = 77-curve-secp160r1-tls13-client -[72-curve-secp160r1-tls13-server] +[77-curve-secp160r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp160r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[72-curve-secp160r1-tls13-client] +[77-curve-secp160r1-tls13-client] CipherString = ECDHE Curves = secp160r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-72] +[test-77] ExpectedResult = ClientFail # =========================================================== -[73-curve-secp160r2-tls13] -ssl_conf = 73-curve-secp160r2-tls13-ssl +[78-curve-secp160r2-tls13] +ssl_conf = 78-curve-secp160r2-tls13-ssl -[73-curve-secp160r2-tls13-ssl] -server = 73-curve-secp160r2-tls13-server -client = 73-curve-secp160r2-tls13-client +[78-curve-secp160r2-tls13-ssl] +server = 78-curve-secp160r2-tls13-server +client = 78-curve-secp160r2-tls13-client -[73-curve-secp160r2-tls13-server] +[78-curve-secp160r2-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp160r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[73-curve-secp160r2-tls13-client] +[78-curve-secp160r2-tls13-client] CipherString = ECDHE Curves = secp160r2 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-73] +[test-78] ExpectedResult = ClientFail # =========================================================== -[74-curve-secp192k1-tls13] -ssl_conf = 74-curve-secp192k1-tls13-ssl +[79-curve-secp192k1-tls13] +ssl_conf = 79-curve-secp192k1-tls13-ssl -[74-curve-secp192k1-tls13-ssl] -server = 74-curve-secp192k1-tls13-server -client = 74-curve-secp192k1-tls13-client +[79-curve-secp192k1-tls13-ssl] +server = 79-curve-secp192k1-tls13-server +client = 79-curve-secp192k1-tls13-client -[74-curve-secp192k1-tls13-server] +[79-curve-secp192k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp192k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[74-curve-secp192k1-tls13-client] +[79-curve-secp192k1-tls13-client] CipherString = ECDHE Curves = secp192k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-74] +[test-79] ExpectedResult = ClientFail # =========================================================== -[75-curve-secp224k1-tls13] -ssl_conf = 75-curve-secp224k1-tls13-ssl +[80-curve-secp224k1-tls13] +ssl_conf = 80-curve-secp224k1-tls13-ssl -[75-curve-secp224k1-tls13-ssl] -server = 75-curve-secp224k1-tls13-server -client = 75-curve-secp224k1-tls13-client +[80-curve-secp224k1-tls13-ssl] +server = 80-curve-secp224k1-tls13-server +client = 80-curve-secp224k1-tls13-client -[75-curve-secp224k1-tls13-server] +[80-curve-secp224k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp224k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[75-curve-secp224k1-tls13-client] +[80-curve-secp224k1-tls13-client] CipherString = ECDHE Curves = secp224k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-75] +[test-80] ExpectedResult = ClientFail # =========================================================== -[76-curve-secp256k1-tls13] -ssl_conf = 76-curve-secp256k1-tls13-ssl +[81-curve-secp256k1-tls13] +ssl_conf = 81-curve-secp256k1-tls13-ssl -[76-curve-secp256k1-tls13-ssl] -server = 76-curve-secp256k1-tls13-server -client = 76-curve-secp256k1-tls13-client +[81-curve-secp256k1-tls13-ssl] +server = 81-curve-secp256k1-tls13-server +client = 81-curve-secp256k1-tls13-client -[76-curve-secp256k1-tls13-server] +[81-curve-secp256k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = secp256k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[76-curve-secp256k1-tls13-client] +[81-curve-secp256k1-tls13-client] CipherString = ECDHE Curves = secp256k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-76] +[test-81] ExpectedResult = ClientFail # =========================================================== -[77-curve-brainpoolP256r1-tls13] -ssl_conf = 77-curve-brainpoolP256r1-tls13-ssl +[82-curve-brainpoolP256r1-tls13] +ssl_conf = 82-curve-brainpoolP256r1-tls13-ssl -[77-curve-brainpoolP256r1-tls13-ssl] -server = 77-curve-brainpoolP256r1-tls13-server -client = 77-curve-brainpoolP256r1-tls13-client +[82-curve-brainpoolP256r1-tls13-ssl] +server = 82-curve-brainpoolP256r1-tls13-server +client = 82-curve-brainpoolP256r1-tls13-client -[77-curve-brainpoolP256r1-tls13-server] +[82-curve-brainpoolP256r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = brainpoolP256r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[77-curve-brainpoolP256r1-tls13-client] +[82-curve-brainpoolP256r1-tls13-client] CipherString = ECDHE Curves = brainpoolP256r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-77] +[test-82] ExpectedResult = ClientFail # =========================================================== -[78-curve-brainpoolP384r1-tls13] -ssl_conf = 78-curve-brainpoolP384r1-tls13-ssl +[83-curve-brainpoolP384r1-tls13] +ssl_conf = 83-curve-brainpoolP384r1-tls13-ssl -[78-curve-brainpoolP384r1-tls13-ssl] -server = 78-curve-brainpoolP384r1-tls13-server -client = 78-curve-brainpoolP384r1-tls13-client +[83-curve-brainpoolP384r1-tls13-ssl] +server = 83-curve-brainpoolP384r1-tls13-server +client = 83-curve-brainpoolP384r1-tls13-client -[78-curve-brainpoolP384r1-tls13-server] +[83-curve-brainpoolP384r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = brainpoolP384r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[78-curve-brainpoolP384r1-tls13-client] +[83-curve-brainpoolP384r1-tls13-client] CipherString = ECDHE Curves = brainpoolP384r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-78] +[test-83] ExpectedResult = ClientFail # =========================================================== -[79-curve-brainpoolP512r1-tls13] -ssl_conf = 79-curve-brainpoolP512r1-tls13-ssl +[84-curve-brainpoolP512r1-tls13] +ssl_conf = 84-curve-brainpoolP512r1-tls13-ssl -[79-curve-brainpoolP512r1-tls13-ssl] -server = 79-curve-brainpoolP512r1-tls13-server -client = 79-curve-brainpoolP512r1-tls13-client +[84-curve-brainpoolP512r1-tls13-ssl] +server = 84-curve-brainpoolP512r1-tls13-server +client = 84-curve-brainpoolP512r1-tls13-client -[79-curve-brainpoolP512r1-tls13-server] +[84-curve-brainpoolP512r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = brainpoolP512r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[79-curve-brainpoolP512r1-tls13-client] +[84-curve-brainpoolP512r1-tls13-client] CipherString = ECDHE Curves = brainpoolP512r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-79] +[test-84] ExpectedResult = ClientFail +# =========================================================== + +[85-curve-ffdhe2048-tls13-in-tls12] +ssl_conf = 85-curve-ffdhe2048-tls13-in-tls12-ssl + +[85-curve-ffdhe2048-tls13-in-tls12-ssl] +server = 85-curve-ffdhe2048-tls13-in-tls12-server +client = 85-curve-ffdhe2048-tls13-in-tls12-client + +[85-curve-ffdhe2048-tls13-in-tls12-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe2048 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[85-curve-ffdhe2048-tls13-in-tls12-client] +CipherString = ECDHE@SECLEVEL=1 +Curves = ffdhe2048 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-85] +ExpectedResult = ServerFail + + +# =========================================================== + +[86-curve-ffdhe2048-tls13-in-tls12-2] +ssl_conf = 86-curve-ffdhe2048-tls13-in-tls12-2-ssl + +[86-curve-ffdhe2048-tls13-in-tls12-2-ssl] +server = 86-curve-ffdhe2048-tls13-in-tls12-2-server +client = 86-curve-ffdhe2048-tls13-in-tls12-2-client + +[86-curve-ffdhe2048-tls13-in-tls12-2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe2048 +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[86-curve-ffdhe2048-tls13-in-tls12-2-client] +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe2048 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-86] +ExpectedResult = Success + + +# =========================================================== + +[87-curve-ffdhe3072-tls13-in-tls12] +ssl_conf = 87-curve-ffdhe3072-tls13-in-tls12-ssl + +[87-curve-ffdhe3072-tls13-in-tls12-ssl] +server = 87-curve-ffdhe3072-tls13-in-tls12-server +client = 87-curve-ffdhe3072-tls13-in-tls12-client + +[87-curve-ffdhe3072-tls13-in-tls12-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe3072 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[87-curve-ffdhe3072-tls13-in-tls12-client] +CipherString = ECDHE@SECLEVEL=1 +Curves = ffdhe3072 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-87] +ExpectedResult = ServerFail + + +# =========================================================== + +[88-curve-ffdhe3072-tls13-in-tls12-2] +ssl_conf = 88-curve-ffdhe3072-tls13-in-tls12-2-ssl + +[88-curve-ffdhe3072-tls13-in-tls12-2-ssl] +server = 88-curve-ffdhe3072-tls13-in-tls12-2-server +client = 88-curve-ffdhe3072-tls13-in-tls12-2-client + +[88-curve-ffdhe3072-tls13-in-tls12-2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe3072 +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[88-curve-ffdhe3072-tls13-in-tls12-2-client] +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe3072 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-88] +ExpectedResult = Success + + +# =========================================================== + +[89-curve-ffdhe4096-tls13-in-tls12] +ssl_conf = 89-curve-ffdhe4096-tls13-in-tls12-ssl + +[89-curve-ffdhe4096-tls13-in-tls12-ssl] +server = 89-curve-ffdhe4096-tls13-in-tls12-server +client = 89-curve-ffdhe4096-tls13-in-tls12-client + +[89-curve-ffdhe4096-tls13-in-tls12-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe4096 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[89-curve-ffdhe4096-tls13-in-tls12-client] +CipherString = ECDHE@SECLEVEL=1 +Curves = ffdhe4096 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-89] +ExpectedResult = ServerFail + + +# =========================================================== + +[90-curve-ffdhe4096-tls13-in-tls12-2] +ssl_conf = 90-curve-ffdhe4096-tls13-in-tls12-2-ssl + +[90-curve-ffdhe4096-tls13-in-tls12-2-ssl] +server = 90-curve-ffdhe4096-tls13-in-tls12-2-server +client = 90-curve-ffdhe4096-tls13-in-tls12-2-client + +[90-curve-ffdhe4096-tls13-in-tls12-2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe4096 +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[90-curve-ffdhe4096-tls13-in-tls12-2-client] +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe4096 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-90] +ExpectedResult = Success + + +# =========================================================== + +[91-curve-ffdhe6144-tls13-in-tls12] +ssl_conf = 91-curve-ffdhe6144-tls13-in-tls12-ssl + +[91-curve-ffdhe6144-tls13-in-tls12-ssl] +server = 91-curve-ffdhe6144-tls13-in-tls12-server +client = 91-curve-ffdhe6144-tls13-in-tls12-client + +[91-curve-ffdhe6144-tls13-in-tls12-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe6144 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[91-curve-ffdhe6144-tls13-in-tls12-client] +CipherString = ECDHE@SECLEVEL=1 +Curves = ffdhe6144 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-91] +ExpectedResult = ServerFail + + +# =========================================================== + +[92-curve-ffdhe6144-tls13-in-tls12-2] +ssl_conf = 92-curve-ffdhe6144-tls13-in-tls12-2-ssl + +[92-curve-ffdhe6144-tls13-in-tls12-2-ssl] +server = 92-curve-ffdhe6144-tls13-in-tls12-2-server +client = 92-curve-ffdhe6144-tls13-in-tls12-2-client + +[92-curve-ffdhe6144-tls13-in-tls12-2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe6144 +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[92-curve-ffdhe6144-tls13-in-tls12-2-client] +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe6144 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-92] +ExpectedResult = Success + + +# =========================================================== + +[93-curve-ffdhe8192-tls13-in-tls12] +ssl_conf = 93-curve-ffdhe8192-tls13-in-tls12-ssl + +[93-curve-ffdhe8192-tls13-in-tls12-ssl] +server = 93-curve-ffdhe8192-tls13-in-tls12-server +client = 93-curve-ffdhe8192-tls13-in-tls12-client + +[93-curve-ffdhe8192-tls13-in-tls12-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe8192 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[93-curve-ffdhe8192-tls13-in-tls12-client] +CipherString = ECDHE@SECLEVEL=1 +Curves = ffdhe8192 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-93] +ExpectedResult = ServerFail + + +# =========================================================== + +[94-curve-ffdhe8192-tls13-in-tls12-2] +ssl_conf = 94-curve-ffdhe8192-tls13-in-tls12-2-ssl + +[94-curve-ffdhe8192-tls13-in-tls12-2-ssl] +server = 94-curve-ffdhe8192-tls13-in-tls12-2-server +client = 94-curve-ffdhe8192-tls13-in-tls12-2-client + +[94-curve-ffdhe8192-tls13-in-tls12-2-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe8192 +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[94-curve-ffdhe8192-tls13-in-tls12-2-client] +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe8192 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-94] +ExpectedResult = Success + + diff --git a/deps/openssl/openssl/test/ssl-tests/14-curves.cnf.in b/deps/openssl/openssl/test/ssl-tests/14-curves.cnf.in index 5653e70bef21c4..1e003bace0b7a4 100644 --- a/deps/openssl/openssl/test/ssl-tests/14-curves.cnf.in +++ b/deps/openssl/openssl/test/ssl-tests/14-curves.cnf.in @@ -15,6 +15,12 @@ our $fips_mode; my @curves = ("prime256v1", "secp384r1", "secp521r1", "X25519", "X448"); +#Curves *only* suitable for use in TLSv1.3 +my @curves_tls_1_3 = ("ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144", + "ffdhe8192"); + +push @curves, @curves_tls_1_3; + my @curves_tls_1_2 = ("sect233k1", "sect233r1", "sect283k1", "sect283r1", "sect409k1", "sect409r1", "sect571k1", "sect571r1", "secp224r1"); @@ -29,6 +35,19 @@ push @curves_tls_1_2, @curves_non_fips if !$fips_mode; our @tests = (); +sub get_key_type { + my $group = shift; + my $keyType; + + if ($group =~ /ffdhe/) { + $keyType = "dhKeyAgreement"; + } else { + $keyType = $group; + } + + return $keyType; +} + sub generate_tests() { foreach (0..$#curves) { my $curve = $curves[$_]; @@ -44,7 +63,7 @@ sub generate_tests() { "Curves" => $curve }, test => { - "ExpectedTmpKeyType" => $curve, + "ExpectedTmpKeyType" => get_key_type($curve), "ExpectedProtocol" => "TLSv1.3", "ExpectedResult" => "Success" }, @@ -64,7 +83,7 @@ sub generate_tests() { "Curves" => $curve }, test => { - "ExpectedTmpKeyType" => $curve, + "ExpectedTmpKeyType" => get_key_type($curve), "ExpectedProtocol" => "TLSv1.2", "ExpectedResult" => "Success" }, @@ -112,6 +131,47 @@ sub generate_tests() { }, }; } + foreach (0..$#curves_tls_1_3) { + my $curve = $curves_tls_1_3[$_]; + push @tests, { + name => "curve-${curve}-tls13-in-tls12", + server => { + "Curves" => $curve, + "CipherString" => 'DEFAULT@SECLEVEL=1', + "MaxProtocol" => "TLSv1.3" + }, + client => { + "CipherString" => 'ECDHE@SECLEVEL=1', + "MaxProtocol" => "TLSv1.2", + "Curves" => $curve + }, + test => { + #These curves are only suitable for TLSv1.3 so we expect the + #server to fail because it has no shared groups for TLSv1.2 + #ECDHE key exchange + "ExpectedResult" => "ServerFail" + }, + }; + push @tests, { + name => "curve-${curve}-tls13-in-tls12-2", + server => { + "Curves" => $curve, + "CipherString" => 'DEFAULT@SECLEVEL=1', + "MaxProtocol" => "TLSv1.2" + }, + client => { + "CipherString" => 'DEFAULT@SECLEVEL=1', + "MaxProtocol" => "TLSv1.3", + "Curves" => $curve + }, + test => { + #These curves are only suitable for TLSv1.3. We expect TLSv1.2 + #negotiation to succeed because we fall back to some other + #ciphersuite + "ExpectedResult" => "Success" + }, + }; + } } generate_tests(); diff --git a/deps/openssl/openssl/test/sslapitest.c b/deps/openssl/openssl/test/sslapitest.c index 0a775c9b1d4536..3d0319ee3881af 100644 --- a/deps/openssl/openssl/test/sslapitest.c +++ b/deps/openssl/openssl/test/sslapitest.c @@ -948,18 +948,13 @@ static int test_ccs_change_cipher(void) } #endif -static int execute_test_large_message(const SSL_METHOD *smeth, - const SSL_METHOD *cmeth, - int min_version, int max_version, - int read_ahead) +static int add_large_cert_chain(SSL_CTX *sctx) { - SSL_CTX *cctx = NULL, *sctx = NULL; - SSL *clientssl = NULL, *serverssl = NULL; - int testresult = 0; - int i; BIO *certbio = NULL; X509 *chaincert = NULL; int certlen; + int ret = 0; + int i; if (!TEST_ptr(certbio = BIO_new_file(cert, "r"))) goto end; @@ -972,6 +967,41 @@ static int execute_test_large_message(const SSL_METHOD *smeth, BIO_free(certbio); certbio = NULL; + /* + * We assume the supplied certificate is big enough so that if we add + * NUM_EXTRA_CERTS it will make the overall message large enough. The + * default buffer size is requested to be 16k, but due to the way BUF_MEM + * works, it ends up allocating a little over 21k (16 * 4/3). So, in this + * test we need to have a message larger than that. + */ + certlen = i2d_X509(chaincert, NULL); + OPENSSL_assert(certlen * NUM_EXTRA_CERTS > + (SSL3_RT_MAX_PLAIN_LENGTH * 4) / 3); + for (i = 0; i < NUM_EXTRA_CERTS; i++) { + if (!X509_up_ref(chaincert)) + goto end; + if (!SSL_CTX_add_extra_chain_cert(sctx, chaincert)) { + X509_free(chaincert); + goto end; + } + } + + ret = 1; + end: + BIO_free(certbio); + X509_free(chaincert); + return ret; +} + +static int execute_test_large_message(const SSL_METHOD *smeth, + const SSL_METHOD *cmeth, + int min_version, int max_version, + int read_ahead) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, min_version, max_version, &sctx, &cctx, cert, privkey))) @@ -998,24 +1028,8 @@ static int execute_test_large_message(const SSL_METHOD *smeth, SSL_CTX_set_read_ahead(cctx, 1); } - /* - * We assume the supplied certificate is big enough so that if we add - * NUM_EXTRA_CERTS it will make the overall message large enough. The - * default buffer size is requested to be 16k, but due to the way BUF_MEM - * works, it ends up allocating a little over 21k (16 * 4/3). So, in this - * test we need to have a message larger than that. - */ - certlen = i2d_X509(chaincert, NULL); - OPENSSL_assert(certlen * NUM_EXTRA_CERTS > - (SSL3_RT_MAX_PLAIN_LENGTH * 4) / 3); - for (i = 0; i < NUM_EXTRA_CERTS; i++) { - if (!X509_up_ref(chaincert)) - goto end; - if (!SSL_CTX_add_extra_chain_cert(sctx, chaincert)) { - X509_free(chaincert); - goto end; - } - } + if (!add_large_cert_chain(sctx)) + goto end; if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) @@ -1032,8 +1046,6 @@ static int execute_test_large_message(const SSL_METHOD *smeth, testresult = 1; end: - BIO_free(certbio); - X509_free(chaincert); SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); @@ -10076,7 +10088,6 @@ static int test_inherit_verify_param(void) return testresult; } - static int test_load_dhfile(void) { #ifndef OPENSSL_NO_DH @@ -10298,12 +10309,108 @@ static int test_pipelining(int idx) ENGINE_finish(e); ENGINE_free(e); OPENSSL_free(buf); - if (idx == 5) + if (fragsize == SSL3_RT_MAX_PLAIN_LENGTH) OPENSSL_free(msg); return testresult; } #endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) */ +/* + * Force a write retry during handshaking. We test various combinations of + * scenarios. We test a large certificate message which will fill the buffering + * BIO used in the handshake. We try with client auth on and off. Finally we + * also try a BIO that indicates retry via a 0 return. BIO_write() is documented + * to indicate retry via -1 - but sometimes BIOs don't do that. + * + * Test 0: Standard certificate message + * Test 1: Large certificate message + * Test 2: Standard cert, verify peer + * Test 3: Large cert, verify peer + * Test 4: Standard cert, BIO returns 0 on retry + * Test 5: Large cert, BIO returns 0 on retry + * Test 6: Standard cert, verify peer, BIO returns 0 on retry + * Test 7: Large cert, verify peer, BIO returns 0 on retry + * Test 8-15: Repeat of above with TLSv1.2 + */ +static int test_handshake_retry(int idx) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + BIO *tmp = NULL, *bretry = BIO_new(bio_s_always_retry()); + int maxversion = 0; + + if (!TEST_ptr(bretry)) + goto end; + +#ifndef OPENSSL_NO_TLS1_2 + if ((idx & 8) == 8) + maxversion = TLS1_2_VERSION; +#else + if ((idx & 8) == 8) + return TEST_skip("No TLSv1.2"); +#endif + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), 0, maxversion, + &sctx, &cctx, cert, privkey))) + goto end; + + /* + * Add a large amount of data to fill the buffering BIO used by the SSL + * object + */ + if ((idx & 1) == 1 && !add_large_cert_chain(sctx)) + goto end; + + /* + * We don't actually configure a client cert, but neither do we fail if one + * isn't present. + */ + if ((idx & 2) == 2) + SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER, NULL); + + if ((idx & 4) == 4) + set_always_retry_err_val(0); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL))) + goto end; + + tmp = SSL_get_wbio(serverssl); + if (!TEST_ptr(tmp) || !TEST_true(BIO_up_ref(tmp))) { + tmp = NULL; + goto end; + } + SSL_set0_wbio(serverssl, bretry); + bretry = NULL; + + if (!TEST_int_eq(SSL_connect(clientssl), -1)) + goto end; + + if (!TEST_int_eq(SSL_accept(serverssl), -1) + || !TEST_int_eq(SSL_get_error(serverssl, -1), SSL_ERROR_WANT_WRITE)) + goto end; + + /* Restore a BIO that will let the write succeed */ + SSL_set0_wbio(serverssl, tmp); + tmp = NULL; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + BIO_free(bretry); + BIO_free(tmp); + set_always_retry_err_val(-1); + return testresult; +} + #ifndef OPENSSL_NO_QUIC static int test_quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, @@ -10441,6 +10548,11 @@ static int test_quic_api_version(int clnt, int srvr) testresult = 1; end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; } @@ -10929,6 +11041,7 @@ int setup_tests(void) #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE) ADD_ALL_TESTS(test_pipelining, 6); #endif + ADD_ALL_TESTS(test_handshake_retry, 16); #ifndef OPENSSL_NO_QUIC ADD_ALL_TESTS(test_quic_api, 9); # ifndef OSSL_NO_USABLE_TLS1_3 diff --git a/deps/openssl/openssl/test/testutil/provider.c b/deps/openssl/openssl/test/testutil/provider.c index 5d5991f502584e..79ae13b42a1f0f 100644 --- a/deps/openssl/openssl/test/testutil/provider.c +++ b/deps/openssl/openssl/test/testutil/provider.c @@ -177,11 +177,11 @@ int fips_provider_version_match(OSSL_LIB_CTX *libctx, const char *versions) } mode; while (*versions != '\0') { - for (; isspace(*versions); versions++) + for (; isspace((unsigned char)(*versions)); versions++) continue; if (*versions == '\0') break; - for (p = versions; *versions != '\0' && !isspace(*versions); versions++) + for (p = versions; *versions != '\0' && !isspace((unsigned char)(*versions)); versions++) continue; if (*p == '!') { mode = MODE_NE; @@ -201,7 +201,7 @@ int fips_provider_version_match(OSSL_LIB_CTX *libctx, const char *versions) } else if (*p == '>') { mode = MODE_GT; p++; - } else if (isdigit(*p)) { + } else if (isdigit((unsigned char)*p)) { mode = MODE_EQ; } else { TEST_info("Error matching FIPS version: mode %s\n", p); diff --git a/deps/simdutf/simdutf.cpp b/deps/simdutf/simdutf.cpp index 712bf0cf85833a..eb3c53ba069ede 100644 --- a/deps/simdutf/simdutf.cpp +++ b/deps/simdutf/simdutf.cpp @@ -1,8 +1,8 @@ -/* auto-generated on 2023-06-05 08:58:28 -0400. Do not edit! */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf.cpp +/* auto-generated on 2023-08-11 13:30:54 -0400. Do not edit! */ +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf.cpp /* begin file src/simdutf.cpp */ #include "simdutf.h" -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=implementation.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=implementation.cpp /* begin file src/implementation.cpp */ #include #include @@ -26,7 +26,7 @@ std::string toBinaryString(T b) { // Implementations // The best choice should always come first! -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64.h /* begin file src/simdutf/arm64.h */ #ifndef SIMDUTF_ARM64_H #define SIMDUTF_ARM64_H @@ -53,7 +53,7 @@ namespace arm64 { } // namespace arm64 } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/implementation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/implementation.h /* begin file src/simdutf/arm64/implementation.h */ #ifndef SIMDUTF_ARM64_IMPLEMENTATION_H #define SIMDUTF_ARM64_IMPLEMENTATION_H @@ -130,14 +130,14 @@ class implementation final : public simdutf::implementation { #endif // SIMDUTF_ARM64_IMPLEMENTATION_H /* end file src/simdutf/arm64/implementation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/begin.h /* begin file src/simdutf/arm64/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "arm64" // #define SIMDUTF_IMPLEMENTATION arm64 /* end file src/simdutf/arm64/begin.h */ // Declarations -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/intrinsics.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/intrinsics.h /* begin file src/simdutf/arm64/intrinsics.h */ #ifndef SIMDUTF_ARM64_INTRINSICS_H #define SIMDUTF_ARM64_INTRINSICS_H @@ -149,7 +149,7 @@ class implementation final : public simdutf::implementation { #endif // SIMDUTF_ARM64_INTRINSICS_H /* end file src/simdutf/arm64/intrinsics.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/bitmanipulation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/bitmanipulation.h /* begin file src/simdutf/arm64/bitmanipulation.h */ #ifndef SIMDUTF_ARM64_BITMANIPULATION_H #define SIMDUTF_ARM64_BITMANIPULATION_H @@ -169,7 +169,7 @@ simdutf_really_inline int count_ones(uint64_t input_num) { #endif // SIMDUTF_ARM64_BITMANIPULATION_H /* end file src/simdutf/arm64/bitmanipulation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/simd.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/simd.h /* begin file src/simdutf/arm64/simd.h */ #ifndef SIMDUTF_ARM64_SIMD_H #define SIMDUTF_ARM64_SIMD_H @@ -782,7 +782,7 @@ simdutf_really_inline int16x8_t make_int16x8_t(int16_t x1, int16_t x2, int16_t ).to_bitmask(); } }; // struct simd8x64 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/simd16-inl.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/simd16-inl.h /* begin file src/simdutf/arm64/simd16-inl.h */ template struct simd16; @@ -1095,7 +1095,7 @@ simdutf_really_inline simd16::operator simd16() const { retur #endif // SIMDUTF_ARM64_SIMD_H /* end file src/simdutf/arm64/simd.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/end.h /* begin file src/simdutf/arm64/end.h */ /* end file src/simdutf/arm64/end.h */ @@ -1103,7 +1103,7 @@ simdutf_really_inline simd16::operator simd16() const { retur #endif // SIMDUTF_ARM64_H /* end file src/simdutf/arm64.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake.h /* begin file src/simdutf/icelake.h */ #ifndef SIMDUTF_ICELAKE_H #define SIMDUTF_ICELAKE_H @@ -1155,7 +1155,7 @@ namespace icelake { // // These two need to be included outside SIMDUTF_TARGET_REGION // -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake/intrinsics.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake/intrinsics.h /* begin file src/simdutf/icelake/intrinsics.h */ #ifndef SIMDUTF_ICELAKE_INTRINSICS_H #define SIMDUTF_ICELAKE_INTRINSICS_H @@ -1265,7 +1265,7 @@ inline __m512i _mm512_set_epi8(uint8_t a0, uint8_t a1, uint8_t a2, uint8_t a3, u #endif // SIMDUTF_HASWELL_INTRINSICS_H /* end file src/simdutf/icelake/intrinsics.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake/implementation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake/implementation.h /* begin file src/simdutf/icelake/implementation.h */ #ifndef SIMDUTF_ICELAKE_IMPLEMENTATION_H #define SIMDUTF_ICELAKE_IMPLEMENTATION_H @@ -1348,7 +1348,7 @@ class implementation final : public simdutf::implementation { // // The rest need to be inside the region // -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake/begin.h /* begin file src/simdutf/icelake/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "icelake" // #define SIMDUTF_IMPLEMENTATION icelake @@ -1364,7 +1364,7 @@ SIMDUTF_DISABLE_GCC_WARNING(-Wmaybe-uninitialized) #endif // end of workaround /* end file src/simdutf/icelake/begin.h */ // Declarations -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake/bitmanipulation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake/bitmanipulation.h /* begin file src/simdutf/icelake/bitmanipulation.h */ #ifndef SIMDUTF_ICELAKE_BITMANIPULATION_H #define SIMDUTF_ICELAKE_BITMANIPULATION_H @@ -1390,7 +1390,7 @@ simdutf_really_inline long long int count_ones(uint64_t input_num) { #endif // SIMDUTF_ICELAKE_BITMANIPULATION_H /* end file src/simdutf/icelake/bitmanipulation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake/end.h /* begin file src/simdutf/icelake/end.h */ #if SIMDUTF_CAN_ALWAYS_RUN_ICELAKE // nothing needed. @@ -1409,7 +1409,7 @@ SIMDUTF_POP_DISABLE_WARNINGS #endif // SIMDUTF_IMPLEMENTATION_ICELAKE #endif // SIMDUTF_ICELAKE_H /* end file src/simdutf/icelake.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell.h /* begin file src/simdutf/haswell.h */ #ifndef SIMDUTF_HASWELL_H #define SIMDUTF_HASWELL_H @@ -1455,7 +1455,7 @@ namespace haswell { // // These two need to be included outside SIMDUTF_TARGET_REGION // -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/implementation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/implementation.h /* begin file src/simdutf/haswell/implementation.h */ #ifndef SIMDUTF_HASWELL_IMPLEMENTATION_H #define SIMDUTF_HASWELL_IMPLEMENTATION_H @@ -1534,7 +1534,7 @@ class implementation final : public simdutf::implementation { #endif // SIMDUTF_HASWELL_IMPLEMENTATION_H /* end file src/simdutf/haswell/implementation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/intrinsics.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/intrinsics.h /* begin file src/simdutf/haswell/intrinsics.h */ #ifndef SIMDUTF_HASWELL_INTRINSICS_H #define SIMDUTF_HASWELL_INTRINSICS_H @@ -1603,7 +1603,7 @@ SIMDUTF_POP_DISABLE_WARNINGS // // The rest need to be inside the region // -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/begin.h /* begin file src/simdutf/haswell/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "haswell" // #define SIMDUTF_IMPLEMENTATION haswell @@ -1619,7 +1619,7 @@ SIMDUTF_DISABLE_GCC_WARNING(-Wmaybe-uninitialized) #endif // end of workaround /* end file src/simdutf/haswell/begin.h */ // Declarations -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/bitmanipulation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/bitmanipulation.h /* begin file src/simdutf/haswell/bitmanipulation.h */ #ifndef SIMDUTF_HASWELL_BITMANIPULATION_H #define SIMDUTF_HASWELL_BITMANIPULATION_H @@ -1645,7 +1645,7 @@ simdutf_really_inline long long int count_ones(uint64_t input_num) { #endif // SIMDUTF_HASWELL_BITMANIPULATION_H /* end file src/simdutf/haswell/bitmanipulation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/simd.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/simd.h /* begin file src/simdutf/haswell/simd.h */ #ifndef SIMDUTF_HASWELL_SIMD_H #define SIMDUTF_HASWELL_SIMD_H @@ -2041,7 +2041,7 @@ namespace simd { } }; // struct simd8x64 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/simd16-inl.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/simd16-inl.h /* begin file src/simdutf/haswell/simd16-inl.h */ #ifdef __GNUC__ #if __GNUC__ < 8 @@ -2320,7 +2320,7 @@ struct simd16: base16_numeric { #endif // SIMDUTF_HASWELL_SIMD_H /* end file src/simdutf/haswell/simd.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/end.h /* begin file src/simdutf/haswell/end.h */ #if SIMDUTF_CAN_ALWAYS_RUN_HASWELL // nothing needed. @@ -2337,7 +2337,7 @@ SIMDUTF_POP_DISABLE_WARNINGS #endif // SIMDUTF_IMPLEMENTATION_HASWELL #endif // SIMDUTF_HASWELL_COMMON_H /* end file src/simdutf/haswell.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere.h /* begin file src/simdutf/westmere.h */ #ifndef SIMDUTF_WESTMERE_H #define SIMDUTF_WESTMERE_H @@ -2378,7 +2378,7 @@ namespace westmere { // // These two need to be included outside SIMDUTF_TARGET_REGION // -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/implementation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/implementation.h /* begin file src/simdutf/westmere/implementation.h */ #ifndef SIMDUTF_WESTMERE_IMPLEMENTATION_H #define SIMDUTF_WESTMERE_IMPLEMENTATION_H @@ -2455,7 +2455,7 @@ class implementation final : public simdutf::implementation { #endif // SIMDUTF_WESTMERE_IMPLEMENTATION_H /* end file src/simdutf/westmere/implementation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/intrinsics.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/intrinsics.h /* begin file src/simdutf/westmere/intrinsics.h */ #ifndef SIMDUTF_WESTMERE_INTRINSICS_H #define SIMDUTF_WESTMERE_INTRINSICS_H @@ -2504,7 +2504,7 @@ SIMDUTF_POP_DISABLE_WARNINGS // // The rest need to be inside the region // -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/begin.h /* begin file src/simdutf/westmere/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "westmere" // #define SIMDUTF_IMPLEMENTATION westmere @@ -2517,7 +2517,7 @@ SIMDUTF_TARGET_WESTMERE /* end file src/simdutf/westmere/begin.h */ // Declarations -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/bitmanipulation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/bitmanipulation.h /* begin file src/simdutf/westmere/bitmanipulation.h */ #ifndef SIMDUTF_WESTMERE_BITMANIPULATION_H #define SIMDUTF_WESTMERE_BITMANIPULATION_H @@ -2543,7 +2543,7 @@ simdutf_really_inline long long int count_ones(uint64_t input_num) { #endif // SIMDUTF_WESTMERE_BITMANIPULATION_H /* end file src/simdutf/westmere/bitmanipulation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/simd.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/simd.h /* begin file src/simdutf/westmere/simd.h */ #ifndef SIMDUTF_WESTMERE_SIMD_H #define SIMDUTF_WESTMERE_SIMD_H @@ -2987,7 +2987,7 @@ namespace simd { } }; // struct simd8x64 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/simd16-inl.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/simd16-inl.h /* begin file src/simdutf/westmere/simd16-inl.h */ template struct simd16; @@ -3264,7 +3264,7 @@ template #endif // SIMDUTF_WESTMERE_SIMD_INPUT_H /* end file src/simdutf/westmere/simd.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/end.h /* begin file src/simdutf/westmere/end.h */ #if SIMDUTF_CAN_ALWAYS_RUN_WESTMERE // nothing needed. @@ -3277,7 +3277,7 @@ SIMDUTF_UNTARGET_REGION #endif // SIMDUTF_IMPLEMENTATION_WESTMERE #endif // SIMDUTF_WESTMERE_COMMON_H /* end file src/simdutf/westmere.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64.h /* begin file src/simdutf/ppc64.h */ #ifndef SIMDUTF_PPC64_H #define SIMDUTF_PPC64_H @@ -3304,7 +3304,7 @@ namespace ppc64 { } // namespace ppc64 } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/implementation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/implementation.h /* begin file src/simdutf/ppc64/implementation.h */ #ifndef SIMDUTF_PPC64_IMPLEMENTATION_H #define SIMDUTF_PPC64_IMPLEMENTATION_H @@ -3383,14 +3383,14 @@ class implementation final : public simdutf::implementation { #endif // SIMDUTF_PPC64_IMPLEMENTATION_H /* end file src/simdutf/ppc64/implementation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/begin.h /* begin file src/simdutf/ppc64/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "ppc64" // #define SIMDUTF_IMPLEMENTATION ppc64 /* end file src/simdutf/ppc64/begin.h */ // Declarations -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/intrinsics.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/intrinsics.h /* begin file src/simdutf/ppc64/intrinsics.h */ #ifndef SIMDUTF_PPC64_INTRINSICS_H #define SIMDUTF_PPC64_INTRINSICS_H @@ -3411,7 +3411,7 @@ class implementation final : public simdutf::implementation { #endif // SIMDUTF_PPC64_INTRINSICS_H /* end file src/simdutf/ppc64/intrinsics.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/bitmanipulation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/bitmanipulation.h /* begin file src/simdutf/ppc64/bitmanipulation.h */ #ifndef SIMDUTF_PPC64_BITMANIPULATION_H #define SIMDUTF_PPC64_BITMANIPULATION_H @@ -3437,7 +3437,7 @@ simdutf_really_inline int count_ones(uint64_t input_num) { #endif // SIMDUTF_PPC64_BITMANIPULATION_H /* end file src/simdutf/ppc64/bitmanipulation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/simd.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/simd.h /* begin file src/simdutf/ppc64/simd.h */ #ifndef SIMDUTF_PPC64_SIMD_H #define SIMDUTF_PPC64_SIMD_H @@ -3929,7 +3929,7 @@ template struct simd8x64 { #endif // SIMDUTF_PPC64_SIMD_INPUT_H /* end file src/simdutf/ppc64/simd.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/end.h /* begin file src/simdutf/ppc64/end.h */ /* end file src/simdutf/ppc64/end.h */ @@ -3937,7 +3937,7 @@ template struct simd8x64 { #endif // SIMDUTF_PPC64_H /* end file src/simdutf/ppc64.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/fallback.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/fallback.h /* begin file src/simdutf/fallback.h */ #ifndef SIMDUTF_FALLBACK_H #define SIMDUTF_FALLBACK_H @@ -3966,7 +3966,7 @@ namespace fallback { } // namespace fallback } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/fallback/implementation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/fallback/implementation.h /* begin file src/simdutf/fallback/implementation.h */ #ifndef SIMDUTF_FALLBACK_IMPLEMENTATION_H #define SIMDUTF_FALLBACK_IMPLEMENTATION_H @@ -4047,14 +4047,14 @@ class implementation final : public simdutf::implementation { #endif // SIMDUTF_FALLBACK_IMPLEMENTATION_H /* end file src/simdutf/fallback/implementation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/fallback/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/fallback/begin.h /* begin file src/simdutf/fallback/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "fallback" // #define SIMDUTF_IMPLEMENTATION fallback /* end file src/simdutf/fallback/begin.h */ // Declarations -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/fallback/bitmanipulation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/fallback/bitmanipulation.h /* begin file src/simdutf/fallback/bitmanipulation.h */ #ifndef SIMDUTF_FALLBACK_BITMANIPULATION_H #define SIMDUTF_FALLBACK_BITMANIPULATION_H @@ -4089,7 +4089,7 @@ static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) { #endif // SIMDUTF_FALLBACK_BITMANIPULATION_H /* end file src/simdutf/fallback/bitmanipulation.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/fallback/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/fallback/end.h /* begin file src/simdutf/fallback/end.h */ /* end file src/simdutf/fallback/end.h */ @@ -4978,7 +4978,7 @@ const implementation * builtin_implementation() { } // namespace simdutf /* end file src/implementation.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=encoding_types.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=encoding_types.cpp /* begin file src/encoding_types.cpp */ namespace simdutf { @@ -5040,7 +5040,7 @@ encoding_type check_bom(const char* byte, size_t length) { } } /* end file src/encoding_types.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=error.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=error.cpp /* begin file src/error.cpp */ namespace simdutf { @@ -5052,7 +5052,7 @@ namespace simdutf { /* end file src/error.cpp */ // The large tables should be included once and they // should not depend on a kernel. -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=tables/utf8_to_utf16_tables.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=tables/utf8_to_utf16_tables.h /* begin file src/tables/utf8_to_utf16_tables.h */ #ifndef SIMDUTF_UTF8_TO_UTF16_TABLES_H #define SIMDUTF_UTF8_TO_UTF16_TABLES_H @@ -9391,7 +9391,7 @@ const uint8_t utf8bigindex[4096][2] = #endif // SIMDUTF_UTF8_TO_UTF16_TABLES_H /* end file src/tables/utf8_to_utf16_tables.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=tables/utf16_to_utf8_tables.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=tables/utf16_to_utf8_tables.h /* begin file src/tables/utf16_to_utf8_tables.h */ // file generated by scripts/sse_convert_utf16_to_utf8.py #ifndef SIMDUTF_UTF16_TO_UTF8_TABLES_H @@ -9932,7 +9932,7 @@ namespace utf16_to_utf8 { // End of tables. // The scalar routines should be included once. -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/ascii.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/ascii.h /* begin file src/scalar/ascii.h */ #ifndef SIMDUTF_ASCII_H #define SIMDUTF_ASCII_H @@ -9993,7 +9993,7 @@ inline simdutf_warn_unused result validate_with_errors(const char *buf, size_t l #endif /* end file src/scalar/ascii.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf8.h /* begin file src/scalar/utf8.h */ #ifndef SIMDUTF_UTF8_H #define SIMDUTF_UTF8_H @@ -10138,7 +10138,11 @@ inline simdutf_warn_unused result validate_with_errors(const char *buf, size_t l // Finds the previous leading byte and validates with errors from there // Used to pinpoint the location of an error when an invalid chunk is detected -inline simdutf_warn_unused result rewind_and_validate_with_errors(const char *buf, size_t len) noexcept { +inline simdutf_warn_unused result rewind_and_validate_with_errors(const char *start, const char *buf, size_t len) noexcept { + // First check that we start with a leading byte + if ((*start & 0b11000000) == 0b10000000) { + return result(error_code::TOO_LONG, 0); + } size_t extra_len{0}; // A leading byte cannot be further than 4 bytes away for(int i = 0; i < 5; i++) { @@ -10183,7 +10187,7 @@ inline size_t utf16_length_from_utf8(const char* buf, size_t len) { #endif /* end file src/scalar/utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf16.h /* begin file src/scalar/utf16.h */ #ifndef SIMDUTF_UTF16_H #define SIMDUTF_UTF16_H @@ -10297,7 +10301,7 @@ simdutf_really_inline void change_endianness_utf16(const char16_t* in, size_t si #endif /* end file src/scalar/utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf32.h /* begin file src/scalar/utf32.h */ #ifndef SIMDUTF_UTF32_H #define SIMDUTF_UTF32_H @@ -10372,7 +10376,7 @@ inline size_t utf16_length_from_utf32(const char32_t* buf, size_t len) { #endif /* end file src/scalar/utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf8/valid_utf32_to_utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf8/valid_utf32_to_utf8.h /* begin file src/scalar/utf32_to_utf8/valid_utf32_to_utf8.h */ #ifndef SIMDUTF_VALID_UTF32_TO_UTF8_H #define SIMDUTF_VALID_UTF32_TO_UTF8_H @@ -10439,7 +10443,7 @@ inline size_t convert_valid(const char32_t* buf, size_t len, char* utf8_output) #endif /* end file src/scalar/utf32_to_utf8/valid_utf32_to_utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf8/utf32_to_utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf8/utf32_to_utf8.h /* begin file src/scalar/utf32_to_utf8/utf32_to_utf8.h */ #ifndef SIMDUTF_UTF32_TO_UTF8_H #define SIMDUTF_UTF32_TO_UTF8_H @@ -10555,7 +10559,7 @@ inline result convert_with_errors(const char32_t* buf, size_t len, char* utf8_ou #endif /* end file src/scalar/utf32_to_utf8/utf32_to_utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf16/valid_utf32_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf16/valid_utf32_to_utf16.h /* begin file src/scalar/utf32_to_utf16/valid_utf32_to_utf16.h */ #ifndef SIMDUTF_VALID_UTF32_TO_UTF16_H #define SIMDUTF_VALID_UTF32_TO_UTF16_H @@ -10600,7 +10604,7 @@ inline size_t convert_valid(const char32_t* buf, size_t len, char16_t* utf16_out #endif /* end file src/scalar/utf32_to_utf16/valid_utf32_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf16/utf32_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf32_to_utf16/utf32_to_utf16.h /* begin file src/scalar/utf32_to_utf16/utf32_to_utf16.h */ #ifndef SIMDUTF_UTF32_TO_UTF16_H #define SIMDUTF_UTF32_TO_UTF16_H @@ -10676,7 +10680,7 @@ inline result convert_with_errors(const char32_t* buf, size_t len, char16_t* utf #endif /* end file src/scalar/utf32_to_utf16/utf32_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf8/valid_utf16_to_utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf8/valid_utf16_to_utf8.h /* begin file src/scalar/utf16_to_utf8/valid_utf16_to_utf8.h */ #ifndef SIMDUTF_VALID_UTF16_TO_UTF8_H #define SIMDUTF_VALID_UTF16_TO_UTF8_H @@ -10751,7 +10755,7 @@ inline size_t convert_valid(const char16_t* buf, size_t len, char* utf8_output) #endif /* end file src/scalar/utf16_to_utf8/valid_utf16_to_utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf8/utf16_to_utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf8/utf16_to_utf8.h /* begin file src/scalar/utf16_to_utf8/utf16_to_utf8.h */ #ifndef SIMDUTF_UTF16_TO_UTF8_H #define SIMDUTF_UTF16_TO_UTF8_H @@ -10887,7 +10891,7 @@ inline result convert_with_errors(const char16_t* buf, size_t len, char* utf8_ou #endif /* end file src/scalar/utf16_to_utf8/utf16_to_utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf32/valid_utf16_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf32/valid_utf16_to_utf32.h /* begin file src/scalar/utf16_to_utf32/valid_utf16_to_utf32.h */ #ifndef SIMDUTF_VALID_UTF16_TO_UTF32_H #define SIMDUTF_VALID_UTF16_TO_UTF32_H @@ -10929,7 +10933,7 @@ inline size_t convert_valid(const char16_t* buf, size_t len, char32_t* utf32_out #endif /* end file src/scalar/utf16_to_utf32/valid_utf16_to_utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf32/utf16_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf16_to_utf32/utf16_to_utf32.h /* begin file src/scalar/utf16_to_utf32/utf16_to_utf32.h */ #ifndef SIMDUTF_UTF16_TO_UTF32_H #define SIMDUTF_UTF16_TO_UTF32_H @@ -11001,7 +11005,7 @@ inline result convert_with_errors(const char16_t* buf, size_t len, char32_t* utf #endif /* end file src/scalar/utf16_to_utf32/utf16_to_utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf16/valid_utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf16/valid_utf8_to_utf16.h /* begin file src/scalar/utf8_to_utf16/valid_utf8_to_utf16.h */ #ifndef SIMDUTF_VALID_UTF8_TO_UTF16_H #define SIMDUTF_VALID_UTF8_TO_UTF16_H @@ -11086,7 +11090,7 @@ inline size_t convert_valid(const char* buf, size_t len, char16_t* utf16_output) #endif /* end file src/scalar/utf8_to_utf16/valid_utf8_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf16/utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf16/utf8_to_utf16.h /* begin file src/scalar/utf8_to_utf16/utf8_to_utf16.h */ #ifndef SIMDUTF_UTF8_TO_UTF16_H #define SIMDUTF_UTF8_TO_UTF16_H @@ -11336,7 +11340,7 @@ inline result rewind_and_convert_with_errors(size_t prior_bytes, const char* buf #endif /* end file src/scalar/utf8_to_utf16/utf8_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf32/valid_utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf32/valid_utf8_to_utf32.h /* begin file src/scalar/utf8_to_utf32/valid_utf8_to_utf32.h */ #ifndef SIMDUTF_VALID_UTF8_TO_UTF32_H #define SIMDUTF_VALID_UTF8_TO_UTF32_H @@ -11402,7 +11406,7 @@ inline size_t convert_valid(const char* buf, size_t len, char32_t* utf32_output) #endif /* end file src/scalar/utf8_to_utf32/valid_utf8_to_utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf32/utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=scalar/utf8_to_utf32/utf8_to_utf32.h /* begin file src/scalar/utf8_to_utf32/utf8_to_utf32.h */ #ifndef SIMDUTF_UTF8_TO_UTF32_H #define SIMDUTF_UTF8_TO_UTF32_H @@ -11622,9 +11626,9 @@ SIMDUTF_DISABLE_UNDESIRED_WARNINGS #if SIMDUTF_IMPLEMENTATION_ARM64 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/implementation.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/implementation.cpp /* begin file src/arm64/implementation.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/begin.h /* begin file src/simdutf/arm64/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "arm64" // #define SIMDUTF_IMPLEMENTATION arm64 @@ -11660,7 +11664,7 @@ simdutf_really_inline simd8 must_be_2_3_continuation(const simd8 return is_third_byte ^ is_fourth_byte; } -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_detect_encodings.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_detect_encodings.cpp /* begin file src/arm64/arm_detect_encodings.cpp */ template // len is known to be a multiple of 2 when this is called @@ -11868,7 +11872,7 @@ int arm_detect_encodings(const char * buf, size_t len) { } /* end file src/arm64/arm_detect_encodings.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_validate_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_validate_utf16.cpp /* begin file src/arm64/arm_validate_utf16.cpp */ template const char16_t* arm_validate_utf16(const char16_t* input, size_t size) { @@ -12018,7 +12022,7 @@ const result arm_validate_utf16_with_errors(const char16_t* input, size_t size) return result(error_code::SUCCESS, input - start); } /* end file src/arm64/arm_validate_utf16.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_validate_utf32le.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_validate_utf32le.cpp /* begin file src/arm64/arm_validate_utf32le.cpp */ const char32_t* arm_validate_utf32le(const char32_t* input, size_t size) { @@ -12083,7 +12087,7 @@ const result arm_validate_utf32le_with_errors(const char32_t* input, size_t size } /* end file src/arm64/arm_validate_utf32le.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf8_to_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf8_to_utf16.cpp /* begin file src/arm64/arm_convert_utf8_to_utf16.cpp */ // Convert up to 12 bytes from utf8 to utf16 using a mask indicating the // end of the code points. Only the least significant 12 bits of the mask @@ -12270,7 +12274,7 @@ size_t convert_masked_utf8_to_utf16(const char *input, return consumed; } /* end file src/arm64/arm_convert_utf8_to_utf16.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf8_to_utf32.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf8_to_utf32.cpp /* begin file src/arm64/arm_convert_utf8_to_utf32.cpp */ // Convert up to 12 bytes from utf8 to utf32 using a mask indicating the // end of the code points. Only the least significant 12 bits of the mask @@ -12407,7 +12411,7 @@ size_t convert_masked_utf8_to_utf32(const char *input, } /* end file src/arm64/arm_convert_utf8_to_utf32.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf16_to_utf8.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf16_to_utf8.cpp /* begin file src/arm64/arm_convert_utf16_to_utf8.cpp */ /* The vectorized algorithm works on single SSE register i.e., it @@ -12987,7 +12991,7 @@ std::pair arm_convert_utf16_to_utf8_with_errors(const char16_t* b return std::make_pair(result(error_code::SUCCESS, buf - start), reinterpret_cast(utf8_output)); } /* end file src/arm64/arm_convert_utf16_to_utf8.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf16_to_utf32.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf16_to_utf32.cpp /* begin file src/arm64/arm_convert_utf16_to_utf32.cpp */ /* The vectorized algorithm works on single SSE register i.e., it @@ -13164,7 +13168,7 @@ std::pair arm_convert_utf16_to_utf32_with_errors(const char16 } /* end file src/arm64/arm_convert_utf16_to_utf32.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf32_to_utf8.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf32_to_utf8.cpp /* begin file src/arm64/arm_convert_utf32_to_utf8.cpp */ std::pair arm_convert_utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_out) { uint8_t * utf8_output = reinterpret_cast(utf8_out); @@ -13636,7 +13640,7 @@ std::pair arm_convert_utf32_to_utf8_with_errors(const char32_t* b return std::make_pair(result(error_code::SUCCESS, buf - start), reinterpret_cast(utf8_output)); } /* end file src/arm64/arm_convert_utf32_to_utf8.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf32_to_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=arm64/arm_convert_utf32_to_utf16.cpp /* begin file src/arm64/arm_convert_utf32_to_utf16.cpp */ template std::pair arm_convert_utf32_to_utf16(const char32_t* buf, size_t len, char16_t* utf16_out) { @@ -13769,7 +13773,7 @@ std::pair arm_convert_utf32_to_utf16_with_errors(const char32 } // unnamed namespace } // namespace arm64 } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h /* begin file src/generic/buf_block_reader.h */ namespace simdutf { namespace arm64 { @@ -13864,7 +13868,7 @@ simdutf_really_inline void buf_block_reader::advance() { } // namespace arm64 } // namespace simdutf /* end file src/generic/buf_block_reader.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h /* begin file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ namespace simdutf { namespace arm64 { @@ -14053,7 +14057,7 @@ using utf8_validation::utf8_checker; } // namespace arm64 } // namespace simdutf /* end file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h /* begin file src/generic/utf8_validation/utf8_validator.h */ namespace simdutf { namespace arm64 { @@ -14098,7 +14102,7 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { c.check_next_input(in); if(c.errors()) { if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input + count), length - count); + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input + count), length - count); res.count += count; return res; } @@ -14112,7 +14116,8 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { reader.advance(); c.check_eof(); if (c.errors()) { - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input) + count, length - count); + if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input) + count, length - count); res.count += count; return res; } else { @@ -14180,7 +14185,7 @@ result generic_validate_ascii_with_errors(const char * input, size_t length) { } // namespace simdutf /* end file src/generic/utf8_validation/utf8_validator.h */ // transcoding from UTF-8 to UTF-16 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ @@ -14255,7 +14260,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace arm64 } // namespace simdutf /* end file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/utf8_to_utf16.h */ @@ -14563,7 +14568,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf16/utf8_to_utf16.h */ // transcoding from UTF-8 to UTF-32 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ namespace simdutf { @@ -14609,7 +14614,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace arm64 } // namespace simdutf /* end file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/utf8_to_utf32.h */ @@ -14910,7 +14915,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf32/utf8_to_utf32.h */ // other functions -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8.h /* begin file src/generic/utf8.h */ namespace simdutf { @@ -14957,7 +14962,7 @@ simdutf_really_inline size_t utf32_length_from_utf8(const char* in, size_t size) } // namespace arm64 } // namespace simdutf /* end file src/generic/utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf16.h /* begin file src/generic/utf16.h */ namespace simdutf { namespace arm64 { @@ -15492,15 +15497,15 @@ simdutf_warn_unused size_t implementation::utf32_length_from_utf8(const char * i } // namespace arm64 } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/arm64/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/arm64/end.h /* begin file src/simdutf/arm64/end.h */ /* end file src/simdutf/arm64/end.h */ /* end file src/arm64/implementation.cpp */ #endif #if SIMDUTF_IMPLEMENTATION_FALLBACK -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=fallback/implementation.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=fallback/implementation.cpp /* begin file src/fallback/implementation.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/fallback/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/fallback/begin.h /* begin file src/simdutf/fallback/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "fallback" // #define SIMDUTF_IMPLEMENTATION fallback @@ -15744,17 +15749,17 @@ simdutf_warn_unused size_t implementation::utf32_length_from_utf8(const char * i } // namespace fallback } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/fallback/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/fallback/end.h /* begin file src/simdutf/fallback/end.h */ /* end file src/simdutf/fallback/end.h */ /* end file src/fallback/implementation.cpp */ #endif #if SIMDUTF_IMPLEMENTATION_ICELAKE -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/implementation.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/implementation.cpp /* begin file src/icelake/implementation.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake/begin.h /* begin file src/simdutf/icelake/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "icelake" // #define SIMDUTF_IMPLEMENTATION icelake @@ -15775,7 +15780,7 @@ namespace { #ifndef SIMDUTF_ICELAKE_H #error "icelake.h must be included" #endif -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_utf8_common.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_utf8_common.inl.cpp /* begin file src/icelake/icelake_utf8_common.inl.cpp */ // Common procedures for both validating and non-validating conversions from UTF-8. enum block_processing_mode { SIMDUTF_FULL, SIMDUTF_TAIL}; @@ -16440,7 +16445,7 @@ simdutf_really_inline __m512i expand_utf8_to_utf32(__m512i input) { return expanded_utf8_to_utf32(char_class, input); } /* end file src/icelake/icelake_utf8_common.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_macros.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_macros.inl.cpp /* begin file src/icelake/icelake_macros.inl.cpp */ /* @@ -16576,7 +16581,7 @@ simdutf_really_inline __m512i expand_utf8_to_utf32(__m512i input) { } \ } /* end file src/icelake/icelake_macros.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_from_valid_utf8.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_from_valid_utf8.inl.cpp /* begin file src/icelake/icelake_from_valid_utf8.inl.cpp */ // file included directly @@ -16715,7 +16720,7 @@ std::pair valid_utf8_to_fixed_length(const char* str, size using utf8_to_utf16_result = std::pair; /* end file src/icelake/icelake_from_valid_utf8.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_utf8_validation.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_utf8_validation.inl.cpp /* begin file src/icelake/icelake_utf8_validation.inl.cpp */ // file included directly @@ -16845,7 +16850,7 @@ simdutf_really_inline __m512i check_special_cases(__m512i input, const __m512i p }; // struct avx512_utf8_checker /* end file src/icelake/icelake_utf8_validation.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_from_utf8.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_from_utf8.inl.cpp /* begin file src/icelake/icelake_from_utf8.inl.cpp */ // file included directly @@ -17148,7 +17153,7 @@ std::tuple validating_utf8_to_fixed_length_with_cons return {ptr, output, true}; } /* end file src/icelake/icelake_from_utf8.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf16_to_utf32.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf16_to_utf32.inl.cpp /* begin file src/icelake/icelake_convert_utf16_to_utf32.inl.cpp */ // file included directly @@ -17260,7 +17265,7 @@ std::tuple convert_utf16_to_utf32(const char16 return std::make_tuple(buf+carry, utf32_output, true); } /* end file src/icelake/icelake_convert_utf16_to_utf32.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf32_to_utf8.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf32_to_utf8.inl.cpp /* begin file src/icelake/icelake_convert_utf32_to_utf8.inl.cpp */ // file included directly @@ -17746,7 +17751,7 @@ std::pair avx512_convert_utf32_to_utf8_with_errors(const char32_t return std::make_pair(result(error_code::SUCCESS, buf - start), utf8_output); } /* end file src/icelake/icelake_convert_utf32_to_utf8.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf32_to_utf16.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf32_to_utf16.inl.cpp /* begin file src/icelake/icelake_convert_utf32_to_utf16.inl.cpp */ // file included directly @@ -17881,7 +17886,7 @@ std::pair avx512_convert_utf32_to_utf16_with_errors(const cha return std::make_pair(result(error_code::SUCCESS, buf - start), utf16_output); } /* end file src/icelake/icelake_convert_utf32_to_utf16.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_ascii_validation.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_ascii_validation.inl.cpp /* begin file src/icelake/icelake_ascii_validation.inl.cpp */ // file included directly @@ -17900,7 +17905,7 @@ bool validate_ascii(const char* buf, size_t len) { return (_mm512_test_epi8_mask(running_or, running_or) == 0); } /* end file src/icelake/icelake_ascii_validation.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_utf32_validation.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_utf32_validation.inl.cpp /* begin file src/icelake/icelake_utf32_validation.inl.cpp */ // file included directly @@ -17932,7 +17937,7 @@ const char32_t* validate_utf32(const char32_t* buf, size_t len) { return buf; } /* end file src/icelake/icelake_utf32_validation.inl.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf16_to_utf8.inl.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=icelake/icelake_convert_utf16_to_utf8.inl.cpp /* begin file src/icelake/icelake_convert_utf16_to_utf8.inl.cpp */ // file included directly @@ -18299,7 +18304,7 @@ simdutf_warn_unused result implementation::validate_utf8_with_errors(const char checker.check_next_input(utf8); if(checker.errors()) { if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(buf + count), len - count); + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(buf), reinterpret_cast(buf + count), len - count); res.count += count; return res; } @@ -18310,7 +18315,7 @@ simdutf_warn_unused result implementation::validate_utf8_with_errors(const char checker.check_next_input(utf8); if(checker.errors()) { if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(buf + count), len - count); + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(buf), reinterpret_cast(buf + count), len - count); res.count += count; return res; } else { @@ -19244,7 +19249,7 @@ simdutf_warn_unused size_t implementation::utf32_length_from_utf8(const char * i } // namespace icelake } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/icelake/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/icelake/end.h /* begin file src/simdutf/icelake/end.h */ #if SIMDUTF_CAN_ALWAYS_RUN_ICELAKE // nothing needed. @@ -19260,10 +19265,10 @@ SIMDUTF_POP_DISABLE_WARNINGS /* end file src/icelake/implementation.cpp */ #endif #if SIMDUTF_IMPLEMENTATION_HASWELL -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/implementation.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/implementation.cpp /* begin file src/haswell/implementation.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/begin.h /* begin file src/simdutf/haswell/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "haswell" // #define SIMDUTF_IMPLEMENTATION haswell @@ -19306,7 +19311,7 @@ simdutf_really_inline simd8 must_be_2_3_continuation(const simd8 return simd8(is_third_byte | is_fourth_byte) > int8_t(0); } -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_detect_encodings.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_detect_encodings.cpp /* begin file src/haswell/avx2_detect_encodings.cpp */ template // len is known to be a multiple of 2 when this is called @@ -19496,7 +19501,7 @@ int avx2_detect_encodings(const char * buf, size_t len) { } /* end file src/haswell/avx2_detect_encodings.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_validate_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_validate_utf16.cpp /* begin file src/haswell/avx2_validate_utf16.cpp */ /* In UTF-16 words in range 0xD800 to 0xDFFF have special meaning. @@ -19697,7 +19702,7 @@ const result avx2_validate_utf16_with_errors(const char16_t* input, size_t size) return result(error_code::SUCCESS, input - start); } /* end file src/haswell/avx2_validate_utf16.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_validate_utf32le.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_validate_utf32le.cpp /* begin file src/haswell/avx2_validate_utf32le.cpp */ /* Returns: - pointer to the last unprocessed character (a scalar fallback should check the rest); @@ -19763,7 +19768,7 @@ const result avx2_validate_utf32le_with_errors(const char32_t* input, size_t siz } /* end file src/haswell/avx2_validate_utf32le.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf8_to_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf8_to_utf16.cpp /* begin file src/haswell/avx2_convert_utf8_to_utf16.cpp */ // depends on "tables/utf8_to_utf16_tables.h" @@ -19946,7 +19951,7 @@ size_t convert_masked_utf8_to_utf16(const char *input, return consumed; } /* end file src/haswell/avx2_convert_utf8_to_utf16.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf8_to_utf32.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf8_to_utf32.cpp /* begin file src/haswell/avx2_convert_utf8_to_utf32.cpp */ // depends on "tables/utf8_to_utf16_tables.h" @@ -20075,7 +20080,7 @@ size_t convert_masked_utf8_to_utf32(const char *input, } /* end file src/haswell/avx2_convert_utf8_to_utf32.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf16_to_utf8.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf16_to_utf8.cpp /* begin file src/haswell/avx2_convert_utf16_to_utf8.cpp */ /* The vectorized algorithm works on single SSE register i.e., it @@ -20608,7 +20613,7 @@ std::pair avx2_convert_utf16_to_utf8_with_errors(const char16_t* return std::make_pair(result(error_code::SUCCESS, buf - start), utf8_output); } /* end file src/haswell/avx2_convert_utf16_to_utf8.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf16_to_utf32.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf16_to_utf32.cpp /* begin file src/haswell/avx2_convert_utf16_to_utf32.cpp */ /* The vectorized algorithm works on single SSE register i.e., it @@ -20793,7 +20798,7 @@ std::pair avx2_convert_utf16_to_utf32_with_errors(const char1 } /* end file src/haswell/avx2_convert_utf16_to_utf32.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf32_to_utf8.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf32_to_utf8.cpp /* begin file src/haswell/avx2_convert_utf32_to_utf8.cpp */ std::pair avx2_convert_utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) { const char32_t* end = buf + len; @@ -21276,7 +21281,7 @@ std::pair avx2_convert_utf32_to_utf8_with_errors(const char32_t* return std::make_pair(result(error_code::SUCCESS, buf - start), utf8_output); } /* end file src/haswell/avx2_convert_utf32_to_utf8.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf32_to_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=haswell/avx2_convert_utf32_to_utf16.cpp /* begin file src/haswell/avx2_convert_utf32_to_utf16.cpp */ template std::pair avx2_convert_utf32_to_utf16(const char32_t* buf, size_t len, char16_t* utf16_output) { @@ -21412,7 +21417,7 @@ std::pair avx2_convert_utf32_to_utf16_with_errors(const char3 } // namespace haswell } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h /* begin file src/generic/buf_block_reader.h */ namespace simdutf { namespace haswell { @@ -21507,7 +21512,7 @@ simdutf_really_inline void buf_block_reader::advance() { } // namespace haswell } // namespace simdutf /* end file src/generic/buf_block_reader.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h /* begin file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ namespace simdutf { namespace haswell { @@ -21696,7 +21701,7 @@ using utf8_validation::utf8_checker; } // namespace haswell } // namespace simdutf /* end file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h /* begin file src/generic/utf8_validation/utf8_validator.h */ namespace simdutf { namespace haswell { @@ -21741,7 +21746,7 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { c.check_next_input(in); if(c.errors()) { if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input + count), length - count); + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input + count), length - count); res.count += count; return res; } @@ -21755,7 +21760,8 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { reader.advance(); c.check_eof(); if (c.errors()) { - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input) + count, length - count); + if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input) + count, length - count); res.count += count; return res; } else { @@ -21823,7 +21829,7 @@ result generic_validate_ascii_with_errors(const char * input, size_t length) { } // namespace simdutf /* end file src/generic/utf8_validation/utf8_validator.h */ // transcoding from UTF-8 to UTF-16 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ @@ -21898,7 +21904,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace haswell } // namespace simdutf /* end file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/utf8_to_utf16.h */ @@ -22206,7 +22212,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf16/utf8_to_utf16.h */ // transcoding from UTF-8 to UTF-32 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ namespace simdutf { @@ -22252,7 +22258,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace haswell } // namespace simdutf /* end file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/utf8_to_utf32.h */ @@ -22553,7 +22559,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf32/utf8_to_utf32.h */ // other functions -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8.h /* begin file src/generic/utf8.h */ namespace simdutf { @@ -22600,7 +22606,7 @@ simdutf_really_inline size_t utf32_length_from_utf8(const char* in, size_t size) } // namespace haswell } // namespace simdutf /* end file src/generic/utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf16.h /* begin file src/generic/utf16.h */ namespace simdutf { namespace haswell { @@ -23128,7 +23134,7 @@ simdutf_warn_unused size_t implementation::utf32_length_from_utf8(const char * i } // namespace haswell } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/haswell/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/haswell/end.h /* begin file src/simdutf/haswell/end.h */ #if SIMDUTF_CAN_ALWAYS_RUN_HASWELL // nothing needed. @@ -23144,14 +23150,14 @@ SIMDUTF_POP_DISABLE_WARNINGS /* end file src/haswell/implementation.cpp */ #endif #if SIMDUTF_IMPLEMENTATION_PPC64 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=ppc64/implementation.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=ppc64/implementation.cpp /* begin file src/ppc64/implementation.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/begin.h /* begin file src/simdutf/ppc64/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "ppc64" // #define SIMDUTF_IMPLEMENTATION ppc64 @@ -23189,7 +23195,7 @@ simdutf_really_inline simd8 must_be_2_3_continuation(const simd8 } // namespace ppc64 } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h /* begin file src/generic/buf_block_reader.h */ namespace simdutf { namespace ppc64 { @@ -23284,7 +23290,7 @@ simdutf_really_inline void buf_block_reader::advance() { } // namespace ppc64 } // namespace simdutf /* end file src/generic/buf_block_reader.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h /* begin file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ namespace simdutf { namespace ppc64 { @@ -23473,7 +23479,7 @@ using utf8_validation::utf8_checker; } // namespace ppc64 } // namespace simdutf /* end file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h /* begin file src/generic/utf8_validation/utf8_validator.h */ namespace simdutf { namespace ppc64 { @@ -23518,7 +23524,7 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { c.check_next_input(in); if(c.errors()) { if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input + count), length - count); + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input + count), length - count); res.count += count; return res; } @@ -23532,7 +23538,8 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { reader.advance(); c.check_eof(); if (c.errors()) { - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input) + count, length - count); + if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input) + count, length - count); res.count += count; return res; } else { @@ -23600,7 +23607,7 @@ result generic_validate_ascii_with_errors(const char * input, size_t length) { } // namespace simdutf /* end file src/generic/utf8_validation/utf8_validator.h */ // transcoding from UTF-8 to UTF-16 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ @@ -23675,7 +23682,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace ppc64 } // namespace simdutf /* end file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/utf8_to_utf16.h */ @@ -23983,7 +23990,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf16/utf8_to_utf16.h */ // transcoding from UTF-8 to UTF-32 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ namespace simdutf { @@ -24029,7 +24036,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace ppc64 } // namespace simdutf /* end file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/utf8_to_utf32.h */ @@ -24330,7 +24337,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf32/utf8_to_utf32.h */ // other functions -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8.h /* begin file src/generic/utf8.h */ namespace simdutf { @@ -24377,7 +24384,7 @@ simdutf_really_inline size_t utf32_length_from_utf8(const char* in, size_t size) } // namespace ppc64 } // namespace simdutf /* end file src/generic/utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf16.h /* begin file src/generic/utf16.h */ namespace simdutf { namespace ppc64 { @@ -24676,15 +24683,15 @@ simdutf_warn_unused size_t implementation::utf32_length_from_utf8(const char * i } // namespace ppc64 } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/ppc64/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/ppc64/end.h /* begin file src/simdutf/ppc64/end.h */ /* end file src/simdutf/ppc64/end.h */ /* end file src/ppc64/implementation.cpp */ #endif #if SIMDUTF_IMPLEMENTATION_WESTMERE -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/implementation.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/implementation.cpp /* begin file src/westmere/implementation.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/begin.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/begin.h /* begin file src/simdutf/westmere/begin.h */ // redefining SIMDUTF_IMPLEMENTATION to "westmere" // #define SIMDUTF_IMPLEMENTATION westmere @@ -24722,7 +24729,7 @@ simdutf_really_inline simd8 must_be_2_3_continuation(const simd8 return simd8(is_third_byte | is_fourth_byte) > int8_t(0); } -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_detect_encodings.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_detect_encodings.cpp /* begin file src/westmere/sse_detect_encodings.cpp */ template // len is known to be a multiple of 2 when this is called @@ -24932,7 +24939,7 @@ int sse_detect_encodings(const char * buf, size_t len) { } /* end file src/westmere/sse_detect_encodings.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_validate_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_validate_utf16.cpp /* begin file src/westmere/sse_validate_utf16.cpp */ /* In UTF-16 words in range 0xD800 to 0xDFFF have special meaning. @@ -25132,7 +25139,7 @@ const result sse_validate_utf16_with_errors(const char16_t* input, size_t size) return result(error_code::SUCCESS, input - start); } /* end file src/westmere/sse_validate_utf16.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_validate_utf32le.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_validate_utf32le.cpp /* begin file src/westmere/sse_validate_utf32le.cpp */ /* Returns: - pointer to the last unprocessed character (a scalar fallback should check the rest); @@ -25198,7 +25205,7 @@ const result sse_validate_utf32le_with_errors(const char32_t* input, size_t size } /* end file src/westmere/sse_validate_utf32le.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf8_to_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf8_to_utf16.cpp /* begin file src/westmere/sse_convert_utf8_to_utf16.cpp */ // depends on "tables/utf8_to_utf16_tables.h" @@ -25383,7 +25390,7 @@ size_t convert_masked_utf8_to_utf16(const char *input, return consumed; } /* end file src/westmere/sse_convert_utf8_to_utf16.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf8_to_utf32.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf8_to_utf32.cpp /* begin file src/westmere/sse_convert_utf8_to_utf32.cpp */ // depends on "tables/utf8_to_utf16_tables.h" @@ -25515,7 +25522,7 @@ size_t convert_masked_utf8_to_utf32(const char *input, } /* end file src/westmere/sse_convert_utf8_to_utf32.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf16_to_utf8.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf16_to_utf8.cpp /* begin file src/westmere/sse_convert_utf16_to_utf8.cpp */ /* The vectorized algorithm works on single SSE register i.e., it @@ -26043,7 +26050,7 @@ std::pair sse_convert_utf16_to_utf8_with_errors(const char16_t* b return std::make_pair(result(error_code::SUCCESS, buf - start), utf8_output); } /* end file src/westmere/sse_convert_utf16_to_utf8.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf16_to_utf32.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf16_to_utf32.cpp /* begin file src/westmere/sse_convert_utf16_to_utf32.cpp */ /* The vectorized algorithm works on single SSE register i.e., it @@ -26227,7 +26234,7 @@ std::pair sse_convert_utf16_to_utf32_with_errors(const char16 } /* end file src/westmere/sse_convert_utf16_to_utf32.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf32_to_utf8.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf32_to_utf8.cpp /* begin file src/westmere/sse_convert_utf32_to_utf8.cpp */ std::pair sse_convert_utf32_to_utf8(const char32_t* buf, size_t len, char* utf8_output) { const char32_t* end = buf + len; @@ -26728,7 +26735,7 @@ std::pair sse_convert_utf32_to_utf8_with_errors(const char32_t* b return std::make_pair(result(error_code::SUCCESS, buf - start), utf8_output); } /* end file src/westmere/sse_convert_utf32_to_utf8.cpp */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf32_to_utf16.cpp +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=westmere/sse_convert_utf32_to_utf16.cpp /* begin file src/westmere/sse_convert_utf32_to_utf16.cpp */ template std::pair sse_convert_utf32_to_utf16(const char32_t* buf, size_t len, char16_t* utf16_output) { @@ -26867,7 +26874,7 @@ std::pair sse_convert_utf32_to_utf16_with_errors(const char32 } // namespace westmere } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/buf_block_reader.h /* begin file src/generic/buf_block_reader.h */ namespace simdutf { namespace westmere { @@ -26962,7 +26969,7 @@ simdutf_really_inline void buf_block_reader::advance() { } // namespace westmere } // namespace simdutf /* end file src/generic/buf_block_reader.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_lookup4_algorithm.h /* begin file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ namespace simdutf { namespace westmere { @@ -27151,7 +27158,7 @@ using utf8_validation::utf8_checker; } // namespace westmere } // namespace simdutf /* end file src/generic/utf8_validation/utf8_lookup4_algorithm.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_validation/utf8_validator.h /* begin file src/generic/utf8_validation/utf8_validator.h */ namespace simdutf { namespace westmere { @@ -27196,7 +27203,7 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { c.check_next_input(in); if(c.errors()) { if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input + count), length - count); + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input + count), length - count); res.count += count; return res; } @@ -27210,7 +27217,8 @@ result generic_validate_utf8_with_errors(const uint8_t * input, size_t length) { reader.advance(); c.check_eof(); if (c.errors()) { - result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input) + count, length - count); + if (count != 0) { count--; } // Sometimes the error is only detected in the next chunk + result res = scalar::utf8::rewind_and_validate_with_errors(reinterpret_cast(input), reinterpret_cast(input) + count, length - count); res.count += count; return res; } else { @@ -27278,7 +27286,7 @@ result generic_validate_ascii_with_errors(const char * input, size_t length) { } // namespace simdutf /* end file src/generic/utf8_validation/utf8_validator.h */ // transcoding from UTF-8 to UTF-16 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/valid_utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ @@ -27353,7 +27361,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace westmere } // namespace simdutf /* end file src/generic/utf8_to_utf16/valid_utf8_to_utf16.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf16/utf8_to_utf16.h /* begin file src/generic/utf8_to_utf16/utf8_to_utf16.h */ @@ -27661,7 +27669,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf16/utf8_to_utf16.h */ // transcoding from UTF-8 to UTF-32 -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/valid_utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ namespace simdutf { @@ -27707,7 +27715,7 @@ simdutf_warn_unused size_t convert_valid(const char* input, size_t size, } // namespace westmere } // namespace simdutf /* end file src/generic/utf8_to_utf32/valid_utf8_to_utf32.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8_to_utf32/utf8_to_utf32.h /* begin file src/generic/utf8_to_utf32/utf8_to_utf32.h */ @@ -28008,7 +28016,7 @@ using namespace simd; } // namespace simdutf /* end file src/generic/utf8_to_utf32/utf8_to_utf32.h */ // other functions -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf8.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf8.h /* begin file src/generic/utf8.h */ namespace simdutf { @@ -28055,7 +28063,7 @@ simdutf_really_inline size_t utf32_length_from_utf8(const char* in, size_t size) } // namespace westmere } // namespace simdutf /* end file src/generic/utf8.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=generic/utf16.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=generic/utf16.h /* begin file src/generic/utf16.h */ namespace simdutf { namespace westmere { @@ -28587,7 +28595,7 @@ simdutf_warn_unused size_t implementation::utf32_length_from_utf8(const char * i } // namespace westmere } // namespace simdutf -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/src, filename=simdutf/westmere/end.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/src, filename=simdutf/westmere/end.h /* begin file src/simdutf/westmere/end.h */ #if SIMDUTF_CAN_ALWAYS_RUN_WESTMERE // nothing needed. diff --git a/deps/simdutf/simdutf.h b/deps/simdutf/simdutf.h index f63c163c0f2b30..22a49f48c6bc95 100644 --- a/deps/simdutf/simdutf.h +++ b/deps/simdutf/simdutf.h @@ -1,11 +1,11 @@ -/* auto-generated on 2023-06-05 08:58:28 -0400. Do not edit! */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf.h +/* auto-generated on 2023-08-11 13:30:54 -0400. Do not edit! */ +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf.h /* begin file include/simdutf.h */ #ifndef SIMDUTF_H #define SIMDUTF_H #include -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/compiler_check.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/compiler_check.h /* begin file include/simdutf/compiler_check.h */ #ifndef SIMDUTF_COMPILER_CHECK_H #define SIMDUTF_COMPILER_CHECK_H @@ -43,13 +43,13 @@ #endif // SIMDUTF_COMPILER_CHECK_H /* end file include/simdutf/compiler_check.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/common_defs.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/common_defs.h /* begin file include/simdutf/common_defs.h */ #ifndef SIMDUTF_COMMON_DEFS_H #define SIMDUTF_COMMON_DEFS_H #include -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/portability.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/portability.h /* begin file include/simdutf/portability.h */ #ifndef SIMDUTF_PORTABILITY_H #define SIMDUTF_PORTABILITY_H @@ -280,7 +280,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.") #endif // SIMDUTF_PORTABILITY_H /* end file include/simdutf/portability.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/avx512.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/avx512.h /* begin file include/simdutf/avx512.h */ #ifndef SIMDUTF_AVX512_H_ #define SIMDUTF_AVX512_H_ @@ -483,7 +483,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.") #endif // SIMDUTF_COMMON_DEFS_H /* end file include/simdutf/common_defs.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/encoding_types.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/encoding_types.h /* begin file include/simdutf/encoding_types.h */ #include @@ -531,7 +531,7 @@ size_t bom_byte_size(encoding_type bom); } // BOM namespace } // simdutf namespace /* end file include/simdutf/encoding_types.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/error.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/error.h /* begin file include/simdutf/error.h */ #ifndef ERROR_H #define ERROR_H @@ -568,7 +568,7 @@ SIMDUTF_PUSH_DISABLE_WARNINGS SIMDUTF_DISABLE_UNDESIRED_WARNINGS // Public API -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/simdutf_version.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/simdutf_version.h /* begin file include/simdutf/simdutf_version.h */ // /include/simdutf/simdutf_version.h automatically generated by release.py, // do not change by hand @@ -576,7 +576,7 @@ SIMDUTF_DISABLE_UNDESIRED_WARNINGS #define SIMDUTF_SIMDUTF_VERSION_H /** The version of simdutf being used (major.minor.revision) */ -#define SIMDUTF_VERSION "3.2.14" +#define SIMDUTF_VERSION "3.2.17" namespace simdutf { enum { @@ -591,13 +591,13 @@ enum { /** * The revision (major.minor.REVISION) of simdutf being used. */ - SIMDUTF_VERSION_REVISION = 14 + SIMDUTF_VERSION_REVISION = 17 }; } // namespace simdutf #endif // SIMDUTF_SIMDUTF_VERSION_H /* end file include/simdutf/simdutf_version.h */ -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/implementation.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/implementation.h /* begin file include/simdutf/implementation.h */ #ifndef SIMDUTF_IMPLEMENTATION_H #define SIMDUTF_IMPLEMENTATION_H @@ -607,7 +607,7 @@ enum { #endif #include #include -// dofile: invoked with prepath=/Users/lemire/CVS/github/simdutf/include, filename=simdutf/internal/isadetection.h +// dofile: invoked with prepath=/Users/dlemire/CVS/github/simdutf/include, filename=simdutf/internal/isadetection.h /* begin file include/simdutf/internal/isadetection.h */ /* From https://github.com/endorno/pytorch/blob/master/torch/lib/TH/generic/simd/simd.h diff --git a/deps/undici/src/README.md b/deps/undici/src/README.md index 05a5d21ed1195c..3ba89890df6f69 100644 --- a/deps/undici/src/README.md +++ b/deps/undici/src/README.md @@ -18,30 +18,34 @@ npm i undici ## Benchmarks The benchmark is a simple `hello world` [example](benchmarks/benchmark.js) using a -number of unix sockets (connections) with a pipelining depth of 10 running on Node 16. -The benchmarks below have the [simd](https://github.com/WebAssembly/simd) feature enabled. +number of unix sockets (connections) with a pipelining depth of 10 running on Node 20.6.0. ### Connections 1 + | Tests | Samples | Result | Tolerance | Difference with slowest | |---------------------|---------|---------------|-----------|-------------------------| -| http - no keepalive | 15 | 4.63 req/sec | ± 2.77 % | - | -| http - keepalive | 10 | 4.81 req/sec | ± 2.16 % | + 3.94 % | -| undici - stream | 25 | 62.22 req/sec | ± 2.67 % | + 1244.58 % | -| undici - dispatch | 15 | 64.33 req/sec | ± 2.47 % | + 1290.24 % | -| undici - request | 15 | 66.08 req/sec | ± 2.48 % | + 1327.88 % | -| undici - pipeline | 10 | 66.13 req/sec | ± 1.39 % | + 1329.08 % | +| http - no keepalive | 15 | 5.32 req/sec | ± 2.61 % | - | +| http - keepalive | 10 | 5.35 req/sec | ± 2.47 % | + 0.44 % | +| undici - fetch | 15 | 41.85 req/sec | ± 2.49 % | + 686.04 % | +| undici - pipeline | 40 | 50.36 req/sec | ± 2.77 % | + 845.92 % | +| undici - stream | 15 | 60.58 req/sec | ± 2.75 % | + 1037.72 % | +| undici - request | 10 | 61.19 req/sec | ± 2.60 % | + 1049.24 % | +| undici - dispatch | 20 | 64.84 req/sec | ± 2.81 % | + 1117.81 % | + ### Connections 50 | Tests | Samples | Result | Tolerance | Difference with slowest | |---------------------|---------|------------------|-----------|-------------------------| -| http - no keepalive | 50 | 3546.49 req/sec | ± 2.90 % | - | -| http - keepalive | 15 | 5692.67 req/sec | ± 2.48 % | + 60.52 % | -| undici - pipeline | 25 | 8478.71 req/sec | ± 2.62 % | + 139.07 % | -| undici - request | 20 | 9766.66 req/sec | ± 2.79 % | + 175.39 % | -| undici - stream | 15 | 10109.74 req/sec | ± 2.94 % | + 185.06 % | -| undici - dispatch | 25 | 10949.73 req/sec | ± 2.54 % | + 208.75 % | +| undici - fetch | 30 | 2107.19 req/sec | ± 2.69 % | - | +| http - no keepalive | 10 | 2698.90 req/sec | ± 2.68 % | + 28.08 % | +| http - keepalive | 10 | 4639.49 req/sec | ± 2.55 % | + 120.17 % | +| undici - pipeline | 40 | 6123.33 req/sec | ± 2.97 % | + 190.59 % | +| undici - stream | 50 | 9426.51 req/sec | ± 2.92 % | + 347.35 % | +| undici - request | 10 | 10162.88 req/sec | ± 2.13 % | + 382.29 % | +| undici - dispatch | 50 | 11191.11 req/sec | ± 2.98 % | + 431.09 % | + ## Quick Start @@ -432,6 +436,7 @@ and `undici.Agent`) which will enable the family autoselection algorithm when es * [__Ethan Arrowood__](https://github.com/ethan-arrowood), * [__Matteo Collina__](https://github.com/mcollina), * [__Robert Nagy__](https://github.com/ronag), +* [__Matthew Aitken__](https://github.com/KhafraDev), ## License diff --git a/deps/undici/src/docs/api/Client.md b/deps/undici/src/docs/api/Client.md index fc7c5d26e8f799..c0987713a328c5 100644 --- a/deps/undici/src/docs/api/Client.md +++ b/deps/undici/src/docs/api/Client.md @@ -17,11 +17,13 @@ Returns: `Client` ### Parameter: `ClientOptions` +> ⚠️ Warning: The `H2` support is experimental. + * **bodyTimeout** `number | null` (optional) - Default: `300e3` - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds. -* **headersTimeout** `number | null` (optional) - Default: `300e3` - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds. -* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout` when overridden by *keep-alive* hints from the server. Defaults to 10 minutes. -* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds. -* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second. +* **headersTimeout** `number | null` (optional) - Default: `300e3` - The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds. +* **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Defaults to 10 minutes. +* **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds. +* **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number of milliseconds subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second. * **maxHeaderSize** `number | null` (optional) - Default: `16384` - The maximum length of request headers in bytes. Defaults to 16KiB. * **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable. * **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections. @@ -30,6 +32,8 @@ Returns: `Client` * **interceptors** `{ Client: DispatchInterceptor[] }` - Default: `[RedirectInterceptor]` - A list of interceptors that are applied to the dispatch method. Additional logic can be applied (such as, but not limited to: 302 status code handling, authentication, cookies, compression and caching). Note that the behavior of interceptors is Experimental and might change at any given time. * **autoSelectFamily**: `boolean` (optional) - Default: depends on local Node version, on Node 18.13.0 and above is `false`. Enables a family autodetection algorithm that loosely implements section 5 of [RFC 8305](https://tools.ietf.org/html/rfc8305#section-5). See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. This option is ignored if not supported by the current Node version. * **autoSelectFamilyAttemptTimeout**: `number` - Default: depends on local Node version, on Node 18.13.0 and above is `250`. The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. See [here](https://nodejs.org/api/net.html#socketconnectoptions-connectlistener) for more details. +* **allowH2**: `boolean` - Default: `false`. Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation. +* **maxConcurrentStreams**: `number` - Default: `100`. Dictates the maximum number of concurrent streams for a single H2 session. It can be overriden by a SETTINGS remote frame. #### Parameter: `ConnectOptions` @@ -38,7 +42,7 @@ Furthermore, the following options can be passed: * **socketPath** `string | null` (optional) - Default: `null` - An IPC endpoint, either Unix domain socket or Windows named pipe. * **maxCachedSessions** `number | null` (optional) - Default: `100` - Maximum number of TLS cached sessions. Use 0 to disable TLS session caching. Default: 100. -* **timeout** `number | null` (optional) - Default `10e3` +* **timeout** `number | null` (optional) - In milliseconds, Default `10e3`. * **servername** `string | null` (optional) * **keepAlive** `boolean | null` (optional) - Default: `true` - TCP keep-alive enabled * **keepAliveInitialDelay** `number | null` (optional) - Default: `60000` - TCP keep-alive interval for the socket in milliseconds diff --git a/deps/undici/src/docs/api/Connector.md b/deps/undici/src/docs/api/Connector.md index 7c966507e5fceb..56821bd6430279 100644 --- a/deps/undici/src/docs/api/Connector.md +++ b/deps/undici/src/docs/api/Connector.md @@ -13,8 +13,8 @@ Every Tls option, see [here](https://nodejs.org/api/tls.html#tls_tls_connect_opt Furthermore, the following options can be passed: * **socketPath** `string | null` (optional) - Default: `null` - An IPC endpoint, either Unix domain socket or Windows named pipe. -* **maxCachedSessions** `number | null` (optional) - Default: `100` - Maximum number of TLS cached sessions. Use 0 to disable TLS session caching. Default: 100. -* **timeout** `number | null` (optional) - Default `10e3` +* **maxCachedSessions** `number | null` (optional) - Default: `100` - Maximum number of TLS cached sessions. Use 0 to disable TLS session caching. Default: `100`. +* **timeout** `number | null` (optional) - In milliseconds. Default `10e3`. * **servername** `string | null` (optional) Once you call `buildConnector`, it will return a connector function, which takes the following parameters. diff --git a/deps/undici/src/docs/api/Dispatcher.md b/deps/undici/src/docs/api/Dispatcher.md index a50642948aaca1..fd463bfea16737 100644 --- a/deps/undici/src/docs/api/Dispatcher.md +++ b/deps/undici/src/docs/api/Dispatcher.md @@ -200,8 +200,9 @@ Returns: `Boolean` - `false` if dispatcher is busy and further dispatch calls wo * **blocking** `boolean` (optional) - Default: `false` - Whether the response is expected to take a long time and would end up blocking the pipeline. When this is set to `true` further pipelining will be avoided on the same connection until headers have been received. * **upgrade** `string | null` (optional) - Default: `null` - Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. * **bodyTimeout** `number | null` (optional) - The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Defaults to 300 seconds. -* **headersTimeout** `number | null` (optional) - The amount of time the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds. +* **headersTimeout** `number | null` (optional) - The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers while not sending the request. Defaults to 300 seconds. * **throwOnError** `boolean` (optional) - Default: `false` - Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server. +* **expectContinue** `boolean` (optional) - Default: `false` - For H2, it appends the expect: 100-continue header, and halts the request body until a 100-continue is received from the remote server #### Parameter: `DispatchHandler` diff --git a/deps/undici/src/docs/api/MockPool.md b/deps/undici/src/docs/api/MockPool.md index 923c157aa64657..de53914002eca3 100644 --- a/deps/undici/src/docs/api/MockPool.md +++ b/deps/undici/src/docs/api/MockPool.md @@ -35,7 +35,8 @@ const mockPool = mockAgent.get('http://localhost:3000') ### `MockPool.intercept(options)` -This method defines the interception rules for matching against requests for a MockPool or MockPool. We can intercept multiple times on a single instance. +This method defines the interception rules for matching against requests for a MockPool or MockPool. We can intercept multiple times on a single instance, but each intercept is only used once. +For example if you expect to make 2 requests inside a test, you need to call `intercept()` twice. Assuming you use `disableNetConnect()` you will get `MockNotMatchedError` on the second request when you only call `intercept()` once. When defining interception rules, all the rules must pass for a request to be intercepted. If a request is not intercepted, a real request will be attempted. diff --git a/deps/undici/src/docs/api/ProxyAgent.md b/deps/undici/src/docs/api/ProxyAgent.md index 6a8b07fe6bfb75..cebfe689f39c1d 100644 --- a/deps/undici/src/docs/api/ProxyAgent.md +++ b/deps/undici/src/docs/api/ProxyAgent.md @@ -19,7 +19,9 @@ Extends: [`AgentOptions`](Agent.md#parameter-agentoptions) * **uri** `string` (required) - It can be passed either by a string or a object containing `uri` as string. * **token** `string` (optional) - It can be passed by a string of token for authentication. * **auth** `string` (**deprecated**) - Use token. -* **clientFactory** `(origin: URL, opts: Object) => Dispatcher` - Default: `(origin, opts) => new Pool(origin, opts)` +* **clientFactory** `(origin: URL, opts: Object) => Dispatcher` (optional) - Default: `(origin, opts) => new Pool(origin, opts)` +* **requestTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the request. See [TLS](https://nodejs.org/api/tls.html#tlsconnectoptions-callback). +* **proxyTls** `BuildOptions` (optional) - Options object passed when creating the underlying socket via the connector builder for the proxy server. See [TLS](https://nodejs.org/api/tls.html#tlsconnectoptions-callback). Examples: diff --git a/deps/undici/src/index-fetch.js b/deps/undici/src/index-fetch.js index 0d59d254f7d548..23ac530600769e 100644 --- a/deps/undici/src/index-fetch.js +++ b/deps/undici/src/index-fetch.js @@ -2,9 +2,9 @@ const fetchImpl = require('./lib/fetch').fetch -module.exports.fetch = async function fetch (resource) { +module.exports.fetch = async function fetch (resource, init = undefined) { try { - return await fetchImpl(...arguments) + return await fetchImpl(resource, init) } catch (err) { Error.captureStackTrace(err, this) throw err @@ -14,3 +14,4 @@ module.exports.FormData = require('./lib/fetch/formdata').FormData module.exports.Headers = require('./lib/fetch/headers').Headers module.exports.Response = require('./lib/fetch/response').Response module.exports.Request = require('./lib/fetch/request').Request +module.exports.WebSocket = require('./lib/websocket/websocket').WebSocket diff --git a/deps/undici/src/index.d.ts b/deps/undici/src/index.d.ts index 0730677b29e419..83a786d6a03131 100644 --- a/deps/undici/src/index.d.ts +++ b/deps/undici/src/index.d.ts @@ -1,57 +1,3 @@ -import Dispatcher from'./types/dispatcher' -import { setGlobalDispatcher, getGlobalDispatcher } from './types/global-dispatcher' -import { setGlobalOrigin, getGlobalOrigin } from './types/global-origin' -import Pool from'./types/pool' -import { RedirectHandler, DecoratorHandler } from './types/handlers' - -import BalancedPool from './types/balanced-pool' -import Client from'./types/client' -import buildConnector from'./types/connector' -import errors from'./types/errors' -import Agent from'./types/agent' -import MockClient from'./types/mock-client' -import MockPool from'./types/mock-pool' -import MockAgent from'./types/mock-agent' -import mockErrors from'./types/mock-errors' -import ProxyAgent from'./types/proxy-agent' -import { request, pipeline, stream, connect, upgrade } from './types/api' - -export * from './types/cookies' -export * from './types/fetch' -export * from './types/file' -export * from './types/filereader' -export * from './types/formdata' -export * from './types/diagnostics-channel' -export * from './types/websocket' -export * from './types/content-type' -export * from './types/cache' -export { Interceptable } from './types/mock-interceptor' - -export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, setGlobalOrigin, getGlobalOrigin, MockClient, MockPool, MockAgent, mockErrors, ProxyAgent, RedirectHandler, DecoratorHandler } +export * from './types/index' +import Undici from './types/index' export default Undici - -declare namespace Undici { - var Dispatcher: typeof import('./types/dispatcher').default - var Pool: typeof import('./types/pool').default; - var RedirectHandler: typeof import ('./types/handlers').RedirectHandler - var DecoratorHandler: typeof import ('./types/handlers').DecoratorHandler - var createRedirectInterceptor: typeof import ('./types/interceptors').createRedirectInterceptor - var BalancedPool: typeof import('./types/balanced-pool').default; - var Client: typeof import('./types/client').default; - var buildConnector: typeof import('./types/connector').default; - var errors: typeof import('./types/errors').default; - var Agent: typeof import('./types/agent').default; - var setGlobalDispatcher: typeof import('./types/global-dispatcher').setGlobalDispatcher; - var getGlobalDispatcher: typeof import('./types/global-dispatcher').getGlobalDispatcher; - var request: typeof import('./types/api').request; - var stream: typeof import('./types/api').stream; - var pipeline: typeof import('./types/api').pipeline; - var connect: typeof import('./types/api').connect; - var upgrade: typeof import('./types/api').upgrade; - var MockClient: typeof import('./types/mock-client').default; - var MockPool: typeof import('./types/mock-pool').default; - var MockAgent: typeof import('./types/mock-agent').default; - var mockErrors: typeof import('./types/mock-errors').default; - var fetch: typeof import('./types/fetch').fetch; - var caches: typeof import('./types/cache').caches; -} diff --git a/deps/undici/src/index.js b/deps/undici/src/index.js index 7e8831ceeea3ea..7c0c8adcd6c809 100644 --- a/deps/undici/src/index.js +++ b/deps/undici/src/index.js @@ -106,7 +106,10 @@ if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) { try { return await fetchImpl(...arguments) } catch (err) { - Error.captureStackTrace(err, this) + if (typeof err === 'object') { + Error.captureStackTrace(err, this) + } + throw err } } diff --git a/deps/undici/src/lib/api/abort-signal.js b/deps/undici/src/lib/api/abort-signal.js index 895629aa466daa..2985c1efa969b3 100644 --- a/deps/undici/src/lib/api/abort-signal.js +++ b/deps/undici/src/lib/api/abort-signal.js @@ -1,3 +1,4 @@ +const { addAbortListener } = require('../core/util') const { RequestAbortedError } = require('../core/errors') const kListener = Symbol('kListener') @@ -29,11 +30,7 @@ function addSignal (self, signal) { abort(self) } - if ('addEventListener' in self[kSignal]) { - self[kSignal].addEventListener('abort', self[kListener]) - } else { - self[kSignal].addListener('abort', self[kListener]) - } + addAbortListener(self[kSignal], self[kListener]) } function removeSignal (self) { diff --git a/deps/undici/src/lib/api/api-connect.js b/deps/undici/src/lib/api/api-connect.js index 0503b1a2f0eb10..fd2b6ad97a52d5 100644 --- a/deps/undici/src/lib/api/api-connect.js +++ b/deps/undici/src/lib/api/api-connect.js @@ -1,7 +1,7 @@ 'use strict' -const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors') const { AsyncResource } = require('async_hooks') +const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors') const util = require('../core/util') const { addSignal, removeSignal } = require('./abort-signal') @@ -50,7 +50,13 @@ class ConnectHandler extends AsyncResource { removeSignal(this) this.callback = null - const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + + let headers = rawHeaders + // Indicates is an HTTP2Session + if (headers != null) { + headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders) + } + this.runInAsyncScope(callback, null, null, { statusCode, headers, diff --git a/deps/undici/src/lib/api/api-request.js b/deps/undici/src/lib/api/api-request.js index 71d7e926b4c395..f130ecc9867a88 100644 --- a/deps/undici/src/lib/api/api-request.js +++ b/deps/undici/src/lib/api/api-request.js @@ -95,7 +95,6 @@ class RequestHandler extends AsyncResource { this.callback = null this.res = body - if (callback !== null) { if (this.throwOnError && statusCode >= 400) { this.runInAsyncScope(getResolveErrorBodyCallback, null, diff --git a/deps/undici/src/lib/api/readable.js b/deps/undici/src/lib/api/readable.js index 398a75ba8bbaa7..508fbdef928618 100644 --- a/deps/undici/src/lib/api/readable.js +++ b/deps/undici/src/lib/api/readable.js @@ -155,12 +155,13 @@ module.exports = class BodyReadable extends Readable { const abortFn = () => { this.destroy() } + let signalListenerCleanup if (signal) { if (typeof signal !== 'object' || !('aborted' in signal)) { throw new InvalidArgumentError('signal must be an AbortSignal') } util.throwIfAborted(signal) - signal.addEventListener('abort', abortFn, { once: true }) + signalListenerCleanup = util.addAbortListener(signal, abortFn) } try { for await (const chunk of this) { @@ -173,8 +174,10 @@ module.exports = class BodyReadable extends Readable { } catch { util.throwIfAborted(signal) } finally { - if (signal) { - signal.removeEventListener('abort', abortFn) + if (typeof signalListenerCleanup === 'function') { + signalListenerCleanup() + } else if (signalListenerCleanup) { + signalListenerCleanup[Symbol.dispose]() } } } diff --git a/deps/undici/src/lib/cache/cache.js b/deps/undici/src/lib/cache/cache.js index 18f06a348a0a88..9b3110860cd6b8 100644 --- a/deps/undici/src/lib/cache/cache.js +++ b/deps/undici/src/lib/cache/cache.js @@ -379,11 +379,7 @@ class Cache { const reader = stream.getReader() // 11.3 - readAllBytes( - reader, - (bytes) => bodyReadPromise.resolve(bytes), - (error) => bodyReadPromise.reject(error) - ) + readAllBytes(reader).then(bodyReadPromise.resolve, bodyReadPromise.reject) } else { bodyReadPromise.resolve(undefined) } diff --git a/deps/undici/src/lib/client.js b/deps/undici/src/lib/client.js index 7d9ec8d7c272b3..b5170d4f88da9b 100644 --- a/deps/undici/src/lib/client.js +++ b/deps/undici/src/lib/client.js @@ -6,6 +6,7 @@ const assert = require('assert') const net = require('net') +const { pipeline } = require('stream') const util = require('./core/util') const timers = require('./timers') const Request = require('./core/request') @@ -67,8 +68,40 @@ const { kDispatch, kInterceptors, kLocalAddress, - kMaxResponseSize + kMaxResponseSize, + kHTTPConnVersion, + // HTTP2 + kHost, + kHTTP2Session, + kHTTP2SessionState, + kHTTP2BuildRequest, + kHTTP2CopyHeaders, + kHTTP1BuildRequest } = require('./core/symbols') + +/** @type {import('http2')} */ +let http2 +try { + http2 = require('http2') +} catch { + // @ts-ignore + http2 = { constants: {} } +} + +const { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS + } +} = http2 + +// Experimental +let h2ExperimentalWarned = false + const FastBuffer = Buffer[Symbol.species] const kClosedResolve = Symbol('kClosedResolve') @@ -122,7 +155,10 @@ class Client extends DispatcherBase { localAddress, maxResponseSize, autoSelectFamily, - autoSelectFamilyAttemptTimeout + autoSelectFamilyAttemptTimeout, + // h2 + allowH2, + maxConcurrentStreams } = {}) { super() @@ -205,10 +241,20 @@ class Client extends DispatcherBase { throw new InvalidArgumentError('autoSelectFamilyAttemptTimeout must be a positive number') } + // h2 + if (allowH2 != null && typeof allowH2 !== 'boolean') { + throw new InvalidArgumentError('allowH2 must be a valid boolean value') + } + + if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== 'number' || maxConcurrentStreams < 1)) { + throw new InvalidArgumentError('maxConcurrentStreams must be a possitive integer, greater than 0') + } + if (typeof connect !== 'function') { connect = buildConnector({ ...tls, maxCachedSessions, + allowH2, socketPath, timeout: connectTimeout, ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), @@ -240,6 +286,18 @@ class Client extends DispatcherBase { this[kMaxRequests] = maxRequestsPerClient this[kClosedResolve] = null this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 + this[kHTTPConnVersion] = 'h1' + + // HTTP/2 + this[kHTTP2Session] = null + this[kHTTP2SessionState] = !allowH2 + ? null + : { + // streams: null, // Fixed queue of streams - For future support of `push` + openStreams: 0, // Keep track of them to decide wether or not unref the session + maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 // Max peerConcurrentStreams for a Node h2 server + } + this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ''}` // kQueue is built up of 3 sections separated by // the kRunningIdx and kPendingIdx indices. @@ -298,7 +356,9 @@ class Client extends DispatcherBase { [kDispatch] (opts, handler) { const origin = opts.origin || this[kUrl].origin - const request = new Request(origin, opts, handler) + const request = this[kHTTPConnVersion] === 'h2' + ? Request[kHTTP2BuildRequest](origin, opts, handler) + : Request[kHTTP1BuildRequest](origin, opts, handler) this[kQueue].push(request) if (this[kResuming]) { @@ -319,6 +379,8 @@ class Client extends DispatcherBase { } async [kClose] () { + // TODO: for H2 we need to gracefully flush the remaining enqueued + // request and close each stream. return new Promise((resolve) => { if (!this[kSize]) { resolve(null) @@ -345,6 +407,12 @@ class Client extends DispatcherBase { resolve() } + if (this[kHTTP2Session] != null) { + util.destroy(this[kHTTP2Session], err) + this[kHTTP2Session] = null + this[kHTTP2SessionState] = null + } + if (!this[kSocket]) { queueMicrotask(callback) } else { @@ -356,6 +424,64 @@ class Client extends DispatcherBase { } } +function onHttp2SessionError (err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + + this[kSocket][kError] = err + + onError(this[kClient], err) +} + +function onHttp2FrameError (type, code, id) { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) + + if (id === 0) { + this[kSocket][kError] = err + onError(this[kClient], err) + } +} + +function onHttp2SessionEnd () { + util.destroy(this, new SocketError('other side closed')) + util.destroy(this[kSocket], new SocketError('other side closed')) +} + +function onHTTP2GoAway (code) { + const client = this[kClient] + const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`) + client[kSocket] = null + client[kHTTP2Session] = null + + if (client.destroyed) { + assert(this[kPending] === 0) + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } + } else if (client[kRunning] > 0) { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null + + errorRequest(client, request, err) + } + + client[kPendingIdx] = client[kRunningIdx] + + assert(client[kRunning] === 0) + + client.emit('disconnect', + client[kUrl], + [client], + err + ) + + resume(client) +} + const constants = require('./llhttp/constants') const createRedirectInterceptor = require('./interceptor/redirectInterceptor') const EMPTY_BUF = Buffer.alloc(0) @@ -946,16 +1072,18 @@ function onSocketReadable () { } function onSocketError (err) { - const { [kParser]: parser } = this + const { [kClient]: client, [kParser]: parser } = this assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded - // to the user. - if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so for as a valid response. - parser.onMessageComplete() - return + if (client[kHTTPConnVersion] !== 'h2') { + // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded + // to the user. + if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so for as a valid response. + parser.onMessageComplete() + return + } } this[kError] = err @@ -984,27 +1112,31 @@ function onError (client, err) { } function onSocketEnd () { - const { [kParser]: parser } = this + const { [kParser]: parser, [kClient]: client } = this - if (parser.statusCode && !parser.shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - parser.onMessageComplete() - return + if (client[kHTTPConnVersion] !== 'h2') { + if (parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + return + } } util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this))) } function onSocketClose () { - const { [kClient]: client } = this + const { [kClient]: client, [kParser]: parser } = this - if (!this[kError] && this[kParser].statusCode && !this[kParser].shouldKeepAlive) { - // We treat all incoming data so far as a valid response. - this[kParser].onMessageComplete() - } + if (client[kHTTPConnVersion] === 'h1' && parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + } - this[kParser].destroy() - this[kParser] = null + this[kParser].destroy() + this[kParser] = null + } const err = this[kError] || new SocketError('closed', util.getSocketInfo(this)) @@ -1092,24 +1224,54 @@ async function connect (client) { return } - if (!llhttpInstance) { - llhttpInstance = await llhttpPromise - llhttpPromise = null - } - client[kConnecting] = false assert(socket) - socket[kNoRef] = false - socket[kWriting] = false - socket[kReset] = false - socket[kBlocking] = false - socket[kError] = null - socket[kParser] = new Parser(client, socket, llhttpInstance) - socket[kClient] = client + const isH2 = socket.alpnProtocol === 'h2' + if (isH2) { + if (!h2ExperimentalWarned) { + h2ExperimentalWarned = true + process.emitWarning('H2 support is experimental, expect them to change at any time.', { + code: 'UNDICI-H2' + }) + } + + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: client[kHTTP2SessionState].maxConcurrentStreams + }) + + client[kHTTPConnVersion] = 'h2' + session[kClient] = client + session[kSocket] = socket + session.on('error', onHttp2SessionError) + session.on('frameError', onHttp2FrameError) + session.on('end', onHttp2SessionEnd) + session.on('goaway', onHTTP2GoAway) + session.on('close', onSocketClose) + session.unref() + + client[kHTTP2Session] = session + socket[kHTTP2Session] = session + } else { + if (!llhttpInstance) { + llhttpInstance = await llhttpPromise + llhttpPromise = null + } + + socket[kNoRef] = false + socket[kWriting] = false + socket[kReset] = false + socket[kBlocking] = false + socket[kParser] = new Parser(client, socket, llhttpInstance) + } + socket[kCounter] = 0 socket[kMaxRequests] = client[kMaxRequests] + socket[kClient] = client + socket[kError] = null + socket .on('error', onSocketError) .on('readable', onSocketReadable) @@ -1208,7 +1370,7 @@ function _resume (client, sync) { const socket = client[kSocket] - if (socket && !socket.destroyed) { + if (socket && !socket.destroyed && socket.alpnProtocol !== 'h2') { if (client[kSize] === 0) { if (!socket[kNoRef] && socket.unref) { socket.unref() @@ -1273,7 +1435,7 @@ function _resume (client, sync) { return } - if (!socket) { + if (!socket && !client[kHTTP2Session]) { connect(client) return } @@ -1334,6 +1496,11 @@ function _resume (client, sync) { } function write (client, request) { + if (client[kHTTPConnVersion] === 'h2') { + writeH2(client, client[kHTTP2Session], request) + return + } + const { body, method, path, host, upgrade, headers, blocking, reset } = request // https://tools.ietf.org/html/rfc7231#section-4.3.1 @@ -1489,9 +1656,291 @@ function write (client, request) { return true } -function writeStream ({ body, client, request, socket, contentLength, header, expectsPayload }) { +function writeH2 (client, session, request) { + const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request + + let headers + if (typeof reqHeaders === 'string') headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()) + else headers = reqHeaders + + if (upgrade) { + errorRequest(client, request, new Error('Upgrade not supported for H2')) + return false + } + + try { + // TODO(HTTP/2): Should we call onConnect immediately or on stream ready event? + request.onConnect((err) => { + if (request.aborted || request.completed) { + return + } + + errorRequest(client, request, err || new RequestAbortedError()) + }) + } catch (err) { + errorRequest(client, request, err) + } + + if (request.aborted) { + return false + } + + let stream + const h2State = client[kHTTP2SessionState] + + headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost] + headers[HTTP2_HEADER_PATH] = path + + if (method === 'CONNECT') { + session.ref() + // we are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered + // We disabled endStream to allow the user to write to the stream + stream = session.request(headers, { endStream: false, signal }) + + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + } else { + stream.once('ready', () => { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + }) + } + + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) session.unref() + }) + + return true + } else { + headers[HTTP2_HEADER_METHOD] = method + } + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = ( + method === 'PUT' || + method === 'POST' || + method === 'PATCH' + ) + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } + + let contentLength = util.bodyLength(body) + + if (contentLength == null) { + contentLength = request.contentLength + } + + if (contentLength === 0 || !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null + } + + if (request.contentLength != null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()) + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + if (contentLength != null) { + assert(body, 'no body must not have content length') + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` + } + + session.ref() + + const shouldEndStream = method === 'GET' || method === 'HEAD' + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = '100-continue' + /** + * @type {import('node:http2').ClientHttp2Stream} + */ + stream = session.request(headers, { endStream: shouldEndStream, signal }) + + stream.once('continue', writeBodyH2) + } else { + /** @type {import('node:http2').ClientHttp2Stream} */ + stream = session.request(headers, { + endStream: shouldEndStream, + signal + }) + writeBodyH2() + } + + // Increment counter as we have new several streams open + ++h2State.openStreams + + stream.once('response', headers => { + if (request.onHeaders(Number(headers[HTTP2_HEADER_STATUS]), headers, stream.resume.bind(stream), '') === false) { + stream.pause() + } + }) + + stream.once('end', () => { + request.onComplete([]) + }) + + stream.on('data', (chunk) => { + if (request.onData(chunk) === false) stream.pause() + }) + + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) session.unref() + }) + + stream.once('error', function (err) { + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) + + stream.once('frameError', (type, code) => { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`) + errorRequest(client, request, err) + + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) + + // stream.on('aborted', () => { + // // TODO(HTTP/2): Support aborted + // }) + + // stream.on('timeout', () => { + // // TODO(HTTP/2): Support timeout + // }) + + // stream.on('push', headers => { + // // TODO(HTTP/2): Suppor push + // }) + + // stream.on('trailers', headers => { + // // TODO(HTTP/2): Support trailers + // }) + + return true + + function writeBodyH2 () { + /* istanbul ignore else: assertion */ + if (!body) { + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, 'buffer body must have content length') + stream.cork() + stream.write(body) + stream.uncork() + request.onBodySent(body) + request.onRequestSent() + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ + client, + request, + contentLength, + h2stream: stream, + expectsPayload, + body: body.stream(), + socket: client[kSocket], + header: '' + }) + } else { + writeBlob({ + body, + client, + request, + contentLength, + expectsPayload, + h2stream: stream, + header: '', + socket: client[kSocket] + }) + } + } else if (util.isStream(body)) { + writeStream({ + body, + client, + request, + contentLength, + expectsPayload, + socket: client[kSocket], + h2stream: stream, + header: '' + }) + } else if (util.isIterable(body)) { + writeIterable({ + body, + client, + request, + contentLength, + expectsPayload, + header: '', + h2stream: stream, + socket: client[kSocket] + }) + } else { + assert(false) + } + } +} + +function writeStream ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined') + if (client[kHTTPConnVersion] === 'h2') { + // For HTTP/2, is enough to pipe the stream + const pipe = pipeline( + body, + h2stream, + (err) => { + if (err) { + util.destroy(body, err) + util.destroy(h2stream, err) + } else { + request.onRequestSent() + } + } + ) + + pipe.on('data', onPipeData) + pipe.once('end', () => { + pipe.removeListener('data', onPipeData) + util.destroy(pipe) + }) + + function onPipeData (chunk) { + request.onBodySent(chunk) + } + + return + } + let finished = false const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }) @@ -1572,9 +2021,10 @@ function writeStream ({ body, client, request, socket, contentLength, header, ex .on('error', onFinished) } -async function writeBlob ({ body, client, request, socket, contentLength, header, expectsPayload }) { +async function writeBlob ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { assert(contentLength === body.size, 'blob body must have content length') + const isH2 = client[kHTTPConnVersion] === 'h2' try { if (contentLength != null && contentLength !== body.size) { throw new RequestContentLengthMismatchError() @@ -1582,10 +2032,16 @@ async function writeBlob ({ body, client, request, socket, contentLength, header const buffer = Buffer.from(await body.arrayBuffer()) - socket.cork() - socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') - socket.write(buffer) - socket.uncork() + if (isH2) { + h2stream.cork() + h2stream.write(buffer) + h2stream.uncork() + } else { + socket.cork() + socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1') + socket.write(buffer) + socket.uncork() + } request.onBodySent(buffer) request.onRequestSent() @@ -1596,11 +2052,11 @@ async function writeBlob ({ body, client, request, socket, contentLength, header resume(client) } catch (err) { - util.destroy(socket, err) + util.destroy(isH2 ? h2stream : socket, err) } } -async function writeIterable ({ body, client, request, socket, contentLength, header, expectsPayload }) { +async function writeIterable ({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined') let callback = null @@ -1622,6 +2078,33 @@ async function writeIterable ({ body, client, request, socket, contentLength, he } }) + if (client[kHTTPConnVersion] === 'h2') { + h2stream + .on('close', onDrain) + .on('drain', onDrain) + + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + if (!h2stream.write(chunk)) { + await waitForDrain() + } + } + } catch (err) { + h2stream.destroy(err) + } finally { + h2stream + .off('close', onDrain) + .off('drain', onDrain) + } + + return + } + socket .on('close', onDrain) .on('drain', onDrain) diff --git a/deps/undici/src/lib/core/connect.js b/deps/undici/src/lib/core/connect.js index f3b5cc33edd6cf..bb71085a1565fc 100644 --- a/deps/undici/src/lib/core/connect.js +++ b/deps/undici/src/lib/core/connect.js @@ -71,7 +71,7 @@ if (global.FinalizationRegistry) { } } -function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) { +function buildConnector ({ allowH2, maxCachedSessions, socketPath, timeout, ...opts }) { if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero') } @@ -79,7 +79,7 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) { const options = { path: socketPath, ...opts } const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions) timeout = timeout == null ? 10e3 : timeout - + allowH2 = allowH2 != null ? allowH2 : false return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { let socket if (protocol === 'https:') { @@ -99,6 +99,8 @@ function buildConnector ({ maxCachedSessions, socketPath, timeout, ...opts }) { servername, session, localAddress, + // TODO(HTTP/2): Add support for h2c + ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], socket: httpSocket, // upgrade socket connection port: port || 443, host: hostname diff --git a/deps/undici/src/lib/core/request.js b/deps/undici/src/lib/core/request.js index 6c9a24d5d590d7..e3b0c7b9dbf06c 100644 --- a/deps/undici/src/lib/core/request.js +++ b/deps/undici/src/lib/core/request.js @@ -5,6 +5,7 @@ const { NotSupportedError } = require('./errors') const assert = require('assert') +const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = require('./symbols') const util = require('./util') // tokenRegExp and headerCharRegex have been lifted from @@ -62,7 +63,8 @@ class Request { headersTimeout, bodyTimeout, reset, - throwOnError + throwOnError, + expectContinue }, handler) { if (typeof path !== 'string') { throw new InvalidArgumentError('path must be a string') @@ -98,6 +100,10 @@ class Request { throw new InvalidArgumentError('invalid reset') } + if (expectContinue != null && typeof expectContinue !== 'boolean') { + throw new InvalidArgumentError('invalid expectContinue') + } + this.headersTimeout = headersTimeout this.bodyTimeout = bodyTimeout @@ -150,6 +156,9 @@ class Request { this.headers = '' + // Only for H2 + this.expectContinue = expectContinue != null ? expectContinue : false + if (Array.isArray(headers)) { if (headers.length % 2 !== 0) { throw new InvalidArgumentError('headers array must be even') @@ -269,13 +278,64 @@ class Request { return this[kHandler].onError(error) } + // TODO: adjust to support H2 addHeader (key, value) { processHeader(this, key, value) return this } + + static [kHTTP1BuildRequest] (origin, opts, handler) { + // TODO: Migrate header parsing here, to make Requests + // HTTP agnostic + return new Request(origin, opts, handler) + } + + static [kHTTP2BuildRequest] (origin, opts, handler) { + const headers = opts.headers + opts = { ...opts, headers: null } + + const request = new Request(origin, opts, handler) + + request.headers = {} + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(request, headers[i], headers[i + 1], true) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(request, key, headers[key], true) + } + } else if (headers != null) { + throw new InvalidArgumentError('headers must be an object or an array') + } + + return request + } + + static [kHTTP2CopyHeaders] (raw) { + const rawHeaders = raw.split('\r\n') + const headers = {} + + for (const header of rawHeaders) { + const [key, value] = header.split(': ') + + if (value == null || value.length === 0) continue + + if (headers[key]) headers[key] += `,${value}` + else headers[key] = value + } + + return headers + } } -function processHeaderValue (key, val) { +function processHeaderValue (key, val, skipAppend) { if (val && typeof val === 'object') { throw new InvalidArgumentError(`invalid ${key} header`) } @@ -286,10 +346,10 @@ function processHeaderValue (key, val) { throw new InvalidArgumentError(`invalid ${key} header`) } - return `${key}: ${val}\r\n` + return skipAppend ? val : `${key}: ${val}\r\n` } -function processHeader (request, key, val) { +function processHeader (request, key, val, skipAppend = false) { if (val && (typeof val === 'object' && !Array.isArray(val))) { throw new InvalidArgumentError(`invalid ${key} header`) } else if (val === undefined) { @@ -357,10 +417,16 @@ function processHeader (request, key, val) { } else { if (Array.isArray(val)) { for (let i = 0; i < val.length; i++) { - request.headers += processHeaderValue(key, val[i]) + if (skipAppend) { + if (request.headers[key]) request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}` + else request.headers[key] = processHeaderValue(key, val[i], skipAppend) + } else { + request.headers += processHeaderValue(key, val[i]) + } } } else { - request.headers += processHeaderValue(key, val) + if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) } } } diff --git a/deps/undici/src/lib/core/symbols.js b/deps/undici/src/lib/core/symbols.js index c852107a72af26..c2492f4355fd2a 100644 --- a/deps/undici/src/lib/core/symbols.js +++ b/deps/undici/src/lib/core/symbols.js @@ -51,5 +51,11 @@ module.exports = { kProxy: Symbol('proxy agent options'), kCounter: Symbol('socket request counter'), kInterceptors: Symbol('dispatch interceptors'), - kMaxResponseSize: Symbol('max response size') + kMaxResponseSize: Symbol('max response size'), + kHTTP2Session: Symbol('http2Session'), + kHTTP2SessionState: Symbol('http2Session state'), + kHTTP2BuildRequest: Symbol('http2 build request'), + kHTTP1BuildRequest: Symbol('http1 build request'), + kHTTP2CopyHeaders: Symbol('http2 copy headers'), + kHTTPConnVersion: Symbol('http connection version') } diff --git a/deps/undici/src/lib/core/util.js b/deps/undici/src/lib/core/util.js index 6f247d22a524bf..259ba7b38a64e9 100644 --- a/deps/undici/src/lib/core/util.js +++ b/deps/undici/src/lib/core/util.js @@ -168,7 +168,7 @@ function bodyLength (body) { return 0 } else if (isStream(body)) { const state = body._readableState - return state && state.ended === true && Number.isFinite(state.length) + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) ? state.length : null } else if (isBlobLike(body)) { @@ -199,6 +199,7 @@ function destroy (stream, err) { // See: https://github.com/nodejs/node/pull/38505/files stream.socket = null } + stream.destroy(err) } else if (err) { process.nextTick((stream, err) => { @@ -218,6 +219,9 @@ function parseKeepAliveTimeout (val) { } function parseHeaders (headers, obj = {}) { + // For H2 support + if (!Array.isArray(headers)) return headers + for (let i = 0; i < headers.length; i += 2) { const key = headers[i].toString().toLowerCase() let val = obj[key] @@ -355,6 +359,12 @@ function getSocketInfo (socket) { } } +async function * convertIterableToBuffer (iterable) { + for await (const chunk of iterable) { + yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) + } +} + let ReadableStream function ReadableStreamFrom (iterable) { if (!ReadableStream) { @@ -362,8 +372,7 @@ function ReadableStreamFrom (iterable) { } if (ReadableStream.from) { - // https://github.com/whatwg/streams/pull/1083 - return ReadableStream.from(iterable) + return ReadableStream.from(convertIterableToBuffer(iterable)) } let iterator @@ -422,6 +431,24 @@ function throwIfAborted (signal) { } } +let events +function addAbortListener (signal, listener) { + if (typeof Symbol.dispose === 'symbol') { + if (!events) { + events = require('events') + } + if (typeof events.addAbortListener === 'function' && 'aborted' in signal) { + return events.addAbortListener(signal, listener) + } + } + if ('addEventListener' in signal) { + signal.addEventListener('abort', listener, { once: true }) + return () => signal.removeEventListener('abort', listener) + } + signal.addListener('abort', listener) + return () => signal.removeListener('abort', listener) +} + const hasToWellFormed = !!String.prototype.toWellFormed /** @@ -469,6 +496,7 @@ module.exports = { isFormDataLike, buildURL, throwIfAborted, + addAbortListener, nodeMajor, nodeMinor, nodeHasAutoSelectFamily: nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13) diff --git a/deps/undici/src/lib/fetch/body.js b/deps/undici/src/lib/fetch/body.js index db450ee6bd4ea8..105eb553157b06 100644 --- a/deps/undici/src/lib/fetch/body.js +++ b/deps/undici/src/lib/fetch/body.js @@ -105,7 +105,7 @@ function extractBody (object, keepalive = false) { // Set source to a copy of the bytes held by object. source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) } else if (util.isFormDataLike(object)) { - const boundary = `----formdata-undici-${Math.random()}`.replace('.', '').slice(0, 32) + const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` const prefix = `--${boundary}\r\nContent-Disposition: form-data` /*! formdata-polyfill. MIT License. Jimmy Wärting */ @@ -387,6 +387,7 @@ function bodyMixinMethods (instance) { try { busboy = Busboy({ headers, + preservePath: true, defParamCharset: 'utf8' }) } catch (err) { @@ -532,7 +533,7 @@ async function specConsumeBody (object, convertBytesToJSValue, instance) { // 6. Otherwise, fully read object’s body given successSteps, // errorSteps, and object’s relevant global object. - fullyReadBody(object[kState].body, successSteps, errorSteps) + await fullyReadBody(object[kState].body, successSteps, errorSteps) // 7. Return promise. return promise.promise diff --git a/deps/undici/src/lib/fetch/index.js b/deps/undici/src/lib/fetch/index.js index 519987324274fe..50f1b9f3fcdcc1 100644 --- a/deps/undici/src/lib/fetch/index.js +++ b/deps/undici/src/lib/fetch/index.js @@ -56,7 +56,7 @@ const { const { kHeadersList } = require('../core/symbols') const EE = require('events') const { Readable, pipeline } = require('stream') -const { isErrored, isReadable, nodeMajor, nodeMinor } = require('../core/util') +const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = require('../core/util') const { dataURLProcessor, serializeAMimeType } = require('./dataURL') const { TransformStream } = require('stream/web') const { getGlobalDispatcher } = require('../global') @@ -174,22 +174,22 @@ async function fetch (input, init = {}) { let controller = null // 11. Add the following abort steps to requestObject’s signal: - requestObject.signal.addEventListener( - 'abort', + addAbortListener( + requestObject.signal, () => { // 1. Set locallyAborted to true. locallyAborted = true - // 2. Abort the fetch() call with p, request, responseObject, + // 2. Assert: controller is non-null. + assert(controller != null) + + // 3. Abort controller with requestObject’s signal’s abort reason. + controller.abort(requestObject.signal.reason) + + // 4. Abort the fetch() call with p, request, responseObject, // and requestObject’s signal’s abort reason. abortFetch(p, request, responseObject, requestObject.signal.reason) - - // 3. If controller is not null, then abort controller. - if (controller != null) { - controller.abort() - } - }, - { once: true } + } ) // 12. Let handleFetchDone given response response be to finalize and @@ -319,7 +319,7 @@ function finalizeAndReportTiming (response, initiatorType = 'other') { // https://w3c.github.io/resource-timing/#dfn-mark-resource-timing function markResourceTiming (timingInfo, originalURL, initiatorType, globalThis, cacheState) { if (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2)) { - performance.markResourceTiming(timingInfo, originalURL, initiatorType, globalThis, cacheState) + performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis, cacheState) } } @@ -1760,7 +1760,7 @@ async function httpNetworkFetch ( fetchParams.controller.connection.destroy() // 2. Return the appropriate network error for fetchParams. - return makeAppropriateNetworkError(fetchParams) + return makeAppropriateNetworkError(fetchParams, err) } return makeNetworkError(err) @@ -1979,19 +1979,37 @@ async function httpNetworkFetch ( let location = '' const headers = new Headers() - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString('latin1') - const val = headersList[n + 1].toString('latin1') - if (key.toLowerCase() === 'content-encoding') { - // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 - // "All content-coding values are case-insensitive..." - codings = val.toLowerCase().split(',').map((x) => x.trim()) - } else if (key.toLowerCase() === 'location') { - location = val + // For H2, the headers are a plain JS object + // We distinguish between them and iterate accordingly + if (Array.isArray(headersList)) { + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()) + } else if (key.toLowerCase() === 'location') { + location = val + } + + headers.append(key, val) } + } else { + const keys = Object.keys(headersList) + for (const key of keys) { + const val = headersList[key] + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val.toLowerCase().split(',').map((x) => x.trim()).reverse() + } else if (key.toLowerCase() === 'location') { + location = val + } - headers.append(key, val) + headers.append(key, val) + } } this.body = new Readable({ read: resume }) @@ -2007,7 +2025,14 @@ async function httpNetworkFetch ( for (const coding of codings) { // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 if (coding === 'x-gzip' || coding === 'gzip') { - decoders.push(zlib.createGunzip()) + decoders.push(zlib.createGunzip({ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH + })) } else if (coding === 'deflate') { decoders.push(zlib.createInflate()) } else if (coding === 'br') { diff --git a/deps/undici/src/lib/fetch/request.js b/deps/undici/src/lib/fetch/request.js index 5c836e4e558285..912bd5b8c988af 100644 --- a/deps/undici/src/lib/fetch/request.js +++ b/deps/undici/src/lib/fetch/request.js @@ -232,14 +232,18 @@ class Request { } // 3. If one of the following is true - // parsedReferrer’s cannot-be-a-base-URL is true, scheme is "about", - // and path contains a single string "client" - // parsedReferrer’s origin is not same origin with origin + // - parsedReferrer’s scheme is "about" and path is the string "client" + // - parsedReferrer’s origin is not same origin with origin // then set request’s referrer to "client". - // TODO - - // 4. Otherwise, set request’s referrer to parsedReferrer. - request.referrer = parsedReferrer + if ( + (parsedReferrer.protocol === 'about:' && parsedReferrer.hostname === 'client') || + (origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) + ) { + request.referrer = 'client' + } else { + // 4. Otherwise, set request’s referrer to parsedReferrer. + request.referrer = parsedReferrer + } } } @@ -336,6 +340,8 @@ class Request { // 28. Set this’s signal to a new AbortSignal object with this’s relevant // Realm. + // TODO: could this be simplified with AbortSignal.any + // (https://dom.spec.whatwg.org/#dom-abortsignal-any) const ac = new AbortController() this[kSignal] = ac.signal this[kSignal][kRealm] = this[kRealm] @@ -381,7 +387,7 @@ class Request { } } catch {} - signal.addEventListener('abort', abort, { once: true }) + util.addAbortListener(signal, abort) requestFinalizer.register(ac, { signal, abort }) } } @@ -729,12 +735,11 @@ class Request { if (this.signal.aborted) { ac.abort(this.signal.reason) } else { - this.signal.addEventListener( - 'abort', + util.addAbortListener( + this.signal, () => { ac.abort(this.signal.reason) - }, - { once: true } + } ) } clonedRequestObject[kSignal] = ac.signal diff --git a/deps/undici/src/lib/fetch/response.js b/deps/undici/src/lib/fetch/response.js index 1029dbef53371f..88deb71a06285e 100644 --- a/deps/undici/src/lib/fetch/response.js +++ b/deps/undici/src/lib/fetch/response.js @@ -49,7 +49,7 @@ class Response { } // https://fetch.spec.whatwg.org/#dom-response-json - static json (data = undefined, init = {}) { + static json (data, init = {}) { webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' }) if (init !== null) { @@ -426,15 +426,15 @@ function filterResponse (response, type) { } // https://fetch.spec.whatwg.org/#appropriate-network-error -function makeAppropriateNetworkError (fetchParams) { +function makeAppropriateNetworkError (fetchParams, err = null) { // 1. Assert: fetchParams is canceled. assert(isCancelled(fetchParams)) // 2. Return an aborted network error if fetchParams is aborted; // otherwise return a network error. return isAborted(fetchParams) - ? makeNetworkError(new DOMException('The operation was aborted.', 'AbortError')) - : makeNetworkError('Request was cancelled.') + ? makeNetworkError(Object.assign(new DOMException('The operation was aborted.', 'AbortError'), { cause: err })) + : makeNetworkError(Object.assign(new DOMException('Request was cancelled.'), { cause: err })) } // https://whatpr.org/fetch/1392.html#initialize-a-response diff --git a/deps/undici/src/lib/fetch/util.js b/deps/undici/src/lib/fetch/util.js index 400687ba2e7d23..fcbba84bc9a8b0 100644 --- a/deps/undici/src/lib/fetch/util.js +++ b/deps/undici/src/lib/fetch/util.js @@ -556,16 +556,37 @@ function bytesMatch (bytes, metadataList) { const algorithm = item.algo // 2. Let expectedValue be the val component of item. - const expectedValue = item.hash + let expectedValue = item.hash + + // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e + // "be liberal with padding". This is annoying, and it's not even in the spec. + + if (expectedValue.endsWith('==')) { + expectedValue = expectedValue.slice(0, -2) + } // 3. Let actualValue be the result of applying algorithm to bytes. - const actualValue = crypto.createHash(algorithm).update(bytes).digest('base64') + let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64') + + if (actualValue.endsWith('==')) { + actualValue = actualValue.slice(0, -2) + } // 4. If actualValue is a case-sensitive match for expectedValue, // return true. if (actualValue === expectedValue) { return true } + + let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url') + + if (actualBase64URL.endsWith('==')) { + actualBase64URL = actualBase64URL.slice(0, -2) + } + + if (actualBase64URL === expectedValue) { + return true + } } // 6. Return false. @@ -812,17 +833,17 @@ function iteratorResult (pair, kind) { /** * @see https://fetch.spec.whatwg.org/#body-fully-read */ -function fullyReadBody (body, processBody, processBodyError) { +async function fullyReadBody (body, processBody, processBodyError) { // 1. If taskDestination is null, then set taskDestination to // the result of starting a new parallel queue. // 2. Let successSteps given a byte sequence bytes be to queue a // fetch task to run processBody given bytes, with taskDestination. - const successSteps = (bytes) => queueMicrotask(() => processBody(bytes)) + const successSteps = processBody // 3. Let errorSteps be to queue a fetch task to run processBodyError, // with taskDestination. - const errorSteps = (error) => queueMicrotask(() => processBodyError(error)) + const errorSteps = processBodyError // 4. Let reader be the result of getting a reader for body’s stream. // If that threw an exception, then run errorSteps with that @@ -837,7 +858,12 @@ function fullyReadBody (body, processBody, processBodyError) { } // 5. Read all bytes from reader, given successSteps and errorSteps. - readAllBytes(reader, successSteps, errorSteps) + try { + const result = await readAllBytes(reader) + successSteps(result) + } catch (e) { + errorSteps(e) + } } /** @type {ReadableStream} */ @@ -906,36 +932,23 @@ function isomorphicEncode (input) { * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes * @see https://streams.spec.whatwg.org/#read-loop * @param {ReadableStreamDefaultReader} reader - * @param {(bytes: Uint8Array) => void} successSteps - * @param {(error: Error) => void} failureSteps */ -async function readAllBytes (reader, successSteps, failureSteps) { +async function readAllBytes (reader) { const bytes = [] let byteLength = 0 while (true) { - let done - let chunk - - try { - ({ done, value: chunk } = await reader.read()) - } catch (e) { - // 1. Call failureSteps with e. - failureSteps(e) - return - } + const { done, value: chunk } = await reader.read() if (done) { // 1. Call successSteps with bytes. - successSteps(Buffer.concat(bytes, byteLength)) - return + return Buffer.concat(bytes, byteLength) } // 1. If chunk is not a Uint8Array object, call failureSteps // with a TypeError and abort these steps. if (!isUint8Array(chunk)) { - failureSteps(new TypeError('Received non-Uint8Array chunk')) - return + throw new TypeError('Received non-Uint8Array chunk') } // 2. Append the bytes represented by chunk to bytes. diff --git a/deps/undici/src/lib/llhttp/llhttp-wasm.js b/deps/undici/src/lib/llhttp/llhttp-wasm.js index e176ce2cf51579..ad4682c364de63 100644 --- a/deps/undici/src/lib/llhttp/llhttp-wasm.js +++ b/deps/undici/src/lib/llhttp/llhttp-wasm.js @@ -1 +1 @@ -module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAAMBBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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EGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvc9wEDKH8DfgV/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8gASEQIAEhESABIRIgASETIAEhFCABIRUgASEWIAEhFyABIRggASEZIAEhGiABIRsgASEcIAEhHSABIR4gASEfIAEhICABISEgASEiIAEhIyABISQgASElIAEhJiABIScgASEoIAEhKQJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIipBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4B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AQtBwQEhKgsDQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJA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UGoON+cB5gEBAgMEBQYHCAAAAAAAAAAJCgsMDQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8QERITFAALQR4hKgzEAwtCAiErDOUBC0IDISsM5AELQgQhKwzjAQtCBSErDOIBC0IGISsM4QELQgchKwzgAQtCCCErDN8BC0IJISsM3gELQgohKwzdAQtCCyErDNwBC0IMISsM2wELQg0hKwzaAQtCDiErDNkBC0IPISsM2AELQgohKwzXAQtCCyErDNYBC0IMISsM1QELQg0hKwzUAQtCDiErDNMBC0IPISsM0gELQgAhKwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgKi0AAEFQag435QHkAQABAgMEBQYH5gHmAeYB5gHmAeYB5gEICQoLDA3mAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYBDg8QERIT5gELQgIhKwzkAQtCAyErDOMBC0IEISsM4gELQgUhKwzhAQtCBiErDOABC0IHISsM3wELQgghKwzeAQtCCSErDN0BC0IKISsM3AELQgshKwzbAQtCDCErDNoBC0INISsM2QELQg4hKwzYAQtCDyErDNcBC0IKISsM1gELQgshKwzVAQtCDCErDNQBC0INISsM0wELQg4hKwzSAQtCDyErDNEBCyAAQgAgACkDICIrIAIgASIqa60iLH0iLSAtICtWGzcDICArICxWIi5FDdIBQR8hKgzHAwsCQCABIgEgAkYNACAAQYmAgIAANgIIIAAgATYCBCABIQFBJCEqDK4DC0EgISoMxgMLIAAgASIqIAIQvoCAgABBf2oOBbYBAMsCAdEB0gELQREhKgyrAwsgAEEBOgAvICohAQzCAwsgASIBIAJHDdIBQSQhKgzCAwsgASInIAJHDR5BxgAhKgzBAwsgACABIgEgAhCygICAACIqDdQBIAEhAQy1AQsgASIqIAJHDSZB0AAhKgy/AwsCQCABIgEgAkcNAEEoISoMvwMLIABBADYCBCAAQYyAgIAANgIIIAAgASABELGAgIAAIioN0wEgASEBDNgBCwJAIAEiKiACRw0AQSkhKgy+AwsgKi0AACIBQSBGDRQgAUEJRw3TASAqQQFqIQEMFQsCQCABIgEgAkYNACABQQFqIQEMFwtBKiEqDLwDCwJAIAEiKiACRw0AQSshKgy8AwsCQCAqLQAAIgFBCUYNACABQSBHDdUBCyAALQAsQQhGDdMBICohAQyWAwsCQCABIgEgAkcNAEEsISoMuwMLIAEtAABBCkcN1QEgAUEBaiEBDM8CCyABIiggAkcN1QFBLyEqDLkDCwNAAkAgAS0AACIqQSBGDQACQCAqQXZqDgQA3AHcAQDaAQsgASEBDOIBCyABQQFqIgEgAkcNAAtBMSEqDLgDC0EyISogASIvIAJGDbcDIAIgL2sgACgCACIwaiExIC8hMiAwIQECQANAIDItAAAiLkEgciAuIC5Bv39qQf8BcUEaSRtB/wFxIAFB8LuAgABqLQAARw0BIAFBA0YNmwMgAUEBaiEBIDJBAWoiMiACRw0ACyAAIDE2AgAMuAMLIABBADYCACAyIQEM2QELQTMhKiABIi8gAkYNtgMgAiAvayAAKAIAIjBqITEgLyEyIDAhAQJAA0AgMi0AACIuQSByIC4gLkG/f2pB/wFxQRpJG0H/AXEgAUH0u4CAAGotAABHDQEgAUEIRg3bASABQQFqIQEgMkEBaiIyIAJHDQALIAAgMTYCAAy3AwsgAEEANgIAIDIhAQzYAQtBNCEqIAEiLyACRg21AyACIC9rIAAoAgAiMGohMSAvITIgMCEBAkADQCAyLQAAIi5BIHIgLiAuQb9/akH/AXFBGkkbQf8BcSABQdDCgIAAai0AAEcNASABQQVGDdsBIAFBAWohASAyQQFqIjIgAkcNAAsgACAxNgIADLYDCyAAQQA2AgAgMiEBDNcBCwJAIAEiASACRg0AA0ACQCABLQAAQYC+gIAAai0AACIqQQFGDQAgKkECRg0KIAEhAQzfAQsgAUEBaiIBIAJHDQALQTAhKgy1AwtBMCEqDLQDCwJAIAEiASACRg0AA0ACQCABLQAAIipBIEYNACAqQXZqDgTbAdwB3AHbAdwBCyABQQFqIgEgAkcNAAtBOCEqDLQDC0E4ISoMswMLA0ACQCABLQAAIipBIEYNACAqQQlHDQMLIAFBAWoiASACRw0AC0E8ISoMsgMLA0ACQCABLQAAIipBIEYNAAJAAkAgKkF2ag4E3AEBAdwBAAsgKkEsRg3dAQsgASEBDAQLIAFBAWoiASACRw0AC0E/ISoMsQMLIAEhAQzdAQtBwAAhKiABIjIgAkYNrwMgAiAyayAAKAIAIi9qITAgMiEuIC8hAQJAA0AgLi0AAEEgciABQYDAgIAAai0AAEcNASABQQZGDZUDIAFBAWohASAuQQFqIi4gAkcNAAsgACAwNgIADLADCyAAQQA2AgAgLiEBC0E2ISoMlQMLAkAgASIpIAJHDQBBwQAhKgyuAwsgAEGMgICAADYCCCAAICk2AgQgKSEBIAAtACxBf2oOBM0B1wHZAdsBjAMLIAFBAWohAQzMAQsCQCABIgEgAkYNAANAAkAgAS0AACIqQSByICogKkG/f2pB/wFxQRpJG0H/AXEiKkEJRg0AICpBIEYNAAJAAkACQAJAICpBnX9qDhMAAwMDAwMDAwEDAwMDAwMDAwMCAwsgAUEBaiEBQTEhKgyYAwsgAUEBaiEBQTIhKgyXAwsgAUEBaiEBQTMhKgyWAwsgASEBDNABCyABQQFqIgEgAkcNAAtBNSEqDKwDC0E1ISoMqwMLAkAgASIBIAJGDQADQAJAIAEtAABBgLyAgABqLQAAQQFGDQAgASEBDNUBCyABQQFqIgEgAkcNAAtBPSEqDKsDC0E9ISoMqgMLIAAgASIBIAIQsICAgAAiKg3YASABIQEMAQsgKkEBaiEBC0E8ISoMjgMLAkAgASIBIAJHDQBBwgAhKgynAwsCQANAAkAgAS0AAEF3ag4YAAKDA4MDiQODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwODA4MDgwMAgwMLIAFBAWoiASACRw0AC0HCACEqDKcDCyABQQFqIQEgAC0ALUEBcUUNvQEgASEBC0EsISoMjAMLIAEiASACRw3VAUHEACEqDKQDCwNAAkAgAS0AAEGQwICAAGotAABBAUYNACABIQEMvQILIAFBAWoiASACRw0AC0HFACEqDKMDCyAnLQAAIipBIEYNswEgKkE6Rw2IAyAAKAIEIQEgAEEANgIEIAAgASAnEK+AgIAAIgEN0gEgJ0EBaiEBDLkCC0HHACEqIAEiMiACRg2hAyACIDJrIAAoAgAiL2ohMCAyIScgLyEBAkADQCAnLQAAIi5BIHIgLiAuQb9/akH/AXFBGkkbQf8BcSABQZDCgIAAai0AAEcNiAMgAUEFRg0BIAFBAWohASAnQQFqIicgAkcNAAsgACAwNgIADKIDCyAAQQA2AgAgAEEBOgAsIDIgL2tBBmohAQyCAwtByAAhKiABIjIgAkYNoAMgAiAyayAAKAIAIi9qITAgMiEnIC8hAQJAA0AgJy0AACIuQSByIC4gLkG/f2pB/wFxQRpJG0H/AXEgAUGWwoCAAGotAABHDYcDIAFBCUYNASABQQFqIQEgJ0EBaiInIAJHDQALIAAgMDYCAAyhAwsgAEEANgIAIABBAjoALCAyIC9rQQpqIQEMgQMLAkAgASInIAJHDQBByQAhKgygAwsCQAJAICctAAAiAUEgciABIAFBv39qQf8BcUEaSRtB/wFxQZJ/ag4HAIcDhwOHA4cDhwMBhwMLICdBAWohAUE+ISoMhwMLICdBAWohAUE/ISoMhgMLQcoAISogASIyIAJGDZ4DIAIgMmsgACgCACIvaiEwIDIhJyAvIQEDQCAnLQAAIi5BIHIgLiAuQb9/akH/AXFBGkkbQf8BcSABQaDCgIAAai0AAEcNhAMgAUEBRg34AiABQQFqIQEgJ0EBaiInIAJHDQALIAAgMDYCAAyeAwtBywAhKiABIjIgAkYNnQMgAiAyayAAKAIAIi9qITAgMiEnIC8hAQJAA0AgJy0AACIuQSByIC4gLkG/f2pB/wFxQRpJG0H/AXEgAUGiwoCAAGotAABHDYQDIAFBDkYNASABQQFqIQEgJ0EBaiInIAJHDQALIAAgMDYCAAyeAwsgAEEANgIAIABBAToALCAyIC9rQQ9qIQEM/gILQcwAISogASIyIAJGDZwDIAIgMmsgACgCACIvaiEwIDIhJyAvIQECQANAICctAAAiLkEgciAuIC5Bv39qQf8BcUEaSRtB/wFxIAFBwMKAgABqLQAARw2DAyABQQ9GDQEgAUEBaiEBICdBAWoiJyACRw0ACyAAIDA2AgAMnQMLIABBADYCACAAQQM6ACwgMiAva0EQaiEBDP0CC0HNACEqIAEiMiACRg2bAyACIDJrIAAoAgAiL2ohMCAyIScgLyEBAkADQCAnLQAAIi5BIHIgLiAuQb9/akH/AXFBGkkbQf8BcSABQdDCgIAAai0AAEcNggMgAUEFRg0BIAFBAWohASAnQQFqIicgAkcNAAsgACAwNgIADJwDCyAAQQA2AgAgAEEEOgAsIDIgL2tBBmohAQz8AgsCQCABIicgAkcNAEHOACEqDJsDCwJAAkACQAJAICctAAAiAUEgciABIAFBv39qQf8BcUEaSRtB/wFxQZ1/ag4TAIQDhAOEA4QDhAOEA4QDhAOEA4QDhAOEAwGEA4QDhAMCA4QDCyAnQQFqIQFBwQAhKgyEAwsgJ0EBaiEBQcIAISoMgwMLICdBAWohAUHDACEqDIIDCyAnQQFqIQFBxAAhKgyBAwsCQCABIgEgAkYNACAAQY2AgIAANgIIIAAgATYCBCABIQFBxQAhKgyBAwtBzwAhKgyZAwsgKiEBAkACQCAqLQAAQXZqDgQBrgKuAgCuAgsgKkEBaiEBC0EnISoM/wILAkAgASIBIAJHDQBB0QAhKgyYAwsCQCABLQAAQSBGDQAgASEBDI0BCyABQQFqIQEgAC0ALUEBcUUNyQEgASEBDIwBCyABIgEgAkcNyQFB0gAhKgyWAwtB0wAhKiABIjIgAkYNlQMgAiAyayAAKAIAIi9qITAgMiEuIC8hAQJAA0AgLi0AACABQdbCgIAAai0AAEcNzwEgAUEBRg0BIAFBAWohASAuQQFqIi4gAkcNAAsgACAwNgIADJYDCyAAQQA2AgAgMiAva0ECaiEBDMkBCwJAIAEiASACRw0AQdUAISoMlQMLIAEtAABBCkcNzgEgAUEBaiEBDMkBCwJAIAEiASACRw0AQdYAISoMlAMLAkACQCABLQAAQXZqDgQAzwHPAQHPAQsgAUEBaiEBDMkBCyABQQFqIQFBygAhKgz6AgsgACABIgEgAhCugICAACIqDc0BIAEhAUHNACEqDPkCCyAALQApQSJGDYwDDKwCCwJAIAEiASACRw0AQdsAISoMkQMLQQAhLkEBITJBASEvQQAhKgJAAkACQAJAAkACQAJAAkACQCABLQAAQVBqDgrWAdUBAAECAwQFBgjXAQtBAiEqDAYLQQMhKgwFC0EEISoMBAtBBSEqDAMLQQYhKgwCC0EHISoMAQtBCCEqC0EAITJBACEvQQAhLgzOAQtBCSEqQQEhLkEAITJBACEvDM0BCwJAIAEiASACRw0AQd0AISoMkAMLIAEtAABBLkcNzgEgAUEBaiEBDKwCCwJAIAEiASACRw0AQd8AISoMjwMLQQAhKgJAAkACQAJAAkACQAJAAkAgAS0AAEFQag4K1wHWAQABAgMEBQYH2AELQQIhKgzWAQtBAyEqDNUBC0EEISoM1AELQQUhKgzTAQtBBiEqDNIBC0EHISoM0QELQQghKgzQAQtBCSEqDM8BCwJAIAEiASACRg0AIABBjoCAgAA2AgggACABNgIEIAEhAUHQACEqDPUCC0HgACEqDI0DC0HhACEqIAEiMiACRg2MAyACIDJrIAAoAgAiL2ohMCAyIQEgLyEuA0AgAS0AACAuQeLCgIAAai0AAEcN0QEgLkEDRg3QASAuQQFqIS4gAUEBaiIBIAJHDQALIAAgMDYCAAyMAwtB4gAhKiABIjIgAkYNiwMgAiAyayAAKAIAIi9qITAgMiEBIC8hLgNAIAEtAAAgLkHmwoCAAGotAABHDdABIC5BAkYN0gEgLkEBaiEuIAFBAWoiASACRw0ACyAAIDA2AgAMiwMLQeMAISogASIyIAJGDYoDIAIgMmsgACgCACIvaiEwIDIhASAvIS4DQCABLQAAIC5B6cKAgABqLQAARw3PASAuQQNGDdIBIC5BAWohLiABQQFqIgEgAkcNAAsgACAwNgIADIoDCwJAIAEiASACRw0AQeUAISoMigMLIAAgAUEBaiIBIAIQqICAgAAiKg3RASABIQFB1gAhKgzwAgsCQCABIgEgAkYNAANAAkAgAS0AACIqQSBGDQACQAJAAkAgKkG4f2oOCwAB0wHTAdMB0wHTAdMB0wHTAQLTAQsgAUEBaiEBQdIAISoM9AILIAFBAWohAUHTACEqDPMCCyABQQFqIQFB1AAhKgzyAgsgAUEBaiIBIAJHDQALQeQAISoMiQMLQeQAISoMiAMLA0ACQCABLQAAQfDCgIAAai0AACIqQQFGDQAgKkF+ag4D0wHUAdUB1gELIAFBAWoiASACRw0AC0HmACEqDIcDCwJAIAEiASACRg0AIAFBAWohAQwDC0HnACEqDIYDCwNAAkAgAS0AAEHwxICAAGotAAAiKkEBRg0AAkAgKkF+ag4E1gHXAdgBANkBCyABIQFB1wAhKgzuAgsgAUEBaiIBIAJHDQALQegAISoMhQMLAkAgASIBIAJHDQBB6QAhKgyFAwsCQCABLQAAIipBdmoOGrwB2QHZAb4B2QHZAdkB2QHZAdkB2QHZAdkB2QHZAdkB2QHZAdkB2QHZAdkBzgHZAdkBANcBCyABQQFqIQELQQYhKgzqAgsDQAJAIAEtAABB8MaAgABqLQAAQQFGDQAgASEBDKUCCyABQQFqIgEgAkcNAAtB6gAhKgyCAwsCQCABIgEgAkYNACABQQFqIQEMAwtB6wAhKgyBAwsCQCABIgEgAkcNAEHsACEqDIEDCyABQQFqIQEMAQsCQCABIgEgAkcNAEHtACEqDIADCyABQQFqIQELQQQhKgzlAgsCQCABIi4gAkcNAEHuACEqDP4CCyAuIQECQAJAAkAgLi0AAEHwyICAAGotAABBf2oOB9gB2QHaAQCjAgEC2wELIC5BAWohAQwKCyAuQQFqIQEM0QELQQAhKiAAQQA2AhwgAEGbkoCAADYCECAAQQc2AgwgACAuQQFqNgIUDP0CCwJAA0ACQCABLQAAQfDIgIAAai0AACIqQQRGDQACQAJAICpBf2oOB9YB1wHYAd0BAAQB3QELIAEhAUHaACEqDOcCCyABQQFqIQFB3AAhKgzmAgsgAUEBaiIBIAJHDQALQe8AISoM/QILIAFBAWohAQzPAQsCQCABIi4gAkcNAEHwACEqDPwCCyAuLQAAQS9HDdgBIC5BAWohAQwGCwJAIAEiLiACRw0AQfEAISoM+wILAkAgLi0AACIBQS9HDQAgLkEBaiEBQd0AISoM4gILIAFBdmoiAUEWSw3XAUEBIAF0QYmAgAJxRQ3XAQzSAgsCQCABIgEgAkYNACABQQFqIQFB3gAhKgzhAgtB8gAhKgz5AgsCQCABIi4gAkcNAEH0ACEqDPkCCyAuIQECQCAuLQAAQfDMgIAAai0AAEF/ag4D0QKbAgDYAQtB4QAhKgzfAgsCQCABIi4gAkYNAANAAkAgLi0AAEHwyoCAAGotAAAiAUEDRg0AAkAgAUF/ag4C0wIA2QELIC4hAUHfACEqDOECCyAuQQFqIi4gAkcNAAtB8wAhKgz4AgtB8wAhKgz3AgsCQCABIgEgAkYNACAAQY+AgIAANgIIIAAgATYCBCABIQFB4AAhKgzeAgtB9QAhKgz2AgsCQCABIgEgAkcNAEH2ACEqDPYCCyAAQY+AgIAANgIIIAAgATYCBCABIQELQQMhKgzbAgsDQCABLQAAQSBHDcsCIAFBAWoiASACRw0AC0H3ACEqDPMCCwJAIAEiASACRw0AQfgAISoM8wILIAEtAABBIEcN0gEgAUEBaiEBDPUBCyAAIAEiASACEKyAgIAAIioN0gEgASEBDJUCCwJAIAEiBCACRw0AQfoAISoM8QILIAQtAABBzABHDdUBIARBAWohAUETISoM0wELAkAgASIqIAJHDQBB+wAhKgzwAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQNAIAQtAAAgAUHwzoCAAGotAABHDdQBIAFBBUYN0gEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBB+wAhKgzvAgsCQCABIgQgAkcNAEH8ACEqDO8CCwJAAkAgBC0AAEG9f2oODADVAdUB1QHVAdUB1QHVAdUB1QHVAQHVAQsgBEEBaiEBQeYAISoM1gILIARBAWohAUHnACEqDNUCCwJAIAEiKiACRw0AQf0AISoM7gILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUHtz4CAAGotAABHDdMBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEH9ACEqDO4CCyAAQQA2AgAgKiAua0EDaiEBQRAhKgzQAQsCQCABIiogAkcNAEH+ACEqDO0CCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFB9s6AgABqLQAARw3SASABQQVGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBB/gAhKgztAgsgAEEANgIAICogLmtBBmohAUEWISoMzwELAkAgASIqIAJHDQBB/wAhKgzsAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQfzOgIAAai0AAEcN0QEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQf8AISoM7AILIABBADYCACAqIC5rQQRqIQFBBSEqDM4BCwJAIAEiBCACRw0AQYABISoM6wILIAQtAABB2QBHDc8BIARBAWohAUEIISoMzQELAkAgASIEIAJHDQBBgQEhKgzqAgsCQAJAIAQtAABBsn9qDgMA0AEB0AELIARBAWohAUHrACEqDNECCyAEQQFqIQFB7AAhKgzQAgsCQCABIgQgAkcNAEGCASEqDOkCCwJAAkAgBC0AAEG4f2oOCADPAc8BzwHPAc8BzwEBzwELIARBAWohAUHqACEqDNACCyAEQQFqIQFB7QAhKgzPAgsCQCABIi4gAkcNAEGDASEqDOgCCyACIC5rIAAoAgAiMmohKiAuIQQgMiEBAkADQCAELQAAIAFBgM+AgABqLQAARw3NASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAICo2AgBBgwEhKgzoAgtBACEqIABBADYCACAuIDJrQQNqIQEMygELAkAgASIqIAJHDQBBhAEhKgznAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQYPPgIAAai0AAEcNzAEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQYQBISoM5wILIABBADYCACAqIC5rQQVqIQFBIyEqDMkBCwJAIAEiBCACRw0AQYUBISoM5gILAkACQCAELQAAQbR/ag4IAMwBzAHMAcwBzAHMAQHMAQsgBEEBaiEBQe8AISoMzQILIARBAWohAUHwACEqDMwCCwJAIAEiBCACRw0AQYYBISoM5QILIAQtAABBxQBHDckBIARBAWohAQyKAgsCQCABIiogAkcNAEGHASEqDOQCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBiM+AgABqLQAARw3JASABQQNGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBhwEhKgzkAgsgAEEANgIAICogLmtBBGohAUEtISoMxgELAkAgASIqIAJHDQBBiAEhKgzjAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQdDPgIAAai0AAEcNyAEgAUEIRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQYgBISoM4wILIABBADYCACAqIC5rQQlqIQFBKSEqDMUBCwJAIAEiASACRw0AQYkBISoM4gILQQEhKiABLQAAQd8ARw3EASABQQFqIQEMiAILAkAgASIqIAJHDQBBigEhKgzhAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQNAIAQtAAAgAUGMz4CAAGotAABHDcUBIAFBAUYNtwIgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBigEhKgzgAgsCQCABIiogAkcNAEGLASEqDOACCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBjs+AgABqLQAARw3FASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBiwEhKgzgAgsgAEEANgIAICogLmtBA2ohAUECISoMwgELAkAgASIqIAJHDQBBjAEhKgzfAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQfDPgIAAai0AAEcNxAEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQYwBISoM3wILIABBADYCACAqIC5rQQJqIQFBHyEqDMEBCwJAIAEiKiACRw0AQY0BISoM3gILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUHyz4CAAGotAABHDcMBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGNASEqDN4CCyAAQQA2AgAgKiAua0ECaiEBQQkhKgzAAQsCQCABIgQgAkcNAEGOASEqDN0CCwJAAkAgBC0AAEG3f2oOBwDDAcMBwwHDAcMBAcMBCyAEQQFqIQFB+AAhKgzEAgsgBEEBaiEBQfkAISoMwwILAkAgASIqIAJHDQBBjwEhKgzcAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQZHPgIAAai0AAEcNwQEgAUEFRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQY8BISoM3AILIABBADYCACAqIC5rQQZqIQFBGCEqDL4BCwJAIAEiKiACRw0AQZABISoM2wILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUGXz4CAAGotAABHDcABIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGQASEqDNsCCyAAQQA2AgAgKiAua0EDaiEBQRchKgy9AQsCQCABIiogAkcNAEGRASEqDNoCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBms+AgABqLQAARw2/ASABQQZGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBkQEhKgzaAgsgAEEANgIAICogLmtBB2ohAUEVISoMvAELAkAgASIqIAJHDQBBkgEhKgzZAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQaHPgIAAai0AAEcNvgEgAUEFRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQZIBISoM2QILIABBADYCACAqIC5rQQZqIQFBHiEqDLsBCwJAIAEiBCACRw0AQZMBISoM2AILIAQtAABBzABHDbwBIARBAWohAUEKISoMugELAkAgBCACRw0AQZQBISoM1wILAkACQCAELQAAQb9/ag4PAL0BvQG9Ab0BvQG9Ab0BvQG9Ab0BvQG9Ab0BAb0BCyAEQQFqIQFB/gAhKgy+AgsgBEEBaiEBQf8AISoMvQILAkAgBCACRw0AQZUBISoM1gILAkACQCAELQAAQb9/ag4DALwBAbwBCyAEQQFqIQFB/QAhKgy9AgsgBEEBaiEEQYABISoMvAILAkAgBSACRw0AQZYBISoM1QILIAIgBWsgACgCACIqaiEuIAUhBCAqIQECQANAIAQtAAAgAUGnz4CAAGotAABHDboBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGWASEqDNUCCyAAQQA2AgAgBSAqa0ECaiEBQQshKgy3AQsCQCAEIAJHDQBBlwEhKgzUAgsCQAJAAkACQCAELQAAQVNqDiMAvAG8AbwBvAG8AbwBvAG8AbwBvAG8AbwBvAG8AbwBvAG8AbwBvAG8AbwBvAG8AQG8AbwBvAG8AbwBArwBvAG8AQO8AQsgBEEBaiEBQfsAISoMvQILIARBAWohAUH8ACEqDLwCCyAEQQFqIQRBgQEhKgy7AgsgBEEBaiEFQYIBISoMugILAkAgBiACRw0AQZgBISoM0wILIAIgBmsgACgCACIqaiEuIAYhBCAqIQECQANAIAQtAAAgAUGpz4CAAGotAABHDbgBIAFBBEYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGYASEqDNMCCyAAQQA2AgAgBiAqa0EFaiEBQRkhKgy1AQsCQCAHIAJHDQBBmQEhKgzSAgsgAiAHayAAKAIAIi5qISogByEEIC4hAQJAA0AgBC0AACABQa7PgIAAai0AAEcNtwEgAUEFRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAqNgIAQZkBISoM0gILIABBADYCAEEGISogByAua0EGaiEBDLQBCwJAIAggAkcNAEGaASEqDNECCyACIAhrIAAoAgAiKmohLiAIIQQgKiEBAkADQCAELQAAIAFBtM+AgABqLQAARw22ASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBmgEhKgzRAgsgAEEANgIAIAggKmtBAmohAUEcISoMswELAkAgCSACRw0AQZsBISoM0AILIAIgCWsgACgCACIqaiEuIAkhBCAqIQECQANAIAQtAAAgAUG2z4CAAGotAABHDbUBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGbASEqDNACCyAAQQA2AgAgCSAqa0ECaiEBQSchKgyyAQsCQCAEIAJHDQBBnAEhKgzPAgsCQAJAIAQtAABBrH9qDgIAAbUBCyAEQQFqIQhBhgEhKgy2AgsgBEEBaiEJQYcBISoMtQILAkAgCiACRw0AQZ0BISoMzgILIAIgCmsgACgCACIqaiEuIAohBCAqIQECQANAIAQtAAAgAUG4z4CAAGotAABHDbMBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGdASEqDM4CCyAAQQA2AgAgCiAqa0ECaiEBQSYhKgywAQsCQCALIAJHDQBBngEhKgzNAgsgAiALayAAKAIAIipqIS4gCyEEICohAQJAA0AgBC0AACABQbrPgIAAai0AAEcNsgEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQZ4BISoMzQILIABBADYCACALICprQQJqIQFBAyEqDK8BCwJAIAwgAkcNAEGfASEqDMwCCyACIAxrIAAoAgAiKmohLiAMIQQgKiEBAkADQCAELQAAIAFB7c+AgABqLQAARw2xASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBnwEhKgzMAgsgAEEANgIAIAwgKmtBA2ohAUEMISoMrgELAkAgDSACRw0AQaABISoMywILIAIgDWsgACgCACIqaiEuIA0hBCAqIQECQANAIAQtAAAgAUG8z4CAAGotAABHDbABIAFBA0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGgASEqDMsCCyAAQQA2AgAgDSAqa0EEaiEBQQ0hKgytAQsCQCAEIAJHDQBBoQEhKgzKAgsCQAJAIAQtAABBun9qDgsAsAGwAbABsAGwAbABsAGwAbABAbABCyAEQQFqIQxBiwEhKgyxAgsgBEEBaiENQYwBISoMsAILAkAgBCACRw0AQaIBISoMyQILIAQtAABB0ABHDa0BIARBAWohBAzwAQsCQCAEIAJHDQBBowEhKgzIAgsCQAJAIAQtAABBt39qDgcBrgGuAa4BrgGuAQCuAQsgBEEBaiEEQY4BISoMrwILIARBAWohAUEiISoMqgELAkAgDiACRw0AQaQBISoMxwILIAIgDmsgACgCACIqaiEuIA4hBCAqIQECQANAIAQtAAAgAUHAz4CAAGotAABHDawBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGkASEqDMcCCyAAQQA2AgAgDiAqa0ECaiEBQR0hKgypAQsCQCAEIAJHDQBBpQEhKgzGAgsCQAJAIAQtAABBrn9qDgMArAEBrAELIARBAWohDkGQASEqDK0CCyAEQQFqIQFBBCEqDKgBCwJAIAQgAkcNAEGmASEqDMUCCwJAAkACQAJAAkAgBC0AAEG/f2oOFQCuAa4BrgGuAa4BrgGuAa4BrgGuAQGuAa4BAq4BrgEDrgGuAQSuAQsgBEEBaiEEQYgBISoMrwILIARBAWohCkGJASEqDK4CCyAEQQFqIQtBigEhKgytAgsgBEEBaiEEQY8BISoMrAILIARBAWohBEGRASEqDKsCCwJAIA8gAkcNAEGnASEqDMQCCyACIA9rIAAoAgAiKmohLiAPIQQgKiEBAkADQCAELQAAIAFB7c+AgABqLQAARw2pASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBpwEhKgzEAgsgAEEANgIAIA8gKmtBA2ohAUERISoMpgELAkAgECACRw0AQagBISoMwwILIAIgEGsgACgCACIqaiEuIBAhBCAqIQECQANAIAQtAAAgAUHCz4CAAGotAABHDagBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGoASEqDMMCCyAAQQA2AgAgECAqa0EDaiEBQSwhKgylAQsCQCARIAJHDQBBqQEhKgzCAgsgAiARayAAKAIAIipqIS4gESEEICohAQJAA0AgBC0AACABQcXPgIAAai0AAEcNpwEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQakBISoMwgILIABBADYCACARICprQQVqIQFBKyEqDKQBCwJAIBIgAkcNAEGqASEqDMECCyACIBJrIAAoAgAiKmohLiASIQQgKiEBAkADQCAELQAAIAFBys+AgABqLQAARw2mASABQQJGDQEgAUEBaiEB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8s+AgABqLQAARw2WASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBugEhKgyxAgsgAEEANgIAIBsgKmtBAmohAUEPISoMkwELAkAgBCACRw0AQbsBISoMsAILAkACQCAELQAAQbd/ag4HAJYBlgGWAZYBlgEBlgELIARBAWohGkGlASEqDJcCCyAEQQFqIRtBpgEhKgyWAgsCQCAcIAJHDQBBvAEhKgyvAgsgAiAcayAAKAIAIipqIS4gHCEEICohAQJAA0AgBC0AACABQfTPgIAAai0AAEcNlAEgAUEHRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbwBISoMrwILIABBADYCACAcICprQQhqIQFBGyEqDJEBCwJAIAQgAkcNAEG9ASEqDK4CCwJAAkACQCAELQAAQb5/ag4SAJUBlQGVAZUBlQGVAZUBlQGVAQGVAZUBlQGVAZUBlQEClQELIARBAWohGUGkASEqDJYCCyAEQQFqIQRBpwEhKgyVAgsgBEEBaiEcQagBISoMlAILAkAgBCACRw0AQb4BISoMrQILIAQtAABBzgBHDZEBIARBAWohBAzWAQsCQCAEIAJHDQBBvwEhKgysAgsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAELQAAQb9/ag4VAAECA6ABBAUGoAGgAaABBwgJCgugAQwNDg+gAQsgBEEBaiEBQegAISoMoQILIARBAWohAUHpACEqDKACCyAEQQFqIQFB7gAhKgyfAgsgBEEBaiEBQfIAISoMngILIARBAWohAUHzACEqDJ0CCyAEQQFqIQFB9gAhKgycAgsgBEEBaiEBQfcAISoMmwILIARBAWohAUH6ACEqDJoCCyAEQQFqIQRBgwEhKgyZAgsgBEEBaiEGQYQBISoMmAILIARBAWohB0GFASEqDJcCCyAEQQFqIQRBkgEhKgyWAgsgBEEBaiEEQZgBISoMlQILIARBAWohBEGgASEqDJQCCyAEQQFqIQRBowEhKgyTAgsgBEEBaiEEQaoBISoMkgILAkAgBCACRg0AIABBkICAgAA2AgggACAENgIEQasBISoMkgILQcABISoMqgILIAAgHSACEKqAgIAAIgENjwEgHSEBDF4LAkAgHiACRg0AIB5BAWohHQyRAQtBwgEhKgyoAgsD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NgIUIABB2o2AgAA2AhAgAEEUNgIMQQAhKgyNAgsgACgCBCEyIABBADYCBCAqICunaiIvIQEgACAyICogLyAuGyIqELWAgIAAIi5FDZMBIABBBzYCHCAAICo2AhQgACAuNgIMQQAhKgyMAgsgACAALwEwQYABcjsBMCABIQELQSohKgzxAQsgKkEVRg3ZASAAQQA2AhwgACABNgIUIABBg4yAgAA2AhAgAEETNgIMQQAhKgyJAgsgKkEVRg3XASAAQQA2AhwgACABNgIUIABBmo+AgAA2AhAgAEEiNgIMQQAhKgyIAgsgACgCBCEqIABBADYCBAJAIAAgKiABELeAgIAAIioNACABQQFqIQEMkwELIABBDDYCHCAAICo2AgwgACABQQFqNgIUQQAhKgyHAgsgKkEVRg3UASAAQQA2AhwgACABNgIUIABBmo+AgAA2AhAgAEEiNgIMQQAhKgyGAgsgACgCBCEqIABBADYCBAJAIAAgKiABELeAgIAAIioNACABQQFqIQEMkgELIABBDTYCHCAAICo2AgwgACABQQFqNgIUQQAhKgyFAgsgKkEVRg3RASAAQQA2AhwgACABNgIUIABBxoyAgAA2AhAgAEEjNgIMQQAhKgyEAgsgACgCBCEqIABBADYCBAJAIAAgKiABELmAgIAAIioNACABQQFqIQEMkQELIABBDjYCHCAAICo2AgwgACABQQFqNgIUQQAhKgyDAgsgAEEANgIcIAAgATYCFCAAQcCVgIAANgIQIABBAjYCDEEAISoMggILICpBFUYNzQEgAEEANgIcIAAgATYCFCAAQcaMgIAANgIQIABBIzYCDEEAISoMgQILIABBEDYCHCAAIAE2AhQgACAqNgIMQQAhKgyAAgsgACgCBCEEIABBADYCBAJAIAAgBCABELmAgIAAIgQNACABQQFqIQEM+AELIABBETYCHCAAIAQ2AgwgACABQQFqNgIUQQAhKgz/AQsgKkEVRg3JASAAQQA2AhwgACABNgIUIABBxoyAgAA2AhAgAEEjNgIMQQAhKgz+AQsgACgCBCEqIABBADYCBAJAIAAgKiABELmAgIAAIioNACABQQFqIQEMjgELIABBEzYCHCAAICo2AgwgACABQQFqNgIUQQAhKgz9AQsgACgCBCEEIABBADYCBAJAIAAgBCABELmAgIAAIgQNACAB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AkAgAC0AKUEjTw0AIAEhAQxcCyAAQQA2AhwgACABNgIUIABB04mAgAA2AhAgAEEINgIMQQAhKgy8AQsgAEEANgIAC0EAISogAEEANgIcIAAgATYCFCAAQZCzgIAANgIQIABBCDYCDAy6AQsgAEEANgIAIDIgL2tBA2ohAQJAIAAtAClBIUcNACABIQEMWQsgAEEANgIcIAAgATYCFCAAQZuKgIAANgIQIABBCDYCDEEAISoMuQELIABBADYCACAyIC9rQQRqIQECQCAALQApIipBXWpBC08NACABIQEMWAsCQCAqQQZLDQBBASAqdEHKAHFFDQAgASEBDFgLQQAhKiAAQQA2AhwgACABNgIUIABB94mAgAA2AhAgAEEINgIMDLgBCyAqQRVGDXUgAEEANgIcIAAgATYCFCAAQbmNgIAANgIQIABBGjYCDEEAISoMtwELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDFcLIABB5QA2AhwgACABNgIUIAAgKjYCDEEAISoMtgELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDE8LIABB0gA2AhwgACABNgIUIAAgKjYCDEEAISoMtQELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDE8LIABB0wA2AhwgACABNgIUIAAgKjYCDEEAISoMtAELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDFQLIABB5QA2AhwgACABNgIUIAAgKjYCDEEAISoMswELIABBADYCHCAAIAE2AhQgAEHGioCAADYCECAAQQc2AgxBACEqDLIBCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxLCyAAQdIANgIcIAAgATYCFCAAICo2AgxBACEqDLEBCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxLCyAAQdMANgIcIAAgATYCFCAAICo2AgxBACEqDLABCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxQCyAAQeUANgIcIAAgATYCFCAAICo2AgxBACEqDK8BCyAAQQA2AhwgACABNgIUIABB3IiAgAA2AhAgAEEHNgIMQQAhKgyuAQsgKkE/Rw0BIAFBAWohAQtBBSEqDJMBC0EAISogAEEANgIcIAAgATYCFCAAQf2SgIAANgIQIABBBzYCDAyrAQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMRAsgAEHSADYCHCAAIAE2AhQgACAqNgIMQQAhKgyqAQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMRAsgAEHTADYCHCAAIAE2AhQgACAqNgIMQQAhKgypAQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMSQsgAEHlADYCHCAAIAE2AhQgACAqNgIMQQAhKgyoAQsgACgCBCEBIABBADYCBAJAIAAgASAuEKeAgIAAIgENACAuIQEMQQsgAEHSADYCHCAAIC42AhQgACABNgIMQQAhKgynAQsgACgCBCEBIABBADYCBAJAIAAgASAuEKeAgIAAIgENACAuIQEMQQsgAEHTADYCHCAAIC42AhQgACABNgIMQQAhKgymAQsgACgCBCEBIABBADYCBAJAIAAgASAuEKeAgIAAIgENACAuIQEMRgsgAEHlADYCHCAAIC42AhQgACABNgIMQQAhKgylAQsgAEEANgIcIAAgLjYCFCAAQcOPgIAANgIQIABBBzYCDEEAISoMpAELIABBADYCHCAAIAE2AhQgAEHDj4CAADYCECAAQQc2AgxBACEqDKMBC0EAISogAEEANgIcIAAgLjYCFCAAQYycgIAANgIQIABBBzYCDAyiAQsgAEEANgIcIAAgLjYCFCAAQYycgIAANgIQIABBBzYCDEEAISoMoQELIABBADYCHCAAIC42AhQgAEH+kYCAADYCECAAQQc2AgxBACEqDKABCyAAQQA2AhwgACABNgIUIABBjpuAgAA2AhAgAEEGNgIMQQAhKgyfAQsgKkEVRg1bIABBADYCHCAAIAE2AhQgAEHMjoCAADYCECAAQSA2AgxBACEqDJ4BCyAAQQA2AgAgKiAua0EGaiEBQSQhKgsgACAqOgApIAAoAgQhKiAAQQA2AgQgACAqIAEQq4CAgAAiKg1YIAEhAQxBCyAAQQA2AgALQQAhKiAAQQA2AhwgACAENgIUIABB8ZuAgAA2AhAgAEEGNgIMDJoBCyABQRVGDVQgAEEANgIcIAAgHTYC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AgAgKiAua0ECaiEBQfUAISoMEAsgASEBAkAgAC0AKUEFRw0AQeMAISoMEAtB4gAhKgwPC0EAISogAEEANgIcIABB5JGAgAA2AhAgAEEHNgIMIAAgLkEBajYCFAwnCyAAQQA2AgAgMiAva0ECaiEBQcAAISoMDQsgASEBC0E4ISoMCwsCQCABIikgAkYNAANAAkAgKS0AAEGAvoCAAGotAAAiAUEBRg0AIAFBAkcNAyApQQFqIQEMBAsgKUEBaiIpIAJHDQALQT4hKgwkC0E+ISoMIwsgAEEAOgAsICkhAQwBC0ELISoMCAtBOiEqDAcLIAFBAWohAUEtISoMBgtBKCEqDAULIABBADYCACAvIDBrQQRqIQFBBiEqCyAAICo6ACwgASEBQQwhKgwDCyAAQQA2AgAgMiAva0EHaiEBQQohKgwCCyAAQQA2AgALIABBADoALCAnIQFBCSEqDAALC0EAISogAEEANgIcIAAgIzYCFCAAQc2QgIAANgIQIABBCTYCDAwXC0EAISogAEEANgIcIAAgIjYCFCAAQemKgIAANgIQIABBCTYCDAwWC0EAISogAEEANgIcIAAgITYCFCAAQbeQgIAANgIQIABBCTYCDAwVC0EAISogAEEANgIcIAAgIDYCFCAAQZyRgIAANgIQIABBCTYCDAwUC0EAISogAEEANgIcIAAgATYCFCAAQc2QgIAANgIQIABBCTYCDAwTC0EAISogAEEANgIcIAAgATYCFCAAQemKgIAANgIQIABBCTYCDAwSC0EAISogAEEANgIcIAAgATYCFCAAQbeQgIAANgIQIABBCTYCDAwRC0EAISogAEEANgIcIAAgATYCFCAAQZyRgIAANgIQIABBCTYCDAwQC0EAISogAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwPC0EAISogAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwOC0EAISogAEEANgIcIAAgATYCFCAAQcCSgIAANgIQIABBCzYCDAwNC0EAISogAEEANgIcIAAgATYCFCAAQZWJgIAANgIQIABBCzYCDAwMC0EAISogAEEANgIcIAAgATYCFCAAQeGPgIAANgIQIABBCjYCDAwLC0EAISogAEEANgIcIAAgATYCFCAAQfuPgIAANgIQIABBCjYCDAwKC0EA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AAAABQAAAAAAAAAAAAAABgAAAAcAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJbnZhbGlkIGNoYXIgaW4gdXJsIHF1ZXJ5AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fYm9keQBDb250ZW50LUxlbmd0aCBvdmVyZmxvdwBDaHVuayBzaXplIG92ZXJmbG93AFJlc3BvbnNlIG92ZXJmbG93AEludmFsaWQgbWV0aG9kIGZvciBIVFRQL3gueCByZXF1ZXN0AEludmFsaWQgbWV0aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zAFVzZXIgY2FsbGJhY2sgZXJyb3IAYG9uX3Jlc2V0YCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfaGVhZGVyYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9iZWdpbmAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3N0YXR1c19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3ZlcnNpb25fY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl91cmxfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXRob2RfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfZmllbGRfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fbmFtZWAgY2FsbGJhY2sgZXJyb3IAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzZXJ2ZXIASW52YWxpZCBoZWFkZXIgdmFsdWUgY2hhcgBJbnZhbGlkIGhlYWRlciBmaWVsZCBjaGFyAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdmVyc2lvbgBJbnZhbGlkIG1pbm9yIHZlcnNpb24ASW52YWxpZCBtYWpvciB2ZXJzaW9uAEV4cGVjdGVkIHNwYWNlIGFmdGVyIHZlcnNpb24ARXhwZWN0ZWQgQ1JMRiBhZnRlciB2ZXJzaW9uAEludmFsaWQgSFRUUCB2ZXJzaW9uAEludmFsaWQgaGVhZGVyIHRva2VuAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdXJsAEludmFsaWQgY2hhcmFjdGVycyBpbiB1cmwAVW5leHBlY3RlZCBzdGFydCBjaGFyIGluIHVybABEb3VibGUgQCBpbiB1cmwARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgARHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhciBpbiB1cmwgcGF0aABDb250ZW50LUxlbmd0aCBjYW4ndCBiZSBwcmVzZW50IHdpdGggVHJhbnNmZXItRW5jb2RpbmcASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgc2l6ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl92YWx1ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlZCB2YWx1ZQBQYXVzZWQgYnkgb25faGVhZGVyc19jb21wbGV0ZQBJbnZhbGlkIEVPRiBzdGF0ZQBvbl9yZXNldCBwYXVzZQBvbl9jaHVua19oZWFkZXIgcGF1c2UAb25fbWVzc2FnZV9iZWdpbiBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fdmFsdWUgcGF1c2UAb25fc3RhdHVzX2NvbXBsZXRlIHBhdXNlAG9uX3ZlcnNpb25fY29tcGxldGUgcGF1c2UAb25fdXJsX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXNzYWdlX2NvbXBsZXRlIHBhdXNlAG9uX21ldGhvZF9jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfZmllbGRfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUgcGF1c2UAVW5leHBlY3RlZCBzcGFjZSBhZnRlciBzdGFydCBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAFBhdXNlIG9uIENPTk5FQ1QvVXBncmFkZQBQYXVzZSBvbiBQUkkvVXBncmFkZQBFeHBlY3RlZCBIVFRQLzIgQ29ubmVjdGlvbiBQcmVmYWNlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fbWV0aG9kAEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl9maWVsZABQYXVzZWQASW52YWxpZCB3b3JkIGVuY291bnRlcmVkAEludmFsaWQgbWV0aG9kIGVuY291bnRlcmVkAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2NoZW1hAFJlcXVlc3QgaGFzIGludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYABTV0lUQ0hfUFJPWFkAVVNFX1BST1hZAE1LQUNUSVZJVFkAVU5QUk9DRVNTQUJMRV9FTlRJVFkAQ09QWQBNT1ZFRF9QRVJNQU5FTlRMWQBUT09fRUFSTFkATk9USUZZAEZBSUxFRF9ERVBFTkRFTkNZAEJBRF9HQVRFV0FZAFBMQVkAUFVUAENIRUNLT1VUAEdBVEVXQVlfVElNRU9VVABSRVFVRVNUX1RJTUVPVVQATkVUV09SS19DT05ORUNUX1RJTUVPVVQAQ09OTkVDVElPTl9USU1FT1VUAExPR0lOX1RJTUVPVVQATkVUV09SS19SRUFEX1RJTUVPVVQAUE9TVABNSVNESVJFQ1RFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX0xPQURfQkFMQU5DRURfUkVRVUVTVABCQURfUkVRVUVTVABIVFRQX1JFUVVFU1RfU0VOVF9UT19IVFRQU19QT1JUAFJFUE9SVABJTV9BX1RFQVBPVABSRVNFVF9DT05URU5UAE5PX0NPTlRFTlQAUEFSVElBTF9DT05URU5UAEhQRV9JTlZBTElEX0NPTlNUQU5UAEhQRV9DQl9SRVNFVABHRVQASFBFX1NUUklDVABDT05GTElDVABURU1QT1JBUllfUkVESVJFQ1QAUEVSTUFORU5UX1JFRElSRUNUAENPTk5FQ1QATVVMVElfU1RBVFVTAEhQRV9JTlZBTElEX1NUQVRVUwBUT09fTUFOWV9SRVFVRVNUUwBFQVJMWV9ISU5UUwBVTkFWQUlMQUJMRV9GT1JfTEVHQUxfUkVBU09OUwBPUFRJT05TAFNXSVRDSElOR19QUk9UT0NPTFMAVkFSSUFOVF9BTFNPX05FR09USUFURVMATVVMVElQTEVfQ0hPSUNFUwBJTlRFUk5BTF9TRVJWRVJfRVJST1IAV0VCX1NFUlZFUl9VTktOT1dOX0VSUk9SAFJBSUxHVU5fRVJST1IASURFTlRJVFlfUFJPVklERVJfQVVUSEVOVElDQVRJT05fRVJST1IAU1NMX0NFUlRJRklDQVRFX0VSUk9SAElOVkFMSURfWF9GT1JXQVJERURfRk9SAFNFVF9QQVJBTUVURVIAR0VUX1BBUkFNRVRFUgBIUEVfVVNFUgBTRUVfT1RIRVIASFBFX0NCX0NIVU5LX0hFQURFUgBNS0NBTEVOREFSAFNFVFVQAFdFQl9TRVJWRVJfSVNfRE9XTgBURUFSRE9XTgBIUEVfQ0xPU0VEX0NPTk5FQ1RJT04ASEVVUklTVElDX0VYUElSQVRJT04ARElTQ09OTkVDVEVEX09QRVJBVElPTgBOT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTgBIUEVfSU5WQUxJRF9WRVJTSU9OAEhQRV9DQl9NRVNTQUdFX0JFR0lOAFNJVEVfSVNfRlJPWkVOAEhQRV9JTlZBTElEX0hFQURFUl9UT0tFTgBJTlZBTElEX1RPS0VOAEZPUkJJRERFTgBFTkhBTkNFX1lPVVJfQ0FMTQBIUEVfSU5WQUxJRF9VUkwAQkxPQ0tFRF9CWV9QQVJFTlRBTF9DT05UUk9MAE1LQ09MAEFDTABIUEVfSU5URVJOQUwAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRV9VTk9GRklDSUFMAEhQRV9PSwBVTkxJTksAVU5MT0NLAFBSSQBSRVRSWV9XSVRIAEhQRV9JTlZBTElEX0NPTlRFTlRfTEVOR1RIAEhQRV9VTkVYUEVDVEVEX0NPTlRFTlRfTEVOR1RIAEZMVVNIAFBST1BQQVRDSABNLVNFQVJDSABVUklfVE9PX0xPTkcAUFJPQ0VTU0lORwBNSVNDRUxMQU5FT1VTX1BFUlNJU1RFTlRfV0FSTklORwBNSVNDRUxMQU5FT1VTX1dBUk5JTkcASFBFX0lOVkFMSURfVFJBTlNGRVJfRU5DT0RJTkcARXhwZWN0ZWQgQ1JMRgBIUEVfSU5WQUxJRF9DSFVOS19TSVpFAE1PVkUAQ09OVElOVUUASFBFX0NCX1NUQVRVU19DT01QTEVURQBIUEVfQ0JfSEVBREVSU19DT01QTEVURQBIUEVfQ0JfVkVSU0lPTl9DT01QTEVURQBIUEVfQ0JfVVJMX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8AAF4TAAAmEwAAMBAAAPAXAACdEwAAFRIAADkXAADwEgAAChAAAHUSAACtEgAAghMAAE8UAAB/EAAAoBUAACMUAACJEgAAixQAAE0VAADUEQAAzxQAABAYAADJFgAA3BYAAMERAADgFwAAuxQAAHQUAAB8FQAA5RQAAAgXAAAfEAAAZRUAAKMUAAAoFQAAAhUAAJkVAAAsEAAAixkAAE8PAADUDgAAahAAAM4QAAACFwAAiQ4AAG4TAAAcEwAAZhQAAFYXAADBEwAAzRMAAGwTAABoFwAAZhcAAF8XAAAiEwAAzg8AAGkOAADYDgAAYxYAAMsTAACqDgAAKBcAACYXAADFEwAAXRYAAOgRAABnEwAAZRMAAPIWAABzEwAAHRcAAPkWAADzEQAAzw4AAM4VAAAMEgAAsxEAAKURAABhEAAAMhcAALsTAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAwICAgICAAACAgACAgACAgICAgICAgICAAQAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgACAgICAgAAAgIAAgIAAgICAgICAgICAgADAAQAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxvc2VlZXAtYWxpdmUAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAWNodW5rZWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAAABAQABAQABAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZWN0aW9uZW50LWxlbmd0aG9ucm94eS1jb25uZWN0aW9uAAAAAAAAAAAAAAAAAAAAcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQoNClNNDQoNClRUUC9DRS9UU1AvAAAAAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAEAAAIAAAAAAAAAAAAAAAAAAAAAAAADBAAABAQEBAQEBAQEBAQFBAQEBAQEBAQEBAQEAAQABgcEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAACAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRU9SRElSRUNUT1JUUkNIUEFSQU1FVEVSVVJDRUJTQ1JJQkVBUkRPV05BQ0VJTkROS0NLVUJTQ1JJQkVIVFRQL0FEVFAv' +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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FCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAU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YWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' diff --git a/deps/undici/src/lib/llhttp/llhttp.wasm b/deps/undici/src/lib/llhttp/llhttp.wasm index 633d00a08975ea..fe63282c9a5e6f 100755 Binary files a/deps/undici/src/lib/llhttp/llhttp.wasm and b/deps/undici/src/lib/llhttp/llhttp.wasm differ diff --git a/deps/undici/src/lib/llhttp/llhttp_simd-wasm.js b/deps/undici/src/lib/llhttp/llhttp_simd-wasm.js index 0fb8a67a0e5e65..017e247de6d2aa 100644 --- a/deps/undici/src/lib/llhttp/llhttp_simd-wasm.js +++ b/deps/undici/src/lib/llhttp/llhttp_simd-wasm.js @@ -1 +1 @@ -module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAAMBBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC9z3AQMofwN+BX8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDyABIRAgASERIAEhEiABIRMgASEUIAEhFSABIRYgASEXIAEhGCABIRkgASEaIAEhGyABIRwgASEdIAEhHiABIR8gASEgIAEhISABISIgASEjIAEhJCABISUgASEmIAEhJyABISggASEpAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAAoAhwiKkF/ag7dAdoBAdkBAgMEBQYHCAkKCwwNDtgBDxDXARES1gETFBUWFxgZGhvgAd8BHB0e1QEfICEiIyQl1AEmJygpKiss0wHSAS0u0QHQAS8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRtsBR0hJSs8BzgFLzQFMzAFNTk9QUVJTVFVW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AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJA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AAAAAAAAAAkKCwwNDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxAREhMUAAtBHiEqDMQDC0ICISsM5QELQgMhKwzkAQtCBCErDOMBC0IFISsM4gELQgYhKwzhAQtCByErDOABC0IIISsM3wELQgkhKwzeAQtCCiErDN0BC0ILISsM3AELQgwhKwzbAQtCDSErDNoBC0IOISsM2QELQg8hKwzYAQtCCiErDNcBC0ILISsM1gELQgwhKwzVAQtCDSErDNQBC0IOISsM0wELQg8hKwzSAQtCACErAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAqLQAAQVBqDjflAeQBAAECAwQFBgfmAeYB5gHmAeYB5gHmAQgJCgsMDeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gEODxAREhPmAQtCAiErDOQBC0IDISsM4wELQgQhKwziAQtCBSErDOEBC0IGISsM4AELQgchKwzfAQtCCCErDN4BC0IJISsM3QELQgohKwzcAQtCCyErDNsBC0IMISsM2gELQg0hKwzZAQtCDiErDNgBC0IPISsM1wELQgohKwzWAQtCCyErDNUBC0IMISsM1AELQg0hKwzTAQtCDiErDNIBC0IPISsM0QELIABCACAAKQMgIisgAiABIiprrSIsfSItIC0gK1YbNwMgICsgLFYiLkUN0gFBHyEqDMcDCwJAIAEiASACRg0AIABBiYCAgAA2AgggACABNgIEIAEhAUEkISoMrgMLQSAhKgzGAwsgACABIiogAhC+gICAAEF/ag4FtgEAywIB0QHSAQtBESEqDKsDCyAAQQE6AC8gKiEBDMIDCyABIgEgAkcN0gFBJCEqDMIDCyABIicgAkcNHkHGACEqDMEDCyAAIAEiASACELKAgIAAIioN1AEgASEBDLUBCyABIiogAkcNJkHQACEqDL8DCwJAIAEiASACRw0AQSghKgy/AwsgAEEANgIEIABBjICAgAA2AgggACABIAEQsYCAgAAiKg3TASABIQEM2AELAkAgASIqIAJHDQBBKSEqDL4DCyAqLQAAIgFBIEYNFCABQQlHDdMBICpBAWohAQwVCwJAIAEiASACRg0AIAFBAWohAQwXC0EqISoMvAMLAkAg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DQALIAAgKjYCAEGDASEqDOgCC0EAISogAEEANgIAIC4gMmtBA2ohAQzKAQsCQCABIiogAkcNAEGEASEqDOcCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBg8+AgABqLQAARw3MASABQQRGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBhAEhKgznAgsgAEEANgIAICogLmtBBWohAUEjISoMyQELAkAgASIEIAJHDQBBhQEhKgzmAgsCQAJAIAQtAABBtH9qDggAzAHMAcwBzAHMAcwBAcwBCyAEQQFqIQFB7wAhKgzNAgsgBEEBaiEBQfAAISoMzAILAkAgASIEIAJHDQBBhgEhKgzlAgsgBC0AAEHFAEcNyQEgBEEBaiEBDIoCCwJAIAEiKiACRw0AQYcBISoM5AILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUGIz4CAAGotAABHDckBIAFBA0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGHASEqDOQCCyAAQQA2AgAgKiAua0EEaiEBQS0hKgzGAQsCQCABIiogAkcNAEGIASEqDOMCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFB0M+AgABqLQAARw3IASABQQhGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBiAEhKgzjAgsgAEEANgIAICogLmtBCWohAUEpISoMxQELAkAgASIBIAJHDQBBiQEhKgziAgtBASEqIAEtAABB3wBHDcQBIAFBAWohAQyIAgsCQCABIiogAkcNAEGKASEqDOECCyACICprIAAoAgAiLmohMiAqIQQgLiEBA0AgBC0AACABQYzPgIAAai0AAEcNxQEgAUEBRg23AiABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGKASEqDOACCwJAIAEiKiACRw0AQYsBISoM4AILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUGOz4CAAGotAABHDcUBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGLASEqDOACCyAAQQA2AgAgKiAua0EDaiEBQQIhKgzCAQsCQCABIiogAkcNAEGMASEqDN8CCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFB8M+AgABqLQAARw3EASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBjAEhKgzfAgsgAEEANgIAICogLmtBAmohAUEfISoMwQELAkAgASIqIAJHDQBBjQEhKgzeAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQfLPgIAAai0AAEcNwwEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQY0BISoM3gILIABBADYCACAqIC5rQQJqIQFBCSEqDMABCwJAIAEiBCACRw0AQY4BISoM3QILAkACQCAELQAAQbd/ag4HAMMBwwHDAcMBwwEBwwELIARBAWohAUH4ACEqDMQCCyAEQQFqIQFB+QAhKgzDAgsCQCABIiogAkcNAEGPASEqDNwCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBkc+AgABqLQAARw3BASABQQVGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBjwEhKgzcAgsgAEEANgIAICogLmtBBmohAUEYISoMvgELAkAgASIqIAJHDQBBkAEhKgzbAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQZfPgIAAai0AAEcNwAEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQZABISoM2wILIABBADYCACAqIC5rQQNqIQFBFyEqDL0BCwJAIAEiKiACRw0AQZEBISoM2gILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUGaz4CAAGotAABHDb8BIAFBBkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGRASEqDNoCCyAAQQA2AgAgKiAua0EHaiEBQRUhKgy8AQsCQCABIiogAkcNAEGSASEqDNkCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBoc+AgABqLQAARw2+ASABQQVGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBkgEhKgzZAgsgAEEANgIAICogLmtBBmohAUEeISoMuwELAkAgASIEIAJHDQBBkwEhKgzYAgsgBC0AAEHMAEcN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LjYCAEGqASEqDMECCyAAQQA2AgAgEiAqa0EDaiEBQRQhKgyjAQsCQCAEIAJHDQBBqwEhKgzAAgsCQAJAAkACQCAELQAAQb5/ag4PAAECqAGoAagBqAGoAagBqAGoAagBqAGoAQOoAQsgBEEBaiEPQZMBISoMqQILIARBAWohEEGUASEqDKgCCyAEQQFqIRFBlQEhKgynAgsgBEEBaiESQZYBISoMpgILAkAgBCACRw0AQawBISoMvwILIAQtAABBxQBHDaMBIARBAWohBAznAQsCQCATIAJHDQBBrQEhKgy+AgsgAiATayAAKAIAIipqIS4gEyEEICohAQJAA0AgBC0AACABQc3PgIAAai0AAEcNowEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQa0BISoMvgILIABBADYCACATICprQQNqIQFBDiEqDKABCwJAIAQgAkcNAEGuASEqDL0CCyAELQAAQdAARw2hASAEQQFqIQFBJSEqDJ8BCwJAIBQgAkcNAEGvASEqDLwCCyACIBRrIAAoAgAiKmohLiAUIQQgKiEBAkADQCAELQAAIAFB0M+AgABqLQAARw2hASABQQhGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBrwEhKgy8AgsgAEEANgIAIBQgKmtBCWohAUEqISoMngELAkAgBCACRw0AQbABISoMuwILAkACQCAELQAAQat/ag4LAKEBoQGhAaEBoQGhAaEBoQGhAQGhAQsgBEEBaiEEQZoBISoMogILIARBAWohFEGbASEqDKECCwJAIAQgAkcNAEGxASEqDLoCCwJAAkAgBC0AAEG/f2oOFACgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEBoAELIARBAWohE0GZASEqDKECCyAEQQFqIQRBnAEhKgygAgsCQCAVIAJHDQBBsgEhKgy5AgsgAiAVayAAKAIAIipqIS4gFSEEICohAQJAA0AgBC0AACABQdnPgIAAai0AAEcNngEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbIBISoMuQILIABBADYCACAVICprQQRqIQFBISEqDJsBCwJAIBYgAkcNAEGzASEqDLgCCyACIBZrIAAoAgAiKmohLiAWIQQgKiEBAkADQCAELQAAIAFB3c+AgABqLQAARw2dASABQQZGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBswEhKgy4AgsgAEEANgIAIBYgKmtBB2ohAUEaISoMmgELAkAgBCACRw0AQbQBISoMtwILAkACQAJAIAQtAABBu39qDhEAngGeAZ4BngGeAZ4BngGeAZ4BAZ4BngGeAZ4BngECngELIARBAWohBEGdASEqDJ8CCyAEQQFqIRVBngEhKgyeAgsgBEEBaiEWQZ8BISoMnQILAkAgFyACRw0AQbUBISoMtgILIAIgF2sgACgCACIqaiEuIBchBCAqIQECQANAIAQtAAAgAUHkz4CAAGotAABHDZsBIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEG1ASEqDLYCCyAAQQA2AgAgFyAqa0EGaiEBQSghKgyYAQsCQCAYIAJHDQBBtgEhKgy1AgsgAiAYayAAKAIAIipqIS4gGCEEICohAQJAA0AgBC0AACABQerPgIAAai0AAEcNmgEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbYBISoMtQILIABBADYCACAYICprQQNqIQFBByEqDJcBCwJAIAQgAkcNAEG3ASEqDLQCCwJAAkAgBC0AAEG7f2oODgCaAZoBmgGaAZoBmgGaAZoBmgGaAZoBmgEBmgELIARBAWohF0GhASEqDJsCCyAEQQFqIRhBogEhKgyaAgsCQCAZIAJHDQBBuAEhKgyzAgsgAiAZayAAKAIAIipqIS4gGSEEICohAQJAA0AgBC0AACABQe3PgIAAai0AAEcNmAEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbgBISoMswILIABBADYCACAZICprQQNqIQFBEiEqDJUBCwJAIBogAkcNAEG5ASEqDLICCyACIBprIAAoAgAiKmohLiAaIQQgKiEBAkADQCAELQAAIAFB8M+AgABqLQAARw2XASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBuQEhKgyyAgsgAEEANgIAIBogKmtBAmohAUEgISoMlAELAkAgGyACRw0AQboBISoMsQILIAIgG2sgACgCACIqaiEuIBshBCAqIQECQANAIAQtAAAgAUHyz4CAAGotAABHDZYBIAFB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DM4BCyAAQQA2AhwgACABNgIUIABBoJmAgAA2AhAgAEEeNgIMQQAhKgzNAQsgAUEBaiEBCyAAQYASOwEqIAAgASACEKiAgIAAIioNASABIQELQccAISoMsQELICpBFUcNiQEgAEHRADYCHCAAIAE2AhQgAEHjl4CAADYCECAAQRU2AgxBACEqDMkBCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxiCyAAQdIANgIcIAAgATYCFCAAICo2AgxBACEqDMgBCyAAQQA2AhwgACAuNgIUIABBwaiAgAA2AhAgAEEHNgIMIABBADYCAEEAISoMxwELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDGELIABB0wA2AhwgACABNgIUIAAgKjYCDEEAISoMxgELQQAhKiAAQQA2AhwgACABNgIUIABBgJGAgAA2AhAgAEEJNgIMDMUBCyAqQRVGDYMBIABBADYCHCAAIAE2AhQgAEGUjYCAADYCECAAQSE2AgxBACEqDMQBC0EBIS9BACEyQQAhLkEBISoLIAAgKjoAKyABQQFqIQECQAJAIAAtAC1BEHENAAJAAkACQCAALQAqDgMBAAIECyAvRQ0DDAILIC4NAQwCCyAyRQ0BCyAAKAIEISogAEEANgIEAkAgACAqIAEQrYCAgAAiKg0AIAEhAQxgCyAAQdgANgIcIAAgATYCFCAAICo2AgxBACEqDMMBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQrYCAgAAiBA0AIAEhAQyyAQsgAEHZADYCHCAAIAE2AhQgACAENgIMQQAhKgzCAQsgACgCBCEEIABBADYCBAJAIAAgBCABEK2AgIAAIgQNACABIQEMsAELIABB2gA2AhwgACABNgIUIAAgBDYCDEEAISoMwQELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARCtgICAACIEDQAgASEBDK4BCyAAQdwANgIcIAAgATYCFCAAIAQ2AgxBACEqDMABC0EBISoLIAAgKjoAKiABQQFqIQEMXAsgACgCBCEEIABBADYCBAJAIAAgBCABEK2AgIAAIgQNACABIQEMqgELIABB3gA2AhwgACABNgIUIAAgBDYCDEEAISoMvQELIABBADYCACAyIC9rQQRqIQECQCAALQApQSNPDQAgASEBDFwLIABBADYCHCAAIAE2AhQgAEHTiYCAADYCECAAQQg2AgxBACEqDLwBCyAAQQA2AgALQQAhKiAAQQA2AhwgACABNgIUIABBkLOAgAA2AhAgAEEINgIMDLoBCyAAQQA2AgAgMiAva0EDaiEBAkAgAC0AKUEhRw0AIAEhAQxZCyAAQQA2AhwgACABNgIUIABBm4qAgAA2AhAgAEEINgIMQQAhKgy5AQsgAEEANgIAIDIgL2tBBGohAQJAIAAtACkiKkFdakELTw0AIAEhAQxYCwJAICpBBksNAEEBICp0QcoAcUUNACABIQEMWAtBACEqIABBADYCHCAAIAE2AhQgAEH3iYCAADYCECAAQQg2AgwMuAELICpBFUYNdSAAQQA2AhwgACABNgIUIABBuY2AgAA2AhAgAEEaNgIMQQAhKgy3AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMVwsgAEHlADYCHCAAIAE2AhQgACAqNgIMQQAhKgy2AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMTwsgAEHSADYCHCAAIAE2AhQgACAqNgIMQQAhKgy1AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMTwsgAEHTADYCHCAAIAE2AhQgACAqNgIMQQAhKgy0AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMVAsgAEHlADYCHCAAIAE2AhQgACAqNgIMQQAhKgyzAQsgAEEANgIcIAAgATYCFCAAQcaKgIAANgIQIABBBzYCDEEAISoMsgELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDEsLIABB0gA2AhwgACABNgIUIAAgKjYCDEEAISoMsQELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDEsLIABB0wA2AhwgACABNgIUIAAgKjYCDEEAISoMsAELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDFALIABB5QA2AhwgACABNgIUIAAgKjYCDEEAISoMrwELIABBADYCHCAAIAE2AhQgAEHciICAADYCECAAQQc2AgxBACEqDK4BCyAqQT9HDQEgAUEBaiEB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AAAABwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEludmFsaWQgY2hhciBpbiB1cmwgcXVlcnkAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9ib2R5AENvbnRlbnQtTGVuZ3RoIG92ZXJmbG93AENodW5rIHNpemUgb3ZlcmZsb3cAUmVzcG9uc2Ugb3ZlcmZsb3cASW52YWxpZCBtZXRob2QgZm9yIEhUVFAveC54IHJlcXVlc3QASW52YWxpZCBtZXRob2QgZm9yIFJUU1AveC54IHJlcXVlc3QARXhwZWN0ZWQgU09VUkNFIG1ldGhvZCBmb3IgSUNFL3gueCByZXF1ZXN0AEludmFsaWQgY2hhciBpbiB1cmwgZnJhZ21lbnQgc3RhcnQARXhwZWN0ZWQgZG90AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fc3RhdHVzAEludmFsaWQgcmVzcG9uc2Ugc3RhdHVzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fcmVzZXRgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19oZWFkZXJgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' +module.exports = 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJsbGh0dHBfc3RhdHVzX25hbWUAIRpsbGh0dHBfc2V0X2xlbmllbnRfaGVhZGVycwAiIWxsaHR0cF9zZXRfbGVuaWVudF9jaHVua2VkX2xlbmd0aAAjHWxsaHR0cF9zZXRfbGVuaWVudF9rZWVwX2FsaXZlACQkbGxodHRwX3NldF9sZW5pZW50X3RyYW5zZmVyX2VuY29kaW5nACUYbGxodHRwX21lc3NhZ2VfbmVlZHNfZW9mAD8JFwEAQQELEQECAwQFCwYHNTk3MS8tJyspCrLgAkUCAAsIABCIgICAAAsZACAAEMKAgIAAGiAAIAI2AjggACABOgAoCxwAIAAgAC8BMiAALQAuIAAQwYCAgAAQgICAgAALKgEBf0HAABDGgICAACIBEMKAgIAAGiABQYCIgIAANgI4IAEgADoAKCABCwoAIAAQyICAgAALBwAgAC0AKAsHACAALQAqCwcAIAAtACsLBwAgAC0AKQsHACAALwEyCwcAIAAtAC4LRQEEfyAAKAIYIQEgAC0ALSECIAAtACghAyAAKAI4IQQgABDCgICAABogACAENgI4IAAgAzoAKCAAIAI6AC0gACABNgIYCxEAIAAgASABIAJqEMOAgIAACxAAIABBAEHcABDMgICAABoLZwEBf0EAIQECQCAAKAIMDQACQAJAAkACQCAALQAvDgMBAAMCCyAAKAI4IgFFDQAgASgCLCIBRQ0AIAAgARGAgICAAAAiAQ0DC0EADwsQyoCAgAAACyAAQcOWgIAANgIQQQ4hAQsgAQseAAJAIAAoAgwNACAAQdGbgIAANgIQIABBFTYCDAsLFgACQCAAKAIMQRVHDQAgAEEANgIMCwsWAAJAIAAoAgxBFkcNACAAQQA2AgwLCwcAIAAoAgwLBwAgACgCEAsJACAAIAE2AhALBwAgACgCFAsiAAJAIABBJEkNABDKgICAAAALIABBAnRBoLOAgABqKAIACyIAAkAgAEEuSQ0AEMqAgIAAAAsgAEECdEGwtICAAGooAgAL7gsBAX9B66iAgAAhAQJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABBnH9qDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0Hhp4CAAA8LQaShgIAADwtBy6yAgAAPC0H+sYCAAA8LQcCkgIAADwtBq6SAgAAPC0GNqICAAA8LQeKmgIAADwtBgLCAgAAPC0G5r4CAAA8LQdekgIAADwtB75+AgAAPC0Hhn4CAAA8LQfqfgIAADwtB8qCAgAAPC0Gor4CAAA8LQa6ygIAADwtBiLCAgAAPC0Hsp4CAAA8LQYKigIAADwtBjp2AgAAPC0HQroCAAA8LQcqjgIAADwtBxbKAgAAPC0HfnICAAA8LQdKcgIAADwtBxKCAgAAPC0HXoICAAA8LQaKfgIAADwtB7a6AgAAPC0GrsICAAA8LQdSlgIAADwtBzK6AgAAPC0H6roCAAA8LQfyrgIAADwtB0rCAgAAPC0HxnYCAAA8LQbuggIAADwtB96uAgAAPC0GQsYCAAA8LQdexgIAADwtBoq2AgAAPC0HUp4CAAA8LQeCrgIAADwtBn6yAgAAPC0HrsYCAAA8LQdWfgIAADwtByrGAgAAPC0HepYCAAA8LQdSegIAADwtB9JyAgAAPC0GnsoCAAA8LQbGdgIAADwtBoJ2AgAAPC0G5sYCAAA8LQbywgIAADwtBkqGAgAAPC0GzpoCAAA8LQemsgIAADwtBrJ6AgAAPC0HUq4CAAA8LQfemgIAADwtBgKaAgAAPC0GwoYCAAA8LQf6egIAADwtBjaOAgAAPC0GJrYCAAA8LQfeigIAADwtBoLGAgAAPC0Gun4CAAA8LQcalgIAADwtB6J6AgAAPC0GTooCAAA8LQcKvgIAADwtBw52AgAAPC0GLrICAAA8LQeGdgIAADwtBja+AgAAPC0HqoYCAAA8LQbStgIAADwtB0q+AgAAPC0HfsoCAAA8LQdKygIAADwtB8LCAgAAPC0GpooCAAA8LQfmjgIAADwtBmZ6AgAAPC0G1rICAAA8LQZuwgIAADwtBkrKAgAAPC0G2q4CAAA8LQcKigIAADwtB+LKAgAAPC0GepYCAAA8LQdCigIAADwtBup6AgAAPC0GBnoCAAA8LEMqAgIAAAAtB1qGAgAAhAQsgAQsWACAAIAAtAC1B/gFxIAFBAEdyOgAtCxkAIAAgAC0ALUH9AXEgAUEAR0EBdHI6AC0LGQAgACAALQAtQfsBcSABQQBHQQJ0cjoALQsZACAAIAAtAC1B9wFxIAFBAEdBA3RyOgAtCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAgAiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCBCIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQcaRgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIwIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAggiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2ioCAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCNCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIMIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZqAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAjgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCECIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZWQgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAI8IgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAhQiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEGqm4CAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCQCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIYIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZOAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCJCIERQ0AIAAgBBGAgICAAAAhAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIsIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAigiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2iICAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCUCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIcIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABBwpmAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCICIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZSUgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAJMIgRFDQAgACAEEYCAgIAAACEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAlQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCWCIERQ0AIAAgBBGAgICAAAAhAwsgAwtFAQF/AkACQCAALwEwQRRxQRRHDQBBASEDIAAtAChBAUYNASAALwEyQeUARiEDDAELIAAtAClBBUYhAwsgACADOgAuQQAL/gEBA39BASEDAkAgAC8BMCIEQQhxDQAgACkDIEIAUiEDCwJAAkAgAC0ALkUNAEEBIQUgAC0AKUEFRg0BQQEhBSAEQcAAcUUgA3FBAUcNAQtBACEFIARBwABxDQBBAiEFIARB//8DcSIDQQhxDQACQCADQYAEcUUNAAJAIAAtAChBAUcNACAALQAtQQpxDQBBBQ8LQQQPCwJAIANBIHENAAJAIAAtAChBAUYNACAALwEyQf//A3EiAEGcf2pB5ABJDQAgAEHMAUYNACAAQbACRg0AQQQhBSAEQShxRQ0CIANBiARxQYAERg0CC0EADwtBAEEDIAApAyBQGyEFCyAFC2IBAn9BACEBAkAgAC0AKEEBRg0AIAAvATJB//8DcSICQZx/akHkAEkNACACQcwBRg0AIAJBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhASAAQYgEcUGABEYNACAAQShxRSEBCyABC6cBAQN/AkACQAJAIAAtACpFDQAgAC0AK0UNAEEAIQMgAC8BMCIEQQJxRQ0BDAILQQAhAyAALwEwIgRBAXFFDQELQQEhAyAALQAoQQFGDQAgAC8BMkH//wNxIgVBnH9qQeQASQ0AIAVBzAFGDQAgBUGwAkYNACAEQcAAcQ0AQQAhAyAEQYgEcUGABEYNACAEQShxQQBHIQMLIABBADsBMCAAQQA6AC8gAwuZAQECfwJAAkACQCAALQAqRQ0AIAAtACtFDQBBACEBIAAvATAiAkECcUUNAQwCC0EAIQEgAC8BMCICQQFxRQ0BC0EBIQEgAC0AKEEBRg0AIAAvATJB//8DcSIAQZx/akHkAEkNACAAQcwBRg0AIABBsAJGDQAgAkHAAHENAEEAIQEgAkGIBHFBgARGDQAgAkEocUEARyEBCyABC0kBAXsgAEEQav0MAAAAAAAAAAAAAAAAAAAAACIB/QsDACAAIAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQID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YWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==' diff --git a/deps/undici/src/lib/llhttp/llhttp_simd.wasm b/deps/undici/src/lib/llhttp/llhttp_simd.wasm index 93cdf56803ad43..7aa0b55fe59ef5 100755 Binary files a/deps/undici/src/lib/llhttp/llhttp_simd.wasm and b/deps/undici/src/lib/llhttp/llhttp_simd.wasm differ diff --git a/deps/undici/src/lib/llhttp/wasm_build_env.txt b/deps/undici/src/lib/llhttp/wasm_build_env.txt new file mode 100644 index 00000000000000..5f478b52ecbdfd --- /dev/null +++ b/deps/undici/src/lib/llhttp/wasm_build_env.txt @@ -0,0 +1,32 @@ +alpine-baselayout-data-3.4.0-r0 +musl-1.2.3-r4 +busybox-1.35.0-r29 +busybox-binsh-1.35.0-r29 +alpine-baselayout-3.4.0-r0 +alpine-keys-2.4-r1 +ca-certificates-bundle-20220614-r4 +libcrypto3-3.0.8-r3 +libssl3-3.0.8-r3 +ssl_client-1.35.0-r29 +zlib-1.2.13-r0 +apk-tools-2.12.10-r1 +scanelf-1.3.5-r1 +musl-utils-1.2.3-r4 +libc-utils-0.7.2-r3 +libgcc-12.2.1_git20220924-r4 +libstdc++-12.2.1_git20220924-r4 +libffi-3.4.4-r0 +xz-libs-5.2.9-r0 +libxml2-2.10.4-r0 +zstd-libs-1.5.5-r0 +llvm15-libs-15.0.7-r0 +clang15-libs-15.0.7-r0 +libstdc++-dev-12.2.1_git20220924-r4 +clang15-15.0.7-r0 +lld-libs-15.0.7-r0 +lld-15.0.7-r0 +wasi-libc-0.20220525-r1 +wasi-libcxx-15.0.7-r0 +wasi-libcxxabi-15.0.7-r0 +wasi-compiler-rt-15.0.7-r0 +wasi-sdk-16-r0 diff --git a/deps/undici/src/lib/pool.js b/deps/undici/src/lib/pool.js index 93b3158f21a131..08509958069a4f 100644 --- a/deps/undici/src/lib/pool.js +++ b/deps/undici/src/lib/pool.js @@ -34,6 +34,7 @@ class Pool extends PoolBase { socketPath, autoSelectFamily, autoSelectFamilyAttemptTimeout, + allowH2, ...options } = {}) { super() @@ -54,6 +55,7 @@ class Pool extends PoolBase { connect = buildConnector({ ...tls, maxCachedSessions, + allowH2, socketPath, timeout: connectTimeout == null ? 10e3 : connectTimeout, ...(util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined), @@ -66,7 +68,7 @@ class Pool extends PoolBase { : [] this[kConnections] = connections || null this[kUrl] = util.parseOrigin(origin) - this[kOptions] = { ...util.deepClone(options), connect } + this[kOptions] = { ...util.deepClone(options), connect, allowH2 } this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : undefined diff --git a/deps/undici/src/lib/websocket/connection.js b/deps/undici/src/lib/websocket/connection.js index 8c821899f6553e..e0fa69726b4054 100644 --- a/deps/undici/src/lib/websocket/connection.js +++ b/deps/undici/src/lib/websocket/connection.js @@ -1,6 +1,5 @@ 'use strict' -const { randomBytes, createHash } = require('crypto') const diagnosticsChannel = require('diagnostics_channel') const { uid, states } = require('./constants') const { @@ -22,6 +21,14 @@ channels.open = diagnosticsChannel.channel('undici:websocket:open') channels.close = diagnosticsChannel.channel('undici:websocket:close') channels.socketError = diagnosticsChannel.channel('undici:websocket:socket_error') +/** @type {import('crypto')} */ +let crypto +try { + crypto = require('crypto') +} catch { + +} + /** * @see https://websockets.spec.whatwg.org/#concept-websocket-establish * @param {URL} url @@ -66,7 +73,7 @@ function establishWebSocketConnection (url, protocols, ws, onEstablish, options) // 5. Let keyValue be a nonce consisting of a randomly selected // 16-byte value that has been forgiving-base64-encoded and // isomorphic encoded. - const keyValue = randomBytes(16).toString('base64') + const keyValue = crypto.randomBytes(16).toString('base64') // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s // header list. @@ -148,7 +155,7 @@ function establishWebSocketConnection (url, protocols, ws, onEstablish, options) // trailing whitespace, the client MUST _Fail the WebSocket // Connection_. const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') - const digest = createHash('sha1').update(keyValue + uid).digest('base64') + const digest = crypto.createHash('sha1').update(keyValue + uid).digest('base64') if (secWSAccept !== digest) { failWebsocketConnection(ws, 'Incorrect hash received in Sec-WebSocket-Accept header.') return diff --git a/deps/undici/src/lib/websocket/frame.js b/deps/undici/src/lib/websocket/frame.js index 61bfd3915cecc5..d867ad118b29b8 100644 --- a/deps/undici/src/lib/websocket/frame.js +++ b/deps/undici/src/lib/websocket/frame.js @@ -1,15 +1,22 @@ 'use strict' -const { randomBytes } = require('crypto') const { maxUnsigned16Bit } = require('./constants') +/** @type {import('crypto')} */ +let crypto +try { + crypto = require('crypto') +} catch { + +} + class WebsocketFrameSend { /** * @param {Buffer|undefined} data */ constructor (data) { this.frameData = data - this.maskKey = randomBytes(4) + this.maskKey = crypto.randomBytes(4) } createFrame (opcode) { diff --git a/deps/undici/src/lib/websocket/websocket.js b/deps/undici/src/lib/websocket/websocket.js index 22ad2fb11a1910..e4aa58f52fc589 100644 --- a/deps/undici/src/lib/websocket/websocket.js +++ b/deps/undici/src/lib/websocket/websocket.js @@ -3,6 +3,7 @@ const { webidl } = require('../fetch/webidl') const { DOMException } = require('../fetch/constants') const { URLSerializer } = require('../fetch/dataURL') +const { getGlobalOrigin } = require('../fetch/global') const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = require('./constants') const { kWebSocketURL, @@ -57,18 +58,28 @@ class WebSocket extends EventTarget { url = webidl.converters.USVString(url) protocols = options.protocols - // 1. Let urlRecord be the result of applying the URL parser to url. + // 1. Let baseURL be this's relevant settings object's API base URL. + const baseURL = getGlobalOrigin() + + // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. let urlRecord try { - urlRecord = new URL(url) + urlRecord = new URL(url, baseURL) } catch (e) { - // 2. If urlRecord is failure, then throw a "SyntaxError" DOMException. + // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. throw new DOMException(e, 'SyntaxError') } - // 3. If urlRecord’s scheme is not "ws" or "wss", then throw a - // "SyntaxError" DOMException. + // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". + if (urlRecord.protocol === 'http:') { + urlRecord.protocol = 'ws:' + } else if (urlRecord.protocol === 'https:') { + // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". + urlRecord.protocol = 'wss:' + } + + // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { throw new DOMException( `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, @@ -76,19 +87,19 @@ class WebSocket extends EventTarget { ) } - // 4. If urlRecord’s fragment is non-null, then throw a "SyntaxError" + // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" // DOMException. - if (urlRecord.hash) { + if (urlRecord.hash || urlRecord.href.endsWith('#')) { throw new DOMException('Got fragment', 'SyntaxError') } - // 5. If protocols is a string, set protocols to a sequence consisting + // 8. If protocols is a string, set protocols to a sequence consisting // of just that string. if (typeof protocols === 'string') { protocols = [protocols] } - // 6. If any of the values in protocols occur more than once or otherwise + // 9. If any of the values in protocols occur more than once or otherwise // fail to match the requirements for elements that comprise the value // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket // protocol, then throw a "SyntaxError" DOMException. @@ -100,12 +111,12 @@ class WebSocket extends EventTarget { throw new DOMException('Invalid Sec-WebSocket-Protocol value', 'SyntaxError') } - // 7. Set this's url to urlRecord. - this[kWebSocketURL] = urlRecord + // 10. Set this's url to urlRecord. + this[kWebSocketURL] = new URL(urlRecord.href) - // 8. Let client be this's relevant settings object. + // 11. Let client be this's relevant settings object. - // 9. Run this step in parallel: + // 12. Run this step in parallel: // 1. Establish a WebSocket connection given urlRecord, protocols, // and client. diff --git a/deps/undici/src/package.json b/deps/undici/src/package.json index 49b657fded2805..3846b9dc3988c5 100644 --- a/deps/undici/src/package.json +++ b/deps/undici/src/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "5.22.1", + "version": "5.25.2", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { @@ -11,12 +11,41 @@ "url": "git+https://github.com/nodejs/undici.git" }, "license": "MIT", - "author": "Matteo Collina ", "contributors": [ + { + "name": "Daniele Belardi", + "url": "https://github.com/dnlup", + "author": true + }, + { + "name": "Ethan Arrowood", + "url": "https://github.com/ethan-arrowood", + "author": true + }, + { + "name": "Matteo Collina", + "url": "https://github.com/mcollina", + "author": true + }, + { + "name": "Matthew Aitken", + "url": "https://github.com/KhafraDev", + "author": true + }, { "name": "Robert Nagy", "url": "https://github.com/ronag", "author": true + }, + { + "name": "Szymon Marczak", + "url": "https://github.com/szmarczak", + "author": true + }, + { + "name": "Tomas Della Vedova", + "url": "https://github.com/delvedor", + "author": true } ], "keywords": [ @@ -64,10 +93,11 @@ "bench:run": "CONNECTIONS=1 node benchmarks/benchmark.js; CONNECTIONS=50 node benchmarks/benchmark.js", "serve:website": "docsify serve .", "prepare": "husky install", + "postpublish": "node scripts/update-undici-types-version.js && cd types && npm publish", "fuzz": "jsfuzz test/fuzzing/fuzz.js corpus" }, "devDependencies": { - "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/fake-timers": "^11.1.0", "@types/node": "^18.0.3", "abort-controller": "^3.0.0", "atomic-sleep": "^1.0.0", @@ -86,7 +116,7 @@ "husky": "^8.0.1", "import-fresh": "^3.3.0", "jest": "^29.0.2", - "jsdom": "^21.1.0", + "jsdom": "^22.1.0", "jsfuzz": "^1.0.15", "mocha": "^10.0.0", "p-timeout": "^3.2.0", @@ -98,7 +128,7 @@ "standard": "^17.0.0", "table": "^6.8.0", "tap": "^16.1.0", - "tsd": "^0.28.1", + "tsd": "^0.29.0", "typescript": "^5.0.2", "wait-on": "^7.0.1", "ws": "^8.11.0" diff --git a/deps/undici/src/types/README.md b/deps/undici/src/types/README.md new file mode 100644 index 00000000000000..20a721c445a21b --- /dev/null +++ b/deps/undici/src/types/README.md @@ -0,0 +1,6 @@ +# undici-types + +This package is a dual-publish of the [undici](https://www.npmjs.com/package/undici) library types. The `undici` package **still contains types**. This package is for users who _only_ need undici types (such as for `@types/node`). It is published alongside every release of `undici`, so you can always use the same version. + +- [GitHub nodejs/undici](https://github.com/nodejs/undici) +- [Undici Documentation](https://undici.nodejs.org/#/) diff --git a/deps/undici/src/types/client.d.ts b/deps/undici/src/types/client.d.ts index 56074a15ae7a13..ac1779721f6a2c 100644 --- a/deps/undici/src/types/client.d.ts +++ b/deps/undici/src/types/client.d.ts @@ -1,7 +1,6 @@ import { URL } from 'url' import { TlsOptions } from 'tls' import Dispatcher from './dispatcher' -import DispatchInterceptor from './dispatcher' import buildConnector from "./connector"; /** @@ -19,14 +18,14 @@ export class Client extends Dispatcher { export declare namespace Client { export interface OptionsInterceptors { - Client: readonly DispatchInterceptor[]; + Client: readonly Dispatcher.DispatchInterceptor[]; } export interface Options { /** TODO */ interceptors?: OptionsInterceptors; /** The maximum length of request headers in bytes. Default: `16384` (16KiB). */ maxHeaderSize?: number; - /** The amount of time the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `300e3` milliseconds (300s). */ + /** The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `300e3` milliseconds (300s). */ headersTimeout?: number; /** @deprecated unsupported socketTimeout, use headersTimeout & bodyTimeout instead */ socketTimeout?: never; @@ -40,13 +39,13 @@ export declare namespace Client { idleTimeout?: never; /** @deprecated unsupported keepAlive, use pipelining=0 instead */ keepAlive?: never; - /** the timeout after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. Default: `4e3` milliseconds (4s). */ + /** the timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. Default: `4e3` milliseconds (4s). */ keepAliveTimeout?: number; /** @deprecated unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead */ maxKeepAliveTimeout?: never; - /** the maximum allowed `idleTimeout` when overridden by *keep-alive* hints from the server. Default: `600e3` milliseconds (10min). */ + /** the maximum allowed `idleTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Default: `600e3` milliseconds (10min). */ keepAliveMaxTimeout?: number; - /** A number subtracted from server *keep-alive* hints when overriding `idleTimeout` to account for timing inaccuracies caused by e.g. transport latency. Default: `1e3` milliseconds (1s). */ + /** A number of milliseconds subtracted from server *keep-alive* hints when overriding `idleTimeout` to account for timing inaccuracies caused by e.g. transport latency. Default: `1e3` milliseconds (1s). */ keepAliveTimeoutThreshold?: number; /** TODO */ socketPath?: string; @@ -71,7 +70,17 @@ export declare namespace Client { /** Enables a family autodetection algorithm that loosely implements section 5 of RFC 8305. */ autoSelectFamily?: boolean; /** The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. */ - autoSelectFamilyAttemptTimeout?: number; + autoSelectFamilyAttemptTimeout?: number; + /** + * @description Enables support for H2 if the server has assigned bigger priority to it through ALPN negotiation. + * @default false + */ + allowH2?: boolean; + /** + * @description Dictates the maximum number of concurrent streams for a single H2 session. It can be overriden by a SETTINGS remote frame. + * @default 100 + */ + maxConcurrentStreams?: number } export interface SocketInfo { localAddress?: string diff --git a/deps/undici/src/types/dispatcher.d.ts b/deps/undici/src/types/dispatcher.d.ts index 412520386f3d27..816db19d20d878 100644 --- a/deps/undici/src/types/dispatcher.d.ts +++ b/deps/undici/src/types/dispatcher.d.ts @@ -109,7 +109,7 @@ declare namespace Dispatcher { blocking?: boolean; /** Upgrade the request. Should be used to specify the kind of upgrade i.e. `'Websocket'`. Default: `method === 'CONNECT' || null`. */ upgrade?: boolean | string | null; - /** The amount of time the parser will wait to receive the complete HTTP headers. Defaults to 300 seconds. */ + /** The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers. Defaults to 300 seconds. */ headersTimeout?: number | null; /** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use 0 to disable it entirely. Defaults to 300 seconds. */ bodyTimeout?: number | null; @@ -117,6 +117,8 @@ declare namespace Dispatcher { reset?: boolean; /** Whether Undici should throw an error upon receiving a 4xx or 5xx response from the server. Defaults to false */ throwOnError?: boolean; + /** For H2, it appends the expect: 100-continue header, and halts the request body until a 100-continue is received from the remote server*/ + expectContinue?: boolean; } export interface ConnectOptions { path: string; @@ -229,7 +231,7 @@ declare namespace Dispatcher { arrayBuffer(): Promise; blob(): Promise; formData(): Promise; - json(): Promise; + json(): Promise; text(): Promise; } diff --git a/deps/undici/src/types/index.d.ts b/deps/undici/src/types/index.d.ts new file mode 100644 index 00000000000000..c7532d69a073cc --- /dev/null +++ b/deps/undici/src/types/index.d.ts @@ -0,0 +1,57 @@ +import Dispatcher from'./dispatcher' +import { setGlobalDispatcher, getGlobalDispatcher } from './global-dispatcher' +import { setGlobalOrigin, getGlobalOrigin } from './global-origin' +import Pool from'./pool' +import { RedirectHandler, DecoratorHandler } from './handlers' + +import BalancedPool from './balanced-pool' +import Client from'./client' +import buildConnector from'./connector' +import errors from'./errors' +import Agent from'./agent' +import MockClient from'./mock-client' +import MockPool from'./mock-pool' +import MockAgent from'./mock-agent' +import mockErrors from'./mock-errors' +import ProxyAgent from'./proxy-agent' +import { request, pipeline, stream, connect, upgrade } from './api' + +export * from './cookies' +export * from './fetch' +export * from './file' +export * from './filereader' +export * from './formdata' +export * from './diagnostics-channel' +export * from './websocket' +export * from './content-type' +export * from './cache' +export { Interceptable } from './mock-interceptor' + +export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent, request, stream, pipeline, connect, upgrade, setGlobalDispatcher, getGlobalDispatcher, setGlobalOrigin, getGlobalOrigin, MockClient, MockPool, MockAgent, mockErrors, ProxyAgent, RedirectHandler, DecoratorHandler } +export default Undici + +declare namespace Undici { + var Dispatcher: typeof import('./dispatcher').default + var Pool: typeof import('./pool').default; + var RedirectHandler: typeof import ('./handlers').RedirectHandler + var DecoratorHandler: typeof import ('./handlers').DecoratorHandler + var createRedirectInterceptor: typeof import ('./interceptors').createRedirectInterceptor + var BalancedPool: typeof import('./balanced-pool').default; + var Client: typeof import('./client').default; + var buildConnector: typeof import('./connector').default; + var errors: typeof import('./errors').default; + var Agent: typeof import('./agent').default; + var setGlobalDispatcher: typeof import('./global-dispatcher').setGlobalDispatcher; + var getGlobalDispatcher: typeof import('./global-dispatcher').getGlobalDispatcher; + var request: typeof import('./api').request; + var stream: typeof import('./api').stream; + var pipeline: typeof import('./api').pipeline; + var connect: typeof import('./api').connect; + var upgrade: typeof import('./api').upgrade; + var MockClient: typeof import('./mock-client').default; + var MockPool: typeof import('./mock-pool').default; + var MockAgent: typeof import('./mock-agent').default; + var mockErrors: typeof import('./mock-errors').default; + var fetch: typeof import('./fetch').fetch; + var caches: typeof import('./cache').caches; +} diff --git a/deps/undici/src/types/package.json b/deps/undici/src/types/package.json new file mode 100644 index 00000000000000..16bf97c4ddf83c --- /dev/null +++ b/deps/undici/src/types/package.json @@ -0,0 +1,55 @@ +{ + "name": "undici-types", + "version": "5.25.1", + "description": "A stand-alone types package for Undici", + "homepage": "https://undici.nodejs.org", + "bugs": { + "url": "https://github.com/nodejs/undici/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/nodejs/undici.git" + }, + "license": "MIT", + "types": "index.d.ts", + "files": [ + "*.d.ts" + ], + "contributors": [ + { + "name": "Daniele Belardi", + "url": "https://github.com/dnlup", + "author": true + }, + { + "name": "Ethan Arrowood", + "url": "https://github.com/ethan-arrowood", + "author": true + }, + { + "name": "Matteo Collina", + "url": "https://github.com/mcollina", + "author": true + }, + { + "name": "Matthew Aitken", + "url": "https://github.com/KhafraDev", + "author": true + }, + { + "name": "Robert Nagy", + "url": "https://github.com/ronag", + "author": true + }, + { + "name": "Szymon Marczak", + "url": "https://github.com/szmarczak", + "author": true + }, + { + "name": "Tomas Della Vedova", + "url": "https://github.com/delvedor", + "author": true + } + ] +} \ No newline at end of file diff --git a/deps/undici/src/types/readable.d.ts b/deps/undici/src/types/readable.d.ts index 032b53b01f97a0..4549a8c87e818c 100644 --- a/deps/undici/src/types/readable.d.ts +++ b/deps/undici/src/types/readable.d.ts @@ -18,7 +18,7 @@ declare class BodyReadable extends Readable { /** Consumes and returns the body as a JavaScript Object * https://fetch.spec.whatwg.org/#dom-body-json */ - json(): Promise + json(): Promise /** Consumes and returns the body as a Blob * https://fetch.spec.whatwg.org/#dom-body-blob diff --git a/deps/undici/undici.js b/deps/undici/undici.js index 8b0bfaef593c18..cd6308f9f3cc2d 100644 --- a/deps/undici/undici.js +++ b/deps/undici/undici.js @@ -60,7 +60,13 @@ var require_symbols = __commonJS({ kProxy: Symbol("proxy agent options"), kCounter: Symbol("socket request counter"), kInterceptors: Symbol("dispatch interceptors"), - kMaxResponseSize: Symbol("max response size") + kMaxResponseSize: Symbol("max response size"), + kHTTP2Session: Symbol("http2Session"), + kHTTP2SessionState: Symbol("http2Session state"), + kHTTP2BuildRequest: Symbol("http2 build request"), + kHTTP1BuildRequest: Symbol("http1 build request"), + kHTTP2CopyHeaders: Symbol("http2 copy headers"), + kHTTPConnVersion: Symbol("http connection version") }; } }); @@ -292,7 +298,7 @@ var require_util = __commonJS({ var stream = require("stream"); var net = require("net"); var { InvalidArgumentError } = require_errors(); - var { Blob } = require("buffer"); + var { Blob: Blob2 } = require("buffer"); var nodeUtil = require("util"); var { stringify } = require("querystring"); var [nodeMajor, nodeMinor] = process.versions.node.split(".").map((v) => Number(v)); @@ -302,7 +308,7 @@ var require_util = __commonJS({ return obj && typeof obj === "object" && typeof obj.pipe === "function" && typeof obj.on === "function"; } function isBlobLike(object) { - return Blob && object instanceof Blob || object && typeof object === "object" && (typeof object.stream === "function" || typeof object.arrayBuffer === "function") && /^(Blob|File)$/.test(object[Symbol.toStringTag]); + return Blob2 && object instanceof Blob2 || object && typeof object === "object" && (typeof object.stream === "function" || typeof object.arrayBuffer === "function") && /^(Blob|File)$/.test(object[Symbol.toStringTag]); } function buildURL(url, queryParams) { if (url.includes("?") || url.includes("#")) { @@ -400,7 +406,7 @@ var require_util = __commonJS({ return 0; } else if (isStream(body)) { const state = body._readableState; - return state && state.ended === true && Number.isFinite(state.length) ? state.length : null; + return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length) ? state.length : null; } else if (isBlobLike(body)) { return body.size != null ? body.size : null; } else if (isBuffer(body)) { @@ -439,6 +445,8 @@ var require_util = __commonJS({ return m ? parseInt(m[1], 10) * 1e3 : null; } function parseHeaders(headers, obj = {}) { + if (!Array.isArray(headers)) + return headers; for (let i = 0; i < headers.length; i += 2) { const key = headers[i].toString().toLowerCase(); let val = obj[key]; @@ -535,13 +543,18 @@ var require_util = __commonJS({ bytesRead: socket.bytesRead }; } + async function* convertIterableToBuffer(iterable) { + for await (const chunk of iterable) { + yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); + } + } var ReadableStream; function ReadableStreamFrom(iterable) { if (!ReadableStream) { ReadableStream = require("stream/web").ReadableStream; } if (ReadableStream.from) { - return ReadableStream.from(iterable); + return ReadableStream.from(convertIterableToBuffer(iterable)); } let iterator; return new ReadableStream({ @@ -582,6 +595,23 @@ var require_util = __commonJS({ } } } + var events; + function addAbortListener(signal, listener) { + if (typeof Symbol.dispose === "symbol") { + if (!events) { + events = require("events"); + } + if (typeof events.addAbortListener === "function" && "aborted" in signal) { + return events.addAbortListener(signal, listener); + } + } + if ("addEventListener" in signal) { + signal.addEventListener("abort", listener, { once: true }); + return () => signal.removeEventListener("abort", listener); + } + signal.addListener("abort", listener); + return () => signal.removeListener("abort", listener); + } var hasToWellFormed = !!String.prototype.toWellFormed; function toUSVString(val) { if (hasToWellFormed) { @@ -622,6 +652,7 @@ var require_util = __commonJS({ isFormDataLike, buildURL, throwIfAborted, + addAbortListener, nodeMajor, nodeMinor, nodeHasAutoSelectFamily: nodeMajor > 18 || nodeMajor === 18 && nodeMinor >= 13 @@ -1121,11 +1152,24 @@ var require_util2 = __commonJS({ const metadata = list.filter((item) => item.algo === strongest); for (const item of metadata) { const algorithm = item.algo; - const expectedValue = item.hash; - const actualValue = crypto.createHash(algorithm).update(bytes).digest("base64"); + let expectedValue = item.hash; + if (expectedValue.endsWith("==")) { + expectedValue = expectedValue.slice(0, -2); + } + let actualValue = crypto.createHash(algorithm).update(bytes).digest("base64"); + if (actualValue.endsWith("==")) { + actualValue = actualValue.slice(0, -2); + } if (actualValue === expectedValue) { return true; } + let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest("base64url"); + if (actualBase64URL.endsWith("==")) { + actualBase64URL = actualBase64URL.slice(0, -2); + } + if (actualBase64URL === expectedValue) { + return true; + } } return false; } @@ -1232,9 +1276,9 @@ var require_util2 = __commonJS({ } return { value: result, done: false }; } - function fullyReadBody(body, processBody, processBodyError) { - const successSteps = (bytes) => queueMicrotask(() => processBody(bytes)); - const errorSteps = (error) => queueMicrotask(() => processBodyError(error)); + async function fullyReadBody(body, processBody, processBodyError) { + const successSteps = processBody; + const errorSteps = processBodyError; let reader; try { reader = body.stream.getReader(); @@ -1242,7 +1286,12 @@ var require_util2 = __commonJS({ errorSteps(e); return; } - readAllBytes(reader, successSteps, errorSteps); + try { + const result = await readAllBytes(reader); + successSteps(result); + } catch (e) { + errorSteps(e); + } } var ReadableStream = globalThis.ReadableStream; function isReadableStreamLike(stream) { @@ -1273,25 +1322,16 @@ var require_util2 = __commonJS({ } return input; } - async function readAllBytes(reader, successSteps, failureSteps) { + async function readAllBytes(reader) { const bytes = []; let byteLength = 0; while (true) { - let done; - let chunk; - try { - ({ done, value: chunk } = await reader.read()); - } catch (e) { - failureSteps(e); - return; - } + const { done, value: chunk } = await reader.read(); if (done) { - successSteps(Buffer.concat(bytes, byteLength)); - return; + return Buffer.concat(bytes, byteLength); } if (!isUint8Array(chunk)) { - failureSteps(new TypeError("Received non-Uint8Array chunk")); - return; + throw new TypeError("Received non-Uint8Array chunk"); } bytes.push(chunk); byteLength += chunk.length; @@ -5997,14 +6037,14 @@ var require_dataURL = __commonJS({ var require_file = __commonJS({ "lib/fetch/file.js"(exports2, module2) { "use strict"; - var { Blob, File: NativeFile } = require("buffer"); + var { Blob: Blob2, File: NativeFile } = require("buffer"); var { types } = require("util"); var { kState } = require_symbols2(); var { isBlobLike } = require_util2(); var { webidl } = require_webidl(); var { parseMIMEType, serializeAMimeType } = require_dataURL(); var { kEnumerableProperty } = require_util(); - var File = class extends Blob { + var File = class extends Blob2 { constructor(fileBits, fileName, options = {}) { webidl.argumentLengthCheck(arguments, 2, { header: "File constructor" }); fileBits = webidl.converters["sequence"](fileBits); @@ -6100,7 +6140,7 @@ var require_file = __commonJS({ name: kEnumerableProperty, lastModified: kEnumerableProperty }); - webidl.converters.Blob = webidl.interfaceConverter(Blob); + webidl.converters.Blob = webidl.interfaceConverter(Blob2); webidl.converters.BlobPart = function(V, opts) { if (webidl.util.Type(V) === "Object") { if (isBlobLike(V)) { @@ -6182,7 +6222,7 @@ var require_formdata = __commonJS({ var { kState } = require_symbols2(); var { File: UndiciFile, FileLike, isFileLike } = require_file(); var { webidl } = require_webidl(); - var { Blob, File: NativeFile } = require("buffer"); + var { Blob: Blob2, File: NativeFile } = require("buffer"); var File = NativeFile ?? UndiciFile; var FormData = class { constructor(form) { @@ -6292,7 +6332,7 @@ var require_formdata = __commonJS({ value = Buffer.from(value).toString("utf8"); } else { if (!isFileLike(value)) { - value = value instanceof Blob ? new File([value], "blob", { type: value.type }) : new FileLike(value, "blob", { type: value.type }); + value = value instanceof Blob2 ? new File([value], "blob", { type: value.type }) : new FileLike(value, "blob", { type: value.type }); } if (filename !== void 0) { const options = { @@ -6326,7 +6366,7 @@ var require_body = __commonJS({ var { kState } = require_symbols2(); var { webidl } = require_webidl(); var { DOMException, structuredClone } = require_constants(); - var { Blob, File: NativeFile } = require("buffer"); + var { Blob: Blob2, File: NativeFile } = require("buffer"); var { kBodyUsed } = require_symbols(); var assert = require("assert"); var { isErrored } = require_util(); @@ -6371,7 +6411,7 @@ var require_body = __commonJS({ } else if (ArrayBuffer.isView(object)) { source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)); } else if (util.isFormDataLike(object)) { - const boundary = `----formdata-undici-${Math.random()}`.replace(".", "").slice(0, 32); + const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, "0")}`; const prefix = `--${boundary}\r Content-Disposition: form-data`; const escape = (str) => str.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22"); @@ -6518,7 +6558,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r } else if (mimeType) { mimeType = serializeAMimeType(mimeType); } - return new Blob([bytes], { type: mimeType }); + return new Blob2([bytes], { type: mimeType }); }, instance); }, arrayBuffer() { @@ -6545,6 +6585,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r try { busboy = Busboy({ headers, + preservePath: true, defParamCharset: "utf8" }); } catch (err) { @@ -6642,7 +6683,7 @@ Content-Type: ${value.type || "application/octet-stream"}\r successSteps(new Uint8Array()); return promise.promise; } - fullyReadBody(object[kState].body, successSteps, errorSteps); + await fullyReadBody(object[kState].body, successSteps, errorSteps); return promise.promise; } function bodyUnusable(body) { @@ -6720,7 +6761,7 @@ var require_response = __commonJS({ responseObject[kHeaders][kRealm] = relevantRealm; return responseObject; } - static json(data = void 0, init = {}) { + static json(data, init = {}) { webidl.argumentLengthCheck(arguments, 1, { header: "Response.json" }); if (init !== null) { init = webidl.converters.ResponseInit(init); @@ -6941,9 +6982,9 @@ var require_response = __commonJS({ assert(false); } } - function makeAppropriateNetworkError(fetchParams) { + function makeAppropriateNetworkError(fetchParams, err = null) { assert(isCancelled(fetchParams)); - return isAborted(fetchParams) ? makeNetworkError(new DOMException("The operation was aborted.", "AbortError")) : makeNetworkError("Request was cancelled."); + return isAborted(fetchParams) ? makeNetworkError(Object.assign(new DOMException("The operation was aborted.", "AbortError"), { cause: err })) : makeNetworkError(Object.assign(new DOMException("Request was cancelled."), { cause: err })); } function initializeResponse(response, init, body) { if (init.status !== null && (init.status < 200 || init.status > 599)) { @@ -7197,7 +7238,11 @@ var require_request = __commonJS({ } catch (err) { throw new TypeError(`Referrer "${referrer}" is not a valid URL.`, { cause: err }); } - request.referrer = parsedReferrer; + if (parsedReferrer.protocol === "about:" && parsedReferrer.hostname === "client" || origin && !sameOrigin(parsedReferrer, this[kRealm].settingsObject.baseUrl)) { + request.referrer = "client"; + } else { + request.referrer = parsedReferrer; + } } } if (init.referrerPolicy !== void 0) { @@ -7277,7 +7322,7 @@ var require_request = __commonJS({ } } catch { } - signal.addEventListener("abort", abort, { once: true }); + util.addAbortListener(signal, abort); requestFinalizer.register(ac, { signal, abort }); } } @@ -7439,9 +7484,9 @@ var require_request = __commonJS({ if (this.signal.aborted) { ac.abort(this.signal.reason); } else { - this.signal.addEventListener("abort", () => { + util.addAbortListener(this.signal, () => { ac.abort(this.signal.reason); - }, { once: true }); + }); } clonedRequestObject[kSignal] = ac.signal; return clonedRequestObject; @@ -8118,6 +8163,7 @@ var require_request2 = __commonJS({ NotSupportedError } = require_errors(); var assert = require("assert"); + var { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = require_symbols(); var util = require_util(); var tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/; var headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; @@ -8152,7 +8198,8 @@ var require_request2 = __commonJS({ headersTimeout, bodyTimeout, reset, - throwOnError + throwOnError, + expectContinue }, handler) { if (typeof path !== "string") { throw new InvalidArgumentError("path must be a string"); @@ -8178,6 +8225,9 @@ var require_request2 = __commonJS({ if (reset != null && typeof reset !== "boolean") { throw new InvalidArgumentError("invalid reset"); } + if (expectContinue != null && typeof expectContinue !== "boolean") { + throw new InvalidArgumentError("invalid expectContinue"); + } this.headersTimeout = headersTimeout; this.bodyTimeout = bodyTimeout; this.throwOnError = throwOnError === true; @@ -8211,6 +8261,7 @@ var require_request2 = __commonJS({ this.contentLength = null; this.contentType = null; this.headers = ""; + this.expectContinue = expectContinue != null ? expectContinue : false; if (Array.isArray(headers)) { if (headers.length % 2 !== 0) { throw new InvalidArgumentError("headers array must be even"); @@ -8313,8 +8364,48 @@ var require_request2 = __commonJS({ processHeader(this, key, value); return this; } + static [kHTTP1BuildRequest](origin, opts, handler) { + return new Request(origin, opts, handler); + } + static [kHTTP2BuildRequest](origin, opts, handler) { + const headers = opts.headers; + opts = { ...opts, headers: null }; + const request = new Request(origin, opts, handler); + request.headers = {}; + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError("headers array must be even"); + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(request, headers[i], headers[i + 1], true); + } + } else if (headers && typeof headers === "object") { + const keys = Object.keys(headers); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + processHeader(request, key, headers[key], true); + } + } else if (headers != null) { + throw new InvalidArgumentError("headers must be an object or an array"); + } + return request; + } + static [kHTTP2CopyHeaders](raw) { + const rawHeaders = raw.split("\r\n"); + const headers = {}; + for (const header of rawHeaders) { + const [key, value] = header.split(": "); + if (value == null || value.length === 0) + continue; + if (headers[key]) + headers[key] += `,${value}`; + else + headers[key] = value; + } + return headers; + } }; - function processHeaderValue(key, val) { + function processHeaderValue(key, val, skipAppend) { if (val && typeof val === "object") { throw new InvalidArgumentError(`invalid ${key} header`); } @@ -8322,10 +8413,10 @@ var require_request2 = __commonJS({ if (headerCharRegex.exec(val) !== null) { throw new InvalidArgumentError(`invalid ${key} header`); } - return `${key}: ${val}\r + return skipAppend ? val : `${key}: ${val}\r `; } - function processHeader(request, key, val) { + function processHeader(request, key, val, skipAppend = false) { if (val && (typeof val === "object" && !Array.isArray(val))) { throw new InvalidArgumentError(`invalid ${key} header`); } else if (val === void 0) { @@ -8364,10 +8455,20 @@ var require_request2 = __commonJS({ } else { if (Array.isArray(val)) { for (let i = 0; i < val.length; i++) { - request.headers += processHeaderValue(key, val[i]); + if (skipAppend) { + if (request.headers[key]) + request.headers[key] += `,${processHeaderValue(key, val[i], skipAppend)}`; + else + request.headers[key] = processHeaderValue(key, val[i], skipAppend); + } else { + request.headers += processHeaderValue(key, val[i]); + } } } else { - request.headers += processHeaderValue(key, val); + if (skipAppend) + request.headers[key] = processHeaderValue(key, val, skipAppend); + else + request.headers += processHeaderValue(key, val); } } } @@ -8433,13 +8534,14 @@ var require_connect = __commonJS({ } }; } - function buildConnector({ maxCachedSessions, socketPath, timeout, ...opts }) { + function buildConnector({ allowH2, maxCachedSessions, socketPath, timeout, ...opts }) { if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) { throw new InvalidArgumentError("maxCachedSessions must be a positive integer or zero"); } const options = { path: socketPath, ...opts }; const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions); timeout = timeout == null ? 1e4 : timeout; + allowH2 = allowH2 != null ? allowH2 : false; return function connect({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) { let socket; if (protocol === "https:") { @@ -8456,6 +8558,7 @@ var require_connect = __commonJS({ servername, session, localAddress, + ALPNProtocols: allowH2 ? ["http/1.1", "h2"] : ["http/1.1"], socket: httpSocket, port: port || 443, host: hostname @@ -9029,14 +9132,14 @@ var require_redirectInterceptor = __commonJS({ // lib/llhttp/llhttp-wasm.js var require_llhttp_wasm = __commonJS({ "lib/llhttp/llhttp-wasm.js"(exports2, module2) { - module2.exports = "AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAAMBBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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EGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvc9wEDKH8DfgV/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8gASEQIAEhESABIRIgASETIAEhFCABIRUgASEWIAEhFyABIRggASEZIAEhGiABIRsgASEcIAEhHSABIR4gASEfIAEhICABISEgASEiIAEhIyABISQgASElIAEhJiABIScgASEoIAEhKQJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIipBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4B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AQtBwQEhKgsDQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJA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UGoON+cB5gEBAgMEBQYHCAAAAAAAAAAJCgsMDQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8QERITFAALQR4hKgzEAwtCAiErDOUBC0IDISsM5AELQgQhKwzjAQtCBSErDOIBC0IGISsM4QELQgchKwzgAQtCCCErDN8BC0IJISsM3gELQgohKwzdAQtCCyErDNwBC0IMISsM2wELQg0hKwzaAQtCDiErDNkBC0IPISsM2AELQgohKwzXAQtCCyErDNYBC0IMISsM1QELQg0hKwzUAQtCDiErDNMBC0IPISsM0gELQgAhKwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgKi0AAEFQag435QHkAQABAgMEBQYH5gHmAeYB5gHmAeYB5gEICQoLDA3mAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYBDg8QERIT5gELQgIhKwzkAQtCAyErDOMBC0IEISsM4gELQgUhKwzhAQtCBiErDOABC0IHISsM3wELQgghKwzeAQtCCSErDN0BC0IKISsM3AELQgshKwzbAQtCDCErDNoBC0INISsM2QELQg4hKwzYAQtCDyErDNcBC0IKISsM1gELQgshKwzVAQtCDCErDNQBC0INISsM0wELQg4hKwzSAQtCDyErDNEBCyAAQgAgACkDICIrIAIgASIqa60iLH0iLSAtICtWGzcDICArICxWIi5FDdIBQR8hKgzHAwsCQCABIgEgAkYNACAAQYmAgIAANgIIIAAgATYCBCABIQFBJCEqDK4DC0EgISoMxgMLIAAgASIqIAIQvoCAgABBf2oOBbYBAMsCAdEB0gELQREhKgyrAwsgAEEBOgAvICohAQzCAwsgASIBIAJHDdIBQSQhKgzCAwsgASInIAJHDR5BxgAhKgzBAwsgACABIgEgAhCygICAACIqDdQBIAEhAQy1AQsgASIqIAJHDSZB0AAhKgy/AwsCQCABIgEgAkcNAEEoISoMvwMLIABBADYCBCAAQYyAgIAANgIIIAAgASABELGAgIAAIioN0wEgASEBDNgBCwJAIAEiKiACRw0AQSkhKgy+AwsgKi0AACIBQSBGDRQgAUEJRw3TASAqQQFqIQEMFQsCQCABIgEgAkYNACABQQFq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AUEBaiEBIARBAWoiBCACRw0ACyAAICo2AgBBgwEhKgzoAgtBACEqIABBADYCACAuIDJrQQNqIQEMygELAkAgASIqIAJHDQBBhAEhKgznAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQYPPgIAAai0AAEcNzAEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQYQBISoM5wILIABBADYCACAqIC5rQQVqIQFBIyEqDMkBCwJAIAEiBCACRw0AQYUBISoM5gILAkACQCAELQAAQbR/ag4IAMwBzAHMAcwBzAHMAQHMAQsgBEEBaiEBQe8AISoMzQILIARBAWohAUHwACEqDMwCCwJAIAEiBCACRw0AQYYBISoM5QILIAQtAABBxQBHDckBIARBAWohAQyKAgsCQCABIiogAkcNAEGHASEqDOQCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBiM+AgABqLQAARw3JASABQQNGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBhwEhKgzkAgsgAEEANgIAICogLmtBBGohAUEtISoMxgELAkAgASIqIAJHDQBBiAEhKgzjAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQdDPgIAAai0AAEcNyAEgAUEIRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQYgBISoM4wILIABBADYCACAqIC5rQQlqIQFBKSEqDMUBCwJAIAEiASACRw0AQYkBISoM4gILQQEhKiABLQAAQd8ARw3EASABQQFqIQEMiAILAkAgASIqIAJHDQBBigEhKgzhAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQNAIAQtAAAgAUGMz4CAAGotAABHDcUBIAFBAUYNtwIgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBigEhKgzgAgsCQCABIiogAkcNAEGLASEqDOACCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBjs+AgABqLQAARw3FASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBiwEhKgzgAgsgAEEANgIAICogLmtBA2ohAUECISoMwgELAkAgASIqIAJHDQBB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AABBt39qDgcBrgGuAa4BrgGuAQCuAQsgBEEBaiEEQY4BISoMrwILIARBAWohAUEiISoMqgELAkAgDiACRw0AQaQBISoMxwILIAIgDmsgACgCACIqaiEuIA4hBCAqIQECQANAIAQtAAAgAUHAz4CAAGotAABHDawBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGkASEqDMcCCyAAQQA2AgAgDiAqa0ECaiEBQR0hKgypAQsCQCAEIAJHDQBBpQEhKgzGAgsCQAJAIAQtAABBrn9qDgMArAEBrAELIARBAWohDkGQASEqDK0CCyAEQQFqIQFBBCEqDKgBCwJAIAQgAkcNAEGmASEqDMUCCwJAAkACQAJAAkAgBC0AAEG/f2oOFQCuAa4BrgGuAa4BrgGuAa4BrgGuAQGuAa4BAq4BrgEDrgGuAQSuAQsgBEEBaiEEQYgBISoMrwILIARBAWohCkGJASEqDK4CCyAEQQFqIQtBigEhKgytAgsgBEEBaiEEQY8BISoMrAILIARBAWohBEGRASEqDKsCCwJAIA8gAkcNAEGnASEqDMQCCyACIA9rIAAoAgAiKmohLiAPIQQgKiEBAkADQCAELQAAIAFB7c+AgABqLQAARw2pASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBpwEhKgzEAgsgAEEANgIAIA8gKmtBA2ohAUERISoMpgELAkAgECACRw0AQagBISoMwwILIAIgEGsgACgCACIqaiEuIBAhBCAqIQECQANAIAQtAAAgAUHCz4CAAGotAABHDagBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEGoASEqDMMCCyAAQQA2AgAgECAqa0EDaiEBQSwhKgylAQsCQCARIAJHDQBBqQEhKgzCAgsgAiARayAAKAIAIipqIS4gESEEICohAQJAA0AgBC0AACABQcXPgIAAai0AAEcNpwEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQakBISoMwgILIABBADYCACARICprQQVqIQFBKyEqDKQBCwJAIBIgAkcNAEGqASEqDMECCyACIBJrIAAoAgAiKmohLiASIQQgKiEBAkADQCAELQAAIAFBys+AgABqLQAARw2mASABQQJGDQEgAUEBaiEB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8s+AgABqLQAARw2WASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBugEhKgyxAgsgAEEANgIAIBsgKmtBAmohAUEPISoMkwELAkAgBCACRw0AQbsBISoMsAILAkACQCAELQAAQbd/ag4HAJYBlgGWAZYBlgEBlgELIARBAWohGkGlASEqDJcCCyAEQQFqIRtBpgEhKgyWAgsCQCAcIAJHDQBBvAEhKgyvAgsgAiAcayAAKAIAIipqIS4gHCEEICohAQJAA0AgBC0AACABQfTPgIAAai0AAEcNlAEgAUEHRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbwBISoMrwILIABBADYCACAcICprQQhqIQFBGyEqDJEBCwJAIAQgAkcNAEG9ASEqDK4CCwJAAkACQCAELQAAQb5/ag4SAJUBlQGVAZUBlQGVAZUBlQGVAQGVAZUBlQGVAZUBlQEClQELIARBAWohGUGkASEqDJYCCyAEQQFqIQRBpwEhKgyVAgsgBEEBaiEcQagBISoMlAILAkAgBCACRw0AQb4BISoMrQILIAQtAABBzgBHDZEBIARBAWohBAzWAQsCQCAEIAJHDQBBvwEhKgysAgsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAELQAAQb9/ag4VAAECA6ABBAUGoAGgAaABBwgJCgugAQwNDg+gAQsgBEEBaiEBQegAISoMoQILIARBAWohAUHpACEqDKACCyAEQQFqIQFB7gAhKgyfAgsgBEEBaiEBQfIAISoMngILIARBAWohAUHzACEqDJ0CCyAEQQFqIQFB9gAhKgycAgsgBEEBaiEBQfcAISoMmwILIARBAWohAUH6ACEqDJoCCyAEQQFqIQRBgwEhKgyZAgsgBEEBaiEGQYQBISoMmAILIARBAWohB0GFASEqDJcCCyAEQQFqIQRBkgEhKgyWAgsgBEEBaiEEQZgBISoMlQILIARBAWohBEGgASEqDJQCCyAEQQFqIQRBowEhKgyTAgsgBEEBaiEEQaoBISoMkgILAkAgBCACRg0AIABBkICAgAA2AgggACAENgIEQasBISoMkgILQcABISoMqgILIAAgHSACEKqAgIAAIgENjwEgHSEBDF4LAkAgHiACRg0AIB5BAWohHQyRAQtBwgEhKgyoAgsD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NgIUIABB2o2AgAA2AhAgAEEUNgIMQQAhKgyNAgsgACgCBCEyIABBADYCBCAqICunaiIvIQEgACAyICogLyAuGyIqELWAgIAAIi5FDZMBIABBBzYCHCAAICo2AhQgACAuNgIMQQAhKgyMAgsgACAALwEwQYABcjsBMCABIQELQSohKgzxAQsgKkEVRg3ZASAAQQA2AhwgACABNgIUIABBg4yAgAA2AhAgAEETNgIMQQAhKgyJAgsgKkEVRg3XASAAQQA2AhwgACABNgIUIABBmo+AgAA2AhAgAEEiNgIMQQAhKgyIAgsgACgCBCEqIABBADYCBAJAIAAgKiABELeAgIAAIioNACABQQFqIQEMkwELIABBDDYCHCAAICo2AgwgACABQQFqNgIUQQAhKgyHAgsgKkEVRg3UASAAQQA2AhwgACABNgIUIABBmo+AgAA2AhAgAEEiNgIMQQAhKgyGAgsgACgCBCEqIABBADYCBAJAIAAgKiABELeAgIAAIioNACABQQFqIQEMkgELIABBDTYCHCAAICo2AgwgACABQQFqNgIUQQAhKgyFAgsgKkEVRg3RASAAQQA2AhwgACABNgIUIABBxoyAgAA2AhAgAEEjNgIMQQAhKgyEAgsgACgCBCEqIABBADYCBAJAIAAgKiABELmAgIAAIioNACABQQFqIQEMkQELIABBDjYCHCAAICo2AgwgACABQQFqNgIUQQAhKgyDAgsgAEEANgIcIAAgATYCFCAAQcCVgIAANgIQIABBAjYCDEEAISoMggILICpBFUYNzQEgAEEANgIcIAAgATYCFCAAQcaMgIAANgIQIABBIzYCDEEAISoMgQILIABBEDYCHCAAIAE2AhQgACAqNgIMQQAhKgyAAgsgACgCBCEEIABBADYCBAJAIAAgBCABELmAgIAAIgQNACABQQFqIQEM+AELIABBETYCHCAAIAQ2AgwgACABQQFqNgIUQQAhKgz/AQsgKkEVRg3JASAAQQA2AhwgACABNgIUIABBxoyAgAA2AhAgAEEjNgIMQQAhKgz+AQsgACgCBCEqIABBADYCBAJAIAAgKiABELmAgIAAIioNACABQQFqIQEMjgELIABBEzYCHCAAICo2AgwgACABQQFqNgIUQQAhKgz9AQsgACgCBCEEIABBADYCBAJAIAAgBCABELmAgIAAIgQNACAB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AkAgAC0AKUEjTw0AIAEhAQxcCyAAQQA2AhwgACABNgIUIABB04mAgAA2AhAgAEEINgIMQQAhKgy8AQsgAEEANgIAC0EAISogAEEANgIcIAAgATYCFCAAQZCzgIAANgIQIABBCDYCDAy6AQsgAEEANgIAIDIgL2tBA2ohAQJAIAAtAClBIUcNACABIQEMWQsgAEEANgIcIAAgATYCFCAAQZuKgIAANgIQIABBCDYCDEEAISoMuQELIABBADYCACAyIC9rQQRqIQECQCAALQApIipBXWpBC08NACABIQEMWAsCQCAqQQZLDQBBASAqdEHKAHFFDQAgASEBDFgLQQAhKiAAQQA2AhwgACABNgIUIABB94mAgAA2AhAgAEEINgIMDLgBCyAqQRVGDXUgAEEANgIcIAAgATYCFCAAQbmNgIAANgIQIABBGjYCDEEAISoMtwELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDFcLIABB5QA2AhwgACABNgIUIAAgKjYCDEEAISoMtgELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDE8LIABB0gA2AhwgACABNgIUIAAgKjYCDEEAISoMtQELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDE8LIABB0wA2AhwgACABNgIUIAAgKjYCDEEAISoMtAELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDFQLIABB5QA2AhwgACABNgIUIAAgKjYCDEEAISoMswELIABBADYCHCAAIAE2AhQgAEHGioCAADYCECAAQQc2AgxBACEqDLIBCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxLCyAAQdIANgIcIAAgATYCFCAAICo2AgxBACEqDLEBCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxLCyAAQdMANgIcIAAgATYCFCAAICo2AgxBACEqDLABCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxQCyAAQeUANgIcIAAgATYCFCAAICo2AgxBACEqDK8BCyAAQQA2AhwgACABNgIUIABB3IiAgAA2AhAgAEEHNgIMQQAhKgyuAQsgKkE/Rw0BIAFBAWohAQtBBSEqDJMBC0EAISogAEEANgIcIAAgATYCFCAAQf2SgIAANgIQIABBBzYCDAyrAQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMRAsgAEHSADYCHCAAIAE2AhQgACAqNgIMQQAhKgyqAQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMRAsgAEHTADYCHCAAIAE2AhQgACAqNgIMQQAhKgypAQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMSQsgAEHlADYCHCAAIAE2AhQgACAqNgIMQQAhKgyoAQsgACgCBCEBIABBADYCBAJAIAAgASAuEKeAgIAAIgENACAuIQEMQQsgAEHSADYCHCAAIC42AhQgACABNgIMQQAhKgynAQsgACgCBCEBIABBADYCBAJAIAAgASAuEKeAgIAAIgENACAuIQEMQQsgAEHTADYCHCAAIC42AhQgACABNgIMQQAhKgymAQsgACgCBCEBIABBADYCBAJAIAAgASAuEKeAgIAAIgENACAuIQEMRgsgAEHlADYCHCAAIC42AhQgACABNgIMQQAhKgylAQsgAEEANgIcIAAgLjYCFCAAQcOPgIAANgIQIABBBzYCDEEAISoMpAELIABBADYCHCAAIAE2AhQgAEHDj4CAADYCECAAQQc2AgxBACEqDKMBC0EAISogAEEANgIcIAAgLjYCFCAAQYycgIAANgIQIABBBzYCDAyiAQsgAEEANgIcIAAgLjYCFCAAQYycgIAANgIQIABBBzYCDEEAISoMoQELIABBADYCHCAAIC42AhQgAEH+kYCAADYCECAAQQc2AgxBACEqDKABCyAAQQA2AhwgACABNgIUIABBjpuAgAA2AhAgAEEGNgIMQQAhKgyfAQsgKkEVRg1bIABBADYCHCAAIAE2AhQgAEHMjoCAADYCECAAQSA2AgxBACEqDJ4BCyAAQQA2AgAgKiAua0EGaiEBQSQhKgsgACAqOgApIAAoAgQhKiAAQQA2AgQgACAqIAEQq4CAgAAiKg1YIAEhAQxBCyAAQQA2AgALQQAhKiAAQQA2AhwgACAENgIUIABB8ZuAgAA2AhAgAEEGNgIMDJoBCyABQRVGDVQgAEEANgIcIAAgHTYC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AgAgKiAua0ECaiEBQfUAISoMEAsgASEBAkAgAC0AKUEFRw0AQeMAISoMEAtB4gAhKgwPC0EAISogAEEANgIcIABB5JGAgAA2AhAgAEEHNgIMIAAgLkEBajYCFAwnCyAAQQA2AgAgMiAva0ECaiEBQcAAISoMDQsgASEBC0E4ISoMCwsCQCABIikgAkYNAANAAkAgKS0AAEGAvoCAAGotAAAiAUEBRg0AIAFBAkcNAyApQQFqIQEMBAsgKUEBaiIpIAJHDQALQT4hKgwkC0E+ISoMIwsgAEEAOgAsICkhAQwBC0ELISoMCAtBOiEqDAcLIAFBAWohAUEtISoMBgtBKCEqDAULIABBADYCACAvIDBrQQRqIQFBBiEqCyAAICo6ACwgASEBQQwhKgwDCyAAQQA2AgAgMiAva0EHaiEBQQohKgwCCyAAQQA2AgALIABBADoALCAnIQFBCSEqDAALC0EAISogAEEANgIcIAAgIzYCFCAAQc2QgIAANgIQIABBCTYCDAwXC0EAISogAEEANgIcIAAgIjYCFCAAQemKgIAANgIQIABBCTYCDAwWC0EAISogAEEANgIcIAAgITYCFCAAQbeQgIAANgIQIABBCTYCDAwVC0EAISogAEEANgIcIAAgIDYCFCAAQZyRgIAANgIQIABBCTYCDAwUC0EAISogAEEANgIcIAAgATYCFCAAQc2QgIAANgIQIABBCTYCDAwTC0EAISogAEEANgIcIAAgATYCFCAAQemKgIAANgIQIABBCTYCDAwSC0EAISogAEEANgIcIAAgATYCFCAAQbeQgIAANgIQIABBCTYCDAwRC0EAISogAEEANgIcIAAgATYCFCAAQZyRgIAANgIQIABBCTYCDAwQC0EAISogAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwPC0EAISogAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwOC0EAISogAEEANgIcIAAgATYCFCAAQcCSgIAANgIQIABBCzYCDAwNC0EAISogAEEANgIcIAAgATYCFCAAQZWJgIAANgIQIABBCzYCDAwMC0EAISogAEEANgIcIAAgATYCFCAAQeGPgIAANgIQIABBCjYCDAwLC0EAISogAEEANgIcIAAgATYCFCAAQfuPgIAANgIQIABBCjYCDAwKC0EA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AAAABQAAAAAAAAAAAAAABgAAAAcAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJbnZhbGlkIGNoYXIgaW4gdXJsIHF1ZXJ5AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fYm9keQBDb250ZW50LUxlbmd0aCBvdmVyZmxvdwBDaHVuayBzaXplIG92ZXJmbG93AFJlc3BvbnNlIG92ZXJmbG93AEludmFsaWQgbWV0aG9kIGZvciBIVFRQL3gueCByZXF1ZXN0AEludmFsaWQgbWV0aG9kIGZvciBSVFNQL3gueCByZXF1ZXN0AEV4cGVjdGVkIFNPVVJDRSBtZXRob2QgZm9yIElDRS94LnggcmVxdWVzdABJbnZhbGlkIGNoYXIgaW4gdXJsIGZyYWdtZW50IHN0YXJ0AEV4cGVjdGVkIGRvdABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3N0YXR1cwBJbnZhbGlkIHJlc3BvbnNlIHN0YXR1cwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zAFVzZXIgY2FsbGJhY2sgZXJyb3IAYG9uX3Jlc2V0YCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfaGVhZGVyYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9iZWdpbmAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3N0YXR1c19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3ZlcnNpb25fY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl91cmxfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXRob2RfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfZmllbGRfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fbmFtZWAgY2FsbGJhY2sgZXJyb3IAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzZXJ2ZXIASW52YWxpZCBoZWFkZXIgdmFsdWUgY2hhcgBJbnZhbGlkIGhlYWRlciBmaWVsZCBjaGFyAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdmVyc2lvbgBJbnZhbGlkIG1pbm9yIHZlcnNpb24ASW52YWxpZCBtYWpvciB2ZXJzaW9uAEV4cGVjdGVkIHNwYWNlIGFmdGVyIHZlcnNpb24ARXhwZWN0ZWQgQ1JMRiBhZnRlciB2ZXJzaW9uAEludmFsaWQgSFRUUCB2ZXJzaW9uAEludmFsaWQgaGVhZGVyIHRva2VuAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fdXJsAEludmFsaWQgY2hhcmFjdGVycyBpbiB1cmwAVW5leHBlY3RlZCBzdGFydCBjaGFyIGluIHVybABEb3VibGUgQCBpbiB1cmwARW1wdHkgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyYWN0ZXIgaW4gQ29udGVudC1MZW5ndGgARHVwbGljYXRlIENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhciBpbiB1cmwgcGF0aABDb250ZW50LUxlbmd0aCBjYW4ndCBiZSBwcmVzZW50IHdpdGggVHJhbnNmZXItRW5jb2RpbmcASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgc2l6ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl92YWx1ZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHZhbHVlAE1pc3NpbmcgZXhwZWN0ZWQgTEYgYWZ0ZXIgaGVhZGVyIHZhbHVlAEludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYCBoZWFkZXIgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZSB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlZCB2YWx1ZQBQYXVzZWQgYnkgb25faGVhZGVyc19jb21wbGV0ZQBJbnZhbGlkIEVPRiBzdGF0ZQBvbl9yZXNldCBwYXVzZQBvbl9jaHVua19oZWFkZXIgcGF1c2UAb25fbWVzc2FnZV9iZWdpbiBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fdmFsdWUgcGF1c2UAb25fc3RhdHVzX2NvbXBsZXRlIHBhdXNlAG9uX3ZlcnNpb25fY29tcGxldGUgcGF1c2UAb25fdXJsX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl92YWx1ZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXNzYWdlX2NvbXBsZXRlIHBhdXNlAG9uX21ldGhvZF9jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfZmllbGRfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUgcGF1c2UAVW5leHBlY3RlZCBzcGFjZSBhZnRlciBzdGFydCBsaW5lAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX25hbWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBuYW1lAFBhdXNlIG9uIENPTk5FQ1QvVXBncmFkZQBQYXVzZSBvbiBQUkkvVXBncmFkZQBFeHBlY3RlZCBIVFRQLzIgQ29ubmVjdGlvbiBQcmVmYWNlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fbWV0aG9kAEV4cGVjdGVkIHNwYWNlIGFmdGVyIG1ldGhvZABTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2hlYWRlcl9maWVsZABQYXVzZWQASW52YWxpZCB3b3JkIGVuY291bnRlcmVkAEludmFsaWQgbWV0aG9kIGVuY291bnRlcmVkAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2NoZW1hAFJlcXVlc3QgaGFzIGludmFsaWQgYFRyYW5zZmVyLUVuY29kaW5nYABTV0lUQ0hfUFJPWFkAVVNFX1BST1hZAE1LQUNUSVZJVFkAVU5QUk9DRVNTQUJMRV9FTlRJVFkAQ09QWQBNT1ZFRF9QRVJNQU5FTlRMWQBUT09fRUFSTFkATk9USUZZAEZBSUxFRF9ERVBFTkRFTkNZAEJBRF9HQVRFV0FZAFBMQVkAUFVUAENIRUNLT1VUAEdBVEVXQVlfVElNRU9VVABSRVFVRVNUX1RJTUVPVVQATkVUV09SS19DT05ORUNUX1RJTUVPVVQAQ09OTkVDVElPTl9USU1FT1VUAExPR0lOX1RJTUVPVVQATkVUV09SS19SRUFEX1RJTUVPVVQAUE9TVABNSVNESVJFQ1RFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX0xPQURfQkFMQU5DRURfUkVRVUVTVABCQURfUkVRVUVTVABIVFRQX1JFUVVFU1RfU0VOVF9UT19IVFRQU19QT1JUAFJFUE9SVABJTV9BX1RFQVBPVABSRVNFVF9DT05URU5UAE5PX0NPTlRFTlQAUEFSVElBTF9DT05URU5UAEhQRV9JTlZBTElEX0NPTlNUQU5UAEhQRV9DQl9SRVNFVABHRVQASFBFX1NUUklDVABDT05GTElDVABURU1QT1JBUllfUkVESVJFQ1QAUEVSTUFORU5UX1JFRElSRUNUAENPTk5FQ1QATVVMVElfU1RBVFVTAEhQRV9JTlZBTElEX1NUQVRVUwBUT09fTUFOWV9SRVFVRVNUUwBFQVJMWV9ISU5UUwBVTkFWQUlMQUJMRV9GT1JfTEVHQUxfUkVBU09OUwBPUFRJT05TAFNXSVRDSElOR19QUk9UT0NPTFMAVkFSSUFOVF9BTFNPX05FR09USUFURVMATVVMVElQTEVfQ0hPSUNFUwBJTlRFUk5BTF9TRVJWRVJfRVJST1IAV0VCX1NFUlZFUl9VTktOT1dOX0VSUk9SAFJBSUxHVU5fRVJST1IASURFTlRJVFlfUFJPVklERVJfQVVUSEVOVElDQVRJT05fRVJST1IAU1NMX0NFUlRJRklDQVRFX0VSUk9SAElOVkFMSURfWF9GT1JXQVJERURfRk9SAFNFVF9QQVJBTUVURVIAR0VUX1BBUkFNRVRFUgBIUEVfVVNFUgBTRUVfT1RIRVIASFBFX0NCX0NIVU5LX0hFQURFUgBNS0NBTEVOREFSAFNFVFVQAFdFQl9TRVJWRVJfSVNfRE9XTgBURUFSRE9XTgBIUEVfQ0xPU0VEX0NPTk5FQ1RJT04ASEVVUklTVElDX0VYUElSQVRJT04ARElTQ09OTkVDVEVEX09QRVJBVElPTgBOT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTgBIUEVfSU5WQUxJRF9WRVJTSU9OAEhQRV9DQl9NRVNTQUdFX0JFR0lOAFNJVEVfSVNfRlJPWkVOAEhQRV9JTlZBTElEX0hFQURFUl9UT0tFTgBJTlZBTElEX1RPS0VOAEZPUkJJRERFTgBFTkhBTkNFX1lPVVJfQ0FMTQBIUEVfSU5WQUxJRF9VUkwAQkxPQ0tFRF9CWV9QQVJFTlRBTF9DT05UUk9MAE1LQ09MAEFDTABIUEVfSU5URVJOQUwAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRV9VTk9GRklDSUFMAEhQRV9PSwBVTkxJTksAVU5MT0NLAFBSSQBSRVRSWV9XSVRIAEhQRV9JTlZBTElEX0NPTlRFTlRfTEVOR1RIAEhQRV9VTkVYUEVDVEVEX0NPTlRFTlRfTEVOR1RIAEZMVVNIAFBST1BQQVRDSABNLVNFQVJDSABVUklfVE9PX0xPTkcAUFJPQ0VTU0lORwBNSVNDRUxMQU5FT1VTX1BFUlNJU1RFTlRfV0FSTklORwBNSVNDRUxMQU5FT1VTX1dBUk5JTkcASFBFX0lOVkFMSURfVFJBTlNGRVJfRU5DT0RJTkcARXhwZWN0ZWQgQ1JMRgBIUEVfSU5WQUxJRF9DSFVOS19TSVpFAE1PVkUAQ09OVElOVUUASFBFX0NCX1NUQVRVU19DT01QTEVURQBIUEVfQ0JfSEVBREVSU19DT01QTEVURQBIUEVfQ0JfVkVSU0lPTl9DT01QTEVURQBIUEVfQ0JfVVJMX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19DT01QTEVURQBIUEVfQ0JfSEVBREVSX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9OQU1FX0NPTVBMRVRFAEhQRV9DQl9NRVNTQUdFX0NPTVBMRVRFAEhQRV9DQl9NRVRIT0RfQ09NUExFVEUASFBFX0NCX0hFQURFUl9GSUVMRF9DT01QTEVURQBERUxFVEUASFBFX0lOVkFMSURfRU9GX1NUQVRFAElOVkFMSURfU1NMX0NFUlRJRklDQVRFAFBBVVNFAE5PX1JFU1BPTlNFAFVOU1VQUE9SVEVEX01FRElBX1RZUEUAR09ORQBOT1RfQUNDRVBUQUJMRQBTRVJWSUNFX1VOQVZBSUxBQkxFAFJBTkdFX05PVF9TQVRJU0ZJQUJMRQBPUklHSU5fSVNfVU5SRUFDSEFCTEUAUkVTUE9OU0VfSVNfU1RBTEUAUFVSR0UATUVSR0UAUkVRVUVTVF9IRUFERVJfRklFTERTX1RPT19MQVJHRQBSRVFVRVNUX0hFQURFUl9UT09fTEFSR0UAUEFZTE9BRF9UT09fTEFSR0UASU5TVUZGSUNJRU5UX1NUT1JBR0UASFBFX1BBVVNFRF9VUEdSQURFAEhQRV9QQVVTRURfSDJfVVBHUkFERQBTT1VSQ0UAQU5OT1VOQ0UAVFJBQ0UASFBFX1VORVhQRUNURURfU1BBQ0UAREVTQ1JJQkUAVU5TVUJTQ1JJQkUAUkVDT1JEAEhQRV9JTlZBTElEX01FVEhPRABOT1RfRk9VTkQAUFJPUEZJTkQAVU5CSU5EAFJFQklORABVTkFVVEhPUklaRUQATUVUSE9EX05PVF9BTExPV0VEAEhUVFBfVkVSU0lPTl9OT1RfU1VQUE9SVEVEAEFMUkVBRFlfUkVQT1JURUQAQUNDRVBURUQATk9UX0lNUExFTUVOVEVEAExPT1BfREVURUNURUQASFBFX0NSX0VYUEVDVEVEAEhQRV9MRl9FWFBFQ1RFRABDUkVBVEVEAElNX1VTRUQASFBFX1BBVVNFRABUSU1FT1VUX09DQ1VSRUQAUEFZTUVOVF9SRVFVSVJFRABQUkVDT05ESVRJT05fUkVRVUlSRUQAUFJPWFlfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATkVUV09SS19BVVRIRU5USUNBVElPTl9SRVFVSVJFRABMRU5HVEhfUkVRVUlSRUQAU1NMX0NFUlRJRklDQVRFX1JFUVVJUkVEAFVQR1JBREVfUkVRVUlSRUQAUEFHRV9FWFBJUkVEAFBSRUNPTkRJVElPTl9GQUlMRUQARVhQRUNUQVRJT05fRkFJTEVEAFJFVkFMSURBVElPTl9GQUlMRUQAU1NMX0hBTkRTSEFLRV9GQUlMRUQATE9DS0VEAFRSQU5TRk9STUFUSU9OX0FQUExJRUQATk9UX01PRElGSUVEAE5PVF9FWFRFTkRFRABCQU5EV0lEVEhfTElNSVRfRVhDRUVERUQAU0lURV9JU19PVkVSTE9BREVEAEhFQUQARXhwZWN0ZWQgSFRUUC8AAF4TAAAmEwAAMBAAAPAXAACdEwAAFRIAADkXAADwEgAAChAAAHUSAACtEgAAghMAAE8UAAB/EAAAoBUAACMUAACJEgAAixQAAE0VAADUEQAAzxQAABAYAADJFgAA3BYAAMERAADgFwAAuxQAAHQUAAB8FQAA5RQAAAgXAAAfEAAAZRUAAKMUAAAoFQAAAhUAAJkVAAAsEAAAixkAAE8PAADUDgAAahAAAM4QAAACFwAAiQ4AAG4TAAAcEwAAZhQAAFYXAADBEwAAzRMAAGwTAABoFwAAZhcAAF8XAAAiEwAAzg8AAGkOAADYDgAAYxYAAMsTAACqDgAAKBcAACYXAADFEwAAXRYAAOgRAABnEwAAZRMAAPIWAABzEwAAHRcAAPkWAADzEQAAzw4AAM4VAAAMEgAAsxEAAKURAABhEAAAMhcAALsTAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAwICAgICAAACAgACAgACAgICAgICAgICAAQAAAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgACAgICAgAAAgIAAgIAAgICAgICAgICAgADAAQAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxvc2VlZXAtYWxpdmUAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAWNodW5rZWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAAABAQABAQABAQEBAQEBAQEBAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZWN0aW9uZW50LWxlbmd0aG9ucm94eS1jb25uZWN0aW9uAAAAAAAAAAAAAAAAAAAAcmFuc2Zlci1lbmNvZGluZ3BncmFkZQ0KDQoNClNNDQoNClRUUC9DRS9UU1AvAAAAAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBBQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAEAAAIAAAAAAAAAAAAAAAAAAAAAAAADBAAABAQEBAQEBAQEBAQFBAQEBAQEBAQEBAQEAAQABgcEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAACAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATk9VTkNFRUNLT1VUTkVDVEVURUNSSUJFTFVTSEVURUFEU0VBUkNIUkdFQ1RJVklUWUxFTkRBUlZFT1RJRllQVElPTlNDSFNFQVlTVEFUQ0hHRU9SRElSRUNUT1JUUkNIUEFSQU1FVEVSVVJDRUJTQ1JJQkVBUkRPV05BQ0VJTkROS0NLVUJTQ1JJQkVIVFRQL0FEVFAv"; + module2.exports = "AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAC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FCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAU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YWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8="; } }); // lib/llhttp/llhttp_simd-wasm.js var require_llhttp_simd_wasm = __commonJS({ "lib/llhttp/llhttp_simd-wasm.js"(exports2, module2) { - module2.exports = "AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAAMBBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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ACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC9z3AQMofwN+BX8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDyABIRAgASERIAEhEiABIRMgASEUIAEhFSABIRYgASEXIAEhGCABIRkgASEaIAEhGyABIRwgASEdIAEhHiABIR8gASEgIAEhISABISIgASEjIAEhJCABISUgASEmIAEhJyABISggASEpAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAAoAhwiKkF/ag7dAdoBAdkBAgMEBQYHCAkKCwwNDtgBDxDXARES1gETFBUWFxgZGhvgAd8BHB0e1QEfICEiIyQl1AEmJygpKiss0wHSAS0u0QHQAS8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRtsBR0hJSs8BzgFLzQFMzAFNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AAYEBggGDAYQBhQGGAYcBiAGJAYoBiwGMAY0BjgGPAZABkQGSAZMBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBywHKAbgByQG5AcgBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgEA3AELQQAhKgzGAQtBDiEqDMUBC0ENISoMxAELQQ8hKgzDAQtBECEqDMIBC0ETISoMwQELQRQhKgzAAQtBFSEqDL8BC0EWISoMvgELQRchKgy9AQtBGCEqDLwBC0EZISoMuwELQRohKgy6AQtBGyEqDLkBC0EcISoMuAELQQghKgy3AQtBHSEqDLYBC0EgISoMtQELQR8hKgy0AQtBByEqDLMBC0EhISoMsgELQSIhKgyxAQtBHiEqDLABC0EjISoMrwELQRIhKgyuAQtBESEqDK0BC0EkISoMrAELQSUhKgyrAQtBJiEqDKoBC0EnISoMqQELQcMBISoMqAELQSkhKgynAQtBKyEqDKYBC0EsISoMpQELQS0hKgykAQtBLiEqDKMBC0EvISoMogELQcQBISoMoQELQTAhKgygAQtBNCEqDJ8BC0EMISoMngELQTEhKgydAQtBMiEqDJwBC0EzISoMmwELQTkhKgyaAQtBNSEqDJkBC0HFASEqDJgBC0ELISoMlwELQTohKgyWAQtBNiEqDJUBC0EKISoMlAELQTchKgyTAQtBOCEqDJIBC0E8ISoMkQELQTshKgyQAQtBPSEqDI8BC0EJISoMjgELQSghKgyNAQtBPiEqDIwBC0E/ISoMiwELQcAAISoMigELQcEAISoMiQELQcIAISoMiAELQcMAISoMhwELQcQAISoMhgELQcUAISoMhQELQcYAISoMhAELQSohKgyDAQtBxwAhKgyCAQtByAAhKgyBAQtByQAhKgyAAQtBygAhKgx/C0HLACEqDH4LQc0AISoMfQtBzAAhKgx8C0HOACEqDHsLQc8AISoMegtB0AAhKgx5C0HRACEqDHgLQdIAISoMdwtB0wAhKgx2C0HUACEqDHULQdYAISoMdAtB1QAhKgxzC0EGISoMcgtB1wAhKgxxC0EFISoMcAtB2AAhKgxvC0EEISoMbgtB2QAhKgxtC0HaACEqDGwLQdsAISoMawtB3AAhKgxqC0EDISoMaQtB3QAhKgxoC0HeACEqDGcLQd8AISoMZgtB4QAhKgxlC0HgACEqDGQLQeIAISoMYwtB4wAhKgxiC0ECISoMYQtB5AAhKgxgC0HlACEqDF8LQeYAISoMXgtB5wAhKgxdC0HoACEqDFwLQekAISoMWwtB6gAhKgxaC0HrACEqDFkLQewAISoMWAtB7QAhKgxXC0HuACEqDFYLQe8AISoMVQtB8AAhKgxUC0HxACEqDFMLQfIAISoMUgtB8wAhKgxRC0H0ACEqDFALQfUAISoMTwtB9gAhKgxOC0H3ACEqDE0LQfgAISoMTAtB+QAhKgxLC0H6ACEqDEoLQfsAISoMSQtB/AAhKgxIC0H9ACEqDEcLQf4AISoMRgtB/wAhKgxFC0GAASEqDEQLQYEBISoMQwtBggEhKgxCC0GDASEqDEELQYQBISoMQAtBhQEhKgw/C0GGASEqDD4LQYcBISoMPQtBiAEhKgw8C0GJASEqDDsLQYoBISoMOgtBiwEhKgw5C0GMASEqDDgLQY0BISoMNwtBjgEhKgw2C0GPASEqDDULQZABISoMNAtBkQEhKgwzC0GSASEqDDILQZMBISoMMQtBlAEhKgwwC0GVASEqDC8LQZYBISoMLgtBlwEhKgwtC0GYASEqDCwLQZkBISoMKwtBmgEhKgwqC0GbASEqDCkLQZwBISoMKAtBnQEhKgwnC0GeASEqDCYLQZ8BISoMJQtBoAEhKgwkC0GhASEqDCMLQaIBISoMIgtBowEhKgwhC0GkASEqDCALQaUBISoMHwtBpgEhKgweC0GnASEqDB0LQagBISoMHAtBqQEhKgwbC0GqASEqDBoLQasBISoMGQtBrAEhKgwYC0GtASEqDBcLQa4BISoMFgtBASEqDBULQa8BISoMFAtBsAEhKgwTC0GxASEqDBILQbMBISoMEQtBsgEhKgwQC0G0ASEqDA8LQbUBISoMDgtBtgEhKgwNC0G3ASEqDAwLQbgBISoMCwtBuQEhKgwKC0G6ASEqDAkLQbsBISoMCAtBxgEhKgwHC0G8ASEqDAYLQb0BISoMBQtBvgEhKgwEC0G/ASEqDAMLQcABISoMAgtBwgEhKgwBC0HBASEqCwNAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJA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AAAAAAAAAAkKCwwNDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxAREhMUAAtBHiEqDMQDC0ICISsM5QELQgMhKwzkAQtCBCErDOMBC0IFISsM4gELQgYhKwzhAQtCByErDOABC0IIISsM3wELQgkhKwzeAQtCCiErDN0BC0ILISsM3AELQgwhKwzbAQtCDSErDNoBC0IOISsM2QELQg8hKwzYAQtCCiErDNcBC0ILISsM1gELQgwhKwzVAQtCDSErDNQBC0IOISsM0wELQg8hKwzSAQtCACErAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAqLQAAQVBqDjflAeQBAAECAwQFBgfmAeYB5gHmAeYB5gHmAQgJCgsMDeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gEODxAREhPmAQtCAiErDOQBC0IDISsM4wELQgQhKwziAQtCBSErDOEBC0IGISsM4AELQgchKwzfAQtCCCErDN4BC0IJISsM3QELQgohKwzcAQtCCyErDNsBC0IMISsM2gELQg0hKwzZAQtCDiErDNgBC0IPISsM1wELQgohKwzWAQtCCyErDNUBC0IMISsM1AELQg0hKwzTAQtCDiErDNIBC0IPISsM0QELIABCACAAKQMgIisgAiABIiprrSIsfSItIC0gK1YbNwMgICsgLFYiLkUN0gFBHyEqDMcDCwJAIAEiASACRg0AIABBiYCAgAA2AgggACABNgIEIAEhAUEkISoMrgMLQSAhKgzGAwsgACABIiogAhC+gICAAEF/ag4FtgEAywIB0QHSAQtBESEqDKsDCyAAQQE6AC8gKiEBDMIDCyABIgEgAkcN0gFBJCEqDMIDCyABIicgAkcNHkHGACEqDMEDCyAAIAEiASACELKAgIAAIioN1AEgASEBDLUBCyABIiogAkcNJkHQACEqDL8DCwJAIAEiASACRw0AQSghKgy/AwsgAEEANgIEIABBjICAgAA2AgggACABIAEQsYCAgAAiKg3TASABIQEM2AELAkAgASIqIAJHDQBBKSEqDL4DCyAqLQAAIgFBIEYNFCABQQlHDdMBICpBAWohAQwVCwJAIAEiASACRg0AIAFBAWohAQwXC0EqISoMvAMLAkAg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DQALIAAgKjYCAEGDASEqDOgCC0EAISogAEEANgIAIC4gMmtBA2ohAQzKAQsCQCABIiogAkcNAEGEASEqDOcCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBg8+AgABqLQAARw3MASABQQRGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBhAEhKgznAgsgAEEANgIAICogLmtBBWohAUEjISoMyQELAkAgASIEIAJHDQBBhQEhKgzmAgsCQAJAIAQtAABBtH9qDggAzAHMAcwBzAHMAcwBAcwBCyAEQQFqIQFB7wAhKgzNAgsgBEEBaiEBQfAAISoMzAILAkAgASIEIAJHDQBBhgEhKgzlAgsgBC0AAEHFAEcNyQEgBEEBaiEBDIoCCwJAIAEiKiACRw0AQYcBISoM5AILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUGIz4CAAGotAABHDckBIAFBA0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGHASEqDOQCCyAAQQA2AgAgKiAua0EEaiEBQS0hKgzGAQsCQCABIiogAkcNAEGIASEqDOMCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFB0M+AgABqLQAARw3IASABQQhGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBiAEhKgzjAgsgAEEANgIAICogLmtBCWohAUEpISoMxQELAkAgASIBIAJHDQBBiQEhKgziAgtBASEqIAEtAABB3wBHDcQBIAFBAWohAQyIAgsCQCABIiogAkcNAEGKASEqDOECCyACICprIAAoAgAiLmohMiAqIQQgLiEBA0AgBC0AACABQYzPgIAAai0AAEcNxQEgAUEBRg23AiABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGKASEqDOACCwJAIAEiKiACRw0AQYsBISoM4AILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUGOz4CAAGotAABHDcUBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGLASEqDOACCyAAQQA2AgAgKiAua0EDaiEBQQIhKgzCAQsCQCABIiogAkcNAEGMASEqDN8CCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFB8M+AgABqLQAARw3EASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBjAEhKgzfAgsgAEEANgIAICogLmtBAmohAUEfISoMwQELAkAgASIqIAJHDQBBjQEhKgzeAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQfLPgIAAai0AAEcNwwEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQY0BISoM3gILIABBADYCACAqIC5rQQJqIQFBCSEqDMABCwJAIAEiBCACRw0AQY4BISoM3QILAkACQCAELQAAQbd/ag4HAMMBwwHDAcMBwwEBwwELIARBAWohAUH4ACEqDMQCCyAEQQFqIQFB+QAhKgzDAgsCQCABIiogAkcNAEGPASEqDNwCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBkc+AgABqLQAARw3BASABQQVGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBjwEhKgzcAgsgAEEANgIAICogLmtBBmohAUEYISoMvgELAkAgASIqIAJHDQBBkAEhKgzbAgsgAiAqayAAKAIAIi5qITIgKiEEIC4hAQJAA0AgBC0AACABQZfPgIAAai0AAEcNwAEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAyNgIAQZABISoM2wILIABBADYCACAqIC5rQQNqIQFBFyEqDL0BCwJAIAEiKiACRw0AQZEBISoM2gILIAIgKmsgACgCACIuaiEyICohBCAuIQECQANAIAQtAAAgAUGaz4CAAGotAABHDb8BIAFBBkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgMjYCAEGRASEqDNoCCyAAQQA2AgAgKiAua0EHaiEBQRUhKgy8AQsCQCABIiogAkcNAEGSASEqDNkCCyACICprIAAoAgAiLmohMiAqIQQgLiEBAkADQCAELQAAIAFBoc+AgABqLQAARw2+ASABQQVGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIDI2AgBBkgEhKgzZAgsgAEEANgIAICogLmtBBmohAUEeISoMuwELAkAgASIEIAJHDQBBkwEhKgzYAgsgBC0AAEHMAEcN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LjYCAEGqASEqDMECCyAAQQA2AgAgEiAqa0EDaiEBQRQhKgyjAQsCQCAEIAJHDQBBqwEhKgzAAgsCQAJAAkACQCAELQAAQb5/ag4PAAECqAGoAagBqAGoAagBqAGoAagBqAGoAQOoAQsgBEEBaiEPQZMBISoMqQILIARBAWohEEGUASEqDKgCCyAEQQFqIRFBlQEhKgynAgsgBEEBaiESQZYBISoMpgILAkAgBCACRw0AQawBISoMvwILIAQtAABBxQBHDaMBIARBAWohBAznAQsCQCATIAJHDQBBrQEhKgy+AgsgAiATayAAKAIAIipqIS4gEyEEICohAQJAA0AgBC0AACABQc3PgIAAai0AAEcNowEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQa0BISoMvgILIABBADYCACATICprQQNqIQFBDiEqDKABCwJAIAQgAkcNAEGuASEqDL0CCyAELQAAQdAARw2hASAEQQFqIQFBJSEqDJ8BCwJAIBQgAkcNAEGvASEqDLwCCyACIBRrIAAoAgAiKmohLiAUIQQgKiEBAkADQCAELQAAIAFB0M+AgABqLQAARw2hASABQQhGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBrwEhKgy8AgsgAEEANgIAIBQgKmtBCWohAUEqISoMngELAkAgBCACRw0AQbABISoMuwILAkACQCAELQAAQat/ag4LAKEBoQGhAaEBoQGhAaEBoQGhAQGhAQsgBEEBaiEEQZoBISoMogILIARBAWohFEGbASEqDKECCwJAIAQgAkcNAEGxASEqDLoCCwJAAkAgBC0AAEG/f2oOFACgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAEBoAELIARBAWohE0GZASEqDKECCyAEQQFqIQRBnAEhKgygAgsCQCAVIAJHDQBBsgEhKgy5AgsgAiAVayAAKAIAIipqIS4gFSEEICohAQJAA0AgBC0AACABQdnPgIAAai0AAEcNngEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbIBISoMuQILIABBADYCACAVICprQQRqIQFBISEqDJsBCwJAIBYgAkcNAEGzASEqDLgCCyACIBZrIAAoAgAiKmohLiAWIQQgKiEBAkADQCAELQAAIAFB3c+AgABqLQAARw2dASABQQZGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBswEhKgy4AgsgAEEANgIAIBYgKmtBB2ohAUEaISoMmgELAkAgBCACRw0AQbQBISoMtwILAkACQAJAIAQtAABBu39qDhEAngGeAZ4BngGeAZ4BngGeAZ4BAZ4BngGeAZ4BngECngELIARBAWohBEGdASEqDJ8CCyAEQQFqIRVBngEhKgyeAgsgBEEBaiEWQZ8BISoMnQILAkAgFyACRw0AQbUBISoMtgILIAIgF2sgACgCACIqaiEuIBchBCAqIQECQANAIAQtAAAgAUHkz4CAAGotAABHDZsBIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgLjYCAEG1ASEqDLYCCyAAQQA2AgAgFyAqa0EGaiEBQSghKgyYAQsCQCAYIAJHDQBBtgEhKgy1AgsgAiAYayAAKAIAIipqIS4gGCEEICohAQJAA0AgBC0AACABQerPgIAAai0AAEcNmgEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbYBISoMtQILIABBADYCACAYICprQQNqIQFBByEqDJcBCwJAIAQgAkcNAEG3ASEqDLQCCwJAAkAgBC0AAEG7f2oODgCaAZoBmgGaAZoBmgGaAZoBmgGaAZoBmgEBmgELIARBAWohF0GhASEqDJsCCyAEQQFqIRhBogEhKgyaAgsCQCAZIAJHDQBBuAEhKgyzAgsgAiAZayAAKAIAIipqIS4gGSEEICohAQJAA0AgBC0AACABQe3PgIAAai0AAEcNmAEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAuNgIAQbgBISoMswILIABBADYCACAZICprQQNqIQFBEiEqDJUBCwJAIBogAkcNAEG5ASEqDLICCyACIBprIAAoAgAiKmohLiAaIQQgKiEBAkADQCAELQAAIAFB8M+AgABqLQAARw2XASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIC42AgBBuQEhKgyyAgsgAEEANgIAIBogKmtBAmohAUEgISoMlAELAkAgGyACRw0AQboBISoMsQILIAIgG2sgACgCACIqaiEuIBshBCAqIQECQANAIAQtAAAgAUHyz4CAAGotAABHDZYBIAFB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DM4BCyAAQQA2AhwgACABNgIUIABBoJmAgAA2AhAgAEEeNgIMQQAhKgzNAQsgAUEBaiEBCyAAQYASOwEqIAAgASACEKiAgIAAIioNASABIQELQccAISoMsQELICpBFUcNiQEgAEHRADYCHCAAIAE2AhQgAEHjl4CAADYCECAAQRU2AgxBACEqDMkBCyAAKAIEISogAEEANgIEAkAgACAqIAEQp4CAgAAiKg0AIAEhAQxiCyAAQdIANgIcIAAgATYCFCAAICo2AgxBACEqDMgBCyAAQQA2AhwgACAuNgIUIABBwaiAgAA2AhAgAEEHNgIMIABBADYCAEEAISoMxwELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDGELIABB0wA2AhwgACABNgIUIAAgKjYCDEEAISoMxgELQQAhKiAAQQA2AhwgACABNgIUIABBgJGAgAA2AhAgAEEJNgIMDMUBCyAqQRVGDYMBIABBADYCHCAAIAE2AhQgAEGUjYCAADYCECAAQSE2AgxBACEqDMQBC0EBIS9BACEyQQAhLkEBISoLIAAgKjoAKyABQQFqIQECQAJAIAAtAC1BEHENAAJAAkACQCAALQAqDgMBAAIECyAvRQ0DDAILIC4NAQwCCyAyRQ0BCyAAKAIEISogAEEANgIEAkAgACAqIAEQrYCAgAAiKg0AIAEhAQxgCyAAQdgANgIcIAAgATYCFCAAICo2AgxBACEqDMMBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQrYCAgAAiBA0AIAEhAQyyAQsgAEHZADYCHCAAIAE2AhQgACAENgIMQQAhKgzCAQsgACgCBCEEIABBADYCBAJAIAAgBCABEK2AgIAAIgQNACABIQEMsAELIABB2gA2AhwgACABNgIUIAAgBDYCDEEAISoMwQELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARCtgICAACIEDQAgASEBDK4BCyAAQdwANgIcIAAgATYCFCAAIAQ2AgxBACEqDMABC0EBISoLIAAgKjoAKiABQQFqIQEMXAsgACgCBCEEIABBADYCBAJAIAAgBCABEK2AgIAAIgQNACABIQEMqgELIABB3gA2AhwgACABNgIUIAAgBDYCDEEAISoMvQELIABBADYCACAyIC9rQQRqIQECQCAALQApQSNPDQAgASEBDFwLIABBADYCHCAAIAE2AhQgAEHTiYCAADYCECAAQQg2AgxBACEqDLwBCyAAQQA2AgALQQAhKiAAQQA2AhwgACABNgIUIABBkLOAgAA2AhAgAEEINgIMDLoBCyAAQQA2AgAgMiAva0EDaiEBAkAgAC0AKUEhRw0AIAEhAQxZCyAAQQA2AhwgACABNgIUIABBm4qAgAA2AhAgAEEINgIMQQAhKgy5AQsgAEEANgIAIDIgL2tBBGohAQJAIAAtACkiKkFdakELTw0AIAEhAQxYCwJAICpBBksNAEEBICp0QcoAcUUNACABIQEMWAtBACEqIABBADYCHCAAIAE2AhQgAEH3iYCAADYCECAAQQg2AgwMuAELICpBFUYNdSAAQQA2AhwgACABNgIUIABBuY2AgAA2AhAgAEEaNgIMQQAhKgy3AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMVwsgAEHlADYCHCAAIAE2AhQgACAqNgIMQQAhKgy2AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMTwsgAEHSADYCHCAAIAE2AhQgACAqNgIMQQAhKgy1AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMTwsgAEHTADYCHCAAIAE2AhQgACAqNgIMQQAhKgy0AQsgACgCBCEqIABBADYCBAJAIAAgKiABEKeAgIAAIioNACABIQEMVAsgAEHlADYCHCAAIAE2AhQgACAqNgIMQQAhKgyzAQsgAEEANgIcIAAgATYCFCAAQcaKgIAANgIQIABBBzYCDEEAISoMsgELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDEsLIABB0gA2AhwgACABNgIUIAAgKjYCDEEAISoMsQELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDEsLIABB0wA2AhwgACABNgIUIAAgKjYCDEEAISoMsAELIAAoAgQhKiAAQQA2AgQCQCAAICogARCngICAACIqDQAgASEBDFALIABB5QA2AhwgACABNgIUIAAgKjYCDEEAISoMrwELIABBADYCHCAAIAE2AhQgAEHciICAADYCECAAQQc2AgxBACEqDK4BCyAqQT9HDQEgAUEBaiEB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AAAABwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEludmFsaWQgY2hhciBpbiB1cmwgcXVlcnkAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9ib2R5AENvbnRlbnQtTGVuZ3RoIG92ZXJmbG93AENodW5rIHNpemUgb3ZlcmZsb3cAUmVzcG9uc2Ugb3ZlcmZsb3cASW52YWxpZCBtZXRob2QgZm9yIEhUVFAveC54IHJlcXVlc3QASW52YWxpZCBtZXRob2QgZm9yIFJUU1AveC54IHJlcXVlc3QARXhwZWN0ZWQgU09VUkNFIG1ldGhvZCBmb3IgSUNFL3gueCByZXF1ZXN0AEludmFsaWQgY2hhciBpbiB1cmwgZnJhZ21lbnQgc3RhcnQARXhwZWN0ZWQgZG90AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fc3RhdHVzAEludmFsaWQgcmVzcG9uc2Ugc3RhdHVzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fcmVzZXRgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19oZWFkZXJgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8="; + module2.exports = "AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJs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IAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEB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QAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQID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YWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw=="; } }); @@ -9046,6 +9149,7 @@ var require_client = __commonJS({ "use strict"; var assert = require("assert"); var net = require("net"); + var { pipeline } = require("stream"); var util = require_util(); var timers = require_timers(); var Request = require_request2(); @@ -9107,8 +9211,32 @@ var require_client = __commonJS({ kDispatch, kInterceptors, kLocalAddress, - kMaxResponseSize + kMaxResponseSize, + kHTTPConnVersion, + kHost, + kHTTP2Session, + kHTTP2SessionState, + kHTTP2BuildRequest, + kHTTP2CopyHeaders, + kHTTP1BuildRequest } = require_symbols(); + var http2; + try { + http2 = require("http2"); + } catch { + http2 = { constants: {} }; + } + var { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS + } + } = http2; + var h2ExperimentalWarned = false; var FastBuffer = Buffer[Symbol.species]; var kClosedResolve = Symbol("kClosedResolve"); var channels = {}; @@ -9150,7 +9278,9 @@ var require_client = __commonJS({ localAddress, maxResponseSize, autoSelectFamily, - autoSelectFamilyAttemptTimeout + autoSelectFamilyAttemptTimeout, + allowH2, + maxConcurrentStreams } = {}) { super(); if (keepAlive !== void 0) { @@ -9210,10 +9340,17 @@ var require_client = __commonJS({ if (autoSelectFamilyAttemptTimeout != null && (!Number.isInteger(autoSelectFamilyAttemptTimeout) || autoSelectFamilyAttemptTimeout < -1)) { throw new InvalidArgumentError("autoSelectFamilyAttemptTimeout must be a positive number"); } + if (allowH2 != null && typeof allowH2 !== "boolean") { + throw new InvalidArgumentError("allowH2 must be a valid boolean value"); + } + if (maxConcurrentStreams != null && (typeof maxConcurrentStreams !== "number" || maxConcurrentStreams < 1)) { + throw new InvalidArgumentError("maxConcurrentStreams must be a possitive integer, greater than 0"); + } if (typeof connect2 !== "function") { connect2 = buildConnector({ ...tls, maxCachedSessions, + allowH2, socketPath, timeout: connectTimeout, ...util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0, @@ -9243,6 +9380,13 @@ var require_client = __commonJS({ this[kMaxRequests] = maxRequestsPerClient; this[kClosedResolve] = null; this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1; + this[kHTTPConnVersion] = "h1"; + this[kHTTP2Session] = null; + this[kHTTP2SessionState] = !allowH2 ? null : { + openStreams: 0, + maxConcurrentStreams: maxConcurrentStreams != null ? maxConcurrentStreams : 100 + }; + this[kHost] = `${this[kUrl].hostname}${this[kUrl].port ? `:${this[kUrl].port}` : ""}`; this[kQueue] = []; this[kRunningIdx] = 0; this[kPendingIdx] = 0; @@ -9276,7 +9420,7 @@ var require_client = __commonJS({ } [kDispatch](opts, handler) { const origin = opts.origin || this[kUrl].origin; - const request = new Request(origin, opts, handler); + const request = this[kHTTPConnVersion] === "h2" ? Request[kHTTP2BuildRequest](origin, opts, handler) : Request[kHTTP1BuildRequest](origin, opts, handler); this[kQueue].push(request); if (this[kResuming]) { } else if (util.bodyLength(request.body) == null && util.isIterable(request.body)) { @@ -9313,6 +9457,11 @@ var require_client = __commonJS({ } resolve(); }; + if (this[kHTTP2Session] != null) { + util.destroy(this[kHTTP2Session], err); + this[kHTTP2Session] = null; + this[kHTTP2SessionState] = null; + } if (!this[kSocket]) { queueMicrotask(callback); } else { @@ -9322,6 +9471,44 @@ var require_client = __commonJS({ }); } }; + function onHttp2SessionError(err) { + assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); + this[kSocket][kError] = err; + onError(this[kClient], err); + } + function onHttp2FrameError(type, code, id) { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`); + if (id === 0) { + this[kSocket][kError] = err; + onError(this[kClient], err); + } + } + function onHttp2SessionEnd() { + util.destroy(this, new SocketError("other side closed")); + util.destroy(this[kSocket], new SocketError("other side closed")); + } + function onHTTP2GoAway(code) { + const client = this[kClient]; + const err = new InformationalError(`HTTP/2: "GOAWAY" frame received with code ${code}`); + client[kSocket] = null; + client[kHTTP2Session] = null; + if (client.destroyed) { + assert(this[kPending] === 0); + const requests = client[kQueue].splice(client[kRunningIdx]); + for (let i = 0; i < requests.length; i++) { + const request = requests[i]; + errorRequest(this, request, err); + } + } else if (client[kRunning] > 0) { + const request = client[kQueue][client[kRunningIdx]]; + client[kQueue][client[kRunningIdx]++] = null; + errorRequest(client, request, err); + } + client[kPendingIdx] = client[kRunningIdx]; + assert(client[kRunning] === 0); + client.emit("disconnect", client[kUrl], [client], err); + resume(client); + } var constants = require_constants2(); var createRedirectInterceptor = require_redirectInterceptor(); var EMPTY_BUF = Buffer.alloc(0); @@ -9761,11 +9948,13 @@ var require_client = __commonJS({ parser.readMore(); } function onSocketError(err) { - const { [kParser]: parser } = this; + const { [kClient]: client, [kParser]: parser } = this; assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); - if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { - parser.onMessageComplete(); - return; + if (client[kHTTPConnVersion] !== "h2") { + if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { + parser.onMessageComplete(); + return; + } } this[kError] = err; onError(this[kClient], err); @@ -9782,20 +9971,24 @@ var require_client = __commonJS({ } } function onSocketEnd() { - const { [kParser]: parser } = this; - if (parser.statusCode && !parser.shouldKeepAlive) { - parser.onMessageComplete(); - return; + const { [kParser]: parser, [kClient]: client } = this; + if (client[kHTTPConnVersion] !== "h2") { + if (parser.statusCode && !parser.shouldKeepAlive) { + parser.onMessageComplete(); + return; + } } util.destroy(this, new SocketError("other side closed", util.getSocketInfo(this))); } function onSocketClose() { - const { [kClient]: client } = this; - if (!this[kError] && this[kParser].statusCode && !this[kParser].shouldKeepAlive) { - this[kParser].onMessageComplete(); + const { [kClient]: client, [kParser]: parser } = this; + if (client[kHTTPConnVersion] === "h1" && parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + parser.onMessageComplete(); + } + this[kParser].destroy(); + this[kParser] = null; } - this[kParser].destroy(); - this[kParser] = null; const err = this[kError] || new SocketError("closed", util.getSocketInfo(this)); client[kSocket] = null; if (client.destroyed) { @@ -9862,21 +10055,46 @@ var require_client = __commonJS({ }), new ClientDestroyedError()); return; } - if (!llhttpInstance) { - llhttpInstance = await llhttpPromise; - llhttpPromise = null; - } client[kConnecting] = false; assert(socket); - socket[kNoRef] = false; - socket[kWriting] = false; - socket[kReset] = false; - socket[kBlocking] = false; - socket[kError] = null; - socket[kParser] = new Parser(client, socket, llhttpInstance); - socket[kClient] = client; + const isH2 = socket.alpnProtocol === "h2"; + if (isH2) { + if (!h2ExperimentalWarned) { + h2ExperimentalWarned = true; + process.emitWarning("H2 support is experimental, expect them to change at any time.", { + code: "UNDICI-H2" + }); + } + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: client[kHTTP2SessionState].maxConcurrentStreams + }); + client[kHTTPConnVersion] = "h2"; + session[kClient] = client; + session[kSocket] = socket; + session.on("error", onHttp2SessionError); + session.on("frameError", onHttp2FrameError); + session.on("end", onHttp2SessionEnd); + session.on("goaway", onHTTP2GoAway); + session.on("close", onSocketClose); + session.unref(); + client[kHTTP2Session] = session; + socket[kHTTP2Session] = session; + } else { + if (!llhttpInstance) { + llhttpInstance = await llhttpPromise; + llhttpPromise = null; + } + socket[kNoRef] = false; + socket[kWriting] = false; + socket[kReset] = false; + socket[kBlocking] = false; + socket[kParser] = new Parser(client, socket, llhttpInstance); + } socket[kCounter] = 0; socket[kMaxRequests] = client[kMaxRequests]; + socket[kClient] = client; + socket[kError] = null; socket.on("error", onSocketError).on("readable", onSocketReadable).on("end", onSocketEnd).on("close", onSocketClose); client[kSocket] = socket; if (channels.connected.hasSubscribers) { @@ -9955,7 +10173,7 @@ var require_client = __commonJS({ return; } const socket = client[kSocket]; - if (socket && !socket.destroyed) { + if (socket && !socket.destroyed && socket.alpnProtocol !== "h2") { if (client[kSize] === 0) { if (!socket[kNoRef] && socket.unref) { socket.unref(); @@ -10008,7 +10226,7 @@ var require_client = __commonJS({ if (client[kConnecting]) { return; } - if (!socket) { + if (!socket && !client[kHTTP2Session]) { connect(client); return; } @@ -10042,6 +10260,10 @@ var require_client = __commonJS({ } } function write(client, request) { + if (client[kHTTPConnVersion] === "h2") { + writeH2(client, client[kHTTP2Session], request); + return; + } const { body, method, path, host, upgrade, headers, blocking, reset } = request; const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH"; if (body && typeof body.read === "function") { @@ -10153,8 +10375,205 @@ upgrade: ${upgrade}\r } return true; } - function writeStream({ body, client, request, socket, contentLength, header, expectsPayload }) { + function writeH2(client, session, request) { + const { body, method, path, host, upgrade, expectContinue, signal, headers: reqHeaders } = request; + let headers; + if (typeof reqHeaders === "string") + headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()); + else + headers = reqHeaders; + if (upgrade) { + errorRequest(client, request, new Error("Upgrade not supported for H2")); + return false; + } + try { + request.onConnect((err) => { + if (request.aborted || request.completed) { + return; + } + errorRequest(client, request, err || new RequestAbortedError()); + }); + } catch (err) { + errorRequest(client, request, err); + } + if (request.aborted) { + return false; + } + let stream; + const h2State = client[kHTTP2SessionState]; + headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost]; + headers[HTTP2_HEADER_PATH] = path; + if (method === "CONNECT") { + session.ref(); + stream = session.request(headers, { endStream: false, signal }); + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream); + ++h2State.openStreams; + } else { + stream.once("ready", () => { + request.onUpgrade(null, null, stream); + ++h2State.openStreams; + }); + } + stream.once("close", () => { + h2State.openStreams -= 1; + if (h2State.openStreams === 0) + session.unref(); + }); + return true; + } else { + headers[HTTP2_HEADER_METHOD] = method; + } + const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH"; + if (body && typeof body.read === "function") { + body.read(0); + } + let contentLength = util.bodyLength(body); + if (contentLength == null) { + contentLength = request.contentLength; + } + if (contentLength === 0 || !expectsPayload) { + contentLength = null; + } + if (request.contentLength != null && request.contentLength !== contentLength) { + if (client[kStrictContentLength]) { + errorRequest(client, request, new RequestContentLengthMismatchError()); + return false; + } + process.emitWarning(new RequestContentLengthMismatchError()); + } + if (contentLength != null) { + assert(body, "no body must not have content length"); + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}`; + } + session.ref(); + const shouldEndStream = method === "GET" || method === "HEAD"; + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = "100-continue"; + stream = session.request(headers, { endStream: shouldEndStream, signal }); + stream.once("continue", writeBodyH2); + } else { + stream = session.request(headers, { + endStream: shouldEndStream, + signal + }); + writeBodyH2(); + } + ++h2State.openStreams; + stream.once("response", (headers2) => { + if (request.onHeaders(Number(headers2[HTTP2_HEADER_STATUS]), headers2, stream.resume.bind(stream), "") === false) { + stream.pause(); + } + }); + stream.once("end", () => { + request.onComplete([]); + }); + stream.on("data", (chunk) => { + if (request.onData(chunk) === false) + stream.pause(); + }); + stream.once("close", () => { + h2State.openStreams -= 1; + if (h2State.openStreams === 0) + session.unref(); + }); + stream.once("error", function(err) { + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1; + util.destroy(stream, err); + } + }); + stream.once("frameError", (type, code) => { + const err = new InformationalError(`HTTP/2: "frameError" received - type ${type}, code ${code}`); + errorRequest(client, request, err); + if (client[kHTTP2Session] && !client[kHTTP2Session].destroyed && !this.closed && !this.destroyed) { + h2State.streams -= 1; + util.destroy(stream, err); + } + }); + return true; + function writeBodyH2() { + if (!body) { + request.onRequestSent(); + } else if (util.isBuffer(body)) { + assert(contentLength === body.byteLength, "buffer body must have content length"); + stream.cork(); + stream.write(body); + stream.uncork(); + request.onBodySent(body); + request.onRequestSent(); + } else if (util.isBlobLike(body)) { + if (typeof body.stream === "function") { + writeIterable({ + client, + request, + contentLength, + h2stream: stream, + expectsPayload, + body: body.stream(), + socket: client[kSocket], + header: "" + }); + } else { + writeBlob({ + body, + client, + request, + contentLength, + expectsPayload, + h2stream: stream, + header: "", + socket: client[kSocket] + }); + } + } else if (util.isStream(body)) { + writeStream({ + body, + client, + request, + contentLength, + expectsPayload, + socket: client[kSocket], + h2stream: stream, + header: "" + }); + } else if (util.isIterable(body)) { + writeIterable({ + body, + client, + request, + contentLength, + expectsPayload, + header: "", + h2stream: stream, + socket: client[kSocket] + }); + } else { + assert(false); + } + } + } + function writeStream({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { assert(contentLength !== 0 || client[kRunning] === 0, "stream body cannot be pipelined"); + if (client[kHTTPConnVersion] === "h2") { + let onPipeData = function(chunk) { + request.onBodySent(chunk); + }; + const pipe = pipeline(body, h2stream, (err) => { + if (err) { + util.destroy(body, err); + util.destroy(h2stream, err); + } else { + request.onRequestSent(); + } + }); + pipe.on("data", onPipeData); + pipe.once("end", () => { + pipe.removeListener("data", onPipeData); + util.destroy(pipe); + }); + return; + } let finished = false; const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }); const onData = function(chunk) { @@ -10208,19 +10627,26 @@ upgrade: ${upgrade}\r } socket.on("drain", onDrain).on("error", onFinished); } - async function writeBlob({ body, client, request, socket, contentLength, header, expectsPayload }) { + async function writeBlob({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { assert(contentLength === body.size, "blob body must have content length"); + const isH2 = client[kHTTPConnVersion] === "h2"; try { if (contentLength != null && contentLength !== body.size) { throw new RequestContentLengthMismatchError(); } const buffer = Buffer.from(await body.arrayBuffer()); - socket.cork(); - socket.write(`${header}content-length: ${contentLength}\r + if (isH2) { + h2stream.cork(); + h2stream.write(buffer); + h2stream.uncork(); + } else { + socket.cork(); + socket.write(`${header}content-length: ${contentLength}\r \r `, "latin1"); - socket.write(buffer); - socket.uncork(); + socket.write(buffer); + socket.uncork(); + } request.onBodySent(buffer); request.onRequestSent(); if (!expectsPayload) { @@ -10228,10 +10654,10 @@ upgrade: ${upgrade}\r } resume(client); } catch (err) { - util.destroy(socket, err); + util.destroy(isH2 ? h2stream : socket, err); } } - async function writeIterable({ body, client, request, socket, contentLength, header, expectsPayload }) { + async function writeIterable({ h2stream, body, client, request, socket, contentLength, header, expectsPayload }) { assert(contentLength !== 0 || client[kRunning] === 0, "iterator body cannot be pipelined"); let callback = null; function onDrain() { @@ -10249,6 +10675,24 @@ upgrade: ${upgrade}\r callback = resolve; } }); + if (client[kHTTPConnVersion] === "h2") { + h2stream.on("close", onDrain).on("drain", onDrain); + try { + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError]; + } + if (!h2stream.write(chunk)) { + await waitForDrain(); + } + } + } catch (err) { + h2stream.destroy(err); + } finally { + h2stream.off("close", onDrain).off("drain", onDrain); + } + return; + } socket.on("close", onDrain).on("drain", onDrain); const writer = new AsyncWriter({ socket, request, contentLength, client, expectsPayload, header }); try { @@ -10420,6 +10864,7 @@ var require_pool = __commonJS({ socketPath, autoSelectFamily, autoSelectFamilyAttemptTimeout, + allowH2, ...options } = {}) { super(); @@ -10436,6 +10881,7 @@ var require_pool = __commonJS({ connect = buildConnector({ ...tls, maxCachedSessions, + allowH2, socketPath, timeout: connectTimeout == null ? 1e4 : connectTimeout, ...util.nodeHasAutoSelectFamily && autoSelectFamily ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0, @@ -10445,7 +10891,7 @@ var require_pool = __commonJS({ this[kInterceptors] = options.interceptors && options.interceptors.Pool && Array.isArray(options.interceptors.Pool) ? options.interceptors.Pool : []; this[kConnections] = connections || null; this[kUrl] = util.parseOrigin(origin); - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, allowH2 }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kFactory] = factory; } @@ -10669,7 +11115,7 @@ var require_fetch = __commonJS({ var { kHeadersList } = require_symbols(); var EE = require("events"); var { Readable, pipeline } = require("stream"); - var { isErrored, isReadable, nodeMajor, nodeMinor } = require_util(); + var { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = require_util(); var { dataURLProcessor, serializeAMimeType } = require_dataURL(); var { TransformStream } = require("stream/web"); var { getGlobalDispatcher } = require_global2(); @@ -10730,13 +11176,12 @@ var require_fetch = __commonJS({ const relevantRealm = null; let locallyAborted = false; let controller = null; - requestObject.signal.addEventListener("abort", () => { + addAbortListener(requestObject.signal, () => { locallyAborted = true; + assert(controller != null); + controller.abort(requestObject.signal.reason); abortFetch(p, request, responseObject, requestObject.signal.reason); - if (controller != null) { - controller.abort(); - } - }, { once: true }); + }); const handleFetchDone = (response) => finalizeAndReportTiming(response, "fetch"); const processResponse = (response) => { if (locallyAborted) { @@ -10794,7 +11239,7 @@ var require_fetch = __commonJS({ } function markResourceTiming(timingInfo, originalURL, initiatorType, globalThis2, cacheState) { if (nodeMajor > 18 || nodeMajor === 18 && nodeMinor >= 2) { - performance.markResourceTiming(timingInfo, originalURL, initiatorType, globalThis2, cacheState); + performance.markResourceTiming(timingInfo, originalURL.href, initiatorType, globalThis2, cacheState); } } function abortFetch(p, request, responseObject, error) { @@ -11362,7 +11807,7 @@ var require_fetch = __commonJS({ } catch (err) { if (err.name === "AbortError") { fetchParams.controller.connection.destroy(); - return makeAppropriateNetworkError(fetchParams); + return makeAppropriateNetworkError(fetchParams, err); } return makeNetworkError(err); } @@ -11477,15 +11922,28 @@ var require_fetch = __commonJS({ let codings = []; let location = ""; const headers = new Headers(); - for (let n = 0; n < headersList.length; n += 2) { - const key = headersList[n + 0].toString("latin1"); - const val = headersList[n + 1].toString("latin1"); - if (key.toLowerCase() === "content-encoding") { - codings = val.toLowerCase().split(",").map((x) => x.trim()); - } else if (key.toLowerCase() === "location") { - location = val; + if (Array.isArray(headersList)) { + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString("latin1"); + const val = headersList[n + 1].toString("latin1"); + if (key.toLowerCase() === "content-encoding") { + codings = val.toLowerCase().split(",").map((x) => x.trim()); + } else if (key.toLowerCase() === "location") { + location = val; + } + headers.append(key, val); + } + } else { + const keys = Object.keys(headersList); + for (const key of keys) { + const val = headersList[key]; + if (key.toLowerCase() === "content-encoding") { + codings = val.toLowerCase().split(",").map((x) => x.trim()).reverse(); + } else if (key.toLowerCase() === "location") { + location = val; + } + headers.append(key, val); } - headers.append(key, val); } this.body = new Readable({ read: resume }); const decoders = []; @@ -11493,7 +11951,10 @@ var require_fetch = __commonJS({ if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { for (const coding of codings) { if (coding === "x-gzip" || coding === "gzip") { - decoders.push(zlib.createGunzip()); + decoders.push(zlib.createGunzip({ + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH + })); } else if (coding === "deflate") { decoders.push(zlib.createInflate()); } else if (coding === "br") { @@ -11567,11 +12028,1194 @@ var require_fetch = __commonJS({ } }); +// lib/websocket/constants.js +var require_constants3 = __commonJS({ + "lib/websocket/constants.js"(exports2, module2) { + "use strict"; + var uid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + var staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false + }; + var states = { + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3 + }; + var opcodes = { + CONTINUATION: 0, + TEXT: 1, + BINARY: 2, + CLOSE: 8, + PING: 9, + PONG: 10 + }; + var maxUnsigned16Bit = 2 ** 16 - 1; + var parserStates = { + INFO: 0, + PAYLOADLENGTH_16: 2, + PAYLOADLENGTH_64: 3, + READ_DATA: 4 + }; + var emptyBuffer = Buffer.allocUnsafe(0); + module2.exports = { + uid, + staticPropertyDescriptors, + states, + opcodes, + maxUnsigned16Bit, + parserStates, + emptyBuffer + }; + } +}); + +// lib/websocket/symbols.js +var require_symbols3 = __commonJS({ + "lib/websocket/symbols.js"(exports2, module2) { + "use strict"; + module2.exports = { + kWebSocketURL: Symbol("url"), + kReadyState: Symbol("ready state"), + kController: Symbol("controller"), + kResponse: Symbol("response"), + kBinaryType: Symbol("binary type"), + kSentClose: Symbol("sent close"), + kReceivedClose: Symbol("received close"), + kByteParser: Symbol("byte parser") + }; + } +}); + +// lib/websocket/events.js +var require_events = __commonJS({ + "lib/websocket/events.js"(exports2, module2) { + "use strict"; + var { webidl } = require_webidl(); + var { kEnumerableProperty } = require_util(); + var { MessagePort } = require("worker_threads"); + var MessageEvent = class extends Event { + #eventInit; + constructor(type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: "MessageEvent constructor" }); + type = webidl.converters.DOMString(type); + eventInitDict = webidl.converters.MessageEventInit(eventInitDict); + super(type, eventInitDict); + this.#eventInit = eventInitDict; + } + get data() { + webidl.brandCheck(this, MessageEvent); + return this.#eventInit.data; + } + get origin() { + webidl.brandCheck(this, MessageEvent); + return this.#eventInit.origin; + } + get lastEventId() { + webidl.brandCheck(this, MessageEvent); + return this.#eventInit.lastEventId; + } + get source() { + webidl.brandCheck(this, MessageEvent); + return this.#eventInit.source; + } + get ports() { + webidl.brandCheck(this, MessageEvent); + if (!Object.isFrozen(this.#eventInit.ports)) { + Object.freeze(this.#eventInit.ports); + } + return this.#eventInit.ports; + } + initMessageEvent(type, bubbles = false, cancelable = false, data = null, origin = "", lastEventId = "", source = null, ports = []) { + webidl.brandCheck(this, MessageEvent); + webidl.argumentLengthCheck(arguments, 1, { header: "MessageEvent.initMessageEvent" }); + return new MessageEvent(type, { + bubbles, + cancelable, + data, + origin, + lastEventId, + source, + ports + }); + } + }; + var CloseEvent = class extends Event { + #eventInit; + constructor(type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: "CloseEvent constructor" }); + type = webidl.converters.DOMString(type); + eventInitDict = webidl.converters.CloseEventInit(eventInitDict); + super(type, eventInitDict); + this.#eventInit = eventInitDict; + } + get wasClean() { + webidl.brandCheck(this, CloseEvent); + return this.#eventInit.wasClean; + } + get code() { + webidl.brandCheck(this, CloseEvent); + return this.#eventInit.code; + } + get reason() { + webidl.brandCheck(this, CloseEvent); + return this.#eventInit.reason; + } + }; + var ErrorEvent = class extends Event { + #eventInit; + constructor(type, eventInitDict) { + webidl.argumentLengthCheck(arguments, 1, { header: "ErrorEvent constructor" }); + super(type, eventInitDict); + type = webidl.converters.DOMString(type); + eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}); + this.#eventInit = eventInitDict; + } + get message() { + webidl.brandCheck(this, ErrorEvent); + return this.#eventInit.message; + } + get filename() { + webidl.brandCheck(this, ErrorEvent); + return this.#eventInit.filename; + } + get lineno() { + webidl.brandCheck(this, ErrorEvent); + return this.#eventInit.lineno; + } + get colno() { + webidl.brandCheck(this, ErrorEvent); + return this.#eventInit.colno; + } + get error() { + webidl.brandCheck(this, ErrorEvent); + return this.#eventInit.error; + } + }; + Object.defineProperties(MessageEvent.prototype, { + [Symbol.toStringTag]: { + value: "MessageEvent", + configurable: true + }, + data: kEnumerableProperty, + origin: kEnumerableProperty, + lastEventId: kEnumerableProperty, + source: kEnumerableProperty, + ports: kEnumerableProperty, + initMessageEvent: kEnumerableProperty + }); + Object.defineProperties(CloseEvent.prototype, { + [Symbol.toStringTag]: { + value: "CloseEvent", + configurable: true + }, + reason: kEnumerableProperty, + code: kEnumerableProperty, + wasClean: kEnumerableProperty + }); + Object.defineProperties(ErrorEvent.prototype, { + [Symbol.toStringTag]: { + value: "ErrorEvent", + configurable: true + }, + message: kEnumerableProperty, + filename: kEnumerableProperty, + lineno: kEnumerableProperty, + colno: kEnumerableProperty, + error: kEnumerableProperty + }); + webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort); + webidl.converters["sequence"] = webidl.sequenceConverter(webidl.converters.MessagePort); + var eventInit = [ + { + key: "bubbles", + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: "cancelable", + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: "composed", + converter: webidl.converters.boolean, + defaultValue: false + } + ]; + webidl.converters.MessageEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: "data", + converter: webidl.converters.any, + defaultValue: null + }, + { + key: "origin", + converter: webidl.converters.USVString, + defaultValue: "" + }, + { + key: "lastEventId", + converter: webidl.converters.DOMString, + defaultValue: "" + }, + { + key: "source", + converter: webidl.nullableConverter(webidl.converters.MessagePort), + defaultValue: null + }, + { + key: "ports", + converter: webidl.converters["sequence"], + get defaultValue() { + return []; + } + } + ]); + webidl.converters.CloseEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: "wasClean", + converter: webidl.converters.boolean, + defaultValue: false + }, + { + key: "code", + converter: webidl.converters["unsigned short"], + defaultValue: 0 + }, + { + key: "reason", + converter: webidl.converters.USVString, + defaultValue: "" + } + ]); + webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: "message", + converter: webidl.converters.DOMString, + defaultValue: "" + }, + { + key: "filename", + converter: webidl.converters.USVString, + defaultValue: "" + }, + { + key: "lineno", + converter: webidl.converters["unsigned long"], + defaultValue: 0 + }, + { + key: "colno", + converter: webidl.converters["unsigned long"], + defaultValue: 0 + }, + { + key: "error", + converter: webidl.converters.any + } + ]); + module2.exports = { + MessageEvent, + CloseEvent, + ErrorEvent + }; + } +}); + +// lib/websocket/util.js +var require_util3 = __commonJS({ + "lib/websocket/util.js"(exports2, module2) { + "use strict"; + var { kReadyState, kController, kResponse, kBinaryType, kWebSocketURL } = require_symbols3(); + var { states, opcodes } = require_constants3(); + var { MessageEvent, ErrorEvent } = require_events(); + function isEstablished(ws) { + return ws[kReadyState] === states.OPEN; + } + function isClosing(ws) { + return ws[kReadyState] === states.CLOSING; + } + function isClosed(ws) { + return ws[kReadyState] === states.CLOSED; + } + function fireEvent(e, target, eventConstructor = Event, eventInitDict) { + const event = new eventConstructor(e, eventInitDict); + target.dispatchEvent(event); + } + function websocketMessageReceived(ws, type, data) { + if (ws[kReadyState] !== states.OPEN) { + return; + } + let dataForEvent; + if (type === opcodes.TEXT) { + try { + dataForEvent = new TextDecoder("utf-8", { fatal: true }).decode(data); + } catch { + failWebsocketConnection(ws, "Received invalid UTF-8 in text frame."); + return; + } + } else if (type === opcodes.BINARY) { + if (ws[kBinaryType] === "blob") { + dataForEvent = new Blob([data]); + } else { + dataForEvent = new Uint8Array(data).buffer; + } + } + fireEvent("message", ws, MessageEvent, { + origin: ws[kWebSocketURL].origin, + data: dataForEvent + }); + } + function isValidSubprotocol(protocol) { + if (protocol.length === 0) { + return false; + } + for (const char of protocol) { + const code = char.charCodeAt(0); + if (code < 33 || code > 126 || char === "(" || char === ")" || char === "<" || char === ">" || char === "@" || char === "," || char === ";" || char === ":" || char === "\\" || char === '"' || char === "/" || char === "[" || char === "]" || char === "?" || char === "=" || char === "{" || char === "}" || code === 32 || code === 9) { + return false; + } + } + return true; + } + function isValidStatusCode(code) { + if (code >= 1e3 && code < 1015) { + return code !== 1004 && code !== 1005 && code !== 1006; + } + return code >= 3e3 && code <= 4999; + } + function failWebsocketConnection(ws, reason) { + const { [kController]: controller, [kResponse]: response } = ws; + controller.abort(); + if (response?.socket && !response.socket.destroyed) { + response.socket.destroy(); + } + if (reason) { + fireEvent("error", ws, ErrorEvent, { + error: new Error(reason) + }); + } + } + module2.exports = { + isEstablished, + isClosing, + isClosed, + fireEvent, + isValidSubprotocol, + isValidStatusCode, + failWebsocketConnection, + websocketMessageReceived + }; + } +}); + +// lib/websocket/connection.js +var require_connection = __commonJS({ + "lib/websocket/connection.js"(exports2, module2) { + "use strict"; + var diagnosticsChannel = require("diagnostics_channel"); + var { uid, states } = require_constants3(); + var { + kReadyState, + kSentClose, + kByteParser, + kReceivedClose + } = require_symbols3(); + var { fireEvent, failWebsocketConnection } = require_util3(); + var { CloseEvent } = require_events(); + var { makeRequest } = require_request(); + var { fetching } = require_fetch(); + var { Headers } = require_headers(); + var { getGlobalDispatcher } = require_global2(); + var { kHeadersList } = require_symbols(); + var channels = {}; + channels.open = diagnosticsChannel.channel("undici:websocket:open"); + channels.close = diagnosticsChannel.channel("undici:websocket:close"); + channels.socketError = diagnosticsChannel.channel("undici:websocket:socket_error"); + var crypto; + try { + crypto = require("crypto"); + } catch { + } + function establishWebSocketConnection(url, protocols, ws, onEstablish, options) { + const requestURL = url; + requestURL.protocol = url.protocol === "ws:" ? "http:" : "https:"; + const request = makeRequest({ + urlList: [requestURL], + serviceWorkers: "none", + referrer: "no-referrer", + mode: "websocket", + credentials: "include", + cache: "no-store", + redirect: "error" + }); + if (options.headers) { + const headersList = new Headers(options.headers)[kHeadersList]; + request.headersList = headersList; + } + const keyValue = crypto.randomBytes(16).toString("base64"); + request.headersList.append("sec-websocket-key", keyValue); + request.headersList.append("sec-websocket-version", "13"); + for (const protocol of protocols) { + request.headersList.append("sec-websocket-protocol", protocol); + } + const permessageDeflate = ""; + const controller = fetching({ + request, + useParallelQueue: true, + dispatcher: options.dispatcher ?? getGlobalDispatcher(), + processResponse(response) { + if (response.type === "error" || response.status !== 101) { + failWebsocketConnection(ws, "Received network error or non-101 status code."); + return; + } + if (protocols.length !== 0 && !response.headersList.get("Sec-WebSocket-Protocol")) { + failWebsocketConnection(ws, "Server did not respond with sent protocols."); + return; + } + if (response.headersList.get("Upgrade")?.toLowerCase() !== "websocket") { + failWebsocketConnection(ws, 'Server did not set Upgrade header to "websocket".'); + return; + } + if (response.headersList.get("Connection")?.toLowerCase() !== "upgrade") { + failWebsocketConnection(ws, 'Server did not set Connection header to "upgrade".'); + return; + } + const secWSAccept = response.headersList.get("Sec-WebSocket-Accept"); + const digest = crypto.createHash("sha1").update(keyValue + uid).digest("base64"); + if (secWSAccept !== digest) { + failWebsocketConnection(ws, "Incorrect hash received in Sec-WebSocket-Accept header."); + return; + } + const secExtension = response.headersList.get("Sec-WebSocket-Extensions"); + if (secExtension !== null && secExtension !== permessageDeflate) { + failWebsocketConnection(ws, "Received different permessage-deflate than the one set."); + return; + } + const secProtocol = response.headersList.get("Sec-WebSocket-Protocol"); + if (secProtocol !== null && secProtocol !== request.headersList.get("Sec-WebSocket-Protocol")) { + failWebsocketConnection(ws, "Protocol was not set in the opening handshake."); + return; + } + response.socket.on("data", onSocketData); + response.socket.on("close", onSocketClose); + response.socket.on("error", onSocketError); + if (channels.open.hasSubscribers) { + channels.open.publish({ + address: response.socket.address(), + protocol: secProtocol, + extensions: secExtension + }); + } + onEstablish(response); + } + }); + return controller; + } + function onSocketData(chunk) { + if (!this.ws[kByteParser].write(chunk)) { + this.pause(); + } + } + function onSocketClose() { + const { ws } = this; + const wasClean = ws[kSentClose] && ws[kReceivedClose]; + let code = 1005; + let reason = ""; + const result = ws[kByteParser].closingInfo; + if (result) { + code = result.code ?? 1005; + reason = result.reason; + } else if (!ws[kSentClose]) { + code = 1006; + } + ws[kReadyState] = states.CLOSED; + fireEvent("close", ws, CloseEvent, { + wasClean, + code, + reason + }); + if (channels.close.hasSubscribers) { + channels.close.publish({ + websocket: ws, + code, + reason + }); + } + } + function onSocketError(error) { + const { ws } = this; + ws[kReadyState] = states.CLOSING; + if (channels.socketError.hasSubscribers) { + channels.socketError.publish(error); + } + this.destroy(); + } + module2.exports = { + establishWebSocketConnection + }; + } +}); + +// lib/websocket/frame.js +var require_frame = __commonJS({ + "lib/websocket/frame.js"(exports2, module2) { + "use strict"; + var { maxUnsigned16Bit } = require_constants3(); + var crypto; + try { + crypto = require("crypto"); + } catch { + } + var WebsocketFrameSend = class { + constructor(data) { + this.frameData = data; + this.maskKey = crypto.randomBytes(4); + } + createFrame(opcode) { + const bodyLength = this.frameData?.byteLength ?? 0; + let payloadLength = bodyLength; + let offset = 6; + if (bodyLength > maxUnsigned16Bit) { + offset += 8; + payloadLength = 127; + } else if (bodyLength > 125) { + offset += 2; + payloadLength = 126; + } + const buffer = Buffer.allocUnsafe(bodyLength + offset); + buffer[0] = buffer[1] = 0; + buffer[0] |= 128; + buffer[0] = (buffer[0] & 240) + opcode; + buffer[offset - 4] = this.maskKey[0]; + buffer[offset - 3] = this.maskKey[1]; + buffer[offset - 2] = this.maskKey[2]; + buffer[offset - 1] = this.maskKey[3]; + buffer[1] = payloadLength; + if (payloadLength === 126) { + buffer.writeUInt16BE(bodyLength, 2); + } else if (payloadLength === 127) { + buffer[2] = buffer[3] = 0; + buffer.writeUIntBE(bodyLength, 4, 6); + } + buffer[1] |= 128; + for (let i = 0; i < bodyLength; i++) { + buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4]; + } + return buffer; + } + }; + module2.exports = { + WebsocketFrameSend + }; + } +}); + +// lib/websocket/receiver.js +var require_receiver = __commonJS({ + "lib/websocket/receiver.js"(exports2, module2) { + "use strict"; + var { Writable } = require("stream"); + var diagnosticsChannel = require("diagnostics_channel"); + var { parserStates, opcodes, states, emptyBuffer } = require_constants3(); + var { kReadyState, kSentClose, kResponse, kReceivedClose } = require_symbols3(); + var { isValidStatusCode, failWebsocketConnection, websocketMessageReceived } = require_util3(); + var { WebsocketFrameSend } = require_frame(); + var channels = {}; + channels.ping = diagnosticsChannel.channel("undici:websocket:ping"); + channels.pong = diagnosticsChannel.channel("undici:websocket:pong"); + var ByteParser = class extends Writable { + #buffers = []; + #byteOffset = 0; + #state = parserStates.INFO; + #info = {}; + #fragments = []; + constructor(ws) { + super(); + this.ws = ws; + } + _write(chunk, _, callback) { + this.#buffers.push(chunk); + this.#byteOffset += chunk.length; + this.run(callback); + } + run(callback) { + while (true) { + if (this.#state === parserStates.INFO) { + if (this.#byteOffset < 2) { + return callback(); + } + const buffer = this.consume(2); + this.#info.fin = (buffer[0] & 128) !== 0; + this.#info.opcode = buffer[0] & 15; + this.#info.originalOpcode ??= this.#info.opcode; + this.#info.fragmented = !this.#info.fin && this.#info.opcode !== opcodes.CONTINUATION; + if (this.#info.fragmented && this.#info.opcode !== opcodes.BINARY && this.#info.opcode !== opcodes.TEXT) { + failWebsocketConnection(this.ws, "Invalid frame type was fragmented."); + return; + } + const payloadLength = buffer[1] & 127; + if (payloadLength <= 125) { + this.#info.payloadLength = payloadLength; + this.#state = parserStates.READ_DATA; + } else if (payloadLength === 126) { + this.#state = parserStates.PAYLOADLENGTH_16; + } else if (payloadLength === 127) { + this.#state = parserStates.PAYLOADLENGTH_64; + } + if (this.#info.fragmented && payloadLength > 125) { + failWebsocketConnection(this.ws, "Fragmented frame exceeded 125 bytes."); + return; + } else if ((this.#info.opcode === opcodes.PING || this.#info.opcode === opcodes.PONG || this.#info.opcode === opcodes.CLOSE) && payloadLength > 125) { + failWebsocketConnection(this.ws, "Payload length for control frame exceeded 125 bytes."); + return; + } else if (this.#info.opcode === opcodes.CLOSE) { + if (payloadLength === 1) { + failWebsocketConnection(this.ws, "Received close frame with a 1-byte body."); + return; + } + const body = this.consume(payloadLength); + this.#info.closeInfo = this.parseCloseBody(false, body); + if (!this.ws[kSentClose]) { + const body2 = Buffer.allocUnsafe(2); + body2.writeUInt16BE(this.#info.closeInfo.code, 0); + const closeFrame = new WebsocketFrameSend(body2); + this.ws[kResponse].socket.write(closeFrame.createFrame(opcodes.CLOSE), (err) => { + if (!err) { + this.ws[kSentClose] = true; + } + }); + } + this.ws[kReadyState] = states.CLOSING; + this.ws[kReceivedClose] = true; + this.end(); + return; + } else if (this.#info.opcode === opcodes.PING) { + const body = this.consume(payloadLength); + if (!this.ws[kReceivedClose]) { + const frame = new WebsocketFrameSend(body); + this.ws[kResponse].socket.write(frame.createFrame(opcodes.PONG)); + if (channels.ping.hasSubscribers) { + channels.ping.publish({ + payload: body + }); + } + } + this.#state = parserStates.INFO; + if (this.#byteOffset > 0) { + continue; + } else { + callback(); + return; + } + } else if (this.#info.opcode === opcodes.PONG) { + const body = this.consume(payloadLength); + if (channels.pong.hasSubscribers) { + channels.pong.publish({ + payload: body + }); + } + if (this.#byteOffset > 0) { + continue; + } else { + callback(); + return; + } + } + } else if (this.#state === parserStates.PAYLOADLENGTH_16) { + if (this.#byteOffset < 2) { + return callback(); + } + const buffer = this.consume(2); + this.#info.payloadLength = buffer.readUInt16BE(0); + this.#state = parserStates.READ_DATA; + } else if (this.#state === parserStates.PAYLOADLENGTH_64) { + if (this.#byteOffset < 8) { + return callback(); + } + const buffer = this.consume(8); + const upper = buffer.readUInt32BE(0); + if (upper > 2 ** 31 - 1) { + failWebsocketConnection(this.ws, "Received payload length > 2^31 bytes."); + return; + } + const lower = buffer.readUInt32BE(4); + this.#info.payloadLength = (upper << 8) + lower; + this.#state = parserStates.READ_DATA; + } else if (this.#state === parserStates.READ_DATA) { + if (this.#byteOffset < this.#info.payloadLength) { + return callback(); + } else if (this.#byteOffset >= this.#info.payloadLength) { + const body = this.consume(this.#info.payloadLength); + this.#fragments.push(body); + if (!this.#info.fragmented || this.#info.fin && this.#info.opcode === opcodes.CONTINUATION) { + const fullMessage = Buffer.concat(this.#fragments); + websocketMessageReceived(this.ws, this.#info.originalOpcode, fullMessage); + this.#info = {}; + this.#fragments.length = 0; + } + this.#state = parserStates.INFO; + } + } + if (this.#byteOffset > 0) { + continue; + } else { + callback(); + break; + } + } + } + consume(n) { + if (n > this.#byteOffset) { + return null; + } else if (n === 0) { + return emptyBuffer; + } + if (this.#buffers[0].length === n) { + this.#byteOffset -= this.#buffers[0].length; + return this.#buffers.shift(); + } + const buffer = Buffer.allocUnsafe(n); + let offset = 0; + while (offset !== n) { + const next = this.#buffers[0]; + const { length } = next; + if (length + offset === n) { + buffer.set(this.#buffers.shift(), offset); + break; + } else if (length + offset > n) { + buffer.set(next.subarray(0, n - offset), offset); + this.#buffers[0] = next.subarray(n - offset); + break; + } else { + buffer.set(this.#buffers.shift(), offset); + offset += next.length; + } + } + this.#byteOffset -= n; + return buffer; + } + parseCloseBody(onlyCode, data) { + let code; + if (data.length >= 2) { + code = data.readUInt16BE(0); + } + if (onlyCode) { + if (!isValidStatusCode(code)) { + return null; + } + return { code }; + } + let reason = data.subarray(2); + if (reason[0] === 239 && reason[1] === 187 && reason[2] === 191) { + reason = reason.subarray(3); + } + if (code !== void 0 && !isValidStatusCode(code)) { + return null; + } + try { + reason = new TextDecoder("utf-8", { fatal: true }).decode(reason); + } catch { + return null; + } + return { code, reason }; + } + get closingInfo() { + return this.#info.closeInfo; + } + }; + module2.exports = { + ByteParser + }; + } +}); + +// lib/websocket/websocket.js +var require_websocket = __commonJS({ + "lib/websocket/websocket.js"(exports2, module2) { + "use strict"; + var { webidl } = require_webidl(); + var { DOMException } = require_constants(); + var { URLSerializer } = require_dataURL(); + var { getGlobalOrigin } = require_global(); + var { staticPropertyDescriptors, states, opcodes, emptyBuffer } = require_constants3(); + var { + kWebSocketURL, + kReadyState, + kController, + kBinaryType, + kResponse, + kSentClose, + kByteParser + } = require_symbols3(); + var { isEstablished, isClosing, isValidSubprotocol, failWebsocketConnection, fireEvent } = require_util3(); + var { establishWebSocketConnection } = require_connection(); + var { WebsocketFrameSend } = require_frame(); + var { ByteParser } = require_receiver(); + var { kEnumerableProperty, isBlobLike } = require_util(); + var { getGlobalDispatcher } = require_global2(); + var { types } = require("util"); + var experimentalWarned = false; + var WebSocket = class extends EventTarget { + #events = { + open: null, + error: null, + close: null, + message: null + }; + #bufferedAmount = 0; + #protocol = ""; + #extensions = ""; + constructor(url, protocols = []) { + super(); + webidl.argumentLengthCheck(arguments, 1, { header: "WebSocket constructor" }); + if (!experimentalWarned) { + experimentalWarned = true; + process.emitWarning("WebSockets are experimental, expect them to change at any time.", { + code: "UNDICI-WS" + }); + } + const options = webidl.converters["DOMString or sequence or WebSocketInit"](protocols); + url = webidl.converters.USVString(url); + protocols = options.protocols; + const baseURL = getGlobalOrigin(); + let urlRecord; + try { + urlRecord = new URL(url, baseURL); + } catch (e) { + throw new DOMException(e, "SyntaxError"); + } + if (urlRecord.protocol === "http:") { + urlRecord.protocol = "ws:"; + } else if (urlRecord.protocol === "https:") { + urlRecord.protocol = "wss:"; + } + if (urlRecord.protocol !== "ws:" && urlRecord.protocol !== "wss:") { + throw new DOMException(`Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, "SyntaxError"); + } + if (urlRecord.hash || urlRecord.href.endsWith("#")) { + throw new DOMException("Got fragment", "SyntaxError"); + } + if (typeof protocols === "string") { + protocols = [protocols]; + } + if (protocols.length !== new Set(protocols.map((p) => p.toLowerCase())).size) { + throw new DOMException("Invalid Sec-WebSocket-Protocol value", "SyntaxError"); + } + if (protocols.length > 0 && !protocols.every((p) => isValidSubprotocol(p))) { + throw new DOMException("Invalid Sec-WebSocket-Protocol value", "SyntaxError"); + } + this[kWebSocketURL] = new URL(urlRecord.href); + this[kController] = establishWebSocketConnection(urlRecord, protocols, this, (response) => this.#onConnectionEstablished(response), options); + this[kReadyState] = WebSocket.CONNECTING; + this[kBinaryType] = "blob"; + } + close(code = void 0, reason = void 0) { + webidl.brandCheck(this, WebSocket); + if (code !== void 0) { + code = webidl.converters["unsigned short"](code, { clamp: true }); + } + if (reason !== void 0) { + reason = webidl.converters.USVString(reason); + } + if (code !== void 0) { + if (code !== 1e3 && (code < 3e3 || code > 4999)) { + throw new DOMException("invalid code", "InvalidAccessError"); + } + } + let reasonByteLength = 0; + if (reason !== void 0) { + reasonByteLength = Buffer.byteLength(reason); + if (reasonByteLength > 123) { + throw new DOMException(`Reason must be less than 123 bytes; received ${reasonByteLength}`, "SyntaxError"); + } + } + if (this[kReadyState] === WebSocket.CLOSING || this[kReadyState] === WebSocket.CLOSED) { + } else if (!isEstablished(this)) { + failWebsocketConnection(this, "Connection was closed before it was established."); + this[kReadyState] = WebSocket.CLOSING; + } else if (!isClosing(this)) { + const frame = new WebsocketFrameSend(); + if (code !== void 0 && reason === void 0) { + frame.frameData = Buffer.allocUnsafe(2); + frame.frameData.writeUInt16BE(code, 0); + } else if (code !== void 0 && reason !== void 0) { + frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength); + frame.frameData.writeUInt16BE(code, 0); + frame.frameData.write(reason, 2, "utf-8"); + } else { + frame.frameData = emptyBuffer; + } + const socket = this[kResponse].socket; + socket.write(frame.createFrame(opcodes.CLOSE), (err) => { + if (!err) { + this[kSentClose] = true; + } + }); + this[kReadyState] = states.CLOSING; + } else { + this[kReadyState] = WebSocket.CLOSING; + } + } + send(data) { + webidl.brandCheck(this, WebSocket); + webidl.argumentLengthCheck(arguments, 1, { header: "WebSocket.send" }); + data = webidl.converters.WebSocketSendData(data); + if (this[kReadyState] === WebSocket.CONNECTING) { + throw new DOMException("Sent before connected.", "InvalidStateError"); + } + if (!isEstablished(this) || isClosing(this)) { + return; + } + const socket = this[kResponse].socket; + if (typeof data === "string") { + const value = Buffer.from(data); + const frame = new WebsocketFrameSend(value); + const buffer = frame.createFrame(opcodes.TEXT); + this.#bufferedAmount += value.byteLength; + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength; + }); + } else if (types.isArrayBuffer(data)) { + const value = Buffer.from(data); + const frame = new WebsocketFrameSend(value); + const buffer = frame.createFrame(opcodes.BINARY); + this.#bufferedAmount += value.byteLength; + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength; + }); + } else if (ArrayBuffer.isView(data)) { + const ab = Buffer.from(data, data.byteOffset, data.byteLength); + const frame = new WebsocketFrameSend(ab); + const buffer = frame.createFrame(opcodes.BINARY); + this.#bufferedAmount += ab.byteLength; + socket.write(buffer, () => { + this.#bufferedAmount -= ab.byteLength; + }); + } else if (isBlobLike(data)) { + const frame = new WebsocketFrameSend(); + data.arrayBuffer().then((ab) => { + const value = Buffer.from(ab); + frame.frameData = value; + const buffer = frame.createFrame(opcodes.BINARY); + this.#bufferedAmount += value.byteLength; + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength; + }); + }); + } + } + get readyState() { + webidl.brandCheck(this, WebSocket); + return this[kReadyState]; + } + get bufferedAmount() { + webidl.brandCheck(this, WebSocket); + return this.#bufferedAmount; + } + get url() { + webidl.brandCheck(this, WebSocket); + return URLSerializer(this[kWebSocketURL]); + } + get extensions() { + webidl.brandCheck(this, WebSocket); + return this.#extensions; + } + get protocol() { + webidl.brandCheck(this, WebSocket); + return this.#protocol; + } + get onopen() { + webidl.brandCheck(this, WebSocket); + return this.#events.open; + } + set onopen(fn) { + webidl.brandCheck(this, WebSocket); + if (this.#events.open) { + this.removeEventListener("open", this.#events.open); + } + if (typeof fn === "function") { + this.#events.open = fn; + this.addEventListener("open", fn); + } else { + this.#events.open = null; + } + } + get onerror() { + webidl.brandCheck(this, WebSocket); + return this.#events.error; + } + set onerror(fn) { + webidl.brandCheck(this, WebSocket); + if (this.#events.error) { + this.removeEventListener("error", this.#events.error); + } + if (typeof fn === "function") { + this.#events.error = fn; + this.addEventListener("error", fn); + } else { + this.#events.error = null; + } + } + get onclose() { + webidl.brandCheck(this, WebSocket); + return this.#events.close; + } + set onclose(fn) { + webidl.brandCheck(this, WebSocket); + if (this.#events.close) { + this.removeEventListener("close", this.#events.close); + } + if (typeof fn === "function") { + this.#events.close = fn; + this.addEventListener("close", fn); + } else { + this.#events.close = null; + } + } + get onmessage() { + webidl.brandCheck(this, WebSocket); + return this.#events.message; + } + set onmessage(fn) { + webidl.brandCheck(this, WebSocket); + if (this.#events.message) { + this.removeEventListener("message", this.#events.message); + } + if (typeof fn === "function") { + this.#events.message = fn; + this.addEventListener("message", fn); + } else { + this.#events.message = null; + } + } + get binaryType() { + webidl.brandCheck(this, WebSocket); + return this[kBinaryType]; + } + set binaryType(type) { + webidl.brandCheck(this, WebSocket); + if (type !== "blob" && type !== "arraybuffer") { + this[kBinaryType] = "blob"; + } else { + this[kBinaryType] = type; + } + } + #onConnectionEstablished(response) { + this[kResponse] = response; + const parser = new ByteParser(this); + parser.on("drain", function onParserDrain() { + this.ws[kResponse].socket.resume(); + }); + response.socket.ws = this; + this[kByteParser] = parser; + this[kReadyState] = states.OPEN; + const extensions = response.headersList.get("sec-websocket-extensions"); + if (extensions !== null) { + this.#extensions = extensions; + } + const protocol = response.headersList.get("sec-websocket-protocol"); + if (protocol !== null) { + this.#protocol = protocol; + } + fireEvent("open", this); + } + }; + WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING; + WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN; + WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING; + WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED; + Object.defineProperties(WebSocket.prototype, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors, + url: kEnumerableProperty, + readyState: kEnumerableProperty, + bufferedAmount: kEnumerableProperty, + onopen: kEnumerableProperty, + onerror: kEnumerableProperty, + onclose: kEnumerableProperty, + close: kEnumerableProperty, + onmessage: kEnumerableProperty, + binaryType: kEnumerableProperty, + send: kEnumerableProperty, + extensions: kEnumerableProperty, + protocol: kEnumerableProperty, + [Symbol.toStringTag]: { + value: "WebSocket", + writable: false, + enumerable: false, + configurable: true + } + }); + Object.defineProperties(WebSocket, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors + }); + webidl.converters["sequence"] = webidl.sequenceConverter(webidl.converters.DOMString); + webidl.converters["DOMString or sequence"] = function(V) { + if (webidl.util.Type(V) === "Object" && Symbol.iterator in V) { + return webidl.converters["sequence"](V); + } + return webidl.converters.DOMString(V); + }; + webidl.converters.WebSocketInit = webidl.dictionaryConverter([ + { + key: "protocols", + converter: webidl.converters["DOMString or sequence"], + get defaultValue() { + return []; + } + }, + { + key: "dispatcher", + converter: (V) => V, + get defaultValue() { + return getGlobalDispatcher(); + } + }, + { + key: "headers", + converter: webidl.nullableConverter(webidl.converters.HeadersInit) + } + ]); + webidl.converters["DOMString or sequence or WebSocketInit"] = function(V) { + if (webidl.util.Type(V) === "Object" && !(Symbol.iterator in V)) { + return webidl.converters.WebSocketInit(V); + } + return { protocols: webidl.converters["DOMString or sequence"](V) }; + }; + webidl.converters.WebSocketSendData = function(V) { + if (webidl.util.Type(V) === "Object") { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }); + } + if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { + return webidl.converters.BufferSource(V); + } + } + return webidl.converters.USVString(V); + }; + module2.exports = { + WebSocket + }; + } +}); + // index-fetch.js var fetchImpl = require_fetch().fetch; -module.exports.fetch = async function fetch(resource) { +module.exports.fetch = async function fetch(resource, init = void 0) { try { - return await fetchImpl(...arguments); + return await fetchImpl(resource, init); } catch (err) { Error.captureStackTrace(err, this); throw err; @@ -11581,4 +13225,6 @@ module.exports.FormData = require_formdata().FormData; module.exports.Headers = require_headers().Headers; module.exports.Response = require_response().Response; module.exports.Request = require_request().Request; +module.exports.WebSocket = require_websocket().WebSocket; /*! formdata-polyfill. MIT License. Jimmy Wärting */ +/*! ws. MIT License. Einar Otto Stangvik */ diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index af6dccd8dedfa2..6c86c3fa50496d 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -51,6 +51,7 @@ 'src/strscpy.h', 'src/strtok.c', 'src/strtok.h', + 'src/thread-common.c', 'src/threadpool.c', 'src/timer.c', 'src/uv-data-getter-setters.c', @@ -135,7 +136,6 @@ 'uv_sources_android': [ 'src/unix/linux.c', 'src/unix/procfs-exepath.c', - 'src/unix/pthread-fixes.c', 'src/unix/random-getentropy.c', 'src/unix/random-getrandom.c', 'src/unix/random-sysctl-linux.c', @@ -397,7 +397,6 @@ }], ['OS=="zos"', { 'sources': [ - 'src/unix/pthread-fixes.c', 'src/unix/os390.c', 'src/unix/os390-syscalls.c' ] diff --git a/deps/v8/include/v8-cppgc.h b/deps/v8/include/v8-cppgc.h index 4a457027c9f76b..e0d76f45016e87 100644 --- a/deps/v8/include/v8-cppgc.h +++ b/deps/v8/include/v8-cppgc.h @@ -177,6 +177,11 @@ class V8_EXPORT CppHeap { void CollectGarbageInYoungGenerationForTesting( cppgc::EmbedderStackState stack_state); + /** + * \returns the wrapper descriptor of this CppHeap. + */ + v8::WrapperDescriptor wrapper_descriptor() const; + private: CppHeap() = default; diff --git a/deps/v8/include/v8-object.h b/deps/v8/include/v8-object.h index d805dbe9e7d818..b34253d7ac5a8e 100644 --- a/deps/v8/include/v8-object.h +++ b/deps/v8/include/v8-object.h @@ -474,11 +474,20 @@ class V8_EXPORT Object : public Value { return object->InternalFieldCount(); } - /** Gets the value from an internal field. */ - V8_INLINE Local GetInternalField(int index); + /** + * Gets the data from an internal field. + * To cast the return value into v8::Value subtypes, it needs to be + * casted to a v8::Value first. For example, to cast it into v8::External: + * + * object->GetInternalField(index).As().As(); + * + * The embedder should make sure that the internal field being retrieved + * using this method has already been set with SetInternalField() before. + **/ + V8_INLINE Local GetInternalField(int index); - /** Sets the value in an internal field. */ - void SetInternalField(int index, Local value); + /** Sets the data in an internal field. */ + void SetInternalField(int index, Local data); /** * Gets a 2-byte-aligned native pointer from an internal field. This field @@ -710,13 +719,13 @@ class V8_EXPORT Object : public Value { private: Object(); static void CheckCast(Value* obj); - Local SlowGetInternalField(int index); + Local SlowGetInternalField(int index); void* SlowGetAlignedPointerFromInternalField(int index); }; // --- Implementation --- -Local Object::GetInternalField(int index) { +Local Object::GetInternalField(int index) { #ifndef V8_ENABLE_CHECKS using A = internal::Address; using I = internal::Internals; @@ -734,12 +743,12 @@ Local Object::GetInternalField(int index) { #endif #ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING - return Local(reinterpret_cast(value)); + return Local(reinterpret_cast(value)); #else internal::Isolate* isolate = internal::IsolateFromNeverReadOnlySpaceObject(obj); A* result = HandleScope::CreateHandle(isolate, value); - return Local(reinterpret_cast(result)); + return Local(reinterpret_cast(result)); #endif } #endif diff --git a/deps/v8/include/v8-script.h b/deps/v8/include/v8-script.h index 4a8ccab7e28d1d..9b278da6d587a4 100644 --- a/deps/v8/include/v8-script.h +++ b/deps/v8/include/v8-script.h @@ -55,7 +55,7 @@ class V8_EXPORT ScriptOrModule { /** * A compiled JavaScript script, not yet tied to a Context. */ -class V8_EXPORT UnboundScript { +class V8_EXPORT UnboundScript : public Data { public: /** * Binds the script to the currently entered context. @@ -320,7 +320,7 @@ class V8_EXPORT Module : public Data { * A compiled JavaScript script, tied to a Context which was active when the * script was compiled. */ -class V8_EXPORT Script { +class V8_EXPORT Script : public Data { public: /** * A shorthand for ScriptCompiler::Compile(). diff --git a/deps/v8/samples/process.cc b/deps/v8/samples/process.cc index 28b6f119c3acd2..32e87b854be803 100644 --- a/deps/v8/samples/process.cc +++ b/deps/v8/samples/process.cc @@ -388,7 +388,7 @@ Local JsHttpRequestProcessor::WrapMap(map* obj) { // Utility function that extracts the C++ map pointer from a wrapper // object. map* JsHttpRequestProcessor::UnwrapMap(Local obj) { - Local field = obj->GetInternalField(0).As(); + Local field = obj->GetInternalField(0).As().As(); void* ptr = field->Value(); return static_cast*>(ptr); } @@ -504,7 +504,7 @@ Local JsHttpRequestProcessor::WrapRequest(HttpRequest* request) { * wrapper object. */ HttpRequest* JsHttpRequestProcessor::UnwrapRequest(Local obj) { - Local field = obj->GetInternalField(0).As(); + Local field = obj->GetInternalField(0).As().As(); void* ptr = field->Value(); return static_cast(ptr); } diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc index 10e342d496a703..7071b221a7afe0 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -6342,16 +6342,16 @@ static bool InternalFieldOK(i::Handle obj, int index, location, "Internal field out of bounds"); } -Local v8::Object::SlowGetInternalField(int index) { +Local v8::Object::SlowGetInternalField(int index) { i::Handle obj = Utils::OpenHandle(this); const char* location = "v8::Object::GetInternalField()"; if (!InternalFieldOK(obj, index, location)) return Local(); i::Handle value(i::JSObject::cast(*obj).GetEmbedderField(index), obj->GetIsolate()); - return Utils::ToLocal(value); + return ToApiHandle(value); } -void v8::Object::SetInternalField(int index, v8::Local value) { +void v8::Object::SetInternalField(int index, v8::Local value) { i::Handle obj = Utils::OpenHandle(this); const char* location = "v8::Object::SetInternalField()"; if (!InternalFieldOK(obj, index, location)) return; diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.cc b/deps/v8/src/codegen/s390/macro-assembler-s390.cc index 7f88a15259ad74..4dcfb9b00475a6 100644 --- a/deps/v8/src/codegen/s390/macro-assembler-s390.cc +++ b/deps/v8/src/codegen/s390/macro-assembler-s390.cc @@ -2906,8 +2906,23 @@ void MacroAssembler::MulS64(Register dst, const MemOperand& opnd) { } void MacroAssembler::MulHighS64(Register dst, Register src1, Register src2) { - mgrk(r0, src1, src2); - lgr(dst, r0); + if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) { + mgrk(r0, src1, src2); + lgr(dst, r0); + } else { + SaveFPRegsMode fp_mode = SaveFPRegsMode::kSave; + PushCallerSaved(fp_mode, ip); + Push(src1, src2); + Pop(r2, r3); + { + FrameScope scope(this, StackFrame::INTERNAL); + PrepareCallCFunction(2, 0, r0); + CallCFunction(ExternalReference::int64_mul_high_function(), 2, 0); + } + mov(r0, r2); + PopCallerSaved(fp_mode, ip); + mov(dst, r0); + } } void MacroAssembler::MulHighS64(Register dst, Register src1, diff --git a/deps/v8/src/compiler/backend/s390/code-generator-s390.cc b/deps/v8/src/compiler/backend/s390/code-generator-s390.cc index 510616a82f9c93..d2cb552b9c0915 100644 --- a/deps/v8/src/compiler/backend/s390/code-generator-s390.cc +++ b/deps/v8/src/compiler/backend/s390/code-generator-s390.cc @@ -1699,15 +1699,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kS390_Mul64WithOverflow: { Register dst = i.OutputRegister(), src1 = i.InputRegister(0), src2 = i.InputRegister(1); - DCHECK(!AreAliased(dst, src1, src2)); + CHECK(!AreAliased(dst, src1, src2)); if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) { __ msgrkc(dst, src1, src2); } else { - __ mgrk(r0, src1, src2); // r0 = high 64-bits, r1 = low 64-bits. - __ lgr(dst, r1); - __ ShiftRightS64(r1, r1, Operand(63)); + // Mul high. + __ MulHighS64(r1, src1, src2); + // Mul low. + __ mov(dst, src1); + __ MulS64(dst, src2); // Test whether {high} is a sign-extension of {result}. - __ CmpU64(r0, r1); + __ ShiftRightS64(r0, dst, Operand(63)); + __ CmpU64(r1, r0); } break; } @@ -1725,20 +1728,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ASSEMBLE_BIN_OP(RRRInstr(MulHighU64), nullInstr, nullInstr); break; case kS390_MulHighS64: - if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) { - ASSEMBLE_BIN_OP(RRRInstr(MulHighS64), nullInstr, nullInstr); - } else { - __ Push(r2, r3, i.InputRegister(0), i.InputRegister(1)); - __ Pop(r2, r3); - { - FrameScope scope(masm(), StackFrame::INTERNAL); - __ PrepareCallCFunction(2, 0, kScratchReg); - __ CallCFunction(ExternalReference::int64_mul_high_function(), 2, 0); - } - __ mov(kScratchReg, r2); - __ Pop(r2, r3); - __ mov(i.OutputRegister(), kScratchReg); - } + ASSEMBLE_BIN_OP(RRRInstr(MulHighS64), nullInstr, nullInstr); break; case kS390_MulFloat: ASSEMBLE_BIN_OP(DDInstr(meebr), DMTInstr(MulFloat32), nullInstr); diff --git a/deps/v8/src/flags/flags.cc b/deps/v8/src/flags/flags.cc index e41b71f85ec657..78d7b82354cb04 100644 --- a/deps/v8/src/flags/flags.cc +++ b/deps/v8/src/flags/flags.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "src/base/functional.h" @@ -103,7 +104,12 @@ struct Flag { const char* cmt_; // A comment about the flags purpose. bool owns_ptr_; // Does the flag own its string value? SetBy set_by_ = SetBy::kDefault; + // Name of the flag implying this flag, if any. const char* implied_by_ = nullptr; +#ifdef DEBUG + // Pointer to the flag implying this flag, if any. + const Flag* implied_by_ptr_ = nullptr; +#endif FlagType type() const { return type_; } @@ -113,6 +119,17 @@ struct Flag { bool PointsTo(const void* ptr) const { return valptr_ == ptr; } +#ifdef DEBUG + bool ImpliedBy(const void* ptr) const { + const Flag* current = this->implied_by_ptr_; + while (current != nullptr) { + if (current->PointsTo(ptr)) return true; + current = current->implied_by_ptr_; + } + return false; + } +#endif + bool bool_variable() const { return GetValue(); } void set_bool_variable(bool value, SetBy set_by) { @@ -333,6 +350,15 @@ struct Flag { if (IsAnyImplication(new_set_by)) { DCHECK_NOT_NULL(implied_by); implied_by_ = implied_by; +#ifdef DEBUG + // This only works when implied_by is a flag_name or !flag_name, but it + // can also be a condition e.g. flag_name > 3. Since this is only used for + // checks in DEBUG mode, we will just ignore the more complex conditions + // for now - that will just lead to a nullptr which won't be followed. + implied_by_ptr_ = static_cast( + FindFlagByName(implied_by[0] == '!' ? implied_by + 1 : implied_by)); + DCHECK_NE(implied_by_ptr_, this); +#endif } return change_flag; } @@ -534,15 +560,70 @@ uint32_t ComputeFlagListHash() { std::ostringstream modified_args_as_string; if (COMPRESS_POINTERS_BOOL) modified_args_as_string << "ptr-compr"; if (DEBUG_BOOL) modified_args_as_string << "debug"; + +#ifdef DEBUG + // These two sets are used to check that we don't leave out any flags + // implied by --predictable in the list below. + std::set flags_implied_by_predictable; + std::set flags_ignored_because_of_predictable; +#endif + for (const Flag& flag : flags) { if (flag.IsDefault()) continue; +#ifdef DEBUG + if (flag.ImpliedBy(&v8_flags.predictable)) { + flags_implied_by_predictable.insert(flag.name()); + } +#endif // We want to be able to flip --profile-deserialization without // causing the code cache to get invalidated by this hash. if (flag.PointsTo(&v8_flags.profile_deserialization)) continue; - // Skip v8_flags.random_seed to allow predictable code caching. + // Skip v8_flags.random_seed and v8_flags.predictable to allow predictable + // code caching. if (flag.PointsTo(&v8_flags.random_seed)) continue; + if (flag.PointsTo(&v8_flags.predictable)) continue; + + // The following flags are implied by --predictable (some negated). + if (flag.PointsTo(&v8_flags.concurrent_sparkplug) || + flag.PointsTo(&v8_flags.concurrent_recompilation) || +#ifdef V8_ENABLE_MAGLEV + flag.PointsTo(&v8_flags.maglev_deopt_data_on_background) || + flag.PointsTo(&v8_flags.maglev_build_code_on_background) || +#endif + flag.PointsTo(&v8_flags.parallel_scavenge) || + flag.PointsTo(&v8_flags.concurrent_marking) || + flag.PointsTo(&v8_flags.concurrent_array_buffer_sweeping) || + flag.PointsTo(&v8_flags.parallel_marking) || + flag.PointsTo(&v8_flags.concurrent_sweeping) || + flag.PointsTo(&v8_flags.parallel_compaction) || + flag.PointsTo(&v8_flags.parallel_pointer_update) || + flag.PointsTo(&v8_flags.memory_reducer) || + flag.PointsTo(&v8_flags.cppheap_concurrent_marking) || + flag.PointsTo(&v8_flags.cppheap_incremental_marking) || + flag.PointsTo(&v8_flags.single_threaded_gc)) { +#ifdef DEBUG + if (flag.ImpliedBy(&v8_flags.predictable)) { + flags_ignored_because_of_predictable.insert(flag.name()); + } +#endif + continue; + } modified_args_as_string << flag; } + +#ifdef DEBUG + for (const char* name : flags_implied_by_predictable) { + if (flags_ignored_because_of_predictable.find(name) == + flags_ignored_because_of_predictable.end()) { + PrintF( + "%s should be added to the list of " + "flags_ignored_because_of_predictable\n", + name); + UNREACHABLE(); + } + } +#endif + std::string args(modified_args_as_string.str()); // Generate a hash that is not 0. uint32_t hash = static_cast(base::hash_range( diff --git a/deps/v8/src/heap/cppgc-js/cpp-heap.cc b/deps/v8/src/heap/cppgc-js/cpp-heap.cc index 7481a81c4a832e..81fe3fb4497d89 100644 --- a/deps/v8/src/heap/cppgc-js/cpp-heap.cc +++ b/deps/v8/src/heap/cppgc-js/cpp-heap.cc @@ -147,6 +147,10 @@ void CppHeap::CollectGarbageInYoungGenerationForTesting( internal::CppHeap::CollectionType::kMinor, stack_state); } +v8::WrapperDescriptor CppHeap::wrapper_descriptor() const { + return internal::CppHeap::From(this)->wrapper_descriptor(); +} + namespace internal { namespace { diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index af7dfbf03ce2d8..230e57c4795a78 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -2874,6 +2874,43 @@ THREADED_TEST(FunctionPrototype) { CHECK_EQ(v8_run_int32value(script), 321); } +bool internal_field_check_called = false; +void OnInternalFieldCheck(const char* location, const char* message) { + internal_field_check_called = true; + exit(strcmp(location, "v8::Value::Cast") + + strcmp(message, "Data is not a Value")); +} + +THREADED_TEST(InternalDataFields) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + Local templ = v8::FunctionTemplate::New(isolate); + Local instance_templ = templ->InstanceTemplate(); + instance_templ->SetInternalFieldCount(1); + Local obj = templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + CHECK_EQ(1, obj->InternalFieldCount()); + Local data = obj->GetInternalField(0); + CHECK(data->IsValue() && data.As()->IsUndefined()); + Local sym = v8::Private::New(isolate, v8_str("Foo")); + obj->SetInternalField(0, sym); + Local field = obj->GetInternalField(0); + CHECK(!field->IsValue()); + CHECK(field->IsPrivate()); + CHECK_EQ(sym, field); + +#ifdef V8_ENABLE_CHECKS + isolate->SetFatalErrorHandler(OnInternalFieldCheck); + USE(obj->GetInternalField(0).As()); + // If it's never called this would fail. + CHECK(internal_field_check_called); +#endif +} + THREADED_TEST(InternalFields) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); @@ -2887,9 +2924,12 @@ THREADED_TEST(InternalFields) { ->NewInstance(env.local()) .ToLocalChecked(); CHECK_EQ(1, obj->InternalFieldCount()); - CHECK(obj->GetInternalField(0)->IsUndefined()); + CHECK(obj->GetInternalField(0).As()->IsUndefined()); obj->SetInternalField(0, v8_num(17)); - CHECK_EQ(17, obj->GetInternalField(0)->Int32Value(env.local()).FromJust()); + CHECK_EQ(17, obj->GetInternalField(0) + .As() + ->Int32Value(env.local()) + .FromJust()); } TEST(InternalFieldsSubclassing) { @@ -2915,14 +2955,16 @@ TEST(InternalFieldsSubclassing) { CHECK_EQ(0, i_obj->map().GetInObjectProperties()); // Check writing and reading internal fields. for (int j = 0; j < nof_embedder_fields; j++) { - CHECK(obj->GetInternalField(j)->IsUndefined()); + CHECK(obj->GetInternalField(j).As()->IsUndefined()); int value = 17 + j; obj->SetInternalField(j, v8_num(value)); } for (int j = 0; j < nof_embedder_fields; j++) { int value = 17 + j; - CHECK_EQ(value, - obj->GetInternalField(j)->Int32Value(env.local()).FromJust()); + CHECK_EQ(value, obj->GetInternalField(j) + .As() + ->Int32Value(env.local()) + .FromJust()); } CHECK(env->Global() ->Set(env.local(), v8_str("BaseClass"), constructor) @@ -3022,9 +3064,12 @@ THREADED_TEST(GlobalObjectInternalFields) { v8::Local global_proxy = env->Global(); v8::Local global = global_proxy->GetPrototype().As(); CHECK_EQ(1, global->InternalFieldCount()); - CHECK(global->GetInternalField(0)->IsUndefined()); + CHECK(global->GetInternalField(0).As()->IsUndefined()); global->SetInternalField(0, v8_num(17)); - CHECK_EQ(17, global->GetInternalField(0)->Int32Value(env.local()).FromJust()); + CHECK_EQ(17, global->GetInternalField(0) + .As() + ->Int32Value(env.local()) + .FromJust()); } @@ -7766,7 +7811,7 @@ void InternalFieldCallback(bool global_gc) { .ToLocalChecked(); handle.Reset(isolate, obj); CHECK_EQ(2, obj->InternalFieldCount()); - CHECK(obj->GetInternalField(0)->IsUndefined()); + CHECK(obj->GetInternalField(0).As()->IsUndefined()); t1 = new Trivial(42); t2 = new Trivial2(103, 9); @@ -29858,7 +29903,8 @@ class HiddenDataDelegate : public v8::Context::DeepFreezeDelegate { std::vector>& children_out) override { int fields = obj->InternalFieldCount(); for (int idx = 0; idx < fields; idx++) { - v8::Local child_value = obj->GetInternalField(idx); + v8::Local child_value = + obj->GetInternalField(idx).As(); if (child_value->IsExternal()) { if (!FreezeExternal(v8::Local::Cast(child_value), children_out)) { diff --git a/deps/v8/test/cctest/test-api.h b/deps/v8/test/cctest/test-api.h index 0604deb9af8810..ba443198dbce2d 100644 --- a/deps/v8/test/cctest/test-api.h +++ b/deps/v8/test/cctest/test-api.h @@ -44,9 +44,11 @@ template static void CheckInternalFieldsAreZero(v8::Local value) { CHECK_EQ(T::kInternalFieldCount, value->InternalFieldCount()); for (int i = 0; i < value->InternalFieldCount(); i++) { - CHECK_EQ(0, value->GetInternalField(i) - ->Int32Value(CcTest::isolate()->GetCurrentContext()) - .FromJust()); + v8::Local field = + value->GetInternalField(i).template As(); + CHECK_EQ( + 0, + field->Int32Value(CcTest::isolate()->GetCurrentContext()).FromJust()); } } diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index ee9cb5493bee07..e5135a5b04d390 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -3577,23 +3577,27 @@ UNINITIALIZED_TEST(SnapshotCreatorTemplates) { .ToLocalChecked() ->ToObject(context) .ToLocalChecked(); - v8::Local b = - a->GetInternalField(0)->ToObject(context).ToLocalChecked(); - v8::Local c = - b->GetInternalField(0)->ToObject(context).ToLocalChecked(); + v8::Local b = a->GetInternalField(0) + .As() + ->ToObject(context) + .ToLocalChecked(); + v8::Local c = b->GetInternalField(0) + .As() + ->ToObject(context) + .ToLocalChecked(); InternalFieldData* a1 = reinterpret_cast( a->GetAlignedPointerFromInternalField(1)); - v8::Local a2 = a->GetInternalField(2); + v8::Local a2 = a->GetInternalField(2).As(); InternalFieldData* b1 = reinterpret_cast( b->GetAlignedPointerFromInternalField(1)); - v8::Local b2 = b->GetInternalField(2); + v8::Local b2 = b->GetInternalField(2).As(); - v8::Local c0 = c->GetInternalField(0); + v8::Local c0 = c->GetInternalField(0).As(); InternalFieldData* c1 = reinterpret_cast( c->GetAlignedPointerFromInternalField(1)); - v8::Local c2 = c->GetInternalField(2); + v8::Local c2 = c->GetInternalField(2).As(); CHECK(c0->IsUndefined()); diff --git a/deps/v8/test/mjsunit/regress/regress-1320641.js b/deps/v8/test/mjsunit/regress/regress-1320641.js index 6c52c9d178606d..6bd109421a94af 100644 --- a/deps/v8/test/mjsunit/regress/regress-1320641.js +++ b/deps/v8/test/mjsunit/regress/regress-1320641.js @@ -8,9 +8,21 @@ function foo(){ const xs = new Uint16Array(3775336418); return xs[-981886074]; } -%PrepareFunctionForOptimization(foo); -foo(); -assertEquals(undefined, foo()); -%OptimizeFunctionOnNextCall(foo); -assertEquals(undefined, foo()); +var skip = false; +try { + new Uint16Array(3775336418); +} catch (e) { + if (/Array buffer allocation failed/.test(e.message)) { + skip = true; // We don't have enough memory, just skip the test. + } +} + +if (!skip) { + %PrepareFunctionForOptimization(foo); + foo(); + + assertEquals(undefined, foo()); + %OptimizeFunctionOnNextCall(foo); + assertEquals(undefined, foo()); +} diff --git a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc index 3934eb8b008515..31b0ee07aac74d 100644 --- a/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc +++ b/deps/v8/test/unittests/heap/cppgc-js/unified-heap-unittest.cc @@ -706,4 +706,45 @@ TEST_F(UnifiedHeapTest, TracedReferenceHandlesDoNotLeak) { EXPECT_EQ(initial_count, final_count + 1); } +namespace { +class Wrappable2 final : public cppgc::GarbageCollected { + public: + static size_t destructor_call_count; + void Trace(cppgc::Visitor* visitor) const {} + ~Wrappable2() { destructor_call_count++; } +}; + +size_t Wrappable2::destructor_call_count = 0; +} // namespace + +TEST_F(UnifiedHeapTest, WrapperDescriptorGetter) { + v8::Isolate* isolate = v8_isolate(); + v8::HandleScope scope(isolate); + auto* wrappable_object = + cppgc::MakeGarbageCollected(allocation_handle()); + v8::WrapperDescriptor descriptor = + isolate->GetCppHeap()->wrapper_descriptor(); + v8::Local tmpl = v8::ObjectTemplate::New(isolate); + int size = std::max(descriptor.wrappable_type_index, + descriptor.wrappable_instance_index) + + 1; + tmpl->SetInternalFieldCount(size); + v8::Local api_object = + tmpl->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); + api_object->SetAlignedPointerInInternalField( + descriptor.wrappable_type_index, + &descriptor.embedder_id_for_garbage_collected); + api_object->SetAlignedPointerInInternalField( + descriptor.wrappable_instance_index, wrappable_object); + + Wrappable2::destructor_call_count = 0; + EXPECT_EQ(0u, Wrappable2::destructor_call_count); + CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic); + EXPECT_EQ(0u, Wrappable2::destructor_call_count); + api_object->SetAlignedPointerInInternalField( + descriptor.wrappable_instance_index, nullptr); + CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic); + EXPECT_EQ(1u, Wrappable2::destructor_call_count); +} + } // namespace v8::internal diff --git a/deps/v8/test/unittests/objects/value-serializer-unittest.cc b/deps/v8/test/unittests/objects/value-serializer-unittest.cc index bf81b745dea261..8298dc9decd888 100644 --- a/deps/v8/test/unittests/objects/value-serializer-unittest.cc +++ b/deps/v8/test/unittests/objects/value-serializer-unittest.cc @@ -61,12 +61,14 @@ class ValueSerializerTest : public TestWithIsolate { function_template->InstanceTemplate()->SetAccessor( StringFromUtf8("value"), [](Local property, const PropertyCallbackInfo& args) { - args.GetReturnValue().Set(args.Holder()->GetInternalField(0)); + args.GetReturnValue().Set( + args.Holder()->GetInternalField(0).As()); }); function_template->InstanceTemplate()->SetAccessor( StringFromUtf8("value2"), [](Local property, const PropertyCallbackInfo& args) { - args.GetReturnValue().Set(args.Holder()->GetInternalField(1)); + args.GetReturnValue().Set( + args.Holder()->GetInternalField(1).As()); }); for (Local context : {serialization_context_, deserialization_context_}) { @@ -2897,6 +2899,7 @@ TEST_F(ValueSerializerTestWithHostObject, RoundTripUint32) { .WillRepeatedly(Invoke([this](Isolate*, Local object) { uint32_t value = 0; EXPECT_TRUE(object->GetInternalField(0) + .As() ->Uint32Value(serialization_context()) .To(&value)); WriteExampleHostObjectTag(); @@ -2928,9 +2931,11 @@ TEST_F(ValueSerializerTestWithHostObject, RoundTripUint64) { .WillRepeatedly(Invoke([this](Isolate*, Local object) { uint32_t value = 0, value2 = 0; EXPECT_TRUE(object->GetInternalField(0) + .As() ->Uint32Value(serialization_context()) .To(&value)); EXPECT_TRUE(object->GetInternalField(1) + .As() ->Uint32Value(serialization_context()) .To(&value2)); WriteExampleHostObjectTag(); @@ -2968,6 +2973,7 @@ TEST_F(ValueSerializerTestWithHostObject, RoundTripDouble) { .WillRepeatedly(Invoke([this](Isolate*, Local object) { double value = 0; EXPECT_TRUE(object->GetInternalField(0) + .As() ->NumberValue(serialization_context()) .To(&value)); WriteExampleHostObjectTag(); diff --git a/deps/zlib/BUILD.gn b/deps/zlib/BUILD.gn index 9b3971041dffa0..8ed0807a994b1e 100644 --- a/deps/zlib/BUILD.gn +++ b/deps/zlib/BUILD.gn @@ -124,45 +124,40 @@ source_set("zlib_adler32_simd") { if (use_arm_neon_optimizations) { config("zlib_arm_crc32_config") { - # Disabled for iPhone, as described in DDI0487C_a_armv8_arm: - # "All implementations of the ARMv8.1 architecture are required to - # implement the CRC32* instructions. These are optional in ARMv8.0." - if (!is_ios) { - defines = [ "CRC32_ARMV8_CRC32" ] - if (is_android) { - defines += [ "ARMV8_OS_ANDROID" ] - } else if (is_linux || is_chromeos) { - defines += [ "ARMV8_OS_LINUX" ] - } else if (is_mac) { - defines += [ "ARMV8_OS_MACOS" ] - } else if (is_fuchsia) { - defines += [ "ARMV8_OS_FUCHSIA" ] - } else if (is_win) { - defines += [ "ARMV8_OS_WINDOWS" ] - } else { - assert(false, "Unsupported ARM OS") - } + defines = [ "CRC32_ARMV8_CRC32" ] + if (is_android) { + defines += [ "ARMV8_OS_ANDROID" ] + } else if (is_linux || is_chromeos) { + defines += [ "ARMV8_OS_LINUX" ] + } else if (is_mac) { + defines += [ "ARMV8_OS_MACOS" ] + } else if (is_ios) { + defines += [ "ARMV8_OS_IOS" ] + } else if (is_fuchsia) { + defines += [ "ARMV8_OS_FUCHSIA" ] + } else if (is_win) { + defines += [ "ARMV8_OS_WINDOWS" ] + } else { + assert(false, "Unsupported ARM OS") } } source_set("zlib_arm_crc32") { visibility = [ ":*" ] - if (!is_ios) { - include_dirs = [ "." ] - - if (!is_win && !is_clang) { - assert(!use_thin_lto, - "ThinLTO fails mixing different module-level targets") - cflags_c = [ "-march=armv8-a+aes+crc" ] - } + include_dirs = [ "." ] - sources = [ - "crc32_simd.c", - "crc32_simd.h", - ] + if (!is_win && !is_clang) { + assert(!use_thin_lto, + "ThinLTO fails mixing different module-level targets") + cflags_c = [ "-march=armv8-a+aes+crc" ] } + sources = [ + "crc32_simd.c", + "crc32_simd.h", + ] + configs += [ ":zlib_internal_config" ] public_configs = [ ":zlib_arm_crc32_config" ] @@ -332,14 +327,6 @@ component("zlib") { defines += [ "CPU_NO_SIMD" ] } - if (is_ios) { - # iOS@ARM is a special case where we always have NEON but don't check - # for crypto extensions. - # TODO(cavalcantii): verify what is the current state of CPU features - # shipped on latest iOS devices. - defines += [ "ARM_OS_IOS" ] - } - if (use_x86_x64_optimizations || use_arm_neon_optimizations) { deps += [ ":zlib_adler32_simd", @@ -398,6 +385,11 @@ config("minizip_warnings") { } static_library("minizip") { + include_dirs = [ + ".", + "//third_party/zlib", + ] + sources = [ "contrib/minizip/ioapi.c", "contrib/minizip/ioapi.h", @@ -520,6 +512,7 @@ if (build_with_chromium) { } deps = [ + ":minizip", ":zlib", "google:compression_utils", "google:zip", diff --git a/deps/zlib/CMakeLists.txt b/deps/zlib/CMakeLists.txt index 378a3792f4ba8f..471a3a46a09dd6 100644 --- a/deps/zlib/CMakeLists.txt +++ b/deps/zlib/CMakeLists.txt @@ -23,6 +23,11 @@ check_include_file(stddef.h HAVE_STDDEF_H) option(ENABLE_SIMD_OPTIMIZATIONS "Enable all SIMD optimizations" OFF) option(ENABLE_SIMD_AVX512 "Enable SIMD AXV512 optimizations" OFF) +option(USE_ZLIB_RABIN_KARP_HASH "Enable bitstream compatibility with canonical zlib" OFF) + +if (USE_ZLIB_RABIN_KARP_HASH) + add_definitions(-DUSE_ZLIB_RABIN_KARP_ROLLING_HASH) +endif() # TODO(cavalcantii): add support for other OSes (e.g. Android, fuchsia, osx) # and architectures (e.g. Arm). @@ -238,3 +243,12 @@ enable_language(CXX) set(CMAKE_CXX_STANDARD 14) # workaround for older compilers (e.g. g++ 5.4). add_executable(zlib_bench contrib/bench/zlib_bench.cc) target_link_libraries(zlib_bench zlib) + +#============================================================================ +# Minigzip tool +#============================================================================ +add_executable(minizip_bin contrib/minizip/minizip.c contrib/minizip/ioapi.c +contrib/minizip/ioapi.h contrib/minizip/unzip.c +contrib/minizip/unzip.h contrib/minizip/zip.c contrib/minizip/zip.h +) +target_link_libraries(minizip_bin zlib) diff --git a/deps/zlib/README.chromium b/deps/zlib/README.chromium index 190430f5325ce6..663ee0521ed30c 100644 --- a/deps/zlib/README.chromium +++ b/deps/zlib/README.chromium @@ -4,6 +4,7 @@ URL: http://zlib.net/ Version: 1.2.13 CPEPrefix: cpe:/a:zlib:zlib:1.2.13 Security Critical: yes +Shipped: yes License: Custom license License File: LICENSE License Android Compatible: yes diff --git a/deps/zlib/adler32.c b/deps/zlib/adler32.c index 81c584f68e2331..99a294496f7eb5 100644 --- a/deps/zlib/adler32.c +++ b/deps/zlib/adler32.c @@ -90,9 +90,9 @@ uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { return adler | (sum2 << 16); } -#if defined(ADLER32_SIMD_SSSE3) +#if defined(ADLER32_SIMD_SSSE3) || defined(ADLER32_SIMD_NEON) /* - * Use SSSE3 to compute the adler32. Since this routine can be + * Use SIMD to compute the adler32. Since this function can be * freely used, check CPU features here. zlib convention is to * call adler32(0, NULL, 0), before making calls to adler32(). * So this is a good early (and infrequent) place to cache CPU diff --git a/deps/zlib/contrib/bench/zlib_bench.cc b/deps/zlib/contrib/bench/zlib_bench.cc index 8580319edf25bc..b65f9291bff500 100644 --- a/deps/zlib/contrib/bench/zlib_bench.cc +++ b/deps/zlib/contrib/bench/zlib_bench.cc @@ -236,7 +236,11 @@ void check_file(const Data& file, zlib_wrapper type, int mode) { error_exit("check file: error writing output", 3); } -void zlib_file(const char* name, zlib_wrapper type, int width, int check) { +void zlib_file(const char* name, + zlib_wrapper type, + int width, + int check, + bool output_csv_format) { /* * Read the file data. */ @@ -257,7 +261,9 @@ void zlib_file(const char* name, zlib_wrapper type, int width, int check) { * Report compression strategy and file name. */ const char* strategy = zlib_level_strategy_name(zlib_compression_level); - printf("%s%-40s :\n", strategy, name); + if (!output_csv_format) { + printf("%s%-40s :\n", strategy, name); + } /* * Chop the data into blocks. @@ -329,19 +335,28 @@ void zlib_file(const char* name, zlib_wrapper type, int width, int check) { std::sort(ctime, ctime + runs); std::sort(utime, utime + runs); - double deflate_rate_med = length * repeats / mega_byte / ctime[runs / 2]; - double inflate_rate_med = length * repeats / mega_byte / utime[runs / 2]; - double deflate_rate_max = length * repeats / mega_byte / ctime[0]; - double inflate_rate_max = length * repeats / mega_byte / utime[0]; - - // type, block size, compression ratio, etc - printf("%s: [b %dM] bytes %*d -> %*u %4.2f%%", - zlib_wrapper_name(type), block_size / (1 << 20), width, length, width, - unsigned(output_length), output_length * 100.0 / length); - - // compress / uncompress median (max) rates - printf(" comp %5.1f (%5.1f) MB/s uncomp %5.1f (%5.1f) MB/s\n", - deflate_rate_med, deflate_rate_max, inflate_rate_med, inflate_rate_max); + double deflate_rate_med, inflate_rate_med, deflate_rate_max, inflate_rate_max; + deflate_rate_med = length * repeats / mega_byte / ctime[runs / 2]; + inflate_rate_med = length * repeats / mega_byte / utime[runs / 2]; + deflate_rate_max = length * repeats / mega_byte / ctime[0]; + inflate_rate_max = length * repeats / mega_byte / utime[0]; + double compress_ratio = output_length * 100.0 / length; + + if (!output_csv_format) { + // type, block size, compression ratio, etc + printf("%s: [b %dM] bytes %*d -> %*u %4.2f%%", zlib_wrapper_name(type), + block_size / (1 << 20), width, length, width, + unsigned(output_length), compress_ratio); + + // compress / uncompress median (max) rates + printf(" comp %5.1f (%5.1f) MB/s uncomp %5.1f (%5.1f) MB/s\n", + deflate_rate_med, deflate_rate_max, inflate_rate_med, + inflate_rate_max); + } else { + printf("%s\t%.5lf\t%.5lf\t%.5lf\t%.5lf\t%.5lf\n", name, deflate_rate_med, + inflate_rate_med, deflate_rate_max, inflate_rate_max, + compress_ratio); + } } static int argn = 1; @@ -363,8 +378,10 @@ void get_field_width(int argc, char* argv[], int& value) { } void usage_exit(const char* program) { - static auto* options = "gzip|zlib|raw" - " [--compression 0:9] [--huffman|--rle] [--field width] [--check]"; + static auto* options = + "gzip|zlib|raw" + " [--compression 0:9] [--huffman|--rle] [--field width] [--check]" + " [--csv]"; printf("usage: %s %s files ...\n", program, options); printf("zlib version: %s\n", ZLIB_VERSION); exit(1); @@ -383,7 +400,7 @@ int main(int argc, char* argv[]) { int size_field_width = 0; int file_check = 0; - + bool output_csv = false; while (argn < argc && argv[argn][0] == '-') { if (get_option(argc, argv, "--compression")) { if (!get_compression(argc, argv, zlib_compression_level)) @@ -398,6 +415,11 @@ int main(int argc, char* argv[]) { file_check = 2; } else if (get_option(argc, argv, "--field")) { get_field_width(argc, argv, size_field_width); + } else if (get_option(argc, argv, "--csv")) { + output_csv = true; + printf( + "filename\tcompression\tdecompression\tcomp_max\t" + "decomp_max\tcompress_ratio\n"); } else { usage_exit(argv[0]); } @@ -408,8 +430,9 @@ int main(int argc, char* argv[]) { if (size_field_width < 6) size_field_width = 6; - while (argn < argc) - zlib_file(argv[argn++], type, size_field_width, file_check); + while (argn < argc) { + zlib_file(argv[argn++], type, size_field_width, file_check, output_csv); + } return 0; } diff --git a/deps/zlib/contrib/minizip/README.chromium b/deps/zlib/contrib/minizip/README.chromium index 1ad489a6780db2..9c780f94682075 100644 --- a/deps/zlib/contrib/minizip/README.chromium +++ b/deps/zlib/contrib/minizip/README.chromium @@ -3,7 +3,9 @@ Short Name: minizip URL: https://github.com/madler/zlib/tree/master/contrib/minizip Version: 1.2.12 License: Zlib +License File: //third_party/zlib/LICENSE Security Critical: yes +Shipped: yes Description: Minizip provides API on top of zlib that can enumerate and extract ZIP archive @@ -13,3 +15,6 @@ Local Modifications: - Add parsing of the 'Info-ZIP Unicode Path Extra Field' as described in https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT section 4.6.9. (see crrev.com/1002476) + +- Check for overly long filename, comment, or extra field in + zipOpenNewFileInZip4_64 (crbug.com/1470539). diff --git a/deps/zlib/contrib/minizip/ioapi.h b/deps/zlib/contrib/minizip/ioapi.h index c1b7a54847f552..8dcbdb06e35ad5 100644 --- a/deps/zlib/contrib/minizip/ioapi.h +++ b/deps/zlib/contrib/minizip/ioapi.h @@ -43,7 +43,7 @@ #include #include -#include "third_party/zlib/zlib.h" +#include "zlib.h" #if defined(USE_FILE32API) #define fopen64 fopen diff --git a/deps/zlib/contrib/minizip/mztools.c b/deps/zlib/contrib/minizip/mztools.c index 8bf9cca326338a..96891c2e0b71ef 100644 --- a/deps/zlib/contrib/minizip/mztools.c +++ b/deps/zlib/contrib/minizip/mztools.c @@ -8,7 +8,7 @@ #include #include #include -#include "third_party/zlib/zlib.h" +#include "zlib.h" #include "unzip.h" #define READ_8(adr) ((unsigned char)*(adr)) diff --git a/deps/zlib/contrib/minizip/mztools.h b/deps/zlib/contrib/minizip/mztools.h index f295ffeda6afcf..a49a426ec2fcb2 100644 --- a/deps/zlib/contrib/minizip/mztools.h +++ b/deps/zlib/contrib/minizip/mztools.h @@ -12,7 +12,7 @@ extern "C" { #endif #ifndef _ZLIB_H -#include "third_party/zlib/zlib.h" +#include "zlib.h" #endif #include "unzip.h" diff --git a/deps/zlib/contrib/minizip/unzip.c b/deps/zlib/contrib/minizip/unzip.c index 0a1d8b4fe2cf78..4973a4eea97b99 100644 --- a/deps/zlib/contrib/minizip/unzip.c +++ b/deps/zlib/contrib/minizip/unzip.c @@ -68,7 +68,7 @@ #include #include -#include "third_party/zlib/zlib.h" +#include "zlib.h" #include "unzip.h" #ifdef STDC diff --git a/deps/zlib/contrib/minizip/unzip.h b/deps/zlib/contrib/minizip/unzip.h index 3c0143529b9144..2104e39150749b 100644 --- a/deps/zlib/contrib/minizip/unzip.h +++ b/deps/zlib/contrib/minizip/unzip.h @@ -48,7 +48,7 @@ extern "C" { #endif #ifndef _ZLIB_H -#include "third_party/zlib/zlib.h" +#include "zlib.h" #endif #ifndef _ZLIBIOAPI_H diff --git a/deps/zlib/contrib/minizip/zip.c b/deps/zlib/contrib/minizip/zip.c index 65c0c7251843c0..f21d4954286af4 100644 --- a/deps/zlib/contrib/minizip/zip.c +++ b/deps/zlib/contrib/minizip/zip.c @@ -26,7 +26,7 @@ #include #include #include -#include "third_party/zlib/zlib.h" +#include "zlib.h" #include "zip.h" #ifdef STDC @@ -1083,6 +1083,17 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, return ZIP_PARAMERROR; #endif + // The filename and comment length must fit in 16 bits. + if ((filename!=NULL) && (strlen(filename)>0xffff)) + return ZIP_PARAMERROR; + if ((comment!=NULL) && (strlen(comment)>0xffff)) + return ZIP_PARAMERROR; + // The extra field length must fit in 16 bits. If the member also requires + // a Zip64 extra block, that will also need to fit within that 16-bit + // length, but that will be checked for later. + if ((size_extrafield_local>0xffff) || (size_extrafield_global>0xffff)) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; if (zi->in_opened_file_inzip == 1) diff --git a/deps/zlib/contrib/minizip/zip.h b/deps/zlib/contrib/minizip/zip.h index 8c06c0aa7bb08b..8aaebb623430fc 100644 --- a/deps/zlib/contrib/minizip/zip.h +++ b/deps/zlib/contrib/minizip/zip.h @@ -47,7 +47,7 @@ extern "C" { //#define HAVE_BZIP2 #ifndef _ZLIB_H -#include "third_party/zlib/zlib.h" +#include "zlib.h" #endif #ifndef _ZLIBIOAPI_H diff --git a/deps/zlib/contrib/tests/DEPS b/deps/zlib/contrib/tests/DEPS index 42751740686776..67973613c74138 100644 --- a/deps/zlib/contrib/tests/DEPS +++ b/deps/zlib/contrib/tests/DEPS @@ -1,4 +1,5 @@ include_rules = [ "+testing/gtest", + "+third_party/zlib/contrib/minizip", "+base", ] diff --git a/deps/zlib/contrib/tests/utils_unittest.cc b/deps/zlib/contrib/tests/utils_unittest.cc index 5745939f24f9d1..7270d0af90855f 100644 --- a/deps/zlib/contrib/tests/utils_unittest.cc +++ b/deps/zlib/contrib/tests/utils_unittest.cc @@ -7,8 +7,12 @@ #include #include +#include "base/files/file_path.h" +#include "base/files/scoped_temp_dir.h" #include "compression_utils_portable.h" #include "gtest.h" +#include "third_party/zlib/contrib/minizip/unzip.h" +#include "third_party/zlib/contrib/minizip/zip.h" #include "zlib.h" void TestPayloads(size_t input_size, zlib_internal::WrapperType type) { @@ -1015,3 +1019,122 @@ TEST(ZlibTest, DeflateZFixedCorruption) { memcmp(zFixedCorruptionData, decompressed.data(), decompressed.size()), 0); } + +TEST(ZlibTest, ZipFilenameCommentSize) { + // Check that minizip rejects zip member filenames or comments longer than + // the zip format can represent. + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath zip_file = temp_dir.GetPath().AppendASCII("crbug1470539.zip"); + + zipFile zf = zipOpen(zip_file.AsUTF8Unsafe().c_str(), APPEND_STATUS_CREATE); + ASSERT_NE(zf, nullptr); + + // Adding a member with 2^16 byte filename is okay. + std::string long_filename(UINT16_MAX, 'a'); + EXPECT_EQ(zipOpenNewFileInZip(zf, long_filename.c_str(), nullptr, nullptr, 0, + nullptr, 0, nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_OK); + EXPECT_EQ(zipWriteInFileInZip(zf, "1", 1), ZIP_OK); + EXPECT_EQ(zipCloseFileInZip(zf), ZIP_OK); + + // Adding a member with 2^16+1 byte filename is NOT okay. + std::string too_long_filename = long_filename + 'a'; + EXPECT_EQ(zipOpenNewFileInZip(zf, too_long_filename.c_str(), nullptr, nullptr, + 0, nullptr, 0, nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + + // Adding a member with 2^16 byte comment is okay. + std::string long_comment(UINT16_MAX, 'x'); + EXPECT_EQ(zipOpenNewFileInZip(zf, "x", nullptr, nullptr, 0, nullptr, 0, + long_comment.c_str(), Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_OK); + EXPECT_EQ(zipCloseFileInZip(zf), ZIP_OK); + + // Adding a member with 2^16+1 byte comment is NOT okay. + std::string too_long_comment = long_comment + 'x'; + EXPECT_EQ(zipOpenNewFileInZip(zf, "x", nullptr, nullptr, 0, nullptr, 0, + too_long_comment.c_str(), Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + + EXPECT_EQ(zipClose(zf, nullptr), ZIP_OK); + + // Check that the long filename and comment members were successfully added. + unzFile uzf = unzOpen(zip_file.AsUTF8Unsafe().c_str()); + ASSERT_NE(uzf, nullptr); + char buf[UINT16_MAX + 2]; + + ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); + ASSERT_EQ(unzGetCurrentFileInfo(uzf, nullptr, buf, sizeof(buf), nullptr, 0, + nullptr, 0), + UNZ_OK); + EXPECT_EQ(std::string(buf), long_filename); + + ASSERT_EQ(unzGoToNextFile(uzf), UNZ_OK); + ASSERT_EQ(unzGetCurrentFileInfo(uzf, nullptr, nullptr, 0, nullptr, 0, buf, + sizeof(buf)), + UNZ_OK); + EXPECT_EQ(std::string(buf), long_comment); + + EXPECT_EQ(unzGoToNextFile(uzf), UNZ_END_OF_LIST_OF_FILE); + EXPECT_EQ(unzClose(uzf), UNZ_OK); +} + +TEST(ZlibTest, ZipExtraFieldSize) { + // Check that minizip rejects zip members with too large extra fields. + + std::string extra_field; + extra_field.append("\x12\x34"); // Header ID. + extra_field.append("\xfb\xff"); // Data size (not including the header). + extra_field.append(UINT16_MAX - 4, 'a'); + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath zip_file = temp_dir.GetPath().AppendASCII("extrafield.zip"); + + zipFile zf = zipOpen(zip_file.AsUTF8Unsafe().c_str(), APPEND_STATUS_CREATE); + ASSERT_NE(zf, nullptr); + + // Adding a member with 2^16 byte extra field should work. + EXPECT_EQ(zipOpenNewFileInZip(zf, "a", nullptr, extra_field.data(), + extra_field.size(), extra_field.data(), + extra_field.size(), nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_OK); + EXPECT_EQ(zipWriteInFileInZip(zf, "1", 1), ZIP_OK); + EXPECT_EQ(zipCloseFileInZip(zf), ZIP_OK); + + // More then 2^16 bytes doesn't work. Neither for size_extrafield_local, nor + // size_extrafield_global. + std::string extra_field_long = extra_field + 'x'; + EXPECT_EQ( + zipOpenNewFileInZip(zf, "b", nullptr, nullptr, 0, extra_field_long.data(), + extra_field_long.size(), nullptr, Z_DEFLATED, + Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + EXPECT_EQ(zipOpenNewFileInZip(zf, "b", nullptr, extra_field_long.data(), + extra_field_long.size(), nullptr, 0, nullptr, + Z_DEFLATED, Z_DEFAULT_COMPRESSION), + ZIP_PARAMERROR); + + EXPECT_EQ(zipClose(zf, nullptr), ZIP_OK); + + // Check that the data can be read back. + unzFile uzf = unzOpen(zip_file.AsUTF8Unsafe().c_str()); + ASSERT_NE(uzf, nullptr); + char buf[UINT16_MAX + 1] = {0}; + + ASSERT_EQ(unzGoToFirstFile(uzf), UNZ_OK); + ASSERT_EQ(unzGetCurrentFileInfo(uzf, nullptr, nullptr, 0, buf, + sizeof(buf) - 1, nullptr, 0), + UNZ_OK); + EXPECT_EQ(std::string(buf), extra_field); + + EXPECT_EQ(unzGoToNextFile(uzf), UNZ_END_OF_LIST_OF_FILE); + EXPECT_EQ(unzClose(uzf), UNZ_OK); +} diff --git a/deps/zlib/cpu_features.c b/deps/zlib/cpu_features.c index ac6ee88e460e2e..64e0428cd2fc2d 100644 --- a/deps/zlib/cpu_features.c +++ b/deps/zlib/cpu_features.c @@ -35,7 +35,7 @@ int ZLIB_INTERNAL x86_cpu_enable_avx512 = 0; #ifndef CPU_NO_SIMD -#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_FUCHSIA) +#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_FUCHSIA) || defined(ARMV8_OS_IOS) #include #endif @@ -50,17 +50,19 @@ int ZLIB_INTERNAL x86_cpu_enable_avx512 = 0; #include #elif defined(ARMV8_OS_WINDOWS) || defined(X86_WINDOWS) #include +#elif defined(ARMV8_OS_IOS) +#include #elif !defined(_MSC_VER) #include #else #error cpu_features.c CPU feature detection in not defined for your platform #endif -#if !defined(CPU_NO_SIMD) && !defined(ARMV8_OS_MACOS) && !defined(ARM_OS_IOS) +#if !defined(CPU_NO_SIMD) && !defined(ARMV8_OS_MACOS) static void _cpu_check_features(void); #endif -#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_MACOS) || defined(ARMV8_OS_FUCHSIA) || defined(X86_NOT_WINDOWS) +#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_MACOS) || defined(ARMV8_OS_FUCHSIA) || defined(X86_NOT_WINDOWS) || defined(ARMV8_OS_IOS) #if !defined(ARMV8_OS_MACOS) // _cpu_check_features() doesn't need to do anything on mac/arm since all // features are known at build time, so don't call it. @@ -89,11 +91,7 @@ void ZLIB_INTERNAL cpu_check_features(void) #endif #if (defined(__ARM_NEON__) || defined(__ARM_NEON)) -/* - * iOS@ARM is a special case where we always have NEON but don't check - * for crypto extensions. - */ -#if !defined(ARMV8_OS_MACOS) && !defined(ARM_OS_IOS) +#if !defined(ARMV8_OS_MACOS) /* * See http://bit.ly/2CcoEsr for run-time detection of ARM features and also * crbug.com/931275 for android_getCpuFeatures() use in the Android sandbox. @@ -127,6 +125,18 @@ static void _cpu_check_features(void) #elif defined(ARMV8_OS_WINDOWS) arm_cpu_enable_crc32 = IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); arm_cpu_enable_pmull = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); +#elif defined(ARMV8_OS_IOS) + // Determine what features are supported dynamically. This code is applicable to macOS + // as well if we wish to do that dynamically on that platform in the future. + // See https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics + int val = 0; + size_t len = sizeof(val); + arm_cpu_enable_crc32 = sysctlbyname("hw.optional.armv8_crc32", &val, &len, 0, 0) == 0 + && val != 0; + val = 0; + len = sizeof(val); + arm_cpu_enable_pmull = sysctlbyname("hw.optional.arm.FEAT_PMULL", &val, &len, 0, 0) == 0 + && val != 0; #endif } #endif diff --git a/deps/zlib/google/zip_internal.cc b/deps/zlib/google/zip_internal.cc index c986e763cccda3..9b20b421e24765 100644 --- a/deps/zlib/google/zip_internal.cc +++ b/deps/zlib/google/zip_internal.cc @@ -8,12 +8,12 @@ #include #include -#include +#include "base/containers/fixed_flat_set.h" #include "base/files/file_path.h" #include "base/logging.h" -#include "base/no_destructor.h" #include "base/notreached.h" +#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -407,59 +407,59 @@ Compression GetCompressionMethod(const base::FilePath& path) { // Well known filename extensions of files that a likely to be already // compressed. The extensions are in lower case without the leading dot. - static const base::NoDestructor> exts( - std::initializer_list{ - FILE_PATH_LITERAL("3g2"), // - FILE_PATH_LITERAL("3gp"), // - FILE_PATH_LITERAL("7z"), // - FILE_PATH_LITERAL("7zip"), // - FILE_PATH_LITERAL("aac"), // - FILE_PATH_LITERAL("avi"), // - FILE_PATH_LITERAL("bz"), // - FILE_PATH_LITERAL("bz2"), // - FILE_PATH_LITERAL("crx"), // - FILE_PATH_LITERAL("gif"), // - FILE_PATH_LITERAL("gz"), // - FILE_PATH_LITERAL("jar"), // - FILE_PATH_LITERAL("jpeg"), // - FILE_PATH_LITERAL("jpg"), // - FILE_PATH_LITERAL("lz"), // - FILE_PATH_LITERAL("m2v"), // - FILE_PATH_LITERAL("m4p"), // - FILE_PATH_LITERAL("m4v"), // - FILE_PATH_LITERAL("mng"), // - FILE_PATH_LITERAL("mov"), // - FILE_PATH_LITERAL("mp2"), // - FILE_PATH_LITERAL("mp3"), // - FILE_PATH_LITERAL("mp4"), // - FILE_PATH_LITERAL("mpe"), // - FILE_PATH_LITERAL("mpeg"), // - FILE_PATH_LITERAL("mpg"), // - FILE_PATH_LITERAL("mpv"), // - FILE_PATH_LITERAL("ogg"), // - FILE_PATH_LITERAL("ogv"), // - FILE_PATH_LITERAL("png"), // - FILE_PATH_LITERAL("qt"), // - FILE_PATH_LITERAL("rar"), // - FILE_PATH_LITERAL("taz"), // - FILE_PATH_LITERAL("tb2"), // - FILE_PATH_LITERAL("tbz"), // - FILE_PATH_LITERAL("tbz2"), // - FILE_PATH_LITERAL("tgz"), // - FILE_PATH_LITERAL("tlz"), // - FILE_PATH_LITERAL("tz"), // - FILE_PATH_LITERAL("tz2"), // - FILE_PATH_LITERAL("vob"), // - FILE_PATH_LITERAL("webm"), // - FILE_PATH_LITERAL("wma"), // - FILE_PATH_LITERAL("wmv"), // - FILE_PATH_LITERAL("xz"), // - FILE_PATH_LITERAL("z"), // - FILE_PATH_LITERAL("zip"), // - }); - - if (exts->count(ext_without_dot)) + static constexpr auto kExts = base::MakeFixedFlatSet({ + FILE_PATH_LITERAL("3g2"), // + FILE_PATH_LITERAL("3gp"), // + FILE_PATH_LITERAL("7z"), // + FILE_PATH_LITERAL("7zip"), // + FILE_PATH_LITERAL("aac"), // + FILE_PATH_LITERAL("avi"), // + FILE_PATH_LITERAL("bz"), // + FILE_PATH_LITERAL("bz2"), // + FILE_PATH_LITERAL("crx"), // + FILE_PATH_LITERAL("gif"), // + FILE_PATH_LITERAL("gz"), // + FILE_PATH_LITERAL("jar"), // + FILE_PATH_LITERAL("jpeg"), // + FILE_PATH_LITERAL("jpg"), // + FILE_PATH_LITERAL("lz"), // + FILE_PATH_LITERAL("m2v"), // + FILE_PATH_LITERAL("m4p"), // + FILE_PATH_LITERAL("m4v"), // + FILE_PATH_LITERAL("mng"), // + FILE_PATH_LITERAL("mov"), // + FILE_PATH_LITERAL("mp2"), // + FILE_PATH_LITERAL("mp3"), // + FILE_PATH_LITERAL("mp4"), // + FILE_PATH_LITERAL("mpe"), // + FILE_PATH_LITERAL("mpeg"), // + FILE_PATH_LITERAL("mpg"), // + FILE_PATH_LITERAL("mpv"), // + FILE_PATH_LITERAL("ogg"), // + FILE_PATH_LITERAL("ogv"), // + FILE_PATH_LITERAL("png"), // + FILE_PATH_LITERAL("qt"), // + FILE_PATH_LITERAL("rar"), // + FILE_PATH_LITERAL("taz"), // + FILE_PATH_LITERAL("tb2"), // + FILE_PATH_LITERAL("tbz"), // + FILE_PATH_LITERAL("tbz2"), // + FILE_PATH_LITERAL("tgz"), // + FILE_PATH_LITERAL("tlz"), // + FILE_PATH_LITERAL("tz"), // + FILE_PATH_LITERAL("tz2"), // + FILE_PATH_LITERAL("vob"), // + FILE_PATH_LITERAL("webm"), // + FILE_PATH_LITERAL("wma"), // + FILE_PATH_LITERAL("wmv"), // + FILE_PATH_LITERAL("xz"), // + FILE_PATH_LITERAL("z"), // + FILE_PATH_LITERAL("zip"), // + }); + + if (kExts.count(ext_without_dot)) { return kStored; + } return kDeflated; } diff --git a/deps/zlib/patches/0000-build.patch b/deps/zlib/patches/0000-build.patch index b7c59964822096..6119f09c05b73c 100644 --- a/deps/zlib/patches/0000-build.patch +++ b/deps/zlib/patches/0000-build.patch @@ -1,16 +1,3 @@ -diff --git a/contrib/minizip/ioapi.h b/contrib/minizip/ioapi.h -index 8dcbdb06e35a..c1b7a54847f5 100644 ---- a/contrib/minizip/ioapi.h -+++ b/contrib/minizip/ioapi.h -@@ -43,7 +43,7 @@ - - #include - #include --#include "zlib.h" -+#include "third_party/zlib/zlib.h" - - #if defined(USE_FILE32API) - #define fopen64 fopen diff --git a/contrib/minizip/iowin32.c b/contrib/minizip/iowin32.c index 274f39eb1dd2..246ceb91a139 100644 --- a/contrib/minizip/iowin32.c @@ -35,45 +22,10 @@ index 274f39eb1dd2..246ceb91a139 100644 voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode)); uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -diff --git a/contrib/minizip/mztools.c b/contrib/minizip/mztools.c -index 96891c2e0b71..8bf9cca32633 100644 ---- a/contrib/minizip/mztools.c -+++ b/contrib/minizip/mztools.c -@@ -8,7 +8,7 @@ - #include - #include - #include --#include "zlib.h" -+#include "third_party/zlib/zlib.h" - #include "unzip.h" - - #define READ_8(adr) ((unsigned char)*(adr)) -diff --git a/contrib/minizip/mztools.h b/contrib/minizip/mztools.h -index a49a426ec2fc..f295ffeda6af 100644 ---- a/contrib/minizip/mztools.h -+++ b/contrib/minizip/mztools.h -@@ -12,7 +12,7 @@ extern "C" { - #endif - - #ifndef _ZLIB_H --#include "zlib.h" -+#include "third_party/zlib/zlib.h" - #endif - - #include "unzip.h" diff --git a/contrib/minizip/unzip.c b/contrib/minizip/unzip.c index bcfb9416ec35..199b4723fcfc 100644 --- a/contrib/minizip/unzip.c +++ b/contrib/minizip/unzip.c -@@ -72,7 +72,7 @@ - #define NOUNCRYPT - #endif - --#include "zlib.h" -+#include "third_party/zlib/zlib.h" - #include "unzip.h" - - #ifdef STDC @@ -1705,11 +1705,6 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) pfile_in_zip_read_info->stream.avail_out = (uInt)len; @@ -86,45 +38,6 @@ index bcfb9416ec35..199b4723fcfc 100644 if ((len>pfile_in_zip_read_info->rest_read_compressed+ pfile_in_zip_read_info->stream.avail_in) && (pfile_in_zip_read_info->raw)) -diff --git a/contrib/minizip/unzip.h b/contrib/minizip/unzip.h -index 2104e3915074..3c0143529b91 100644 ---- a/contrib/minizip/unzip.h -+++ b/contrib/minizip/unzip.h -@@ -48,7 +48,7 @@ extern "C" { - #endif - - #ifndef _ZLIB_H --#include "zlib.h" -+#include "third_party/zlib/zlib.h" - #endif - - #ifndef _ZLIBIOAPI_H -diff --git a/contrib/minizip/zip.c b/contrib/minizip/zip.c -index 44e88a9cb989..65c0c7251843 100644 ---- a/contrib/minizip/zip.c -+++ b/contrib/minizip/zip.c -@@ -26,7 +26,7 @@ - #include - #include - #include --#include "zlib.h" -+#include "third_party/zlib/zlib.h" - #include "zip.h" - - #ifdef STDC -diff --git a/contrib/minizip/zip.h b/contrib/minizip/zip.h -index 8aaebb623430..8c06c0aa7bb0 100644 ---- a/contrib/minizip/zip.h -+++ b/contrib/minizip/zip.h -@@ -47,7 +47,7 @@ extern "C" { - //#define HAVE_BZIP2 - - #ifndef _ZLIB_H --#include "zlib.h" -+#include "third_party/zlib/zlib.h" - #endif - - #ifndef _ZLIBIOAPI_H diff --git a/gzread.c b/gzread.c index 956b91ea7d9e..832d3ef98c59 100644 --- a/gzread.c diff --git a/deps/zlib/patches/0013-cpu-feature-detection-for-arm.patch b/deps/zlib/patches/0013-cpu-feature-detection-for-arm.patch new file mode 100644 index 00000000000000..0547851fe5d99d --- /dev/null +++ b/deps/zlib/patches/0013-cpu-feature-detection-for-arm.patch @@ -0,0 +1,30 @@ +From c43ba7a55f091c0dcbfd8d89f7a5121269ce1b81 Mon Sep 17 00:00:00 2001 +From: Ho Cheung +Date: Thu, 27 Jul 2023 09:47:52 +0800 +Subject: [PATCH] [zlib] Perform CPU feature detection for ARM inside adler32() + +Perform CPU feature detection for ARM within adler32() to have the same +behavior as x86. + +--- + third_party/zlib/adler32.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/third_party/zlib/adler32.c b/third_party/zlib/adler32.c +index 81c584f68e233..99a294496f7eb 100644 +--- a/third_party/zlib/adler32.c ++++ b/third_party/zlib/adler32.c +@@ -90,9 +90,9 @@ uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { + return adler | (sum2 << 16); + } + +-#if defined(ADLER32_SIMD_SSSE3) ++#if defined(ADLER32_SIMD_SSSE3) || defined(ADLER32_SIMD_NEON) + /* +- * Use SSSE3 to compute the adler32. Since this routine can be ++ * Use SIMD to compute the adler32. Since this function can be + * freely used, check CPU features here. zlib convention is to + * call adler32(0, NULL, 0), before making calls to adler32(). + * So this is a good early (and infrequent) place to cache CPU +-- +2.41.0.windows.3 diff --git a/deps/zlib/zlib.gyp b/deps/zlib/zlib.gyp index 49de2a6c6de903..26ceed9fbe6825 100644 --- a/deps/zlib/zlib.gyp +++ b/deps/zlib/zlib.gyp @@ -107,33 +107,33 @@ }], ], }, # zlib_arm_crc32 - { - 'target_name': 'zlib_crc32_simd', - 'type': 'static_library', - 'conditions': [ - ['OS!="win" or llvm_version!="0.0"', { - 'cflags': [ - '-msse4.2', - '-mpclmul', - ], - 'xcode_settings': { - 'OTHER_CFLAGS': [ - '-msse4.2', - '-mpclmul', - ], - }, - }] - ], - 'defines': [ 'CRC32_SIMD_SSE42_PCLMUL' ], - 'include_dirs': [ '<(ZLIB_ROOT)' ], - 'direct_dependent_settings': { - 'defines': [ 'CRC32_SIMD_SSE42_PCLMUL' ], - 'include_dirs': [ '<(ZLIB_ROOT)' ], - }, - 'sources': [ - '& args) { const int argc = 1; Local argv[argc] = { args[0] }; Local cons = - args.Data().As()->GetInternalField(0).As(); + args.Data().As()->GetInternalField(0) + .As().As(); Local result = cons->NewInstance(context, argc, argv).ToLocalChecked(); args.GetReturnValue().Set(result); diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index 1b408ba97b717c..a5571c30be575d 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -768,6 +768,7 @@ import { executionAsyncId } from 'node:async_hooks'; import fs from 'node:fs'; console.log(executionAsyncId()); // 1 - bootstrap +const path = '.'; fs.open(path, 'r', (err, fd) => { console.log(executionAsyncId()); // 6 - open() }); @@ -778,6 +779,7 @@ const async_hooks = require('node:async_hooks'); const fs = require('node:fs'); console.log(async_hooks.executionAsyncId()); // 1 - bootstrap +const path = '.'; fs.open(path, 'r', (err, fd) => { console.log(async_hooks.executionAsyncId()); // 6 - open() }); diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 2c644c61c5f1ad..58fbed1c0daf8e 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -925,8 +925,8 @@ changes: * `options` {Object} * `cwd` {string|URL} Current working directory of the child process. * `input` {string|Buffer|TypedArray|DataView} The value which will be passed - as stdin to the spawned process. Supplying this value will override - `stdio[0]`. + as stdin to the spawned process. If `stdio[0]` is set to `'pipe'`, Supplying + this value will override `stdio[0]`. * `stdio` {string|Array} Child's stdio configuration. `stderr` by default will be output to the parent process' stderr unless `stdio` is specified. **Default:** `'pipe'`. @@ -995,8 +995,8 @@ changes: * `options` {Object} * `cwd` {string|URL} Current working directory of the child process. * `input` {string|Buffer|TypedArray|DataView} The value which will be passed - as stdin to the spawned process. Supplying this value will override - `stdio[0]`. + as stdin to the spawned process. If `stdio[0]` is set to `'pipe'`, Supplying + this value will override `stdio[0]`. * `stdio` {string|Array} Child's stdio configuration. `stderr` by default will be output to the parent process' stderr unless `stdio` is specified. **Default:** `'pipe'`. @@ -1071,11 +1071,11 @@ changes: * `options` {Object} * `cwd` {string|URL} Current working directory of the child process. * `input` {string|Buffer|TypedArray|DataView} The value which will be passed - as stdin to the spawned process. Supplying this value will override - `stdio[0]`. + as stdin to the spawned process. If `stdio[0]` is set to `'pipe'`, Supplying + this value will override `stdio[0]`. * `argv0` {string} Explicitly set the value of `argv[0]` sent to the child process. This will be set to `command` if not specified. - * `stdio` {string|Array} Child's stdio configuration. + * `stdio` {string|Array} Child's stdio configuration. **Default:** `'pipe'`. * `env` {Object} Environment key-value pairs. **Default:** `process.env`. * `uid` {number} Sets the user identity of the process (see setuid(2)). * `gid` {number} Sets the group identity of the process (see setgid(2)). @@ -1405,7 +1405,9 @@ setTimeout(() => { ### `subprocess[Symbol.dispose]()` > Stability: 1 - Experimental diff --git a/doc/api/cli.md b/doc/api/cli.md index e8b21861d24850..1da38c1739126b 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -28,8 +28,8 @@ absolute path, it's resolved as a relative path from the current working directory. That path is then resolved by [CommonJS][] module loader. If no corresponding file is found, an error is thrown. -If a file is found, its path will be passed to the [ECMAScript module loader][] -under any of the following conditions: +If a file is found, its path will be passed to the +[ES module loader][Modules loaders] under any of the following conditions: * The program was started with a command-line flag that forces the entry point to be loaded with ECMAScript module loader. @@ -43,9 +43,9 @@ Otherwise, the file is loaded using the CommonJS module loader. See ### ECMAScript modules loader entry point caveat -When loading [ECMAScript module loader][] loads the program entry point, the `node` -command will only accept as input only files with `.js`, `.mjs`, or `.cjs` -extensions; and with `.wasm` extensions when +When loading, the [ES module loader][Modules loaders] loads the program +entry point, the `node` command will accept as input only files with `.js`, +`.mjs`, or `.cjs` extensions; and with `.wasm` extensions when [`--experimental-wasm-modules`][] is enabled. ## Options @@ -145,6 +145,10 @@ Error: Access to this API has been restricted > Stability: 1 - Experimental @@ -155,8 +159,11 @@ the [Permission Model][]. The valid arguments for the `--allow-fs-read` flag are: * `*` - To allow all `FileSystemRead` operations. -* Paths delimited by comma (`,`) to allow only matching `FileSystemRead` - operations. +* Multiple paths can be allowed using multiple `--allow-fs-read` flags. + Example `--allow-fs-read=/folder1/ --allow-fs-read=/folder1/` + +Paths delimited by comma (`,`) are no longer allowed. +When passing a single flag with a comma a warning will be diplayed Examples can be found in the [File System Permissions][] documentation. @@ -192,6 +199,10 @@ node --experimental-permission --allow-fs-read=/path/to/index.js index.js > Stability: 1 - Experimental @@ -202,8 +213,11 @@ the [Permission Model][]. The valid arguments for the `--allow-fs-write` flag are: * `*` - To allow all `FileSystemWrite` operations. -* Paths delimited by comma (`,`) to allow only matching `FileSystemWrite` - operations. +* Multiple paths can be allowed using multiple `--allow-fs-read` flags. + Example `--allow-fs-read=/folder1/ --allow-fs-read=/folder1/` + +Paths delimited by comma (`,`) are no longer allowed. +When passing a single flag with a comma a warning will be diplayed Examples can be found in the [File System Permissions][] documentation. @@ -306,6 +320,20 @@ Currently the support for run-time snapshot is experimental in that: a report in the [Node.js issue tracker][] and link to it in the [tracking issue for user-land snapshots][]. +### `-c`, `--check` + + + +Syntax check the script without executing. + ### `--completion-bash` -Disables the family autoselection algorithm unless connection options explicitly -enables it. +Enables the family autoselection algorithm unless connection options explicitly +disables it. ### `--enable-source-maps` @@ -506,15 +528,83 @@ when `Error.stack` is accessed. If you access `Error.stack` frequently in your application, take into account the performance implications of `--enable-source-maps`. +### `--env-file=config` + +> Stability: 1.1 - Active development + + + +Loads environment variables from a file relative to the current directory, +making them available to applications on `process.env`. The [environment +variables which configure Node.js][environment_variables], such as `NODE_OPTIONS`, +are parsed and applied. If the same variable is defined in the environment and +in the file, the value from the environment takes precedence. + +You can pass multiple `--env-file` arguments. Subsequent files override +pre-existing variables defined in previous files. + +```bash +node --env-file=.env --env-file=.development.env index.js +``` + +The format of the file should be one line per key-value pair of environment +variable name and value separated by `=`: + +```text +PORT=3000 +``` + +Any text after a `#` is treated as a comment: + +```text +# This is a comment +PORT=3000 # This is also a comment +``` + +Values can start and end with the following quotes: `\`, `"` or `'`. +They are omitted from the values. + +```text +USERNAME="nodejs" # will result in `nodejs` as the value. +``` + +### `-e`, `--eval "script"` + + + +Evaluate the following argument as JavaScript. The modules which are +predefined in the REPL can also be used in `script`. + +On Windows, using `cmd.exe` a single quote will not work correctly because it +only recognizes double `"` for quoting. In Powershell or Git bash, both `'` +and `"` are usable. + ### `--experimental-import-meta-resolve` -Enable experimental `import.meta.resolve()` support. +Enable experimental `import.meta.resolve()` parent URL support, which allows +passing a second `parentURL` argument for contextual resolution. + +Previously gated the entire `import.meta.resolve` feature. ### `--experimental-loader=module` @@ -527,7 +617,11 @@ changes: `--experimental-loader`. --> -Specify the `module` of a custom experimental [ECMAScript module loader][]. +> This flag is discouraged and may be removed in a future version of Node.js. +> Please use +> [`--import` with `register()`][module customization hooks: enabling] instead. + +Specify the `module` containing exported [module customization hooks][]. `module` may be any string accepted as an [`import` specifier][]. ### `--experimental-network-imports` @@ -566,38 +660,6 @@ added: v11.8.0 Use the specified file as a security policy. -### `--no-experimental-fetch` - - - -Disable experimental support for the [Fetch API][]. - -### `--no-experimental-global-webcrypto` - - - -Disable exposition of [Web Crypto API][] on the global scope. - -### `--no-experimental-global-customevent` - - - -Disable exposition of [CustomEvent Web API][] on the global scope. - -### `--no-experimental-repl-await` - - - -Use this flag to disable top-level await in REPL. - ### `--experimental-sea-config` @@ -652,7 +716,9 @@ added: - v13.3.0 - v12.16.0 changes: - - version: v20.0.0 + - version: + - v20.0.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/47286 description: This option is no longer required as WASI is enabled by default, but can still be passed. @@ -689,6 +755,20 @@ added: v6.0.0 Force FIPS-compliant crypto on startup. (Cannot be disabled from script code.) (Same requirements as `--enable-fips`.) +### `--force-node-api-uncaught-exceptions-policy` + + + +Enforces `uncaughtException` event on Node-API asynchronous callbacks. + +To prevent from an existing add-on from crashing the process, this flag is not +enabled by default. In the future, this flag will be enabled by default to +enforce the correct behavior. + ### `--frozen-intrinsics` -Enforces `uncaughtException` event on Node-API asynchronous callbacks. +> Stability: 1 - Experimental -To prevent from an existing add-on from crashing the process, this flag is not -enabled by default. In the future, this flag will be enabled by default to -enforce the correct behavior. +Starts the V8 heap profiler on start up, and writes the heap profile to disk +before exit. + +If `--heap-prof-dir` is not specified, the generated profile is placed +in the current working directory. + +If `--heap-prof-name` is not specified, the generated profile is +named `Heap.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.heapprofile`. + +```console +$ node --heap-prof index.js +$ ls *.heapprofile +Heap.20190409.202950.15293.0.001.heapprofile +``` + +### `--heap-prof-dir` + + + +> Stability: 1 - Experimental + +Specify the directory where the heap profiles generated by `--heap-prof` will +be placed. + +The default value is controlled by the +[`--diagnostic-dir`][] command-line option. + +### `--heap-prof-interval` + + + +> Stability: 1 - Experimental + +Specify the average sampling interval in bytes for the heap profiles generated +by `--heap-prof`. The default is 512 \* 1024 bytes. + +### `--heap-prof-name` + + + +> Stability: 1 - Experimental + +Specify the file name of the heap profile generated by `--heap-prof`. ### `--heapsnapshot-near-heap-limit=max_count` @@ -789,63 +913,14 @@ $ ls Heap.20190718.133405.15554.0.001.heapsnapshot ``` -### `--heap-prof` - - - -> Stability: 1 - Experimental - -Starts the V8 heap profiler on start up, and writes the heap profile to disk -before exit. - -If `--heap-prof-dir` is not specified, the generated profile is placed -in the current working directory. - -If `--heap-prof-name` is not specified, the generated profile is -named `Heap.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.heapprofile`. - -```console -$ node --heap-prof index.js -$ ls *.heapprofile -Heap.20190409.202950.15293.0.001.heapprofile -``` - -### `--heap-prof-dir` - - - -> Stability: 1 - Experimental - -Specify the directory where the heap profiles generated by `--heap-prof` will -be placed. - -The default value is controlled by the -[`--diagnostic-dir`][] command-line option. - -### `--heap-prof-interval` - - - -> Stability: 1 - Experimental - -Specify the average sampling interval in bytes for the heap profiles generated -by `--heap-prof`. The default is 512 \* 1024 bytes. - -### `--heap-prof-name` +### `-h`, `--help` -> Stability: 1 - Experimental - -Specify the file name of the heap profile generated by `--heap-prof`. +Print node command-line options. +The output of this option is less detailed than this document. ### `--icu-data-dir=file` @@ -858,7 +933,9 @@ Specify ICU data load path. (Overrides `NODE_ICU_DATA`.) ### `--import=module` > Stability: 1 - Experimental @@ -882,28 +959,32 @@ Valid values are `"commonjs"` and `"module"`. The default is `"commonjs"`. The REPL does not support this option. -### `--inspect-brk[=[host:]port]` +### `--insecure-http-parser` -Activate inspector on `host:port` and break at start of user script. -Default `host:port` is `127.0.0.1:9229`. +Enable leniency flags on the HTTP parser. This may allow +interoperability with non-conformant HTTP implementations. -### `--inspect-port=[host:]port` +When enabled, the parser will accept the following: - +* Invalid HTTP headers values. +* Invalid HTTP versions. +* Allow message containing both `Transfer-Encoding` + and `Content-Length` headers. +* Allow extra data after message when `Connection: close` is present. +* Allow extra trasfer encodings after `chunked` has been provided. +* Allow `\n` to be used as token separator instead of `\r\n`. +* Allow `\r\n` not to be provided after a chunk. +* Allow spaces to be present after a chunk size and before `\r\n`. -Set the `host:port` to be used when the inspector is activated. -Useful when activating the inspector by sending the `SIGUSR1` signal. - -Default host is `127.0.0.1`. - -See the [security warning][] below regarding the `host` -parameter usage. +All the above will expose your application to request smuggling +or poisoning attack. Avoid using this option. ### `--inspect[=[host:]port]` @@ -932,10 +1013,33 @@ If specifying a host, make sure that either: * The host is not accessible from public networks. * A firewall disallows unwanted connections on the port. -**More specifically, `--inspect=0.0.0.0` is insecure if the port (`9229` by -default) is not firewall-protected.** +**More specifically, `--inspect=0.0.0.0` is insecure if the port (`9229` by +default) is not firewall-protected.** + +See the [debugging security implications][] section for more information. + +### `--inspect-brk[=[host:]port]` + + + +Activate inspector on `host:port` and break at start of user script. +Default `host:port` is `127.0.0.1:9229`. + +### `--inspect-port=[host:]port` + + + +Set the `host:port` to be used when the inspector is activated. +Useful when activating the inspector by sending the `SIGUSR1` signal. + +Default host is `127.0.0.1`. -See the [debugging security implications][] section for more information. +See the [security warning][] below regarding the `host` +parameter usage. ### `--inspect-publish-uid=stderr,http` @@ -944,19 +1048,13 @@ Specify ways of the inspector web socket url exposure. By default inspector websocket url is available in stderr and under `/json/list` endpoint on `http://host:port/json/list`. -### `--insecure-http-parser` +### `-i`, `--interactive` -Use an insecure HTTP parser that accepts invalid HTTP headers. This may allow -interoperability with non-conformant HTTP implementations. It may also allow -request smuggling and other HTTP attacks that rely on invalid headers being -accepted. Avoid using this option. +Opens the REPL even if stdin does not appear to be a terminal. ### `--jitless` @@ -1013,6 +1111,38 @@ added: v0.8.0 Silence deprecation warnings. +### `--no-experimental-fetch` + + + +Disable exposition of [Fetch API][] on the global scope. + +### `--no-experimental-global-customevent` + + + +Disable exposition of [CustomEvent Web API][] on the global scope. + +### `--no-experimental-global-webcrypto` + + + +Disable exposition of [Web Crypto API][] on the global scope. + +### `--no-experimental-repl-await` + + + +Use this flag to disable top-level await in REPL. + ### `--no-extra-info-on-fatal-exception` + +Disables the family autoselection algorithm unless connection options explicitly +enables it. + ### `--no-warnings` + +Enable OpenSSL 3.0 legacy provider. For more information please see +[OSSL\_PROVIDER-legacy][OSSL_PROVIDER-legacy]. + ### `--openssl-shared-config` - -Enable OpenSSL 3.0 legacy provider. For more information please see -[OSSL\_PROVIDER-legacy][OSSL_PROVIDER-legacy]. - ### `--pending-deprecation` + +Identical to `-e` but prints the result. + ### `--prof` + +Preload the specified module at startup. + +Follows `require()`'s module resolution +rules. `module` may be either a path to a file, or a node module name. + +Only CommonJS modules are supported. +Use [`--import`][] to preload an [ECMAScript module][]. +Modules preloaded with `--require` will run before modules preloaded with `--import`. + ### `--secure-heap=n` -A test reporter to use when running tests. See the documentation on -[test reporters][] for more details. +Configures the test runner to only execute top level tests that have the `only` +option set. -### `--test-reporter-destination` +### `--test-reporter` -The destination for the corresponding test reporter. See the documentation on +A test reporter to use when running tests. See the documentation on [test reporters][] for more details. -### `--test-only` +### `--test-reporter-destination` -Configures the test runner to only execute top level tests that have the `only` -option set. +The destination for the corresponding test reporter. See the documentation on +[test reporters][] for more details. ### `--test-shard` Test suite shard to execute in a format of `/`, where @@ -1849,6 +2021,14 @@ The amount of parallelism refers to the number of computations that can be carried out simultaneously in a given machine. In general, it's the same as the amount of CPUs, but it may diverge in environments such as VMs or containers. +### `-v`, `--version` + + + +Print node's version. + ### `--watch` - -Syntax check the script without executing. - -### `-e`, `--eval "script"` - - - -Evaluate the following argument as JavaScript. The modules which are -predefined in the REPL can also be used in `script`. - -On Windows, using `cmd.exe` a single quote will not work correctly because it -only recognizes double `"` for quoting. In Powershell or Git bash, both `'` -and `"` are usable. - -### `-h`, `--help` - - - -Print node command-line options. -The output of this option is less detailed than this document. - -### `-i`, `--interactive` - - - -Opens the REPL even if stdin does not appear to be a terminal. - -### `-p`, `--print "script"` - - - -Identical to `-e` but prints the result. - -### `-r`, `--require module` - - - -Preload the specified module at startup. - -Follows `require()`'s module resolution -rules. `module` may be either a path to a file, or a node module name. - -Only CommonJS modules are supported. -Use [`--import`][] to preload an [ECMAScript module][]. -Modules preloaded with `--require` will run before modules preloaded with `--import`. - -### `-v`, `--version` - - - -Print node's version. - ## Environment variables ### `FORCE_COLOR=[1, 2, 3]` @@ -2022,6 +2119,11 @@ and `NODE_DISABLE_COLORS` environment variables are ignored. Any other value will result in colorized output being disabled. +### `NO_COLOR=` + +[`NO_COLOR`][] is an alias for `NODE_DISABLE_COLORS`. The value of the +environment variable is arbitrary. + ### `NODE_DEBUG=module[,…]` - -Path to the file used to store the persistent REPL history. The default path is -`~/.node_repl_history`, which is overridden by this variable. Setting the value -to an empty string (`''` or `' '`) disables persistent REPL history. - ### `NODE_REPL_EXTERNAL_MODULE=file` + +Path to the file used to store the persistent REPL history. The default path is +`~/.node_repl_history`, which is overridden by this variable. Setting the value +to an empty string (`''` or `' '`) disables persistent REPL history. + ### `NODE_SKIP_PLATFORM_CHECK=value` + +Type: Runtime + +Calling [`util.promisify`][] on a function that returns a will ignore +the result of said promise, which can lead to unhandled promise rejections. + +### DEP0175: `util.toUSVString` + + + +Type: Documentation-only + +The [`util.toUSVString()`][] API is deprecated. Please use +[`String.prototype.toWellFormed`][] instead. + +### DEP0176: `fs.F_OK`, `fs.R_OK`, `fs.W_OK`, `fs.X_OK` + + + +Type: Documentation-only + +`F_OK`, `R_OK`, `W_OK` and `X_OK` getters exposed directly on `node:fs` are +deprecated. Get them from `fs.constants` or `fs.promises.constants` instead. + [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 [RFC 8247 Section 2.4]: https://www.rfc-editor.org/rfc/rfc8247#section-2.4 @@ -3400,6 +3450,7 @@ Consider using alternatives such as the [`mock`][] helper function. [`Server.getConnections()`]: net.md#servergetconnectionscallback [`Server.listen({fd: })`]: net.md#serverlistenhandle-backlog-callback [`SlowBuffer`]: buffer.md#class-slowbuffer +[`String.prototype.toWellFormed`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toWellFormed [`WriteStream.open()`]: fs.md#class-fswritestream [`assert.CallTracker`]: assert.md#class-assertcalltracker [`assert`]: assert.md @@ -3518,6 +3569,8 @@ Consider using alternatives such as the [`mock`][] helper function. [`util.isSymbol()`]: util.md#utilissymbolobject [`util.isUndefined()`]: util.md#utilisundefinedobject [`util.log()`]: util.md#utillogstring +[`util.promisify`]: util.md#utilpromisifyoriginal +[`util.toUSVString()`]: util.md#utiltousvstringstring [`util.types`]: util.md#utiltypes [`util`]: util.md [`worker.exitedAfterDisconnect`]: cluster.md#workerexitedafterdisconnect @@ -3530,6 +3583,8 @@ Consider using alternatives such as the [`mock`][] helper function. [from_string_encoding]: buffer.md#static-method-bufferfromstring-encoding [legacy URL API]: url.md#legacy-url-api [legacy `urlObject`]: url.md#legacy-urlobject +[permission model]: permissions.md#permission-model +[policies]: permissions.md#policies [static methods of `crypto.Certificate()`]: crypto.md#class-certificate [subpath exports]: packages.md#subpath-exports [subpath imports]: packages.md#subpath-imports diff --git a/doc/api/dgram.md b/doc/api/dgram.md index aa5030d94bce01..f19e62bc7736bd 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -375,7 +375,9 @@ provided, it is added as a listener for the [`'close'`][] event. ### `socket[Symbol.asyncDispose]()` > Stability: 1 - Experimental diff --git a/doc/api/dns.md b/doc/api/dns.md index d04dbd4a3768ef..1a460598bcd5fb 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -795,7 +795,9 @@ dns orders in workers. ## `dns.getDefaultResultOrder()` Get the default value for `verbatim` in [`dns.lookup()`][] and @@ -1366,7 +1368,9 @@ default dns orders in workers. ### `dnsPromises.getDefaultResultOrder()` Get the value of `dnsOrder`. diff --git a/doc/api/errors.md b/doc/api/errors.md index 3e338a4e8f8cd6..95ad3c9c671954 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -773,19 +773,17 @@ STDERR/STDOUT, and the data's length is longer than the `maxBuffer` option. ### `ERR_CLOSED_MESSAGE_PORT` - There was an attempt to use a `MessagePort` instance in a closed @@ -802,7 +800,7 @@ non-writable `stdout` or `stderr` stream. ### `ERR_CONSTRUCT_CALL_INVALID` - @@ -1233,23 +1231,6 @@ provided. Encoding provided to `TextDecoder()` API was not one of the [WHATWG Supported Encodings][]. - - -### `ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE` - - - -Programmatically registering custom ESM loaders -currently requires at least one custom loader to have been -registered via the `--experimental-loader` flag. A no-op -loader registered via CLI is sufficient -(for example: `--experimental-loader data:text/javascript,`; -do not omit the necessary trailing comma). -A future version of Node.js will support the programmatic -registration of loaders without needing to also use the flag. - ### `ERR_EVAL_ESM_CANNOT_PRINT` @@ -1292,7 +1273,7 @@ to the current platform which is running Node.js is used. ### `ERR_FS_CP_DIR_TO_NON_DIR` - @@ -1303,7 +1284,7 @@ etc.) using [`fs.cp()`][]. ### `ERR_FS_CP_EEXIST` - @@ -1314,7 +1295,7 @@ An attempt was made to copy over a file that already existed with ### `ERR_FS_CP_EINVAL` - @@ -1335,7 +1316,7 @@ Response body size doesn't match with the specified content-length header value. ### `ERR_FS_CP_FIFO_PIPE` - @@ -1345,7 +1326,7 @@ An attempt was made to copy a named pipe with [`fs.cp()`][]. ### `ERR_FS_CP_NON_DIR_TO_DIR` - @@ -1356,7 +1337,7 @@ using [`fs.cp()`][]. ### `ERR_FS_CP_SOCKET` - @@ -1366,7 +1347,7 @@ An attempt was made to copy to a socket with [`fs.cp()`][]. ### `ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY` - @@ -1377,7 +1358,7 @@ of `src`. ### `ERR_FS_CP_UNKNOWN` - @@ -1733,7 +1714,7 @@ made to mark a stream and dependent of itself. ### `ERR_HTTP2_TOO_MANY_INVALID_FRAMES` - @@ -3194,7 +3175,7 @@ attempting a [`require()`][] operation or when loading the program entry point. ### `ERR_CANNOT_TRANSFER_OBJECT` - diff --git a/doc/api/esm.md b/doc/api/esm.md index 68ecad93b8ad3b..b40b4ccb6f0865 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -9,12 +9,12 @@ added: v8.5.0 changes: - version: v20.0.0 pr-url: https://github.com/nodejs/node/pull/44710 - description: Loader hooks are executed off the main thread. + description: Module customization hooks are executed off the main thread. - version: - v18.6.0 - v16.17.0 pr-url: https://github.com/nodejs/node/pull/42623 - description: Add support for chaining loaders. + description: Add support for chaining module customization hooks. - version: - v17.1.0 - v16.14.0 @@ -25,7 +25,7 @@ changes: - v16.12.0 pr-url: https://github.com/nodejs/node/pull/37468 description: - Consolidate loader hooks, removed `getFormat`, `getSource`, + Consolidate customization hooks, removed `getFormat`, `getSource`, `transformSource`, and `getGlobalPreloadCode` hooks added `load` and `globalPreload` hooks allowed returning `format` from either `resolve` or `load` hooks. @@ -322,13 +322,21 @@ import { readFileSync } from 'node:fs'; const buffer = readFileSync(new URL('./data.proto', import.meta.url)); ``` -### `import.meta.resolve(specifier[, parent])` +### `import.meta.resolve(specifier)` - -> Stability: 1 - Experimental - -This feature is only available with the `--experimental-import-meta-resolve` -command flag enabled. +> Stability: 1.2 - Release candidate -* `specifier` {string} The module specifier to resolve relative to `parent`. -* `parent` {string|URL} The absolute parent module URL to resolve from. If none - is specified, the value of `import.meta.url` is used as the default. -* Returns: {string} +* `specifier` {string} The module specifier to resolve relative to the + current module. +* Returns: {string} The absolute URL string that the specifier would resolve to. -Provides a module-relative resolution function scoped to each module, returning -the URL string. In alignment with browser behavior, this now returns -synchronously. - -> **Caveat** This can result in synchronous file-system operations, which -> can impact performance similarly to `require.resolve`. +[`import.meta.resolve`][] is a module-relative resolution function scoped to +each module, returning the URL string. ```js const dependencyAsset = import.meta.resolve('component-lib/asset.css'); +// file:///app/node_modules/component-lib/asset.css +import.meta.resolve('./dep.js'); +// file:///app/dep.js ``` -`import.meta.resolve` also accepts a second argument which is the parent module -from which to resolve: +All features of the Node.js module resolution are supported. Dependency +resolutions are subject to the permitted exports resolutions within the package. -```js -import.meta.resolve('./dep', import.meta.url); -``` +**Caveats**: + +* This can result in synchronous file-system operations, which + can impact performance similarly to `require.resolve`. +* This feature is not available within custom loaders (it would + create a deadlock). + +**Non-standard API**: + +When using the `--experimental-import-meta-resolve` flag, that function accepts +a second argument: + +* `parent` {string|URL} An optional absolute parent module URL to resolve from. + **Default:** `import.meta.url` ## Interoperability with CommonJS @@ -501,8 +515,8 @@ They can instead be loaded with [`module.createRequire()`][] or Relative resolution can be handled via `new URL('./local', import.meta.url)`. -For a complete `require.resolve` replacement, there is a flagged experimental -[`import.meta.resolve`][] API. +For a complete `require.resolve` replacement, there is the +[import.meta.resolve][] API. Alternatively `module.createRequire()` can be used. @@ -513,8 +527,8 @@ if this behavior is desired. #### No `require.extensions` -`require.extensions` is not used by `import`. The expectation is that loader -hooks can provide this workflow in the future. +`require.extensions` is not used by `import`. Module customization hooks can +provide a replacement. #### No `require.cache` @@ -682,559 +696,8 @@ of Node.js applications. ## Loaders - - -> Stability: 1 - Experimental - -> This API is currently being redesigned and will still change. - - - -To customize the default module resolution, loader hooks can optionally be -provided via a `--experimental-loader ./loader-name.mjs` argument to Node.js. - -When hooks are used they apply to each subsequent loader, the entry point, and -all `import` calls. They won't apply to `require` calls; those still follow -[CommonJS][] rules. - -Loaders follow the pattern of `--require`: - -```bash -node \ - --experimental-loader unpkg \ - --experimental-loader http-to-https \ - --experimental-loader cache-buster -``` - -These are called in the following sequence: `cache-buster` calls -`http-to-https` which calls `unpkg`. - -### Hooks - -Hooks are part of a chain, even if that chain consists of only one custom -(user-provided) hook and the default hook, which is always present. Hook -functions nest: each one must always return a plain object, and chaining happens -as a result of each function calling `next()`, which is a reference -to the subsequent loader's hook. - -A hook that returns a value lacking a required property triggers an exception. -A hook that returns without calling `next()` _and_ without returning -`shortCircuit: true` also triggers an exception. These errors are to help -prevent unintentional breaks in the chain. - -Hooks are run in a separate thread, isolated from the main. That means it is a -different [realm](https://tc39.es/ecma262/#realm). The hooks thread may be -terminated by the main thread at any time, so do not depend on asynchronous -operations (like `console.log`) to complete. - -#### `resolve(specifier, context, nextResolve)` - - - -> The loaders API is being redesigned. This hook may disappear or its -> signature may change. Do not rely on the API described below. - -* `specifier` {string} -* `context` {Object} - * `conditions` {string\[]} Export conditions of the relevant `package.json` - * `importAssertions` {Object} An object whose key-value pairs represent the - assertions for the module to import - * `parentURL` {string|undefined} The module importing this one, or undefined - if this is the Node.js entry point -* `nextResolve` {Function} The subsequent `resolve` hook in the chain, or the - Node.js default `resolve` hook after the last user-supplied `resolve` hook - * `specifier` {string} - * `context` {Object} -* Returns: {Object|Promise} - * `format` {string|null|undefined} A hint to the load hook (it might be - ignored) - `'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'` - * `importAssertions` {Object|undefined} The import assertions to use when - caching the module (optional; if excluded the input will be used) - * `shortCircuit` {undefined|boolean} A signal that this hook intends to - terminate the chain of `resolve` hooks. **Default:** `false` - * `url` {string} The absolute URL to which this input resolves - -> **Caveat** Despite support for returning promises and async functions, calls -> to `resolve` may block the main thread which can impact performance. - -The `resolve` hook chain is responsible for telling Node.js where to find and -how to cache a given `import` statement or expression. It can optionally return -its format (such as `'module'`) as a hint to the `load` hook. If a format is -specified, the `load` hook is ultimately responsible for providing the final -`format` value (and it is free to ignore the hint provided by `resolve`); if -`resolve` provides a `format`, a custom `load` hook is required even if only to -pass the value to the Node.js default `load` hook. - -Import type assertions are part of the cache key for saving loaded modules into -the internal module cache. The `resolve` hook is responsible for -returning an `importAssertions` object if the module should be cached with -different assertions than were present in the source code. - -The `conditions` property in `context` is an array of conditions for -[package exports conditions][Conditional Exports] that apply to this resolution -request. They can be used for looking up conditional mappings elsewhere or to -modify the list when calling the default resolution logic. - -The current [package exports conditions][Conditional Exports] are always in -the `context.conditions` array passed into the hook. To guarantee _default -Node.js module specifier resolution behavior_ when calling `defaultResolve`, the -`context.conditions` array passed to it _must_ include _all_ elements of the -`context.conditions` array originally passed into the `resolve` hook. - -```js -export function resolve(specifier, context, nextResolve) { - const { parentURL = null } = context; - - if (Math.random() > 0.5) { // Some condition. - // For some or all specifiers, do some custom logic for resolving. - // Always return an object of the form {url: }. - return { - shortCircuit: true, - url: parentURL ? - new URL(specifier, parentURL).href : - new URL(specifier).href, - }; - } - - if (Math.random() < 0.5) { // Another condition. - // When calling `defaultResolve`, the arguments can be modified. In this - // case it's adding another value for matching conditional exports. - return nextResolve(specifier, { - ...context, - conditions: [...context.conditions, 'another-condition'], - }); - } - - // Defer to the next hook in the chain, which would be the - // Node.js default resolve if this is the last user-specified loader. - return nextResolve(specifier); -} -``` - -#### `load(url, context, nextLoad)` - - - -> The loaders API is being redesigned. This hook may disappear or its -> signature may change. Do not rely on the API described below. - -> In a previous version of this API, this was split across 3 separate, now -> deprecated, hooks (`getFormat`, `getSource`, and `transformSource`). - -* `url` {string} The URL returned by the `resolve` chain -* `context` {Object} - * `conditions` {string\[]} Export conditions of the relevant `package.json` - * `format` {string|null|undefined} The format optionally supplied by the - `resolve` hook chain - * `importAssertions` {Object} -* `nextLoad` {Function} The subsequent `load` hook in the chain, or the - Node.js default `load` hook after the last user-supplied `load` hook - * `specifier` {string} - * `context` {Object} -* Returns: {Object} - * `format` {string} - * `shortCircuit` {undefined|boolean} A signal that this hook intends to - terminate the chain of `resolve` hooks. **Default:** `false` - * `source` {string|ArrayBuffer|TypedArray} The source for Node.js to evaluate - -The `load` hook provides a way to define a custom method of determining how -a URL should be interpreted, retrieved, and parsed. It is also in charge of -validating the import assertion. - -The final value of `format` must be one of the following: - -| `format` | Description | Acceptable types for `source` returned by `load` | -| ------------ | ------------------------------ | ----------------------------------------------------- | -| `'builtin'` | Load a Node.js builtin module | Not applicable | -| `'commonjs'` | Load a Node.js CommonJS module | Not applicable | -| `'json'` | Load a JSON file | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | -| `'module'` | Load an ES module | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | -| `'wasm'` | Load a WebAssembly module | { [`ArrayBuffer`][], [`TypedArray`][] } | - -The value of `source` is ignored for type `'builtin'` because currently it is -not possible to replace the value of a Node.js builtin (core) module. The value -of `source` is ignored for type `'commonjs'` because the CommonJS module loader -does not provide a mechanism for the ES module loader to override the -[CommonJS module return value](#commonjs-namespaces). This limitation might be -overcome in the future. - -> **Caveat**: The ESM `load` hook and namespaced exports from CommonJS modules -> are incompatible. Attempting to use them together will result in an empty -> object from the import. This may be addressed in the future. - -> These types all correspond to classes defined in ECMAScript. - -* The specific [`ArrayBuffer`][] object is a [`SharedArrayBuffer`][]. -* The specific [`TypedArray`][] object is a [`Uint8Array`][]. - -If the source value of a text-based format (i.e., `'json'`, `'module'`) -is not a string, it is converted to a string using [`util.TextDecoder`][]. - -The `load` hook provides a way to define a custom method for retrieving the -source code of an ES module specifier. This would allow a loader to potentially -avoid reading files from disk. It could also be used to map an unrecognized -format to a supported one, for example `yaml` to `module`. - -```js -export async function load(url, context, nextLoad) { - const { format } = context; - - if (Math.random() > 0.5) { // Some condition - /* - For some or all URLs, do some custom logic for retrieving the source. - Always return an object of the form { - format: , - source: , - }. - */ - return { - format, - shortCircuit: true, - source: '...', - }; - } - - // Defer to the next hook in the chain. - return nextLoad(url); -} -``` - -In a more advanced scenario, this can also be used to transform an unsupported -source to a supported one (see [Examples](#examples) below). - -#### `globalPreload()` - - - -> The loaders API is being redesigned. This hook may disappear or its -> signature may change. Do not rely on the API described below. - -> In a previous version of this API, this hook was named -> `getGlobalPreloadCode`. - -* `context` {Object} Information to assist the preload code - * `port` {MessagePort} -* Returns: {string} Code to run before application startup - -Sometimes it might be necessary to run some code inside of the same global -scope that the application runs in. This hook allows the return of a string -that is run as a sloppy-mode script on startup. - -Similar to how CommonJS wrappers work, the code runs in an implicit function -scope. The only argument is a `require`-like function that can be used to load -builtins like "fs": `getBuiltin(request: string)`. - -If the code needs more advanced `require` features, it has to construct -its own `require` using `module.createRequire()`. - -```js -export function globalPreload(context) { - return `\ -globalThis.someInjectedProperty = 42; -console.log('I just set some globals!'); - -const { createRequire } = getBuiltin('module'); -const { cwd } = getBuiltin('process'); - -const require = createRequire(cwd() + '/'); -// [...] -`; -} -``` - -In order to allow communication between the application and the loader, another -argument is provided to the preload code: `port`. This is available as a -parameter to the loader hook and inside of the source text returned by the hook. -Some care must be taken in order to properly call [`port.ref()`][] and -[`port.unref()`][] to prevent a process from being in a state where it won't -close normally. - -```js -/** - * This example has the application context send a message to the loader - * and sends the message back to the application context - */ -export function globalPreload({ port }) { - port.onmessage = (evt) => { - port.postMessage(evt.data); - }; - return `\ - port.postMessage('console.log("I went to the Loader and back");'); - port.onmessage = (evt) => { - eval(evt.data); - }; - `; -} -``` - -### Examples - -The various loader hooks can be used together to accomplish wide-ranging -customizations of the Node.js code loading and evaluation behaviors. - -#### HTTPS loader - -In current Node.js, specifiers starting with `https://` are experimental (see -[HTTPS and HTTP imports][]). - -The loader below registers hooks to enable rudimentary support for such -specifiers. While this may seem like a significant improvement to Node.js core -functionality, there are substantial downsides to actually using this loader: -performance is much slower than loading files from disk, there is no caching, -and there is no security. - -```js -// https-loader.mjs -import { get } from 'node:https'; - -export function load(url, context, nextLoad) { - // For JavaScript to be loaded over the network, we need to fetch and - // return it. - if (url.startsWith('https://')) { - return new Promise((resolve, reject) => { - get(url, (res) => { - let data = ''; - res.setEncoding('utf8'); - res.on('data', (chunk) => data += chunk); - res.on('end', () => resolve({ - // This example assumes all network-provided JavaScript is ES module - // code. - format: 'module', - shortCircuit: true, - source: data, - })); - }).on('error', (err) => reject(err)); - }); - } - - // Let Node.js handle all other URLs. - return nextLoad(url); -} -``` - -```js -// main.mjs -import { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js'; - -console.log(VERSION); -``` - -With the preceding loader, running -`node --experimental-loader ./https-loader.mjs ./main.mjs` -prints the current version of CoffeeScript per the module at the URL in -`main.mjs`. - -#### Transpiler loader - -Sources that are in formats Node.js doesn't understand can be converted into -JavaScript using the [`load` hook][load hook]. - -This is less performant than transpiling source files before running -Node.js; a transpiler loader should only be used for development and testing -purposes. - -```js -// coffeescript-loader.mjs -import { readFile } from 'node:fs/promises'; -import { dirname, extname, resolve as resolvePath } from 'node:path'; -import { cwd } from 'node:process'; -import { fileURLToPath, pathToFileURL } from 'node:url'; -import CoffeeScript from 'coffeescript'; - -const baseURL = pathToFileURL(`${cwd()}/`).href; - -export async function load(url, context, nextLoad) { - if (extensionsRegex.test(url)) { - // Now that we patched resolve to let CoffeeScript URLs through, we need to - // tell Node.js what format such URLs should be interpreted as. Because - // CoffeeScript transpiles into JavaScript, it should be one of the two - // JavaScript formats: 'commonjs' or 'module'. - - // CoffeeScript files can be either CommonJS or ES modules, so we want any - // CoffeeScript file to be treated by Node.js the same as a .js file at the - // same location. To determine how Node.js would interpret an arbitrary .js - // file, search up the file system for the nearest parent package.json file - // and read its "type" field. - const format = await getPackageType(url); - // When a hook returns a format of 'commonjs', `source` is ignored. - // To handle CommonJS files, a handler needs to be registered with - // `require.extensions` in order to process the files with the CommonJS - // loader. Avoiding the need for a separate CommonJS handler is a future - // enhancement planned for ES module loaders. - if (format === 'commonjs') { - return { - format, - shortCircuit: true, - }; - } - - const { source: rawSource } = await nextLoad(url, { ...context, format }); - // This hook converts CoffeeScript source code into JavaScript source code - // for all imported CoffeeScript files. - const transformedSource = coffeeCompile(rawSource.toString(), url); - - return { - format, - shortCircuit: true, - source: transformedSource, - }; - } - - // Let Node.js handle all other URLs. - return nextLoad(url); -} - -async function getPackageType(url) { - // `url` is only a file path during the first iteration when passed the - // resolved url from the load() hook - // an actual file path from load() will contain a file extension as it's - // required by the spec - // this simple truthy check for whether `url` contains a file extension will - // work for most projects but does not cover some edge-cases (such as - // extensionless files or a url ending in a trailing space) - const isFilePath = !!extname(url); - // If it is a file path, get the directory it's in - const dir = isFilePath ? - dirname(fileURLToPath(url)) : - url; - // Compose a file path to a package.json in the same directory, - // which may or may not exist - const packagePath = resolvePath(dir, 'package.json'); - // Try to read the possibly nonexistent package.json - const type = await readFile(packagePath, { encoding: 'utf8' }) - .then((filestring) => JSON.parse(filestring).type) - .catch((err) => { - if (err?.code !== 'ENOENT') console.error(err); - }); - // Ff package.json existed and contained a `type` field with a value, voila - if (type) return type; - // Otherwise, (if not at the root) continue checking the next directory up - // If at the root, stop and return false - return dir.length > 1 && getPackageType(resolvePath(dir, '..')); -} -``` - -```coffee -# main.coffee -import { scream } from './scream.coffee' -console.log scream 'hello, world' - -import { version } from 'node:process' -console.log "Brought to you by Node.js version #{version}" -``` - -```coffee -# scream.coffee -export scream = (str) -> str.toUpperCase() -``` - -With the preceding loader, running -`node --experimental-loader ./coffeescript-loader.mjs main.coffee` -causes `main.coffee` to be turned into JavaScript after its source code is -loaded from disk but before Node.js executes it; and so on for any `.coffee`, -`.litcoffee` or `.coffee.md` files referenced via `import` statements of any -loaded file. - -#### "import map" loader - -The previous two loaders defined `load` hooks. This is an example of a loader -that does its work via the `resolve` hook. This loader reads an -`import-map.json` file that specifies which specifiers to override to another -URL (this is a very simplistic implemenation of a small subset of the -"import maps" specification). - -```js -// import-map-loader.js -import fs from 'node:fs/promises'; - -const { imports } = JSON.parse(await fs.readFile('import-map.json')); - -export async function resolve(specifier, context, nextResolve) { - if (Object.hasOwn(imports, specifier)) { - return nextResolve(imports[specifier], context); - } - - return nextResolve(specifier, context); -} -``` - -Let's assume we have these files: - -```js -// main.js -import 'a-module'; -``` - -```json -// import-map.json -{ - "imports": { - "a-module": "./some-module.js" - } -} -``` - -```js -// some-module.js -console.log('some module!'); -``` - -If you run `node --experimental-loader ./import-map-loader.js main.js` -the output will be `some module!`. - -### Register loaders programmatically - - - -In addition to using the `--experimental-loader` option in the CLI, -loaders can also be registered programmatically. You can find -detailed information about this process in the documentation page -for [`module.register()`][]. +The former Loaders documentation is now at +[Modules: Customization hooks][Module customization hooks]. ## Resolution and loading algorithm @@ -1574,54 +1037,43 @@ _isImports_, _conditions_) ### Customizing ESM specifier resolution algorithm -The [Loaders API][] provides a mechanism for customizing the ESM specifier -resolution algorithm. An example loader that provides CommonJS-style resolution -for ESM specifiers is [commonjs-extension-resolution-loader][]. +[Module customization hooks][] provide a mechanism for customizing the ESM +specifier resolution algorithm. An example that provides CommonJS-style +resolution for ESM specifiers is [commonjs-extension-resolution-loader][]. [6.1.7 Array Index]: https://tc39.es/ecma262/#integer-index [Addons]: addons.md [CommonJS]: modules.md -[Conditional exports]: packages.md#conditional-exports [Core modules]: modules.md#core-modules [Determining module system]: packages.md#determining-module-system [Dynamic `import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import [ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration -[HTTPS and HTTP imports]: #https-and-http-imports [Import Assertions]: #import-assertions [Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions [JSON modules]: #json-modules -[Loaders API]: #loaders +[Module customization hooks]: module.md#customization-hooks [Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification [Terminology]: #terminology [URL]: https://url.spec.whatwg.org/ [`"exports"`]: packages.md#exports [`"type"`]: packages.md#type [`--input-type`]: cli.md#--input-typetype -[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer -[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer -[`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray -[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array [`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs [`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export [`import()`]: #import-expressions -[`import.meta.resolve`]: #importmetaresolvespecifier-parent +[`import.meta.resolve`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve [`import.meta.url`]: #importmetaurl [`import`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import [`module.createRequire()`]: module.md#modulecreaterequirefilename -[`module.register()`]: module.md#moduleregister [`module.syncBuiltinESMExports()`]: module.md#modulesyncbuiltinesmexports [`package.json`]: packages.md#nodejs-packagejson-field-definitions -[`port.ref()`]: https://nodejs.org/dist/latest-v17.x/docs/api/worker_threads.html#portref -[`port.unref()`]: https://nodejs.org/dist/latest-v17.x/docs/api/worker_threads.html#portunref [`process.dlopen`]: process.md#processdlopenmodule-filename-flags -[`string`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String -[`util.TextDecoder`]: util.md#class-utiltextdecoder [cjs-module-lexer]: https://github.com/nodejs/cjs-module-lexer/tree/1.2.2 [commonjs-extension-resolution-loader]: https://github.com/nodejs/loaders-test/tree/main/commonjs-extension-resolution-loader -[custom https loader]: #https-loader -[load hook]: #loadurl-context-nextload +[custom https loader]: module.md#import-from-https +[import.meta.resolve]: #importmetaresolvespecifier [percent-encoded]: url.md#percent-encoding-in-urls [special scheme]: https://url.spec.whatwg.org/#special-scheme [status code]: process.md#exit-codes diff --git a/doc/api/events.md b/doc/api/events.md index c4e58442991364..19fccbce0c5a4b 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -105,7 +105,7 @@ class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', (a, b) => { console.log(a, b, this); - // Prints: a b {} + // Prints: a b undefined }); myEmitter.emit('event', 'a', 'b'); ``` @@ -1271,7 +1271,9 @@ const { getEventListeners, EventEmitter } = require('node:events'); ## `events.getMaxListeners(emitterOrTarget)` * `emitterOrTarget` {EventEmitter|EventTarget} @@ -1801,10 +1803,12 @@ const emitter = new EventEmitter(); setMaxListeners(5, target, emitter); ``` -## `events.addAbortListener(signal, resource)` +## `events.addAbortListener(signal, listener)` > Stability: 1 - Experimental diff --git a/doc/api/fs.md b/doc/api/fs.md index d52662a63f75cb..98abd7eadd8714 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -325,6 +325,7 @@ added: v16.11.0 * `autoClose` {boolean} **Default:** `true` * `emitClose` {boolean} **Default:** `true` * `start` {integer} + * `highWaterMark` {number} **Default:** `16384` * Returns: {fs.WriteStream} `options` may also include a `start` option to allow writing data at some @@ -446,12 +447,14 @@ Reads data from the file and stores that in the given buffer. If the file is not modified concurrently, the end-of-file is reached when the number of bytes read is zero. -#### `filehandle.readableWebStream(options)` +#### `filehandle.readableWebStream([options])` @@ -820,7 +823,9 @@ the end of the file. #### `filehandle[Symbol.asyncDispose]()` > Stability: 1 - Experimental @@ -976,7 +981,9 @@ try { -* `prefix` {string} +* `prefix` {string|Buffer|URL} * `options` {string|Object} * `encoding` {string} **Default:** `'utf8'` * Returns: {Promise} Fulfills with a string containing the file system path @@ -1230,7 +1241,9 @@ a colon, Node.js will open a file system stream, as described by -* `prefix` {string} +* `prefix` {string|Buffer|URL} * `options` {string|Object} * `encoding` {string} **Default:** `'utf8'` * `callback` {Function} @@ -3422,7 +3448,9 @@ const { openAsBlob } = require('node:fs'); -* `prefix` {string} +* `prefix` {string|Buffer|URL} * `options` {string|Object} * `encoding` {string} **Default:** `'utf8'` * Returns: {string} @@ -5575,7 +5611,9 @@ object with an `encoding` property specifying the character encoding to use. * {string} diff --git a/doc/api/globals.md b/doc/api/globals.md index 63b15b4b7f8788..7cc6b3d02454eb 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -124,7 +124,9 @@ Returns a new `AbortSignal` which will be aborted in `delay` milliseconds. #### Static method: `AbortSignal.any(signals)` * `signals` {AbortSignal\[]} The `AbortSignal`s of which to compose a new `AbortSignal`. @@ -476,13 +478,16 @@ added: - v17.5.0 - v16.15.0 changes: + - version: + - REPLACEME + pr-url: https://github.com/nodejs/node/pull/45684 + description: No longer experimental. - version: v18.0.0 pr-url: https://github.com/nodejs/node/pull/41811 description: No longer behind `--experimental-global-fetch` CLI flag. --> -> Stability: 1 - Experimental. Disable this API with the [`--no-experimental-fetch`][] -> CLI flag. +> Stability: 2 - Stable A browser-compatible implementation of the [`fetch()`][] function. @@ -503,13 +508,16 @@ added: - v17.6.0 - v16.15.0 changes: + - version: + - REPLACEME + pr-url: https://github.com/nodejs/node/pull/45684 + description: No longer experimental. - version: v18.0.0 pr-url: https://github.com/nodejs/node/pull/41811 description: No longer behind `--experimental-global-fetch` CLI flag. --> -> Stability: 1 - Experimental. Disable this API with the [`--no-experimental-fetch`][] -> CLI flag. +> Stability: 2 - Stable A browser-compatible implementation of {FormData}. @@ -539,13 +547,16 @@ added: - v17.5.0 - v16.15.0 changes: + - version: + - REPLACEME + pr-url: https://github.com/nodejs/node/pull/45684 + description: No longer experimental. - version: v18.0.0 pr-url: https://github.com/nodejs/node/pull/41811 description: No longer behind `--experimental-global-fetch` CLI flag. --> -> Stability: 1 - Experimental. Disable this API with the [`--no-experimental-fetch`][] -> CLI flag. +> Stability: 2 - Stable A browser-compatible implementation of {Headers}. @@ -811,13 +822,16 @@ added: - v17.5.0 - v16.15.0 changes: + - version: + - REPLACEME + pr-url: https://github.com/nodejs/node/pull/45684 + description: No longer experimental. - version: v18.0.0 pr-url: https://github.com/nodejs/node/pull/41811 description: No longer behind `--experimental-global-fetch` CLI flag. --> -> Stability: 1 - Experimental. Disable this API with the [`--no-experimental-fetch`][] -> CLI flag. +> Stability: 2 - Stable A browser-compatible implementation of {Response}. @@ -828,13 +842,16 @@ added: - v17.5.0 - v16.15.0 changes: + - version: + - REPLACEME + pr-url: https://github.com/nodejs/node/pull/45684 + description: No longer experimental. - version: v18.0.0 pr-url: https://github.com/nodejs/node/pull/41811 description: No longer behind `--experimental-global-fetch` CLI flag. --> -> Stability: 1 - Experimental. Disable this API with the [`--no-experimental-fetch`][] -> CLI flag. +> Stability: 2 - Stable A browser-compatible implementation of {Request}. @@ -1035,7 +1052,6 @@ A browser-compatible implementation of [`WritableStreamDefaultWriter`][]. [ECMAScript module]: esm.md [Navigator API]: https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object [Web Crypto API]: webcrypto.md -[`--no-experimental-fetch`]: cli.md#--no-experimental-fetch [`--no-experimental-global-customevent`]: cli.md#--no-experimental-global-customevent [`--no-experimental-global-webcrypto`]: cli.md#--no-experimental-global-webcrypto [`AbortController`]: https://developer.mozilla.org/en-US/docs/Web/API/AbortController diff --git a/doc/api/http.md b/doc/api/http.md index a0437f329bb148..ce761af7561198 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -187,7 +187,14 @@ of these values set to their respective defaults. To configure any of them, a custom [`http.Agent`][] instance must be created. -```js +```mjs +import { Agent, request } from 'node:http'; +const keepAliveAgent = new Agent({ keepAlive: true }); +options.agent = keepAliveAgent; +request(options, onResponseCallback); +``` + +```cjs const http = require('node:http'); const keepAliveAgent = new http.Agent({ keepAlive: true }); options.agent = keepAliveAgent; @@ -474,7 +481,62 @@ type other than {net.Socket}. A client and server pair demonstrating how to listen for the `'connect'` event: -```js +```mjs +import { createServer, request } from 'node:http'; +import { connect } from 'node:net'; +import { URL } from 'node:url'; + +// Create an HTTP tunneling proxy +const proxy = createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('okay'); +}); +proxy.on('connect', (req, clientSocket, head) => { + // Connect to an origin server + const { port, hostname } = new URL(`http://${req.url}`); + const serverSocket = connect(port || 80, hostname, () => { + clientSocket.write('HTTP/1.1 200 Connection Established\r\n' + + 'Proxy-agent: Node.js-Proxy\r\n' + + '\r\n'); + serverSocket.write(head); + serverSocket.pipe(clientSocket); + clientSocket.pipe(serverSocket); + }); +}); + +// Now that proxy is running +proxy.listen(1337, '127.0.0.1', () => { + + // Make a request to a tunneling proxy + const options = { + port: 1337, + host: '127.0.0.1', + method: 'CONNECT', + path: 'www.google.com:80', + }; + + const req = request(options); + req.end(); + + req.on('connect', (res, socket, head) => { + console.log('got connected!'); + + // Make a request over an HTTP tunnel + socket.write('GET / HTTP/1.1\r\n' + + 'Host: www.google.com:80\r\n' + + 'Connection: close\r\n' + + '\r\n'); + socket.on('data', (chunk) => { + console.log(chunk.toString()); + }); + socket.on('end', () => { + proxy.close(); + }); + }); +}); +``` + +```cjs const http = require('node:http'); const net = require('node:net'); const { URL } = require('node:url'); @@ -570,7 +632,25 @@ Upgrade). The listeners of this event will receive an object containing the HTTP version, status code, status message, key-value headers object, and array with the raw header names followed by their respective values. -```js +```mjs +import { request } from 'node:http'; + +const options = { + host: '127.0.0.1', + port: 8080, + path: '/length_request', +}; + +// Make a request +const req = request(options); +req.end(); + +req.on('information', (info) => { + console.log(`Got information prior to main response: ${info.statusCode}`); +}); +``` + +```cjs const http = require('node:http'); const options = { @@ -648,7 +728,49 @@ type other than {net.Socket}. A client server pair demonstrating how to listen for the `'upgrade'` event. -```js +```mjs +import http from 'node:http'; +import process from 'node:process'; + +// Create an HTTP server +const server = http.createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('okay'); +}); +server.on('upgrade', (req, socket, head) => { + socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + + 'Upgrade: WebSocket\r\n' + + 'Connection: Upgrade\r\n' + + '\r\n'); + + socket.pipe(socket); // echo back +}); + +// Now that server is running +server.listen(1337, '127.0.0.1', () => { + + // make a request + const options = { + port: 1337, + host: '127.0.0.1', + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket', + }, + }; + + const req = http.request(options); + req.end(); + + req.on('upgrade', (res, socket, upgradeHead) => { + console.log('got upgraded!'); + socket.end(); + process.exit(0); + }); +}); +``` + +```cjs const http = require('node:http'); // Create an HTTP server @@ -1019,7 +1141,28 @@ When sending request through a keep-alive enabled agent, the underlying socket might be reused. But if server closes connection at unfortunate time, client may run into a 'ECONNRESET' error. -```js +```mjs +import http from 'node:http'; + +// Server has a 5 seconds keep-alive timeout by default +http + .createServer((req, res) => { + res.write('hello\n'); + res.end(); + }) + .listen(3000); + +setInterval(() => { + // Adapting a keep-alive agent + http.get('http://localhost:3000', { agent }, (res) => { + res.on('data', (data) => { + // Do nothing + }); + }); +}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout +``` + +```cjs const http = require('node:http'); // Server has a 5 seconds keep-alive timeout by default @@ -1043,7 +1186,27 @@ setInterval(() => { By marking a request whether it reused socket or not, we can do automatic error retry base on it. -```js +```mjs +import http from 'node:http'; +const agent = new http.Agent({ keepAlive: true }); + +function retriableRequest() { + const req = http + .get('http://localhost:3000', { agent }, (res) => { + // ... + }) + .on('error', (err) => { + // Check if retry is needed + if (req.reusedSocket && err.code === 'ECONNRESET') { + retriableRequest(); + } + }); +} + +retriableRequest(); +``` + +```cjs const http = require('node:http'); const agent = new http.Agent({ keepAlive: true }); @@ -1153,7 +1316,22 @@ Reference to the underlying socket. Usually users will not want to access this property. In particular, the socket will not emit `'readable'` events because of how the protocol parser attaches to the socket. -```js +```mjs +import http from 'node:http'; +const options = { + host: 'www.google.com', +}; +const req = http.get(options); +req.end(); +req.once('response', (res) => { + const ip = req.socket.localAddress; + const port = req.socket.localPort; + console.log(`Your IP address is ${ip} and your source port is ${port}.`); + // Consume response object +}); +``` + +```cjs const http = require('node:http'); const options = { host: 'www.google.com', @@ -1326,7 +1504,19 @@ immediately destroyed. `socket` is the [`net.Socket`][] object that the error originated from. -```js +```mjs +import http from 'node:http'; + +const server = http.createServer((req, res) => { + res.end(); +}); +server.on('clientError', (err, socket) => { + socket.end('HTTP/1.1 400 Bad Request\r\n\r\n'); +}); +server.listen(8000); +``` + +```cjs const http = require('node:http'); const server = http.createServer((req, res) => { @@ -2034,7 +2224,16 @@ this property. In particular, the socket will not emit `'readable'` events because of how the protocol parser attaches to the socket. After `response.end()`, the property is nulled. -```js +```mjs +import http from 'node:http'; +const server = http.createServer((req, res) => { + const ip = res.socket.remoteAddress; + const port = res.socket.remotePort; + res.end(`Your IP address is ${ip} and your source port is ${port}.`); +}).listen(3000); +``` + +```cjs const http = require('node:http'); const server = http.createServer((req, res) => { const ip = res.socket.remoteAddress; @@ -3204,7 +3403,9 @@ Found'`. true + console.error(err.code); // --> 'ERR_INVALID_HTTP_TOKEN' + console.error(err.message); // --> 'Header name must be a valid HTTP token [""]' +} +``` + +```cjs const { validateHeaderName } = require('node:http'); try { @@ -3807,7 +4093,27 @@ or response. The HTTP module will automatically validate such headers. Examples: -```js +```mjs +import { validateHeaderValue } from 'node:http'; + +try { + validateHeaderValue('x-my-header', undefined); +} catch (err) { + console.error(err instanceof TypeError); // --> true + console.error(err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'); // --> true + console.error(err.message); // --> 'Invalid value "undefined" for header "x-my-header"' +} + +try { + validateHeaderValue('x-my-header', 'oʊmɪɡə'); +} catch (err) { + console.error(err instanceof TypeError); // --> true + console.error(err.code === 'ERR_INVALID_CHAR'); // --> true + console.error(err.message); // --> 'Invalid character in header content ["x-my-header"]' +} +``` + +```cjs const { validateHeaderValue } = require('node:http'); try { diff --git a/doc/api/inspector.md b/doc/api/inspector.md index 34fad2a0ca1805..7d91377fc0040e 100644 --- a/doc/api/inspector.md +++ b/doc/api/inspector.md @@ -419,12 +419,20 @@ console. ### `inspector.open([port[, host[, wait]]])` + + * `port` {number} Port to listen on for inspector connections. Optional. **Default:** what was specified on the CLI. * `host` {string} Host to listen on for inspector connections. Optional. **Default:** what was specified on the CLI. * `wait` {boolean} Block until a client has connected. Optional. **Default:** `false`. +* Returns: {Disposable} that calls [`inspector.close()`][]. Activate inspector on host and port. Equivalent to `node --inspect=[[host:]port]`, but can be done programmatically after node has @@ -472,5 +480,6 @@ An exception will be thrown if there is no active inspector. [Chrome DevTools Protocol Viewer]: https://chromedevtools.github.io/devtools-protocol/v8/ [Heap Profiler]: https://chromedevtools.github.io/devtools-protocol/v8/HeapProfiler [`'Debugger.paused'`]: https://chromedevtools.github.io/devtools-protocol/v8/Debugger#event-paused +[`inspector.close()`]: #inspectorclose [`session.connect()`]: #sessionconnect [security warning]: cli.md#warning-binding-inspector-to-a-public-ipport-combination-is-insecure diff --git a/doc/api/intl.md b/doc/api/intl.md index 3af63ae8a19bd7..ec3e26db3b4c1e 100644 --- a/doc/api/intl.md +++ b/doc/api/intl.md @@ -113,27 +113,47 @@ This mode provides a balance between features and binary size. If the `small-icu` option is used, one can still provide additional locale data at runtime so that the JS methods would work for all ICU locales. Assuming the -data file is stored at `/some/directory`, it can be made available to ICU -through either: +data file is stored at `/runtime/directory/with/dat/file`, it can be made +available to ICU through either: + +* The `--with-icu-default-data-dir` configure option: + + ```bash + ./configure --with-icu-default-data-dir=/runtime/directory/with/dat/file --with-intl=small-icu + ``` + + This only embeds the default data directory path into the binary. + The actual data file is going to be loaded at runtime from this directory + path. * The [`NODE_ICU_DATA`][] environment variable: ```bash - env NODE_ICU_DATA=/some/directory node + env NODE_ICU_DATA=/runtime/directory/with/dat/file node ``` * The [`--icu-data-dir`][] CLI parameter: ```bash - node --icu-data-dir=/some/directory + node --icu-data-dir=/runtime/directory/with/dat/file ``` -(If both are specified, the `--icu-data-dir` CLI parameter takes precedence.) +When more than one of them is specified, the `--icu-data-dir` CLI parameter has +the highest precedence, then the `NODE_ICU_DATA` environment variable, then +the `--with-icu-default-data-dir` configure option. ICU is able to automatically find and load a variety of data formats, but the data must be appropriate for the ICU version, and the file correctly named. -The most common name for the data file is `icudt6X[bl].dat`, where `6X` denotes +The most common name for the data file is `icudtX[bl].dat`, where `X` denotes the intended ICU version, and `b` or `l` indicates the system's endianness. +Node.js would fail to load if the expected data file cannot be read from the +specified directory. The name of the data file corresponding to the current +Node.js version can be computed with: + +```js +`icudt${process.versions.icu.split('.')[0]}${os.endianness()[0].toLowerCase()}.dat`; +``` + Check ["ICU Data"][] article in the ICU User Guide for other supported formats and more details on ICU data in general. diff --git a/doc/api/module.md b/doc/api/module.md index 8dd5fd4fa59f6c..3a0d4db6bfec64 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -80,15 +80,139 @@ isBuiltin('fs'); // true isBuiltin('wss'); // false ``` -### `module.register()` +### `module.register(specifier[, parentURL][, options])` -In addition to using the `--experimental-loader` option in the CLI, -loaders can be registered programmatically using the -`module.register()` method. +> Stability: 1.2 - Release candidate + +* `specifier` {string|URL} Customization hooks to be registered; this should be + the same string that would be passed to `import()`, except that if it is + relative, it is resolved relative to `parentURL`. +* `parentURL` {string|URL} If you want to resolve `specifier` relative to a base + URL, such as `import.meta.url`, you can pass that URL here. **Default:** + `'data:'` +* `options` {Object} + * `data` {any} Any arbitrary, cloneable JavaScript value to pass into the + [`initialize`][] hook. + * `transferList` {Object\[]} [transferrable objects][] to be passed into the + `initialize` hook. + +Register a module that exports [hooks][] that customize Node.js module +resolution and loading behavior. See [Customization hooks][]. + +### `module.syncBuiltinESMExports()` + + + +The `module.syncBuiltinESMExports()` method updates all the live bindings for +builtin [ES Modules][] to match the properties of the [CommonJS][] exports. It +does not add or remove exported names from the [ES Modules][]. + +```js +const fs = require('node:fs'); +const assert = require('node:assert'); +const { syncBuiltinESMExports } = require('node:module'); + +fs.readFile = newAPI; + +delete fs.readFileSync; + +function newAPI() { + // ... +} + +fs.newAPI = newAPI; + +syncBuiltinESMExports(); + +import('node:fs').then((esmFS) => { + // It syncs the existing readFile property with the new value + assert.strictEqual(esmFS.readFile, newAPI); + // readFileSync has been deleted from the required fs + assert.strictEqual('readFileSync' in fs, false); + // syncBuiltinESMExports() does not remove readFileSync from esmFS + assert.strictEqual('readFileSync' in esmFS, true); + // syncBuiltinESMExports() does not add names + assert.strictEqual(esmFS.newAPI, undefined); +}); +``` + + + +## Customization Hooks + + + +> Stability: 1.2 - Release candidate + + + + + +### Enabling + +Module resolution and loading can be customized by registering a file which +exports a set of hooks. This can be done using the [`register`][] method +from `node:module`, which you can run before your application code by +using the `--import` flag: + +```bash +node --import ./register-hooks.js ./my-app.js +``` + +```mjs +// register-hooks.js +import { register } from 'node:module'; + +register('./hooks.mjs', import.meta.url); +``` + +```cjs +// register-hooks.js +const { register } = require('node:module'); +const { pathToFileURL } = require('node:url'); + +register('./hooks.mjs', pathToFileURL(__filename)); +``` + +The file passed to `--import` can also be an export from a dependency: + +```bash +node --import some-package/register ./my-app.js +``` + +Where `some-package` has an [`"exports"`][] field defining the `/register` +export to map to a file that calls `register()`, like the following `register-hooks.js` +example. + +Using `--import` ensures that the hooks are registered before any application +files are imported, including the entry point of the application. Alternatively, +`register` can be called from the entry point, but dynamic `import()` must be +used for any code that should be run after the hooks are registered: ```mjs import { register } from 'node:module'; @@ -96,124 +220,662 @@ import { register } from 'node:module'; register('http-to-https', import.meta.url); // Because this is a dynamic `import()`, the `http-to-https` hooks will run -// before importing `./my-app.mjs`. -await import('./my-app.mjs'); +// to handle `./my-app.js` and any other files it imports or requires. +await import('./my-app.js'); ``` -In the example above, we are registering the `http-to-https` loader, -but it will only be available for subsequently imported modules—in -this case, `my-app.mjs`. If the `await import('./my-app.mjs')` had -instead been a static `import './my-app.mjs'`, _the app would already -have been loaded_ before the `http-to-https` hooks were -registered. This is part of the design of ES modules, where static -imports are evaluated from the leaves of the tree first back to the -trunk. There can be static imports _within_ `my-app.mjs`, which -will not be evaluated until `my-app.mjs` is when it's dynamically -imported. +```cjs +const { register } = require('node:module'); +const { pathToFileURL } = require('node:url'); -The `--experimental-loader` flag of the CLI can be used together -with the `register` function; the loaders registered with the -function will follow the same evaluation chain of loaders registered -within the CLI: +register('http-to-https', pathToFileURL(__filename)); + +// Because this is a dynamic `import()`, the `http-to-https` hooks will run +// to handle `./my-app.js` and any other files it imports or requires. +import('./my-app.js'); +``` -```console -node \ - --experimental-loader unpkg \ - --experimental-loader http-to-https \ - --experimental-loader cache-buster \ - entrypoint.mjs +In this example, we are registering the `http-to-https` hooks, but they will +only be available for subsequently imported modules—in this case, `my-app.js` +and anything it references via `import` (and optionally `require`). If the +`import('./my-app.js')` had instead been a static `import './my-app.js'`, the +app would have _already_ been loaded **before** the `http-to-https` hooks were +registered. This due to the ES modules specification, where static imports are +evaluated from the leaves of the tree first, then back to the trunk. There can +be static imports _within_ `my-app.js`, which will not be evaluated until +`my-app.js` is dynamically imported. + +`my-app.js` can also be CommonJS. Customization hooks will run for any +modules that it references via `import` (and optionally `require`). + +Finally, if all you want to do is register hooks before your app runs and you +don't want to create a separate file for that purpose, you can pass a `data:` +URL to `--import`: + +```bash +node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("http-to-https", pathToFileURL("./"));' ./my-app.js ``` +### Chaining + +It's possible to call `register` more than once: + ```mjs // entrypoint.mjs -import { URL } from 'node:url'; import { register } from 'node:module'; -const loaderURL = new URL('./my-programmatically-loader.mjs', import.meta.url); - -register(loaderURL); +register('./first.mjs', import.meta.url); +register('./second.mjs', import.meta.url); await import('./my-app.mjs'); ``` -The `my-programmatic-loader.mjs` can leverage `unpkg`, -`http-to-https`, and `cache-buster` loaders. +```cjs +// entrypoint.cjs +const { register } = require('node:module'); +const { pathToFileURL } = require('node:url'); + +const parentURL = pathToFileURL(__filename); +register('./first.mjs', parentURL); +register('./second.mjs', parentURL); +import('./my-app.mjs'); +``` + +In this example, the registered hooks will form chains. If both `first.mjs` and +`second.mjs` define a `resolve` hook, both will be called, in the order they +were registered. The same applies to all the other hooks. + +The registered hooks also affect `register` itself. In this example, +`second.mjs` will be resolved and loaded per the hooks registered by +`first.mjs`. This allows for things like writing hooks in non-JavaScript +languages, so long as an earlier registered loader is one that transpiles into +JavaScript. -It's also possible to use `register` more than once: +The `register` method cannot be called from within the module that defines the +hooks. + +### Communication with module customization hooks + +Module customization hooks run on a dedicated thread, separate from the main +thread that runs application code. This means mutating global variables won't +affect the other thread(s), and message channels must be used to communicate +between the threads. + +The `register` method can be used to pass data to an [`initialize`][] hook. The +data passed to the hook may include transferrable objects like ports. ```mjs -// entrypoint.mjs -import { URL } from 'node:url'; import { register } from 'node:module'; +import { MessageChannel } from 'node:worker_threads'; -register(new URL('./first-loader.mjs', import.meta.url)); -register('./second-loader.mjs', import.meta.url); -await import('./my-app.mjs'); +// This example demonstrates how a message channel can be used to +// communicate with the hooks, by sending `port2` to the hooks. +const { port1, port2 } = new MessageChannel(); + +port1.on('message', (msg) => { + console.log(msg); +}); + +register('./my-hooks.mjs', { + parentURL: import.meta.url, + data: { number: 1, port: port2 }, + transferList: [port2], +}); ``` -Both loaders (`first-loader.mjs` and `second-loader.mjs`) can use -all the resources provided by the loaders registered in the CLI. But -remember that they will only be available in the next imported -module (`my-app.mjs`). The evaluation order of the hooks when -importing `my-app.mjs` and consecutive modules in the example above -will be: - -```console -resolve: second-loader.mjs -resolve: first-loader.mjs -resolve: cache-buster -resolve: http-to-https -resolve: unpkg -load: second-loader.mjs -load: first-loader.mjs -load: cache-buster -load: http-to-https -load: unpkg -globalPreload: second-loader.mjs -globalPreload: first-loader.mjs -globalPreload: cache-buster -globalPreload: http-to-https -globalPreload: unpkg +```cjs +const { register } = require('node:module'); +const { pathToFileURL } = require('node:url'); +const { MessageChannel } = require('node:worker_threads'); + +// This example showcases how a message channel can be used to +// communicate with the hooks, by sending `port2` to the hooks. +const { port1, port2 } = new MessageChannel(); + +port1.on('message', (msg) => { + console.log(msg); +}); + +register('./my-hooks.mjs', { + parentURL: pathToFileURL(__filename), + data: { number: 1, port: port2 }, + transferList: [port2], +}); ``` -### `module.syncBuiltinESMExports()` +### Hooks + +The [`register`][] method can be used to register a module that exports a set of +hooks. The hooks are functions that are called by Node.js to customize the +module resolution and loading process. The exported functions must have specific +names and signatures, and they must be exported as named exports. + +```mjs +export async function initialize({ number, port }) { + // Receives data from `register`. +} + +export async function resolve(specifier, context, nextResolve) { + // Take an `import` or `require` specifier and resolve it to a URL. +} + +export async function load(url, context, nextLoad) { + // Take a resolved URL and return the source code to be evaluated. +} +``` + +Hooks are part of a chain, even if that chain consists of only one custom +(user-provided) hook and the default hook, which is always present. Hook +functions nest: each one must always return a plain object, and chaining happens +as a result of each function calling `next()`, which is a reference to +the subsequent loader's hook. + +A hook that returns a value lacking a required property triggers an exception. A +hook that returns without calling `next()` _and_ without returning +`shortCircuit: true` also triggers an exception. These errors are to help +prevent unintentional breaks in the chain. Return `shortCircuit: true` from a +hook to signal that the chain is intentionally ending at your hook. + +Hooks are run in a separate thread, isolated from the main thread where +application code runs. That means it is a different [realm][]. The hooks thread +may be terminated by the main thread at any time, so do not depend on +asynchronous operations (like `console.log`) to complete. + +#### `initialize()` -The `module.syncBuiltinESMExports()` method updates all the live bindings for -builtin [ES Modules][] to match the properties of the [CommonJS][] exports. It -does not add or remove exported names from the [ES Modules][]. +> Stability: 1.2 - Release candidate -```js -const fs = require('node:fs'); -const assert = require('node:assert'); -const { syncBuiltinESMExports } = require('node:module'); +* `data` {any} The data from `register(loader, import.meta.url, { data })`. -fs.readFile = newAPI; +The `initialize` hook provides a way to define a custom function that runs in +the hooks thread when the hooks module is initialized. Initialization happens +when the hooks module is registered via [`register`][]. -delete fs.readFileSync; +This hook can receive data from a [`register`][] invocation, including +ports and other transferrable objects. The return value of `initialize` can be a +{Promise}, in which case it will be awaited before the main application thread +execution resumes. -function newAPI() { - // ... +Module customization code: + +```mjs +// path-to-my-hooks.js + +export async function initialize({ number, port }) { + port.postMessage(`increment: ${number + 1}`); } +``` -fs.newAPI = newAPI; +Caller code: -syncBuiltinESMExports(); +```mjs +import assert from 'node:assert'; +import { register } from 'node:module'; +import { MessageChannel } from 'node:worker_threads'; -import('node:fs').then((esmFS) => { - // It syncs the existing readFile property with the new value - assert.strictEqual(esmFS.readFile, newAPI); - // readFileSync has been deleted from the required fs - assert.strictEqual('readFileSync' in fs, false); - // syncBuiltinESMExports() does not remove readFileSync from esmFS - assert.strictEqual('readFileSync' in esmFS, true); - // syncBuiltinESMExports() does not add names - assert.strictEqual(esmFS.newAPI, undefined); +// This example showcases how a message channel can be used to communicate +// between the main (application) thread and the hooks running on the hooks +// thread, by sending `port2` to the `initialize` hook. +const { port1, port2 } = new MessageChannel(); + +port1.on('message', (msg) => { + assert.strictEqual(msg, 'increment: 2'); +}); + +register('./path-to-my-hooks.js', { + parentURL: import.meta.url, + data: { number: 1, port: port2 }, + transferList: [port2], }); ``` +```cjs +const assert = require('node:assert'); +const { register } = require('node:module'); +const { pathToFileURL } = require('node:url'); +const { MessageChannel } = require('node:worker_threads'); + +// This example showcases how a message channel can be used to communicate +// between the main (application) thread and the hooks running on the hooks +// thread, by sending `port2` to the `initialize` hook. +const { port1, port2 } = new MessageChannel(); + +port1.on('message', (msg) => { + assert.strictEqual(msg, 'increment: 2'); +}); + +register('./path-to-my-hooks.js', { + parentURL: pathToFileURL(__filename), + data: { number: 1, port: port2 }, + transferList: [port2], +}); +``` + +#### `resolve(specifier, context, nextResolve)` + + + +> Stability: 1.2 - Release candidate + +* `specifier` {string} +* `context` {Object} + * `conditions` {string\[]} Export conditions of the relevant `package.json` + * `importAssertions` {Object} An object whose key-value pairs represent the + assertions for the module to import + * `parentURL` {string|undefined} The module importing this one, or undefined + if this is the Node.js entry point +* `nextResolve` {Function} The subsequent `resolve` hook in the chain, or the + Node.js default `resolve` hook after the last user-supplied `resolve` hook + * `specifier` {string} + * `context` {Object} +* Returns: {Object|Promise} + * `format` {string|null|undefined} A hint to the load hook (it might be + ignored) + `'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'` + * `importAssertions` {Object|undefined} The import assertions to use when + caching the module (optional; if excluded the input will be used) + * `shortCircuit` {undefined|boolean} A signal that this hook intends to + terminate the chain of `resolve` hooks. **Default:** `false` + * `url` {string} The absolute URL to which this input resolves + +> **Warning** Despite support for returning promises and async functions, calls +> to `resolve` may block the main thread which can impact performance. + +The `resolve` hook chain is responsible for telling Node.js where to find and +how to cache a given `import` statement or expression, or `require` call. It can +optionally return a format (such as `'module'`) as a hint to the `load` hook. If +a format is specified, the `load` hook is ultimately responsible for providing +the final `format` value (and it is free to ignore the hint provided by +`resolve`); if `resolve` provides a `format`, a custom `load` hook is required +even if only to pass the value to the Node.js default `load` hook. + +Import type assertions are part of the cache key for saving loaded modules into +the internal module cache. The `resolve` hook is responsible for returning an +`importAssertions` object if the module should be cached with different +assertions than were present in the source code. + +The `conditions` property in `context` is an array of conditions for +[package exports conditions][Conditional exports] that apply to this resolution +request. They can be used for looking up conditional mappings elsewhere or to +modify the list when calling the default resolution logic. + +The current [package exports conditions][Conditional exports] are always in +the `context.conditions` array passed into the hook. To guarantee _default +Node.js module specifier resolution behavior_ when calling `defaultResolve`, the +`context.conditions` array passed to it _must_ include _all_ elements of the +`context.conditions` array originally passed into the `resolve` hook. + +```mjs +export async function resolve(specifier, context, nextResolve) { + const { parentURL = null } = context; + + if (Math.random() > 0.5) { // Some condition. + // For some or all specifiers, do some custom logic for resolving. + // Always return an object of the form {url: }. + return { + shortCircuit: true, + url: parentURL ? + new URL(specifier, parentURL).href : + new URL(specifier).href, + }; + } + + if (Math.random() < 0.5) { // Another condition. + // When calling `defaultResolve`, the arguments can be modified. In this + // case it's adding another value for matching conditional exports. + return nextResolve(specifier, { + ...context, + conditions: [...context.conditions, 'another-condition'], + }); + } + + // Defer to the next hook in the chain, which would be the + // Node.js default resolve if this is the last user-specified loader. + return nextResolve(specifier); +} +``` + +#### `load(url, context, nextLoad)` + + + +> Stability: 1.2 - Release candidate + +* `url` {string} The URL returned by the `resolve` chain +* `context` {Object} + * `conditions` {string\[]} Export conditions of the relevant `package.json` + * `format` {string|null|undefined} The format optionally supplied by the + `resolve` hook chain + * `importAssertions` {Object} +* `nextLoad` {Function} The subsequent `load` hook in the chain, or the + Node.js default `load` hook after the last user-supplied `load` hook + * `specifier` {string} + * `context` {Object} +* Returns: {Object} + * `format` {string} + * `shortCircuit` {undefined|boolean} A signal that this hook intends to + terminate the chain of `resolve` hooks. **Default:** `false` + * `source` {string|ArrayBuffer|TypedArray} The source for Node.js to evaluate + +The `load` hook provides a way to define a custom method of determining how a +URL should be interpreted, retrieved, and parsed. It is also in charge of +validating the import assertion. + +The final value of `format` must be one of the following: + +| `format` | Description | Acceptable types for `source` returned by `load` | +| ------------ | ------------------------------ | -------------------------------------------------------------------------- | +| `'builtin'` | Load a Node.js builtin module | Not applicable | +| `'commonjs'` | Load a Node.js CommonJS module | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][], `null`, `undefined` } | +| `'json'` | Load a JSON file | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | +| `'module'` | Load an ES module | { [`string`][], [`ArrayBuffer`][], [`TypedArray`][] } | +| `'wasm'` | Load a WebAssembly module | { [`ArrayBuffer`][], [`TypedArray`][] } | + +The value of `source` is ignored for type `'builtin'` because currently it is +not possible to replace the value of a Node.js builtin (core) module. + +Omitting vs providing a `source` for `'commonjs'` has very different effects: + +* When a `source` is provided, all `require` calls from this module will be + processed by the ESM loader with registered `resolve` and `load` hooks; all + `require.resolve` calls from this module will be processed by the ESM loader + with registered `resolve` hooks; only a subset of the CommonJS API will be + available (e.g. no `require.extensions`, no `require.cache`, no + `require.resolve.paths`) and monkey-patching on the CommonJS module loader + will not apply. +* If `source` is undefined or `null`, it will be handled by the CommonJS module + loader and `require`/`require.resolve` calls will not go through the + registered hooks. This behavior for nullish `source` is temporary — in the + future, nullish `source` will not be supported. + +The Node.js internal `load` implementation, which is the value of `next` for the +last hook in the `load` chain, returns `null` for `source` when `format` is +`'commonjs'` for backward compatibility. Here is an example hook that would +opt-in to using the non-default behavior: + +```mjs +import { readFile } from 'node:fs/promises'; + +export async function load(url, context, nextLoad) { + const result = await nextLoad(url, context); + if (result.format === 'commonjs') { + result.source ??= await readFile(new URL(result.responseURL ?? url)); + } + return result; +} +``` + +> **Warning**: The ESM `load` hook and namespaced exports from CommonJS modules +> are incompatible. Attempting to use them together will result in an empty +> object from the import. This may be addressed in the future. + +> These types all correspond to classes defined in ECMAScript. + +* The specific [`ArrayBuffer`][] object is a [`SharedArrayBuffer`][]. +* The specific [`TypedArray`][] object is a [`Uint8Array`][]. + +If the source value of a text-based format (i.e., `'json'`, `'module'`) +is not a string, it is converted to a string using [`util.TextDecoder`][]. + +The `load` hook provides a way to define a custom method for retrieving the +source code of a resolved URL. This would allow a loader to potentially avoid +reading files from disk. It could also be used to map an unrecognized format to +a supported one, for example `yaml` to `module`. + +```mjs +export async function load(url, context, nextLoad) { + const { format } = context; + + if (Math.random() > 0.5) { // Some condition + /* + For some or all URLs, do some custom logic for retrieving the source. + Always return an object of the form { + format: , + source: , + }. + */ + return { + format, + shortCircuit: true, + source: '...', + }; + } + + // Defer to the next hook in the chain. + return nextLoad(url); +} +``` + +In a more advanced scenario, this can also be used to transform an unsupported +source to a supported one (see [Examples](#examples) below). + +### Examples + +The various module customization hooks can be used together to accomplish +wide-ranging customizations of the Node.js code loading and evaluation +behaviors. + +#### Import from HTTPS + +In current Node.js, specifiers starting with `https://` are experimental (see +[HTTPS and HTTP imports][]). + +The hook below registers hooks to enable rudimentary support for such +specifiers. While this may seem like a significant improvement to Node.js core +functionality, there are substantial downsides to actually using these hooks: +performance is much slower than loading files from disk, there is no caching, +and there is no security. + +```mjs +// https-hooks.mjs +import { get } from 'node:https'; + +export function load(url, context, nextLoad) { + // For JavaScript to be loaded over the network, we need to fetch and + // return it. + if (url.startsWith('https://')) { + return new Promise((resolve, reject) => { + get(url, (res) => { + let data = ''; + res.setEncoding('utf8'); + res.on('data', (chunk) => data += chunk); + res.on('end', () => resolve({ + // This example assumes all network-provided JavaScript is ES module + // code. + format: 'module', + shortCircuit: true, + source: data, + })); + }).on('error', (err) => reject(err)); + }); + } + + // Let Node.js handle all other URLs. + return nextLoad(url); +} +``` + +```mjs +// main.mjs +import { VERSION } from 'https://coffeescript.org/browser-compiler-modern/coffeescript.js'; + +console.log(VERSION); +``` + +With the preceding hooks module, running +`node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./https-hooks.mjs"));' ./main.mjs` +prints the current version of CoffeeScript per the module at the URL in +`main.mjs`. + +#### Transpilation + +Sources that are in formats Node.js doesn't understand can be converted into +JavaScript using the [`load` hook][load hook]. + +This is less performant than transpiling source files before running Node.js; +transpiler hooks should only be used for development and testing purposes. + +```mjs +// coffeescript-hooks.mjs +import { readFile } from 'node:fs/promises'; +import { dirname, extname, resolve as resolvePath } from 'node:path'; +import { cwd } from 'node:process'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import coffeescript from 'coffeescript'; + +const extensionsRegex = /\.(coffee|litcoffee|coffee\.md)$/; + +export async function load(url, context, nextLoad) { + if (extensionsRegex.test(url)) { + // CoffeeScript files can be either CommonJS or ES modules, so we want any + // CoffeeScript file to be treated by Node.js the same as a .js file at the + // same location. To determine how Node.js would interpret an arbitrary .js + // file, search up the file system for the nearest parent package.json file + // and read its "type" field. + const format = await getPackageType(url); + + const { source: rawSource } = await nextLoad(url, { ...context, format }); + // This hook converts CoffeeScript source code into JavaScript source code + // for all imported CoffeeScript files. + const transformedSource = coffeescript.compile(rawSource.toString(), url); + + return { + format, + shortCircuit: true, + source: transformedSource, + }; + } + + // Let Node.js handle all other URLs. + return nextLoad(url); +} + +async function getPackageType(url) { + // `url` is only a file path during the first iteration when passed the + // resolved url from the load() hook + // an actual file path from load() will contain a file extension as it's + // required by the spec + // this simple truthy check for whether `url` contains a file extension will + // work for most projects but does not cover some edge-cases (such as + // extensionless files or a url ending in a trailing space) + const isFilePath = !!extname(url); + // If it is a file path, get the directory it's in + const dir = isFilePath ? + dirname(fileURLToPath(url)) : + url; + // Compose a file path to a package.json in the same directory, + // which may or may not exist + const packagePath = resolvePath(dir, 'package.json'); + // Try to read the possibly nonexistent package.json + const type = await readFile(packagePath, { encoding: 'utf8' }) + .then((filestring) => JSON.parse(filestring).type) + .catch((err) => { + if (err?.code !== 'ENOENT') console.error(err); + }); + // Ff package.json existed and contained a `type` field with a value, voila + if (type) return type; + // Otherwise, (if not at the root) continue checking the next directory up + // If at the root, stop and return false + return dir.length > 1 && getPackageType(resolvePath(dir, '..')); +} +``` + +```coffee +# main.coffee +import { scream } from './scream.coffee' +console.log scream 'hello, world' + +import { version } from 'node:process' +console.log "Brought to you by Node.js version #{version}" +``` + +```coffee +# scream.coffee +export scream = (str) -> str.toUpperCase() +``` + +With the preceding hooks module, running +`node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./coffeescript-hooks.mjs"));' ./main.coffee` +causes `main.coffee` to be turned into JavaScript after its source code is +loaded from disk but before Node.js executes it; and so on for any `.coffee`, +`.litcoffee` or `.coffee.md` files referenced via `import` statements of any +loaded file. + +#### Import maps + +The previous two examples defined `load` hooks. This is an example of a +`resolve` hook. This hooks module reads an `import-map.json` file that defines +which specifiers to override to other URLs (this is a very simplistic +implementation of a small subset of the "import maps" specification). + +```mjs +// import-map-hooks.js +import fs from 'node:fs/promises'; + +const { imports } = JSON.parse(await fs.readFile('import-map.json')); + +export async function resolve(specifier, context, nextResolve) { + if (Object.hasOwn(imports, specifier)) { + return nextResolve(imports[specifier], context); + } + + return nextResolve(specifier, context); +} +``` + +With these files: + +```mjs +// main.js +import 'a-module'; +``` + +```json +// import-map.json +{ + "imports": { + "a-module": "./some-module.js" + } +} +``` + +```mjs +// some-module.js +console.log('some module!'); +``` + +Running `node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./import-map-hooks.js"));' main.js` +should print `some module!`. + ## Source map v3 support - - - - - - - - - - - - - - - - + + - - - - + + - - - - + + -
123
v6.xv6.14.2*
v8.xv8.6.0**v8.10.0*v8.11.2Node-API versionSupported In
v9.xv9.0.0*v9.3.0*v9.11.0*9v18.17.0+, 20.3.0+, 21.0.0 and all later versions
≥ v10.xall releasesall releasesall releases8v12.22.0+, v14.17.0+, v15.12.0+, 16.0.0 and all later versions
- - - - - - - - + + - - - - - - + + - - - - - - + + - - - - - - + + - - - - - - - - - - - - - - + + + - - - - - - + + - - - - - - + +
456787v10.23.0+, v12.19.0+, v14.12.0+, 15.0.0 and all later versions
v10.xv10.16.0v10.17.0v10.20.0v10.23.06v10.20.0+, v12.17.0+, 14.0.0 and all later versions
v11.xv11.8.05v10.17.0+, v12.11.0+, 13.0.0 and all later versions
v12.xv12.0.0v12.11.0v12.17.0v12.19.0v12.22.04v10.16.0+, v11.8.0+, 12.0.0 and all later versions
v13.xv13.0.0v13.0.0
v14.xv14.0.0v14.0.0v14.0.0v14.12.0v14.17.0
3v6.14.2*, 8.11.2+, v9.11.0+*, 10.0.0 and all later versions
v15.xv15.0.0v15.0.0v15.0.0v15.0.0v15.12.02v8.10.0+*, v9.3.0+*, 10.0.0 and all later versions
v16.xv16.0.0v16.0.0v16.0.0v16.0.0v16.0.01v8.6.0+**, v9.0.0+*, 10.0.0 and all later versions
@@ -398,7 +346,7 @@ napi_value create_addon(napi_env env); // addon.c #include "addon.h" -#define NAPI_CALL(env, call) \ +#define NODE_API_CALL(env, call) \ do { \ napi_status status = (call); \ if (status != napi_ok) { \ @@ -407,13 +355,14 @@ napi_value create_addon(napi_env env); const char* err_message = error_info->error_message; \ bool is_pending; \ napi_is_exception_pending((env), &is_pending); \ + /* If an exception is already pending, don't rethrow it */ \ if (!is_pending) { \ const char* message = (err_message == NULL) \ ? "empty error message" \ : err_message; \ napi_throw_error((env), NULL, message); \ - return NULL; \ } \ + return NULL; \ } \ } while(0) @@ -425,20 +374,20 @@ DoSomethingUseful(napi_env env, napi_callback_info info) { napi_value create_addon(napi_env env) { napi_value result; - NAPI_CALL(env, napi_create_object(env, &result)); + NODE_API_CALL(env, napi_create_object(env, &result)); napi_value exported_function; - NAPI_CALL(env, napi_create_function(env, - "doSomethingUseful", - NAPI_AUTO_LENGTH, - DoSomethingUseful, - NULL, - &exported_function)); - - NAPI_CALL(env, napi_set_named_property(env, - result, - "doSomethingUseful", - exported_function)); + NODE_API_CALL(env, napi_create_function(env, + "doSomethingUseful", + NAPI_AUTO_LENGTH, + DoSomethingUseful, + NULL, + &exported_function)); + + NODE_API_CALL(env, napi_set_named_property(env, + result, + "doSomethingUseful", + exported_function)); return result; } @@ -2894,7 +2843,9 @@ The JavaScript `string` type is described in #### `node_api_create_external_string_latin1` > Stability: 1 - Experimental @@ -2972,7 +2923,9 @@ The JavaScript `string` type is described in #### `node_api_create_external_string_utf16` > Stability: 1 - Experimental @@ -3122,13 +3075,18 @@ napi_status napi_get_buffer_info(napi_env env, ``` * `[in] env`: The environment that the API is invoked under. -* `[in] value`: `napi_value` representing the `node::Buffer` being queried. -* `[out] data`: The underlying data buffer of the `node::Buffer`. - If length is `0`, this may be `NULL` or any other pointer value. +* `[in] value`: `napi_value` representing the `node::Buffer` or `Uint8Array` + being queried. +* `[out] data`: The underlying data buffer of the `node::Buffer` or + `Uint8Array`. If length is `0`, this may be `NULL` or any other pointer value. * `[out] length`: Length in bytes of the underlying data buffer. Returns `napi_ok` if the API succeeded. +This method returns the identical `data` and `byte_length` as +[`napi_get_typedarray_info`][]. And `napi_get_typedarray_info` accepts a +`node::Buffer` (a Uint8Array) as the value too. + This API is used to retrieve the underlying data buffer of a `node::Buffer` and its length. @@ -3879,12 +3837,14 @@ napi_status napi_is_buffer(napi_env env, napi_value value, bool* result) * `[in] env`: The environment that the API is invoked under. * `[in] value`: The JavaScript value to check. -* `[out] result`: Whether the given `napi_value` represents a `node::Buffer` - object. +* `[out] result`: Whether the given `napi_value` represents a `node::Buffer` or + `Uint8Array` object. Returns `napi_ok` if the API succeeded. -This API checks if the `Object` passed in is a buffer. +This API checks if the `Object` passed in is a buffer or Uint8Array. +[`napi_is_typedarray`][] should be preferred if the caller needs to check if the +value is a Uint8Array. ### `napi_is_date` @@ -5685,7 +5645,7 @@ problems like loss of async context when using the `AsyncLocalStorage` API. In order to retain ABI compatibility with previous versions, passing `NULL` for `async_resource` does not result in an error. However, this is not -recommended as this will result poor results with `async_hooks` +recommended as this will result in undesirable behavior with `async_hooks` [`init` hooks][] and `async_hooks.executionAsyncResource()` as the resource is now required by the underlying `async_hooks` implementation in order to provide the linkage between async callbacks. @@ -6289,6 +6249,13 @@ napi_create_threadsafe_function(napi_env env, [`napi_threadsafe_function_call_js`][] provides more details. * `[out] result`: The asynchronous thread-safe JavaScript function. +**Change History:** + +* Experimental (`NAPI_EXPERIMENTAL` is defined): + + Uncaught exceptions thrown in `call_js_cb` are handled with the + [`'uncaughtException'`][] event, instead of being ignored. + ### `napi_get_threadsafe_function_context` > Stability: 1 - Experimental @@ -799,7 +801,9 @@ socket as reported by the operating system: ### `socket.autoSelectFamilyAttemptedAddresses` * {string\[]} @@ -886,7 +890,9 @@ behavior. Gets the current default value of the `autoSelectFamilyAttemptTimeout` option of [`socket.connect(options)`][]. @@ -1688,7 +1698,9 @@ The initial default value is `250`. ## `net.setDefaultAutoSelectFamilyAttemptTimeout(value)` Sets the default value of the `autoSelectFamilyAttemptTimeout` option of [`socket.connect(options)`][]. diff --git a/doc/api/os.md b/doc/api/os.md index bbc4c30cdb71d4..a02726fb7c2eb1 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -51,7 +51,7 @@ added: v0.5.0 Returns the operating system CPU architecture for which the Node.js binary was compiled. Possible values are `'arm'`, `'arm64'`, `'ia32'`, `'mips'`, -`'mipsel'`, `'ppc'`, `'ppc64'`, `'s390'`, `'s390x'`, and `'x64'`. +`'mipsel'`, `'ppc'`, `'ppc64'`, `'riscv64'`, `'s390'`, `'s390x'`, and `'x64'`. The return value is equivalent to [`process.arch`][]. diff --git a/doc/api/packages.md b/doc/api/packages.md index 09f32e6c160892..a42e1e041a00b6 100644 --- a/doc/api/packages.md +++ b/doc/api/packages.md @@ -251,7 +251,7 @@ both CommonJS and ES modules in a single package please consult Existing packages introducing the [`"exports"`][] field will prevent consumers of the package from using any entry points that are not defined, including the -[`package.json`][] (e.g. `require('your-package/package.json')`. **This will +[`package.json`][] (e.g. `require('your-package/package.json')`). **This will likely be a breaking change.** To make the introduction of [`"exports"`][] non-breaking, ensure that every diff --git a/doc/api/permissions.md b/doc/api/permissions.md index 2c50c4fbabfb55..33e24f49dd5a7e 100644 --- a/doc/api/permissions.md +++ b/doc/api/permissions.md @@ -33,11 +33,18 @@ If you find a potential security vulnerability, please refer to our Node.js contains experimental support for creating policies on loading code. -Policies are a security feature intended to allow guarantees -about what code Node.js is able to load. The use of policies assumes -safe practices for the policy files such as ensuring that policy -files cannot be overwritten by the Node.js application by using -file permissions. +Policies are a security feature intended to ensure the integrity +of the loaded code. + +While it does not function as a provenance mechanism to trace the origin of +code, it serves as a robust defense against the execution of malicious code. +Unlike runtime-based models that may restrict capabilities once the code is +loaded, Node.js policies focus on preventing malicious code from ever being +fully loaded into the application in the first place. + +The use of policies assumes safe practices for the policy +files such as ensuring that policy files cannot be overwritten by the Node.js +application by using file permissions. A best practice would be to ensure that the policy manifest is read-only for the running Node.js application and that the file cannot be changed @@ -202,12 +209,6 @@ the manifest and then immediately used without searching. Any specifier string for which resolution is attempted and that is not listed in the dependencies results in an error according to the policy. -Redirection does not prevent access to APIs through means such as direct access -to `require.cache` or through `module.constructor` which allow access to -loading modules. Policy redirection only affects specifiers to `require()` and -`import`. Other means, such as to prevent undesired access to APIs through -variables, are necessary to lock down that path of loading modules. - A boolean value of `true` for the dependencies map can be specified to allow a module to load any specifier without redirection. This can be useful for local development and may have some valid usage in production, but should be used @@ -224,6 +225,9 @@ can be used to ensure some kinds of dynamic access are explicitly prevented. Unknown values for the resolved module location cause failures but are not guaranteed to be forward compatible. +All the guarantees for policy redirection are specified in the +[Guarantees](#guarantees) section. + ##### Example: Patched dependency Redirected dependencies can provide attenuated or modified functionality as fits @@ -446,6 +450,18 @@ not adopt the origin of the `blob:` URL. Additionally, import maps only work on `import` so it may be desirable to add a `"import"` condition to all dependency mappings. +#### Guarantees + +* The policies guarantee the file integrity when a module is loaded using + `require()`, `import()` or `new Module()`. +* Redirection does not prevent access to APIs through means such as direct + access to `require.cache` which allow access to loaded modules. + Policy redirection only affects specifiers to `require()` and + `import`. +* The approval of the module integrity in policies threat model implies + they are allowed to muck with and even circumvent security features once + loaded so environmental/runtime hardening is expected. + ## Process-based permissions ### Permission Model @@ -532,7 +548,7 @@ Example: * `--allow-fs-write=*` - It will allow all `FileSystemWrite` operations. * `--allow-fs-write=/tmp/` - It will allow `FileSystemWrite` access to the `/tmp/` folder. -* `--allow-fs-read=/tmp/,/home/.gitignore` - It allows `FileSystemRead` access +* `--allow-fs-read=/tmp/ --allow-fs-read=/home/.gitignore` - It allows `FileSystemRead` access to the `/tmp/` folder **and** the `/home/.gitignore` path. Wildcards are supported too: @@ -544,6 +560,8 @@ Wildcards are supported too: There are constraints you need to know before using this system: +* When the permission model is enabled, Node.js may resolve some paths + differently than when it is disabled. * Native modules are restricted by default when using the Permission Model. * OpenSSL engines currently cannot be requested at runtime when the Permission Model is enabled, affecting the built-in crypto, https, and tls modules. diff --git a/doc/api/policy.md b/doc/api/policy.md index cf2ff88b7ffdaf..c3a974a2d81b2b 100644 --- a/doc/api/policy.md +++ b/doc/api/policy.md @@ -6,6 +6,6 @@ > Stability: 1 - Experimental -The former Policies documentation is now at [Permissions documentation][] +The former Policies documentation is now at [Permissions documentation][]. [Permissions documentation]: permissions.md#policies diff --git a/doc/api/process.md b/doc/api/process.md index de56638e70d27e..5718c83e4fbcf4 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -606,7 +606,10 @@ process.on('warning', (warning) => { By default, Node.js will print process warnings to `stderr`. The `--no-warnings` command-line option can be used to suppress the default console output but the -`'warning'` event will still be emitted by the `process` object. +`'warning'` event will still be emitted by the `process` object. Currently, it +is not possible to suppress specific warning types other than deprecation +warnings. To suppress deprecation warnings, check out the [`--no-deprecation`][] +flag. The following example illustrates the warning that is printed to `stderr` when too many listeners have been added to an event: @@ -871,7 +874,7 @@ added: v0.5.0 The operating system CPU architecture for which the Node.js binary was compiled. Possible values are: `'arm'`, `'arm64'`, `'ia32'`, `'mips'`,`'mipsel'`, `'ppc'`, -`'ppc64'`, `'s390'`, `'s390x'`, and `'x64'`. +`'ppc64'`, `'riscv64'`, `'s390'`, `'s390x'`, and `'x64'`. ```mjs import { arch } from 'node:process'; @@ -1666,7 +1669,9 @@ each [`Worker`][] thread has its own copy of `process.env`, based on its parent thread's `process.env`, or whatever was specified as the `env` option to the [`Worker`][] constructor. Changes to `process.env` will not be visible across [`Worker`][] threads, and only the main thread can make changes that -are visible to the operating system or to native add-ons. +are visible to the operating system or to native add-ons. On Windows, a copy of +`process.env` on a [`Worker`][] instance operates in a case-sensitive manner +unlike the main thread. ## `process.execArgv` @@ -3515,6 +3520,19 @@ throw an error. Using this function is mutually exclusive with using the deprecated [`domain`][] built-in module. +## `process.sourceMapsEnabled` + + + +> Stability: 1 - Experimental + +* {boolean} + +The `process.sourceMapsEnabled` property returns whether the +[Source Map v3][Source Map] support for stack traces is enabled. + ## `process.stderr` * {Stream} @@ -3939,6 +3957,7 @@ cases: [`'message'`]: child_process.md#event-message [`'uncaughtException'`]: #event-uncaughtexception [`--experimental-permission`]: cli.md#--experimental-permission +[`--no-deprecation`]: cli.md#--no-deprecation [`--unhandled-rejections`]: cli.md#--unhandled-rejectionsmode [`Buffer`]: buffer.md [`ChildProcess.disconnect()`]: child_process.md#subprocessdisconnect diff --git a/doc/api/readline.md b/doc/api/readline.md index 034a285073ce6f..bf0951fdd1b55c 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -1247,8 +1247,8 @@ const { createInterface } = require('node:readline'); Meta+Y - Cycle among previously deleted lines - Only available when the last keystroke is Ctrl+Y + Cycle among previously deleted texts + Only available when the last keystroke is Ctrl+Y or Meta+Y Ctrl+A diff --git a/doc/api/single-executable-applications.md b/doc/api/single-executable-applications.md index 2db06fdd7239e1..12c9e34a9805f3 100644 --- a/doc/api/single-executable-applications.md +++ b/doc/api/single-executable-applications.md @@ -6,6 +6,13 @@ added: - v19.7.0 - v18.16.0 +changes: + - version: v20.6.0 + pr-url: https://github.com/nodejs/node/pull/46824 + description: Added support for "useSnapshot". + - version: v20.6.0 + pr-url: https://github.com/nodejs/node/pull/48191 + description: Added support for "useCodeCache". --> > Stability: 1 - Experimental: This feature is being designed and will change. @@ -169,7 +176,9 @@ The configuration currently reads the following top-level fields: { "main": "/path/to/bundled/script.js", "output": "/path/to/write/the/generated/blob.blob", - "disableExperimentalSEAWarning": true // Default: false + "disableExperimentalSEAWarning": true, // Default: false + "useSnapshot": false, // Default: false + "useCodeCache": true // Default: false } ``` @@ -177,6 +186,49 @@ If the paths are not absolute, Node.js will use the path relative to the current working directory. The version of the Node.js binary used to produce the blob must be the same as the one to which the blob will be injected. +### Startup snapshot support + +The `useSnapshot` field can be used to enable startup snapshot support. In this +case the `main` script would not be when the final executable is launched. +Instead, it would be run when the single executable application preparation +blob is generated on the building machine. The generated preparation blob would +then include a snapshot capturing the states initialized by the `main` script. +The final executable with the preparation blob injected would deserialize +the snapshot at run time. + +When `useSnapshot` is true, the main script must invoke the +[`v8.startupSnapshot.setDeserializeMainFunction()`][] API to configure code +that needs to be run when the final executable is launched by the users. + +The typical pattern for an application to use snapshot in a single executable +application is: + +1. At build time, on the building machine, the main script is run to + initialize the heap to a state that's ready to take user input. The script + should also configure a main function with + [`v8.startupSnapshot.setDeserializeMainFunction()`][]. This function will be + compiled and serialized into the snapshot, but not invoked at build time. +2. At run time, the main function will be run on top of the deserialized heap + on the user machine to process user input and generate output. + +The general constraints of the startup snapshot scripts also apply to the main +script when it's used to build snapshot for the single executable application, +and the main script can use the [`v8.startupSnapshot` API][] to adapt to +these constraints. See +[documentation about startup snapshot support in Node.js][]. + +### V8 code cache support + +When `useCodeCache` is set to `true` in the configuration, during the generation +of the single executable preparation blob, Node.js will compile the `main` +script to generate the V8 code cache. The generated code cache would be part of +the preparation blob and get injected into the final executable. When the single +executable application is launched, instead of compiling the `main` script from +scratch, Node.js would use the code cache to speed up the compilation, then +execute the script, which would improve the startup performance. + +**Note:** `import()` does not work when `useCodeCache` is `true`. + ## Notes ### `require(id)` in the injected module is not file based @@ -249,6 +301,9 @@ to help us document them. [`process.execPath`]: process.md#processexecpath [`require()`]: modules.md#requireid [`require.main`]: modules.md#accessing-the-main-module +[`v8.startupSnapshot.setDeserializeMainFunction()`]: v8.md#v8startupsnapshotsetdeserializemainfunctioncallback-data +[`v8.startupSnapshot` API]: v8.md#startup-snapshot-api +[documentation about startup snapshot support in Node.js]: cli.md#--build-snapshot [fuse]: https://www.electronjs.org/docs/latest/tutorial/fuses [postject]: https://github.com/nodejs/postject [signtool]: https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool diff --git a/doc/api/stream.md b/doc/api/stream.md index 8dc9a1a7257587..b9c4b4c2ac86f0 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -278,7 +278,7 @@ run().catch(console.error); rs.resume(); // Drain the stream. ``` -The `finished` API provides [callback version][stream-finished]: +The `finished` API also provides a [callback version][stream-finished]. ### Object mode @@ -1907,7 +1907,9 @@ has less then 64 KiB of data because no `highWaterMark` option is provided to ##### `readable[Symbol.asyncDispose]()` > Stability: 1 - Experimental @@ -2012,6 +2014,10 @@ showBoth(); added: - v17.4.0 - v16.14.0 +changes: + - version: v20.7.0 + pr-url: https://github.com/nodejs/node/pull/49249 + description: added `highWaterMark` in options. --> > Stability: 1 - Experimental @@ -2025,6 +2031,8 @@ added: * `options` {Object} * `concurrency` {number} the maximum concurrent invocation of `fn` to call on the stream at once. **Default:** `1`. + * `highWaterMark` {number} how many items to buffer while waiting for user + consumption of the mapped items. **Default:** `concurrency * 2 - 1`. * `signal` {AbortSignal} allows destroying the stream if the signal is aborted. * Returns: {Readable} a stream mapped with the function `fn`. @@ -2059,6 +2067,10 @@ for await (const result of dnsResults) { added: - v17.4.0 - v16.14.0 +changes: + - version: v20.7.0 + pr-url: https://github.com/nodejs/node/pull/49249 + description: added `highWaterMark` in options. --> > Stability: 1 - Experimental @@ -2071,6 +2083,8 @@ added: * `options` {Object} * `concurrency` {number} the maximum concurrent invocation of `fn` to call on the stream at once. **Default:** `1`. + * `highWaterMark` {number} how many items to buffer while waiting for user + consumption of the filtered items. **Default:** `concurrency * 2 - 1`. * `signal` {AbortSignal} allows destroying the stream if the signal is aborted. * Returns: {Readable} a stream filtered with the predicate `fn`. @@ -3064,7 +3078,9 @@ added: v17.0.0 * `objectMode` {boolean} @@ -3354,7 +3372,9 @@ Defaults to `16384` (16 KiB), or `16` for `objectMode`. ### `stream.setDefaultHighWaterMark(objectMode, value)` * `objectMode` {boolean} diff --git a/doc/api/string_decoder.md b/doc/api/string_decoder.md index 70387d2edba696..18960f6acb1736 100644 --- a/doc/api/string_decoder.md +++ b/doc/api/string_decoder.md @@ -21,10 +21,10 @@ const { StringDecoder } = require('node:string_decoder'); const decoder = new StringDecoder('utf8'); const cent = Buffer.from([0xC2, 0xA2]); -console.log(decoder.write(cent)); +console.log(decoder.write(cent)); // Prints: ¢ const euro = Buffer.from([0xE2, 0x82, 0xAC]); -console.log(decoder.write(euro)); +console.log(decoder.write(euro)); // Prints: € ``` When a `Buffer` instance is written to the `StringDecoder` instance, an @@ -41,7 +41,7 @@ const decoder = new StringDecoder('utf8'); decoder.write(Buffer.from([0xE2])); decoder.write(Buffer.from([0x82])); -console.log(decoder.end(Buffer.from([0xAC]))); +console.log(decoder.end(Buffer.from([0xAC]))); // Prints: € ``` ## Class: `StringDecoder` @@ -63,8 +63,7 @@ Creates a new `StringDecoder` instance. added: v0.9.3 --> -* `buffer` {Buffer|TypedArray|DataView} A `Buffer`, or `TypedArray`, or - `DataView` containing the bytes to decode. +* `buffer` {string|Buffer|TypedArray|DataView} The bytes to decode. * Returns: {string} Returns any remaining input stored in the internal buffer as a string. Bytes @@ -86,8 +85,7 @@ changes: character instead of one for each individual byte. --> -* `buffer` {Buffer|TypedArray|DataView} A `Buffer`, or `TypedArray`, or - `DataView` containing the bytes to decode. +* `buffer` {string|Buffer|TypedArray|DataView} The bytes to decode. * Returns: {string} Returns a decoded string, ensuring that any incomplete multibyte characters at diff --git a/doc/api/test.md b/doc/api/test.md index 3e460dd1c09228..a5bb79c5e63d71 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -609,7 +609,9 @@ added: - v19.6.0 - v18.15.0 changes: - - version: v19.9.0 + - version: + - v19.9.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/47238 description: Reporters are now exposed at `node:test/reporters`. --> @@ -630,6 +632,9 @@ The following built-reporters are supported: where each passing test is represented by a `.`, and each failing test is represented by a `X`. +* `junit` + The junit reporter outputs test results in a jUnit XML format + When `stdout` is a [TTY][], the `spec` reporter is used by default. Otherwise, the `tap` reporter is used by default. @@ -641,11 +646,11 @@ to the test runner's output is required, use the events emitted by the The reporters are available via the `node:test/reporters` module: ```mjs -import { tap, spec, dot } from 'node:test/reporters'; +import { tap, spec, dot, junit } from 'node:test/reporters'; ``` ```cjs -const { tap, spec, dot } = require('node:test/reporters'); +const { tap, spec, dot, junit } = require('node:test/reporters'); ``` ### Custom reporters @@ -664,6 +669,15 @@ const customReporter = new Transform({ writableObjectMode: true, transform(event, encoding, callback) { switch (event.type) { + case 'test:dequeue': + callback(null, `test ${event.data.name} dequeued`); + break; + case 'test:enqueue': + callback(null, `test ${event.data.name} enqueued`); + break; + case 'test:watch:drained': + callback(null, 'test watch queue drained'); + break; case 'test:start': callback(null, `test ${event.data.name} started`); break; @@ -677,6 +691,8 @@ const customReporter = new Transform({ callback(null, 'test plan'); break; case 'test:diagnostic': + case 'test:stderr': + case 'test:stdout': callback(null, event.data.message); break; case 'test:coverage': { @@ -698,6 +714,15 @@ const customReporter = new Transform({ writableObjectMode: true, transform(event, encoding, callback) { switch (event.type) { + case 'test:dequeue': + callback(null, `test ${event.data.name} dequeued`); + break; + case 'test:enqueue': + callback(null, `test ${event.data.name} enqueued`); + break; + case 'test:watch:drained': + callback(null, 'test watch queue drained'); + break; case 'test:start': callback(null, `test ${event.data.name} started`); break; @@ -711,6 +736,8 @@ const customReporter = new Transform({ callback(null, 'test plan'); break; case 'test:diagnostic': + case 'test:stderr': + case 'test:stdout': callback(null, event.data.message); break; case 'test:coverage': { @@ -731,6 +758,15 @@ Example of a custom reporter using a generator function: export default async function * customReporter(source) { for await (const event of source) { switch (event.type) { + case 'test:dequeue': + yield `test ${event.data.name} dequeued`; + break; + case 'test:enqueue': + yield `test ${event.data.name} enqueued`; + break; + case 'test:watch:drained': + yield 'test watch queue drained'; + break; case 'test:start': yield `test ${event.data.name} started\n`; break; @@ -744,6 +780,8 @@ export default async function * customReporter(source) { yield 'test plan'; break; case 'test:diagnostic': + case 'test:stderr': + case 'test:stdout': yield `${event.data.message}\n`; break; case 'test:coverage': { @@ -760,6 +798,15 @@ export default async function * customReporter(source) { module.exports = async function * customReporter(source) { for await (const event of source) { switch (event.type) { + case 'test:dequeue': + yield `test ${event.data.name} dequeued`; + break; + case 'test:enqueue': + yield `test ${event.data.name} enqueued`; + break; + case 'test:watch:drained': + yield 'test watch queue drained'; + break; case 'test:start': yield `test ${event.data.name} started\n`; break; @@ -773,6 +820,8 @@ module.exports = async function * customReporter(source) { yield 'test plan\n'; break; case 'test:diagnostic': + case 'test:stderr': + case 'test:stdout': yield `${event.data.message}\n`; break; case 'test:coverage': { @@ -815,7 +864,9 @@ added: - v18.9.0 - v16.19.0 changes: - - version: v20.1.0 + - version: + - v20.1.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/47628 description: Add a testNamePatterns option. --> @@ -836,6 +887,8 @@ changes: number. If a nullish value is provided, each process gets its own port, incremented from the primary's `process.debugPort`. **Default:** `undefined`. + * `only`: {boolean} If truthy, the test context will only run tests that + have the `only` option set * `setup` {Function} A function that accepts the `TestsStream` instance and can be used to setup listeners before any tests are run. **Default:** `undefined`. @@ -860,7 +913,9 @@ changes: ```mjs import { tap } from 'node:test/reporters'; +import { run } from 'node:test'; import process from 'node:process'; +import path from 'node:path'; run({ files: [path.resolve('./tests/test.js')] }) .compose(tap) @@ -869,6 +924,8 @@ run({ files: [path.resolve('./tests/test.js')] }) ```cjs const { tap } = require('node:test/reporters'); +const { run } = require('node:test'); +const path = require('node:path'); run({ files: [path.resolve('./tests/test.js')] }) .compose(tap) @@ -882,7 +939,9 @@ added: - v18.0.0 - v16.17.0 changes: - - version: v20.2.0 + - version: + - v20.2.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/47909 description: Added the `skip`, `todo`, and `only` shorthands. - version: @@ -1529,9 +1588,10 @@ added: Enables timer mocking for the specified timers. * `timers` {Array} An optional array containing the timers to mock. - The currently supported timer values are `'setInterval'` and `'setTimeout'`. - If no array is provided, all timers (`'setInterval'`, `'clearInterval'`, `'setTimeout'`, - and `'clearTimeout'`) will be mocked by default. + The currently supported timer values are `'setInterval'`, `'setTimeout'`, + and `'setImmediate'`. If no value is provided, all timers (`'setInterval'`, + `'clearInterval'`, `'setTimeout'`, `'clearTimeout'`, `'setImmediate'`, + and `'clearImmediate'`) will be mocked by default. **Note:** When you enable mocking for a specific timer, its associated clear function will also be implicitly mocked. @@ -1543,7 +1603,7 @@ import { mock } from 'node:test'; mock.timers.enable(['setInterval']); ``` -```js +```cjs const { mock } = require('node:test'); mock.timers.enable(['setInterval']); ``` @@ -1580,7 +1640,7 @@ import { mock } from 'node:test'; mock.timers.reset(); ``` -```js +```cjs const { mock } = require('node:test'); mock.timers.reset(); ``` @@ -1629,7 +1689,7 @@ test('mocks setTimeout to be executed synchronously without having to actually w }); ``` -```js +```cjs const assert = require('node:assert'); const { test } = require('node:test'); @@ -1668,7 +1728,7 @@ test('mocks setTimeout to be executed synchronously without having to actually w }); ``` -```js +```cjs const assert = require('node:assert'); const { test } = require('node:test'); @@ -1712,7 +1772,7 @@ test('mocks setTimeout to be executed synchronously without having to actually w }); ``` -```js +```cjs const assert = require('node:assert'); const { test } = require('node:test'); @@ -1769,7 +1829,7 @@ test('mocks setTimeout to be executed synchronously without having to actually w }); ``` -```js +```cjs const assert = require('node:assert'); const { test } = require('node:test'); const nodeTimers = require('node:timers'); @@ -1831,7 +1891,7 @@ test('should tick five times testing a real use case', async (context) => { }); ``` -```js +```cjs const assert = require('node:assert'); const { test } = require('node:test'); const nodeTimersPromises = require('node:timers/promises'); @@ -1897,7 +1957,7 @@ test('runAll functions following the given order', (context) => { }); ``` -```js +```cjs const assert = require('node:assert'); const { test } = require('node:test'); @@ -1930,6 +1990,13 @@ clocks or actual timers outside of the mocking environment. added: - v18.9.0 - v16.19.0 +changes: + - version: + - v20.0.0 + - v19.9.0 + - v18.17.0 + pr-url: https://github.com/nodejs/node/pull/47094 + description: added type to test:pass and test:fail events for when the test is a suite. --> * Extends {ReadableStream} @@ -1954,8 +2021,18 @@ object, streaming a series of events representing the execution of the tests. * `coveredLinePercent` {number} The percentage of lines covered. * `coveredBranchPercent` {number} The percentage of branches covered. * `coveredFunctionPercent` {number} The percentage of functions covered. - * `uncoveredLineNumbers` {Array} An array of integers representing line - numbers that are uncovered. + * `functions` {Array} An array of functions representing function + coverage. + * `name` {string} The name of the function. + * `line` {number} The line number where the function is defined. + * `count` {number} The number of times the function was called. + * `branches` {Array} An array of branches representing branch coverage. + * `line` {number} The line number where the branch is defined. + * `count` {number} The number of times the branch was taken. + * `lines` {Array} An array of lines representing line + numbers and the number of times they were covered. + * `line` {number} The line number. + * `count` {number} The number of times the line was covered. * `totals` {Object} An object containing a summary of coverage for all files. * `totalLineCount` {number} The total number of lines. @@ -1977,8 +2054,12 @@ Emitted when code coverage is enabled and all tests have completed. ### Event: `'test:dequeue'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. @@ -1987,8 +2068,12 @@ Emitted when a test is dequeued, right before it is executed. ### Event: `'test:diagnostic'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `message` {string} The diagnostic message. * `nesting` {number} The nesting level of the test. @@ -1997,8 +2082,12 @@ Emitted when [`context.diagnostic`][] is called. ### Event: `'test:enqueue'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. @@ -2007,11 +2096,18 @@ Emitted when a test is enqueued for execution. ### Event: `'test:fail'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `details` {Object} Additional execution metadata. - * `duration` {number} The duration of the test in milliseconds. - * `error` {Error} The error thrown by the test. + * `duration_ms` {number} The duration of the test in milliseconds. + * `error` {Error} An error wrapping the error thrown by the test. + * `cause` {Error} The actual error thrown by the test. + * `type` {string|undefined} The type of the test, used to denote whether + this is a suite. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. * `testNumber` {number} The ordinal number of the test. @@ -2023,10 +2119,16 @@ Emitted when a test fails. ### Event: `'test:pass'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `details` {Object} Additional execution metadata. - * `duration` {number} The duration of the test in milliseconds. + * `duration_ms` {number} The duration of the test in milliseconds. + * `type` {string|undefined} The type of the test, used to denote whether + this is a suite. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. * `testNumber` {number} The ordinal number of the test. @@ -2038,8 +2140,12 @@ Emitted when a test passes. ### Event: `'test:plan'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `nesting` {number} The nesting level of the test. * `count` {number} The number of subtests that have ran. @@ -2048,8 +2154,12 @@ Emitted when all subtests have completed for a given test. ### Event: `'test:start'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. @@ -2060,7 +2170,11 @@ defined. ### Event: `'test:stderr'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string} The path of the test file. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `message` {string} The message written to `stderr`. Emitted when a running test writes to `stderr`. @@ -2069,7 +2183,11 @@ This event is only emitted if `--test` flag is passed. ### Event: `'test:stdout'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string} The path of the test file. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `message` {string} The message written to `stdout`. Emitted when a running test writes to `stdout`. @@ -2086,7 +2204,9 @@ added: - v18.0.0 - v16.17.0 changes: - - version: v20.1.0 + - version: + - v20.1.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/47586 description: The `before` function was added to TestContext. --> @@ -2098,7 +2218,9 @@ exposed as part of the API. ### `context.before([fn][, options])` * `fn` {Function|AsyncFunction} The hook function. The first argument diff --git a/doc/api/timers.md b/doc/api/timers.md index 768f59fd6f1d2b..3789e9efd00906 100644 --- a/doc/api/timers.md +++ b/doc/api/timers.md @@ -66,7 +66,9 @@ invoked. Calling `immediate.unref()` multiple times will have no effect. ### `immediate[Symbol.dispose]()` > Stability: 1 - Experimental @@ -170,7 +172,9 @@ thread. This allows enhanced compatibility with browser ### `timeout[Symbol.dispose]()` > Stability: 1 - Experimental diff --git a/doc/api/url.md b/doc/api/url.md index d0f325e5bde3a4..6412988d6103b6 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -129,9 +129,11 @@ return `true`. #### `new URL(input[, base])` - @@ -669,7 +671,9 @@ ID that isn't registered will silently fail. #### `URL.canParse(input[, base])` * `input` {string} The absolute or relative input URL to parse. If `input` @@ -863,7 +867,9 @@ Append a new name-value pair to the query string. @@ -933,7 +939,9 @@ no such pairs, an empty array is returned. @@ -1062,7 +1070,9 @@ added: - v7.4.0 - v6.13.0 changes: - - version: v20.0.0 + - version: + - v20.0.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/47339 description: ICU requirement is removed. --> @@ -1104,7 +1114,9 @@ added: - v7.4.0 - v6.13.0 changes: - - version: v20.0.0 + - version: + - v20.0.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/47339 description: ICU requirement is removed. --> @@ -1282,7 +1294,9 @@ added: - v15.7.0 - v14.18.0 changes: - - version: v19.9.0 + - version: + - v19.9.0 + - v18.17.0 pr-url: https://github.com/nodejs/node/pull/46989 description: The returned object will also contain all the own enumerable properties of the `url` argument. @@ -1730,18 +1744,19 @@ The WHATWG algorithm defines four "percent-encode sets" that describe ranges of characters that must be percent-encoded: * The _C0 control percent-encode set_ includes code points in range U+0000 to - U+001F (inclusive) and all code points greater than U+007E. + U+001F (inclusive) and all code points greater than U+007E (\~). * The _fragment percent-encode set_ includes the _C0 control percent-encode set_ - and code points U+0020, U+0022, U+003C, U+003E, and U+0060. + and code points U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), + and U+0060 (\`). * The _path percent-encode set_ includes the _C0 control percent-encode set_ - and code points U+0020, U+0022, U+0023, U+003C, U+003E, U+003F, U+0060, - U+007B, and U+007D. + and code points U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), U+003E (>), + U+003F (?), U+0060 (\`), U+007B ({), and U+007D (}). * The _userinfo encode set_ includes the _path percent-encode set_ and code - points U+002F, U+003A, U+003B, U+003D, U+0040, U+005B, U+005C, U+005D, - U+005E, and U+007C. + points U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), + U+005B (\[) to U+005E(^), and U+007C (|). The _userinfo percent-encode set_ is used exclusively for username and passwords encoded within the URL. The _path percent-encode set_ is used for the diff --git a/doc/api/util.md b/doc/api/util.md index 07d574694cc88a..50048beac89b80 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -777,8 +777,14 @@ const million = 1_000_000; const bigNumber = 123_456_789n; const bigDecimal = 1_234.123_45; -console.log(thousand, million, bigNumber, bigDecimal); -// 1_000 1_000_000 123_456_789n 1_234.123_45 +console.log(inspect(thousand, { numericSeparator: true })); +// 1_000 +console.log(inspect(million, { numericSeparator: true })); +// 1_000_000 +console.log(inspect(bigNumber, { numericSeparator: true })); +// 123_456_789n +console.log(inspect(bigDecimal, { numericSeparator: true })); +// 1_234.123_45 ``` `util.inspect()` is a synchronous method intended for debugging. Its maximum @@ -1328,7 +1334,7 @@ const { params } = new MIMEType('text/plain;foo=0;bar=1'); params.set('foo', 'def'); params.set('baz', 'xyz'); console.log(params.toString()); -// Prints: foo=def&bar=1&baz=xyz +// Prints: foo=def;bar=1;baz=xyz ``` ```cjs @@ -1338,7 +1344,7 @@ const { params } = new MIMEType('text/plain;foo=0;bar=1'); params.set('foo', 'def'); params.set('baz', 'xyz'); console.log(params.toString()); -// Prints: foo=def&bar=1&baz=xyz +// Prints: foo=def;bar=1;baz=xyz ``` ### `mimeParams.values()` @@ -1591,6 +1597,11 @@ $ node negate.js --no-logfile --logfile=test.log --color --no-color * `original` {Function} @@ -1624,6 +1635,8 @@ async function callStat() { const stats = await stat('.'); console.log(`This directory is owned by ${stats.uid}`); } + +callStat(); ``` If there is an `original[util.promisify.custom]` property present, `promisify` diff --git a/doc/api/webcrypto.md b/doc/api/webcrypto.md index fb33d552e4ebac..2cb6981b8794c9 100644 --- a/doc/api/webcrypto.md +++ b/doc/api/webcrypto.md @@ -2,7 +2,9 @@ -> Stability: 1 - Experimental. +> Stability: 2 - Stable An implementation of the [WHATWG Streams Standard][]. @@ -248,6 +252,7 @@ const transformedStream = stream.pipeThrough(transform); for await (const chunk of transformedStream) console.log(chunk); + // Prints: A ``` ```cjs @@ -273,6 +278,7 @@ const transformedStream = stream.pipeThrough(transform); (async () => { for await (const chunk of transformedStream) console.log(chunk); + // Prints: A })(); ``` @@ -387,6 +393,49 @@ port1.onmessage = ({ data }) => { port2.postMessage(stream, [stream]); ``` +### `ReadableStream.from(iterable)` + + + +* `iterable` {Iterable} Object implementing the `Symbol.asyncIterator` or + `Symbol.iterator` iterable protocol. + +A utility method that creates a new {ReadableStream} from an iterable. + +```mjs +import { ReadableStream } from 'node:stream/web'; + +async function* asyncIterableGenerator() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +const stream = ReadableStream.from(asyncIterableGenerator()); + +for await (const chunk of stream) + console.log(chunk); // Prints: 'a', 'b', 'c' +``` + +```cjs +const { ReadableStream } = require('node:stream/web'); + +async function* asyncIterableGenerator() { + yield 'a'; + yield 'b'; + yield 'c'; +} + +(async () => { + const stream = ReadableStream.from(asyncIterableGenerator()); + + for await (const chunk of stream) + console.log(chunk); // Prints: 'a', 'b', 'c' +})(); +``` + ### Class: `ReadableStreamDefaultReader` -* type: A promise that is fulfilled with `undefined` when the - writer is ready to be used. +* Type: {Promise} Fulfilled with `undefined` when the writer is ready + to be used. #### `writableStreamDefaultWriter.releaseLock()` @@ -1174,13 +1223,13 @@ changes: description: This class is now exposed on the global object. --> -#### `new ByteLengthQueuingStrategy(options)` +#### `new ByteLengthQueuingStrategy(init)` -* `options` {Object} +* `init` {Object} * `highWaterMark` {number} #### `byteLengthQueuingStrategy.highWaterMark` @@ -1211,13 +1260,13 @@ changes: description: This class is now exposed on the global object. --> -#### `new CountQueuingStrategy(options)` +#### `new CountQueuingStrategy(init)` -* `options` {Object} +* `init` {Object} * `highWaterMark` {number} #### `countQueuingStrategy.highWaterMark` @@ -1477,6 +1526,7 @@ const dataArray = encoder.encode('hello world from consumers!'); const readable = Readable.from(dataArray); const data = await arrayBuffer(readable); console.log(`from readable: ${data.byteLength}`); +// Prints: from readable: 76 ``` ```cjs @@ -1489,6 +1539,7 @@ const dataArray = encoder.encode('hello world from consumers!'); const readable = Readable.from(dataArray); arrayBuffer(readable).then((data) => { console.log(`from readable: ${data.byteLength}`); + // Prints: from readable: 76 }); ``` @@ -1510,6 +1561,7 @@ const dataBlob = new Blob(['hello world from consumers!']); const readable = dataBlob.stream(); const data = await blob(readable); console.log(`from readable: ${data.size}`); +// Prints: from readable: 27 ``` ```cjs @@ -1520,6 +1572,7 @@ const dataBlob = new Blob(['hello world from consumers!']); const readable = dataBlob.stream(); blob(readable).then((data) => { console.log(`from readable: ${data.size}`); + // Prints: from readable: 27 }); ``` @@ -1543,6 +1596,7 @@ const dataBuffer = Buffer.from('hello world from consumers!'); const readable = Readable.from(dataBuffer); const data = await buffer(readable); console.log(`from readable: ${data.length}`); +// Prints: from readable: 27 ``` ```cjs @@ -1555,6 +1609,7 @@ const dataBuffer = Buffer.from('hello world from consumers!'); const readable = Readable.from(dataBuffer); buffer(readable).then((data) => { console.log(`from readable: ${data.length}`); + // Prints: from readable: 27 }); ``` @@ -1584,6 +1639,7 @@ const items = Array.from( const readable = Readable.from(JSON.stringify(items)); const data = await json(readable); console.log(`from readable: ${data.length}`); +// Prints: from readable: 100 ``` ```cjs @@ -1602,6 +1658,7 @@ const items = Array.from( const readable = Readable.from(JSON.stringify(items)); json(readable).then((data) => { console.log(`from readable: ${data.length}`); + // Prints: from readable: 100 }); ``` @@ -1622,6 +1679,7 @@ import { Readable } from 'node:stream'; const readable = Readable.from('Hello world from consumers!'); const data = await text(readable); console.log(`from readable: ${data.length}`); +// Prints: from readable: 27 ``` ```cjs @@ -1631,6 +1689,7 @@ const { Readable } = require('node:stream'); const readable = Readable.from('Hello world from consumers!'); text(readable).then((data) => { console.log(`from readable: ${data.length}`); + // Prints: from readable: 27 }); ``` diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index 09b695eb96ea29..28afb77d8036a1 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -886,7 +886,8 @@ Notable differences inside a Worker environment are: unless otherwise specified. Changes to one copy are not visible in other threads, and are not visible to native add-ons (unless [`worker.SHARE_ENV`][] is passed as the `env` option to the - [`Worker`][] constructor). + [`Worker`][] constructor). On Windows, unlike the main thread, a copy of the + environment variables operates in a case-sensitive manner. * [`process.title`][] cannot be modified. * Signals are not delivered through [`process.on('...')`][Signals events]. * Execution may stop at any point as a result of [`worker.terminate()`][] diff --git a/doc/api_assets/api.js b/doc/api_assets/api.js index c1151ae493e8da..c7568206e29f19 100644 --- a/doc/api_assets/api.js +++ b/doc/api_assets/api.js @@ -136,18 +136,41 @@ updateHashes(); } + function setupFlavorToggles() { + const kFlavorPreference = 'customFlavor'; + const flavorSetting = localStorage.getItem(kFlavorPreference) === 'true'; + const flavorToggles = document.querySelectorAll('.js-flavor-toggle'); + + flavorToggles.forEach((toggleElement) => { + toggleElement.checked = flavorSetting; + toggleElement.addEventListener('change', (e) => { + const checked = e.target.checked; + + if (checked) { + localStorage.setItem(kFlavorPreference, true); + } else { + localStorage.removeItem(kFlavorPreference); + } + + flavorToggles.forEach((el) => { + el.checked = checked; + }); + }); + }); + } + function setupCopyButton() { const buttons = document.querySelectorAll('.copy-button'); buttons.forEach((button) => { button.addEventListener('click', (el) => { const parentNode = el.target.parentNode; - const flavorSelector = parentNode.querySelector('.js-flavor-selector'); + const flavorToggle = parentNode.querySelector('.js-flavor-toggle'); let code = ''; - if (flavorSelector) { - if (flavorSelector.checked) { + if (flavorToggle) { + if (flavorToggle.checked) { code = parentNode.querySelector('.mjs').textContent; } else { code = parentNode.querySelector('.cjs').textContent; @@ -182,6 +205,8 @@ // Make link to other versions of the doc open to the same hash target (if it exists). setupAltDocsLink(); + setupFlavorToggles(); + setupCopyButton(); } diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index 15e7b73f770eab..d5c708be0bf3ef 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -950,7 +950,7 @@ kbd { display: block; } -.js-flavor-selector { +.js-flavor-toggle { -webkit-appearance: none; appearance: none; float: right; @@ -963,14 +963,14 @@ kbd { cursor: pointer; margin: 0; } -.js-flavor-selector:checked { +.js-flavor-toggle:checked { background-image: url(./js-flavor-esm.svg); } -.js-flavor-selector:not(:checked) ~ .mjs, -.js-flavor-selector:checked ~ .cjs { +.js-flavor-toggle:not(:checked) ~ .mjs, +.js-flavor-toggle:checked ~ .cjs { display: none; } -.dark-mode .js-flavor-selector { +.dark-mode .js-flavor-toggle { filter: invert(1); } @@ -1001,7 +1001,7 @@ kbd { } @supports (aspect-ratio: 1 / 1) { - .js-flavor-selector { + .js-flavor-toggle { height: 1.5em; width: auto; aspect-ratio: 2719 / 384; @@ -1058,24 +1058,24 @@ kbd { #apicontent { overflow: hidden; } - .js-flavor-selector { + .js-flavor-toggle { display: none; } - .js-flavor-selector + * { + .js-flavor-toggle + * { margin-bottom: 2rem; padding-bottom: 2rem; border-bottom: 1px solid var(--color-text-primary); } - .js-flavor-selector ~ * { + .js-flavor-toggle ~ * { display: block !important; background-position: top right; background-size: 142px 20px; background-repeat: no-repeat; } - .js-flavor-selector ~ .cjs { + .js-flavor-toggle ~ .cjs { background-image: url(./js-flavor-cjs.svg); } - .js-flavor-selector ~ .mjs { + .js-flavor-toggle ~ .mjs { background-image: url(./js-flavor-esm.svg); } } diff --git a/doc/changelogs/CHANGELOG_V16.md b/doc/changelogs/CHANGELOG_V16.md index 44d4d93d9385cd..4c081b0a77c9d0 100644 --- a/doc/changelogs/CHANGELOG_V16.md +++ b/doc/changelogs/CHANGELOG_V16.md @@ -9,6 +9,7 @@ +16.20.2
16.20.1
16.20.0
16.19.1
@@ -73,6 +74,34 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2023-08-09, Version 16.20.2 'Gallium' (LTS), @RafaelGSS + +This is a security release. + +### Notable Changes + +The following CVEs are fixed in this release: + +* [CVE-2023-32002](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32002): Policies can be bypassed via Module.\_load (High) +* [CVE-2023-32006](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32006): Policies can be bypassed by module.constructor.createRequire (Medium) +* [CVE-2023-32559](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32559): Policies can be bypassed via process.binding (Medium) +* OpenSSL Security Releases + * [OpenSSL security advisory 14th July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000264.html). + * [OpenSSL security advisory 19th July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000265.html). + * [OpenSSL security advisory 31st July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000267.html) + +More detailed information on each of the vulnerabilities can be found in [August 2023 Security Releases](https://nodejs.org/en/blog/vulnerability/august-2023-security-releases/) blog post. + +### Commits + +* \[[`40c3958a5a`](https://github.com/nodejs/node/commit/40c3958a5a)] - **deps**: update archs files for OpenSSL-1.1.1v (RafaelGSS) [#49043](https://github.com/nodejs/node/pull/49043) +* \[[`a9ac9da89a`](https://github.com/nodejs/node/commit/a9ac9da89a)] - **deps**: fix openssl crypto clean (RafaelGSS) [#49043](https://github.com/nodejs/node/pull/49043) +* \[[`362d4c7494`](https://github.com/nodejs/node/commit/362d4c7494)] - **deps**: upgrade openssl sources to OpenSSL\_1\_1\_1v (RafaelGSS) [#49043](https://github.com/nodejs/node/pull/49043) +* \[[`d8ccfe9ad4`](https://github.com/nodejs/node/commit/d8ccfe9ad4)] - **policy**: handle Module.constructor and main.extensions bypass (RafaelGSS) [nodejs-private/node-private#445](https://github.com/nodejs-private/node-private/pull/445) +* \[[`242aaa0caa`](https://github.com/nodejs/node/commit/242aaa0caa)] - **policy**: disable process.binding() when enabled (Tobias Nießen) [nodejs-private/node-private#459](https://github.com/nodejs-private/node-private/pull/459) + ## 2023-06-20, Version 16.20.1 'Gallium' (LTS), @RafaelGSS diff --git a/doc/changelogs/CHANGELOG_V18.md b/doc/changelogs/CHANGELOG_V18.md index 1de2ebcfe36e0c..9640d12c3967e0 100644 --- a/doc/changelogs/CHANGELOG_V18.md +++ b/doc/changelogs/CHANGELOG_V18.md @@ -9,6 +9,9 @@ +18.18.0
+18.17.1
+18.17.0
18.16.1
18.16.0
18.15.0
@@ -59,6 +62,779 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2023-09-18, Version 18.18.0 'Hydrogen' (LTS), @ruyadorno + +### Notable Changes + +* \[[`7dc731d4bf`](https://github.com/nodejs/node/commit/7dc731d4bf)] - **build**: sync libuv header change (Jiawen Geng) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`490fc004b0`](https://github.com/nodejs/node/commit/490fc004b0)] - **crypto**: update root certificates to NSS 3.93 (Node.js GitHub Bot) [#49341](https://github.com/nodejs/node/pull/49341) +* \[[`dd8cd97d4d`](https://github.com/nodejs/node/commit/dd8cd97d4d)] - **crypto**: update root certificates to NSS 3.90 (Node.js GitHub Bot) [#48416](https://github.com/nodejs/node/pull/48416) +* \[[`ea23870bec`](https://github.com/nodejs/node/commit/ea23870bec)] - **deps**: add missing thread-common.c in uv.gyp (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`88855e0b1b`](https://github.com/nodejs/node/commit/88855e0b1b)] - **deps**: upgrade to libuv 1.46.0 (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`fb2b80fca0`](https://github.com/nodejs/node/commit/fb2b80fca0)] - **deps**: upgrade to libuv 1.45.0 (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`249879e46c`](https://github.com/nodejs/node/commit/249879e46c)] - **doc**: add atlowChemi to collaborators (atlowChemi) [#48757](https://github.com/nodejs/node/pull/48757) +* \[[`e8dc7bde6a`](https://github.com/nodejs/node/commit/e8dc7bde6a)] - **doc**: add vmoroz to collaborators (Vladimir Morozov) [#48527](https://github.com/nodejs/node/pull/48527) +* \[[`a30f2fbcc1`](https://github.com/nodejs/node/commit/a30f2fbcc1)] - **doc**: add kvakil to collaborators (Keyhan Vakil) [#48449](https://github.com/nodejs/node/pull/48449) +* \[[`c39b7c240e`](https://github.com/nodejs/node/commit/c39b7c240e)] - **(SEMVER-MINOR)** **esm**: add `--import` flag (Moshe Atlow) [#43942](https://github.com/nodejs/node/pull/43942) +* \[[`a68a67f54d`](https://github.com/nodejs/node/commit/a68a67f54d)] - **(SEMVER-MINOR)** **events**: allow safely adding listener to abortSignal (Chemi Atlow) [#48596](https://github.com/nodejs/node/pull/48596) +* \[[`3a8586bee2`](https://github.com/nodejs/node/commit/3a8586bee2)] - **fs, stream**: initial `Symbol.dispose` and `Symbol.asyncDispose` support (Moshe Atlow) [#48518](https://github.com/nodejs/node/pull/48518) +* \[[`863bdb785d`](https://github.com/nodejs/node/commit/863bdb785d)] - **net**: add autoSelectFamily global getter and setter (Paolo Insogna) [#45777](https://github.com/nodejs/node/pull/45777) +* \[[`c59ae86ba0`](https://github.com/nodejs/node/commit/c59ae86ba0)] - **(SEMVER-MINOR)** **url**: add value argument to has and delete methods (Sankalp Shubham) [#47885](https://github.com/nodejs/node/pull/47885) + +### Commits + +* \[[`d1f43317ea`](https://github.com/nodejs/node/commit/d1f43317ea)] - **benchmark**: add bar.R (Rafael Gonzaga) [#47729](https://github.com/nodejs/node/pull/47729) +* \[[`4f74be3c92`](https://github.com/nodejs/node/commit/4f74be3c92)] - **benchmark**: refactor crypto oneshot (Filip Skokan) [#48267](https://github.com/nodejs/node/pull/48267) +* \[[`fe9da9df0f`](https://github.com/nodejs/node/commit/fe9da9df0f)] - **benchmark**: add crypto.create\*Key (Filip Skokan) [#48284](https://github.com/nodejs/node/pull/48284) +* \[[`9cb18b3e9d`](https://github.com/nodejs/node/commit/9cb18b3e9d)] - **build**: do not pass target toolchain flags to host toolchain (Ivan Trubach) [#48597](https://github.com/nodejs/node/pull/48597) +* \[[`7dc731d4bf`](https://github.com/nodejs/node/commit/7dc731d4bf)] - **build**: sync libuv header change (Jiawen Geng) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`211a4f88a9`](https://github.com/nodejs/node/commit/211a4f88a9)] - **build**: update action to close stale PRs (Michael Dawson) [#48196](https://github.com/nodejs/node/pull/48196) +* \[[`cc33a1864b`](https://github.com/nodejs/node/commit/cc33a1864b)] - **child\_process**: harden against prototype pollution (Livia Medeiros) [#48726](https://github.com/nodejs/node/pull/48726) +* \[[`b5df084e1e`](https://github.com/nodejs/node/commit/b5df084e1e)] - **child\_process**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`611db8df1a`](https://github.com/nodejs/node/commit/611db8df1a)] - **child\_process**: support `Symbol.dispose` (Moshe Atlow) [#48551](https://github.com/nodejs/node/pull/48551) +* \[[`490fc004b0`](https://github.com/nodejs/node/commit/490fc004b0)] - **crypto**: update root certificates to NSS 3.93 (Node.js GitHub Bot) [#49341](https://github.com/nodejs/node/pull/49341) +* \[[`dd8cd97d4d`](https://github.com/nodejs/node/commit/dd8cd97d4d)] - **crypto**: update root certificates to NSS 3.90 (Node.js GitHub Bot) [#48416](https://github.com/nodejs/node/pull/48416) +* \[[`b2bc839d4c`](https://github.com/nodejs/node/commit/b2bc839d4c)] - **crypto**: remove OPENSSL\_FIPS guard for OpenSSL 3 (Richard Lau) [#48392](https://github.com/nodejs/node/pull/48392) +* \[[`c8da8c80b9`](https://github.com/nodejs/node/commit/c8da8c80b9)] - **deps**: update nghttp2 to 1.55.0 (Node.js GitHub Bot) [#48746](https://github.com/nodejs/node/pull/48746) +* \[[`7e04242dcb`](https://github.com/nodejs/node/commit/7e04242dcb)] - **deps**: update minimatch to 9.0.3 (Node.js GitHub Bot) [#48704](https://github.com/nodejs/node/pull/48704) +* \[[`ea23870bec`](https://github.com/nodejs/node/commit/ea23870bec)] - **deps**: add missing thread-common.c in uv.gyp (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`88855e0b1b`](https://github.com/nodejs/node/commit/88855e0b1b)] - **deps**: upgrade to libuv 1.46.0 (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`fb2b80fca0`](https://github.com/nodejs/node/commit/fb2b80fca0)] - **deps**: upgrade to libuv 1.45.0 (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`59fca4e09a`](https://github.com/nodejs/node/commit/59fca4e09a)] - **deps**: update acorn to 8.10.0 (Node.js GitHub Bot) [#48713](https://github.com/nodejs/node/pull/48713) +* \[[`bcb255d5a8`](https://github.com/nodejs/node/commit/bcb255d5a8)] - **deps**: V8: cherry-pick cb00db4dba6c (Keyhan Vakil) [#48671](https://github.com/nodejs/node/pull/48671) +* \[[`65a6c90fc6`](https://github.com/nodejs/node/commit/65a6c90fc6)] - **deps**: update acorn to 8.9.0 (Node.js GitHub Bot) [#48484](https://github.com/nodejs/node/pull/48484) +* \[[`6b6d5d91e9`](https://github.com/nodejs/node/commit/6b6d5d91e9)] - **deps**: update zlib to 1.2.13.1-motley-f81f385 (Node.js GitHub Bot) [#48541](https://github.com/nodejs/node/pull/48541) +* \[[`56249b0770`](https://github.com/nodejs/node/commit/56249b0770)] - **deps**: update googletest to ec4fed9 (Node.js GitHub Bot) [#48538](https://github.com/nodejs/node/pull/48538) +* \[[`8914a5204a`](https://github.com/nodejs/node/commit/8914a5204a)] - **deps**: update minimatch to 9.0.2 (Node.js GitHub Bot) [#48542](https://github.com/nodejs/node/pull/48542) +* \[[`1b960d9988`](https://github.com/nodejs/node/commit/1b960d9988)] - **deps**: update icu to 73.2 (Node.js GitHub Bot) [#48502](https://github.com/nodejs/node/pull/48502) +* \[[`f0e2e3c549`](https://github.com/nodejs/node/commit/f0e2e3c549)] - **deps**: update zlib to 1.2.13.1-motley-3ca9f16 (Node.js GitHub Bot) [#48413](https://github.com/nodejs/node/pull/48413) +* \[[`9cf8fe6b93`](https://github.com/nodejs/node/commit/9cf8fe6b93)] - **deps**: upgrade npm to 9.8.1 (npm team) [#48838](https://github.com/nodejs/node/pull/48838) +* \[[`d9ff473ff3`](https://github.com/nodejs/node/commit/d9ff473ff3)] - **deps**: upgrade npm to 9.8.0 (npm team) [#48665](https://github.com/nodejs/node/pull/48665) +* \[[`4a6177daad`](https://github.com/nodejs/node/commit/4a6177daad)] - **deps**: upgrade npm to 9.7.2 (npm team) [#48514](https://github.com/nodejs/node/pull/48514) +* \[[`104b58feb1`](https://github.com/nodejs/node/commit/104b58feb1)] - **deps**: update ada to 2.6.0 (Node.js GitHub Bot) [#48896](https://github.com/nodejs/node/pull/48896) +* \[[`7f7a125d78`](https://github.com/nodejs/node/commit/7f7a125d78)] - **deps**: update corepack to 0.19.0 (Node.js GitHub Bot) [#48540](https://github.com/nodejs/node/pull/48540) +* \[[`5e1eb451d1`](https://github.com/nodejs/node/commit/5e1eb451d1)] - **deps**: update corepack to 0.18.1 (Node.js GitHub Bot) [#48483](https://github.com/nodejs/node/pull/48483) +* \[[`3be53358bc`](https://github.com/nodejs/node/commit/3be53358bc)] - **deps**: add loong64 config into openssl gypi (Shi Pujin) [#48043](https://github.com/nodejs/node/pull/48043) +* \[[`555982c59e`](https://github.com/nodejs/node/commit/555982c59e)] - **deps**: upgrade npm to 9.7.1 (npm team) [#48378](https://github.com/nodejs/node/pull/48378) +* \[[`3c03ec0832`](https://github.com/nodejs/node/commit/3c03ec0832)] - **deps**: update simdutf to 3.2.14 (Node.js GitHub Bot) [#48344](https://github.com/nodejs/node/pull/48344) +* \[[`a2964a4583`](https://github.com/nodejs/node/commit/a2964a4583)] - **deps**: update ada to 2.5.1 (Node.js GitHub Bot) [#48319](https://github.com/nodejs/node/pull/48319) +* \[[`38f6e0d8cd`](https://github.com/nodejs/node/commit/38f6e0d8cd)] - **deps**: update zlib to 982b036 (Node.js GitHub Bot) [#48327](https://github.com/nodejs/node/pull/48327) +* \[[`f4617a4f81`](https://github.com/nodejs/node/commit/f4617a4f81)] - **deps**: add loongarch64 into openssl Makefile and gen openssl-loongarch64 (Shi Pujin) [#46401](https://github.com/nodejs/node/pull/46401) +* \[[`573eb4be12`](https://github.com/nodejs/node/commit/573eb4be12)] - **dgram**: socket add `asyncDispose` (atlowChemi) [#48717](https://github.com/nodejs/node/pull/48717) +* \[[`f3c4300e00`](https://github.com/nodejs/node/commit/f3c4300e00)] - **dgram**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`d3041df738`](https://github.com/nodejs/node/commit/d3041df738)] - **doc**: expand on squashing and rebasing to land a PR (Chengzhong Wu) [#48751](https://github.com/nodejs/node/pull/48751) +* \[[`249879e46c`](https://github.com/nodejs/node/commit/249879e46c)] - **doc**: add atlowChemi to collaborators (atlowChemi) [#48757](https://github.com/nodejs/node/pull/48757) +* \[[`42ecd46d1f`](https://github.com/nodejs/node/commit/42ecd46d1f)] - **doc**: fix ambiguity in http.md and https.md (an5er) [#48692](https://github.com/nodejs/node/pull/48692) +* \[[`e78824e053`](https://github.com/nodejs/node/commit/e78824e053)] - **doc**: add release key for Ulises Gascon (Ulises Gascón) [#49196](https://github.com/nodejs/node/pull/49196) +* \[[`1aa798d69f`](https://github.com/nodejs/node/commit/1aa798d69f)] - **doc**: clarify transform.\_transform() callback argument logic (Rafael Sofi-zada) [#48680](https://github.com/nodejs/node/pull/48680) +* \[[`d723e870a2`](https://github.com/nodejs/node/commit/d723e870a2)] - **doc**: mention git node release prepare (Rafael Gonzaga) [#48644](https://github.com/nodejs/node/pull/48644) +* \[[`a9a1394388`](https://github.com/nodejs/node/commit/a9a1394388)] - **doc**: fix options order (Luigi Pinca) [#48617](https://github.com/nodejs/node/pull/48617) +* \[[`989ea6858f`](https://github.com/nodejs/node/commit/989ea6858f)] - **doc**: update security release stewards (Rafael Gonzaga) [#48569](https://github.com/nodejs/node/pull/48569) +* \[[`f436ac1803`](https://github.com/nodejs/node/commit/f436ac1803)] - **doc**: update return type for describe (Shrujal Shah) [#48572](https://github.com/nodejs/node/pull/48572) +* \[[`fbe89e6320`](https://github.com/nodejs/node/commit/fbe89e6320)] - **doc**: run license-builder (github-actions\[bot]) [#48552](https://github.com/nodejs/node/pull/48552) +* \[[`f18b287bc3`](https://github.com/nodejs/node/commit/f18b287bc3)] - **doc**: add description of autoAllocateChunkSize in ReadableStream (Debadree Chatterjee) [#48004](https://github.com/nodejs/node/pull/48004) +* \[[`e2f3ed1444`](https://github.com/nodejs/node/commit/e2f3ed1444)] - **doc**: fix `filename` type in `watch` result (Dmitry Semigradsky) [#48032](https://github.com/nodejs/node/pull/48032) +* \[[`1fe75dc2b0`](https://github.com/nodejs/node/commit/1fe75dc2b0)] - **doc**: unnest `mime` and `MIMEParams` from MIMEType constructor (Dmitry Semigradsky) [#47950](https://github.com/nodejs/node/pull/47950) +* \[[`e1339d58e8`](https://github.com/nodejs/node/commit/e1339d58e8)] - **doc**: update security-release-process.md (Rafael Gonzaga) [#48504](https://github.com/nodejs/node/pull/48504) +* \[[`e8dc7bde6a`](https://github.com/nodejs/node/commit/e8dc7bde6a)] - **doc**: add vmoroz to collaborators (Vladimir Morozov) [#48527](https://github.com/nodejs/node/pull/48527) +* \[[`f8ba672c7b`](https://github.com/nodejs/node/commit/f8ba672c7b)] - **doc**: link to Runtime Keys in export conditions (Jacob Hummer) [#48408](https://github.com/nodejs/node/pull/48408) +* \[[`0056cb93e9`](https://github.com/nodejs/node/commit/0056cb93e9)] - **doc**: update fs flags documentation (sinkhaha) [#48463](https://github.com/nodejs/node/pull/48463) +* \[[`3cf3fb9479`](https://github.com/nodejs/node/commit/3cf3fb9479)] - **doc**: revise `error.md` introduction (Antoine du Hamel) [#48423](https://github.com/nodejs/node/pull/48423) +* \[[`7575d8b90e`](https://github.com/nodejs/node/commit/7575d8b90e)] - **doc**: add preveen-stack to triagers (Preveen P) [#48387](https://github.com/nodejs/node/pull/48387) +* \[[`820aa550a4`](https://github.com/nodejs/node/commit/820aa550a4)] - **doc**: refine when file is undefined in test events (Moshe Atlow) [#48451](https://github.com/nodejs/node/pull/48451) +* \[[`a30f2fbcc1`](https://github.com/nodejs/node/commit/a30f2fbcc1)] - **doc**: add kvakil to collaborators (Keyhan Vakil) [#48449](https://github.com/nodejs/node/pull/48449) +* \[[`239b4ea66f`](https://github.com/nodejs/node/commit/239b4ea66f)] - **doc**: mark `--import` as experimental (Moshe Atlow) [#44067](https://github.com/nodejs/node/pull/44067) +* \[[`2a561aefe2`](https://github.com/nodejs/node/commit/2a561aefe2)] - **doc**: add additional info on TSFN dispatch (Michael Dawson) [#48367](https://github.com/nodejs/node/pull/48367) +* \[[`5cc6eee30d`](https://github.com/nodejs/node/commit/5cc6eee30d)] - **doc**: add link for news from security wg (Michael Dawson) [#48396](https://github.com/nodejs/node/pull/48396) +* \[[`ffece88452`](https://github.com/nodejs/node/commit/ffece88452)] - **doc**: fix typo in events.md (Darshan Sen) [#48436](https://github.com/nodejs/node/pull/48436) +* \[[`06513585dc`](https://github.com/nodejs/node/commit/06513585dc)] - **doc**: run license-builder (github-actions\[bot]) [#48336](https://github.com/nodejs/node/pull/48336) +* \[[`d9a800ee5c`](https://github.com/nodejs/node/commit/d9a800ee5c)] - **esm**: fix emit deprecation on legacy main resolve (Antoine du Hamel) [#48664](https://github.com/nodejs/node/pull/48664) +* \[[`c39b7c240e`](https://github.com/nodejs/node/commit/c39b7c240e)] - **(SEMVER-MINOR)** **esm**: add `--import` flag (Moshe Atlow) [#43942](https://github.com/nodejs/node/pull/43942) +* \[[`a00464ee06`](https://github.com/nodejs/node/commit/a00464ee06)] - **esm**: fix specifier resolution and symlinks (Zack Newsham) [#47674](https://github.com/nodejs/node/pull/47674) +* \[[`3b8ec348b0`](https://github.com/nodejs/node/commit/3b8ec348b0)] - **events**: fix bug listenerCount don't compare wrapped listener (yuzheng14) [#48592](https://github.com/nodejs/node/pull/48592) +* \[[`a68a67f54d`](https://github.com/nodejs/node/commit/a68a67f54d)] - **(SEMVER-MINOR)** **events**: allow safely adding listener to abortSignal (Chemi Atlow) [#48596](https://github.com/nodejs/node/pull/48596) +* \[[`5354af3dab`](https://github.com/nodejs/node/commit/5354af3dab)] - **fs**: call the callback with an error if writeSync fails (killa) [#47949](https://github.com/nodejs/node/pull/47949) +* \[[`c3a27d1d3d`](https://github.com/nodejs/node/commit/c3a27d1d3d)] - **fs**: remove unneeded return statement (Luigi Pinca) [#48526](https://github.com/nodejs/node/pull/48526) +* \[[`3a8586bee2`](https://github.com/nodejs/node/commit/3a8586bee2)] - **fs, stream**: initial `Symbol.dispose` and `Symbol.asyncDispose` support (Moshe Atlow) [#48518](https://github.com/nodejs/node/pull/48518) +* \[[`01746c71df`](https://github.com/nodejs/node/commit/01746c71df)] - **http**: null the joinDuplicateHeaders property on cleanup (Luigi Pinca) [#48608](https://github.com/nodejs/node/pull/48608) +* \[[`d47eb73a85`](https://github.com/nodejs/node/commit/d47eb73a85)] - **http**: remove useless ternary in test (geekreal) [#48481](https://github.com/nodejs/node/pull/48481) +* \[[`977e9a38b4`](https://github.com/nodejs/node/commit/977e9a38b4)] - **http**: fix for handling on boot timers headers and request (Franciszek Koltuniuk) [#48291](https://github.com/nodejs/node/pull/48291) +* \[[`be88f7cd22`](https://github.com/nodejs/node/commit/be88f7cd22)] - **http2**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`7c7230a85c`](https://github.com/nodejs/node/commit/7c7230a85c)] - **http2**: send RST code 8 on AbortController signal (Devraj Mehta) [#48573](https://github.com/nodejs/node/pull/48573) +* \[[`f74c2fc72a`](https://github.com/nodejs/node/commit/f74c2fc72a)] - **lib**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`db355d1f37`](https://github.com/nodejs/node/commit/db355d1f37)] - **lib**: add option to force handling stopped events (Chemi Atlow) [#48301](https://github.com/nodejs/node/pull/48301) +* \[[`5d682c55a5`](https://github.com/nodejs/node/commit/5d682c55a5)] - **lib**: reduce url getters on `makeRequireFunction` (Yagiz Nizipli) [#48492](https://github.com/nodejs/node/pull/48492) +* \[[`5260f53e55`](https://github.com/nodejs/node/commit/5260f53e55)] - **lib**: add support for inherited custom inspection methods (Antoine du Hamel) [#48306](https://github.com/nodejs/node/pull/48306) +* \[[`69aaf8b1d1`](https://github.com/nodejs/node/commit/69aaf8b1d1)] - **lib**: remove invalid parameter to toASCII (Yagiz Nizipli) [#48878](https://github.com/nodejs/node/pull/48878) +* \[[`51863b80e4`](https://github.com/nodejs/node/commit/51863b80e4)] - **meta**: bump actions/checkout from 3.5.2 to 3.5.3 (dependabot\[bot]) [#48625](https://github.com/nodejs/node/pull/48625) +* \[[`7ec370991d`](https://github.com/nodejs/node/commit/7ec370991d)] - **meta**: bump step-security/harden-runner from 2.4.0 to 2.4.1 (dependabot\[bot]) [#48626](https://github.com/nodejs/node/pull/48626) +* \[[`34b8e980d4`](https://github.com/nodejs/node/commit/34b8e980d4)] - **meta**: bump ossf/scorecard-action from 2.1.3 to 2.2.0 (dependabot\[bot]) [#48628](https://github.com/nodejs/node/pull/48628) +* \[[`dfed9a7da9`](https://github.com/nodejs/node/commit/dfed9a7da9)] - **meta**: bump github/codeql-action from 2.3.6 to 2.20.1 (dependabot\[bot]) [#48627](https://github.com/nodejs/node/pull/48627) +* \[[`071eaadc5a`](https://github.com/nodejs/node/commit/071eaadc5a)] - **module**: add SourceMap.findOrigin (Isaac Z. Schlueter) [#47790](https://github.com/nodejs/node/pull/47790) +* \[[`bf1525c549`](https://github.com/nodejs/node/commit/bf1525c549)] - **module**: reduce url invocations in esm/load.js (Yagiz Nizipli) [#48337](https://github.com/nodejs/node/pull/48337) +* \[[`f8921630a2`](https://github.com/nodejs/node/commit/f8921630a2)] - **net**: server add `asyncDispose` (atlowChemi) [#48717](https://github.com/nodejs/node/pull/48717) +* \[[`b5f53d9a0b`](https://github.com/nodejs/node/commit/b5f53d9a0b)] - **net**: fix family autoselection SSL connection handling (Paolo Insogna) [#48189](https://github.com/nodejs/node/pull/48189) +* \[[`267439fc34`](https://github.com/nodejs/node/commit/267439fc34)] - **net**: rework autoSelectFamily implementation (Paolo Insogna) [#46587](https://github.com/nodejs/node/pull/46587) +* \[[`d3637cdbbf`](https://github.com/nodejs/node/commit/d3637cdbbf)] - **net**: fix address iteration with autoSelectFamily (Fedor Indutny) [#48258](https://github.com/nodejs/node/pull/48258) +* \[[`e8289a83f1`](https://github.com/nodejs/node/commit/e8289a83f1)] - **net**: fix family autoselection timeout handling (Paolo Insogna) [#47860](https://github.com/nodejs/node/pull/47860) +* \[[`863bdb785d`](https://github.com/nodejs/node/commit/863bdb785d)] - **net**: add autoSelectFamily global getter and setter (Paolo Insogna) [#45777](https://github.com/nodejs/node/pull/45777) +* \[[`04dc090bfa`](https://github.com/nodejs/node/commit/04dc090bfa)] - **node-api**: provide napi\_define\_properties fast path (Gabriel Schulhof) [#48440](https://github.com/nodejs/node/pull/48440) +* \[[`feb6a54dc3`](https://github.com/nodejs/node/commit/feb6a54dc3)] - **node-api**: implement external strings (Gabriel Schulhof) [#48339](https://github.com/nodejs/node/pull/48339) +* \[[`121f74c463`](https://github.com/nodejs/node/commit/121f74c463)] - **perf\_hooks**: convert maxSize to IDL value in setResourceTimingBufferSize (Chengzhong Wu) [#44902](https://github.com/nodejs/node/pull/44902) +* \[[`804d880589`](https://github.com/nodejs/node/commit/804d880589)] - **permission**: fix data types in PrintTree (Tobias Nießen) [#48770](https://github.com/nodejs/node/pull/48770) +* \[[`7aaecce9bf`](https://github.com/nodejs/node/commit/7aaecce9bf)] - **permission**: add debug log when inserting fs nodes (Rafael Gonzaga) [#48677](https://github.com/nodejs/node/pull/48677) +* \[[`cb51ef2905`](https://github.com/nodejs/node/commit/cb51ef2905)] - **readline**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`07065d0814`](https://github.com/nodejs/node/commit/07065d0814)] - **report**: disable js stack when no context is entered (Chengzhong Wu) [#48495](https://github.com/nodejs/node/pull/48495) +* \[[`572b82ffef`](https://github.com/nodejs/node/commit/572b82ffef)] - **src**: make BaseObject iteration order deterministic (Joyee Cheung) [#48702](https://github.com/nodejs/node/pull/48702) +* \[[`3f65598a41`](https://github.com/nodejs/node/commit/3f65598a41)] - **src**: remove kEagerCompile for CompileFunction (Keyhan Vakil) [#48671](https://github.com/nodejs/node/pull/48671) +* \[[`f43eacac9b`](https://github.com/nodejs/node/commit/f43eacac9b)] - **src**: deduplicate X509 getter implementations (Tobias Nießen) [#48563](https://github.com/nodejs/node/pull/48563) +* \[[`0c19621bdc`](https://github.com/nodejs/node/commit/0c19621bdc)] - **src**: fix uninitialized field access in AsyncHooks (Jan Olaf Krems) [#48566](https://github.com/nodejs/node/pull/48566) +* \[[`0c38184d62`](https://github.com/nodejs/node/commit/0c38184d62)] - **src**: fix Coverity issue regarding unnecessary copy (Yagiz Nizipli) [#48565](https://github.com/nodejs/node/pull/48565) +* \[[`0d73009ba3`](https://github.com/nodejs/node/commit/0d73009ba3)] - **src**: refactor `SplitString` in util (Yagiz Nizipli) [#48491](https://github.com/nodejs/node/pull/48491) +* \[[`6c72622df9`](https://github.com/nodejs/node/commit/6c72622df9)] - **src**: handle wasm out of bound in osx will raise SIGBUS correctly (Congcong Cai) [#46561](https://github.com/nodejs/node/pull/46561) +* \[[`e4261809b0`](https://github.com/nodejs/node/commit/e4261809b0)] - **src**: replace idna functions with ada::idna (Yagiz Nizipli) [#47735](https://github.com/nodejs/node/pull/47735) +* \[[`3dd82b1820`](https://github.com/nodejs/node/commit/3dd82b1820)] - **stream**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`786fbdb824`](https://github.com/nodejs/node/commit/786fbdb824)] - **stream**: fix premature pipeline end (Robert Nagy) [#48435](https://github.com/nodejs/node/pull/48435) +* \[[`c224e1b255`](https://github.com/nodejs/node/commit/c224e1b255)] - **stream**: fix deadlock when pipeing to full sink (Robert Nagy) [#48691](https://github.com/nodejs/node/pull/48691) +* \[[`2c75b9ece2`](https://github.com/nodejs/node/commit/2c75b9ece2)] - **test**: fix flaky test-string-decode.js on x86 (Stefan Stojanovic) [#48750](https://github.com/nodejs/node/pull/48750) +* \[[`279c4f64c1`](https://github.com/nodejs/node/commit/279c4f64c1)] - **test**: mark test-http-regr-gh-2928 as flaky (Joyee Cheung) [#49565](https://github.com/nodejs/node/pull/49565) +* \[[`01eacccd9a`](https://github.com/nodejs/node/commit/01eacccd9a)] - **test**: deflake test-net-throttle (Luigi Pinca) [#48599](https://github.com/nodejs/node/pull/48599) +* \[[`33886b271c`](https://github.com/nodejs/node/commit/33886b271c)] - **test**: move test-net-throttle to parallel (Luigi Pinca) [#48599](https://github.com/nodejs/node/pull/48599) +* \[[`a79112b5f4`](https://github.com/nodejs/node/commit/a79112b5f4)] - _**Revert**_ "**test**: remove test-crypto-keygen flaky designation" (Luigi Pinca) [#48652](https://github.com/nodejs/node/pull/48652) +* \[[`6ec57984db`](https://github.com/nodejs/node/commit/6ec57984db)] - **test**: add missing assertions to test-runner-cli (Moshe Atlow) [#48593](https://github.com/nodejs/node/pull/48593) +* \[[`dd1805e802`](https://github.com/nodejs/node/commit/dd1805e802)] - **test**: remove test-crypto-keygen flaky designation (Luigi Pinca) [#48575](https://github.com/nodejs/node/pull/48575) +* \[[`df9a9afc99`](https://github.com/nodejs/node/commit/df9a9afc99)] - **test**: remove test-timers-immediate-queue flaky designation (Luigi Pinca) [#48575](https://github.com/nodejs/node/pull/48575) +* \[[`3ae96ae380`](https://github.com/nodejs/node/commit/3ae96ae380)] - **test**: make IsolateData per-isolate in cctest (Joyee Cheung) [#48450](https://github.com/nodejs/node/pull/48450) +* \[[`f2ce8e0c06`](https://github.com/nodejs/node/commit/f2ce8e0c06)] - **test**: define NAPI\_VERSION before including node\_api.h (Chengzhong Wu) [#48376](https://github.com/nodejs/node/pull/48376) +* \[[`13ac0a5e26`](https://github.com/nodejs/node/commit/13ac0a5e26)] - **test**: remove unnecessary noop function args to `mustNotCall()` (Antoine du Hamel) [#48513](https://github.com/nodejs/node/pull/48513) +* \[[`8fdd4c55b3`](https://github.com/nodejs/node/commit/8fdd4c55b3)] - **test**: skip test-runner-watch-mode on IBMi (Moshe Atlow) [#48473](https://github.com/nodejs/node/pull/48473) +* \[[`9d90409241`](https://github.com/nodejs/node/commit/9d90409241)] - **test**: fix flaky test-watch-mode (Moshe Atlow) [#48147](https://github.com/nodejs/node/pull/48147) +* \[[`27a4bc7c32`](https://github.com/nodejs/node/commit/27a4bc7c32)] - **test**: add missing \ include for std::find (Sam James) [#48380](https://github.com/nodejs/node/pull/48380) +* \[[`cb92c4b9fe`](https://github.com/nodejs/node/commit/cb92c4b9fe)] - **test**: update url web-platform tests (Yagiz Nizipli) [#48319](https://github.com/nodejs/node/pull/48319) +* \[[`f35c4d3190`](https://github.com/nodejs/node/commit/f35c4d3190)] - **test**: ignore the copied entry\_point.c (Luigi Pinca) [#48297](https://github.com/nodejs/node/pull/48297) +* \[[`41d1e6888f`](https://github.com/nodejs/node/commit/41d1e6888f)] - **test**: refactor test-gc-http-client-timeout (Luigi Pinca) [#48292](https://github.com/nodejs/node/pull/48292) +* \[[`125bca621a`](https://github.com/nodejs/node/commit/125bca621a)] - **test**: update encoding web-platform tests (Yagiz Nizipli) [#48320](https://github.com/nodejs/node/pull/48320) +* \[[`e9ac111d02`](https://github.com/nodejs/node/commit/e9ac111d02)] - **test**: update FileAPI web-platform tests (Yagiz Nizipli) [#48322](https://github.com/nodejs/node/pull/48322) +* \[[`3da57d17f5`](https://github.com/nodejs/node/commit/3da57d17f5)] - **test**: update user-timing web-platform tests (Yagiz Nizipli) [#48321](https://github.com/nodejs/node/pull/48321) +* \[[`c728b8a29b`](https://github.com/nodejs/node/commit/c728b8a29b)] - **test**: fix `test-net-autoselectfamily` for kernel without IPv6 support (Livia Medeiros) [#45856](https://github.com/nodejs/node/pull/45856) +* \[[`6de7aa1d19`](https://github.com/nodejs/node/commit/6de7aa1d19)] - **test**: move `test-tls-autoselectfamily-servername` to `test/internet` (Antoine du Hamel) [#47029](https://github.com/nodejs/node/pull/47029) +* \[[`2de9868292`](https://github.com/nodejs/node/commit/2de9868292)] - **test**: validate host with commas on url.parse (Yagiz Nizipli) [#48878](https://github.com/nodejs/node/pull/48878) +* \[[`e7d2e8ef2a`](https://github.com/nodejs/node/commit/e7d2e8ef2a)] - **test**: delete test-net-bytes-per-incoming-chunk-overhead (Michaël Zasso) [#48811](https://github.com/nodejs/node/pull/48811) +* \[[`f5494fa1b0`](https://github.com/nodejs/node/commit/f5494fa1b0)] - **test\_runner**: fixed `test` shorthands return type (Shocker) [#48555](https://github.com/nodejs/node/pull/48555) +* \[[`7051cafdfa`](https://github.com/nodejs/node/commit/7051cafdfa)] - **test\_runner**: make `--test-name-pattern` recursive (Moshe Atlow) [#48382](https://github.com/nodejs/node/pull/48382) +* \[[`f302286442`](https://github.com/nodejs/node/commit/f302286442)] - **test\_runner**: refactor coverage report output for readability (Damien Seguin) [#47791](https://github.com/nodejs/node/pull/47791) +* \[[`7822a541e5`](https://github.com/nodejs/node/commit/7822a541e5)] - **timers**: support Symbol.dispose (Moshe Atlow) [#48633](https://github.com/nodejs/node/pull/48633) +* \[[`3eeca52db1`](https://github.com/nodejs/node/commit/3eeca52db1)] - **tls**: fix bugs of double TLS (rogertyang) [#48969](https://github.com/nodejs/node/pull/48969) +* \[[`4826379516`](https://github.com/nodejs/node/commit/4826379516)] - **tools**: run fetch\_deps.py with Python 3 (Richard Lau) [#48729](https://github.com/nodejs/node/pull/48729) +* \[[`e2688c8d79`](https://github.com/nodejs/node/commit/e2688c8d79)] - **tools**: update doc to unist-util-select\@5.0.0 unist-util-visit\@5.0.0 (Node.js GitHub Bot) [#48714](https://github.com/nodejs/node/pull/48714) +* \[[`7399481096`](https://github.com/nodejs/node/commit/7399481096)] - **tools**: update lint-md-dependencies to rollup\@3.26.2 (Node.js GitHub Bot) [#48705](https://github.com/nodejs/node/pull/48705) +* \[[`31c07153ce`](https://github.com/nodejs/node/commit/31c07153ce)] - **tools**: update eslint to 8.44.0 (Node.js GitHub Bot) [#48632](https://github.com/nodejs/node/pull/48632) +* \[[`4e53f51e24`](https://github.com/nodejs/node/commit/4e53f51e24)] - **tools**: update lint-md-dependencies to rollup\@3.26.0 (Node.js GitHub Bot) [#48631](https://github.com/nodejs/node/pull/48631) +* \[[`7d52950a96`](https://github.com/nodejs/node/commit/7d52950a96)] - **tools**: update lint-md-dependencies (Node.js GitHub Bot) [#48544](https://github.com/nodejs/node/pull/48544) +* \[[`e168eab3ee`](https://github.com/nodejs/node/commit/e168eab3ee)] - **tools**: update lint-md-dependencies (Node.js GitHub Bot) [#48486](https://github.com/nodejs/node/pull/48486) +* \[[`9711bc24f6`](https://github.com/nodejs/node/commit/9711bc24f6)] - **tools**: replace sed with perl (Luigi Pinca) [#48499](https://github.com/nodejs/node/pull/48499) +* \[[`9c1937c0a7`](https://github.com/nodejs/node/commit/9c1937c0a7)] - **tools**: update eslint to 8.43.0 (Node.js GitHub Bot) [#48487](https://github.com/nodejs/node/pull/48487) +* \[[`9449f05ab1`](https://github.com/nodejs/node/commit/9449f05ab1)] - **tools**: update doc to to-vfile\@8.0.0 (Node.js GitHub Bot) [#48485](https://github.com/nodejs/node/pull/48485) +* \[[`79dcd968b1`](https://github.com/nodejs/node/commit/79dcd968b1)] - **tools**: prepare tools/doc for to-vfile 8.0.0 (Rich Trott) [#48485](https://github.com/nodejs/node/pull/48485) +* \[[`538f388ac0`](https://github.com/nodejs/node/commit/538f388ac0)] - **tools**: update lint-md-dependencies (Node.js GitHub Bot) [#48417](https://github.com/nodejs/node/pull/48417) +* \[[`01bc10dcd5`](https://github.com/nodejs/node/commit/01bc10dcd5)] - **tools**: update create-or-update-pull-request-action (Richard Lau) [#48398](https://github.com/nodejs/node/pull/48398) +* \[[`590a072657`](https://github.com/nodejs/node/commit/590a072657)] - **tools**: update eslint-plugin-jsdoc (Richard Lau) [#48393](https://github.com/nodejs/node/pull/48393) +* \[[`6a5805491e`](https://github.com/nodejs/node/commit/6a5805491e)] - **tools**: update eslint to 8.42.0 (Node.js GitHub Bot) [#48328](https://github.com/nodejs/node/pull/48328) +* \[[`2eb13e3986`](https://github.com/nodejs/node/commit/2eb13e3986)] - **tools**: disable jsdoc/no-defaults rule (Luigi Pinca) [#48328](https://github.com/nodejs/node/pull/48328) +* \[[`3363cfa6c7`](https://github.com/nodejs/node/commit/3363cfa6c7)] - **typings**: remove unused primordials (Yagiz Nizipli) [#48509](https://github.com/nodejs/node/pull/48509) +* \[[`c59ae86ba0`](https://github.com/nodejs/node/commit/c59ae86ba0)] - **(SEMVER-MINOR)** **url**: add value argument to has and delete methods (Sankalp Shubham) [#47885](https://github.com/nodejs/node/pull/47885) +* \[[`f59c9636f4`](https://github.com/nodejs/node/commit/f59c9636f4)] - **url**: conform to origin getter spec changes (Yagiz Nizipli) [#48319](https://github.com/nodejs/node/pull/48319) +* \[[`0beb5ab93d`](https://github.com/nodejs/node/commit/0beb5ab93d)] - **url**: ensure getter access do not mutate observable symbols (Antoine du Hamel) [#48897](https://github.com/nodejs/node/pull/48897) +* \[[`0a022c496d`](https://github.com/nodejs/node/commit/0a022c496d)] - **util**: use `primordials.ArrayPrototypeIndexOf` instead of mutable method (DaisyDogs07) [#48586](https://github.com/nodejs/node/pull/48586) + + + +## 2023-08-09, Version 18.17.1 'Hydrogen' (LTS), @RafaelGSS + +This is a security release. + +### Notable Changes + +The following CVEs are fixed in this release: + +* [CVE-2023-32002](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32002): Policies can be bypassed via Module.\_load (High) +* [CVE-2023-32006](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32006): Policies can be bypassed by module.constructor.createRequire (Medium) +* [CVE-2023-32559](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32559): Policies can be bypassed via process.binding (Medium) +* OpenSSL Security Releases + * [OpenSSL security advisory 14th July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000264.html). + * [OpenSSL security advisory 19th July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000265.html). + * [OpenSSL security advisory 31st July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000267.html) + +More detailed information on each of the vulnerabilities can be found in [August 2023 Security Releases](https://nodejs.org/en/blog/vulnerability/august-2023-security-releases/) blog post. + +### Commits + +* \[[`fe3abdf82e`](https://github.com/nodejs/node/commit/fe3abdf82e)] - **deps**: update archs files for openssl-3.0.10+quic1 (Node.js GitHub Bot) [#49036](https://github.com/nodejs/node/pull/49036) +* \[[`2c5a522d9c`](https://github.com/nodejs/node/commit/2c5a522d9c)] - **deps**: upgrade openssl sources to quictls/openssl-3.0.10+quic1 (Node.js GitHub Bot) [#49036](https://github.com/nodejs/node/pull/49036) +* \[[`15bced0bde`](https://github.com/nodejs/node/commit/15bced0bde)] - **policy**: handle Module.constructor and main.extensions bypass (RafaelGSS) [nodejs-private/node-private#417](https://github.com/nodejs-private/node-private/pull/417) +* \[[`d4570fae35`](https://github.com/nodejs/node/commit/d4570fae35)] - **policy**: disable process.binding() when enabled (Tobias Nießen) [nodejs-private/node-private#460](https://github.com/nodejs-private/node-private/pull/460) + + + +## 2023-07-18, Version 18.17.0 'Hydrogen' (LTS), @danielleadams + +### Notable Changes + +#### Ada 2.0 + +Node.js v18.17.0 comes with the latest version of the URL parser, Ada. This update brings significant performance improvements +to URL parsing, including enhancements to the url.domainToASCII and url.domainToUnicode functions in node:url. + +Ada 2.0 has been integrated into the Node.js codebase, ensuring that all parts of the application can benefit from the +improved performance. Additionally, Ada 2.0 features a significant performance boost over its predecessor, Ada 1.0.4, +while also eliminating the need for the ICU requirement for URL hostname parsing. + +Contributed by Yagiz Nizipli and Daniel Lemire in [#47339](https://github.com/nodejs/node/pull/47339) + +#### Web Crypto API + +Web Crypto API functions' arguments are now coerced and validated as per their WebIDL definitions like in other Web Crypto API implementations. +This further improves interoperability with other implementations of Web Crypto API. + +Contributed by Filip Skokan in [#46067](https://github.com/nodejs/node/pull/46067) + +* **crypto**: + * update root certificates to NSS 3.89 (Node.js GitHub Bot) [#47659](https://github.com/nodejs/node/pull/47659) +* **dns**: + * **(SEMVER-MINOR)** expose getDefaultResultOrder (btea) [#46973](https://github.com/nodejs/node/pull/46973) +* **doc**: + * add ovflowd to collaborators (Claudio Wunder) [#47844](https://github.com/nodejs/node/pull/47844) + * add KhafraDev to collaborators (Matthew Aitken) [#47510](https://github.com/nodejs/node/pull/47510) +* **events**: + * **(SEMVER-MINOR)** add getMaxListeners method (Matthew Aitken) [#47039](https://github.com/nodejs/node/pull/47039) +* **fs**: + * **(SEMVER-MINOR)** add support for mode flag to specify the copy behavior (Tetsuharu Ohzeki) [#47084](https://github.com/nodejs/node/pull/47084) + * **(SEMVER-MINOR)** add recursive option to readdir and opendir (Ethan Arrowood) [#41439](https://github.com/nodejs/node/pull/41439) + * **(SEMVER-MINOR)** add support for mode flag to specify the copy behavior (Tetsuharu Ohzeki) [#47084](https://github.com/nodejs/node/pull/47084) + * **(SEMVER-MINOR)** implement byob mode for readableWebStream() (Debadree Chatterjee) [#46933](https://github.com/nodejs/node/pull/46933) +* **http**: + * **(SEMVER-MINOR)** prevent writing to the body when not allowed by HTTP spec (Gerrard Lindsay) [#47732](https://github.com/nodejs/node/pull/47732) + * **(SEMVER-MINOR)** remove internal error in assignSocket (Matteo Collina) [#47723](https://github.com/nodejs/node/pull/47723) + * **(SEMVER-MINOR)** add highWaterMark opt in http.createServer (HinataKah0) [#47405](https://github.com/nodejs/node/pull/47405) +* **lib**: + * **(SEMVER-MINOR)** add webstreams to Duplex.from() (Debadree Chatterjee) [#46190](https://github.com/nodejs/node/pull/46190) + * **(SEMVER-MINOR)** implement AbortSignal.any() (Chemi Atlow) [#47821](https://github.com/nodejs/node/pull/47821) +* **module**: + * change default resolver to not throw on unknown scheme (Gil Tayar) [#47824](https://github.com/nodejs/node/pull/47824) +* **node-api**: + * **(SEMVER-MINOR)** define version 9 (Chengzhong Wu) [#48151](https://github.com/nodejs/node/pull/48151) + * **(SEMVER-MINOR)** deprecate napi\_module\_register (Vladimir Morozov) [#46319](https://github.com/nodejs/node/pull/46319) +* **stream**: + * **(SEMVER-MINOR)** preserve object mode in compose (Raz Luvaton) [#47413](https://github.com/nodejs/node/pull/47413) + * **(SEMVER-MINOR)** add setter & getter for default highWaterMark (#46929) (Robert Nagy) [#46929](https://github.com/nodejs/node/pull/46929) +* **test**: + * unflake test-vm-timeout-escape-nexttick (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* **test\_runner**: + * **(SEMVER-MINOR)** add shorthands to `test` (Chemi Atlow) [#47909](https://github.com/nodejs/node/pull/47909) + * **(SEMVER-MINOR)** support combining coverage reports (Colin Ihrig) [#47686](https://github.com/nodejs/node/pull/47686) + * **(SEMVER-MINOR)** execute before hook on test (Chemi Atlow) [#47586](https://github.com/nodejs/node/pull/47586) + * **(SEMVER-MINOR)** expose reporter for use in run api (Chemi Atlow) [#47238](https://github.com/nodejs/node/pull/47238) +* **tools**: + * update LICENSE and license-builder.sh (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* **url**: + * **(SEMVER-MINOR)** implement URL.canParse (Matthew Aitken) [#47179](https://github.com/nodejs/node/pull/47179) +* **wasi**: + * **(SEMVER-MINOR)** no longer require flag to enable wasi (Michael Dawson) [#47286](https://github.com/nodejs/node/pull/47286) + +### Commits + +* \[[`2ba08ac002`](https://github.com/nodejs/node/commit/2ba08ac002)] - **benchmark**: use `cluster.isPrimary` instead of `cluster.isMaster` (Deokjin Kim) [#48002](https://github.com/nodejs/node/pull/48002) +* \[[`60ca69d96c`](https://github.com/nodejs/node/commit/60ca69d96c)] - **benchmark**: add eventtarget creation bench (Rafael Gonzaga) [#47774](https://github.com/nodejs/node/pull/47774) +* \[[`d8233d96bb`](https://github.com/nodejs/node/commit/d8233d96bb)] - **benchmark**: add a benchmark for `defaultResolve` (Antoine du Hamel) [#47543](https://github.com/nodejs/node/pull/47543) +* \[[`a1aabb6912`](https://github.com/nodejs/node/commit/a1aabb6912)] - **benchmark**: fix invalid requirementsURL (Deokjin Kim) [#47378](https://github.com/nodejs/node/pull/47378) +* \[[`394c61caf9`](https://github.com/nodejs/node/commit/394c61caf9)] - **bootstrap**: support namespaced builtins in snapshot scripts (Joyee Cheung) [#47467](https://github.com/nodejs/node/pull/47467) +* \[[`0165a765a0`](https://github.com/nodejs/node/commit/0165a765a0)] - **bootstrap**: do not expand process.argv\[1] for snapshot entry points (Joyee Cheung) [#47466](https://github.com/nodejs/node/pull/47466) +* \[[`cca557cdd9`](https://github.com/nodejs/node/commit/cca557cdd9)] - **buffer**: combine checking range of sourceStart in `buf.copy` (Deokjin Kim) [#47758](https://github.com/nodejs/node/pull/47758) +* \[[`4c69be467c`](https://github.com/nodejs/node/commit/4c69be467c)] - **buffer**: use private properties for brand checks in File (Matthew Aitken) [#47154](https://github.com/nodejs/node/pull/47154) +* \[[`d002f9b6e2`](https://github.com/nodejs/node/commit/d002f9b6e2)] - **build**: revert unkonwn ruff selector (Moshe Atlow) [#48753](https://github.com/nodejs/node/pull/48753) +* \[[`93f77cb762`](https://github.com/nodejs/node/commit/93f77cb762)] - **build**: set v8\_enable\_webassembly=false when lite mode is enabled (Cheng Shao) [#48248](https://github.com/nodejs/node/pull/48248) +* \[[`1662e894f3`](https://github.com/nodejs/node/commit/1662e894f3)] - **build**: add action to close stale PRs (Michael Dawson) [#48051](https://github.com/nodejs/node/pull/48051) +* \[[`5ca437b288`](https://github.com/nodejs/node/commit/5ca437b288)] - **build**: use pathlib for paths (Mohammed Keyvanzadeh) [#47581](https://github.com/nodejs/node/pull/47581) +* \[[`72443bc54b`](https://github.com/nodejs/node/commit/72443bc54b)] - **build**: refactor configure.py (Mohammed Keyvanzadeh) [#47667](https://github.com/nodejs/node/pull/47667) +* \[[`d4eecb5be9`](https://github.com/nodejs/node/commit/d4eecb5be9)] - **build**: add devcontainer configuration (Tierney Cyren) [#40825](https://github.com/nodejs/node/pull/40825) +* \[[`803ed41144`](https://github.com/nodejs/node/commit/803ed41144)] - **build**: bump ossf/scorecard-action from 2.1.2 to 2.1.3 (dependabot\[bot]) [#47367](https://github.com/nodejs/node/pull/47367) +* \[[`48468c4413`](https://github.com/nodejs/node/commit/48468c4413)] - **build**: replace Python linter flake8 with ruff (Christian Clauss) [#47519](https://github.com/nodejs/node/pull/47519) +* \[[`3ceb2c4387`](https://github.com/nodejs/node/commit/3ceb2c4387)] - **build**: add node-core-utils to setup (Jiawen Geng) [#47442](https://github.com/nodejs/node/pull/47442) +* \[[`fdc59b8e14`](https://github.com/nodejs/node/commit/fdc59b8e14)] - **build**: bump github/codeql-action from 2.2.6 to 2.2.9 (dependabot\[bot]) [#47366](https://github.com/nodejs/node/pull/47366) +* \[[`3924893023`](https://github.com/nodejs/node/commit/3924893023)] - **build**: update stale action from v7 to v8 (Rich Trott) [#47357](https://github.com/nodejs/node/pull/47357) +* \[[`753185c5b0`](https://github.com/nodejs/node/commit/753185c5b0)] - **build**: remove Python pip `--no-user` option (Christian Clauss) [#47372](https://github.com/nodejs/node/pull/47372) +* \[[`67af0a6a2b`](https://github.com/nodejs/node/commit/67af0a6a2b)] - **build**: avoid usage of pipes library (Mohammed Keyvanzadeh) [#47271](https://github.com/nodejs/node/pull/47271) +* \[[`db910dd6b2`](https://github.com/nodejs/node/commit/db910dd6b2)] - **build, deps, tools**: avoid excessive LTO (Konstantin Demin) [#47313](https://github.com/nodejs/node/pull/47313) +* \[[`35d1def891`](https://github.com/nodejs/node/commit/35d1def891)] - **child\_process**: use signal.reason in child process abort (Debadree Chatterjee) [#47817](https://github.com/nodejs/node/pull/47817) +* \[[`7692d2e7b9`](https://github.com/nodejs/node/commit/7692d2e7b9)] - **cluster**: use ObjectPrototypeHasOwnProperty (Daeyeon Jeong) [#48141](https://github.com/nodejs/node/pull/48141) +* \[[`7617772762`](https://github.com/nodejs/node/commit/7617772762)] - **crypto**: use openssl's own memory BIOs in crypto\_context.cc (GauriSpears) [#47160](https://github.com/nodejs/node/pull/47160) +* \[[`8cabfe7c6e`](https://github.com/nodejs/node/commit/8cabfe7c6e)] - **crypto**: fix setEngine() when OPENSSL\_NO\_ENGINE set (Tobias Nießen) [#47977](https://github.com/nodejs/node/pull/47977) +* \[[`de1338da05`](https://github.com/nodejs/node/commit/de1338da05)] - **crypto**: fix webcrypto private/secret import with empty usages (Filip Skokan) [#47877](https://github.com/nodejs/node/pull/47877) +* \[[`27a696fda9`](https://github.com/nodejs/node/commit/27a696fda9)] - **crypto**: update root certificates to NSS 3.89 (Node.js GitHub Bot) [#47659](https://github.com/nodejs/node/pull/47659) +* \[[`e2292f936e`](https://github.com/nodejs/node/commit/e2292f936e)] - **crypto**: remove INT\_MAX restriction in randomBytes (Tobias Nießen) [#47559](https://github.com/nodejs/node/pull/47559) +* \[[`a5f214c00c`](https://github.com/nodejs/node/commit/a5f214c00c)] - **crypto**: replace THROW with CHECK for scrypt keylen (Tobias Nießen) [#47407](https://github.com/nodejs/node/pull/47407) +* \[[`dd42214fd4`](https://github.com/nodejs/node/commit/dd42214fd4)] - **crypto**: unify validation of checkPrime checks (Tobias Nießen) [#47165](https://github.com/nodejs/node/pull/47165) +* \[[`76e4d12fb3`](https://github.com/nodejs/node/commit/76e4d12fb3)] - **crypto**: re-add padding for AES-KW wrapped JWKs (Filip Skokan) [#46563](https://github.com/nodejs/node/pull/46563) +* \[[`9d894c17dd`](https://github.com/nodejs/node/commit/9d894c17dd)] - **crypto**: use WebIDL converters in WebCryptoAPI (Filip Skokan) [#46067](https://github.com/nodejs/node/pull/46067) +* \[[`6f3a8b45a5`](https://github.com/nodejs/node/commit/6f3a8b45a5)] - **deps**: update ada to 2.5.0 (Node.js GitHub Bot) [#48223](https://github.com/nodejs/node/pull/48223) +* \[[`075b6db919`](https://github.com/nodejs/node/commit/075b6db919)] - **deps**: update ada to 2.4.2 (Node.js GitHub Bot) [#48092](https://github.com/nodejs/node/pull/48092) +* \[[`a4ee1f652c`](https://github.com/nodejs/node/commit/a4ee1f652c)] - **deps**: update ada to 2.4.1 (Node.js GitHub Bot) [#48036](https://github.com/nodejs/node/pull/48036) +* \[[`81b514d3f0`](https://github.com/nodejs/node/commit/81b514d3f0)] - **deps**: update ada to 2.4.0 (Node.js GitHub Bot) [#47922](https://github.com/nodejs/node/pull/47922) +* \[[`575ddf694f`](https://github.com/nodejs/node/commit/575ddf694f)] - **deps**: update ada to 2.3.1 (Node.js GitHub Bot) [#47893](https://github.com/nodejs/node/pull/47893) +* \[[`2d03d5f458`](https://github.com/nodejs/node/commit/2d03d5f458)] - **deps**: update ada to 2.3.0 (Node.js GitHub Bot) [#47737](https://github.com/nodejs/node/pull/47737) +* \[[`42e690f2d5`](https://github.com/nodejs/node/commit/42e690f2d5)] - **deps**: update ada to 2.2.0 (Node.js GitHub Bot) [#47678](https://github.com/nodejs/node/pull/47678) +* \[[`08dd271521`](https://github.com/nodejs/node/commit/08dd271521)] - **deps**: update ada to 2.1.0 (Node.js GitHub Bot) [#47598](https://github.com/nodejs/node/pull/47598) +* \[[`96c50ba71f`](https://github.com/nodejs/node/commit/96c50ba71f)] - **deps**: update ada to 2.0.0 (Node.js GitHub Bot) [#47339](https://github.com/nodejs/node/pull/47339) +* \[[`4d1c38b758`](https://github.com/nodejs/node/commit/4d1c38b758)] - **deps**: update zlib to 337322d (Node.js GitHub Bot) [#48218](https://github.com/nodejs/node/pull/48218) +* \[[`74206b2549`](https://github.com/nodejs/node/commit/74206b2549)] - **deps**: update histogram 0.11.8 (Marco Ippolito) [#47742](https://github.com/nodejs/node/pull/47742) +* \[[`fbb4b3775d`](https://github.com/nodejs/node/commit/fbb4b3775d)] - **deps**: update histogram to 0.11.7 (Marco Ippolito) [#47742](https://github.com/nodejs/node/pull/47742) +* \[[`e88c079022`](https://github.com/nodejs/node/commit/e88c079022)] - **deps**: update simdutf to 3.2.12 (Node.js GitHub Bot) [#48118](https://github.com/nodejs/node/pull/48118) +* \[[`48bd1248b9`](https://github.com/nodejs/node/commit/48bd1248b9)] - **deps**: update minimatch to 9.0.1 (Node.js GitHub Bot) [#48094](https://github.com/nodejs/node/pull/48094) +* \[[`d4572d31fa`](https://github.com/nodejs/node/commit/d4572d31fa)] - **deps**: update corepack to 0.18.0 (Node.js GitHub Bot) [#48091](https://github.com/nodejs/node/pull/48091) +* \[[`8090d29dc4`](https://github.com/nodejs/node/commit/8090d29dc4)] - **deps**: update uvwasi to 0.0.18 (Node.js GitHub Bot) [#47866](https://github.com/nodejs/node/pull/47866) +* \[[`169c8eea2e`](https://github.com/nodejs/node/commit/169c8eea2e)] - **deps**: update uvwasi to 0.0.17 (Node.js GitHub Bot) [#47866](https://github.com/nodejs/node/pull/47866) +* \[[`6acbb23380`](https://github.com/nodejs/node/commit/6acbb23380)] - **deps**: upgrade npm to 9.6.7 (npm team) [#48062](https://github.com/nodejs/node/pull/48062) +* \[[`e8f2c0a58b`](https://github.com/nodejs/node/commit/e8f2c0a58b)] - **deps**: update undici to 5.22.1 (Node.js GitHub Bot) [#47994](https://github.com/nodejs/node/pull/47994) +* \[[`9309fd3120`](https://github.com/nodejs/node/commit/9309fd3120)] - **deps**: update simdutf to 3.2.9 (Node.js GitHub Bot) [#47983](https://github.com/nodejs/node/pull/47983) +* \[[`b796d3560a`](https://github.com/nodejs/node/commit/b796d3560a)] - **deps**: upgrade npm to 9.6.6 (npm team) [#47862](https://github.com/nodejs/node/pull/47862) +* \[[`cce372e14e`](https://github.com/nodejs/node/commit/cce372e14e)] - **deps**: V8: cherry-pick c5ab3e4f0c5a (Richard Lau) [#47736](https://github.com/nodejs/node/pull/47736) +* \[[`7283486adb`](https://github.com/nodejs/node/commit/7283486adb)] - **deps**: update undici to 5.22.0 (Node.js GitHub Bot) [#47679](https://github.com/nodejs/node/pull/47679) +* \[[`2ea6e03003`](https://github.com/nodejs/node/commit/2ea6e03003)] - **deps**: add minimatch as a dependency (Moshe Atlow) [#47499](https://github.com/nodejs/node/pull/47499) +* \[[`261e1d23d1`](https://github.com/nodejs/node/commit/261e1d23d1)] - **deps**: update ICU to 73.1 release (Steven R. Loomis) [#47456](https://github.com/nodejs/node/pull/47456) +* \[[`f532f9df5f`](https://github.com/nodejs/node/commit/f532f9df5f)] - **deps**: update undici to 5.21.2 (Node.js GitHub Bot) [#47508](https://github.com/nodejs/node/pull/47508) +* \[[`dcb8c038b9`](https://github.com/nodejs/node/commit/dcb8c038b9)] - **deps**: update simdutf to 3.2.8 (Node.js GitHub Bot) [#47507](https://github.com/nodejs/node/pull/47507) +* \[[`6c8456d61f`](https://github.com/nodejs/node/commit/6c8456d61f)] - **deps**: update undici to 5.21.1 (Node.js GitHub Bot) [#47488](https://github.com/nodejs/node/pull/47488) +* \[[`d3b2e8a438`](https://github.com/nodejs/node/commit/d3b2e8a438)] - **deps**: update simdutf to 3.2.7 (Node.js GitHub Bot) [#47473](https://github.com/nodejs/node/pull/47473) +* \[[`64a5fe0499`](https://github.com/nodejs/node/commit/64a5fe0499)] - **deps**: update corepack to 0.17.2 (Node.js GitHub Bot) [#47474](https://github.com/nodejs/node/pull/47474) +* \[[`6f0f61a7d3`](https://github.com/nodejs/node/commit/6f0f61a7d3)] - **deps**: upgrade npm to 9.6.4 (npm team) [#47432](https://github.com/nodejs/node/pull/47432) +* \[[`443a72e207`](https://github.com/nodejs/node/commit/443a72e207)] - **deps**: update zlib to upstream 5edb52d4 (Luigi Pinca) [#47151](https://github.com/nodejs/node/pull/47151) +* \[[`dc3bc46914`](https://github.com/nodejs/node/commit/dc3bc46914)] - **deps**: update simdutf to 3.2.3 (Node.js GitHub Bot) [#47331](https://github.com/nodejs/node/pull/47331) +* \[[`b2f2bebbc2`](https://github.com/nodejs/node/commit/b2f2bebbc2)] - **deps**: update timezone to 2023c (Node.js GitHub Bot) [#47302](https://github.com/nodejs/node/pull/47302) +* \[[`c10729ffa7`](https://github.com/nodejs/node/commit/c10729ffa7)] - **deps**: upgrade npm to 9.6.3 (npm team) [#47325](https://github.com/nodejs/node/pull/47325) +* \[[`420deac1de`](https://github.com/nodejs/node/commit/420deac1de)] - **deps**: update corepack to 0.17.1 (Node.js GitHub Bot) [#47156](https://github.com/nodejs/node/pull/47156) +* \[[`966ba28491`](https://github.com/nodejs/node/commit/966ba28491)] - **deps**: V8: cherry-pick 3e4952cb2a59 (Richard Lau) [#47236](https://github.com/nodejs/node/pull/47236) +* \[[`fc6ab26824`](https://github.com/nodejs/node/commit/fc6ab26824)] - **deps**: update timezone to 2023b (Node.js GitHub Bot) [#47256](https://github.com/nodejs/node/pull/47256) +* \[[`2700e70215`](https://github.com/nodejs/node/commit/2700e70215)] - **deps**: upgrade npm to 9.6.2 (npm team) [#47108](https://github.com/nodejs/node/pull/47108) +* \[[`29ba98a0a5`](https://github.com/nodejs/node/commit/29ba98a0a5)] - **deps**: V8: cherry-pick 975ff4dbfd1b (Debadree Chatterjee) [#47209](https://github.com/nodejs/node/pull/47209) +* \[[`be34777be8`](https://github.com/nodejs/node/commit/be34777be8)] - **deps**: cherry-pick win/arm64/clang fixes (Cheng Zhao) [#47011](https://github.com/nodejs/node/pull/47011) +* \[[`b52aacb614`](https://github.com/nodejs/node/commit/b52aacb614)] - **deps**: update uvwasi to v0.0.16 (Michael Dawson) [#46434](https://github.com/nodejs/node/pull/46434) +* \[[`27a76cf5e0`](https://github.com/nodejs/node/commit/27a76cf5e0)] - **deps,test**: update postject to 1.0.0-alpha.6 (Node.js GitHub Bot) [#48072](https://github.com/nodejs/node/pull/48072) +* \[[`b171c1a3a4`](https://github.com/nodejs/node/commit/b171c1a3a4)] - **dgram**: convert macro to template (Tobias Nießen) [#47891](https://github.com/nodejs/node/pull/47891) +* \[[`709bf1c758`](https://github.com/nodejs/node/commit/709bf1c758)] - **(SEMVER-MINOR)** **dns**: expose getDefaultResultOrder (btea) [#46973](https://github.com/nodejs/node/pull/46973) +* \[[`2f202c93e7`](https://github.com/nodejs/node/commit/2f202c93e7)] - **doc**: clarify array args to Buffer.from() (Bryan English) [#48274](https://github.com/nodejs/node/pull/48274) +* \[[`27f195f8d8`](https://github.com/nodejs/node/commit/27f195f8d8)] - **doc**: document watch option for node:test run() (Moshe Atlow) [#48256](https://github.com/nodejs/node/pull/48256) +* \[[`7558ef350a`](https://github.com/nodejs/node/commit/7558ef350a)] - **doc**: update documentation for FIPS support (Richard Lau) [#48194](https://github.com/nodejs/node/pull/48194) +* \[[`f2bb1919e5`](https://github.com/nodejs/node/commit/f2bb1919e5)] - **doc**: improve the documentation of the stdio option (Kumar Arnav) [#48110](https://github.com/nodejs/node/pull/48110) +* \[[`a2aa52ba92`](https://github.com/nodejs/node/commit/a2aa52ba92)] - **doc**: update Buffer.allocUnsafe description (sinkhaha) [#48183](https://github.com/nodejs/node/pull/48183) +* \[[`19ad471d52`](https://github.com/nodejs/node/commit/19ad471d52)] - **doc**: update codeowners with website team (Claudio Wunder) [#48197](https://github.com/nodejs/node/pull/48197) +* \[[`67b2c2a98f`](https://github.com/nodejs/node/commit/67b2c2a98f)] - **doc**: fix broken link to new folder doc/contributing/maintaining (Andrea Fassina) [#48205](https://github.com/nodejs/node/pull/48205) +* \[[`795ca70815`](https://github.com/nodejs/node/commit/795ca70815)] - **doc**: add atlowChemi to triagers (Chemi Atlow) [#48104](https://github.com/nodejs/node/pull/48104) +* \[[`e437a0aff1`](https://github.com/nodejs/node/commit/e437a0aff1)] - **doc**: fix typo in readline completer function section (Vadym) [#48188](https://github.com/nodejs/node/pull/48188) +* \[[`92e0ea496d`](https://github.com/nodejs/node/commit/92e0ea496d)] - **doc**: remove broken link for keygen (Rich Trott) [#48176](https://github.com/nodejs/node/pull/48176) +* \[[`fe15dae8e6`](https://github.com/nodejs/node/commit/fe15dae8e6)] - **doc**: add `auto` intrinsic height to prevent jitter/flicker (Daniel Holbert) [#48195](https://github.com/nodejs/node/pull/48195) +* \[[`230335e21f`](https://github.com/nodejs/node/commit/230335e21f)] - **doc**: add version info on the SEA docs (Antoine du Hamel) [#48173](https://github.com/nodejs/node/pull/48173) +* \[[`e6f37d1b80`](https://github.com/nodejs/node/commit/e6f37d1b80)] - **doc**: add Ruy to list of TSC members (Michael Dawson) [#48172](https://github.com/nodejs/node/pull/48172) +* \[[`69205a250c`](https://github.com/nodejs/node/commit/69205a250c)] - **doc**: update socket.remote\* properties documentation (Saba Kharanauli) [#48139](https://github.com/nodejs/node/pull/48139) +* \[[`e4a5d6298c`](https://github.com/nodejs/node/commit/e4a5d6298c)] - **doc**: update outdated section on TLSv1.3-PSK (Tobias Nießen) [#48123](https://github.com/nodejs/node/pull/48123) +* \[[`d14018ed99`](https://github.com/nodejs/node/commit/d14018ed99)] - **doc**: improve HMAC key recommendations (Tobias Nießen) [#48121](https://github.com/nodejs/node/pull/48121) +* \[[`e9d4baf770`](https://github.com/nodejs/node/commit/e9d4baf770)] - **doc**: clarify mkdir() recursive behavior (Stephen Odogwu) [#48109](https://github.com/nodejs/node/pull/48109) +* \[[`3e4a469139`](https://github.com/nodejs/node/commit/3e4a469139)] - **doc**: fix typo in crypto legacy streams API section (Tobias Nießen) [#48122](https://github.com/nodejs/node/pull/48122) +* \[[`bdf366ab88`](https://github.com/nodejs/node/commit/bdf366ab88)] - **doc**: update SEA source link (Rich Trott) [#48080](https://github.com/nodejs/node/pull/48080) +* \[[`2a4f79a75f`](https://github.com/nodejs/node/commit/2a4f79a75f)] - **doc**: clarify tty.isRaw (Roberto Vidal) [#48055](https://github.com/nodejs/node/pull/48055) +* \[[`98c6e4be03`](https://github.com/nodejs/node/commit/98c6e4be03)] - **doc**: use secure key length for HMAC generateKey (Tobias Nießen) [#48052](https://github.com/nodejs/node/pull/48052) +* \[[`8ae5c8cf9d`](https://github.com/nodejs/node/commit/8ae5c8cf9d)] - **doc**: update broken EVP\_BytesToKey link (Rich Trott) [#48064](https://github.com/nodejs/node/pull/48064) +* \[[`3c713e7caa`](https://github.com/nodejs/node/commit/3c713e7caa)] - **doc**: update broken spkac link (Rich Trott) [#48063](https://github.com/nodejs/node/pull/48063) +* \[[`c22f739e94`](https://github.com/nodejs/node/commit/c22f739e94)] - **doc**: document node-api version process (Chengzhong Wu) [#47972](https://github.com/nodejs/node/pull/47972) +* \[[`ce859f9f9f`](https://github.com/nodejs/node/commit/ce859f9f9f)] - **doc**: fix typo in binding functions (Deokjin Kim) [#48003](https://github.com/nodejs/node/pull/48003) +* \[[`070c3457b7`](https://github.com/nodejs/node/commit/070c3457b7)] - **doc**: mark Node.js 14 as End-of-Life (Richard Lau) [#48023](https://github.com/nodejs/node/pull/48023) +* \[[`3611027d8e`](https://github.com/nodejs/node/commit/3611027d8e)] - **doc**: clarify CRYPTO\_CUSTOM\_ENGINE\_NOT\_SUPPORTED (Tobias Nießen) [#47976](https://github.com/nodejs/node/pull/47976) +* \[[`dbffad958c`](https://github.com/nodejs/node/commit/dbffad958c)] - **doc**: add missing deprecated blocks to cluster (Tobias Nießen) [#47981](https://github.com/nodejs/node/pull/47981) +* \[[`035356f711`](https://github.com/nodejs/node/commit/035356f711)] - **doc**: update description of global (Tobias Nießen) [#47969](https://github.com/nodejs/node/pull/47969) +* \[[`081a6ffaea`](https://github.com/nodejs/node/commit/081a6ffaea)] - **doc**: update measure memory rejection information (Yash Ladha) [#41639](https://github.com/nodejs/node/pull/41639) +* \[[`3460cf9c23`](https://github.com/nodejs/node/commit/3460cf9c23)] - **doc**: fix broken link to TC39 import attributes proposal (Rich Trott) [#47954](https://github.com/nodejs/node/pull/47954) +* \[[`3b018c8aa9`](https://github.com/nodejs/node/commit/3b018c8aa9)] - **doc**: fix broken link (Rich Trott) [#47953](https://github.com/nodejs/node/pull/47953) +* \[[`244db960a9`](https://github.com/nodejs/node/commit/244db960a9)] - **doc**: remove broken link (Rich Trott) [#47942](https://github.com/nodejs/node/pull/47942) +* \[[`2cc8715bb9`](https://github.com/nodejs/node/commit/2cc8715bb9)] - **doc**: document make lint-md-clean (Matteo Collina) [#47926](https://github.com/nodejs/node/pull/47926) +* \[[`b80e006c17`](https://github.com/nodejs/node/commit/b80e006c17)] - **doc**: mark global object as legacy (Mert Can Altın) [#47819](https://github.com/nodejs/node/pull/47819) +* \[[`bf4eb058f3`](https://github.com/nodejs/node/commit/bf4eb058f3)] - **doc**: ntfs junction points must link to directories (Ben Noordhuis) [#47907](https://github.com/nodejs/node/pull/47907) +* \[[`49875f0d69`](https://github.com/nodejs/node/commit/49875f0d69)] - **doc**: fix params names (Dmitry Semigradsky) [#47853](https://github.com/nodejs/node/pull/47853) +* \[[`94b5eaaf17`](https://github.com/nodejs/node/commit/94b5eaaf17)] - **doc**: update supported version of FreeBSD to 12.4 (Michaël Zasso) [#47838](https://github.com/nodejs/node/pull/47838) +* \[[`0114201825`](https://github.com/nodejs/node/commit/0114201825)] - **doc**: swap Matteo with Rafael in the stewards (Rafael Gonzaga) [#47841](https://github.com/nodejs/node/pull/47841) +* \[[`8bcfcc0af9`](https://github.com/nodejs/node/commit/8bcfcc0af9)] - **doc**: add valgrind suppression details (Kevin Eady) [#47760](https://github.com/nodejs/node/pull/47760) +* \[[`75d397ecab`](https://github.com/nodejs/node/commit/75d397ecab)] - **doc**: replace EOL versions in README (Tobias Nießen) [#47833](https://github.com/nodejs/node/pull/47833) +* \[[`2b0c57cb80`](https://github.com/nodejs/node/commit/2b0c57cb80)] - **doc**: add ovflowd to collaborators (Claudio Wunder) [#47844](https://github.com/nodejs/node/pull/47844) +* \[[`be4966977c`](https://github.com/nodejs/node/commit/be4966977c)] - **doc**: update BUILDING.md previous versions links (Tobias Nießen) [#47835](https://github.com/nodejs/node/pull/47835) +* \[[`a9e8a20fb8`](https://github.com/nodejs/node/commit/a9e8a20fb8)] - **doc**: create maintaining folder for deps (Marco Ippolito) [#47589](https://github.com/nodejs/node/pull/47589) +* \[[`fd0f362d7c`](https://github.com/nodejs/node/commit/fd0f362d7c)] - **doc**: remove MoLow from Triagers (Moshe Atlow) [#47792](https://github.com/nodejs/node/pull/47792) +* \[[`0927c67ab6`](https://github.com/nodejs/node/commit/0927c67ab6)] - **doc**: fix typo in webstreams.md (Christian Takle) [#47766](https://github.com/nodejs/node/pull/47766) +* \[[`994be578da`](https://github.com/nodejs/node/commit/994be578da)] - **doc**: move BethGriggs to regular member (Rich Trott) [#47776](https://github.com/nodejs/node/pull/47776) +* \[[`64d19f4678`](https://github.com/nodejs/node/commit/64d19f4678)] - **doc**: move addaleax to TSC emeriti (Anna Henningsen) [#47752](https://github.com/nodejs/node/pull/47752) +* \[[`33ec10e6b8`](https://github.com/nodejs/node/commit/33ec10e6b8)] - **doc**: add link to news for Node.js core (Michael Dawson) [#47704](https://github.com/nodejs/node/pull/47704) +* \[[`2a682b5efe`](https://github.com/nodejs/node/commit/2a682b5efe)] - **doc**: async\_hooks asynchronous content example add mjs code (btea) [#47401](https://github.com/nodejs/node/pull/47401) +* \[[`4f541c3ca3`](https://github.com/nodejs/node/commit/4f541c3ca3)] - **doc**: clarify concurrency model of test runner (Tobias Nießen) [#47642](https://github.com/nodejs/node/pull/47642) +* \[[`ffcff68f0d`](https://github.com/nodejs/node/commit/ffcff68f0d)] - **doc**: fix typos (Mohammed Keyvanzadeh) [#47685](https://github.com/nodejs/node/pull/47685) +* \[[`290b2b7afc`](https://github.com/nodejs/node/commit/290b2b7afc)] - **doc**: fix capitalization of ASan (Mohammed Keyvanzadeh) [#47676](https://github.com/nodejs/node/pull/47676) +* \[[`b4ca788878`](https://github.com/nodejs/node/commit/b4ca788878)] - **doc**: fix typos in SECURITY.md (Mohammed Keyvanzadeh) [#47677](https://github.com/nodejs/node/pull/47677) +* \[[`971c545a47`](https://github.com/nodejs/node/commit/971c545a47)] - **doc**: update error code of buffer (Deokjin Kim) [#47617](https://github.com/nodejs/node/pull/47617) +* \[[`ec5c919928`](https://github.com/nodejs/node/commit/ec5c919928)] - **doc**: change offset of example in `Buffer.copyBytesFrom` (Deokjin Kim) [#47606](https://github.com/nodejs/node/pull/47606) +* \[[`980bf052c7`](https://github.com/nodejs/node/commit/980bf052c7)] - **doc**: remove markdown link from heading (Tobias Nießen) [#47585](https://github.com/nodejs/node/pull/47585) +* \[[`e96451ec5e`](https://github.com/nodejs/node/commit/e96451ec5e)] - **doc**: fix release-post script location (Rafael Gonzaga) [#47517](https://github.com/nodejs/node/pull/47517) +* \[[`61ea15339c`](https://github.com/nodejs/node/commit/61ea15339c)] - **doc**: add link for news from uvwasi team (Michael Dawson) [#47531](https://github.com/nodejs/node/pull/47531) +* \[[`d40bcdd73e`](https://github.com/nodejs/node/commit/d40bcdd73e)] - **doc**: add missing setEncoding call in ESM example (Anna Henningsen) [#47558](https://github.com/nodejs/node/pull/47558) +* \[[`924dc909b3`](https://github.com/nodejs/node/commit/924dc909b3)] - **doc**: fix typo in util.types.isNativeError() (Julian Dax) [#47532](https://github.com/nodejs/node/pull/47532) +* \[[`a24d72a6fb`](https://github.com/nodejs/node/commit/a24d72a6fb)] - **doc**: add KhafraDev to collaborators (Matthew Aitken) [#47510](https://github.com/nodejs/node/pull/47510) +* \[[`b0196378b6`](https://github.com/nodejs/node/commit/b0196378b6)] - **doc**: create maintaining-brotli.md (Marco Ippolito) [#47380](https://github.com/nodejs/node/pull/47380) +* \[[`3902be8fe8`](https://github.com/nodejs/node/commit/3902be8fe8)] - **doc**: info on handling unintended breaking changes (Michael Dawson) [#47426](https://github.com/nodejs/node/pull/47426) +* \[[`670f9a591d`](https://github.com/nodejs/node/commit/670f9a591d)] - **doc**: add performance initiative (Yagiz Nizipli) [#47424](https://github.com/nodejs/node/pull/47424) +* \[[`89a5d04a8e`](https://github.com/nodejs/node/commit/89a5d04a8e)] - **doc**: do not create a backup file (Luigi Pinca) [#47151](https://github.com/nodejs/node/pull/47151) +* \[[`7f2bccc5d6`](https://github.com/nodejs/node/commit/7f2bccc5d6)] - **doc**: add MoLow to the TSC (Colin Ihrig) [#47436](https://github.com/nodejs/node/pull/47436) +* \[[`7db2e889ac`](https://github.com/nodejs/node/commit/7db2e889ac)] - **doc**: add a note about os.cpus() returning an empty list (codedokode) [#47363](https://github.com/nodejs/node/pull/47363) +* \[[`289a8e30d6`](https://github.com/nodejs/node/commit/289a8e30d6)] - **doc**: clarify reports are only evaluated on active versions (Rafael Gonzaga) [#47341](https://github.com/nodejs/node/pull/47341) +* \[[`dc22edb4d2`](https://github.com/nodejs/node/commit/dc22edb4d2)] - **doc**: remove Vladimir de Turckheim from Security release stewards (Vladimir de Turckheim) [#47318](https://github.com/nodejs/node/pull/47318) +* \[[`3e74a74da3`](https://github.com/nodejs/node/commit/3e74a74da3)] - **doc**: add importing util to example of \`process.report.getReport' (Deokjin Kim) [#47298](https://github.com/nodejs/node/pull/47298) +* \[[`ece029f64e`](https://github.com/nodejs/node/commit/ece029f64e)] - **doc**: vm.SourceTextModule() without context option (Axel Kittenberger) [#47295](https://github.com/nodejs/node/pull/47295) +* \[[`c7227204cc`](https://github.com/nodejs/node/commit/c7227204cc)] - **doc**: document process for sharing project news (Michael Dawson) [#47189](https://github.com/nodejs/node/pull/47189) +* \[[`2865cbb4bd`](https://github.com/nodejs/node/commit/2865cbb4bd)] - **doc**: revise example of assert.CallTracker (Deokjin Kim) [#47252](https://github.com/nodejs/node/pull/47252) +* \[[`81ebaf2670`](https://github.com/nodejs/node/commit/81ebaf2670)] - **doc**: fix typo in SECURITY.md (Rich Trott) [#47282](https://github.com/nodejs/node/pull/47282) +* \[[`faabd48f11`](https://github.com/nodejs/node/commit/faabd48f11)] - **doc**: use serial comma in cli docs (Tobias Nießen) [#47262](https://github.com/nodejs/node/pull/47262) +* \[[`3a85794089`](https://github.com/nodejs/node/commit/3a85794089)] - **doc**: improve example for Error.captureStackTrace() (Julian Dax) [#46886](https://github.com/nodejs/node/pull/46886) +* \[[`2114fa472b`](https://github.com/nodejs/node/commit/2114fa472b)] - **doc**: clarify http error events after calling destroy() (Zach Bjornson) [#46903](https://github.com/nodejs/node/pull/46903) +* \[[`d15f522d1f`](https://github.com/nodejs/node/commit/d15f522d1f)] - **doc**: update output of example in AbortController (Deokjin Kim) [#47227](https://github.com/nodejs/node/pull/47227) +* \[[`ab6588e343`](https://github.com/nodejs/node/commit/ab6588e343)] - **doc**: drop one-week branch sync on major releases (Rafael Gonzaga) [#47149](https://github.com/nodejs/node/pull/47149) +* \[[`6ac52e3061`](https://github.com/nodejs/node/commit/6ac52e3061)] - **doc**: fix grammar in the collaborator guide (Mohammed Keyvanzadeh) [#47245](https://github.com/nodejs/node/pull/47245) +* \[[`13175774a6`](https://github.com/nodejs/node/commit/13175774a6)] - **doc**: update stream.reduce concurrency note (Raz Luvaton) [#47166](https://github.com/nodejs/node/pull/47166) +* \[[`1e97ccd6d4`](https://github.com/nodejs/node/commit/1e97ccd6d4)] - **doc**: remove use of DEFAULT\_ENCODING in PBKDF2 docs (Tobias Nießen) [#47181](https://github.com/nodejs/node/pull/47181) +* \[[`d562a7c461`](https://github.com/nodejs/node/commit/d562a7c461)] - **doc**: fix typos in async\_context.md (Shubham Sharma) [#47155](https://github.com/nodejs/node/pull/47155) +* \[[`9a11788cdf`](https://github.com/nodejs/node/commit/9a11788cdf)] - **doc**: update collaborator guide to reflect TSC changes (Rich Trott) [#47126](https://github.com/nodejs/node/pull/47126) +* \[[`5fc2bb763f`](https://github.com/nodejs/node/commit/5fc2bb763f)] - **doc**: clarify that `fs.create{Read,Write}Stream` support `AbortSignal` (Antoine du Hamel) [#47122](https://github.com/nodejs/node/pull/47122) +* \[[`2dd3b0213e`](https://github.com/nodejs/node/commit/2dd3b0213e)] - **doc**: improve documentation for util.types.isNativeError() (Julian Dax) [#46840](https://github.com/nodejs/node/pull/46840) +* \[[`ce4636e36b`](https://github.com/nodejs/node/commit/ce4636e36b)] - **doc**: rename the startup performance initiative to startup snapshot (#47111) (Joyee Cheung) +* \[[`309d017f15`](https://github.com/nodejs/node/commit/309d017f15)] - **doc**: fix "maintaining dependencies" heading typos (Keyhan Vakil) [#47082](https://github.com/nodejs/node/pull/47082) +* \[[`230a984eb3`](https://github.com/nodejs/node/commit/230a984eb3)] - **doc**: include webstreams in finished() and Duplex.from() parameters (Debadree Chatterjee) [#46312](https://github.com/nodejs/node/pull/46312) +* \[[`8651ea822e`](https://github.com/nodejs/node/commit/8651ea822e)] - **doc,fs**: update description of fs.stat() method (Mert Can Altın) [#47654](https://github.com/nodejs/node/pull/47654) +* \[[`e4539e1f19`](https://github.com/nodejs/node/commit/e4539e1f19)] - **doc,test**: update the v8.startupSnapshot doc and test the example (Joyee Cheung) [#47468](https://github.com/nodejs/node/pull/47468) +* \[[`3dddc0175f`](https://github.com/nodejs/node/commit/3dddc0175f)] - **doc,test**: fix concurrency option of test() (Tobias Nießen) [#47734](https://github.com/nodejs/node/pull/47734) +* \[[`563f9fe06a`](https://github.com/nodejs/node/commit/563f9fe06a)] - **doc,vm**: clarify usage of cachedData in vm.compileFunction() (Darshan Sen) [#48193](https://github.com/nodejs/node/pull/48193) +* \[[`316016ffac`](https://github.com/nodejs/node/commit/316016ffac)] - **esm**: avoid accessing lazy getters for urls (Yagiz Nizipli) [#47542](https://github.com/nodejs/node/pull/47542) +* \[[`e5e385d2b2`](https://github.com/nodejs/node/commit/e5e385d2b2)] - **esm**: increase test coverage of edge cases (Antoine du Hamel) [#47033](https://github.com/nodejs/node/pull/47033) +* \[[`061fb20660`](https://github.com/nodejs/node/commit/061fb20660)] - **(SEMVER-MINOR)** **events**: add getMaxListeners method (Matthew Aitken) [#47039](https://github.com/nodejs/node/pull/47039) +* \[[`ed0b62cc01`](https://github.com/nodejs/node/commit/ed0b62cc01)] - **(SEMVER-MINOR)** **fs**: add support for mode flag to specify the copy behavior (Tetsuharu Ohzeki) [#47084](https://github.com/nodejs/node/pull/47084) +* \[[`9b44c56c9a`](https://github.com/nodejs/node/commit/9b44c56c9a)] - **fs**: make readdir recursive algorithm iterative (Ethan Arrowood) [#47650](https://github.com/nodejs/node/pull/47650) +* \[[`7273ef53b3`](https://github.com/nodejs/node/commit/7273ef53b3)] - **(SEMVER-MINOR)** **fs**: add recursive option to readdir and opendir (Ethan Arrowood) [#41439](https://github.com/nodejs/node/pull/41439) +* \[[`3f0636d2c1`](https://github.com/nodejs/node/commit/3f0636d2c1)] - **(SEMVER-MINOR)** **fs**: add support for mode flag to specify the copy behavior (Tetsuharu Ohzeki) [#47084](https://github.com/nodejs/node/pull/47084) +* \[[`a0b9853251`](https://github.com/nodejs/node/commit/a0b9853251)] - **(SEMVER-MINOR)** **fs**: implement byob mode for readableWebStream() (Debadree Chatterjee) [#46933](https://github.com/nodejs/node/pull/46933) +* \[[`709e368708`](https://github.com/nodejs/node/commit/709e368708)] - **http**: send implicit headers on HEAD with no body (Matteo Collina) [#48108](https://github.com/nodejs/node/pull/48108) +* \[[`dc318f26c0`](https://github.com/nodejs/node/commit/dc318f26c0)] - **(SEMVER-MINOR)** **http**: prevent writing to the body when not allowed by HTTP spec (Gerrard Lindsay) [#47732](https://github.com/nodejs/node/pull/47732) +* \[[`4b2a015642`](https://github.com/nodejs/node/commit/4b2a015642)] - **(SEMVER-MINOR)** **http**: remove internal error in assignSocket (Matteo Collina) [#47723](https://github.com/nodejs/node/pull/47723) +* \[[`7cef6aa721`](https://github.com/nodejs/node/commit/7cef6aa721)] - **(SEMVER-MINOR)** **http**: add highWaterMark opt in http.createServer (HinataKah0) [#47405](https://github.com/nodejs/node/pull/47405) +* \[[`9186f3a0ef`](https://github.com/nodejs/node/commit/9186f3a0ef)] - **http2**: improve nghttp2 error callback (Tobias Nießen) [#47840](https://github.com/nodejs/node/pull/47840) +* \[[`cc7e5dd4cd`](https://github.com/nodejs/node/commit/cc7e5dd4cd)] - **inspector**: add tips for Session (theanarkh) [#47195](https://github.com/nodejs/node/pull/47195) +* \[[`70c0e882d3`](https://github.com/nodejs/node/commit/70c0e882d3)] - **inspector**: log response and requests in the inspector for debugging (Joyee Cheung) [#46941](https://github.com/nodejs/node/pull/46941) +* \[[`6099d2d08b`](https://github.com/nodejs/node/commit/6099d2d08b)] - **inspector**: fix session.disconnect crash (theanarkh) [#46942](https://github.com/nodejs/node/pull/46942) +* \[[`156292d44a`](https://github.com/nodejs/node/commit/156292d44a)] - **lib**: create weakRef only if any signals provided (Chemi Atlow) [#48448](https://github.com/nodejs/node/pull/48448) +* \[[`efaa073303`](https://github.com/nodejs/node/commit/efaa073303)] - **(SEMVER-MINOR)** **lib**: implement AbortSignal.any() (Chemi Atlow) [#47821](https://github.com/nodejs/node/pull/47821) +* \[[`c46b31f3bf`](https://github.com/nodejs/node/commit/c46b31f3bf)] - **lib**: support FORCE\_COLOR for non TTY streams (Moshe Atlow) [#48034](https://github.com/nodejs/node/pull/48034) +* \[[`286c358832`](https://github.com/nodejs/node/commit/286c358832)] - **lib**: do not disable linter for entire files (Antoine du Hamel) [#48299](https://github.com/nodejs/node/pull/48299) +* \[[`a2552ab7c0`](https://github.com/nodejs/node/commit/a2552ab7c0)] - **lib**: use existing `isWindows` variable (sinkhaha) [#48134](https://github.com/nodejs/node/pull/48134) +* \[[`2b65625281`](https://github.com/nodejs/node/commit/2b65625281)] - **lib**: update comment (sinkhaha) [#47884](https://github.com/nodejs/node/pull/47884) +* \[[`fa447b5120`](https://github.com/nodejs/node/commit/fa447b5120)] - **lib**: use webidl DOMString converter in EventTarget (Matthew Aitken) [#47514](https://github.com/nodejs/node/pull/47514) +* \[[`33f32dc318`](https://github.com/nodejs/node/commit/33f32dc318)] - **lib**: define Event.isTrusted in the prototype (Santiago Gimeno) [#46974](https://github.com/nodejs/node/pull/46974) +* \[[`50789a5e4a`](https://github.com/nodejs/node/commit/50789a5e4a)] - **lib**: refactor to use `validateBuffer` (Deokjin Kim) [#46489](https://github.com/nodejs/node/pull/46489) +* \[[`3658abea26`](https://github.com/nodejs/node/commit/3658abea26)] - **(SEMVER-MINOR)** **lib**: add webstreams to Duplex.from() (Debadree Chatterjee) [#46190](https://github.com/nodejs/node/pull/46190) +* \[[`fcf3781d22`](https://github.com/nodejs/node/commit/fcf3781d22)] - **lib,src,test**: lint codebase according new rules for v18.x (Juan José Arboleda) [#48697](https://github.com/nodejs/node/pull/48697) +* \[[`b55dc53422`](https://github.com/nodejs/node/commit/b55dc53422)] - **meta**: bump github/codeql-action from 2.3.3 to 2.3.6 (dependabot\[bot]) [#48287](https://github.com/nodejs/node/pull/48287) +* \[[`8ac4579d85`](https://github.com/nodejs/node/commit/8ac4579d85)] - **meta**: bump actions/setup-python from 4.6.0 to 4.6.1 (dependabot\[bot]) [#48286](https://github.com/nodejs/node/pull/48286) +* \[[`b1854fe9c1`](https://github.com/nodejs/node/commit/b1854fe9c1)] - **meta**: bump codecov/codecov-action from 3.1.3 to 3.1.4 (dependabot\[bot]) [#48285](https://github.com/nodejs/node/pull/48285) +* \[[`d9448b8d93`](https://github.com/nodejs/node/commit/d9448b8d93)] - **meta**: remove dont-land-on-v14 auto labeling (Shrujal Shah) [#48031](https://github.com/nodejs/node/pull/48031) +* \[[`bb859768b6`](https://github.com/nodejs/node/commit/bb859768b6)] - **meta**: move one or more collaborators to emeritus (Node.js GitHub Bot) [#48010](https://github.com/nodejs/node/pull/48010) +* \[[`af90fb939b`](https://github.com/nodejs/node/commit/af90fb939b)] - **meta**: bump step-security/harden-runner from 2.3.1 to 2.4.0 (Rich Trott) [#47980](https://github.com/nodejs/node/pull/47980) +* \[[`4dcf5e2052`](https://github.com/nodejs/node/commit/4dcf5e2052)] - **meta**: bump github/codeql-action from 2.3.2 to 2.3.3 (Rich Trott) [#47979](https://github.com/nodejs/node/pull/47979) +* \[[`dab3186ea2`](https://github.com/nodejs/node/commit/dab3186ea2)] - **meta**: bump actions/setup-python from 4.5.0 to 4.6.0 (Rich Trott) [#47968](https://github.com/nodejs/node/pull/47968) +* \[[`546224c13c`](https://github.com/nodejs/node/commit/546224c13c)] - **meta**: add security-wg ping to permission.js (Rafael Gonzaga) [#47941](https://github.com/nodejs/node/pull/47941) +* \[[`353dfbd2d6`](https://github.com/nodejs/node/commit/353dfbd2d6)] - **meta**: bump step-security/harden-runner from 2.2.1 to 2.3.1 (dependabot\[bot]) [#47808](https://github.com/nodejs/node/pull/47808) +* \[[`20a5cc27ec`](https://github.com/nodejs/node/commit/20a5cc27ec)] - **meta**: bump actions/setup-python from 4.5.0 to 4.6.0 (dependabot\[bot]) [#47806](https://github.com/nodejs/node/pull/47806) +* \[[`eef6442d8d`](https://github.com/nodejs/node/commit/eef6442d8d)] - **meta**: bump actions/checkout from 3.3.0 to 3.5.2 (dependabot\[bot]) [#47805](https://github.com/nodejs/node/pull/47805) +* \[[`e30e6a718a`](https://github.com/nodejs/node/commit/e30e6a718a)] - **meta**: remove extra space in scorecard workflow (Mestery) [#47805](https://github.com/nodejs/node/pull/47805) +* \[[`2d13cdebc4`](https://github.com/nodejs/node/commit/2d13cdebc4)] - **meta**: bump github/codeql-action from 2.2.9 to 2.3.2 (dependabot\[bot]) [#47809](https://github.com/nodejs/node/pull/47809) +* \[[`f0d8352ed8`](https://github.com/nodejs/node/commit/f0d8352ed8)] - **meta**: bump codecov/codecov-action from 3.1.1 to 3.1.3 (dependabot\[bot]) [#47807](https://github.com/nodejs/node/pull/47807) +* \[[`7e95fba0ff`](https://github.com/nodejs/node/commit/7e95fba0ff)] - **meta**: fix dependabot commit message (Mestery) [#47810](https://github.com/nodejs/node/pull/47810) +* \[[`d31d9c7c28`](https://github.com/nodejs/node/commit/d31d9c7c28)] - **meta**: ping nodejs/startup for startup test changes (Joyee Cheung) [#47771](https://github.com/nodejs/node/pull/47771) +* \[[`077686055b`](https://github.com/nodejs/node/commit/077686055b)] - **meta**: add mailmap entry for KhafraDev (Rich Trott) [#47512](https://github.com/nodejs/node/pull/47512) +* \[[`e50eb6570a`](https://github.com/nodejs/node/commit/e50eb6570a)] - **meta**: ping security-wg team on permission model changes (Rafael Gonzaga) [#47483](https://github.com/nodejs/node/pull/47483) +* \[[`2df1a36214`](https://github.com/nodejs/node/commit/2df1a36214)] - **meta**: ping startup and realm team on src/node\_realm\* changes (Joyee Cheung) [#47448](https://github.com/nodejs/node/pull/47448) +* \[[`c7dc6e321b`](https://github.com/nodejs/node/commit/c7dc6e321b)] - **meta**: fix notable-change comment label url (Filip Skokan) [#47300](https://github.com/nodejs/node/pull/47300) +* \[[`e859ca44d5`](https://github.com/nodejs/node/commit/e859ca44d5)] - **meta**: clarify the threat model to explain the JSON.parse case (Matteo Collina) [#47276](https://github.com/nodejs/node/pull/47276) +* \[[`1f08f4848d`](https://github.com/nodejs/node/commit/1f08f4848d)] - **meta**: update link to collaborators discussion page (Michaël Zasso) [#47211](https://github.com/nodejs/node/pull/47211) +* \[[`3b524cbf86`](https://github.com/nodejs/node/commit/3b524cbf86)] - **meta**: automate description requests when notable change label is added (Danielle Adams) [#47078](https://github.com/nodejs/node/pull/47078) +* \[[`da16ca7c59`](https://github.com/nodejs/node/commit/da16ca7c59)] - **meta**: move TSC voting member(s) to regular member(s) (Node.js GitHub Bot) [#47180](https://github.com/nodejs/node/pull/47180) +* \[[`0c80e60d7e`](https://github.com/nodejs/node/commit/0c80e60d7e)] - **meta**: move TSC voting member to regular membership (Node.js GitHub Bot) [#46985](https://github.com/nodejs/node/pull/46985) +* \[[`0edcfed895`](https://github.com/nodejs/node/commit/0edcfed895)] - **meta**: update GOVERNANCE.md to reflect TSC charter changes (Rich Trott) [#47126](https://github.com/nodejs/node/pull/47126) +* \[[`baada5d035`](https://github.com/nodejs/node/commit/baada5d035)] - **meta**: ask expected behavior reason in bug template (Ben Noordhuis) [#47049](https://github.com/nodejs/node/pull/47049) +* \[[`5d75ec402e`](https://github.com/nodejs/node/commit/5d75ec402e)] - **module**: reduce the number of URL initializations (Yagiz Nizipli) [#48272](https://github.com/nodejs/node/pull/48272) +* \[[`c5af5a4f4f`](https://github.com/nodejs/node/commit/c5af5a4f4f)] - **module**: change default resolver to not throw on unknown scheme (Gil Tayar) [#47824](https://github.com/nodejs/node/pull/47824) +* \[[`cf8845d001`](https://github.com/nodejs/node/commit/cf8845d001)] - **module**: block requiring `test/reporters` without scheme (Moshe Atlow) [#47831](https://github.com/nodejs/node/pull/47831) +* \[[`ce7e6c6765`](https://github.com/nodejs/node/commit/ce7e6c6765)] - **(SEMVER-MINOR)** **node-api**: define version 9 (Chengzhong Wu) [#48151](https://github.com/nodejs/node/pull/48151) +* \[[`53c02b20b8`](https://github.com/nodejs/node/commit/53c02b20b8)] - **node-api**: add status napi\_cannot\_run\_js (Gabriel Schulhof) [#47986](https://github.com/nodejs/node/pull/47986) +* \[[`4b280d5361`](https://github.com/nodejs/node/commit/4b280d5361)] - **node-api**: napi\_ref on all types is experimental (Vladimir Morozov) [#47975](https://github.com/nodejs/node/pull/47975) +* \[[`e2553b12e7`](https://github.com/nodejs/node/commit/e2553b12e7)] - **(NODE-API-SEMVER-MAJOR)** **node-api**: get Node API version used by addon (Vladimir Morozov) [#45715](https://github.com/nodejs/node/pull/45715) +* \[[`beaad7f692`](https://github.com/nodejs/node/commit/beaad7f692)] - **node-api**: test passing NULL to napi\_define\_class (Gabriel Schulhof) [#47567](https://github.com/nodejs/node/pull/47567) +* \[[`6ab892780c`](https://github.com/nodejs/node/commit/6ab892780c)] - **node-api**: test passing NULL to number APIs (Gabriel Schulhof) [#47549](https://github.com/nodejs/node/pull/47549) +* \[[`a67e5ea89c`](https://github.com/nodejs/node/commit/a67e5ea89c)] - **node-api**: remove unused mark\_arraybuffer\_as\_untransferable (Chengzhong Wu) [#47557](https://github.com/nodejs/node/pull/47557) +* \[[`7019d48ba1`](https://github.com/nodejs/node/commit/7019d48ba1)] - **(SEMVER-MINOR)** **node-api**: deprecate napi\_module\_register (Vladimir Morozov) [#46319](https://github.com/nodejs/node/pull/46319) +* \[[`395c56bd7c`](https://github.com/nodejs/node/commit/395c56bd7c)] - **node-api**: extend type-tagging to externals (Gabriel Schulhof) [#47141](https://github.com/nodejs/node/pull/47141) +* \[[`6e66371eee`](https://github.com/nodejs/node/commit/6e66371eee)] - **node-api**: document node-api shutdown finalization (Chengzhong Wu) [#45903](https://github.com/nodejs/node/pull/45903) +* \[[`d8d2d33efb`](https://github.com/nodejs/node/commit/d8d2d33efb)] - **node-api**: verify cleanup hooks order (Chengzhong Wu) [#46692](https://github.com/nodejs/node/pull/46692) +* \[[`b34eaf393e`](https://github.com/nodejs/node/commit/b34eaf393e)] - **path**: indicate index of wrong resolve() parameter (sosoba) [#47660](https://github.com/nodejs/node/pull/47660) +* \[[`13bc5488a1`](https://github.com/nodejs/node/commit/13bc5488a1)] - **permission**: remove unused function declaration (Deokjin Kim) [#47957](https://github.com/nodejs/node/pull/47957) +* \[[`5f8aef477e`](https://github.com/nodejs/node/commit/5f8aef477e)] - **quic**: address recent coverity warning (Michael Dawson) [#47753](https://github.com/nodejs/node/pull/47753) +* \[[`75d7024ecd`](https://github.com/nodejs/node/commit/75d7024ecd)] - **quic**: add more QUIC implementation (James M Snell) [#47494](https://github.com/nodejs/node/pull/47494) +* \[[`24840832bd`](https://github.com/nodejs/node/commit/24840832bd)] - **quic**: add more QUIC impl (James M Snell) [#47348](https://github.com/nodejs/node/pull/47348) +* \[[`114b8479b4`](https://github.com/nodejs/node/commit/114b8479b4)] - **readline**: fix issue with newline-less last line (Ian Harris) [#47317](https://github.com/nodejs/node/pull/47317) +* \[[`e668efac6b`](https://github.com/nodejs/node/commit/e668efac6b)] - **repl**: preserve preview on ESCAPE key press (Xuguang Mei) [#46878](https://github.com/nodejs/node/pull/46878) +* \[[`7306b0f733`](https://github.com/nodejs/node/commit/7306b0f733)] - **sea**: fix memory leak detected by asan (Darshan Sen) [#47309](https://github.com/nodejs/node/pull/47309) +* \[[`1f2c91f98a`](https://github.com/nodejs/node/commit/1f2c91f98a)] - **src**: use std::array for passing argv in node::url (Anna Henningsen) [#47035](https://github.com/nodejs/node/pull/47035) +* \[[`36bf06904f`](https://github.com/nodejs/node/commit/36bf06904f)] - **src**: add Realm document in the src README.md (Chengzhong Wu) [#47932](https://github.com/nodejs/node/pull/47932) +* \[[`5445835671`](https://github.com/nodejs/node/commit/5445835671)] - **src**: check node\_extra\_ca\_certs after openssl cfg (Raghu Saxena) [#48159](https://github.com/nodejs/node/pull/48159) +* \[[`eb96856555`](https://github.com/nodejs/node/commit/eb96856555)] - **src**: include missing header in node\_sea.h (Joyee Cheung) [#48152](https://github.com/nodejs/node/pull/48152) +* \[[`2a35462045`](https://github.com/nodejs/node/commit/2a35462045)] - **src**: deduplicate X509Certificate::Fingerprint\* (Tobias Nießen) [#47978](https://github.com/nodejs/node/pull/47978) +* \[[`4c556816bd`](https://github.com/nodejs/node/commit/4c556816bd)] - **src**: move BlobSerializerDeserializer to a separate header file (Darshan Sen) [#47933](https://github.com/nodejs/node/pull/47933) +* \[[`4bad757012`](https://github.com/nodejs/node/commit/4bad757012)] - **src**: rename SKIP\_CHECK\_SIZE to SKIP\_CHECK\_STRLEN (Tobias Nießen) [#47845](https://github.com/nodejs/node/pull/47845) +* \[[`33daa89dac`](https://github.com/nodejs/node/commit/33daa89dac)] - **src**: register ext reference for Fingerprint512 (Tobias Nießen) [#47892](https://github.com/nodejs/node/pull/47892) +* \[[`30b7133008`](https://github.com/nodejs/node/commit/30b7133008)] - **src**: clarify the parameter name in `Permission::Apply` (Daeyeon Jeong) [#47874](https://github.com/nodejs/node/pull/47874) +* \[[`274c0f2e0a`](https://github.com/nodejs/node/commit/274c0f2e0a)] - **src**: avoid strcmp() with Utf8Value (Tobias Nießen) [#47827](https://github.com/nodejs/node/pull/47827) +* \[[`559c98f468`](https://github.com/nodejs/node/commit/559c98f468)] - **src**: prefer data accessor of string and vector (Mohammed Keyvanzadeh) [#47750](https://github.com/nodejs/node/pull/47750) +* \[[`933673de61`](https://github.com/nodejs/node/commit/933673de61)] - **src**: avoid copying string in fs\_permission (Yagiz Nizipli) [#47746](https://github.com/nodejs/node/pull/47746) +* \[[`77f2b97197`](https://github.com/nodejs/node/commit/77f2b97197)] - **src**: fix typo in comment in quic/sessionticket.cc (Tobias Nießen) [#47754](https://github.com/nodejs/node/pull/47754) +* \[[`8e6af9fcf4`](https://github.com/nodejs/node/commit/8e6af9fcf4)] - **src**: mark fatal error functions as noreturn (Chengzhong Wu) [#47695](https://github.com/nodejs/node/pull/47695) +* \[[`d0ad873b0e`](https://github.com/nodejs/node/commit/d0ad873b0e)] - **src**: prevent changing FunctionTemplateInfo after publish (Shelley Vohr) [#46979](https://github.com/nodejs/node/pull/46979) +* \[[`71fb476781`](https://github.com/nodejs/node/commit/71fb476781)] - **src**: use v8::Boolean(b) over b ? True() : False() (Tobias Nießen) [#47554](https://github.com/nodejs/node/pull/47554) +* \[[`175b78bc02`](https://github.com/nodejs/node/commit/175b78bc02)] - **src**: fix typo in process.env accessor error message (Moritz Raho) [#47014](https://github.com/nodejs/node/pull/47014) +* \[[`2c2b6d1661`](https://github.com/nodejs/node/commit/2c2b6d1661)] - **src**: replace static const string\_view by static constexpr (Daniel Lemire) [#47524](https://github.com/nodejs/node/pull/47524) +* \[[`3840bb586e`](https://github.com/nodejs/node/commit/3840bb586e)] - **src**: fix CSPRNG when length exceeds INT\_MAX (Tobias Nießen) [#47515](https://github.com/nodejs/node/pull/47515) +* \[[`f6aa38dc5f`](https://github.com/nodejs/node/commit/f6aa38dc5f)] - **src**: use correct variable in node\_builtins.cc (Michaël Zasso) [#47343](https://github.com/nodejs/node/pull/47343) +* \[[`e88e249838`](https://github.com/nodejs/node/commit/e88e249838)] - **src**: slim down stream\_base-inl.h (lilsweetcaligula) [#46972](https://github.com/nodejs/node/pull/46972) +* \[[`b34de64442`](https://github.com/nodejs/node/commit/b34de64442)] - **src**: allow simdutf::convert\_\* functions to return zero (Daniel Lemire) [#47471](https://github.com/nodejs/node/pull/47471) +* \[[`ded4a5eb8f`](https://github.com/nodejs/node/commit/ded4a5eb8f)] - **src**: remove usage of `std::shared_ptr::unique()` (Darshan Sen) [#47315](https://github.com/nodejs/node/pull/47315) +* \[[`0fbfb28cf5`](https://github.com/nodejs/node/commit/0fbfb28cf5)] - **src**: use stricter compile-time guidance (Tobias Nießen) [#46509](https://github.com/nodejs/node/pull/46509) +* \[[`a8430ad211`](https://github.com/nodejs/node/commit/a8430ad211)] - **src**: remove unused variable in crypto\_x509.cc (Michaël Zasso) [#47344](https://github.com/nodejs/node/pull/47344) +* \[[`24dabf8965`](https://github.com/nodejs/node/commit/24dabf8965)] - **src**: don't reset embeder signal handlers (Dmitry Vyukov) [#47188](https://github.com/nodejs/node/pull/47188) +* \[[`4add36872c`](https://github.com/nodejs/node/commit/4add36872c)] - **src**: replace impossible THROW with CHECK (Tobias Nießen) [#47168](https://github.com/nodejs/node/pull/47168) +* \[[`e1007ff6a8`](https://github.com/nodejs/node/commit/e1007ff6a8)] - **src**: remove dead comments about return\_code\_cache (Keyhan Vakil) [#47083](https://github.com/nodejs/node/pull/47083) +* \[[`5501d12713`](https://github.com/nodejs/node/commit/5501d12713)] - **src**: remove SSL\_CTX\_get\_tlsext\_ticket\_keys guards (Tobias Nießen) [#47068](https://github.com/nodejs/node/pull/47068) +* \[[`716d289874`](https://github.com/nodejs/node/commit/716d289874)] - **src**: fix clang 14 linker error (Keyhan Vakil) [#47057](https://github.com/nodejs/node/pull/47057) +* \[[`8809adfdb6`](https://github.com/nodejs/node/commit/8809adfdb6)] - **src**: clarify OptionEnvvarSettings member names (Chengzhong Wu) [#45057](https://github.com/nodejs/node/pull/45057) +* \[[`05f5c79574`](https://github.com/nodejs/node/commit/05f5c79574)] - **src**: per-realm binding data (Chengzhong Wu) [#46556](https://github.com/nodejs/node/pull/46556) +* \[[`a7620d19c8`](https://github.com/nodejs/node/commit/a7620d19c8)] - **src,http2**: ensure cleanup if a frame is not sent (ywave620) [#47244](https://github.com/nodejs/node/pull/47244) +* \[[`585d62848e`](https://github.com/nodejs/node/commit/585d62848e)] - **stream**: deprecate asIndexedPairs (Chemi Atlow) [#48102](https://github.com/nodejs/node/pull/48102) +* \[[`d3449ca010`](https://github.com/nodejs/node/commit/d3449ca010)] - **stream**: prevent pipeline hang with generator functions (Debadree Chatterjee) [#47712](https://github.com/nodejs/node/pull/47712) +* \[[`5e4b2434a6`](https://github.com/nodejs/node/commit/5e4b2434a6)] - **(SEMVER-MINOR)** **stream**: preserve object mode in compose (Raz Luvaton) [#47413](https://github.com/nodejs/node/pull/47413) +* \[[`912eb308ab`](https://github.com/nodejs/node/commit/912eb308ab)] - **(SEMVER-MINOR)** **stream**: add setter & getter for default highWaterMark (#46929) (Robert Nagy) [#46929](https://github.com/nodejs/node/pull/46929) +* \[[`c59887744a`](https://github.com/nodejs/node/commit/c59887744a)] - **stream**: expose stream symbols (Robert Nagy) [#45671](https://github.com/nodejs/node/pull/45671) +* \[[`4edc1abf0b`](https://github.com/nodejs/node/commit/4edc1abf0b)] - **stream**: dont wait for next item in take when finished (Raz Luvaton) [#47132](https://github.com/nodejs/node/pull/47132) +* \[[`cfb18d816d`](https://github.com/nodejs/node/commit/cfb18d816d)] - **stream**: remove brandchecks from stream duplexify (Debadree Chatterjee) [#46315](https://github.com/nodejs/node/pull/46315) +* \[[`9d4025c411`](https://github.com/nodejs/node/commit/9d4025c411)] - **test**: mark test-child-process-pipe-dataflow as flaky (Moshe Atlow) [#48334](https://github.com/nodejs/node/pull/48334) +* \[[`c29b6874d4`](https://github.com/nodejs/node/commit/c29b6874d4)] - **test**: unflake test-vm-timeout-escape-nexttick (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`0e3312b01b`](https://github.com/nodejs/node/commit/0e3312b01b)] - **test**: fix zlib version regex (Luigi Pinca) [#48227](https://github.com/nodejs/node/pull/48227) +* \[[`a9d0b8d005`](https://github.com/nodejs/node/commit/a9d0b8d005)] - **test**: use lower security level in s\_client (Luigi Pinca) [#48192](https://github.com/nodejs/node/pull/48192) +* \[[`7250d8c2f1`](https://github.com/nodejs/node/commit/7250d8c2f1)] - _**Revert**_ "**test**: unskip negative-settimeout.any.js WPT" (Filip Skokan) [#48182](https://github.com/nodejs/node/pull/48182) +* \[[`18476697bd`](https://github.com/nodejs/node/commit/18476697bd)] - **test**: mark test\_cannot\_run\_js as flaky (Keyhan Vakil) [#48181](https://github.com/nodejs/node/pull/48181) +* \[[`446f6118ff`](https://github.com/nodejs/node/commit/446f6118ff)] - **test**: fix flaky test-runner-watch-mode (Moshe Atlow) [#48144](https://github.com/nodejs/node/pull/48144) +* \[[`7fa144e3fe`](https://github.com/nodejs/node/commit/7fa144e3fe)] - **test**: skip test-http-pipeline-flood on IBM i (Abdirahim Musse) [#48048](https://github.com/nodejs/node/pull/48048) +* \[[`5c5b1d2867`](https://github.com/nodejs/node/commit/5c5b1d2867)] - **test**: ignore helper files in WPTs (Filip Skokan) [#48079](https://github.com/nodejs/node/pull/48079) +* \[[`3b2cee071b`](https://github.com/nodejs/node/commit/3b2cee071b)] - **test**: move `test-cluster-primary-error` flaky test (Yagiz Nizipli) [#48039](https://github.com/nodejs/node/pull/48039) +* \[[`7b816b4922`](https://github.com/nodejs/node/commit/7b816b4922)] - **test**: fix suite signal (Benjamin Gruenbaum) [#47800](https://github.com/nodejs/node/pull/47800) +* \[[`ca4a0e3717`](https://github.com/nodejs/node/commit/ca4a0e3717)] - **test**: fix parsing test flags (Daeyeon Jeong) [#48012](https://github.com/nodejs/node/pull/48012) +* \[[`a3f0504556`](https://github.com/nodejs/node/commit/a3f0504556)] - **test**: mark test-esm-loader-http-imports as flaky (Tobias Nießen) [#47987](https://github.com/nodejs/node/pull/47987) +* \[[`ab36a30143`](https://github.com/nodejs/node/commit/ab36a30143)] - **test**: unskip negative-settimeout.any.js WPT (Filip Skokan) [#47946](https://github.com/nodejs/node/pull/47946) +* \[[`7c80439b21`](https://github.com/nodejs/node/commit/7c80439b21)] - **test**: use appropriate usages for a negative import test (Filip Skokan) [#47878](https://github.com/nodejs/node/pull/47878) +* \[[`81d8d95ba0`](https://github.com/nodejs/node/commit/81d8d95ba0)] - **test**: fix webcrypto wrap unwrap tests (Filip Skokan) [#47876](https://github.com/nodejs/node/pull/47876) +* \[[`1b84e85576`](https://github.com/nodejs/node/commit/1b84e85576)] - **test**: fix output tests when path includes node version (Moshe Atlow) [#47843](https://github.com/nodejs/node/pull/47843) +* \[[`95972aac8d`](https://github.com/nodejs/node/commit/95972aac8d)] - **test**: migrate a pseudo\_tty test to use assertSnapshot (Moshe Atlow) [#47803](https://github.com/nodejs/node/pull/47803) +* \[[`f1e131283d`](https://github.com/nodejs/node/commit/f1e131283d)] - **test**: fix WPT state when process exits but workers are still running (Filip Skokan) [#47826](https://github.com/nodejs/node/pull/47826) +* \[[`03dcf7bc94`](https://github.com/nodejs/node/commit/03dcf7bc94)] - **test**: migrate message tests to use assertSnapshot (Moshe Atlow) [#47498](https://github.com/nodejs/node/pull/47498) +* \[[`dedbeee336`](https://github.com/nodejs/node/commit/dedbeee336)] - **test**: refactor to use `getEventListeners` in timers (Deokjin Kim) [#47759](https://github.com/nodejs/node/pull/47759) +* \[[`11a2d1c4e4`](https://github.com/nodejs/node/commit/11a2d1c4e4)] - **test**: add and use tmpdir.hasEnoughSpace() (Tobias Nießen) [#47767](https://github.com/nodejs/node/pull/47767) +* \[[`d669714e57`](https://github.com/nodejs/node/commit/d669714e57)] - **test**: remove spaces from test runner test names (Tobias Nießen) [#47733](https://github.com/nodejs/node/pull/47733) +* \[[`3a9c43a6d7`](https://github.com/nodejs/node/commit/3a9c43a6d7)] - **test**: mark test-cluster-primary-error flaky on asan (Yagiz Nizipli) [#47422](https://github.com/nodejs/node/pull/47422) +* \[[`bd1eb14cb0`](https://github.com/nodejs/node/commit/bd1eb14cb0)] - **test**: remove unnecessary status check on test-release-npm (RafaelGSS) [#47516](https://github.com/nodejs/node/pull/47516) +* \[[`914f68d953`](https://github.com/nodejs/node/commit/914f68d953)] - **test**: mark test/parallel/test-file-write-stream4 as flaky (Yagiz Nizipli) [#47423](https://github.com/nodejs/node/pull/47423) +* \[[`7c4178cb11`](https://github.com/nodejs/node/commit/7c4178cb11)] - **test**: remove unused callback variables (angellovc) [#47167](https://github.com/nodejs/node/pull/47167) +* \[[`d0bda902dc`](https://github.com/nodejs/node/commit/d0bda902dc)] - **test**: migrate test runner message tests to snapshot (Moshe Atlow) [#47392](https://github.com/nodejs/node/pull/47392) +* \[[`095ca5ccf2`](https://github.com/nodejs/node/commit/095ca5ccf2)] - **test**: remove stale entry from known\_issues.status (Richard Lau) [#47454](https://github.com/nodejs/node/pull/47454) +* \[[`8820d5415b`](https://github.com/nodejs/node/commit/8820d5415b)] - **test**: move more inspector sequential tests to parallel (Joyee Cheung) [#47412](https://github.com/nodejs/node/pull/47412) +* \[[`f6ef5c4ad3`](https://github.com/nodejs/node/commit/f6ef5c4ad3)] - **test**: use random port in test-inspector-enabled (Joyee Cheung) [#47412](https://github.com/nodejs/node/pull/47412) +* \[[`e97ceeca69`](https://github.com/nodejs/node/commit/e97ceeca69)] - **test**: use random port in test-inspector-debug-brk-flag (Joyee Cheung) [#47412](https://github.com/nodejs/node/pull/47412) +* \[[`a2e4643981`](https://github.com/nodejs/node/commit/a2e4643981)] - **test**: use random port in NodeInstance.startViaSignal() (Joyee Cheung) [#47412](https://github.com/nodejs/node/pull/47412) +* \[[`a779261732`](https://github.com/nodejs/node/commit/a779261732)] - **test**: fix flaky test-watch-mode-inspect (Moshe Atlow) [#47403](https://github.com/nodejs/node/pull/47403) +* \[[`116df2ad3e`](https://github.com/nodejs/node/commit/116df2ad3e)] - **test**: move debugger tests with --port=0 to parallel (Joyee Cheung) [#47274](https://github.com/nodejs/node/pull/47274) +* \[[`016b8bd27d`](https://github.com/nodejs/node/commit/016b8bd27d)] - **test**: use --port=0 in debugger tests that do not have to work on 9229 (Joyee Cheung) [#47274](https://github.com/nodejs/node/pull/47274) +* \[[`3c157cb7a3`](https://github.com/nodejs/node/commit/3c157cb7a3)] - **test**: run doctool tests in parallel (Joyee Cheung) [#47273](https://github.com/nodejs/node/pull/47273) +* \[[`44f08ed941`](https://github.com/nodejs/node/commit/44f08ed941)] - **test**: move test-shadow-realm-gc.js to known\_issues (Joyee Cheung) [#47355](https://github.com/nodejs/node/pull/47355) +* \[[`e2b5d968c3`](https://github.com/nodejs/node/commit/e2b5d968c3)] - **test**: update wasm/jsapi WPT (Michaël Zasso) [#47210](https://github.com/nodejs/node/pull/47210) +* \[[`53d9eb5950`](https://github.com/nodejs/node/commit/53d9eb5950)] - **test**: skip test-wasm-web-api on ARM (Michaël Zasso) [#47299](https://github.com/nodejs/node/pull/47299) +* \[[`b620f5fcd6`](https://github.com/nodejs/node/commit/b620f5fcd6)] - **test**: skip instantiateStreaming-bad-imports WPT (Michaël Zasso) [#47292](https://github.com/nodejs/node/pull/47292) +* \[[`1e6fe56333`](https://github.com/nodejs/node/commit/1e6fe56333)] - **test**: fix test-child-process-exec-cwd (Stefan Stojanovic) [#47235](https://github.com/nodejs/node/pull/47235) +* \[[`0dc4971aab`](https://github.com/nodejs/node/commit/0dc4971aab)] - **test**: skip broken tests win arm64 (Stefan Stojanovic) [#47020](https://github.com/nodejs/node/pull/47020) +* \[[`6fee6050e3`](https://github.com/nodejs/node/commit/6fee6050e3)] - **test**: fix 'checks' validation test for checkPrime (Tobias Nießen) [#47139](https://github.com/nodejs/node/pull/47139) +* \[[`6b85472f01`](https://github.com/nodejs/node/commit/6b85472f01)] - **test**: update URL web-platform-tests (Yagiz Nizipli) [#47135](https://github.com/nodejs/node/pull/47135) +* \[[`732a98e1ba`](https://github.com/nodejs/node/commit/732a98e1ba)] - **test**: reduce flakiness of test-http-remove-header-stays-removed.js (Debadree Chatterjee) [#46855](https://github.com/nodejs/node/pull/46855) +* \[[`713b412ee9`](https://github.com/nodejs/node/commit/713b412ee9)] - **test**: mark test-http-max-sockets as flaky on win32 (Tobias Nießen) [#47134](https://github.com/nodejs/node/pull/47134) +* \[[`b3b7dbc395`](https://github.com/nodejs/node/commit/b3b7dbc395)] - **test**: update web-platform tests for url (Xuguang Mei) [#46860](https://github.com/nodejs/node/pull/46860) +* \[[`2edd0fdb5b`](https://github.com/nodejs/node/commit/2edd0fdb5b)] - **test**: mark test-child-process-stdio-reuse-readable-stdio flaky (Luigi Pinca) [#48537](https://github.com/nodejs/node/pull/48537) +* \[[`fae240e492`](https://github.com/nodejs/node/commit/fae240e492)] - **test**: mark test-child-process-pipe-dataflow as flaky (Moshe Atlow) [#48334](https://github.com/nodejs/node/pull/48334) +* \[[`9ca3cc0f2a`](https://github.com/nodejs/node/commit/9ca3cc0f2a)] - **test**: remove useless require('../common') from WPTs (Filip Skokan) [#46796](https://github.com/nodejs/node/pull/46796) +* \[[`4bece055a5`](https://github.com/nodejs/node/commit/4bece055a5)] - **test,crypto**: update WebCryptoAPI WPT (Filip Skokan) [#47921](https://github.com/nodejs/node/pull/47921) +* \[[`7ef169b706`](https://github.com/nodejs/node/commit/7ef169b706)] - **test,crypto**: update WebCryptoAPI WPT (Filip Skokan) [#47222](https://github.com/nodejs/node/pull/47222) +* \[[`873606b355`](https://github.com/nodejs/node/commit/873606b355)] - **test,crypto**: update WebCryptoAPI WPT (Filip Skokan) [#47131](https://github.com/nodejs/node/pull/47131) +* \[[`8f1fc0bc99`](https://github.com/nodejs/node/commit/8f1fc0bc99)] - **test,doc,sea**: run SEA tests on ppc64 (Darshan Sen) [#48111](https://github.com/nodejs/node/pull/48111) +* \[[`5d910ca389`](https://github.com/nodejs/node/commit/5d910ca389)] - **test\_runner**: add enqueue and dequeue events (Moshe Atlow) [#48428](https://github.com/nodejs/node/pull/48428) +* \[[`d795c0ab0c`](https://github.com/nodejs/node/commit/d795c0ab0c)] - **test\_runner**: dont split lines on `test:stdout` (Moshe Atlow) [#48057](https://github.com/nodejs/node/pull/48057) +* \[[`04eb1f85da`](https://github.com/nodejs/node/commit/04eb1f85da)] - **test\_runner**: pass FORCE\_COLOR to child process (Moshe Atlow) [#48057](https://github.com/nodejs/node/pull/48057) +* \[[`2262653148`](https://github.com/nodejs/node/commit/2262653148)] - **test\_runner**: apply `runOnly` on suites (Moshe Atlow) [#48279](https://github.com/nodejs/node/pull/48279) +* \[[`033d0bb3e1`](https://github.com/nodejs/node/commit/033d0bb3e1)] - **test\_runner**: emit `test:watch:drained` event (Moshe Atlow) [#48259](https://github.com/nodejs/node/pull/48259) +* \[[`618a9e1c09`](https://github.com/nodejs/node/commit/618a9e1c09)] - **test\_runner**: stop watch mode when abortSignal aborted (Moshe Atlow) [#48259](https://github.com/nodejs/node/pull/48259) +* \[[`6a82fbd006`](https://github.com/nodejs/node/commit/6a82fbd006)] - **test\_runner**: fix global after hook (Moshe Atlow) [#48231](https://github.com/nodejs/node/pull/48231) +* \[[`d1295d7b10`](https://github.com/nodejs/node/commit/d1295d7b10)] - **test\_runner**: remove redundant check from coverage (Colin Ihrig) [#48070](https://github.com/nodejs/node/pull/48070) +* \[[`47602fe73b`](https://github.com/nodejs/node/commit/47602fe73b)] - **test\_runner**: fix test deserialize edge cases (Moshe Atlow) [#48106](https://github.com/nodejs/node/pull/48106) +* \[[`b18a78cd0b`](https://github.com/nodejs/node/commit/b18a78cd0b)] - **test\_runner**: delegate stderr and stdout formatting to reporter (Shiba) [#48045](https://github.com/nodejs/node/pull/48045) +* \[[`e0d0b19c30`](https://github.com/nodejs/node/commit/e0d0b19c30)] - **test\_runner**: display dot report as wide as the terminal width (Raz Luvaton) [#48038](https://github.com/nodejs/node/pull/48038) +* \[[`bdca468a79`](https://github.com/nodejs/node/commit/bdca468a79)] - **test\_runner**: use v8.serialize instead of TAP (Moshe Atlow) [#47867](https://github.com/nodejs/node/pull/47867) +* \[[`866ed6a887`](https://github.com/nodejs/node/commit/866ed6a887)] - **(SEMVER-MINOR)** **test\_runner**: add shorthands to `test` (Chemi Atlow) [#47909](https://github.com/nodejs/node/pull/47909) +* \[[`4737314865`](https://github.com/nodejs/node/commit/4737314865)] - **test\_runner**: fix ordering of test hooks (Phil Nash) [#47931](https://github.com/nodejs/node/pull/47931) +* \[[`ea543d95f6`](https://github.com/nodejs/node/commit/ea543d95f6)] - **test\_runner**: omit inaccessible files from coverage (Colin Ihrig) [#47850](https://github.com/nodejs/node/pull/47850) +* \[[`8398bca842`](https://github.com/nodejs/node/commit/8398bca842)] - **test\_runner**: fix --require with --experimental-loader (Moshe Atlow) [#47751](https://github.com/nodejs/node/pull/47751) +* \[[`4c0036ba1b`](https://github.com/nodejs/node/commit/4c0036ba1b)] - **(SEMVER-MINOR)** **test\_runner**: support combining coverage reports (Colin Ihrig) [#47686](https://github.com/nodejs/node/pull/47686) +* \[[`cb3abda9aa`](https://github.com/nodejs/node/commit/cb3abda9aa)] - **test\_runner**: remove no-op validation (Colin Ihrig) [#47687](https://github.com/nodejs/node/pull/47687) +* \[[`323881f60b`](https://github.com/nodejs/node/commit/323881f60b)] - **test\_runner**: fix test runner concurrency (Moshe Atlow) [#47675](https://github.com/nodejs/node/pull/47675) +* \[[`3bbb1fc990`](https://github.com/nodejs/node/commit/3bbb1fc990)] - **test\_runner**: fix test counting (Moshe Atlow) [#47675](https://github.com/nodejs/node/pull/47675) +* \[[`0ea63717ba`](https://github.com/nodejs/node/commit/0ea63717ba)] - **test\_runner**: fix nested hooks (Moshe Atlow) [#47648](https://github.com/nodejs/node/pull/47648) +* \[[`fa18b17d88`](https://github.com/nodejs/node/commit/fa18b17d88)] - **test\_runner**: add testNamePatterns to run api (atlowChemi) [#47648](https://github.com/nodejs/node/pull/47648) +* \[[`2033691bfc`](https://github.com/nodejs/node/commit/2033691bfc)] - **test\_runner**: support coverage of unnamed functions (Colin Ihrig) [#47652](https://github.com/nodejs/node/pull/47652) +* \[[`882c6127ae`](https://github.com/nodejs/node/commit/882c6127ae)] - **test\_runner**: move coverage collection to root.postRun() (Colin Ihrig) [#47651](https://github.com/nodejs/node/pull/47651) +* \[[`e97eefa538`](https://github.com/nodejs/node/commit/e97eefa538)] - **(SEMVER-MINOR)** **test\_runner**: execute before hook on test (Chemi Atlow) [#47586](https://github.com/nodejs/node/pull/47586) +* \[[`4bce39108c`](https://github.com/nodejs/node/commit/4bce39108c)] - **test\_runner**: avoid reporting parents of failing tests in summary (Moshe Atlow) [#47579](https://github.com/nodejs/node/pull/47579) +* \[[`688078b93a`](https://github.com/nodejs/node/commit/688078b93a)] - **test\_runner**: fix spec skip detection (Moshe Atlow) [#47537](https://github.com/nodejs/node/pull/47537) +* \[[`0b32a8c8a3`](https://github.com/nodejs/node/commit/0b32a8c8a3)] - **test\_runner**: color errors only when colors are available (Moshe Atlow) [#47394](https://github.com/nodejs/node/pull/47394) +* \[[`d5fc8236bf`](https://github.com/nodejs/node/commit/d5fc8236bf)] - **test\_runner**: hide failing tests title when all tests pass (Moshe Atlow) [#47370](https://github.com/nodejs/node/pull/47370) +* \[[`1d453e4d31`](https://github.com/nodejs/node/commit/1d453e4d31)] - **test\_runner**: stringify AssertError expected and actual (Moshe Atlow) [#47088](https://github.com/nodejs/node/pull/47088) +* \[[`99312a55f2`](https://github.com/nodejs/node/commit/99312a55f2)] - **test\_runner**: add code coverage support to spec reporter (Pulkit Gupta) [#46674](https://github.com/nodejs/node/pull/46674) +* \[[`2091b4718f`](https://github.com/nodejs/node/commit/2091b4718f)] - **(SEMVER-MINOR)** **test\_runner**: expose reporter for use in run api (Chemi Atlow) [#47238](https://github.com/nodejs/node/pull/47238) +* \[[`9cbf89717e`](https://github.com/nodejs/node/commit/9cbf89717e)] - **test\_runner**: report failing tests after summary (HinataKah0) [#47164](https://github.com/nodejs/node/pull/47164) +* \[[`460bcc042e`](https://github.com/nodejs/node/commit/460bcc042e)] - **test\_runner**: count nested tests (Moshe Atlow) [#47094](https://github.com/nodejs/node/pull/47094) +* \[[`c62e6b2e54`](https://github.com/nodejs/node/commit/c62e6b2e54)] - **test\_runner**: accept \x1b as a escape symbol (Debadree Chatterjee) [#47050](https://github.com/nodejs/node/pull/47050) +* \[[`ddf819f810`](https://github.com/nodejs/node/commit/ddf819f810)] - **test\_runner**: support defining test reporter in NODE\_OPTIONS (Steve Herzog) [#46688](https://github.com/nodejs/node/pull/46688) +* \[[`e049ce296a`](https://github.com/nodejs/node/commit/e049ce296a)] - **tls**: reapply servername on happy eyeballs connect (Fedor Indutny) [#48255](https://github.com/nodejs/node/pull/48255) +* \[[`19b0f244b2`](https://github.com/nodejs/node/commit/19b0f244b2)] - **tls**: accept SecureContext object in server.addContext() (HinataKah0) [#47570](https://github.com/nodejs/node/pull/47570) +* \[[`7786d7cece`](https://github.com/nodejs/node/commit/7786d7cece)] - **tools**: pin ruff version number (Rich Trott) [#48505](https://github.com/nodejs/node/pull/48505) +* \[[`a2bfe02289`](https://github.com/nodejs/node/commit/a2bfe02289)] - **tools**: remove non-existing file from CODEOWNERS file (Juan José Arboleda) [#48697](https://github.com/nodejs/node/pull/48697) +* \[[`87562c9af0`](https://github.com/nodejs/node/commit/87562c9af0)] - **tools**: update rollup lint-md-dependencies (Node.js GitHub Bot) [#48329](https://github.com/nodejs/node/pull/48329) +* \[[`1cde4a4299`](https://github.com/nodejs/node/commit/1cde4a4299)] - _**Revert**_ "**tools**: open issue when update workflow fails" (Marco Ippolito) [#48312](https://github.com/nodejs/node/pull/48312) +* \[[`361cf8cffc`](https://github.com/nodejs/node/commit/361cf8cffc)] - **tools**: don't gitignore base64 config.h (Ben Noordhuis) [#48174](https://github.com/nodejs/node/pull/48174) +* \[[`0cfdb3affa`](https://github.com/nodejs/node/commit/0cfdb3affa)] - **tools**: update LICENSE and license-builder.sh (Santiago Gimeno) [#48078](https://github.com/nodejs/node/pull/48078) +* \[[`715cf81b4a`](https://github.com/nodejs/node/commit/715cf81b4a)] - **tools**: automate histogram update (Marco Ippolito) [#48171](https://github.com/nodejs/node/pull/48171) +* \[[`d9afffab03`](https://github.com/nodejs/node/commit/d9afffab03)] - **tools**: use shasum instead of sha256sum (Luigi Pinca) [#48229](https://github.com/nodejs/node/pull/48229) +* \[[`1a5cddfc1f`](https://github.com/nodejs/node/commit/1a5cddfc1f)] - **tools**: harmonize `dep_updaters` scripts (Antoine du Hamel) [#48201](https://github.com/nodejs/node/pull/48201) +* \[[`24abe07dda`](https://github.com/nodejs/node/commit/24abe07dda)] - **tools**: log and verify sha256sum (Andrea Fassina) [#48088](https://github.com/nodejs/node/pull/48088) +* \[[`9aed8683aa`](https://github.com/nodejs/node/commit/9aed8683aa)] - **tools**: open issue when update workflow fails (Marco Ippolito) [#48018](https://github.com/nodejs/node/pull/48018) +* \[[`4c5c63fd82`](https://github.com/nodejs/node/commit/4c5c63fd82)] - **tools**: alphabetize CODEOWNERS (Rich Trott) [#48124](https://github.com/nodejs/node/pull/48124) +* \[[`9b849a7270`](https://github.com/nodejs/node/commit/9b849a7270)] - **tools**: use latest upstream commit for zlib updates (Andrea Fassina) [#48054](https://github.com/nodejs/node/pull/48054) +* \[[`e18c1258ae`](https://github.com/nodejs/node/commit/e18c1258ae)] - **tools**: add security-wg as dep updaters owner (Marco Ippolito) [#48113](https://github.com/nodejs/node/pull/48113) +* \[[`999a289dd9`](https://github.com/nodejs/node/commit/999a289dd9)] - **tools**: fix race condition when npm installing (Tobias Nießen) [#48101](https://github.com/nodejs/node/pull/48101) +* \[[`25b0033b86`](https://github.com/nodejs/node/commit/25b0033b86)] - **tools**: refloat 7 Node.js patches to cpplint.py (Rich Trott) [#48098](https://github.com/nodejs/node/pull/48098) +* \[[`87b36b3a8a`](https://github.com/nodejs/node/commit/87b36b3a8a)] - **tools**: update cpplint to 1.6.1 (Yagiz Nizipli) [#48098](https://github.com/nodejs/node/pull/48098) +* \[[`64ff6fe443`](https://github.com/nodejs/node/commit/64ff6fe443)] - **tools**: update eslint to 8.41.0 (Node.js GitHub Bot) [#48097](https://github.com/nodejs/node/pull/48097) +* \[[`739c314851`](https://github.com/nodejs/node/commit/739c314851)] - **tools**: update lint-md-dependencies (Node.js GitHub Bot) [#48096](https://github.com/nodejs/node/pull/48096) +* \[[`6674ed1901`](https://github.com/nodejs/node/commit/6674ed1901)] - **tools**: update doc to remark-parse\@10.0.2 (Node.js GitHub Bot) [#48095](https://github.com/nodejs/node/pull/48095) +* \[[`0b0818caab`](https://github.com/nodejs/node/commit/0b0818caab)] - **tools**: add debug logs (Marco Ippolito) [#48060](https://github.com/nodejs/node/pull/48060) +* \[[`168d080f40`](https://github.com/nodejs/node/commit/168d080f40)] - **tools**: fix zconf.h path (Luigi Pinca) [#48089](https://github.com/nodejs/node/pull/48089) +* \[[`ccd2795f42`](https://github.com/nodejs/node/commit/ccd2795f42)] - **tools**: update remark-preset-lint-node to 4.0.0 (Node.js GitHub Bot) [#47995](https://github.com/nodejs/node/pull/47995) +* \[[`89e068a550`](https://github.com/nodejs/node/commit/89e068a550)] - **tools**: debug log for nghttp3 (Marco Ippolito) [#47992](https://github.com/nodejs/node/pull/47992) +* \[[`3bf2bd4ec6`](https://github.com/nodejs/node/commit/3bf2bd4ec6)] - **tools**: automate icu-small update (Marco Ippolito) [#47727](https://github.com/nodejs/node/pull/47727) +* \[[`fdf9681dc0`](https://github.com/nodejs/node/commit/fdf9681dc0)] - **tools**: update lint-md-dependencies to rollup\@3.21.5 (Node.js GitHub Bot) [#47903](https://github.com/nodejs/node/pull/47903) +* \[[`52532c2cb1`](https://github.com/nodejs/node/commit/52532c2cb1)] - **tools**: update eslint to 8.40.0 (Node.js GitHub Bot) [#47906](https://github.com/nodejs/node/pull/47906) +* \[[`951cc7b624`](https://github.com/nodejs/node/commit/951cc7b624)] - **tools**: update eslint to 8.39.0 (Node.js GitHub Bot) [#47789](https://github.com/nodejs/node/pull/47789) +* \[[`706c87db50`](https://github.com/nodejs/node/commit/706c87db50)] - **tools**: fix jsdoc lint (Moshe Atlow) [#47789](https://github.com/nodejs/node/pull/47789) +* \[[`8eef5f5f5f`](https://github.com/nodejs/node/commit/8eef5f5f5f)] - **tools**: update doc to highlight.js\@11.8.0 (Node.js GitHub Bot) [#47786](https://github.com/nodejs/node/pull/47786) +* \[[`899eea6237`](https://github.com/nodejs/node/commit/899eea6237)] - **tools**: update lint-md-dependencies to rollup\@3.21.1 (Node.js GitHub Bot) [#47787](https://github.com/nodejs/node/pull/47787) +* \[[`8ca50b6ac9`](https://github.com/nodejs/node/commit/8ca50b6ac9)] - **tools**: move update-npm to dep updaters (Marco Ippolito) [#47619](https://github.com/nodejs/node/pull/47619) +* \[[`5ee554397d`](https://github.com/nodejs/node/commit/5ee554397d)] - **tools**: fix update-v8-patch cache (Marco Ippolito) [#47725](https://github.com/nodejs/node/pull/47725) +* \[[`4e0d19e1bd`](https://github.com/nodejs/node/commit/4e0d19e1bd)] - **tools**: automate v8 patch update (Marco Ippolito) [#47594](https://github.com/nodejs/node/pull/47594) +* \[[`64c3154bdf`](https://github.com/nodejs/node/commit/64c3154bdf)] - **tools**: fix skip message in update-cjs-module-lexer (Tobias Nießen) [#47701](https://github.com/nodejs/node/pull/47701) +* \[[`6535ab90d9`](https://github.com/nodejs/node/commit/6535ab90d9)] - **tools**: update lint-md-dependencies to @rollup/plugin-commonjs\@24.1.0 (Node.js GitHub Bot) [#47577](https://github.com/nodejs/node/pull/47577) +* \[[`7cfc00d072`](https://github.com/nodejs/node/commit/7cfc00d072)] - **tools**: keep PR titles/description up-to-date (Tobias Nießen) [#47621](https://github.com/nodejs/node/pull/47621) +* \[[`d6b555e2c8`](https://github.com/nodejs/node/commit/d6b555e2c8)] - **tools**: fix updating root certificates (Richard Lau) [#47607](https://github.com/nodejs/node/pull/47607) +* \[[`0d3e3ddea6`](https://github.com/nodejs/node/commit/0d3e3ddea6)] - **tools**: update PR label config (Mohammed Keyvanzadeh) [#47593](https://github.com/nodejs/node/pull/47593) +* \[[`fa52c472b8`](https://github.com/nodejs/node/commit/fa52c472b8)] - **tools**: add execution permission to uvwasi script (Mert Can Altın) [#47600](https://github.com/nodejs/node/pull/47600) +* \[[`f6955a6b0c`](https://github.com/nodejs/node/commit/f6955a6b0c)] - **tools**: add update script for googletest (Tobias Nießen) [#47482](https://github.com/nodejs/node/pull/47482) +* \[[`4e1d87e752`](https://github.com/nodejs/node/commit/4e1d87e752)] - **tools**: add option to run workflow with specific tool id (Michaël Zasso) [#47591](https://github.com/nodejs/node/pull/47591) +* \[[`e605402590`](https://github.com/nodejs/node/commit/e605402590)] - **tools**: automate zlib update (Marco Ippolito) [#47417](https://github.com/nodejs/node/pull/47417) +* \[[`b6ca57e8d0`](https://github.com/nodejs/node/commit/b6ca57e8d0)] - **tools**: add url and whatwg-url labels automatically (Yagiz Nizipli) [#47545](https://github.com/nodejs/node/pull/47545) +* \[[`d5c9bc4f8e`](https://github.com/nodejs/node/commit/d5c9bc4f8e)] - **tools**: add performance label to benchmark changes (Yagiz Nizipli) [#47545](https://github.com/nodejs/node/pull/47545) +* \[[`c5227628a9`](https://github.com/nodejs/node/commit/c5227628a9)] - **tools**: automate uvwasi dependency update (Ranieri Innocenti Spada) [#47509](https://github.com/nodejs/node/pull/47509) +* \[[`5ffdb57302`](https://github.com/nodejs/node/commit/5ffdb57302)] - **tools**: add missing pinned dependencies (Mateo Nunez) [#47346](https://github.com/nodejs/node/pull/47346) +* \[[`c7b898d4e4`](https://github.com/nodejs/node/commit/c7b898d4e4)] - **tools**: automate ngtcp2 and nghttp3 update (Marco Ippolito) [#47402](https://github.com/nodejs/node/pull/47402) +* \[[`e696a48225`](https://github.com/nodejs/node/commit/e696a48225)] - **tools**: move update-undici.sh to dep\_updaters and create maintain md (Marco Ippolito) [#47380](https://github.com/nodejs/node/pull/47380) +* \[[`056067286a`](https://github.com/nodejs/node/commit/056067286a)] - **tools**: make `js2c.py` usable for other build systems (Cheng Zhao) [#46930](https://github.com/nodejs/node/pull/46930) +* \[[`d11c6ba2eb`](https://github.com/nodejs/node/commit/d11c6ba2eb)] - **tools**: move update-acorn.sh to dep\_updaters and create maintaining md (Marco Ippolito) [#47382](https://github.com/nodejs/node/pull/47382) +* \[[`0a65c7c300`](https://github.com/nodejs/node/commit/0a65c7c300)] - **tools**: update eslint to 8.38.0 (Node.js GitHub Bot) [#47475](https://github.com/nodejs/node/pull/47475) +* \[[`60dc249cd5`](https://github.com/nodejs/node/commit/60dc249cd5)] - **tools**: update eslint to 8.38.0 (Node.js GitHub Bot) [#47475](https://github.com/nodejs/node/pull/47475) +* \[[`1271b0eded`](https://github.com/nodejs/node/commit/1271b0eded)] - **tools**: automate cjs-module-lexer dependency update (Marco Ippolito) [#47446](https://github.com/nodejs/node/pull/47446) +* \[[`26905572d4`](https://github.com/nodejs/node/commit/26905572d4)] - **tools**: fix notify-on-push Slack messages (Antoine du Hamel) [#47453](https://github.com/nodejs/node/pull/47453) +* \[[`3c62663797`](https://github.com/nodejs/node/commit/3c62663797)] - **tools**: update lint-md-dependencies to @rollup/plugin-node-resolve\@15.0.2 (Node.js GitHub Bot) [#47431](https://github.com/nodejs/node/pull/47431) +* \[[`c57dabe360`](https://github.com/nodejs/node/commit/c57dabe360)] - **tools**: add root certificate update script (Richard Lau) [#47425](https://github.com/nodejs/node/pull/47425) +* \[[`f27680e37c`](https://github.com/nodejs/node/commit/f27680e37c)] - **tools**: fix update-openssl.yml compare version (Marco Ippolito) [#47384](https://github.com/nodejs/node/pull/47384) +* \[[`35e6cf2944`](https://github.com/nodejs/node/commit/35e6cf2944)] - **tools**: use ref\_name to get branch pushed on (Debadree Chatterjee) [#47358](https://github.com/nodejs/node/pull/47358) +* \[[`28935a86f8`](https://github.com/nodejs/node/commit/28935a86f8)] - **tools**: add a at here tag for slack messages (Debadree Chatterjee) [#47358](https://github.com/nodejs/node/pull/47358) +* \[[`e1846ee4f1`](https://github.com/nodejs/node/commit/e1846ee4f1)] - **tools**: disable Codecov commit statuses (Michaël Zasso) [#47306](https://github.com/nodejs/node/pull/47306) +* \[[`d1c8229da4`](https://github.com/nodejs/node/commit/d1c8229da4)] - **tools**: update eslint to 8.37.0 (Node.js GitHub Bot) [#47333](https://github.com/nodejs/node/pull/47333) +* \[[`6ab22151c4`](https://github.com/nodejs/node/commit/6ab22151c4)] - **tools**: fix duration\_ms to be milliseconds (Moshe Atlow) [#44490](https://github.com/nodejs/node/pull/44490) +* \[[`5d46c594a7`](https://github.com/nodejs/node/commit/5d46c594a7)] - **tools**: automate brotli update (Marco Ippolito) [#47205](https://github.com/nodejs/node/pull/47205) +* \[[`d324c15227`](https://github.com/nodejs/node/commit/d324c15227)] - **tools**: fix typo in nghttp2 path (Marco Ippolito) [#47330](https://github.com/nodejs/node/pull/47330) +* \[[`b1bcdceef5`](https://github.com/nodejs/node/commit/b1bcdceef5)] - **tools**: add scorecard workflow (Mateo Nunez) [#47254](https://github.com/nodejs/node/pull/47254) +* \[[`281362bcc2`](https://github.com/nodejs/node/commit/281362bcc2)] - **tools**: pin actions by hash for auto-start-ci.yml (Gabriela Gutierrez) [#46820](https://github.com/nodejs/node/pull/46820) +* \[[`6cae1bd377`](https://github.com/nodejs/node/commit/6cae1bd377)] - **tools**: standardize base64 update (Marco Ippolito) [#47201](https://github.com/nodejs/node/pull/47201) +* \[[`a682bd0714`](https://github.com/nodejs/node/commit/a682bd0714)] - **tools**: update codecov branch (Rich Trott) [#47285](https://github.com/nodejs/node/pull/47285) +* \[[`1061e17c66`](https://github.com/nodejs/node/commit/1061e17c66)] - **tools**: standardize update-llhttp.sh (Marco Ippolito) [#47198](https://github.com/nodejs/node/pull/47198) +* \[[`9781185943`](https://github.com/nodejs/node/commit/9781185943)] - **tools**: upgrade Windows digital signature to SHA256 (Tobias Nießen) [#47206](https://github.com/nodejs/node/pull/47206) +* \[[`37638e43c5`](https://github.com/nodejs/node/commit/37638e43c5)] - **tools**: add button to copy code example to clipboard (jakecastelli) [#46928](https://github.com/nodejs/node/pull/46928) +* \[[`05cb503f02`](https://github.com/nodejs/node/commit/05cb503f02)] - **tools**: standardize update-nghttp2.sh (Marco Ippolito) [#47197](https://github.com/nodejs/node/pull/47197) +* \[[`816e215701`](https://github.com/nodejs/node/commit/816e215701)] - **tools**: fix Slack notification action (Antoine du Hamel) [#47237](https://github.com/nodejs/node/pull/47237) +* \[[`9ac01ecc59`](https://github.com/nodejs/node/commit/9ac01ecc59)] - **tools**: notify on Slack when invalid commit lands (Antoine du Hamel) [#47178](https://github.com/nodejs/node/pull/47178) +* \[[`13eb029b4f`](https://github.com/nodejs/node/commit/13eb029b4f)] - **tools**: update daily wpt actions summary (Filip Skokan) [#47138](https://github.com/nodejs/node/pull/47138) +* \[[`e0a00ebfc5`](https://github.com/nodejs/node/commit/e0a00ebfc5)] - **tools**: allow test tap output to include unicode characters (Moshe Atlow) [#47175](https://github.com/nodejs/node/pull/47175) +* \[[`fca3391d0b`](https://github.com/nodejs/node/commit/fca3391d0b)] - **tools**: update lint-md-dependencies to rollup\@3.19.1 (Node.js GitHub Bot) [#47045](https://github.com/nodejs/node/pull/47045) +* \[[`c0fd6a3721`](https://github.com/nodejs/node/commit/c0fd6a3721)] - **tools**: update eslint to 8.36.0 (Node.js GitHub Bot) [#47046](https://github.com/nodejs/node/pull/47046) +* \[[`7d971daf29`](https://github.com/nodejs/node/commit/7d971daf29)] - **tools,meta**: update README and tools to reflect changes in TSC charter (Rich Trott) [#47126](https://github.com/nodejs/node/pull/47126) +* \[[`d078d66bdc`](https://github.com/nodejs/node/commit/d078d66bdc)] - **typings**: fix syntax error in tsconfig (Mohammed Keyvanzadeh) [#47584](https://github.com/nodejs/node/pull/47584) +* \[[`889730512c`](https://github.com/nodejs/node/commit/889730512c)] - **url**: handle URL.canParse without base parameter (Yagiz Nizipli) [#47547](https://github.com/nodejs/node/pull/47547) +* \[[`0dc485eb28`](https://github.com/nodejs/node/commit/0dc485eb28)] - **url**: drop ICU requirement for parsing hostnames (Yagiz Nizipli) [#47339](https://github.com/nodejs/node/pull/47339) +* \[[`b395b16c40`](https://github.com/nodejs/node/commit/b395b16c40)] - **url**: use ada::url\_aggregator for parsing urls (Yagiz Nizipli) [#47339](https://github.com/nodejs/node/pull/47339) +* \[[`11f48e02a8`](https://github.com/nodejs/node/commit/11f48e02a8)] - **(SEMVER-MINOR)** **url**: implement URL.canParse (Matthew Aitken) [#47179](https://github.com/nodejs/node/pull/47179) +* \[[`977a8bad35`](https://github.com/nodejs/node/commit/977a8bad35)] - **url**: fix array overrun in node:url::SetArgs() (Yagiz Nizipli) [#47001](https://github.com/nodejs/node/pull/47001) +* \[[`4784e64850`](https://github.com/nodejs/node/commit/4784e64850)] - **url**: allow extension of user provided URL objects (Antoine du Hamel) [#46989](https://github.com/nodejs/node/pull/46989) +* \[[`f495cb6bf4`](https://github.com/nodejs/node/commit/f495cb6bf4)] - **url**: backport non-major changes from #46904 (Yagiz Nizipli) [#46904](https://github.com/nodejs/node/pull/46904) +* \[[`aa4f485388`](https://github.com/nodejs/node/commit/aa4f485388)] - **url**: set `formatUrl` method as no side effect (Yagiz Nizipli) [#46884](https://github.com/nodejs/node/pull/46884) +* \[[`c79e1b72f2`](https://github.com/nodejs/node/commit/c79e1b72f2)] - **url**: offload `URLSearchParams` initialization (Yagiz Nizipli) [#46867](https://github.com/nodejs/node/pull/46867) +* \[[`3db235b822`](https://github.com/nodejs/node/commit/3db235b822)] - **url**: remove unused `kFormat` from url (Yagiz Nizipli) [#46867](https://github.com/nodejs/node/pull/46867) +* \[[`b9df1a9668`](https://github.com/nodejs/node/commit/b9df1a9668)] - **url**: clean vertical alignment of docs (Robin Ury) [#48037](https://github.com/nodejs/node/pull/48037) +* \[[`9a2354d4a9`](https://github.com/nodejs/node/commit/9a2354d4a9)] - **url**: do not use object as hashmap (Timothy Gu) [#47415](https://github.com/nodejs/node/pull/47415) +* \[[`4850ba4bd4`](https://github.com/nodejs/node/commit/4850ba4bd4)] - **url**: improve URLSearchParams creation performance (Yagiz Nizipli) [#47190](https://github.com/nodejs/node/pull/47190) +* \[[`7fb1980fd9`](https://github.com/nodejs/node/commit/7fb1980fd9)] - **url**: add pending-deprecation to `url.parse()` (Yagiz Nizipli) [#47203](https://github.com/nodejs/node/pull/47203) +* \[[`b04ea5aa9b`](https://github.com/nodejs/node/commit/b04ea5aa9b)] - **url**: allow extension of user provided URL objects (Antoine du Hamel) [#46989](https://github.com/nodejs/node/pull/46989) +* \[[`972c851918`](https://github.com/nodejs/node/commit/972c851918)] - **url**: remove unnecessary call to `FunctionPrototypeBind` (Antoine du Hamel) [#46870](https://github.com/nodejs/node/pull/46870) +* \[[`87ef1b2859`](https://github.com/nodejs/node/commit/87ef1b2859)] - **util**: fix inspecting error with a throwing getter for `cause` (Antoine du Hamel) [#47163](https://github.com/nodejs/node/pull/47163) +* \[[`4729d30c1e`](https://github.com/nodejs/node/commit/4729d30c1e)] - **v8**: fix ERR\_NOT\_BUILDING\_SNAPSHOT is not a constructor (Chengzhong Wu) [#47721](https://github.com/nodejs/node/pull/47721) +* \[[`d9a68b821e`](https://github.com/nodejs/node/commit/d9a68b821e)] - **vm**: properly handle defining symbol props (Nicolas DUBIEN) [#47572](https://github.com/nodejs/node/pull/47572) +* \[[`0d0fad8f0a`](https://github.com/nodejs/node/commit/0d0fad8f0a)] - **vm**: fix crash when setting \_\_proto\_\_ on context's globalThis (Feng Yu) [#47939](https://github.com/nodejs/node/pull/47939) +* \[[`fb90b6b3fb`](https://github.com/nodejs/node/commit/fb90b6b3fb)] - **vm**: properly handle defining props on any value (Nicolas DUBIEN) [#46615](https://github.com/nodejs/node/pull/46615) +* \[[`4b2aa3d27c`](https://github.com/nodejs/node/commit/4b2aa3d27c)] - **vm,lib**: refactor microtaskQueue assignment logic (Khaidi Chu) [#47765](https://github.com/nodejs/node/pull/47765) +* \[[`58afcc27f6`](https://github.com/nodejs/node/commit/58afcc27f6)] - **(SEMVER-MINOR)** **wasi**: no longer require flag to enable wasi (Michael Dawson) [#47286](https://github.com/nodejs/node/pull/47286) +* \[[`407af51cf5`](https://github.com/nodejs/node/commit/407af51cf5)] - **wasi**: add wasi sock\_accept stub (Michael Dawson) [#46434](https://github.com/nodejs/node/pull/46434) +* \[[`d3e0229948`](https://github.com/nodejs/node/commit/d3e0229948)] - **watch**: fix watch path with equals (Moshe Atlow) [#47369](https://github.com/nodejs/node/pull/47369) +* \[[`78972d4696`](https://github.com/nodejs/node/commit/78972d4696)] - **worker**: support more cases when (de)serializing errors (Moshe Atlow) [#47925](https://github.com/nodejs/node/pull/47925) + ## 2023-06-20, Version 18.16.1 'Hydrogen' (LTS), @RafaelGSS diff --git a/doc/changelogs/CHANGELOG_V20.md b/doc/changelogs/CHANGELOG_V20.md index 9a9f76334017bb..10da1821ac465f 100644 --- a/doc/changelogs/CHANGELOG_V20.md +++ b/doc/changelogs/CHANGELOG_V20.md @@ -8,6 +8,11 @@ +20.7.0
+20.6.1
+20.6.0
+20.5.1
+20.5.0
20.4.0
20.3.1
20.3.0
@@ -40,6 +45,485 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + + +## 2023-09-18, Version 20.7.0 (Current), @UlisesGascon + +### Notable Changes + +* \[[`022f1b70c1`](https://github.com/nodejs/node/commit/022f1b70c1)] - **src**: support multiple `--env-file` declarations (Yagiz Nizipli) [#49542](https://github.com/nodejs/node/pull/49542) +* \[[`4a1d1cad61`](https://github.com/nodejs/node/commit/4a1d1cad61)] - **crypto**: update root certificates to NSS 3.93 (Node.js GitHub Bot) [#49341](https://github.com/nodejs/node/pull/49341) +* \[[`a1a65f593c`](https://github.com/nodejs/node/commit/a1a65f593c)] - **deps**: upgrade npm to 10.1.0 (npm team) [#49570](https://github.com/nodejs/node/pull/49570) +* \[[`6c2480cad9`](https://github.com/nodejs/node/commit/6c2480cad9)] - **(SEMVER-MINOR)** **deps**: upgrade npm to 10.0.0 (npm team) [#49423](https://github.com/nodejs/node/pull/49423) +* \[[`bef900e56b`](https://github.com/nodejs/node/commit/bef900e56b)] - **doc**: move and rename loaders section (Geoffrey Booth) [#49261](https://github.com/nodejs/node/pull/49261) +* \[[`db4ce8a593`](https://github.com/nodejs/node/commit/db4ce8a593)] - **doc**: add release key for Ulises Gascon (Ulises Gascón) [#49196](https://github.com/nodejs/node/pull/49196) +* \[[`11c85ffa98`](https://github.com/nodejs/node/commit/11c85ffa98)] - **(SEMVER-MINOR)** **lib**: add api to detect whether source-maps are enabled (翠 / green) [#46391](https://github.com/nodejs/node/pull/46391) +* \[[`ec51e25ed7`](https://github.com/nodejs/node/commit/ec51e25ed7)] - **src,permission**: add multiple allow-fs-\* flags (Carlos Espa) [#49047](https://github.com/nodejs/node/pull/49047) +* \[[`efdc95fbc0`](https://github.com/nodejs/node/commit/efdc95fbc0)] - **(SEMVER-MINOR)** **test\_runner**: expose location of tests (Colin Ihrig) [#48975](https://github.com/nodejs/node/pull/48975) + +### Commits + +* \[[`e84515594e`](https://github.com/nodejs/node/commit/e84515594e)] - **benchmark**: use `tmpdir.resolve()` (Livia Medeiros) [#49137](https://github.com/nodejs/node/pull/49137) +* \[[`f37444e896`](https://github.com/nodejs/node/commit/f37444e896)] - **bootstrap**: build code cache from deserialized isolate (Joyee Cheung) [#49099](https://github.com/nodejs/node/pull/49099) +* \[[`af6dc1754d`](https://github.com/nodejs/node/commit/af6dc1754d)] - **bootstrap**: do not generate code cache in an unfinalized isolate (Joyee Cheung) [#49108](https://github.com/nodejs/node/pull/49108) +* \[[`cade5716df`](https://github.com/nodejs/node/commit/cade5716df)] - **build**: add symlink to `compile_commands.json` file if needed (Juan José) [#49260](https://github.com/nodejs/node/pull/49260) +* \[[`34a2590b05`](https://github.com/nodejs/node/commit/34a2590b05)] - **build**: expand when we run internet tests (Michael Dawson) [#49218](https://github.com/nodejs/node/pull/49218) +* \[[`f637fd46ab`](https://github.com/nodejs/node/commit/f637fd46ab)] - **build**: fix typo `libray` -> `library` (configure.py) (michalbiesek) [#49106](https://github.com/nodejs/node/pull/49106) +* \[[`ef3d8dd493`](https://github.com/nodejs/node/commit/ef3d8dd493)] - **crypto**: remove webcrypto EdDSA key checks and properties (Filip Skokan) [#49408](https://github.com/nodejs/node/pull/49408) +* \[[`4a1d1cad61`](https://github.com/nodejs/node/commit/4a1d1cad61)] - **crypto**: update root certificates to NSS 3.93 (Node.js GitHub Bot) [#49341](https://github.com/nodejs/node/pull/49341) +* \[[`7eb10a38ea`](https://github.com/nodejs/node/commit/7eb10a38ea)] - **crypto**: remove getDefaultEncoding() (Tobias Nießen) [#49170](https://github.com/nodejs/node/pull/49170) +* \[[`772496c030`](https://github.com/nodejs/node/commit/772496c030)] - **crypto**: remove default encoding from DiffieHellman (Tobias Nießen) [#49169](https://github.com/nodejs/node/pull/49169) +* \[[`c795083232`](https://github.com/nodejs/node/commit/c795083232)] - **crypto**: remove default encoding from Hash/Hmac (Tobias Nießen) [#49167](https://github.com/nodejs/node/pull/49167) +* \[[`08197aa010`](https://github.com/nodejs/node/commit/08197aa010)] - **crypto**: remove default encoding from sign/verify (Tobias Nießen) [#49145](https://github.com/nodejs/node/pull/49145) +* \[[`a1a65f593c`](https://github.com/nodejs/node/commit/a1a65f593c)] - **deps**: upgrade npm to 10.1.0 (npm team) [#49570](https://github.com/nodejs/node/pull/49570) +* \[[`6c2480cad9`](https://github.com/nodejs/node/commit/6c2480cad9)] - **(SEMVER-MINOR)** **deps**: upgrade npm to 10.0.0 (npm team) [#49423](https://github.com/nodejs/node/pull/49423) +* \[[`84195d9584`](https://github.com/nodejs/node/commit/84195d9584)] - **deps**: add missing thread-common.c in uv.gyp (Santiago Gimeno) [#49410](https://github.com/nodejs/node/pull/49410) +* \[[`5b70b68b3d`](https://github.com/nodejs/node/commit/5b70b68b3d)] - **deps**: V8: cherry-pick eadaef581c29 (Adam Majer) [#49401](https://github.com/nodejs/node/pull/49401) +* \[[`fe34d632e8`](https://github.com/nodejs/node/commit/fe34d632e8)] - **deps**: update zlib to 1.2.13.1-motley-f5fd0ad (Node.js GitHub Bot) [#49252](https://github.com/nodejs/node/pull/49252) +* \[[`db4ce8a593`](https://github.com/nodejs/node/commit/db4ce8a593)] - **doc**: add release key for Ulises Gascon (Ulises Gascón) [#49196](https://github.com/nodejs/node/pull/49196) +* \[[`e5f3a694cf`](https://github.com/nodejs/node/commit/e5f3a694cf)] - **doc**: fix node-api call example (Chengzhong Wu) [#49395](https://github.com/nodejs/node/pull/49395) +* \[[`021345a724`](https://github.com/nodejs/node/commit/021345a724)] - **doc**: add news issue for Diagnostics WG (Michael Dawson) [#49306](https://github.com/nodejs/node/pull/49306) +* \[[`f82347266b`](https://github.com/nodejs/node/commit/f82347266b)] - **doc**: clarify policy expectations (Rafael Gonzaga) [#48947](https://github.com/nodejs/node/pull/48947) +* \[[`73cfd9c895`](https://github.com/nodejs/node/commit/73cfd9c895)] - **doc**: add print results for examples in `StringDecoder` (Jungku Lee) [#49326](https://github.com/nodejs/node/pull/49326) +* \[[`63ab591416`](https://github.com/nodejs/node/commit/63ab591416)] - **doc**: update outdated reference to NIST SP 800-131A (Tobias Nießen) [#49316](https://github.com/nodejs/node/pull/49316) +* \[[`935dfe2afd`](https://github.com/nodejs/node/commit/935dfe2afd)] - **doc**: use `cjs` as block code's type in `MockTimers` (Deokjin Kim) [#49309](https://github.com/nodejs/node/pull/49309) +* \[[`7c0cd2fb87`](https://github.com/nodejs/node/commit/7c0cd2fb87)] - **doc**: update `options.filter` description for `fs.cp` (Shubham Pandey) [#49289](https://github.com/nodejs/node/pull/49289) +* \[[`f72e79ea67`](https://github.com/nodejs/node/commit/f72e79ea67)] - **doc**: add riscv64 to list of architectures (Stewart X Addison) [#49284](https://github.com/nodejs/node/pull/49284) +* \[[`d19c710064`](https://github.com/nodejs/node/commit/d19c710064)] - **doc**: avoid "not currently recommended" (Tobias Nießen) [#49300](https://github.com/nodejs/node/pull/49300) +* \[[`ae656101c0`](https://github.com/nodejs/node/commit/ae656101c0)] - **doc**: update module hooks docs (Geoffrey Booth) [#49265](https://github.com/nodejs/node/pull/49265) +* \[[`fefbdb92f2`](https://github.com/nodejs/node/commit/fefbdb92f2)] - **doc**: modify param description for end(),write() in `StringDecoder` (Jungku Lee) [#49285](https://github.com/nodejs/node/pull/49285) +* \[[`59e66a1ebe`](https://github.com/nodejs/node/commit/59e66a1ebe)] - **doc**: use NODE\_API\_SUPPORTED\_VERSION\_MAX in release doc (Cheng Zhao) [#49268](https://github.com/nodejs/node/pull/49268) +* \[[`ac3b88449b`](https://github.com/nodejs/node/commit/ac3b88449b)] - **doc**: fix typo in `stream.finished` documentation (Antoine du Hamel) [#49271](https://github.com/nodejs/node/pull/49271) +* \[[`7428ebf6c3`](https://github.com/nodejs/node/commit/7428ebf6c3)] - **doc**: update description for `percent_encode` sets in `WHATWG API` (Jungku Lee) [#49258](https://github.com/nodejs/node/pull/49258) +* \[[`bef900e56b`](https://github.com/nodejs/node/commit/bef900e56b)] - **doc**: move and rename loaders section (Geoffrey Booth) [#49261](https://github.com/nodejs/node/pull/49261) +* \[[`a22e0d9696`](https://github.com/nodejs/node/commit/a22e0d9696)] - **doc**: clarify use of Uint8Array for n-api (Fedor Indutny) [#48742](https://github.com/nodejs/node/pull/48742) +* \[[`1704f24cb9`](https://github.com/nodejs/node/commit/1704f24cb9)] - **doc**: add signature for `module.register` (Geoffrey Booth) [#49251](https://github.com/nodejs/node/pull/49251) +* \[[`5a363bb01b`](https://github.com/nodejs/node/commit/5a363bb01b)] - **doc**: caveat unavailability of `import.meta.resolve` in custom loaders (Jacob Smith) [#49242](https://github.com/nodejs/node/pull/49242) +* \[[`8101f2b259`](https://github.com/nodejs/node/commit/8101f2b259)] - **doc**: use same name in the doc as in the code (Hyunjin Kim) [#49216](https://github.com/nodejs/node/pull/49216) +* \[[`edf278d60d`](https://github.com/nodejs/node/commit/edf278d60d)] - **doc**: add notable-change label mention to PR template (Rafael Gonzaga) [#49188](https://github.com/nodejs/node/pull/49188) +* \[[`3df2251a6a`](https://github.com/nodejs/node/commit/3df2251a6a)] - **doc**: add h1 summary to security release process (Rafael Gonzaga) [#49112](https://github.com/nodejs/node/pull/49112) +* \[[`9fcd99a744`](https://github.com/nodejs/node/commit/9fcd99a744)] - **doc**: update to semver-minor releases by default (Rafael Gonzaga) [#49175](https://github.com/nodejs/node/pull/49175) +* \[[`777931f499`](https://github.com/nodejs/node/commit/777931f499)] - **doc**: fix wording in napi\_async\_init (Tobias Nießen) [#49180](https://github.com/nodejs/node/pull/49180) +* \[[`f45c8e10c0`](https://github.com/nodejs/node/commit/f45c8e10c0)] - **doc,test**: add known path resolution issue in permission model (Tobias Nießen) [#49155](https://github.com/nodejs/node/pull/49155) +* \[[`a6cfea3f74`](https://github.com/nodejs/node/commit/a6cfea3f74)] - **esm**: align sync and async load implementations (Antoine du Hamel) [#49152](https://github.com/nodejs/node/pull/49152) +* \[[`9fac310b33`](https://github.com/nodejs/node/commit/9fac310b33)] - **fs**: add the options param description in openAsBlob() (Yeseul Lee) [#49308](https://github.com/nodejs/node/pull/49308) +* \[[`92772a8175`](https://github.com/nodejs/node/commit/92772a8175)] - **fs**: remove redundant code in readableWebStream() (Deokjin Kim) [#49298](https://github.com/nodejs/node/pull/49298) +* \[[`88ba79b083`](https://github.com/nodejs/node/commit/88ba79b083)] - **fs**: make sure to write entire buffer (Robert Nagy) [#49211](https://github.com/nodejs/node/pull/49211) +* \[[`11c85ffa98`](https://github.com/nodejs/node/commit/11c85ffa98)] - **(SEMVER-MINOR)** **lib**: add api to detect whether source-maps are enabled (翠 / green) [#46391](https://github.com/nodejs/node/pull/46391) +* \[[`c12711ebfe`](https://github.com/nodejs/node/commit/c12711ebfe)] - **lib**: implement WeakReference on top of JS WeakRef (Joyee Cheung) [#49053](https://github.com/nodejs/node/pull/49053) +* \[[`9a0891f88d`](https://github.com/nodejs/node/commit/9a0891f88d)] - **meta**: bump step-security/harden-runner from 2.5.0 to 2.5.1 (dependabot\[bot]) [#49435](https://github.com/nodejs/node/pull/49435) +* \[[`ae67f41ef1`](https://github.com/nodejs/node/commit/ae67f41ef1)] - **meta**: bump actions/checkout from 3.5.3 to 3.6.0 (dependabot\[bot]) [#49436](https://github.com/nodejs/node/pull/49436) +* \[[`71b4411fb2`](https://github.com/nodejs/node/commit/71b4411fb2)] - **meta**: bump actions/setup-node from 3.7.0 to 3.8.1 (dependabot\[bot]) [#49434](https://github.com/nodejs/node/pull/49434) +* \[[`83b7d3a395`](https://github.com/nodejs/node/commit/83b7d3a395)] - **meta**: remove modules team from CODEOWNERS (Benjamin Gruenbaum) [#49412](https://github.com/nodejs/node/pull/49412) +* \[[`81ff68c45c`](https://github.com/nodejs/node/commit/81ff68c45c)] - **meta**: move one or more collaborators to emeritus (Node.js GitHub Bot) [#49264](https://github.com/nodejs/node/pull/49264) +* \[[`ab975233cc`](https://github.com/nodejs/node/commit/ab975233cc)] - **meta**: mention nodejs/tsc when changing GH templates (Rafael Gonzaga) [#49189](https://github.com/nodejs/node/pull/49189) +* \[[`ceaa5494de`](https://github.com/nodejs/node/commit/ceaa5494de)] - **meta**: add test/reporters to codeowners (Chemi Atlow) [#49186](https://github.com/nodejs/node/pull/49186) +* \[[`de0a51b7cf`](https://github.com/nodejs/node/commit/de0a51b7cf)] - **net**: improve performance of isIPv4 and isIPv6 (Uzlopak) [#49568](https://github.com/nodejs/node/pull/49568) +* \[[`8d0913bf95`](https://github.com/nodejs/node/commit/8d0913bf95)] - **net**: use asserts in JS Socket Stream to catch races in future (Tim Perry) [#49400](https://github.com/nodejs/node/pull/49400) +* \[[`2486836a7d`](https://github.com/nodejs/node/commit/2486836a7d)] - **net**: fix crash due to simultaneous close/shutdown on JS Stream Sockets (Tim Perry) [#49400](https://github.com/nodejs/node/pull/49400) +* \[[`7a808340cd`](https://github.com/nodejs/node/commit/7a808340cd)] - **node-api**: fix compiler warning in node\_api.h (Michael Graeb) [#49103](https://github.com/nodejs/node/pull/49103) +* \[[`30f26a99f4`](https://github.com/nodejs/node/commit/30f26a99f4)] - **permission**: ensure to resolve path when calling mkdtemp (RafaelGSS) [nodejs-private/node-private#440](https://github.com/nodejs-private/node-private/pull/440) +* \[[`5051c75a5b`](https://github.com/nodejs/node/commit/5051c75a5b)] - **policy**: fix path to URL conversion (Antoine du Hamel) [#49133](https://github.com/nodejs/node/pull/49133) +* \[[`173aed4757`](https://github.com/nodejs/node/commit/173aed4757)] - **report**: fix recent coverity warning (Michael Dawson) [#48954](https://github.com/nodejs/node/pull/48954) +* \[[`d7ff78b442`](https://github.com/nodejs/node/commit/d7ff78b442)] - **sea**: generate code cache with deserialized isolate (Joyee Cheung) [#49226](https://github.com/nodejs/node/pull/49226) +* \[[`022f1b70c1`](https://github.com/nodejs/node/commit/022f1b70c1)] - **src**: support multiple `--env-file` declarations (Yagiz Nizipli) [#49542](https://github.com/nodejs/node/pull/49542) +* \[[`154b1c2115`](https://github.com/nodejs/node/commit/154b1c2115)] - **src**: don't overwrite environment from .env file (Phil Nash) [#49424](https://github.com/nodejs/node/pull/49424) +* \[[`dc4de1c69b`](https://github.com/nodejs/node/commit/dc4de1c69b)] - **src**: modify code for empty string (pluris) [#49336](https://github.com/nodejs/node/pull/49336) +* \[[`701c46f967`](https://github.com/nodejs/node/commit/701c46f967)] - **src**: remove unused PromiseWrap-related code (Joyee Cheung) [#49335](https://github.com/nodejs/node/pull/49335) +* \[[`4a094dc7af`](https://github.com/nodejs/node/commit/4a094dc7af)] - **src**: rename IsAnyByteSource to IsAnyBufferSource (Tobias Nießen) [#49346](https://github.com/nodejs/node/pull/49346) +* \[[`55d6649175`](https://github.com/nodejs/node/commit/55d6649175)] - **src**: support snapshot deserialization in RAIIIsolate (Joyee Cheung) [#49226](https://github.com/nodejs/node/pull/49226) +* \[[`dc092864ef`](https://github.com/nodejs/node/commit/dc092864ef)] - **src**: remove unused function `GetName()` in node\_perf (Jungku Lee) [#49244](https://github.com/nodejs/node/pull/49244) +* \[[`f2552a410e`](https://github.com/nodejs/node/commit/f2552a410e)] - **src**: use ARES\_SUCCESS instead of 0 (Jungku Lee) [#49048](https://github.com/nodejs/node/pull/49048) +* \[[`4a9ae31519`](https://github.com/nodejs/node/commit/4a9ae31519)] - **src**: add a condition if the argument of `DomainToUnicode` is empty (Jungku Lee) [#49097](https://github.com/nodejs/node/pull/49097) +* \[[`f460362cdf`](https://github.com/nodejs/node/commit/f460362cdf)] - **src**: remove C++ WeakReference implementation (Joyee Cheung) [#49053](https://github.com/nodejs/node/pull/49053) +* \[[`2a35383b3e`](https://github.com/nodejs/node/commit/2a35383b3e)] - **src**: use per-realm GetBindingData() wherever applicable (Joyee Cheung) [#49007](https://github.com/nodejs/node/pull/49007) +* \[[`184bbddcf5`](https://github.com/nodejs/node/commit/184bbddcf5)] - **src**: add per-realm GetBindingData() method (Joyee Cheung) [#49007](https://github.com/nodejs/node/pull/49007) +* \[[`e9946885f9`](https://github.com/nodejs/node/commit/e9946885f9)] - **src**: serialize both BaseObject slots (Joyee Cheung) [#48996](https://github.com/nodejs/node/pull/48996) +* \[[`ec51e25ed7`](https://github.com/nodejs/node/commit/ec51e25ed7)] - **src,permission**: add multiple allow-fs-\* flags (Carlos Espa) [#49047](https://github.com/nodejs/node/pull/49047) +* \[[`8aac95de4b`](https://github.com/nodejs/node/commit/8aac95de4b)] - **stream**: improve tee perf by reduce `ReflectConstruct` usages (Raz Luvaton) [#49546](https://github.com/nodejs/node/pull/49546) +* \[[`0eea7fd8fb`](https://github.com/nodejs/node/commit/0eea7fd8fb)] - **stream**: use Buffer.from when constructor is a Buffer (Matthew Aitken) [#49250](https://github.com/nodejs/node/pull/49250) +* \[[`b961d9bd52`](https://github.com/nodejs/node/commit/b961d9bd52)] - **stream**: add `highWaterMark` for the map operator (Raz Luvaton) [#49249](https://github.com/nodejs/node/pull/49249) +* \[[`ca1384166d`](https://github.com/nodejs/node/commit/ca1384166d)] - **test**: fix warning for comment in embedtest (Jungku Lee) [#49416](https://github.com/nodejs/node/pull/49416) +* \[[`2a35782809`](https://github.com/nodejs/node/commit/2a35782809)] - **test**: simplify test-crypto-dh-group-setters (Tobias Nießen) [#49404](https://github.com/nodejs/node/pull/49404) +* \[[`6740f3c209`](https://github.com/nodejs/node/commit/6740f3c209)] - **test**: verify dynamic import call with absolute path strings (Chengzhong Wu) [#49275](https://github.com/nodejs/node/pull/49275) +* \[[`6ed47bd8fb`](https://github.com/nodejs/node/commit/6ed47bd8fb)] - **test**: reduce length in crypto keygen tests (Joyee Cheung) [#49221](https://github.com/nodejs/node/pull/49221) +* \[[`4faa30c553`](https://github.com/nodejs/node/commit/4faa30c553)] - **test**: split JWK async elliptic curve keygen tests (Joyee Cheung) [#49221](https://github.com/nodejs/node/pull/49221) +* \[[`e04a2603d8`](https://github.com/nodejs/node/commit/e04a2603d8)] - **test**: split test-crypto-keygen.js (Joyee Cheung) [#49221](https://github.com/nodejs/node/pull/49221) +* \[[`0d23c1d4ce`](https://github.com/nodejs/node/commit/0d23c1d4ce)] - **test**: rename test-crypto-modp1-error (Tobias Nießen) [#49348](https://github.com/nodejs/node/pull/49348) +* \[[`48e41569e2`](https://github.com/nodejs/node/commit/48e41569e2)] - **test**: migrate message source map tests from Python to JS (Yiyun Lei) [#49238](https://github.com/nodejs/node/pull/49238) +* \[[`a11e64e09c`](https://github.com/nodejs/node/commit/a11e64e09c)] - **test**: fix compiler warning in NodeCryptoEnv (Tobias Nießen) [#49206](https://github.com/nodejs/node/pull/49206) +* \[[`345543938f`](https://github.com/nodejs/node/commit/345543938f)] - **test**: handle EUNATCH (Abdirahim Musse) [#48050](https://github.com/nodejs/node/pull/48050) +* \[[`e391f4b197`](https://github.com/nodejs/node/commit/e391f4b197)] - **test**: use `tmpdir.resolve()` (Livia Medeiros) [#49136](https://github.com/nodejs/node/pull/49136) +* \[[`910378f93f`](https://github.com/nodejs/node/commit/910378f93f)] - **test**: reduce flakiness of `test-esm-loader-hooks` (Antoine du Hamel) [#49248](https://github.com/nodejs/node/pull/49248) +* \[[`4a85f70462`](https://github.com/nodejs/node/commit/4a85f70462)] - **test**: add spawnSyncAndExit() and spawnSyncAndExitWithoutError() (Joyee Cheung) [#49200](https://github.com/nodejs/node/pull/49200) +* \[[`9610008b79`](https://github.com/nodejs/node/commit/9610008b79)] - **test**: make test-perf-hooks more robust and work with workers (Joyee Cheung) [#49197](https://github.com/nodejs/node/pull/49197) +* \[[`dc8fff9a75`](https://github.com/nodejs/node/commit/dc8fff9a75)] - **test**: use gcUntil() in test-v8-serialize-leak (Joyee Cheung) [#49168](https://github.com/nodejs/node/pull/49168) +* \[[`ca9f801332`](https://github.com/nodejs/node/commit/ca9f801332)] - **test**: make WeakReference tests robust (Joyee Cheung) [#49053](https://github.com/nodejs/node/pull/49053) +* \[[`de103a4686`](https://github.com/nodejs/node/commit/de103a4686)] - **test**: add test for effect of UV\_THREADPOOL\_SIZE (Tobias Nießen) [#49165](https://github.com/nodejs/node/pull/49165) +* \[[`47d24f144b`](https://github.com/nodejs/node/commit/47d24f144b)] - **test**: use expectSyncExit{WithErrors} in snapshot tests (Joyee Cheung) [#49020](https://github.com/nodejs/node/pull/49020) +* \[[`c441f5a097`](https://github.com/nodejs/node/commit/c441f5a097)] - **test**: add expectSyncExitWithoutError() and expectSyncExit() utils (Joyee Cheung) [#49020](https://github.com/nodejs/node/pull/49020) +* \[[`4d184b5251`](https://github.com/nodejs/node/commit/4d184b5251)] - **test**: remove --no-warnings flag in test\_runner fixtures (Raz Luvaton) [#48989](https://github.com/nodejs/node/pull/48989) +* \[[`25e967a90b`](https://github.com/nodejs/node/commit/25e967a90b)] - **test**: reorder test files fixtures for better understanding (Raz Luvaton) [#48787](https://github.com/nodejs/node/pull/48787) +* \[[`fac56dbcc0`](https://github.com/nodejs/node/commit/fac56dbcc0)] - **test,benchmark**: use `tmpdir.fileURL()` (Livia Medeiros) [#49138](https://github.com/nodejs/node/pull/49138) +* \[[`36763fa532`](https://github.com/nodejs/node/commit/36763fa532)] - **test\_runner**: preserve original property descriptor (Erick Wendel) [#49433](https://github.com/nodejs/node/pull/49433) +* \[[`40e9fcdbea`](https://github.com/nodejs/node/commit/40e9fcdbea)] - **test\_runner**: add support for setImmediate (Erick Wendel) [#49397](https://github.com/nodejs/node/pull/49397) +* \[[`23216f1935`](https://github.com/nodejs/node/commit/23216f1935)] - **test\_runner**: report covered lines, functions and branches to reporters (Phil Nash) [#49320](https://github.com/nodejs/node/pull/49320) +* \[[`283f2806b1`](https://github.com/nodejs/node/commit/283f2806b1)] - **test\_runner**: expose spec reporter as newable function (Chemi Atlow) [#49184](https://github.com/nodejs/node/pull/49184) +* \[[`546ad5f770`](https://github.com/nodejs/node/commit/546ad5f770)] - **test\_runner**: reland run global after() hook earlier (Colin Ihrig) [#49116](https://github.com/nodejs/node/pull/49116) +* \[[`efdc95fbc0`](https://github.com/nodejs/node/commit/efdc95fbc0)] - **(SEMVER-MINOR)** **test\_runner**: expose location of tests (Colin Ihrig) [#48975](https://github.com/nodejs/node/pull/48975) +* \[[`4bc0a8fe99`](https://github.com/nodejs/node/commit/4bc0a8fe99)] - **test\_runner**: fix global after not failing the tests (Raz Luvaton) [#48913](https://github.com/nodejs/node/pull/48913) +* \[[`08738b2664`](https://github.com/nodejs/node/commit/08738b2664)] - **test\_runner**: fix timeout in \*Each hook failing further tests (Raz Luvaton) [#48925](https://github.com/nodejs/node/pull/48925) +* \[[`c2f1830f66`](https://github.com/nodejs/node/commit/c2f1830f66)] - **test\_runner**: cleanup test timeout abort listener (Raz Luvaton) [#48915](https://github.com/nodejs/node/pull/48915) +* \[[`75333f38b2`](https://github.com/nodejs/node/commit/75333f38b2)] - **test\_runner**: fix global before not called when no global test exists (Raz Luvaton) [#48877](https://github.com/nodejs/node/pull/48877) +* \[[`b28b85adf8`](https://github.com/nodejs/node/commit/b28b85adf8)] - **tls**: remove redundant code in onConnectSecure() (Deokjin Kim) [#49457](https://github.com/nodejs/node/pull/49457) +* \[[`83fc4dccbc`](https://github.com/nodejs/node/commit/83fc4dccbc)] - **tls**: refactor to use validateFunction (Deokjin Kim) [#49422](https://github.com/nodejs/node/pull/49422) +* \[[`8949cc79dd`](https://github.com/nodejs/node/commit/8949cc79dd)] - **tls**: ensure TLS Sockets are closed if the underlying wrap closes (Tim Perry) [#49327](https://github.com/nodejs/node/pull/49327) +* \[[`1df56e6f01`](https://github.com/nodejs/node/commit/1df56e6f01)] - **tools**: update eslint to 8.48.0 (Node.js GitHub Bot) [#49343](https://github.com/nodejs/node/pull/49343) +* \[[`ef50ec5b57`](https://github.com/nodejs/node/commit/ef50ec5b57)] - **tools**: update lint-md-dependencies (Node.js GitHub Bot) [#49342](https://github.com/nodejs/node/pull/49342) +* \[[`9a8fb4fc34`](https://github.com/nodejs/node/commit/9a8fb4fc34)] - **tools**: remove v8\_dump\_build\_config action (Cheng Zhao) [#49301](https://github.com/nodejs/node/pull/49301) +* \[[`91b2d4314b`](https://github.com/nodejs/node/commit/91b2d4314b)] - **tools**: update lint-md-dependencies (Node.js GitHub Bot) [#49253](https://github.com/nodejs/node/pull/49253) +* \[[`b51946ebdd`](https://github.com/nodejs/node/commit/b51946ebdd)] - **tools**: fix github reporter appended multiple times (Moshe Atlow) [#49199](https://github.com/nodejs/node/pull/49199) +* \[[`ae40cb1612`](https://github.com/nodejs/node/commit/ae40cb1612)] - **url**: validate `pathToFileURL(path)` argument as string (LiviaMedeiros) [#49161](https://github.com/nodejs/node/pull/49161) +* \[[`e787673dcf`](https://github.com/nodejs/node/commit/e787673dcf)] - **url**: handle unicode hostname if empty (Yagiz Nizipli) [#49396](https://github.com/nodejs/node/pull/49396) +* \[[`6ee74be87f`](https://github.com/nodejs/node/commit/6ee74be87f)] - **vm**: store MicrotaskQueue in ContextifyContext directly (Joyee Cheung) [#48982](https://github.com/nodejs/node/pull/48982) +* \[[`0179c6dc8f`](https://github.com/nodejs/node/commit/0179c6dc8f)] - **worker**: protect against user mutating well-known prototypes (Antoine du Hamel) [#49270](https://github.com/nodejs/node/pull/49270) + + + +## 2023-09-08, Version 20.6.1 (Current), @RafaelGSS + +### Commits + +* \[[`8acbe6d8e8`](https://github.com/nodejs/node/commit/8acbe6d8e8)] - **esm**: fix loading of CJS modules from ESM (Antoine du Hamel) [#49500](https://github.com/nodejs/node/pull/49500) + + + +## 2023-09-04, Version 20.6.0 (Current), @juanarbol prepared by @UlisesGascon + +### Notable changes + +#### built-in `.env` file support + +Starting from Node.js v20.6.0, Node.js supports `.env` files for configuring environment variables. + +Your configuration file should follow the INI file format, with each line containing a key-value pair for an environment variable. +To initialize your Node.js application with predefined configurations, use the following CLI command: `node --env-file=config.env index.js`. + +For example, you can access the following environment variable using `process.env.PASSWORD` when your application is initialized: + +```text +PASSWORD=nodejs +``` + +In addition to environment variables, this change allows you to define your `NODE_OPTIONS` directly in the `.env` file, eliminating the need to include it in your `package.json`. + +This feature was contributed by Yagiz Nizipli in [#48890](https://github.com/nodejs/node/pull/48890). + +#### `import.meta.resolve` unflagged + +In ES modules, [`import.meta.resolve(specifier)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta/resolve) can be used to get an absolute URL string to which `specifier` resolves, similar to `require.resolve` in CommonJS. This aligns Node.js with browsers and other server-side runtimes. + +This feature was contributed by Guy Bedford in + +#### New `node:module` API `register` for module customization hooks; new `initialize` hook + +There is a new API `register` available on `node:module` to specify a file that exports module customization hooks, and pass data to the hooks, and establish communication channels with them. The “define the file with the hooks” part was previously handled by a flag `--experimental-loader`, but when the hooks moved into a dedicated thread in 20.0.0 there was a need to provide a way to communicate between the main (application) thread and the hooks thread. This can now be done by calling `register` from the main thread and passing data, including `MessageChannel` instances. + +We encourage users to migrate to an approach that uses [`--import`](https://nodejs.org/api/cli.html#--importmodule) with `register`, such as: + +```bash +node --import ./file-that-calls-register.js ./app.js +``` + +Using `--import` ensures that the customization hooks are registered before any application code runs, even the entry point. + +This feature was contributed by Izaak Schroeder in and + +#### Module customization `load` hook can now support CommonJS + +Authors of module customization hooks can how handle both ES module and CommonJS sources in the `load` hook. This works for CommonJS modules referenced via either `import` or `require`, so long as [the main entry point of the application is handled by the ES module loader](https://nodejs.org/api/cli.html#program-entry-point) (such as because the entry point is an ES module file, or if the `--import` flag is passed). This should simplify the customization of the Node.js module loading process, as package authors can customize more of Node.js without relying on deprecated APIs such as `require.extensions`. + +This feature was contributed by Antoine du Hamel in + +#### Node.js C++ addons now have experimental support for cppgc (Oilpan), a C++ garbage collection library in V8. + +Now when Node.js starts up, it makes sure that there is a `v8::CppHeap` attached to the V8 isolate. This enables users to allocate in the `v8::CppHeap` using `` headers from V8, which are now also included into the Node.js headers available to addons. Note that since Node.js only bundles the cppgc library coming from V8, [the ABI stability](https://nodejs.org/en/docs/guides/abi-stability#abi-stability-in-nodejs) of cppgc is currently not guaranteed in semver-minor and -patch updates, but we do not expect the ABI to break often, as it has been stable and battle-tested in Chromium for years. We may consider including cppgc into the ABI stability guarantees when it gets enough adoption internally and externally. + +To help addon authors create JavaScript-to-C++ references of which V8's garbage collector can be aware, a helper function [`node::SetCppgcReference(isolate, js_object, cppgc_object)`](https://github.com/nodejs/node/blob/v20.6.0/test/addons/cppgc-object/binding.cc) has been added to `node.h`. V8 may provide a native alternative in the future, which could then replace this Node.js-specific helper. In the mean time, users can use this API to avoid having to hard-code the layout of JavaScript wrapper objects. An example of how to create garbage-collected C++ objects in the unified heap and wrap it in a JavaScript object can be found in the [Node.js addon tests](https://github.com/nodejs/node/blob/v20.6.0/test/addons/cppgc-object/binding.cc). + +The existing `node::ObjectWrap` helper would continue to work, while cppgc-based object management serves as an alternative with some advantages mentioned in [the V8 blog post about Oilpan](https://v8.dev/blog/oilpan-library). + +This feature was contributed by Daryl Haresign and Joyee Cheung in and . + +#### Other notable changes + +* \[[`d6862b085c`](https://github.com/nodejs/node/commit/d6862b085c)] - **deps**: V8: cherry-pick 93275031284c (Joyee Cheung) [#48660](https://github.com/nodejs/node/pull/48660) +* \[[`00fc8bb8b3`](https://github.com/nodejs/node/commit/00fc8bb8b3)] - **doc**: add rluvaton to collaborators (Raz Luvaton) [#49215](https://github.com/nodejs/node/pull/49215) +* \[[`d649339abd`](https://github.com/nodejs/node/commit/d649339abd)] - **doc**: add new TSC members (Michael Dawson) [#48841](https://github.com/nodejs/node/pull/48841) +* \[[`67f9896247`](https://github.com/nodejs/node/commit/67f9896247)] - **(SEMVER-MINOR)** **inspector**: open add `SymbolDispose` (Chemi Atlow) [#48765](https://github.com/nodejs/node/pull/48765) +* \[[`5aef593db3`](https://github.com/nodejs/node/commit/5aef593db3)] - **module**: implement `register` utility (João Lenon) [#46826](https://github.com/nodejs/node/pull/46826) + +### Commits + +* \[[`771abcb5da`](https://github.com/nodejs/node/commit/771abcb5da)] - **benchmark**: add benchmarks for the test\_runner (Raz Luvaton) [#48931](https://github.com/nodejs/node/pull/48931) +* \[[`6b27bb0dab`](https://github.com/nodejs/node/commit/6b27bb0dab)] - **benchmark**: add pm startup benchmark (Rafael Gonzaga) [#48905](https://github.com/nodejs/node/pull/48905) +* \[[`1f35c0ca55`](https://github.com/nodejs/node/commit/1f35c0ca55)] - **child\_process**: harden against prototype pollution (Livia Medeiros) [#48726](https://github.com/nodejs/node/pull/48726) +* \[[`d6862b085c`](https://github.com/nodejs/node/commit/d6862b085c)] - **deps**: V8: cherry-pick 93275031284c (Joyee Cheung) [#48660](https://github.com/nodejs/node/pull/48660) +* \[[`f71e383948`](https://github.com/nodejs/node/commit/f71e383948)] - **deps**: update simdutf to 3.2.17 (Node.js GitHub Bot) [#49019](https://github.com/nodejs/node/pull/49019) +* \[[`e14f0456ae`](https://github.com/nodejs/node/commit/e14f0456ae)] - **deps**: update googletest to 7e33b6a (Node.js GitHub Bot) [#49034](https://github.com/nodejs/node/pull/49034) +* \[[`bfaa0fb500`](https://github.com/nodejs/node/commit/bfaa0fb500)] - **deps**: update zlib to 1.2.13.1-motley-526382e (Node.js GitHub Bot) [#49033](https://github.com/nodejs/node/pull/49033) +* \[[`b79c652c85`](https://github.com/nodejs/node/commit/b79c652c85)] - **deps**: update undici to 5.23.0 (Node.js GitHub Bot) [#49021](https://github.com/nodejs/node/pull/49021) +* \[[`6ead86145c`](https://github.com/nodejs/node/commit/6ead86145c)] - **deps**: update googletest to c875c4e (Node.js GitHub Bot) [#48964](https://github.com/nodejs/node/pull/48964) +* \[[`4b0e50501e`](https://github.com/nodejs/node/commit/4b0e50501e)] - **deps**: update ada to 2.6.0 (Node.js GitHub Bot) [#48896](https://github.com/nodejs/node/pull/48896) +* \[[`d960ee0ba3`](https://github.com/nodejs/node/commit/d960ee0ba3)] - **deps**: upgrade npm to 9.8.1 (npm team) [#48838](https://github.com/nodejs/node/pull/48838) +* \[[`d92b0139ca`](https://github.com/nodejs/node/commit/d92b0139ca)] - **deps**: update zlib to 1.2.13.1-motley-61dc0bd (Node.js GitHub Bot) [#48788](https://github.com/nodejs/node/pull/48788) +* \[[`2a7835c376`](https://github.com/nodejs/node/commit/2a7835c376)] - **deps**: V8: cherry-pick 9f4b7699f68e (Joyee Cheung) [#48830](https://github.com/nodejs/node/pull/48830) +* \[[`c8e17829ac`](https://github.com/nodejs/node/commit/c8e17829ac)] - **deps**: V8: cherry-pick c1a54d5ffcd1 (Joyee Cheung) [#48830](https://github.com/nodejs/node/pull/48830) +* \[[`318e075b6f`](https://github.com/nodejs/node/commit/318e075b6f)] - **deps**: update googletest to cc36671 (Node.js GitHub Bot) [#48789](https://github.com/nodejs/node/pull/48789) +* \[[`114e088267`](https://github.com/nodejs/node/commit/114e088267)] - **diagnostics\_channel**: fix last subscriber removal (Gabriel Schulhof) [#48933](https://github.com/nodejs/node/pull/48933) +* \[[`00fc8bb8b3`](https://github.com/nodejs/node/commit/00fc8bb8b3)] - **doc**: add rluvaton to collaborators (Raz Luvaton) [#49215](https://github.com/nodejs/node/pull/49215) +* \[[`21949c45b6`](https://github.com/nodejs/node/commit/21949c45b6)] - **doc**: add print results for examples in `WebStreams` (Jungku Lee) [#49143](https://github.com/nodejs/node/pull/49143) +* \[[`032107a6fe`](https://github.com/nodejs/node/commit/032107a6fe)] - **doc**: fix `Type` notation in webstreams (Deokjin Kim) [#49121](https://github.com/nodejs/node/pull/49121) +* \[[`91d41e7c5a`](https://github.com/nodejs/node/commit/91d41e7c5a)] - **doc**: fix name of the flag in `initialize()` docs (Antoine du Hamel) [#49158](https://github.com/nodejs/node/pull/49158) +* \[[`aa4caf810e`](https://github.com/nodejs/node/commit/aa4caf810e)] - **doc**: make the NODE\_VERSION\_IS\_RELEASE revert clear (Rafael Gonzaga) [#49114](https://github.com/nodejs/node/pull/49114) +* \[[`f888a1dbe3`](https://github.com/nodejs/node/commit/f888a1dbe3)] - **doc**: update process.binding deprecation text (Tobias Nießen) [#49086](https://github.com/nodejs/node/pull/49086) +* \[[`89fa3faf92`](https://github.com/nodejs/node/commit/89fa3faf92)] - **doc**: update with latest security release (Rafael Gonzaga) [#49085](https://github.com/nodejs/node/pull/49085) +* \[[`3d36e7a941`](https://github.com/nodejs/node/commit/3d36e7a941)] - **doc**: add description for `--port` flag of `node inspect` (Michael Bianco) [#48785](https://github.com/nodejs/node/pull/48785) +* \[[`e9d9ca12a3`](https://github.com/nodejs/node/commit/e9d9ca12a3)] - **doc**: add missing period (Rich Trott) [#49094](https://github.com/nodejs/node/pull/49094) +* \[[`7e7b554de0`](https://github.com/nodejs/node/commit/7e7b554de0)] - **doc**: add ESM examples in http.md (btea) [#47763](https://github.com/nodejs/node/pull/47763) +* \[[`48f8ccfd54`](https://github.com/nodejs/node/commit/48f8ccfd54)] - **doc**: detailed description of keystrokes Ctrl-Y and Meta-Y (Ray) [#43529](https://github.com/nodejs/node/pull/43529) +* \[[`195885c8f8`](https://github.com/nodejs/node/commit/195885c8f8)] - **doc**: add "type" to test runner event details (Phil Nash) [#49014](https://github.com/nodejs/node/pull/49014) +* \[[`6ce25f8415`](https://github.com/nodejs/node/commit/6ce25f8415)] - **doc**: reserve 118 for Electron 27 (David Sanders) [#49023](https://github.com/nodejs/node/pull/49023) +* \[[`9c26c0f296`](https://github.com/nodejs/node/commit/9c26c0f296)] - **doc**: clarify use of process.env in worker threads on Windows (Daeyeon Jeong) [#49008](https://github.com/nodejs/node/pull/49008) +* \[[`7186e02aa0`](https://github.com/nodejs/node/commit/7186e02aa0)] - **doc**: remove v14 mention (Rafael Gonzaga) [#49005](https://github.com/nodejs/node/pull/49005) +* \[[`9641ac6c65`](https://github.com/nodejs/node/commit/9641ac6c65)] - **doc**: drop github actions check in sec release process (Rafael Gonzaga) [#48978](https://github.com/nodejs/node/pull/48978) +* \[[`f3d62abb19`](https://github.com/nodejs/node/commit/f3d62abb19)] - **doc**: improved joinDuplicateHeaders definition (Matteo Bianchi) [#48859](https://github.com/nodejs/node/pull/48859) +* \[[`0db104a08b`](https://github.com/nodejs/node/commit/0db104a08b)] - **doc**: fix second parameter name of `events.addAbortListener` (Deokjin Kim) [#48922](https://github.com/nodejs/node/pull/48922) +* \[[`5173c559b7`](https://github.com/nodejs/node/commit/5173c559b7)] - **doc**: add new reporter events to custom reporter examples (Chemi Atlow) [#48903](https://github.com/nodejs/node/pull/48903) +* \[[`660da785e6`](https://github.com/nodejs/node/commit/660da785e6)] - **doc**: run license-builder (github-actions\[bot]) [#48898](https://github.com/nodejs/node/pull/48898) +* \[[`092f9fe92a`](https://github.com/nodejs/node/commit/092f9fe92a)] - **doc**: change duration to duration\_ms on test documentation (Ardi\_Nugraha) [#48892](https://github.com/nodejs/node/pull/48892) +* \[[`5e4730858d`](https://github.com/nodejs/node/commit/5e4730858d)] - **doc**: improve requireHostHeader (Guido Penta) [#48860](https://github.com/nodejs/node/pull/48860) +* \[[`045e3c549a`](https://github.com/nodejs/node/commit/045e3c549a)] - **doc**: add ver of 18.x where Node-api 9 is supported (Michael Dawson) [#48876](https://github.com/nodejs/node/pull/48876) +* \[[`c20d35df34`](https://github.com/nodejs/node/commit/c20d35df34)] - **doc**: include experimental features assessment (Rafael Gonzaga) [#48824](https://github.com/nodejs/node/pull/48824) +* \[[`d649339abd`](https://github.com/nodejs/node/commit/d649339abd)] - **doc**: add new TSC members (Michael Dawson) [#48841](https://github.com/nodejs/node/pull/48841) +* \[[`aeac327f2b`](https://github.com/nodejs/node/commit/aeac327f2b)] - **doc**: refactor node-api support matrix (Michael Dawson) [#48774](https://github.com/nodejs/node/pull/48774) +* \[[`388c7d9232`](https://github.com/nodejs/node/commit/388c7d9232)] - **doc**: declare `path` on example of `async_hooks.executionAsyncId()` (Deokjin Kim) [#48556](https://github.com/nodejs/node/pull/48556) +* \[[`fe20528c8e`](https://github.com/nodejs/node/commit/fe20528c8e)] - **doc**: remove the . in the end to reduce confusing (Jason) [#48719](https://github.com/nodejs/node/pull/48719) +* \[[`e69c8e173f`](https://github.com/nodejs/node/commit/e69c8e173f)] - **doc**: nodejs-social over nodejs/tweet (Rafael Gonzaga) [#48769](https://github.com/nodejs/node/pull/48769) +* \[[`ea547849fd`](https://github.com/nodejs/node/commit/ea547849fd)] - **doc**: expand on squashing and rebasing to land a PR (Chengzhong Wu) [#48751](https://github.com/nodejs/node/pull/48751) +* \[[`31442b96a5`](https://github.com/nodejs/node/commit/31442b96a5)] - **esm**: fix `globalPreload` warning (Antoine du Hamel) [#49069](https://github.com/nodejs/node/pull/49069) +* \[[`eb1215878b`](https://github.com/nodejs/node/commit/eb1215878b)] - **esm**: unflag import.meta.resolve (Guy Bedford) [#49028](https://github.com/nodejs/node/pull/49028) +* \[[`57b24a34e6`](https://github.com/nodejs/node/commit/57b24a34e6)] - **esm**: import.meta.resolve exact module not found errors should return (Guy Bedford) [#49038](https://github.com/nodejs/node/pull/49038) +* \[[`f23b2a3066`](https://github.com/nodejs/node/commit/f23b2a3066)] - **esm**: protect `ERR_UNSUPPORTED_DIR_IMPORT` against prototype pollution (Antoine du Hamel) [#49060](https://github.com/nodejs/node/pull/49060) +* \[[`386e826a56`](https://github.com/nodejs/node/commit/386e826a56)] - **esm**: add `initialize` hook, integrate with `register` (Izaak Schroeder) [#48842](https://github.com/nodejs/node/pull/48842) +* \[[`74a2e1e0ab`](https://github.com/nodejs/node/commit/74a2e1e0ab)] - **esm**: fix typo `parentUrl` -> `parentURL` (Antoine du Hamel) [#48999](https://github.com/nodejs/node/pull/48999) +* \[[`0a4f7c669a`](https://github.com/nodejs/node/commit/0a4f7c669a)] - **esm**: unflag `Module.register` and allow nested loader `import()` (Izaak Schroeder) [#48559](https://github.com/nodejs/node/pull/48559) +* \[[`a5597470ce`](https://github.com/nodejs/node/commit/a5597470ce)] - **esm**: add back `globalPreload` tests and fix failing ones (Antoine du Hamel) [#48779](https://github.com/nodejs/node/pull/48779) +* \[[`d568600b42`](https://github.com/nodejs/node/commit/d568600b42)] - **events**: remove weak listener for event target (Raz Luvaton) [#48952](https://github.com/nodejs/node/pull/48952) +* \[[`3d942d9842`](https://github.com/nodejs/node/commit/3d942d9842)] - **fs**: fix readdir recursive sync & callback (Ethan Arrowood) [#48698](https://github.com/nodejs/node/pull/48698) +* \[[`c14ff69d69`](https://github.com/nodejs/node/commit/c14ff69d69)] - **fs**: mention `URL` in NUL character error message (LiviaMedeiros) [#48828](https://github.com/nodejs/node/pull/48828) +* \[[`d634d781d7`](https://github.com/nodejs/node/commit/d634d781d7)] - **fs**: make `mkdtemp` accept buffers and URL (LiviaMedeiros) [#48828](https://github.com/nodejs/node/pull/48828) +* \[[`4515a285a4`](https://github.com/nodejs/node/commit/4515a285a4)] - **fs**: remove redundant `nullCheck` (Livia Medeiros) [#48826](https://github.com/nodejs/node/pull/48826) +* \[[`742597b14a`](https://github.com/nodejs/node/commit/742597b14a)] - **http**: start connections checking interval on listen (Paolo Insogna) [#48611](https://github.com/nodejs/node/pull/48611) +* \[[`67f9896247`](https://github.com/nodejs/node/commit/67f9896247)] - **(SEMVER-MINOR)** **inspector**: open add `SymbolDispose` (Chemi Atlow) [#48765](https://github.com/nodejs/node/pull/48765) +* \[[`b66a3c1c96`](https://github.com/nodejs/node/commit/b66a3c1c96)] - **lib**: fix MIME overmatch in data URLs (André Alves) [#49104](https://github.com/nodejs/node/pull/49104) +* \[[`dca8678a22`](https://github.com/nodejs/node/commit/dca8678a22)] - **lib**: fix to add resolve() before return at Blob.stream()'s source.pull() (bellbind) [#48935](https://github.com/nodejs/node/pull/48935) +* \[[`420b85c00f`](https://github.com/nodejs/node/commit/420b85c00f)] - **lib**: remove invalid parameter to toASCII (Yagiz Nizipli) [#48878](https://github.com/nodejs/node/pull/48878) +* \[[`a12ce11b09`](https://github.com/nodejs/node/commit/a12ce11b09)] - **lib,permission**: drop repl autocomplete when pm enabled (Rafael Gonzaga) [#48920](https://github.com/nodejs/node/pull/48920) +* \[[`458eaf5e75`](https://github.com/nodejs/node/commit/458eaf5e75)] - **meta**: bump github/codeql-action from 2.20.1 to 2.21.2 (dependabot\[bot]) [#48986](https://github.com/nodejs/node/pull/48986) +* \[[`4f88cb10e0`](https://github.com/nodejs/node/commit/4f88cb10e0)] - **meta**: bump step-security/harden-runner from 2.4.1 to 2.5.0 (dependabot\[bot]) [#48985](https://github.com/nodejs/node/pull/48985) +* \[[`22fc2a6ec6`](https://github.com/nodejs/node/commit/22fc2a6ec6)] - **meta**: bump actions/setup-node from 3.6.0 to 3.7.0 (dependabot\[bot]) [#48984](https://github.com/nodejs/node/pull/48984) +* \[[`40103adabd`](https://github.com/nodejs/node/commit/40103adabd)] - **meta**: bump actions/setup-python from 4.6.1 to 4.7.0 (dependabot\[bot]) [#48983](https://github.com/nodejs/node/pull/48983) +* \[[`84c0c6848c`](https://github.com/nodejs/node/commit/84c0c6848c)] - **meta**: add mailmap entry for atlowChemi (Chemi Atlow) [#48810](https://github.com/nodejs/node/pull/48810) +* \[[`1a6e9450b8`](https://github.com/nodejs/node/commit/1a6e9450b8)] - **module**: make CJS load from ESM loader (Antoine du Hamel) [#47999](https://github.com/nodejs/node/pull/47999) +* \[[`a5322c4b4a`](https://github.com/nodejs/node/commit/a5322c4b4a)] - **module**: ensure successful import returns the same result (Antoine du Hamel) [#46662](https://github.com/nodejs/node/pull/46662) +* \[[`5aef593db3`](https://github.com/nodejs/node/commit/5aef593db3)] - **module**: implement `register` utility (João Lenon) [#46826](https://github.com/nodejs/node/pull/46826) +* \[[`015c4f788d`](https://github.com/nodejs/node/commit/015c4f788d)] - **node-api**: avoid macro redefinition (Tobias Nießen) [#48879](https://github.com/nodejs/node/pull/48879) +* \[[`53ee98566b`](https://github.com/nodejs/node/commit/53ee98566b)] - **permission**: move PrintTree into unnamed namespace (Tobias Nießen) [#48874](https://github.com/nodejs/node/pull/48874) +* \[[`30ea480135`](https://github.com/nodejs/node/commit/30ea480135)] - **permission**: fix data types in PrintTree (Tobias Nießen) [#48770](https://github.com/nodejs/node/pull/48770) +* \[[`8380800375`](https://github.com/nodejs/node/commit/8380800375)] - **readline**: add paste bracket mode (Jakub Jankiewicz) [#47150](https://github.com/nodejs/node/pull/47150) +* \[[`bc009d0c10`](https://github.com/nodejs/node/commit/bc009d0c10)] - **sea**: add support for V8 bytecode-only caching (Darshan Sen) [#48191](https://github.com/nodejs/node/pull/48191) +* \[[`f2f4ce9e29`](https://github.com/nodejs/node/commit/f2f4ce9e29)] - **src**: use effective cppgc wrapper id to deduce non-cppgc id (Joyee Cheung) [#48660](https://github.com/nodejs/node/pull/48660) +* \[[`bf7ff369f6`](https://github.com/nodejs/node/commit/bf7ff369f6)] - **src**: add built-in `.env` file support (Yagiz Nizipli) [#48890](https://github.com/nodejs/node/pull/48890) +* \[[`8d6948f8e2`](https://github.com/nodejs/node/commit/8d6948f8e2)] - **src**: remove duplicated code in `GenerateSingleExecutableBlob()` (Jungku Lee) [#49119](https://github.com/nodejs/node/pull/49119) +* \[[`b030004cee`](https://github.com/nodejs/node/commit/b030004cee)] - **src**: refactor vector writing in snapshot builder (Joyee Cheung) [#48851](https://github.com/nodejs/node/pull/48851) +* \[[`497df8288d`](https://github.com/nodejs/node/commit/497df8288d)] - **src**: add ability to overload fast api functions (Yagiz Nizipli) [#48993](https://github.com/nodejs/node/pull/48993) +* \[[`e5b0dfa359`](https://github.com/nodejs/node/commit/e5b0dfa359)] - **src**: remove redundant code for uv\_handle\_type (Jungku Lee) [#49061](https://github.com/nodejs/node/pull/49061) +* \[[`f126b9e3d1`](https://github.com/nodejs/node/commit/f126b9e3d1)] - **src**: modernize use-equals-default (Jason) [#48735](https://github.com/nodejs/node/pull/48735) +* \[[`db4370fc3e`](https://github.com/nodejs/node/commit/db4370fc3e)] - **src**: avoid string copy in BuiltinLoader::GetBuiltinIds (Yagiz Nizipli) [#48721](https://github.com/nodejs/node/pull/48721) +* \[[`9d13503c4e`](https://github.com/nodejs/node/commit/9d13503c4e)] - **src**: fix callback\_queue.h missing header (Jason) [#48733](https://github.com/nodejs/node/pull/48733) +* \[[`6c389df3aa`](https://github.com/nodejs/node/commit/6c389df3aa)] - **src**: cast v8::Object::GetInternalField() return value to v8::Value (Joyee Cheung) [#48943](https://github.com/nodejs/node/pull/48943) +* \[[`7b9adff0be`](https://github.com/nodejs/node/commit/7b9adff0be)] - **src**: do not pass user input to format string (Antoine du Hamel) [#48973](https://github.com/nodejs/node/pull/48973) +* \[[`e0fdb7b092`](https://github.com/nodejs/node/commit/e0fdb7b092)] - **src**: remove ContextEmbedderIndex::kBindingDataStoreIndex (Joyee Cheung) [#48836](https://github.com/nodejs/node/pull/48836) +* \[[`578c3d1e14`](https://github.com/nodejs/node/commit/578c3d1e14)] - **src**: use ARES\_SUCCESS instead of 0 (Hyunjin Kim) [#48834](https://github.com/nodejs/node/pull/48834) +* \[[`ed23426aac`](https://github.com/nodejs/node/commit/ed23426aac)] - **src**: save the performance milestone time origin in the AliasedArray (Joyee Cheung) [#48708](https://github.com/nodejs/node/pull/48708) +* \[[`5dec186663`](https://github.com/nodejs/node/commit/5dec186663)] - **src**: support snapshot in single executable applications (Joyee Cheung) [#46824](https://github.com/nodejs/node/pull/46824) +* \[[`d759d4f631`](https://github.com/nodejs/node/commit/d759d4f631)] - **src**: remove unnecessary temporary creation (Jason) [#48734](https://github.com/nodejs/node/pull/48734) +* \[[`409cc692db`](https://github.com/nodejs/node/commit/409cc692db)] - **src**: fix nullptr access on realm (Jan Olaf Krems) [#48802](https://github.com/nodejs/node/pull/48802) +* \[[`07d0fd61b1`](https://github.com/nodejs/node/commit/07d0fd61b1)] - **src**: remove OnScopeLeaveImpl's move assignment overload (Jason) [#48732](https://github.com/nodejs/node/pull/48732) +* \[[`41cc3efa23`](https://github.com/nodejs/node/commit/41cc3efa23)] - **src**: use string\_view for utf-8 string creation (Yagiz Nizipli) [#48722](https://github.com/nodejs/node/pull/48722) +* \[[`62a46d9335`](https://github.com/nodejs/node/commit/62a46d9335)] - **src,permission**: restrict by default when pm enabled (Rafael Gonzaga) [#48907](https://github.com/nodejs/node/pull/48907) +* \[[`099159ce04`](https://github.com/nodejs/node/commit/099159ce04)] - **src,tools**: initialize cppgc (Daryl Haresign) [#48660](https://github.com/nodejs/node/pull/48660) +* \[[`600c08d197`](https://github.com/nodejs/node/commit/600c08d197)] - **stream**: improve WebStreams performance (Raz Luvaton) [#49089](https://github.com/nodejs/node/pull/49089) +* \[[`609b25fa99`](https://github.com/nodejs/node/commit/609b25fa99)] - **stream**: implement ReadableStream.from (Debadree Chatterjee) [#48395](https://github.com/nodejs/node/pull/48395) +* \[[`750cca2738`](https://github.com/nodejs/node/commit/750cca2738)] - **test**: use `tmpdir.resolve()` (Livia Medeiros) [#49128](https://github.com/nodejs/node/pull/49128) +* \[[`6595367649`](https://github.com/nodejs/node/commit/6595367649)] - **test**: use `tmpdir.resolve()` (Livia Medeiros) [#49127](https://github.com/nodejs/node/pull/49127) +* \[[`661b055e75`](https://github.com/nodejs/node/commit/661b055e75)] - **test**: use `tmpdir.resolve()` in fs tests (Livia Medeiros) [#49126](https://github.com/nodejs/node/pull/49126) +* \[[`b3c56d206f`](https://github.com/nodejs/node/commit/b3c56d206f)] - **test**: use `tmpdir.resolve()` in fs tests (Livia Medeiros) [#49125](https://github.com/nodejs/node/pull/49125) +* \[[`3ddb155d16`](https://github.com/nodejs/node/commit/3ddb155d16)] - **test**: fix assertion message in test\_async.c (Tobias Nießen) [#49146](https://github.com/nodejs/node/pull/49146) +* \[[`1d17c1032d`](https://github.com/nodejs/node/commit/1d17c1032d)] - **test**: refactor `test-esm-loader-hooks` for easier debugging (Antoine du Hamel) [#49131](https://github.com/nodejs/node/pull/49131) +* \[[`13bd7a0293`](https://github.com/nodejs/node/commit/13bd7a0293)] - **test**: add `tmpdir.resolve()` (Livia Medeiros) [#49079](https://github.com/nodejs/node/pull/49079) +* \[[`89b1bce56d`](https://github.com/nodejs/node/commit/89b1bce56d)] - **test**: document `fixtures.fileURL()` (Livia Medeiros) [#49083](https://github.com/nodejs/node/pull/49083) +* \[[`2fcb855c76`](https://github.com/nodejs/node/commit/2fcb855c76)] - **test**: reduce flakiness of `test-esm-loader-hooks` (Antoine du Hamel) [#49105](https://github.com/nodejs/node/pull/49105) +* \[[`7816e040df`](https://github.com/nodejs/node/commit/7816e040df)] - **test**: stabilize the inspector-open-dispose test (Chemi Atlow) [#49000](https://github.com/nodejs/node/pull/49000) +* \[[`e70e9747e4`](https://github.com/nodejs/node/commit/e70e9747e4)] - **test**: print instruction for creating missing snapshot in assertSnapshot (Raz Luvaton) [#48914](https://github.com/nodejs/node/pull/48914) +* \[[`669ac03520`](https://github.com/nodejs/node/commit/669ac03520)] - **test**: add `tmpdir.fileURL()` (Livia Medeiros) [#49040](https://github.com/nodejs/node/pull/49040) +* \[[`b945d7be35`](https://github.com/nodejs/node/commit/b945d7be35)] - **test**: use `spawn` and `spawnPromisified` instead of `exec` (Antoine du Hamel) [#48991](https://github.com/nodejs/node/pull/48991) +* \[[`b3a7427583`](https://github.com/nodejs/node/commit/b3a7427583)] - **test**: refactor `test-node-output-errors` (Antoine du Hamel) [#48992](https://github.com/nodejs/node/pull/48992) +* \[[`6c3e5c4d69`](https://github.com/nodejs/node/commit/6c3e5c4d69)] - **test**: use `fixtures.fileURL` when appropriate (Antoine du Hamel) [#48990](https://github.com/nodejs/node/pull/48990) +* \[[`9138b78bcb`](https://github.com/nodejs/node/commit/9138b78bcb)] - **test**: validate error code rather than message (Antoine du Hamel) [#48972](https://github.com/nodejs/node/pull/48972) +* \[[`b4ca4a6f80`](https://github.com/nodejs/node/commit/b4ca4a6f80)] - **test**: fix snapshot tests when cwd contains spaces or backslashes (Antoine du Hamel) [#48959](https://github.com/nodejs/node/pull/48959) +* \[[`d4398d458c`](https://github.com/nodejs/node/commit/d4398d458c)] - **test**: order `common.mjs` in ASCII order (Antoine du Hamel) [#48960](https://github.com/nodejs/node/pull/48960) +* \[[`b5991f5250`](https://github.com/nodejs/node/commit/b5991f5250)] - **test**: fix some assumptions in tests (Antoine du Hamel) [#48958](https://github.com/nodejs/node/pull/48958) +* \[[`62e23f83f9`](https://github.com/nodejs/node/commit/62e23f83f9)] - **test**: improve internal/worker/io.js coverage (Yoshiki Kurihara) [#42387](https://github.com/nodejs/node/pull/42387) +* \[[`314bd6095c`](https://github.com/nodejs/node/commit/314bd6095c)] - **test**: fix `es-module/test-esm-initialization` (Antoine du Hamel) [#48880](https://github.com/nodejs/node/pull/48880) +* \[[`3680a66df4`](https://github.com/nodejs/node/commit/3680a66df4)] - **test**: validate host with commas on url.parse (Yagiz Nizipli) [#48878](https://github.com/nodejs/node/pull/48878) +* \[[`24c3742372`](https://github.com/nodejs/node/commit/24c3742372)] - **test**: delete test-net-bytes-per-incoming-chunk-overhead (Michaël Zasso) [#48811](https://github.com/nodejs/node/pull/48811) +* \[[`e01cce50f5`](https://github.com/nodejs/node/commit/e01cce50f5)] - **test**: skip experimental test with pointer compression (Colin Ihrig) [#48738](https://github.com/nodejs/node/pull/48738) +* \[[`d5e93b1074`](https://github.com/nodejs/node/commit/d5e93b1074)] - **test**: fix flaky test-string-decode.js on x86 (Stefan Stojanovic) [#48750](https://github.com/nodejs/node/pull/48750) +* \[[`9136667d7d`](https://github.com/nodejs/node/commit/9136667d7d)] - **test\_runner**: dont set exit code on todo tests (Moshe Atlow) [#48929](https://github.com/nodejs/node/pull/48929) +* \[[`52c94908c0`](https://github.com/nodejs/node/commit/52c94908c0)] - **test\_runner**: fix todo and only in spec reporter (Moshe Atlow) [#48929](https://github.com/nodejs/node/pull/48929) +* \[[`5ccfb8d515`](https://github.com/nodejs/node/commit/5ccfb8d515)] - **test\_runner**: unwrap error message in TAP reporter (Colin Ihrig) [#48942](https://github.com/nodejs/node/pull/48942) +* \[[`fa19b0ed05`](https://github.com/nodejs/node/commit/fa19b0ed05)] - **test\_runner**: add `__proto__` null (Raz Luvaton) [#48663](https://github.com/nodejs/node/pull/48663) +* \[[`65d23940bf`](https://github.com/nodejs/node/commit/65d23940bf)] - **test\_runner**: fix async callback in describe not awaited (Raz Luvaton) [#48856](https://github.com/nodejs/node/pull/48856) +* \[[`4bd5e55b43`](https://github.com/nodejs/node/commit/4bd5e55b43)] - **test\_runner**: fix test\_runner `test:fail` event type (Ethan Arrowood) [#48854](https://github.com/nodejs/node/pull/48854) +* \[[`41058beed8`](https://github.com/nodejs/node/commit/41058beed8)] - **test\_runner**: call abort on test finish (Raz Luvaton) [#48827](https://github.com/nodejs/node/pull/48827) +* \[[`821b11a59f`](https://github.com/nodejs/node/commit/821b11a59f)] - **tls**: fix bugs of double TLS (rogertyang) [#48969](https://github.com/nodejs/node/pull/48969) +* \[[`4439327e73`](https://github.com/nodejs/node/commit/4439327e73)] - **tools**: update lint-md-dependencies (Node.js GitHub Bot) [#49122](https://github.com/nodejs/node/pull/49122) +* \[[`21dc844309`](https://github.com/nodejs/node/commit/21dc844309)] - **tools**: use spec reporter in actions (Moshe Atlow) [#49129](https://github.com/nodejs/node/pull/49129) +* \[[`3471758696`](https://github.com/nodejs/node/commit/3471758696)] - **tools**: use @reporters/github when running in github actions (Moshe Atlow) [#49129](https://github.com/nodejs/node/pull/49129) +* \[[`95a6e7661e`](https://github.com/nodejs/node/commit/95a6e7661e)] - **tools**: add @reporters/github to tools (Moshe Atlow) [#49129](https://github.com/nodejs/node/pull/49129) +* \[[`995cbf93eb`](https://github.com/nodejs/node/commit/995cbf93eb)] - **tools**: update eslint to 8.47.0 (Node.js GitHub Bot) [#49124](https://github.com/nodejs/node/pull/49124) +* \[[`ed065bc56e`](https://github.com/nodejs/node/commit/ed065bc56e)] - **tools**: update lint-md-dependencies to rollup\@3.27.2 (Node.js GitHub Bot) [#49035](https://github.com/nodejs/node/pull/49035) +* \[[`a5f37178ad`](https://github.com/nodejs/node/commit/a5f37178ad)] - **tools**: limit the number of auto start CIs (Antoine du Hamel) [#49067](https://github.com/nodejs/node/pull/49067) +* \[[`c1bd680f89`](https://github.com/nodejs/node/commit/c1bd680f89)] - **tools**: update eslint to 8.46.0 (Node.js GitHub Bot) [#48966](https://github.com/nodejs/node/pull/48966) +* \[[`e09a6b4821`](https://github.com/nodejs/node/commit/e09a6b4821)] - **tools**: update lint-md-dependencies to rollup\@3.27.0 (Node.js GitHub Bot) [#48965](https://github.com/nodejs/node/pull/48965) +* \[[`0cd2393bd9`](https://github.com/nodejs/node/commit/0cd2393bd9)] - **tools**: update lint-md-dependencies to rollup\@3.26.3 (Node.js GitHub Bot) [#48888](https://github.com/nodejs/node/pull/48888) +* \[[`41929a2906`](https://github.com/nodejs/node/commit/41929a2906)] - **tools**: update lint-md-dependencies to @rollup/plugin-commonjs\@25.0.3 (Node.js GitHub Bot) [#48791](https://github.com/nodejs/node/pull/48791) +* \[[`1761bdfbd9`](https://github.com/nodejs/node/commit/1761bdfbd9)] - **tools**: update eslint to 8.45.0 (Node.js GitHub Bot) [#48793](https://github.com/nodejs/node/pull/48793) +* \[[`b82f05cc4b`](https://github.com/nodejs/node/commit/b82f05cc4b)] - **typings**: update JSDoc for `cwd` in `child_process` (LiviaMedeiros) [#49029](https://github.com/nodejs/node/pull/49029) +* \[[`be7b511255`](https://github.com/nodejs/node/commit/be7b511255)] - **typings**: sync JSDoc with the actual implementation (Hyunjin Kim) [#48853](https://github.com/nodejs/node/pull/48853) +* \[[`45c860035d`](https://github.com/nodejs/node/commit/45c860035d)] - **url**: overload `canParse` V8 fast api method (Yagiz Nizipli) [#48993](https://github.com/nodejs/node/pull/48993) +* \[[`60d614157b`](https://github.com/nodejs/node/commit/60d614157b)] - **url**: fix `isURL` detection by checking `path` (Zhuo Zhang) [#48928](https://github.com/nodejs/node/pull/48928) +* \[[`b12c3b5240`](https://github.com/nodejs/node/commit/b12c3b5240)] - **url**: ensure getter access do not mutate observable symbols (Antoine du Hamel) [#48897](https://github.com/nodejs/node/pull/48897) +* \[[`30fb7b7535`](https://github.com/nodejs/node/commit/30fb7b7535)] - **url**: reduce `pathToFileURL` cpp calls (Yagiz Nizipli) [#48709](https://github.com/nodejs/node/pull/48709) +* \[[`c3dbd0c1e4`](https://github.com/nodejs/node/commit/c3dbd0c1e4)] - **util**: use `primordials.ArrayPrototypeIndexOf` instead of mutable method (DaisyDogs07) [#48586](https://github.com/nodejs/node/pull/48586) +* \[[`b79b2927ca`](https://github.com/nodejs/node/commit/b79b2927ca)] - **watch**: decrease debounce rate (Moshe Atlow) [#48926](https://github.com/nodejs/node/pull/48926) +* \[[`a12996298e`](https://github.com/nodejs/node/commit/a12996298e)] - **watch**: use debounce instead of throttle (Moshe Atlow) [#48926](https://github.com/nodejs/node/pull/48926) + + + +## 2023-08-09, Version 20.5.1 (Current), @RafaelGSS + +This is a security release. + +### Notable Changes + +The following CVEs are fixed in this release: + +* [CVE-2023-32002](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32002): Policies can be bypassed via Module.\_load (High) +* [CVE-2023-32558](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32558): process.binding() can bypass the permission model through path traversal (High) +* [CVE-2023-32004](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32004): Permission model can be bypassed by specifying a path traversal sequence in a Buffer (High) +* [CVE-2023-32006](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32006): Policies can be bypassed by module.constructor.createRequire (Medium) +* [CVE-2023-32559](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32559): Policies can be bypassed via process.binding (Medium) +* [CVE-2023-32005](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32005): fs.statfs can bypass the permission model (Low) +* [CVE-2023-32003](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-32003): fs.mkdtemp() and fs.mkdtempSync() can bypass the permission model (Low) +* OpenSSL Security Releases + * [OpenSSL security advisory 14th July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000264.html). + * [OpenSSL security advisory 19th July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000265.html). + * [OpenSSL security advisory 31st July](https://mta.openssl.org/pipermail/openssl-announce/2023-July/000267.html) + +More detailed information on each of the vulnerabilities can be found in [August 2023 Security Releases](https://nodejs.org/en/blog/vulnerability/august-2023-security-releases/) blog post. + +### Commits + +* \[[`92300b51b4`](https://github.com/nodejs/node/commit/92300b51b4)] - **deps**: update archs files for openssl-3.0.10+quic1 (Node.js GitHub Bot) [#49036](https://github.com/nodejs/node/pull/49036) +* \[[`559698abf2`](https://github.com/nodejs/node/commit/559698abf2)] - **deps**: upgrade openssl sources to quictls/openssl-3.0.10+quic1 (Node.js GitHub Bot) [#49036](https://github.com/nodejs/node/pull/49036) +* \[[`1bf3429e8e`](https://github.com/nodejs/node/commit/1bf3429e8e)] - **lib,permission**: restrict process.binding when pm is enabled (RafaelGSS) [nodejs-private/node-private#438](https://github.com/nodejs-private/node-private/pull/438) +* \[[`98a83a67e6`](https://github.com/nodejs/node/commit/98a83a67e6)] - **permission**: ensure to resolve path when calling mkdtemp (RafaelGSS) [nodejs-private/node-private#464](https://github.com/nodejs-private/node-private/pull/464) +* \[[`1f0cde466b`](https://github.com/nodejs/node/commit/1f0cde466b)] - **permission**: handle buffer path on fs calls (RafaelGSS) [nodejs-private/node-private#439](https://github.com/nodejs-private/node-private/pull/439) +* \[[`bd094d60ea`](https://github.com/nodejs/node/commit/bd094d60ea)] - **permission**: handle fstatfs and add pm supported list (RafaelGSS) [nodejs-private/node-private#441](https://github.com/nodejs-private/node-private/pull/441) +* \[[`7337d21484`](https://github.com/nodejs/node/commit/7337d21484)] - **policy**: handle Module.constructor and main.extensions bypass (RafaelGSS) [nodejs-private/node-private#417](https://github.com/nodejs-private/node-private/pull/417) +* \[[`cf348ec640`](https://github.com/nodejs/node/commit/cf348ec640)] - **policy**: disable process.binding() when enabled (Tobias Nießen) [nodejs-private/node-private#397](https://github.com/nodejs-private/node-private/pull/397) + + + +## 2023-07-18, Version 20.5.0 (Current), @juanarbol + +### Notable Changes + +* \[[`45be29d89f`](https://github.com/nodejs/node/commit/45be29d89f)] - **doc**: add atlowChemi to collaborators (atlowChemi) [#48757](https://github.com/nodejs/node/pull/48757) +* \[[`a316808136`](https://github.com/nodejs/node/commit/a316808136)] - **(SEMVER-MINOR)** **events**: allow safely adding listener to abortSignal (Chemi Atlow) [#48596](https://github.com/nodejs/node/pull/48596) +* \[[`986b46a567`](https://github.com/nodejs/node/commit/986b46a567)] - **fs**: add a fast-path for readFileSync utf-8 (Yagiz Nizipli) [#48658](https://github.com/nodejs/node/pull/48658) +* \[[`0ef73ff6f0`](https://github.com/nodejs/node/commit/0ef73ff6f0)] - **(SEMVER-MINOR)** **test\_runner**: add shards support (Raz Luvaton) [#48639](https://github.com/nodejs/node/pull/48639) + +### Commits + +* \[[`eb0aba59b8`](https://github.com/nodejs/node/commit/eb0aba59b8)] - **bootstrap**: use correct descriptor for Symbol.{dispose,asyncDispose} (Jordan Harband) [#48703](https://github.com/nodejs/node/pull/48703) +* \[[`e2d0195dcf`](https://github.com/nodejs/node/commit/e2d0195dcf)] - **bootstrap**: hide experimental web globals with flag kNoBrowserGlobals (Chengzhong Wu) [#48545](https://github.com/nodejs/node/pull/48545) +* \[[`67a1018389`](https://github.com/nodejs/node/commit/67a1018389)] - **build**: do not pass target toolchain flags to host toolchain (Ivan Trubach) [#48597](https://github.com/nodejs/node/pull/48597) +* \[[`7d843bb942`](https://github.com/nodejs/node/commit/7d843bb942)] - **child\_process**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`4e08160f8c`](https://github.com/nodejs/node/commit/4e08160f8c)] - **child\_process**: support `Symbol.dispose` (Moshe Atlow) [#48551](https://github.com/nodejs/node/pull/48551) +* \[[`ef7728bf36`](https://github.com/nodejs/node/commit/ef7728bf36)] - **deps**: update nghttp2 to 1.55.1 (Node.js GitHub Bot) [#48790](https://github.com/nodejs/node/pull/48790) +* \[[`1454f02499`](https://github.com/nodejs/node/commit/1454f02499)] - **deps**: update nghttp2 to 1.55.0 (Node.js GitHub Bot) [#48746](https://github.com/nodejs/node/pull/48746) +* \[[`fa94debf46`](https://github.com/nodejs/node/commit/fa94debf46)] - **deps**: update minimatch to 9.0.3 (Node.js GitHub Bot) [#48704](https://github.com/nodejs/node/pull/48704) +* \[[`c73cfcc144`](https://github.com/nodejs/node/commit/c73cfcc144)] - **deps**: update acorn to 8.10.0 (Node.js GitHub Bot) [#48713](https://github.com/nodejs/node/pull/48713) +* \[[`b7a076a052`](https://github.com/nodejs/node/commit/b7a076a052)] - **deps**: V8: cherry-pick cb00db4dba6c (Keyhan Vakil) [#48671](https://github.com/nodejs/node/pull/48671) +* \[[`150e15536b`](https://github.com/nodejs/node/commit/150e15536b)] - **deps**: upgrade npm to 9.8.0 (npm team) [#48665](https://github.com/nodejs/node/pull/48665) +* \[[`c47b2cbd35`](https://github.com/nodejs/node/commit/c47b2cbd35)] - **dgram**: socket add `asyncDispose` (atlowChemi) [#48717](https://github.com/nodejs/node/pull/48717) +* \[[`002ce31cca`](https://github.com/nodejs/node/commit/002ce31cca)] - **dgram**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`45be29d89f`](https://github.com/nodejs/node/commit/45be29d89f)] - **doc**: add atlowChemi to collaborators (atlowChemi) [#48757](https://github.com/nodejs/node/pull/48757) +* \[[`69b55d2261`](https://github.com/nodejs/node/commit/69b55d2261)] - **doc**: fix ambiguity in http.md and https.md (an5er) [#48692](https://github.com/nodejs/node/pull/48692) +* \[[`caccb051c7`](https://github.com/nodejs/node/commit/caccb051c7)] - **doc**: clarify transform.\_transform() callback argument logic (Rafael Sofi-zada) [#48680](https://github.com/nodejs/node/pull/48680) +* \[[`999ae0c8c3`](https://github.com/nodejs/node/commit/999ae0c8c3)] - **doc**: fix copy node executable in Windows (Yoav Vainrich) [#48624](https://github.com/nodejs/node/pull/48624) +* \[[`7daefaeb44`](https://github.com/nodejs/node/commit/7daefaeb44)] - **doc**: drop \ of v20 changelog (Rafael Gonzaga) [#48649](https://github.com/nodejs/node/pull/48649) +* \[[`dd7ea3e1df`](https://github.com/nodejs/node/commit/dd7ea3e1df)] - **doc**: mention git node release prepare (Rafael Gonzaga) [#48644](https://github.com/nodejs/node/pull/48644) +* \[[`cc7809df21`](https://github.com/nodejs/node/commit/cc7809df21)] - **esm**: fix emit deprecation on legacy main resolve (Antoine du Hamel) [#48664](https://github.com/nodejs/node/pull/48664) +* \[[`67b13d1dba`](https://github.com/nodejs/node/commit/67b13d1dba)] - **events**: fix bug listenerCount don't compare wrapped listener (yuzheng14) [#48592](https://github.com/nodejs/node/pull/48592) +* \[[`a316808136`](https://github.com/nodejs/node/commit/a316808136)] - **(SEMVER-MINOR)** **events**: allow safely adding listener to abortSignal (Chemi Atlow) [#48596](https://github.com/nodejs/node/pull/48596) +* \[[`986b46a567`](https://github.com/nodejs/node/commit/986b46a567)] - **fs**: add a fast-path for readFileSync utf-8 (Yagiz Nizipli) [#48658](https://github.com/nodejs/node/pull/48658) +* \[[`e4333ac41f`](https://github.com/nodejs/node/commit/e4333ac41f)] - **http2**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`4a0b66e4f9`](https://github.com/nodejs/node/commit/4a0b66e4f9)] - **http2**: send RST code 8 on AbortController signal (Devraj Mehta) [#48573](https://github.com/nodejs/node/pull/48573) +* \[[`1295c76fce`](https://github.com/nodejs/node/commit/1295c76fce)] - **lib**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`dff6c25a36`](https://github.com/nodejs/node/commit/dff6c25a36)] - **meta**: bump actions/checkout from 3.5.2 to 3.5.3 (dependabot\[bot]) [#48625](https://github.com/nodejs/node/pull/48625) +* \[[`b5cb69ceaa`](https://github.com/nodejs/node/commit/b5cb69ceaa)] - **meta**: bump step-security/harden-runner from 2.4.0 to 2.4.1 (dependabot\[bot]) [#48626](https://github.com/nodejs/node/pull/48626) +* \[[`332e480b46`](https://github.com/nodejs/node/commit/332e480b46)] - **meta**: bump ossf/scorecard-action from 2.1.3 to 2.2.0 (dependabot\[bot]) [#48628](https://github.com/nodejs/node/pull/48628) +* \[[`25c5a0aaee`](https://github.com/nodejs/node/commit/25c5a0aaee)] - **meta**: bump github/codeql-action from 2.3.6 to 2.20.1 (dependabot\[bot]) [#48627](https://github.com/nodejs/node/pull/48627) +* \[[`6406f50ab1`](https://github.com/nodejs/node/commit/6406f50ab1)] - **module**: add SourceMap.lineLengths (Isaac Z. Schlueter) [#48461](https://github.com/nodejs/node/pull/48461) +* \[[`cfa69bd48c`](https://github.com/nodejs/node/commit/cfa69bd48c)] - **net**: server add `asyncDispose` (atlowChemi) [#48717](https://github.com/nodejs/node/pull/48717) +* \[[`ac11264cc5`](https://github.com/nodejs/node/commit/ac11264cc5)] - **net**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`82d6b13bf6`](https://github.com/nodejs/node/commit/82d6b13bf6)] - **permission**: add debug log when inserting fs nodes (Rafael Gonzaga) [#48677](https://github.com/nodejs/node/pull/48677) +* \[[`f4333b1cdd`](https://github.com/nodejs/node/commit/f4333b1cdd)] - **permission**: v8.writeHeapSnapshot and process.report (Rafael Gonzaga) [#48564](https://github.com/nodejs/node/pull/48564) +* \[[`f691dca6c9`](https://github.com/nodejs/node/commit/f691dca6c9)] - **readline**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`227e6bd898`](https://github.com/nodejs/node/commit/227e6bd898)] - **src**: pass syscall on `fs.readFileSync` fail operation (Yagiz Nizipli) [#48815](https://github.com/nodejs/node/pull/48815) +* \[[`a9a4b73653`](https://github.com/nodejs/node/commit/a9a4b73653)] - **src**: make BaseObject iteration order deterministic (Joyee Cheung) [#48702](https://github.com/nodejs/node/pull/48702) +* \[[`d99ea4845a`](https://github.com/nodejs/node/commit/d99ea4845a)] - **src**: remove kEagerCompile for CompileFunction (Keyhan Vakil) [#48671](https://github.com/nodejs/node/pull/48671) +* \[[`df363d0010`](https://github.com/nodejs/node/commit/df363d0010)] - **src**: deduplicate X509 getter implementations (Tobias Nießen) [#48563](https://github.com/nodejs/node/pull/48563) +* \[[`9cf2e1f55b`](https://github.com/nodejs/node/commit/9cf2e1f55b)] - **src,lib**: reducing C++ calls of esm legacy main resolve (Vinicius Lourenço) [#48325](https://github.com/nodejs/node/pull/48325) +* \[[`daeb21dde9`](https://github.com/nodejs/node/commit/daeb21dde9)] - **stream**: fix deadlock when pipeing to full sink (Robert Nagy) [#48691](https://github.com/nodejs/node/pull/48691) +* \[[`5a382d02d6`](https://github.com/nodejs/node/commit/5a382d02d6)] - **stream**: use addAbortListener (atlowChemi) [#48550](https://github.com/nodejs/node/pull/48550) +* \[[`6e82077dd4`](https://github.com/nodejs/node/commit/6e82077dd4)] - **test**: deflake test-net-throttle (Luigi Pinca) [#48599](https://github.com/nodejs/node/pull/48599) +* \[[`d378b2c822`](https://github.com/nodejs/node/commit/d378b2c822)] - **test**: move test-net-throttle to parallel (Luigi Pinca) [#48599](https://github.com/nodejs/node/pull/48599) +* \[[`dfa0aee5bf`](https://github.com/nodejs/node/commit/dfa0aee5bf)] - _**Revert**_ "**test**: remove test-crypto-keygen flaky designation" (Luigi Pinca) [#48652](https://github.com/nodejs/node/pull/48652) +* \[[`0ef73ff6f0`](https://github.com/nodejs/node/commit/0ef73ff6f0)] - **(SEMVER-MINOR)** **test\_runner**: add shards support (Raz Luvaton) [#48639](https://github.com/nodejs/node/pull/48639) +* \[[`e2442bb7ef`](https://github.com/nodejs/node/commit/e2442bb7ef)] - **timers**: support Symbol.dispose (Moshe Atlow) [#48633](https://github.com/nodejs/node/pull/48633) +* \[[`4398ade426`](https://github.com/nodejs/node/commit/4398ade426)] - **tools**: run fetch\_deps.py with Python 3 (Richard Lau) [#48729](https://github.com/nodejs/node/pull/48729) +* \[[`38ce95d054`](https://github.com/nodejs/node/commit/38ce95d054)] - **tools**: update doc to unist-util-select\@5.0.0 unist-util-visit\@5.0.0 (Node.js GitHub Bot) [#48714](https://github.com/nodejs/node/pull/48714) +* \[[`b25e78a998`](https://github.com/nodejs/node/commit/b25e78a998)] - **tools**: update lint-md-dependencies to rollup\@3.26.2 (Node.js GitHub Bot) [#48705](https://github.com/nodejs/node/pull/48705) +* \[[`a1f4ff7c59`](https://github.com/nodejs/node/commit/a1f4ff7c59)] - **tools**: update eslint to 8.44.0 (Node.js GitHub Bot) [#48632](https://github.com/nodejs/node/pull/48632) +* \[[`42dc6eb698`](https://github.com/nodejs/node/commit/42dc6eb698)] - **tools**: update lint-md-dependencies to rollup\@3.26.0 (Node.js GitHub Bot) [#48631](https://github.com/nodejs/node/pull/48631) +* \[[`07bfcc45ab`](https://github.com/nodejs/node/commit/07bfcc45ab)] - **url**: fix `canParse` false value when v8 optimizes (Yagiz Nizipli) [#48817](https://github.com/nodejs/node/pull/48817) + ## 2023-07-05, Version 20.4.0 (Current), @RafaelGSS diff --git a/doc/contributing/backporting-to-release-lines.md b/doc/contributing/backporting-to-release-lines.md index d9dea5dbe2b06f..851e4e255442d1 100644 --- a/doc/contributing/backporting-to-release-lines.md +++ b/doc/contributing/backporting-to-release-lines.md @@ -40,10 +40,26 @@ For the following labels, the `N` in `vN.x` refers to the major release number. ## How to submit a backport pull request -For the following steps, let's assume that a backport is needed for the v10.x -release line. All commands will use the `v10.x-staging` branch as the target -branch. In order to submit a backport pull request to another branch, simply -replace that with the staging branch for the targeted release line. +For the following steps, let's assume that you need to backport PR `123` +to the v20.x release line. All commands will use the `v20.x-staging` branch +as the target branch. In order to submit a backport pull request to another +branch, simply replace that with the staging branch for the targeted release +line. + +### Automated + +1. Make sure you have [`@node-core/utils`][] installed + +2. Run the [`git node backport`][] command + +```bash +# Backport PR 123 to v20.x-staging +git node backport 123 --to=20 +``` + +3. Jump to step 5 in the Manual section below + +### Manually 1. Checkout the staging branch for the targeted release line. @@ -56,10 +72,10 @@ replace that with the staging branch for the targeted release line. # the origin remote points to your fork, and the upstream remote points # to git@github.com:nodejs/node.git cd $NODE_DIR - # If v10.x-staging is checked out `pull` should be used instead of `fetch` - git fetch upstream v10.x-staging:v10.x-staging -f + # If v20.x-staging is checked out `pull` should be used instead of `fetch` + git fetch upstream v20.x-staging:v20.x-staging -f # Assume we want to backport PR #10157 - git checkout -b backport-10157-to-v10.x v10.x-staging + git checkout -b backport-10157-to-v20.x v20.x-staging # Ensure there are no test artifacts from previous builds # Note that this command deletes all files and directories # not under revision control below the ./test directory. @@ -93,10 +109,10 @@ replace that with the staging branch for the targeted release line. 8. Push the changes to your fork. 9. Open a pull request: - 1. Be sure to target the `v10.x-staging` branch in the pull request. + 1. Be sure to target the `v20.x-staging` branch in the pull request. 2. Include the backport target in the pull request title in the following - format: `[v10.x backport] `. - Example: `[v10.x backport] process: improve performance of nextTick` + format: `[v20.x backport] `. + Example: `[v20.x backport] process: improve performance of nextTick` 3. Check the checkbox labeled "Allow edits and access to secrets by maintainers". 4. In the description add a reference to the original pull request. @@ -105,15 +121,17 @@ replace that with the staging branch for the targeted release line. 6. Run a [`node-test-pull-request`][] CI job (with `REBASE_ONTO` set to the default ``) -10. Replace the `backport-requested-v10.x` label on the original pull request - with `backport-open-v10.x`. +10. Replace the `backport-requested-v20.x` label on the original pull request + with `backport-open-v20.x`. 11. If during the review process conflicts arise, use the following to rebase: - `git pull --rebase upstream v10.x-staging` + `git pull --rebase upstream v20.x-staging` -After the pull request lands, replace the `backport-open-v10.x` label on the -original pull request with `backported-to-v10.x`. +After the pull request lands, replace the `backport-open-v20.x` label on the +original pull request with `backported-to-v20.x`. [Release Plan]: https://github.com/nodejs/Release#release-plan [Release Schedule]: https://github.com/nodejs/Release#release-schedule +[`@node-core/utils`]: https://github.com/nodejs/node-core-utils +[`git node backport`]: https://github.com/nodejs/node-core-utils/blob/main/docs/git-node.md#git-node-backport [`node-test-pull-request`]: https://ci.nodejs.org/job/node-test-pull-request/build diff --git a/doc/contributing/collaborator-guide.md b/doc/contributing/collaborator-guide.md index a4218acc7d4fd0..2ecf14a082dc3b 100644 --- a/doc/contributing/collaborator-guide.md +++ b/doc/contributing/collaborator-guide.md @@ -555,22 +555,23 @@ See the [commit queue guide][commit-queue.md]. ### Using `git-node` -In most cases, using [the `git-node` command][git-node] of [`node-core-utils`][] -is enough to land a pull request. If you discover a problem when using -this tool, please file an issue [to the issue tracker][node-core-utils-issues]. +In most cases, using [the `git-node` command][git-node] of +[`@node-core/utils`][] is enough to land a pull request. If you discover a +problem when using this tool, please file an issue +[to the issue tracker][node-core-utils-issues]. Quick example: ```bash -npm install -g node-core-utils +npm install -g @node-core/utils git node land $PRID ``` -To use `node-core-utils`, you will need a GitHub access token. If you do not -have one, `node-core-utils` will create one for you the first time you use it. +To use `@node-core/utils`, you will need a GitHub access token. If you do not +have one, `@node-core/utils` will create one for you the first time you use it. To do this, it will ask for your GitHub password and two-factor authentication code. If you wish to create the token yourself in advance, see -[the `node-core-utils` guide][node-core-utils-credentials]. +[the `@node-core/utils` guide][node-core-utils-credentials]. ### Technical HOWTO @@ -959,7 +960,7 @@ need to be attached anymore, as only important bugfixes will be included. [TSC]: https://github.com/nodejs/TSC [`--pending-deprecation`]: ../api/cli.md#--pending-deprecation [`--throw-deprecation`]: ../api/cli.md#--throw-deprecation -[`node-core-utils`]: https://github.com/nodejs/node-core-utils +[`@node-core/utils`]: https://github.com/nodejs/node-core-utils [backporting guide]: backporting-to-release-lines.md [commit message guidelines]: pull-requests.md#commit-message-guidelines [commit-example]: https://github.com/nodejs/node/commit/b636ba8186 diff --git a/doc/contributing/commit-queue.md b/doc/contributing/commit-queue.md index 4730d0889e99aa..cece9ea84e94f8 100644 --- a/doc/contributing/commit-queue.md +++ b/doc/contributing/commit-queue.md @@ -7,8 +7,8 @@ _tl;dr: You can land pull requests by adding the `commit-queue` label to it._ Commit Queue is an experimental feature for the project which simplifies the landing process by automating it via GitHub Actions. With it, collaborators can land pull requests by adding the `commit-queue` label to a PR. All -checks will run via node-core-utils, and if the pull request is ready to land, -the Action will rebase it and push to `main`. +checks will run via `@node-core/utils`, and if the pull request is ready to +land, the Action will rebase it and push to `main`. This document gives an overview of how the Commit Queue works, as well as implementation details, reasoning for design choices, and current limitations. @@ -76,7 +76,7 @@ reasons: commit, meaning we wouldn't be able to use it for already opened PRs without rebasing them first. -`node-core-utils` is configured with a personal token and +`@node-core/utils` is configured with a personal token and a Jenkins token from [@nodejs-github-bot](https://github.com/nodejs/github-bot). `octokit/graphql-action` is used to fetch all pull requests with the diff --git a/doc/contributing/maintaining/maintaining-V8.md b/doc/contributing/maintaining/maintaining-V8.md index 0fe9b393fc0f15..740af7f228f694 100644 --- a/doc/contributing/maintaining/maintaining-V8.md +++ b/doc/contributing/maintaining/maintaining-V8.md @@ -122,7 +122,7 @@ some manual steps and is recommended. Here are the steps for the bug mentioned above: -1. Install `git-node` by installing [`node-core-utils`][]. +1. Install `git-node` by installing [`@node-core/utils`][]. 2. Install the prerequisites for [`git-node-v8`][]. 3. Find the commit hash linked-to in the issue (in this case a51f429). 4. Checkout a branch off the appropriate _vY.x-staging_ branch (e.g. @@ -277,7 +277,7 @@ that Node.js may be floating (or else cause a merge conflict). #### Applying minor updates with `git-node` (recommended) -1. Install [`git-node`][] by installing [`node-core-utils`][]. +1. Install [`git-node`][] by installing [`@node-core/utils`][]. 2. Install the prerequisites for [`git-node-v8`][]. 3. Run `git node v8 minor` to apply a minor update. @@ -384,8 +384,8 @@ This would require some tooling to: [V8MergingPatching]: https://v8.dev/docs/merge-patch [V8TemplateMergeRequest]: https://bugs.chromium.org/p/v8/issues/entry?template=Node.js%20merge%20request [V8TemplateUpstreamBug]: https://bugs.chromium.org/p/v8/issues/entry?template=Node.js%20upstream%20bug +[`@node-core/utils`]: https://github.com/nodejs/node-core-utils#Install [`git-node-v8-backport`]: https://github.com/nodejs/node-core-utils/blob/main/docs/git-node.md#git-node-v8-backport-sha [`git-node-v8-minor`]: https://github.com/nodejs/node-core-utils/blob/main/docs/git-node.md#git-node-v8-minor [`git-node-v8`]: https://github.com/nodejs/node-core-utils/blob/HEAD/docs/git-node.md#git-node-v8 [`git-node`]: https://github.com/nodejs/node-core-utils/blob/HEAD/docs/git-node.md#git-node-v8 -[`node-core-utils`]: https://github.com/nodejs/node-core-utils#Install diff --git a/doc/contributing/maintaining/maintaining-dependencies.md b/doc/contributing/maintaining/maintaining-dependencies.md index 7f28a17d5ed916..6271f05ce36326 100644 --- a/doc/contributing/maintaining/maintaining-dependencies.md +++ b/doc/contributing/maintaining/maintaining-dependencies.md @@ -9,29 +9,29 @@ All dependencies are located within the `deps` directory. This a list of all the dependencies: * [acorn 8.10.0][] -* [ada 2.5.0][] +* [ada 2.6.0][] * [base64 0.5.0][] * [brotli 1.0.9][] * [c-ares 1.19.0][] * [cjs-module-lexer 1.2.2][] * [corepack][] -* [googletest ec4fed9][] +* [googletest d1467f5][] * [histogram 0.11.8][] * [icu-small 73.2][] * [libuv 1.46.0][] -* [llhttp 8.1.0][] +* [llhttp 9.1.2][] * [minimatch 9.0.3][] -* [nghttp2 1.55.0][] +* [nghttp2 1.56.0][] * [nghttp3 0.7.0][] * [ngtcp2 0.8.1][] * [npm 9.6.7][] * [openssl 3.0.8][] * [postject 1.0.0-alpha.6][] -* [simdutf 3.2.14][] -* [undici 5.22.1][] +* [simdutf 3.2.17][] +* [undici 5.25.2][] * [uvwasi 0.0.16][] * [V8 11.3.244.8][] -* [zlib 1.2.13.1-motley-f81f385][] +* [zlib 1.2.13.1-motley-f5fd0ad][] Any code which meets one or more of these conditions should be managed as a dependency: @@ -150,7 +150,7 @@ The [acorn](https://github.com/acornjs/acorn) dependency is a JavaScript parser. [acorn-walk](https://github.com/acornjs/acorn/tree/master/acorn-walk) is an abstract syntax tree walker for the ESTree format. -### ada 2.5.0 +### ada 2.6.0 The [ada](https://github.com/ada-url/ada) dependency is a fast and spec-compliant URL parser written in C++. @@ -189,7 +189,7 @@ In practical terms, Corepack will let you use Yarn and pnpm without having to install them - just like what currently happens with npm, which is shipped by Node.js by default. -### googletest ec4fed9 +### googletest d1467f5 The [googletest](https://github.com/google/googletest) dependency is Google’s C++ testing and mocking framework. @@ -212,7 +212,7 @@ The [libuv](https://github.com/libuv/libuv) dependency is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by Node.js. -### llhttp 8.1.0 +### llhttp 9.1.2 The [llhttp](https://github.com/nodejs/llhttp) dependency is the http parser used by Node.js. @@ -223,7 +223,7 @@ See [maintaining-http][] for more informations. The [minimatch](https://github.com/isaacs/minimatch) dependency is a minimal matching utility. -### nghttp2 1.55.0 +### nghttp2 1.56.0 The [nghttp2](https://github.com/nghttp2/nghttp2) dependency is a C library implementing HTTP/2 protocol. @@ -286,12 +286,12 @@ See [maintaining-openssl][] for more informations. The [postject](https://github.com/nodejs/postject) dependency is used for the [Single Executable strategic initiative](https://github.com/nodejs/single-executable). -### simdutf 3.2.14 +### simdutf 3.2.17 The [simdutf](https://github.com/simdutf/simdutf) dependency is a C++ library for fast UTF-8 decoding and encoding. -### undici 5.22.1 +### undici 5.25.2 The [undici](https://github.com/nodejs/undici) dependency is an HTTP/1.1 client, written from scratch for Node.js.. @@ -311,7 +311,7 @@ See [maintaining-web-assembly][] for more informations. high-performance JavaScript and WebAssembly engine, written in C++. See [maintaining-V8][] for more informations. -### zlib 1.2.13.1-motley-f81f385 +### zlib 1.2.13.1-motley-f5fd0ad The [zlib](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/zlib) dependency lossless data-compression library, @@ -319,18 +319,18 @@ it comes from the Chromium team's zlib fork which incorporated performance improvements not currently available in standard zlib. [acorn 8.10.0]: #acorn-8100 -[ada 2.5.0]: #ada-250 +[ada 2.6.0]: #ada-260 [base64 0.5.0]: #base64-050 [brotli 1.0.9]: #brotli-109 [c-ares 1.19.0]: #c-ares-1190 [cjs-module-lexer 1.2.2]: #cjs-module-lexer-122 [corepack]: #corepack [dependency-update-action]: ../../../.github/workflows/tools.yml -[googletest ec4fed9]: #googletest-ec4fed9 +[googletest d1467f5]: #googletest-d1467f5 [histogram 0.11.8]: #histogram-0118 [icu-small 73.2]: #icu-small-732 [libuv 1.46.0]: #libuv-1460 -[llhttp 8.1.0]: #llhttp-810 +[llhttp 9.1.2]: #llhttp-912 [maintaining-V8]: ./maintaining-V8.md [maintaining-cjs-module-lexer]: ./maintaining-cjs-module-lexer.md [maintaining-http]: ./maintaining-http.md @@ -338,15 +338,15 @@ performance improvements not currently available in standard zlib. [maintaining-openssl]: ./maintaining-openssl.md [maintaining-web-assembly]: ./maintaining-web-assembly.md [minimatch 9.0.3]: #minimatch-903 -[nghttp2 1.55.0]: #nghttp2-1550 +[nghttp2 1.56.0]: #nghttp2-1560 [nghttp3 0.7.0]: #nghttp3-070 [ngtcp2 0.8.1]: #ngtcp2-081 [npm 9.6.7]: #npm-967 [openssl 3.0.8]: #openssl-308 [postject 1.0.0-alpha.6]: #postject-100-alpha6 -[simdutf 3.2.14]: #simdutf-3214 -[undici 5.22.1]: #undici-5221 +[simdutf 3.2.17]: #simdutf-3217 +[undici 5.25.2]: #undici-5252 [update-openssl-action]: ../../../.github/workflows/update-openssl.yml [uvwasi 0.0.16]: #uvwasi-0016 [v8 11.3.244.8]: #v8-1132448 -[zlib 1.2.13.1-motley-f81f385]: #zlib-12131-motley-f81f385 +[zlib 1.2.13.1-motley-f5fd0ad]: #zlib-12131-motley-f5fd0ad diff --git a/doc/contributing/maintaining/maintaining-openssl.md b/doc/contributing/maintaining/maintaining-openssl.md index b6de7ae340ef01..2814634dd76a03 100644 --- a/doc/contributing/maintaining/maintaining-openssl.md +++ b/doc/contributing/maintaining/maintaining-openssl.md @@ -13,8 +13,6 @@ currently need to generate four PRs as follows: of this guide. * a PR for 16.x following the instructions in the v16.x-staging version of this guide. -* a PR for 14.x following the instructions in the [v14.x-staging version][] - of this guide. ## Use of the quictls/openssl fork @@ -158,4 +156,3 @@ regenerated and committed by: Finally, build Node.js and run the tests. [update-openssl-action]: ../../../.github/workflows/update-openssl.yml -[v14.x-staging version]: https://github.com/nodejs/node/blob/v14.x-staging/doc/guides/maintaining-openssl.md diff --git a/doc/contributing/pull-requests.md b/doc/contributing/pull-requests.md index c35fda734f3173..a2bd63d3572393 100644 --- a/doc/contributing/pull-requests.md +++ b/doc/contributing/pull-requests.md @@ -34,9 +34,11 @@ ## Dependencies Node.js has several bundled dependencies in the _deps/_ and the _tools/_ -directories that are not part of the project proper. Changes to files in those -directories should be sent to their respective projects. Do not send a patch to -Node.js. We cannot accept such patches. +directories that are not part of the project proper. +These are detailed in the [maintaining dependencies][] document. +Changes to files in those directories should be sent +to their respective projects. +Do not send a patch to Node.js. We cannot accept such patches. In case of doubt, open an issue in the [issue tracker](https://github.com/nodejs/node/issues/) or contact one of the @@ -590,6 +592,7 @@ More than one subsystem may be valid for any particular issue or pull request. [guide for writing tests in Node.js]: writing-tests.md [hiding-a-comment]: https://help.github.com/articles/managing-disruptive-comments/#hiding-a-comment [https://ci.nodejs.org/]: https://ci.nodejs.org/ +[maintaining dependencies]: ./maintaining/maintaining-dependencies.md [nodejs/core-validate-commit]: https://github.com/nodejs/core-validate-commit/blob/main/lib/rules/subsystem.js [pull request template]: https://raw.githubusercontent.com/nodejs/node/HEAD/.github/PULL_REQUEST_TEMPLATE.md [running tests]: ../../BUILDING.md#running-tests diff --git a/doc/contributing/releases-node-api.md b/doc/contributing/releases-node-api.md index 265c2b120e4c18..f2277b228ec0d6 100644 --- a/doc/contributing/releases-node-api.md +++ b/doc/contributing/releases-node-api.md @@ -9,7 +9,7 @@ release process. * [0. Pre-release steps](#0-pre-release-steps) * [1. Update the main branch](#1-update-the-main-branch) * [2. Create a new branch for the release](#2-create-a-new-branch-for-the-release) - * [3. Update `NAPI_VERSION`](#3-update-napi_version) + * [3. Update `NODE_API_SUPPORTED_VERSION_MAX`](#3-update-node_api_supported_version_max) * [4. Define `addon_context_register_func`](#4-define-addon_context_register_func) * [5. Update version guards](#5-update-version-guards) * [6. Create release commit](#6-create-release-commit) @@ -55,13 +55,13 @@ Create a new branch named `node-api-x-proposal`, off the main branch. git checkout -b node-api-10-proposal upstream/main ``` -### 3. Update `NAPI_VERSION` +### 3. Update `NODE_API_SUPPORTED_VERSION_MAX` Set the version for the proposed release using the following macros, which are already defined in `src/node_version.h`: ```c -#define NAPI_VERSION x +#define NODE_API_SUPPORTED_VERSION_MAX x ``` > Note: Do not update the `NAPI_VERSION` defined in `src/js_native_api.h`. It diff --git a/doc/contributing/releases.md b/doc/contributing/releases.md index 00fd536c2a0a50..bf34bff850c678 100644 --- a/doc/contributing/releases.md +++ b/doc/contributing/releases.md @@ -182,10 +182,10 @@ metadata, as well as the GitHub labels such as `semver-minor` and omitted from a commit, the commit will show up because it's unsure if it's a duplicate or not. -For a list of commits that could be landed in a patch release on v1.x: +For a list of commits that could be landed in a minor release on v1.x: ```bash -branch-diff v1.x-staging main --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=simple +branch-diff v1.x-staging main --exclude-label=semver-major,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=simple ``` Previously released commits and version bumps do not need to be @@ -201,13 +201,15 @@ Carefully review the list of commits: `baking-for-lts` tag. When you are ready to cherry-pick commits, you can automate with the following -command. (For semver-minor releases, make sure to remove the `semver-minor` tag -from `exclude-label`.) +command. ```bash -branch-diff v1.x-staging main --exclude-label=semver-major,semver-minor,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=sha --reverse | xargs git cherry-pick +branch-diff v1.x-staging main --exclude-label=semver-major,dont-land-on-v1.x,backport-requested-v1.x,backport-blocked-v1.x,backport-open-v1.x,backported-to-v1.x --filter-release --format=sha --reverse | xargs git cherry-pick ``` +For patch releases, make sure to add the `semver-minor` tag +to `exclude-label` + When cherry-picking commits, if there are simple conflicts you can resolve them. Otherwise, add the `backport-requested-vN.x` label to the original PR and post a comment stating that it does not land cleanly and will require a @@ -561,7 +563,7 @@ ecosystem. Use `ncu-ci` to compare `vx.x` run (10) and proposal branch (11) ```bash -npm i -g node-core-utils +npm i -g @node-core/utils ncu-ci citgm 10 11 ``` @@ -813,7 +815,9 @@ git commit --amend Even if there are no conflicts, ensure that you revert all the changes that were -made to `src/node_version.h`. +made to `src/node_version.h`. `NODE_VERSION_IS_RELEASE` must be `0`. + +Edit `src/node_version.h`, revert `NODE_VERSION_IS_RELEASE` back to `0`, and `git commit --amend` If there are conflicts in `doc` due to updated `REPLACEME` placeholders (that happens when a change previously landed on another release @@ -997,9 +1001,13 @@ This script will use the promoted builds and changelog to generate the post. Run Refs: ``` +* In order to trigger the CI Checks of the [nodejs.org repository][]; Please + attach the `github_actions:pull-request` label to the PR. + * Changes to the base branch, `main`, on the [nodejs.org repository][] will - trigger a new build of nodejs.org so your changes should appear a few minutes - after pushing. + trigger a new build of nodejs.org, so your changes should appear a few minutes + after pushing. You can follow the [Deployments](https://github.com/nodejs/nodejs.org/deployments) page + to see when the build finishes and gets published. ### 18. Create the release on GitHub @@ -1044,7 +1052,7 @@ _In whatever form you do this..._ ### Marking a release line as LTS The process of marking a release line as LTS has been automated using -[node-core-utils](https://github.com/nodejs/node-core-utils). +[`@node-core/utils`](https://github.com/nodejs/node-core-utils). Start by checking out the staging branch for the release line that is going to be marked as LTS, e.g: @@ -1053,10 +1061,10 @@ be marked as LTS, e.g: git checkout v1.x-staging ``` -Next, make sure you have **node-core-utils** installed: +Next, make sure you have **`@node-core/utils`** installed: ```bash -npm i -g node-core-utils +npm i -g @node-core/utils ``` Run the prepare LTS release command: @@ -1102,7 +1110,7 @@ current LTS codename in its release line changelog file. The `test/parallel/test-process-release.js` file might also need to be updated. -In case you can not run the automated `node-core-utils` command and you are +In case you can not run the automated `@node-core/utils` command and you are currently running these steps manually it's a good idea to refer to previous LTS proposal PRs and make sure all required changes are covered. diff --git a/doc/contributing/security-release-process.md b/doc/contributing/security-release-process.md index 1f54aae33f6cd6..fd33f3ccbb5afd 100644 --- a/doc/contributing/security-release-process.md +++ b/doc/contributing/security-release-process.md @@ -29,7 +29,7 @@ The current security stewards are documented in the main Node.js | NodeSource | Juan | 2022-Nov-04 | | RH and IBM | Michael | 2023-Feb-16 | | NearForm | Rafael | 2023-Jun-20 | -| NearForm | Rafael | | +| NearForm | Rafael | 2023-Aug-09 | | Datadog | Bryan | | | IBM | Joe | | | Platformatic | Matteo | | @@ -56,6 +56,8 @@ The current security stewards are documented in the main Node.js * [ ] pre-release: _**LINK TO PR**_ * [ ] post-release: _**LINK TO PR**_ * List vulnerabilities in order of descending severity + * Use the "summary" feature in HackerOne to sync post-release content + and CVE requests. Example [2038134](https://hackerone.com/bugs?subject=nodejs\&report_id=2038134) * Ask the HackerOne reporter if they would like to be credited on the security release blog page: ```text @@ -70,8 +72,6 @@ The current security stewards are documented in the main Node.js ## Announcement (one week in advance of the planned release) -* [ ] Verify that GitHub Actions are working as normal: . - * [ ] Check that all vulnerabilities are ready for release integration: * PRs against all affected release lines or cherry-pick clean * Approved @@ -81,6 +81,9 @@ The current security stewards are documented in the main Node.js between Security Releases. * Pass `make test` * Have CVEs + * Use the "summary" feature in HackerOne to create a description for the + CVE and the post release announcement. + Example [2038134](https://hackerone.com/bugs?subject=nodejs\&report_id=2038134) * Make sure that dependent libraries have CVEs for their issues. We should only create CVEs for vulnerabilities in Node.js itself. This is to avoid having duplicate CVEs for the same vulnerability. @@ -117,7 +120,7 @@ The google groups UI does not support adding a CC, until we figure out a better way, forward the email you receive to `oss-security@lists.openwall.com` as a CC. -* [ ] Create a new issue in [nodejs/tweet][] +* [ ] Send a message to `#nodejs-social` in OpenJS Foundation slack ```text Security release pre-alert: diff --git a/doc/contributing/sharing-project-news.md b/doc/contributing/sharing-project-news.md index 4630ccdfa18620..270f290e5584f3 100644 --- a/doc/contributing/sharing-project-news.md +++ b/doc/contributing/sharing-project-news.md @@ -31,3 +31,4 @@ that promotes a specific company or commercial interest. * [node-api/node-addon-api](https://github.com/nodejs/abi-stable-node/issues/446). * [uvwasi](https://github.com/nodejs/uvwasi/issues/201). * [security-team](https://github.com/nodejs/security-wg/issues/1006). +* [diagnostics team](https://github.com/nodejs/diagnostics/issues/619). diff --git a/doc/contributing/strategic-initiatives.md b/doc/contributing/strategic-initiatives.md index b005040d54b479..ca4308daa3ebb8 100644 --- a/doc/contributing/strategic-initiatives.md +++ b/doc/contributing/strategic-initiatives.md @@ -6,16 +6,17 @@ agenda to ensure they are active and have the support they need. ## Current initiatives -| Initiative | Champion | Links | -| ---------------------- | --------------------------- | --------------------------------------------- | -| Core Promise APIs | [Antoine du Hamel][aduh95] | | -| QUIC / HTTP3 | [James M Snell][jasnell] | | -| Shadow Realm | [Chengzhong Wu][legendecas] | | -| Startup Snapshot | [Joyee Cheung][joyeecheung] | | -| V8 Currency | [Michaël Zasso][targos] | | -| Next-10 | [Michael Dawson][mhdawson] | | -| Single executable apps | [Darshan Sen][RaisinTen] | | -| Performance | [Yagiz Nizipli][anonrig] | | +| Initiative | Champion | Links | +| ---------------------- | -------------------------------- | ------------------------------------------------- | +| Core Promise APIs | [Antoine du Hamel][aduh95] | | +| QUIC / HTTP3 | [James M Snell][jasnell] | | +| Shadow Realm | [Chengzhong Wu][legendecas] | | +| Startup Snapshot | [Joyee Cheung][joyeecheung] | | +| V8 Currency | [Michaël Zasso][targos] | | +| Next-10 | [Michael Dawson][mhdawson] | | +| Single executable apps | [Darshan Sen][RaisinTen] | | +| Performance | | | +| Primordials | [Benjamin Gruenbaum][benjamingr] | |
List of completed initiatives @@ -40,7 +41,7 @@ agenda to ensure they are active and have the support they need. [RaisinTen]: https://github.com/RaisinTen [aduh95]: https://github.com/aduh95 -[anonrig]: https://github.com/anonrig +[benjamingr]: https://github.com/benjamingr [jasnell]: https://github.com/jasnell [joyeecheung]: https://github.com/joyeecheung [legendecas]: https://github.com/legendecas diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml index 2b77dce6967d7b..0d9443ed413912 100644 --- a/lib/.eslintrc.yaml +++ b/lib/.eslintrc.yaml @@ -179,6 +179,10 @@ rules: message: Use `const { structuredClone } = require('internal/structured_clone');` instead of the global. - name: SubtleCrypto message: Use `const { SubtleCrypto } = require('internal/crypto/webcrypto');` instead of the global. + no-restricted-modules: + - error + - name: url + message: Require `internal/url` instead of `url`. # Custom rules in tools/eslint-rules node-core/avoid-prototype-pollution: error node-core/lowercase-name-for-primitive: error diff --git a/lib/_http_server.js b/lib/_http_server.js index 0242e7a089dd6f..c62ea17599512f 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -500,14 +500,16 @@ function storeHTTPOptions(options) { } } -function setupConnectionsTracking(server) { +function setupConnectionsTracking() { // Start connection handling - server[kConnections] = new ConnectionsList(); + if (!this[kConnections]) { + this[kConnections] = new ConnectionsList(); + } // This checker is started without checking whether any headersTimeout or requestTimeout is non zero // otherwise it would not be started if such timeouts are modified after createServer. - server[kConnectionsCheckingInterval] = - setInterval(checkConnections.bind(server), server.connectionsCheckingInterval).unref(); + this[kConnectionsCheckingInterval] = + setInterval(checkConnections.bind(this), this.connectionsCheckingInterval).unref(); } function httpServerPreClose(server) { @@ -545,11 +547,12 @@ function Server(options, requestListener) { this.httpAllowHalfOpen = false; this.on('connection', connectionListener); + this.on('listening', setupConnectionsTracking); this.timeout = 0; this.maxHeadersCount = null; this.maxRequestsPerSocket = 0; - setupConnectionsTracking(this); + this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders); } ObjectSetPrototypeOf(Server.prototype, net.Server.prototype); @@ -565,6 +568,10 @@ Server.prototype[SymbolAsyncDispose] = async function() { }; Server.prototype.closeAllConnections = function() { + if (!this[kConnections]) { + return; + } + const connections = this[kConnections].all(); for (let i = 0, l = connections.length; i < l; i++) { @@ -573,6 +580,10 @@ Server.prototype.closeAllConnections = function() { }; Server.prototype.closeIdleConnections = function() { + if (!this[kConnections]) { + return; + } + const connections = this[kConnections].idle(); for (let i = 0, l = connections.length; i < l; i++) { diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 1975e823ee588e..c2dd958f95106e 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -545,17 +545,28 @@ function TLSSocket(socket, opts) { this[kPendingSession] = null; let wrap; - if ((socket instanceof net.Socket && socket._handle) || !socket) { - // 1. connected socket - // 2. no socket, one will be created with net.Socket().connect - wrap = socket; + let handle; + let wrapHasActiveWriteFromPrevOwner; + + if (socket) { + if (socket instanceof net.Socket && socket._handle) { + // 1. connected socket + wrap = socket; + } else { + // 2. socket has no handle so it is js not c++ + // 3. unconnected sockets are wrapped + // TLS expects to interact from C++ with a net.Socket that has a C++ stream + // handle, but a JS stream doesn't have one. Wrap it up to make it look like + // a socket. + wrap = new JSStreamSocket(socket); + } + + handle = wrap._handle; + wrapHasActiveWriteFromPrevOwner = wrap.writableLength > 0; } else { - // 3. socket has no handle so it is js not c++ - // 4. unconnected sockets are wrapped - // TLS expects to interact from C++ with a net.Socket that has a C++ stream - // handle, but a JS stream doesn't have one. Wrap it up to make it look like - // a socket. - wrap = new JSStreamSocket(socket); + // 4. no socket, one will be created with net.Socket().connect + wrap = null; + wrapHasActiveWriteFromPrevOwner = false; } // Just a documented property to make secure sockets @@ -563,7 +574,7 @@ function TLSSocket(socket, opts) { this.encrypted = true; ReflectApply(net.Socket, this, [{ - handle: this._wrapHandle(wrap), + handle: this._wrapHandle(wrap, handle, wrapHasActiveWriteFromPrevOwner), allowHalfOpen: socket ? socket.allowHalfOpen : tlsOptions.allowHalfOpen, pauseOnCreate: tlsOptions.pauseOnConnect, manualStart: true, @@ -582,6 +593,21 @@ function TLSSocket(socket, opts) { if (enableTrace && this._handle) this._handle.enableTrace(); + if (wrapHasActiveWriteFromPrevOwner) { + // `wrap` is a streams.Writable in JS. This empty write will be queued + // and hence finish after all existing writes, which is the timing + // we want to start to send any tls data to `wrap`. + wrap.write('', (err) => { + if (err) { + debug('error got before writing any tls data to the underlying stream'); + this.destroy(err); + return; + } + + this._handle.writesIssuedByPrevListenerDone(); + }); + } + // Read on next tick so the caller has a chance to setup listeners process.nextTick(initRead, this, socket); } @@ -642,11 +668,14 @@ TLSSocket.prototype.disableRenegotiation = function disableRenegotiation() { this[kDisableRenegotiation] = true; }; -TLSSocket.prototype._wrapHandle = function(wrap, handle) { - if (!handle && wrap) { - handle = wrap._handle; - } - +/** + * + * @param {null|net.Socket} wrap + * @param {null|object} handle + * @param {boolean} wrapHasActiveWriteFromPrevOwner + * @returns {object} + */ +TLSSocket.prototype._wrapHandle = function(wrap, handle, wrapHasActiveWriteFromPrevOwner) { const options = this._tlsOptions; if (!handle) { handle = options.pipe ? @@ -663,7 +692,10 @@ TLSSocket.prototype._wrapHandle = function(wrap, handle) { if (!(context.context instanceof NativeSecureContext)) { throw new ERR_TLS_INVALID_CONTEXT('context'); } - const res = tls_wrap.wrap(handle, context.context, !!options.isServer); + + const res = tls_wrap.wrap(handle, context.context, + !!options.isServer, + wrapHasActiveWriteFromPrevOwner); res._parent = handle; // C++ "wrap" object: TCPWrap, JSStream, ... res._parentWrap = wrap; // JS object: net.Socket, JSStreamSocket, ... res._secureContext = context; @@ -672,6 +704,9 @@ TLSSocket.prototype._wrapHandle = function(wrap, handle) { defineHandleReading(this, handle); this.on('close', onSocketCloseDestroySSL); + if (wrap) { + wrap.on('close', () => this.destroy()); + } return res; }; @@ -680,7 +715,7 @@ TLSSocket.prototype[kReinitializeHandle] = function reinitializeHandle(handle) { const originalServername = this.ssl ? this._handle.getServername() : null; const originalSession = this.ssl ? this._handle.getSession() : null; - this.handle = this._wrapHandle(null, handle); + this.handle = this._wrapHandle(null, handle, false); this.ssl = this._handle; net.Socket.prototype[kReinitializeHandle].call(this, this.handle); @@ -799,10 +834,7 @@ TLSSocket.prototype._init = function(socket, wrap) { ssl.handshakes = 0; if (options.ALPNCallback) { - if (typeof options.ALPNCallback !== 'function') { - throw new ERR_INVALID_ARG_TYPE('options.ALPNCallback', 'Function', options.ALPNCallback); - } - assert(typeof options.ALPNCallback === 'function'); + validateFunction(options.ALPNCallback, 'options.ALPNCallback'); this[kALPNCallback] = options.ALPNCallback; ssl.ALPNCallback = callALPNCallback; ssl.enableALPNCb(); @@ -1656,14 +1688,12 @@ function onConnectSecure() { debug('client emit secureConnect. rejectUnauthorized: %s, ' + 'authorizationError: %s', options.rejectUnauthorized, this.authorizationError); - this.secureConnecting = false; - this.emit('secureConnect'); } else { this.authorized = true; debug('client emit secureConnect. authorized:', this.authorized); - this.secureConnecting = false; - this.emit('secureConnect'); } + this.secureConnecting = false; + this.emit('secureConnect'); this[kIsVerified] = true; const session = this[kPendingSession]; diff --git a/lib/child_process.js b/lib/child_process.js index 5bdc474c80169c..449013906e93e5 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -103,7 +103,7 @@ let addAbortListener; * @param {string|URL} modulePath * @param {string[]} [args] * @param {{ - * cwd?: string; + * cwd?: string | URL; * detached?: boolean; * env?: Record; * execPath?: string; @@ -305,7 +305,7 @@ function normalizeExecFileArgs(file, args, options, callback) { * @param {string} file * @param {string[]} [args] * @param {{ - * cwd?: string; + * cwd?: string | URL; * env?: Record; * encoding?: string; * timeout?: number; @@ -733,7 +733,7 @@ function abortChildProcess(child, killSignal, reason) { * @param {string} file * @param {string[]} [args] * @param {{ - * cwd?: string; + * cwd?: string | URL; * env?: Record; * argv0?: string; * stdio?: Array | string; @@ -803,7 +803,7 @@ function spawn(file, args, options) { * @param {string} file * @param {string[]} [args] * @param {{ - * cwd?: string; + * cwd?: string | URL; * input?: string | Buffer | TypedArray | DataView; * argv0?: string; * stdio?: string | Array; @@ -897,7 +897,7 @@ function checkExecSyncError(ret, args, cmd) { * @param {string} file * @param {string[]} [args] * @param {{ - * cwd?: string; + * cwd?: string | URL; * input?: string | Buffer | TypedArray | DataView; * stdio?: string | Array; * env?: Record; @@ -935,7 +935,7 @@ function execFileSync(file, args, options) { * Spawns a shell executing the given `command` synchronously. * @param {string} command * @param {{ - * cwd?: string; + * cwd?: string | URL; * input?: string | Buffer | TypedArray | DataView; * stdio?: string | Array; * env?: Record; diff --git a/lib/diagnostics_channel.js b/lib/diagnostics_channel.js index b399c1e2f87ad3..10d35054f56535 100644 --- a/lib/diagnostics_channel.js +++ b/lib/diagnostics_channel.js @@ -28,7 +28,7 @@ const { const { triggerUncaughtException } = internalBinding('errors'); -const { WeakReference } = internalBinding('util'); +const { WeakReference } = require('internal/util'); // Can't delete when weakref count reaches 0 as it could increment again. // Only GC can be used as a valid time to clean up the channels map. @@ -136,7 +136,7 @@ class ActiveChannel { } publish(data) { - for (let i = 0; i < this._subscribers.length; i++) { + for (let i = 0; i < (this._subscribers?.length || 0); i++) { try { const onMessage = this._subscribers[i]; onMessage(data, this.name); diff --git a/lib/domain.js b/lib/domain.js index 51565795d72010..7da672a3691560 100644 --- a/lib/domain.js +++ b/lib/domain.js @@ -52,9 +52,8 @@ const { const { createHook } = require('async_hooks'); const { useDomainTrampoline } = require('internal/async_hooks'); -// TODO(addaleax): Use a non-internal solution for this. const kWeak = Symbol('kWeak'); -const { WeakReference } = internalBinding('util'); +const { WeakReference } = require('internal/util'); // Overwrite process.domain with a getter/setter that will allow for more // effective optimizations diff --git a/lib/fs.js b/lib/fs.js index 3f4a6163ba3f65..9b6b61dc8efd42 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -105,7 +105,6 @@ const { getValidatedPath, getValidMode, handleErrorFromBinding, - nullCheck, possiblyTransformPath, preprocessSymlinkDestination, Stats, @@ -132,7 +131,7 @@ const { CHAR_BACKWARD_SLASH, } = require('internal/constants'); const { - isUint32, + isInt32, parseFileMode, validateBoolean, validateBuffer, @@ -142,7 +141,7 @@ const { validateObject, validateString, } = require('internal/validators'); -const { readFileSyncUtf8 } = require('internal/fs/read/utf8'); +const syncFs = require('internal/fs/sync'); let truncateWarn = true; let fs; @@ -202,7 +201,7 @@ function makeStatsCallback(cb) { }; } -const isFd = isUint32; +const isFd = isInt32; function isFileType(stats, fileType) { // Use stats array directly to avoid creating an fs.Stats instance just for @@ -244,12 +243,7 @@ function access(path, mode, callback) { * @returns {void} */ function accessSync(path, mode) { - path = getValidatedPath(path); - mode = getValidMode(mode, 'access'); - - const ctx = { path }; - binding.access(pathModule.toNamespacedPath(path), mode, undefined, ctx); - handleErrorFromBinding(ctx); + syncFs.access(path, mode); } /** @@ -291,23 +285,7 @@ ObjectDefineProperty(exists, kCustomPromisifiedSymbol, { * @returns {boolean} */ function existsSync(path) { - try { - path = getValidatedPath(path); - } catch { - return false; - } - const ctx = { path }; - const nPath = pathModule.toNamespacedPath(path); - binding.access(nPath, F_OK, undefined, ctx); - - // In case of an invalid symlink, `binding.access()` on win32 - // will **not** return an error and is therefore not enough. - // Double check with `binding.stat()`. - if (isWindows && ctx.errno === undefined) { - binding.stat(nPath, false, undefined, ctx); - } - - return ctx.errno === undefined; + return syncFs.exists(path); } function readFileAfterOpen(err, fd) { @@ -459,14 +437,11 @@ function tryReadSync(fd, isUserFd, buffer, pos, len) { function readFileSync(path, options) { options = getOptions(options, { flag: 'r' }); - const isUserFd = isFd(path); // File descriptor ownership - - // TODO(@anonrig): Do not handle file descriptor ownership for now. - if (!isUserFd && (options.encoding === 'utf8' || options.encoding === 'utf-8')) { - path = getValidatedPath(path); - return readFileSyncUtf8(pathModule.toNamespacedPath(path), stringToFlags(options.flag)); + if (options.encoding === 'utf8' || options.encoding === 'utf-8') { + return syncFs.readFileUtf8(path, options.flag); } + const isUserFd = isFd(path); // File descriptor ownership const fd = isUserFd ? path : fs.openSync(path, options.flag, 0o666); const stats = tryStatSync(fd, isUserFd); @@ -541,11 +516,7 @@ function close(fd, callback = defaultCloseCallback) { * @returns {void} */ function closeSync(fd) { - fd = getValidatedFd(fd); - - const ctx = {}; - binding.close(fd, undefined, ctx); - handleErrorFromBinding(ctx); + return syncFs.close(fd); } /** @@ -591,20 +562,14 @@ function open(path, flags, mode, callback) { * @returns {number} */ function openSync(path, flags, mode) { - path = getValidatedPath(path); - const flagsNumber = stringToFlags(flags); - mode = parseFileMode(mode, 'mode', 0o666); - - const ctx = { path }; - const result = binding.open(pathModule.toNamespacedPath(path), - flagsNumber, mode, - undefined, ctx); - handleErrorFromBinding(ctx); - return result; + return syncFs.open(path, flags, mode); } /** * @param {string | Buffer | URL } path + * @param {{ + * type?: string; + * }} [options] * @returns {Promise} */ function openAsBlob(path, options = kEmptyObject) { @@ -1420,14 +1385,12 @@ function mkdirSync(path, options) { /** * An iterative algorithm for reading the entire contents of the `basePath` directory. * This function does not validate `basePath` as a directory. It is passed directly to - * `binding.readdir` after a `nullCheck`. + * `binding.readdir`. * @param {string} basePath * @param {{ encoding: string, withFileTypes: boolean }} options * @returns {string[] | Dirent[]} */ function readdirSyncRecursive(basePath, options) { - nullCheck(basePath, 'path', true); - const withFileTypes = Boolean(options.withFileTypes); const encoding = options.encoding; @@ -1446,14 +1409,21 @@ function readdirSyncRecursive(basePath, options) { ); handleErrorFromBinding(ctx); - for (let i = 0; i < readdirResult.length; i++) { - if (withFileTypes) { + if (withFileTypes) { + // Calling `readdir` with `withFileTypes=true`, the result is an array of arrays. + // The first array is the names, and the second array is the types. + // They are guaranteed to be the same length; hence, setting `length` to the length + // of the first array within the result. + const length = readdirResult[0].length; + for (let i = 0; i < length; i++) { const dirent = getDirent(path, readdirResult[0][i], readdirResult[1][i]); ArrayPrototypePush(readdirResults, dirent); if (dirent.isDirectory()) { ArrayPrototypePush(pathsQueue, pathModule.join(dirent.path, dirent.name)); } - } else { + } + } else { + for (let i = 0; i < readdirResult.length; i++) { const resultPath = pathModule.join(path, readdirResult[i]); const relativeResultPath = pathModule.relative(basePath, resultPath); const stat = binding.internalModuleStat(resultPath); @@ -1695,25 +1665,12 @@ function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) { * }} [options] * @returns {Stats} */ -function statSync(path, options = { bigint: false, throwIfNoEntry: true }) { - path = getValidatedPath(path); - const ctx = { path }; - const stats = binding.stat(pathModule.toNamespacedPath(path), - options.bigint, undefined, ctx); - if (options.throwIfNoEntry === false && hasNoEntryError(ctx)) { - return undefined; - } - handleErrorFromBinding(ctx); - return getStatsFromBinding(stats); +function statSync(path, options) { + return syncFs.stat(path, options); } -function statfsSync(path, options = { bigint: false }) { - path = getValidatedPath(path); - const ctx = { path }; - const stats = binding.statfs(pathModule.toNamespacedPath(path), - options.bigint, undefined, ctx); - handleErrorFromBinding(ctx); - return getStatFsFromBinding(stats); +function statfsSync(path, options) { + return syncFs.statfs(path, options); } /** @@ -2902,7 +2859,7 @@ realpath.native = (path, options, callback) => { /** * Creates a unique temporary directory. - * @param {string} prefix + * @param {string | Buffer | URL} prefix * @param {string | { encoding?: string; }} [options] * @param {( * err?: Error, @@ -2914,27 +2871,40 @@ function mkdtemp(prefix, options, callback) { callback = makeCallback(typeof options === 'function' ? options : callback); options = getOptions(options); - validateString(prefix, 'prefix'); - nullCheck(prefix, 'prefix'); + prefix = getValidatedPath(prefix, 'prefix'); warnOnNonPortableTemplate(prefix); + + let path; + if (typeof prefix === 'string') { + path = `${prefix}XXXXXX`; + } else { + path = Buffer.concat([prefix, Buffer.from('XXXXXX')]); + } + const req = new FSReqCallback(); req.oncomplete = callback; - binding.mkdtemp(`${prefix}XXXXXX`, options.encoding, req); + binding.mkdtemp(path, options.encoding, req); } /** * Synchronously creates a unique temporary directory. - * @param {string} prefix + * @param {string | Buffer | URL} prefix * @param {string | { encoding?: string; }} [options] * @returns {string} */ function mkdtempSync(prefix, options) { options = getOptions(options); - validateString(prefix, 'prefix'); - nullCheck(prefix, 'prefix'); + prefix = getValidatedPath(prefix, 'prefix'); warnOnNonPortableTemplate(prefix); - const path = `${prefix}XXXXXX`; + + let path; + if (typeof prefix === 'string') { + path = `${prefix}XXXXXX`; + } else { + path = Buffer.concat([prefix, Buffer.from('XXXXXX')]); + } + const ctx = { path }; const result = binding.mkdtemp(path, options.encoding, undefined, ctx); @@ -2979,16 +2949,7 @@ function copyFile(src, dest, mode, callback) { * @returns {void} */ function copyFileSync(src, dest, mode) { - src = getValidatedPath(src, 'src'); - dest = getValidatedPath(dest, 'dest'); - - const ctx = { path: src, dest }; // non-prefixed - - src = pathModule._makeLong(src); - dest = pathModule._makeLong(dest); - mode = getValidMode(mode, 'copyFile'); - binding.copyFile(src, dest, mode, undefined, ctx); - handleErrorFromBinding(ctx); + syncFs.copyFile(src, dest, mode); } /** diff --git a/lib/https.js b/lib/https.js index d8b42c85493f7e..70ffa73ff1996b 100644 --- a/lib/https.js +++ b/lib/https.js @@ -96,8 +96,9 @@ function Server(opts, requestListener) { this.timeout = 0; this.maxHeadersCount = null; - setupConnectionsTracking(this); + this.on('listening', setupConnectionsTracking); } + ObjectSetPrototypeOf(Server.prototype, tls.Server.prototype); ObjectSetPrototypeOf(Server, tls.Server); diff --git a/lib/inspector.js b/lib/inspector.js index 567d825c4f6a72..70796c83fcffe3 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -5,6 +5,7 @@ const { JSONStringify, SafeMap, Symbol, + SymbolDispose, } = primordials; const { @@ -181,6 +182,8 @@ function inspectorOpen(port, host, wait) { open(port, host); if (wait) waitForDebugger(); + + return { __proto__: null, [SymbolDispose]() { _debugEnd(); } }; } /** diff --git a/lib/internal/blob.js b/lib/internal/blob.js index 655023e07780f2..a54adb615fbc17 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -320,6 +320,7 @@ class Blob { const reader = this[kHandle].getReader(); return new lazyReadableStream({ + type: 'bytes', start(c) { // There really should only be one read at a time so using an // array here is purely defensive. @@ -339,6 +340,9 @@ class Blob { if (status === 0) { // EOS c.close(); + // This is to signal the end for byob readers + // see https://streams.spec.whatwg.org/#example-rbs-pull + c.byobRequest?.respond(0); const pending = this.pendingPulls.shift(); pending.resolve(); return; @@ -352,14 +356,21 @@ class Blob { pending.reject(error); return; } - if (buffer !== undefined) { + // ReadableByteStreamController.enqueue errors if we submit a 0-length + // buffer. We need to check for that here. + if (buffer !== undefined && buffer.byteLength !== 0) { c.enqueue(new Uint8Array(buffer)); } // We keep reading until we either reach EOS, some error, or we // hit the flow rate of the stream (c.desiredSize). queueMicrotask(() => { - if (c.desiredSize <= 0) { + if (c.desiredSize < 0) { // A manual backpressure check. + if (this.pendingPulls.length !== 0) { + // A case of waiting pull finished (= not yet canceled) + const pending = this.pendingPulls.shift(); + pending.resolve(); + } return; } readNext(); diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 36ff5bcd8c526a..7a773d5208e250 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -326,6 +326,7 @@ process.emitWarning = emitWarning; { const { + getSourceMapsEnabled, setSourceMapsEnabled, maybeCacheGeneratedSourceMap, } = require('internal/source_map/source_map_cache'); @@ -333,6 +334,14 @@ process.emitWarning = emitWarning; setMaybeCacheGeneratedSourceMap, } = internalBinding('errors'); + ObjectDefineProperty(process, 'sourceMapsEnabled', { + __proto__: null, + enumerable: true, + configurable: true, + get() { + return getSourceMapsEnabled(); + }, + }); process.setSourceMapsEnabled = setSourceMapsEnabled; // The C++ land calls back to maybeCacheGeneratedSourceMap() // when code is generated by user with eval() or new Function() diff --git a/lib/internal/bootstrap/realm.js b/lib/internal/bootstrap/realm.js index 608e3072850d45..f9d096ca963464 100644 --- a/lib/internal/bootstrap/realm.js +++ b/lib/internal/bootstrap/realm.js @@ -174,9 +174,9 @@ const experimentalModuleList = new SafeSet(); }; } -// Set up internalBinding() in the closure. /** - * @type {InternalBinding} + * Set up internalBinding() in the closure. + * @type {import('typings/globals').internalBinding} */ let internalBinding; { diff --git a/lib/internal/bootstrap/switches/does_own_process_state.js b/lib/internal/bootstrap/switches/does_own_process_state.js index 85b5c3dfcb09ed..8f457de3e1183e 100644 --- a/lib/internal/bootstrap/switches/does_own_process_state.js +++ b/lib/internal/bootstrap/switches/does_own_process_state.js @@ -2,6 +2,12 @@ const credentials = internalBinding('credentials'); const rawMethods = internalBinding('process_methods'); +const { + namespace: { + addSerializeCallback, + isBuildingSnapshot, + }, +} = require('internal/v8/startup_snapshot'); process.abort = rawMethods.abort; process.umask = wrappedUmask; @@ -107,6 +113,12 @@ function wrapPosixCredentialSetters(credentials) { // directory is changed by `chdir`, it'll be updated. let cachedCwd = ''; +if (isBuildingSnapshot()) { + addSerializeCallback(() => { + cachedCwd = ''; + }); +} + function wrappedChdir(directory) { validateString(directory, 'directory'); rawMethods.chdir(directory); diff --git a/lib/internal/bootstrap/switches/is_main_thread.js b/lib/internal/bootstrap/switches/is_main_thread.js index f2c3478e8bb5bf..8707bc7daaa616 100644 --- a/lib/internal/bootstrap/switches/is_main_thread.js +++ b/lib/internal/bootstrap/switches/is_main_thread.js @@ -290,7 +290,7 @@ rawMethods.resetStdioForTesting = function() { // Needed by the module loader and generally needed everywhere. require('fs'); require('util'); -require('url'); +require('url'); // eslint-disable-line no-restricted-modules require('internal/modules/cjs/loader'); require('internal/modules/esm/utils'); diff --git a/lib/internal/crypto/cfrg.js b/lib/internal/crypto/cfrg.js index 51405a6b1596c2..9112dbdd3166a0 100644 --- a/lib/internal/crypto/cfrg.js +++ b/lib/internal/crypto/cfrg.js @@ -272,17 +272,6 @@ async function cfrgImportKey( 'DataError'); } - if (keyData.alg !== undefined) { - if ( - (name === 'Ed25519' || name === 'Ed448') && - keyData.alg !== 'EdDSA' - ) { - throw lazyDOMException( - 'JWK "alg" does not match the requested algorithm', - 'DataError'); - } - } - if (!isPublic && typeof keyData.x !== 'string') { throw lazyDOMException('Invalid JWK', 'DataError'); } diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index 3f52e78d7a3036..59bbf8ff71233c 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -51,7 +51,6 @@ const { const { getArrayBufferOrView, - getDefaultEncoding, jobPromise, toBuf, kHandle, @@ -97,10 +96,6 @@ function DiffieHellman(sizeOrKey, keyEncoding, generator, genEncoding) { keyEncoding = false; } - const encoding = getDefaultEncoding(); - keyEncoding = keyEncoding || encoding; - genEncoding = genEncoding || encoding; - if (typeof sizeOrKey !== 'number') sizeOrKey = toBuf(sizeOrKey, keyEncoding); @@ -148,7 +143,6 @@ DiffieHellmanGroup.prototype.generateKeys = function dhGenerateKeys(encoding) { const keys = this[kHandle].generateKeys(); - encoding = encoding || getDefaultEncoding(); return encode(keys, encoding); } @@ -158,9 +152,6 @@ DiffieHellmanGroup.prototype.computeSecret = dhComputeSecret; function dhComputeSecret(key, inEnc, outEnc) { - const encoding = getDefaultEncoding(); - inEnc = inEnc || encoding; - outEnc = outEnc || encoding; key = getArrayBufferOrView(key, 'key', inEnc); const ret = this[kHandle].computeSecret(key); if (typeof ret === 'string') @@ -175,7 +166,6 @@ DiffieHellmanGroup.prototype.getPrime = function dhGetPrime(encoding) { const prime = this[kHandle].getPrime(); - encoding = encoding || getDefaultEncoding(); return encode(prime, encoding); } @@ -186,7 +176,6 @@ DiffieHellmanGroup.prototype.getGenerator = function dhGetGenerator(encoding) { const generator = this[kHandle].getGenerator(); - encoding = encoding || getDefaultEncoding(); return encode(generator, encoding); } @@ -197,7 +186,6 @@ DiffieHellmanGroup.prototype.getPublicKey = function dhGetPublicKey(encoding) { const key = this[kHandle].getPublicKey(); - encoding = encoding || getDefaultEncoding(); return encode(key, encoding); } @@ -208,13 +196,11 @@ DiffieHellmanGroup.prototype.getPrivateKey = function dhGetPrivateKey(encoding) { const key = this[kHandle].getPrivateKey(); - encoding = encoding || getDefaultEncoding(); return encode(key, encoding); } DiffieHellman.prototype.setPublicKey = function setPublicKey(key, encoding) { - encoding = encoding || getDefaultEncoding(); key = getArrayBufferOrView(key, 'key', encoding); this[kHandle].setPublicKey(key); return this; @@ -222,7 +208,6 @@ DiffieHellman.prototype.setPublicKey = function setPublicKey(key, encoding) { DiffieHellman.prototype.setPrivateKey = function setPrivateKey(key, encoding) { - encoding = encoding || getDefaultEncoding(); key = getArrayBufferOrView(key, 'key', encoding); this[kHandle].setPrivateKey(key); return this; @@ -251,15 +236,12 @@ ECDH.prototype.generateKeys = function generateKeys(encoding, format) { ECDH.prototype.getPublicKey = function getPublicKey(encoding, format) { const f = getFormat(format); const key = this[kHandle].getPublicKey(f); - encoding = encoding || getDefaultEncoding(); return encode(key, encoding); }; ECDH.convertKey = function convertKey(key, curve, inEnc, outEnc, format) { validateString(curve, 'curve'); - const encoding = inEnc || getDefaultEncoding(); - key = getArrayBufferOrView(key, 'key', encoding); - outEnc = outEnc || encoding; + key = getArrayBufferOrView(key, 'key', inEnc); const f = getFormat(format); const convertedKey = _ECDHConvertKey(key, curve, f); return encode(convertedKey, outEnc); diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js index c8e9af003086c8..57fcb63518d52d 100644 --- a/lib/internal/crypto/hash.js +++ b/lib/internal/crypto/hash.js @@ -14,7 +14,6 @@ const { } = internalBinding('crypto'); const { - getDefaultEncoding, getStringOption, jobPromise, normalizeHashName, @@ -95,8 +94,6 @@ Hash.prototype._flush = function _flush(callback) { }; Hash.prototype.update = function update(data, encoding) { - encoding = encoding || getDefaultEncoding(); - const state = this[kState]; if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); @@ -118,10 +115,9 @@ Hash.prototype.digest = function digest(outputEncoding) { const state = this[kState]; if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); - outputEncoding = outputEncoding || getDefaultEncoding(); - // Explicit conversion for backward compatibility. - const ret = this[kHandle].digest(`${outputEncoding}`); + // Explicit conversion of truthy values for backward compatibility. + const ret = this[kHandle].digest(outputEncoding && `${outputEncoding}`); state[kFinalized] = true; return ret; }; @@ -147,15 +143,16 @@ Hmac.prototype.update = Hash.prototype.update; Hmac.prototype.digest = function digest(outputEncoding) { const state = this[kState]; - outputEncoding = outputEncoding || getDefaultEncoding(); if (state[kFinalized]) { const buf = Buffer.from(''); - return outputEncoding === 'buffer' ? buf : buf.toString(outputEncoding); + if (outputEncoding && outputEncoding !== 'buffer') + return buf.toString(outputEncoding); + return buf; } - // Explicit conversion for backward compatibility. - const ret = this[kHandle].digest(`${outputEncoding}`); + // Explicit conversion of truthy values for backward compatibility. + const ret = this[kHandle].digest(outputEncoding && `${outputEncoding}`); state[kFinalized] = true; return ret; }; diff --git a/lib/internal/crypto/sig.js b/lib/internal/crypto/sig.js index 71e8fbadaa84d7..9b3895646c7929 100644 --- a/lib/internal/crypto/sig.js +++ b/lib/internal/crypto/sig.js @@ -34,7 +34,6 @@ const { const { getArrayBufferOrView, - getDefaultEncoding, kHandle, } = require('internal/crypto/util'); @@ -70,8 +69,6 @@ Sign.prototype._write = function _write(chunk, encoding, callback) { }; Sign.prototype.update = function update(data, encoding) { - encoding = encoding || getDefaultEncoding(); - if (typeof data === 'string') { validateEncoding(data, encoding); } else if (!isArrayBufferView(data)) { @@ -131,7 +128,6 @@ Sign.prototype.sign = function sign(options, encoding) { const ret = this[kHandle].sign(data, format, type, passphrase, rsaPadding, pssSaltLength, dsaSigEnc); - encoding = encoding || getDefaultEncoding(); if (encoding && encoding !== 'buffer') return ret.toString(encoding); @@ -216,8 +212,6 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) { passphrase, } = preparePublicOrPrivateKey(options, true); - sigEncoding = sigEncoding || getDefaultEncoding(); - // Options specific to RSA const rsaPadding = getPadding(options); const pssSaltLength = getSaltLength(options); diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index cf044e804ad05a..51ca3f4c056fb9 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -75,11 +75,6 @@ const { const kHandle = Symbol('kHandle'); const kKeyObject = Symbol('kKeyObject'); -// TODO(tniessen): remove all call sites and this function -function getDefaultEncoding() { - return 'buffer'; -} - // This is here because many functions accepted binary strings without // any explicit encoding in older versions of node, and we don't want // to break them unnecessarily. @@ -555,7 +550,6 @@ module.exports = { getCiphers, getCurves, getDataViewOrTypedArrayBuffer, - getDefaultEncoding, getHashes, kHandle, kKeyObject, diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js index 9c1cf1e5d91dda..aaf46ce03dd133 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -475,7 +475,6 @@ async function exportKeyJWK(key) { // Fall through case 'Ed448': jwk.crv ||= key.algorithm.name; - jwk.alg = 'EdDSA'; return jwk; case 'AES-CTR': // Fall through diff --git a/lib/internal/debugger/inspect.js b/lib/internal/debugger/inspect.js index 24e5c0bd401f01..5e93699f8ba078 100644 --- a/lib/internal/debugger/inspect.js +++ b/lib/internal/debugger/inspect.js @@ -338,7 +338,7 @@ function startInspect(argv = ArrayPrototypeSlice(process.argv, 2), process.stderr.write(`Usage: ${invokedAs} script.js\n` + ` ${invokedAs} :\n` + - ` ${invokedAs} --port=\n` + + ` ${invokedAs} --port= Use 0 for random port assignment\n` + ` ${invokedAs} -p \n`); process.exit(kInvalidCommandLineArgument); } diff --git a/lib/internal/debugger/inspect_client.js b/lib/internal/debugger/inspect_client.js index e467899fb3e746..315617bf08a800 100644 --- a/lib/internal/debugger/inspect_client.js +++ b/lib/internal/debugger/inspect_client.js @@ -15,7 +15,7 @@ const crypto = require('crypto'); const { ERR_DEBUGGER_ERROR } = require('internal/errors').codes; const { EventEmitter } = require('events'); const http = require('http'); -const URL = require('url'); +const { URL } = require('internal/url'); const debuglog = require('internal/util/debuglog').debuglog('inspect'); @@ -297,7 +297,8 @@ class Client extends EventEmitter { async _discoverWebsocketPath() { const { 0: { webSocketDebuggerUrl } } = await this._fetchJSON('/json'); - return URL.parse(webSocketDebuggerUrl).path; + const { pathname, search } = new URL(webSocketDebuggerUrl); + return `${pathname}${search}`; } _connectWebsocket(urlPath) { diff --git a/lib/internal/dns/promises.js b/lib/internal/dns/promises.js index 79be8591bbcad2..1169b2735d4efe 100644 --- a/lib/internal/dns/promises.js +++ b/lib/internal/dns/promises.js @@ -113,6 +113,19 @@ function onlookupall(err, addresses) { } } +/** + * Creates a promise that resolves with the IP address of the given hostname. + * @param {0 | 4 | 6} family - The IP address family (4 or 6, or 0 for both). + * @param {string} hostname - The hostname to resolve. + * @param {boolean} all - Whether to resolve with all IP addresses for the hostname. + * @param {number} hints - One or more supported getaddrinfo flags (supply multiple via + * bitwise OR). + * @param {boolean} verbatim - Whether to use the hostname verbatim. + * @returns {Promise} The IP address(es) of the hostname. + * @typedef {object} DNSLookupResult + * @property {string} address - The IP address. + * @property {0 | 4 | 6} family - The IP address type. 4 for IPv4 or 6 for IPv6, or 0 (for both). + */ function createLookupPromise(family, hostname, all, hints, verbatim) { return new Promise((resolve, reject) => { if (!hostname) { @@ -154,6 +167,17 @@ function createLookupPromise(family, hostname, all, hints, verbatim) { } const validFamilies = [0, 4, 6]; +/** + * Get the IP address for a given hostname. + * @param {string} hostname - The hostname to resolve (ex. 'nodejs.org'). + * @param {object} [options] - Optional settings. + * @param {boolean} [options.all=false] - Whether to return all or just the first resolved address. + * @param {0 | 4 | 6} [options.family=0] - The record family. Must be 4, 6, or 0 (for both). + * @param {number} [options.hints] - One or more supported getaddrinfo flags (supply multiple via + * bitwise OR). + * @param {boolean} [options.verbatim=false] - Return results in same order DNS resolved them; + * otherwise IPv4 then IPv6. New code should supply `true`. + */ function lookup(hostname, options) { let hints = 0; let family = 0; diff --git a/lib/internal/encoding.js b/lib/internal/encoding.js index 996b2506a49d3b..a9bfb665c2f1e8 100644 --- a/lib/internal/encoding.js +++ b/lib/internal/encoding.js @@ -76,8 +76,11 @@ const empty = new Uint8Array(0); const encodings = new SafeMap([ ['unicode-1-1-utf-8', 'utf-8'], + ['unicode11utf8', 'utf-8'], + ['unicode20utf8', 'utf-8'], ['utf8', 'utf-8'], ['utf-8', 'utf-8'], + ['x-unicode20utf8', 'utf-8'], ['866', 'ibm866'], ['cp866', 'ibm866'], ['csibm866', 'ibm866'], @@ -176,6 +179,7 @@ const encodings = new SafeMap([ ['iso885915', 'iso-8859-15'], ['iso_8859-15', 'iso-8859-15'], ['l9', 'iso-8859-15'], + ['iso-8859-16', 'iso-8859-16'], ['cskoi8r', 'koi8-r'], ['koi', 'koi8-r'], ['koi8', 'koi8-r'], @@ -283,9 +287,22 @@ const encodings = new SafeMap([ ['ksc5601', 'euc-kr'], ['ksc_5601', 'euc-kr'], ['windows-949', 'euc-kr'], + ['csiso2022kr', 'replacement'], + ['hz-gb-2312', 'replacement'], + ['iso-2022-cn', 'replacement'], + ['iso-2022-cn-ext', 'replacement'], + ['iso-2022-kr', 'replacement'], + ['replacement', 'replacement'], + ['unicodefffe', 'utf-16be'], ['utf-16be', 'utf-16be'], + ['csunicode', 'utf-16le'], + ['iso-10646-ucs-2', 'utf-16le'], + ['ucs-2', 'utf-16le'], + ['unicode', 'utf-16le'], + ['unicodefeff', 'utf-16le'], ['utf-16le', 'utf-16le'], ['utf-16', 'utf-16le'], + ['x-user-defined', 'x-user-defined'], ]); // Unfortunately, String.prototype.trim also removes non-ascii whitespace, diff --git a/lib/internal/errors.js b/lib/internal/errors.js index a7120564c468fb..a8c2a9ea15db04 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -66,7 +66,8 @@ const isWindows = process.platform === 'win32'; const messages = new SafeMap(); const codes = {}; -const classRegExp = /^([A-Z][a-z0-9]*)+$/; +const classRegExp = /^[A-Z][a-zA-Z0-9]*$/; + // Sorted by a rough estimate on most frequently used entries. const kTypes = [ 'string', @@ -957,6 +958,9 @@ module.exports = { // // Note: Node.js specific errors must begin with the prefix ERR_ +E('ERR_ACCESS_DENIED', + 'Access to this API has been restricted. Permission: %s', + Error); E('ERR_AMBIGUOUS_ARGUMENT', 'The "%s" argument is ambiguous. %s', TypeError); E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError); E('ERR_ASSERTION', '%s', Error); @@ -1036,11 +1040,6 @@ E('ERR_ENCODING_INVALID_ENCODED_DATA', function(encoding, ret) { }, TypeError); E('ERR_ENCODING_NOT_SUPPORTED', 'The "%s" encoding is not supported', RangeError); -E('ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE', 'Programmatically registering custom ESM loaders ' + - 'currently requires at least one custom loader to have been registered via the --experimental-loader ' + - 'flag. A no-op loader registered via CLI is sufficient (for example: `--experimental-loader ' + - '"data:text/javascript,"` with the necessary trailing comma). A future version of Node.js ' + - 'will remove this requirement.', Error); E('ERR_EVAL_ESM_CANNOT_PRINT', '--print cannot be used with ESM input', Error); E('ERR_EVENT_RECURSION', 'The event "%s" is already being dispatched', Error); E('ERR_FALSY_VALUE_REJECTION', function(reason) { @@ -1351,17 +1350,11 @@ E('ERR_INVALID_REPL_EVAL_CONFIG', E('ERR_INVALID_REPL_INPUT', '%s', TypeError); E('ERR_INVALID_RETURN_PROPERTY', (input, name, prop, value) => { return `Expected a valid ${input} to be returned for the "${prop}" from the` + - ` "${name}" function but got ${value}.`; + ` "${name}" function but got ${determineSpecificType(value)}.`; }, TypeError); E('ERR_INVALID_RETURN_PROPERTY_VALUE', (input, name, prop, value) => { - let type; - if (value?.constructor?.name) { - type = `instance of ${value.constructor.name}`; - } else { - type = `type ${typeof value}`; - } return `Expected ${input} to be returned for the "${prop}" from the` + - ` "${name}" function but got ${type}.`; + ` "${name}" function but got ${determineSpecificType(value)}.`; }, TypeError); E('ERR_INVALID_RETURN_VALUE', (input, name, value) => { const type = determineSpecificType(value); @@ -1455,8 +1448,12 @@ E('ERR_MISSING_ARGS', return `${msg} must be specified`; }, TypeError); E('ERR_MISSING_OPTION', '%s is required', TypeError); -E('ERR_MODULE_NOT_FOUND', (path, base, type = 'package') => { - return `Cannot find ${type} '${path}' imported from ${base}`; +E('ERR_MODULE_NOT_FOUND', function(path, base, exactUrl) { + if (exactUrl) { + lazyInternalUtil().setOwnProperty(this, 'url', `${exactUrl}`); + } + return `Cannot find ${ + exactUrl ? 'module' : 'package'} '${path}' imported from ${base}`; }, Error); E('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times', Error); E('ERR_NAPI_CONS_FUNCTION', 'Constructor must be a function', TypeError); @@ -1546,7 +1543,7 @@ E('ERR_REQUIRE_ESM', msg += `\n${basename} is treated as an ES module file as it is a .js ` + 'file whose nearest parent package.json contains "type": "module" ' + 'which declares all .js files in that package scope as ES modules.' + - `\nInstead rename ${basename} to end in .cjs, change the requiring ` + + `\nInstead either rename ${basename} to end in .cjs, change the requiring ` + 'code to use dynamic import() which is available in all CommonJS ' + 'modules, or change "type": "module" to "type": "commonjs" in ' + `${packageJsonPath} to treat all .js files as CommonJS (using .mjs for ` + @@ -1698,8 +1695,11 @@ E('ERR_UNKNOWN_FILE_EXTENSION', (ext, path, suggestion) => { E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s for URL %s', RangeError); E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError); -E('ERR_UNSUPPORTED_DIR_IMPORT', "Directory import '%s' is not supported " + -'resolving ES modules imported from %s', Error); +E('ERR_UNSUPPORTED_DIR_IMPORT', function(path, base, exactUrl) { + lazyInternalUtil().setOwnProperty(this, 'url', exactUrl); + return `Directory import '${path}' is not supported ` + + `resolving ES modules imported from ${base}`; +}, Error); E('ERR_UNSUPPORTED_ESM_URL_SCHEME', (url, supported) => { let msg = `Only URLs with a scheme in: ${formatList(supported)} are supported by the default ESM loader`; if (isWindows && url.protocol.length === 2) { diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index c6fbc81a27b4f2..5ab2a23f980549 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -58,6 +58,7 @@ const kWeakHandler = Symbol('kWeak'); const kResistStopPropagation = Symbol('kResistStopPropagation'); const kHybridDispatch = SymbolFor('nodejs.internal.kHybridDispatch'); +const kRemoveWeakListenerHelper = Symbol('nodejs.internal.removeWeakListenerHelper'); const kCreateEvent = Symbol('kCreateEvent'); const kNewListener = Symbol('kNewListener'); const kRemoveListener = Symbol('kRemoveListener'); @@ -406,7 +407,7 @@ let weakListenersState = null; let objectToWeakListenerMap = null; function weakListeners() { weakListenersState ??= new SafeFinalizationRegistry( - (listener) => listener.remove(), + ({ eventTarget, listener, eventType }) => eventTarget.deref()?.[kRemoveWeakListenerHelper](eventType, listener), ); objectToWeakListenerMap ??= new SafeWeakMap(); return { registry: weakListenersState, map: objectToWeakListenerMap }; @@ -428,7 +429,7 @@ const kFlagResistStopPropagation = 1 << 6; // the linked list makes dispatching faster, even if adding/removing is // slower. class Listener { - constructor(previous, listener, once, capture, passive, + constructor(eventTarget, eventType, previous, listener, once, capture, passive, isNodeStyleListener, weak, resistStopPropagation) { this.next = undefined; if (previous !== undefined) @@ -455,7 +456,13 @@ class Listener { if (this.weak) { this.callback = new SafeWeakRef(listener); - weakListeners().registry.register(listener, this, this); + weakListeners().registry.register(listener, { + __proto__: null, + // Weak ref so the listener won't hold the eventTarget alive + eventTarget: new SafeWeakRef(eventTarget), + listener: this, + eventType, + }, this); // Make the retainer retain the listener in a WeakMap weakListeners().map.set(weak, listener); this.listener = this.callback; @@ -621,7 +628,7 @@ class EventTarget { if (root === undefined) { root = { size: 1, next: undefined, resistStopPropagation: Boolean(resistStopPropagation) }; // This is the first handler in our linked list. - new Listener(root, listener, once, capture, passive, + new Listener(this, type, root, listener, once, capture, passive, isNodeStyleListener, weak, resistStopPropagation); this[kNewListener]( root.size, @@ -648,7 +655,7 @@ class EventTarget { return; } - new Listener(previous, listener, once, capture, passive, + new Listener(this, type, previous, listener, once, capture, passive, isNodeStyleListener, weak, resistStopPropagation); root.size++; root.resistStopPropagation ||= Boolean(resistStopPropagation); @@ -691,6 +698,28 @@ class EventTarget { } } + [kRemoveWeakListenerHelper](type, listener) { + const root = this[kEvents].get(type); + if (root === undefined || root.next === undefined) + return; + + const capture = listener.capture === true; + + let handler = root.next; + while (handler !== undefined) { + if (handler === listener) { + handler.remove(); + root.size--; + if (root.size === 0) + this[kEvents].delete(type); + // Undefined is passed as the listener as the listener was GCed + this[kRemoveListener](root.size, type, undefined, capture); + break; + } + handler = handler.next; + } + } + /** * @param {Event} event */ diff --git a/lib/internal/freeze_intrinsics.js b/lib/internal/freeze_intrinsics.js index 72ba32589338b0..793c19df1e9138 100644 --- a/lib/internal/freeze_intrinsics.js +++ b/lib/internal/freeze_intrinsics.js @@ -203,7 +203,6 @@ module.exports = function() { // 25 Structured Data ArrayBufferPrototype, // 25.1 - SharedArrayBuffer.prototype, // 25.2 DataViewPrototype, // 25.3 // 26 Managing Memory @@ -309,7 +308,6 @@ module.exports = function() { // 25 Structured Data ArrayBuffer, // 25.1 - SharedArrayBuffer, // 25.2 DataView, // 25.3 Atomics, // 25.4 // eslint-disable-next-line node-core/prefer-primordials @@ -354,6 +352,11 @@ module.exports = function() { WebAssembly, ]; + if (typeof SharedArrayBuffer !== 'undefined') { // 25.2 + ArrayPrototypePush(intrinsicPrototypes, SharedArrayBuffer.prototype); + ArrayPrototypePush(intrinsics, SharedArrayBuffer); + } + if (typeof Intl !== 'undefined') { ArrayPrototypePush(intrinsicPrototypes, Intl.Collator.prototype, diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index ec0562843d5f5c..1118ff5f674915 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -152,7 +152,7 @@ class Dir { ArrayPrototypePush( this[kDirBufferedEntries], getDirent( - pathModule.join(path, result[i]), + path, result[i], result[i + 1], ), @@ -161,9 +161,10 @@ class Dir { } readSyncRecursive(dirent) { - const ctx = { path: dirent.path }; + const path = pathModule.join(dirent.path, dirent.name); + const ctx = { path }; const handle = dirBinding.opendir( - pathModule.toNamespacedPath(dirent.path), + pathModule.toNamespacedPath(path), this[kDirOptions].encoding, undefined, ctx, @@ -177,7 +178,7 @@ class Dir { ); if (result) { - this.processReadResult(dirent.path, result); + this.processReadResult(path, result); } handle.close(undefined, ctx); @@ -321,18 +322,11 @@ function opendir(path, options, callback) { function opendirSync(path, options) { path = getValidatedPath(path); - options = getOptions(options, { - encoding: 'utf8', - }); + options = getOptions(options, { encoding: 'utf8' }); - const ctx = { path }; - const handle = dirBinding.opendir( + const handle = dirBinding.opendirSync( pathModule.toNamespacedPath(path), - options.encoding, - undefined, - ctx, ); - handleErrorFromBinding(ctx); return new Dir(handle, path, options); } diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index 74af3c9782b7a9..bc506b9be82fbc 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -59,7 +59,6 @@ const { getStatsFromBinding, getValidatedPath, getValidMode, - nullCheck, preprocessSymlinkDestination, stringToFlags, stringToSymlinkType, @@ -255,6 +254,9 @@ class FileHandle extends EventEmitter { /** * @typedef {import('../webstreams/readablestream').ReadableStream * } ReadableStream + * @param {{ + * type?: string; + * }} [options] * @returns {ReadableStream} */ readableWebStream(options = kEmptyObject) { @@ -280,17 +282,8 @@ class FileHandle extends EventEmitter { this[kHandle], undefined, { ondone: () => this[kUnref]() }); - - const { - readableStreamCancel, - } = require('internal/webstreams/readablestream'); - this[kRef](); - this.once('close', () => { - readableStreamCancel(readable); - }); } else { const { - readableStreamCancel, ReadableStream, } = require('internal/webstreams/readablestream'); @@ -317,14 +310,16 @@ class FileHandle extends EventEmitter { ondone(); }, }); - - this[kRef](); - - this.once('close', () => { - readableStreamCancel(readable); - }); } + const { + readableStreamCancel, + } = require('internal/webstreams/readablestream'); + this[kRef](); + this.once('close', () => { + readableStreamCancel(readable); + }); + return readable; } @@ -994,10 +989,17 @@ async function realpath(path, options) { async function mkdtemp(prefix, options) { options = getOptions(options); - validateString(prefix, 'prefix'); - nullCheck(prefix); + prefix = getValidatedPath(prefix, 'prefix'); warnOnNonPortableTemplate(prefix); - return binding.mkdtemp(`${prefix}XXXXXX`, options.encoding, kUsePromises); + + let path; + if (typeof prefix === 'string') { + path = `${prefix}XXXXXX`; + } else { + path = Buffer.concat([prefix, Buffer.from('XXXXXX')]); + } + + return binding.mkdtemp(path, options.encoding, kUsePromises); } async function writeFile(path, data, options) { diff --git a/lib/internal/fs/read/utf8.js b/lib/internal/fs/read/utf8.js deleted file mode 100644 index e916c918c11190..00000000000000 --- a/lib/internal/fs/read/utf8.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -const { handleErrorFromBinding } = require('internal/fs/utils'); - -const binding = internalBinding('fs'); - -/** - * @param {string} path - * @param {number} flag - * @return {string} - */ -function readFileSyncUtf8(path, flag) { - const response = binding.readFileSync(path, flag); - - if (typeof response === 'string') { - return response; - } - - handleErrorFromBinding({ errno: response, path }); -} - -module.exports = { - readFileSyncUtf8, -}; diff --git a/lib/internal/fs/streams.js b/lib/internal/fs/streams.js index f75d0fba917241..c317f3b9202af9 100644 --- a/lib/internal/fs/streams.js +++ b/lib/internal/fs/streams.js @@ -13,8 +13,10 @@ const { const { ERR_INVALID_ARG_TYPE, - ERR_OUT_OF_RANGE, ERR_METHOD_NOT_IMPLEMENTED, + ERR_OUT_OF_RANGE, + ERR_STREAM_DESTROYED, + ERR_SYSTEM_ERROR, } = require('internal/errors').codes; const { deprecate, @@ -392,9 +394,67 @@ WriteStream.prototype.open = openWriteFs; WriteStream.prototype._construct = _construct; +function writeAll(data, size, pos, cb, retries = 0) { + this[kFs].write(this.fd, data, 0, size, pos, (er, bytesWritten, buffer) => { + // No data currently available and operation should be retried later. + if (er?.code === 'EAGAIN') { + er = null; + bytesWritten = 0; + } + + if (this.destroyed || er) { + return cb(er || new ERR_STREAM_DESTROYED('write')); + } + + this.bytesWritten += bytesWritten; + + retries = bytesWritten ? 0 : retries + 1; + size -= bytesWritten; + pos += bytesWritten; + + // Try writing non-zero number of bytes up to 5 times. + if (retries > 5) { + cb(new ERR_SYSTEM_ERROR('write failed')); + } else if (size) { + writeAll.call(this, buffer.slice(bytesWritten), size, pos, cb, retries); + } else { + cb(); + } + }); +} + +function writevAll(chunks, size, pos, cb, retries = 0) { + this[kFs].writev(this.fd, chunks, this.pos, (er, bytesWritten, buffers) => { + // No data currently available and operation should be retried later. + if (er?.code === 'EAGAIN') { + er = null; + bytesWritten = 0; + } + + if (this.destroyed || er) { + return cb(er || new ERR_STREAM_DESTROYED('writev')); + } + + this.bytesWritten += bytesWritten; + + retries = bytesWritten ? 0 : retries + 1; + size -= bytesWritten; + pos += bytesWritten; + + // Try writing non-zero number of bytes up to 5 times. + if (retries > 5) { + cb(new ERR_SYSTEM_ERROR('writev failed')); + } else if (size) { + writevAll.call(this, [Buffer.concat(buffers).slice(bytesWritten)], size, pos, cb, retries); + } else { + cb(); + } + }); +} + WriteStream.prototype._write = function(data, encoding, cb) { this[kIsPerformingIO] = true; - this[kFs].write(this.fd, data, 0, data.length, this.pos, (er, bytes) => { + writeAll.call(this, data, data.length, this.pos, (er) => { this[kIsPerformingIO] = false; if (this.destroyed) { // Tell ._destroy() that it's safe to close the fd now. @@ -402,12 +462,7 @@ WriteStream.prototype._write = function(data, encoding, cb) { return this.emit(kIoDone, er); } - if (er) { - return cb(er); - } - - this.bytesWritten += bytes; - cb(); + cb(er); }); if (this.pos !== undefined) @@ -427,7 +482,7 @@ WriteStream.prototype._writev = function(data, cb) { } this[kIsPerformingIO] = true; - this[kFs].writev(this.fd, chunks, this.pos, (er, bytes) => { + writevAll.call(this, chunks, size, this.pos, (er) => { this[kIsPerformingIO] = false; if (this.destroyed) { // Tell ._destroy() that it's safe to close the fd now. @@ -435,12 +490,7 @@ WriteStream.prototype._writev = function(data, cb) { return this.emit(kIoDone, er); } - if (er) { - return cb(er); - } - - this.bytesWritten += bytes; - cb(); + cb(er); }); if (this.pos !== undefined) diff --git a/lib/internal/fs/sync.js b/lib/internal/fs/sync.js new file mode 100644 index 00000000000000..0d4ba90150e186 --- /dev/null +++ b/lib/internal/fs/sync.js @@ -0,0 +1,100 @@ +'use strict'; + +const pathModule = require('path'); +const { + getValidatedPath, + stringToFlags, + getValidMode, + getStatsFromBinding, + getStatFsFromBinding, + getValidatedFd, +} = require('internal/fs/utils'); +const { parseFileMode, isInt32 } = require('internal/validators'); + +const binding = internalBinding('fs'); + +/** + * @param {string} path + * @param {number} flag + * @return {string} + */ +function readFileUtf8(path, flag) { + if (!isInt32(path)) { + path = pathModule.toNamespacedPath(getValidatedPath(path)); + } + return binding.readFileUtf8(path, stringToFlags(flag)); +} + +function exists(path) { + try { + path = getValidatedPath(path); + } catch { + return false; + } + + return binding.existsSync(pathModule.toNamespacedPath(path)); +} + +function access(path, mode) { + path = getValidatedPath(path); + mode = getValidMode(mode, 'access'); + + binding.accessSync(pathModule.toNamespacedPath(path), mode); +} + +function copyFile(src, dest, mode) { + src = getValidatedPath(src, 'src'); + dest = getValidatedPath(dest, 'dest'); + + binding.copyFileSync( + pathModule.toNamespacedPath(src), + pathModule.toNamespacedPath(dest), + getValidMode(mode, 'copyFile'), + ); +} + +function stat(path, options = { bigint: false, throwIfNoEntry: true }) { + path = getValidatedPath(path); + const stats = binding.statSync( + pathModule.toNamespacedPath(path), + options.bigint, + options.throwIfNoEntry, + ); + if (stats === undefined) { + return undefined; + } + return getStatsFromBinding(stats); +} + +function statfs(path, options = { bigint: false }) { + path = getValidatedPath(path); + const stats = binding.statfsSync(pathModule.toNamespacedPath(path), options.bigint); + return getStatFsFromBinding(stats); +} + +function open(path, flags, mode) { + path = getValidatedPath(path); + + return binding.openSync( + pathModule.toNamespacedPath(path), + stringToFlags(flags), + parseFileMode(mode, 'mode', 0o666), + ); +} + +function close(fd) { + fd = getValidatedFd(fd); + + return binding.closeSync(fd); +} + +module.exports = { + readFileUtf8, + exists, + access, + copyFile, + stat, + statfs, + open, + close, +}; diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 763f39af62bbbb..2fc7bf61e9c488 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -20,6 +20,7 @@ const { StringPrototypeEndsWith, StringPrototypeIncludes, Symbol, + TypedArrayPrototypeAt, TypedArrayPrototypeIncludes, } = primordials; @@ -233,7 +234,7 @@ function join(path, name) { } if (typeof path === 'string' && typeof name === 'string') { - return pathModule.basename(path) === name ? path : pathModule.join(path, name); + return pathModule.join(path, name); } if (isUint8Array(path) && isUint8Array(name)) { @@ -375,7 +376,7 @@ const nullCheck = hideStackFrames((path, propName, throwError = true) => { const err = new ERR_INVALID_ARG_VALUE( propName, path, - 'must be a string or Uint8Array without null bytes', + 'must be a string, Uint8Array, or URL without null bytes', ); if (throwError) { throw err; @@ -711,6 +712,8 @@ function possiblyTransformPath(path) { if (permission.isEnabled()) { if (typeof path === 'string') { return pathModule.resolve(path); + } else if (Buffer.isBuffer(path)) { + return Buffer.from(pathModule.resolve(path.toString())); } } return path; @@ -749,7 +752,9 @@ let nonPortableTemplateWarn = true; function warnOnNonPortableTemplate(template) { // Template strings passed to the mkdtemp() family of functions should not // end with 'X' because they are handled inconsistently across platforms. - if (nonPortableTemplateWarn && StringPrototypeEndsWith(template, 'X')) { + if (nonPortableTemplateWarn && + ((typeof template === 'string' && StringPrototypeEndsWith(template, 'X')) || + (typeof template !== 'string' && TypedArrayPrototypeAt(template, -1) === 0x58))) { process.emitWarning('mkdtemp() templates ending with X are not portable. ' + 'For details see: https://nodejs.org/api/fs.html'); nonPortableTemplateWarn = false; diff --git a/lib/internal/js_stream_socket.js b/lib/internal/js_stream_socket.js index 8bc19296620b3f..70d6d03069f3f1 100644 --- a/lib/internal/js_stream_socket.js +++ b/lib/internal/js_stream_socket.js @@ -21,6 +21,7 @@ const { ERR_STREAM_WRAP } = require('internal/errors').codes; const kCurrentWriteRequest = Symbol('kCurrentWriteRequest'); const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest'); const kPendingShutdownRequest = Symbol('kPendingShutdownRequest'); +const kPendingClose = Symbol('kPendingClose'); function isClosing() { return this[owner_symbol].isClosing(); } @@ -94,6 +95,7 @@ class JSStreamSocket extends Socket { this[kCurrentWriteRequest] = null; this[kCurrentShutdownRequest] = null; this[kPendingShutdownRequest] = null; + this[kPendingClose] = false; this.readable = stream.readable; this.writable = stream.writable; @@ -135,11 +137,19 @@ class JSStreamSocket extends Socket { this[kPendingShutdownRequest] = req; return 0; } + assert(this[kCurrentWriteRequest] === null); assert(this[kCurrentShutdownRequest] === null); this[kCurrentShutdownRequest] = req; + if (this[kPendingClose]) { + // If doClose is pending, the stream & this._handle are gone. We can't do + // anything. doClose will call finishShutdown with ECANCELED for us shortly. + return 0; + } + const handle = this._handle; + assert(handle !== null); process.nextTick(() => { // Ensure that write is dispatched asynchronously. @@ -164,7 +174,16 @@ class JSStreamSocket extends Socket { assert(this[kCurrentWriteRequest] === null); assert(this[kCurrentShutdownRequest] === null); + if (this[kPendingClose]) { + // If doClose is pending, the stream & this._handle are gone. We can't do + // anything. doClose will call finishWrite with ECANCELED for us shortly. + this[kCurrentWriteRequest] = req; // Store req, for doClose to cancel + return 0; + } + const handle = this._handle; + assert(handle !== null); + const self = this; let pending = bufs.length; @@ -217,6 +236,8 @@ class JSStreamSocket extends Socket { } doClose(cb) { + this[kPendingClose] = true; + const handle = this._handle; // When sockets of the "net" module destroyed, they will call @@ -234,6 +255,8 @@ class JSStreamSocket extends Socket { this.finishWrite(handle, uv.UV_ECANCELED); this.finishShutdown(handle, uv.UV_ECANCELED); + this[kPendingClose] = false; + cb(); }); } diff --git a/lib/internal/main/eval_string.js b/lib/internal/main/eval_string.js index ec6a2d51af5450..dc59a2ce4f7709 100644 --- a/lib/internal/main/eval_string.js +++ b/lib/internal/main/eval_string.js @@ -24,7 +24,7 @@ markBootstrapComplete(); const source = getOptionValue('--eval'); const print = getOptionValue('--print'); -const loadESM = getOptionValue('--import').length > 0; +const loadESM = getOptionValue('--import').length > 0 || getOptionValue('--experimental-loader').length > 0; if (getOptionValue('--input-type') === 'module') evalModule(source, print); else { diff --git a/lib/internal/main/mksnapshot.js b/lib/internal/main/mksnapshot.js index 2207d9253d7ec4..34701716839326 100644 --- a/lib/internal/main/mksnapshot.js +++ b/lib/internal/main/mksnapshot.js @@ -16,6 +16,10 @@ const { anonymousMainPath, } = internalBinding('mksnapshot'); +const { isExperimentalSeaWarningNeeded } = internalBinding('sea'); + +const { emitExperimentalWarning } = require('internal/util'); + const { getOptionValue, } = require('internal/options'); @@ -126,8 +130,9 @@ function requireForUserSnapshot(id) { return require(normalizedId); } + function main() { - prepareMainThreadExecution(true, false); + prepareMainThreadExecution(false, false); initializeCallbacks(); let stackTraceLimitDesc; @@ -167,6 +172,10 @@ function main() { const serializeMainArgs = [process, requireForUserSnapshot, minimalRunCjs]; + if (isExperimentalSeaWarningNeeded()) { + emitExperimentalWarning('Single executable application'); + } + if (getOptionValue('--inspect-brk')) { internalBinding('inspector').callAndPauseOnStart( runEmbedderEntryPoint, undefined, ...serializeMainArgs); diff --git a/lib/internal/main/test_runner.js b/lib/internal/main/test_runner.js index 064731d77bede1..4974f4ce0d338b 100644 --- a/lib/internal/main/test_runner.js +++ b/lib/internal/main/test_runner.js @@ -58,6 +58,8 @@ if (shardOption) { } run({ concurrency, inspectPort, watch: getOptionValue('--watch'), setup: setupTestReporters, shard }) -.once('test:fail', () => { - process.exitCode = kGenericUserError; +.on('test:fail', (data) => { + if (data.todo === undefined || data.todo === false) { + process.exitCode = kGenericUserError; + } }); diff --git a/lib/internal/main/watch_mode.js b/lib/internal/main/watch_mode.js index 5d0d29cc2ff9da..4fae6363226310 100644 --- a/lib/internal/main/watch_mode.js +++ b/lib/internal/main/watch_mode.js @@ -44,7 +44,7 @@ const args = ArrayPrototypeFilter(process.execArgv, (arg, i, arr) => arg !== '--watch' && arg !== '--watch-preserve-output'); ArrayPrototypePushApply(args, kCommand); -const watcher = new FilesWatcher({ throttle: 500, mode: kShouldFilterModules ? 'filter' : 'all' }); +const watcher = new FilesWatcher({ debounce: 200, mode: kShouldFilterModules ? 'filter' : 'all' }); ArrayPrototypeForEach(kWatchedPaths, (p) => watcher.watchPath(p)); let graceTimer; diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index d32d7ebf92c438..db31feb93ee724 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -152,9 +152,14 @@ const isWindows = process.platform === 'win32'; const relativeResolveCache = { __proto__: null }; let requireDepth = 0; -let statCache = null; let isPreloading = false; +let statCache = null; +/** + * Our internal implementation of `require`. + * @param {Module} module Parent module of what is being required + * @param {string} id Specifier of the child module being imported + */ function internalRequire(module, id) { validateString(id, 'id'); if (id === '') { @@ -169,11 +174,15 @@ function internalRequire(module, id) { } } +/** + * Get a path's properties, using an in-memory cache to minimize lookups. + * @param {string} filename Absolute path to the file + */ function stat(filename) { filename = path.toNamespacedPath(filename); if (statCache !== null) { const result = statCache.get(filename); - if (result !== undefined) return result; + if (result !== undefined) { return result; } } const result = internalModuleStat(filename); if (statCache !== null && result >= 0) { @@ -195,25 +204,47 @@ ObjectDefineProperty(Module, '_stat', { configurable: true, }); +/** + * Update the parent's children array with the child module. + * @param {Module} parent Module requiring the children + * @param {Module} child Module being required + * @param {boolean} scan Add the child to the parent's children if not already present + */ function updateChildren(parent, child, scan) { const children = parent?.children; - if (children && !(scan && ArrayPrototypeIncludes(children, child))) + if (children && !(scan && ArrayPrototypeIncludes(children, child))) { ArrayPrototypePush(children, child); + } } +/** + * Tell the watch mode that a module was required. + * @param {string} filename Absolute path of the module + */ function reportModuleToWatchMode(filename) { if (shouldReportRequiredModules() && process.send) { process.send({ 'watch:require': [filename] }); } } +/** + * Tell the watch mode that a module was not found. + * @param {string} basePath The absolute path that errored + * @param {string[]} extensions The extensions that were tried + */ function reportModuleNotFoundToWatchMode(basePath, extensions) { if (shouldReportRequiredModules() && process.send) { process.send({ 'watch:require': ArrayPrototypeMap(extensions, (ext) => path.resolve(`${basePath}${ext}`)) }); } } +/** @type {Map} */ const moduleParentCache = new SafeWeakMap(); +/** + * Create a new module instance. + * @param {string} id + * @param {Module} parent + */ function Module(id = '', parent) { this.id = id; this.path = path.dirname(id); @@ -236,16 +267,24 @@ function Module(id = '', parent) { this[require_private_symbol] = internalRequire; } +/** @type {Record} */ Module._cache = { __proto__: null }; +/** @type {Record} */ Module._pathCache = { __proto__: null }; +/** @type {Record void>} */ Module._extensions = { __proto__: null }; +/** @type {string[]} */ let modulePaths = []; +/** @type {string[]} */ Module.globalPaths = []; let patched = false; -// eslint-disable-next-line func-style -let wrap = function(script) { +/** + * Add the CommonJS wrapper around a module's source code. + * @param {string} script Module source code + */ +let wrap = function(script) { // eslint-disable-line func-style return Module.wrapper[0] + script + Module.wrapper[1]; }; @@ -296,10 +335,17 @@ const isPreloadingDesc = { get() { return isPreloading; } }; ObjectDefineProperty(Module.prototype, 'isPreloading', isPreloadingDesc); ObjectDefineProperty(BuiltinModule.prototype, 'isPreloading', isPreloadingDesc); +/** + * Get the parent of the current module from our cache. + */ function getModuleParent() { return moduleParentCache.get(this); } +/** + * Set the parent of the current module in our cache. + * @param {Module} value + */ function setModuleParent(value) { moduleParentCache.set(this, value); } @@ -326,7 +372,10 @@ ObjectDefineProperty(Module.prototype, 'parent', { Module._debug = pendingDeprecate(debug, 'Module._debug is deprecated.', 'DEP0077'); Module.isBuiltin = BuiltinModule.isBuiltin; -// This function is called during pre-execution, before any user code is run. +/** + * Prepare to run CommonJS code. + * This function is called during pre-execution, before any user code is run. + */ function initializeCJS() { // This need to be done at runtime in case --expose-internals is set. const builtinModules = BuiltinModule.getCanBeRequiredByUsersWithoutSchemeList(); @@ -374,6 +423,11 @@ ObjectDefineProperty(Module, '_readPackage', { configurable: true, }); +/** + * Get the nearest parent package.json file from a given path. + * Return the package.json data and the path to the package.json file, or false. + * @param {string} checkPath The path to start searching from. + */ function readPackageScope(checkPath) { const rootSeparatorIndex = StringPrototypeIndexOf(checkPath, sep); let separatorIndex; @@ -386,17 +440,27 @@ function readPackageScope(checkPath) { if (enabledPermission && !permission.has('fs.read', checkPath + sep)) { return false; } - if (StringPrototypeEndsWith(checkPath, sep + 'node_modules')) + if (StringPrototypeEndsWith(checkPath, sep + 'node_modules')) { return false; + } const pjson = _readPackage(checkPath + sep); - if (pjson.exists) return { - data: pjson, - path: checkPath, - }; + if (pjson.exists) { + return { + data: pjson, + path: checkPath, + }; + } } while (separatorIndex > rootSeparatorIndex); return false; } +/** + * Try to load a specifier as a package. + * @param {string} requestPath The path to what we are trying to load + * @param {string[]} exts File extensions to try appending in order to resolve the file + * @param {boolean} isMain Whether the file is the main entry point of the app + * @param {string} originalPath The specifier passed to `require` + */ function tryPackage(requestPath, exts, isMain, originalPath) { const pkg = _readPackage(requestPath).main; @@ -434,34 +498,49 @@ function tryPackage(requestPath, exts, isMain, originalPath) { return actual; } -// In order to minimize unnecessary lstat() calls, -// this cache is a list of known-real paths. -// Set to an empty Map to reset. +/** + * Cache for storing resolved real paths of modules. + * In order to minimize unnecessary lstat() calls, this cache is a list of known-real paths. + * Set to an empty Map to reset. + * @type {Map} + */ const realpathCache = new SafeMap(); -// Check if the file exists and is not a directory -// if using --preserve-symlinks and isMain is false, -// keep symlinks intact, otherwise resolve to the -// absolute realpath. +/** + * Check if the file exists and is not a directory if using `--preserve-symlinks` and `isMain` is false, keep symlinks + * intact, otherwise resolve to the absolute realpath. + * @param {string} requestPath The path to the file to load. + * @param {boolean} isMain Whether the file is the main module. + */ function tryFile(requestPath, isMain) { const rc = _stat(requestPath); - if (rc !== 0) return; + if (rc !== 0) { return; } if (getOptionValue('--preserve-symlinks') && !isMain) { return path.resolve(requestPath); } return toRealPath(requestPath); } + +/** + * Resolves the path of a given `require` specifier, following symlinks. + * @param {string} requestPath The `require` specifier + */ function toRealPath(requestPath) { return fs.realpathSync(requestPath, { [internalFS.realpathCacheKey]: realpathCache, }); } -// Given a path, check if the file exists with any of the set extensions -function tryExtensions(p, exts, isMain) { +/** + * Given a path, check if the file exists with any of the set extensions. + * @param {string} basePath The path and filename without extension + * @param {string[]} exts The extensions to try + * @param {boolean} isMain Whether the module is the main module + */ +function tryExtensions(basePath, exts, isMain) { for (let i = 0; i < exts.length; i++) { - const filename = tryFile(p + exts[i], isMain); + const filename = tryFile(basePath + exts[i], isMain); if (filename) { return filename; @@ -470,8 +549,10 @@ function tryExtensions(p, exts, isMain) { return false; } -// Find the longest (possibly multi-dot) extension registered in -// Module._extensions +/** + * Find the longest (possibly multi-dot) extension registered in `Module._extensions`. + * @param {string} filename The filename to find the longest registered extension for. + */ function findLongestRegisteredExtension(filename) { const name = path.basename(filename); let currentExtension; @@ -479,15 +560,19 @@ function findLongestRegisteredExtension(filename) { let startIndex = 0; while ((index = StringPrototypeIndexOf(name, '.', startIndex)) !== -1) { startIndex = index + 1; - if (index === 0) continue; // Skip dotfiles like .gitignore + if (index === 0) { continue; } // Skip dotfiles like .gitignore currentExtension = StringPrototypeSlice(name, index); - if (Module._extensions[currentExtension]) return currentExtension; + if (Module._extensions[currentExtension]) { return currentExtension; } } return '.js'; } +/** + * Tries to get the absolute file path of the parent module. + * @param {Module} parent The parent module object. + */ function trySelfParentPath(parent) { - if (!parent) return false; + if (!parent) { return false; } if (parent.filename) { return parent.filename; @@ -500,8 +585,13 @@ function trySelfParentPath(parent) { } } +/** + * Attempt to resolve a module request using the parent module package metadata. + * @param {string} parentPath The path of the parent module + * @param {string} request The module request to resolve + */ function trySelf(parentPath, request) { - if (!parentPath) return false; + if (!parentPath) { return false; } const { data: pkg, path: pkgPath } = readPackageScope(parentPath); if (!pkg || pkg.exports == null || pkg.name === undefined) { @@ -523,22 +613,30 @@ function trySelf(parentPath, request) { pathToFileURL(pkgPath + '/package.json'), expansion, pkg, pathToFileURL(parentPath), getCjsConditions()), parentPath, pkgPath); } catch (e) { - if (e.code === 'ERR_MODULE_NOT_FOUND') + if (e.code === 'ERR_MODULE_NOT_FOUND') { throw createEsmNotFoundErr(request, pkgPath + '/package.json'); + } throw e; } } -// This only applies to requests of a specific form: -// 1. name/.* -// 2. @scope/name/.* +/** + * This only applies to requests of a specific form: + * 1. `name/.*` + * 2. `@scope/name/.*` + */ const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/; + +/** + * Resolves the exports for a given module path and request. + * @param {string} nmPath The path to the module. + * @param {string} request The request for the module. + */ function resolveExports(nmPath, request) { // The implementation's behavior is meant to mirror resolution in ESM. const { 1: name, 2: expansion = '' } = RegExpPrototypeExec(EXPORTS_PATTERN, request) || kEmptyObject; - if (!name) - return; + if (!name) { return; } const pkgPath = path.resolve(nmPath, name); const pkg = _readPackage(pkgPath); if (pkg.exists && pkg.exports != null) { @@ -548,17 +646,19 @@ function resolveExports(nmPath, request) { pathToFileURL(pkgPath + '/package.json'), '.' + expansion, pkg, null, getCjsConditions()), null, pkgPath); } catch (e) { - if (e.code === 'ERR_MODULE_NOT_FOUND') + if (e.code === 'ERR_MODULE_NOT_FOUND') { throw createEsmNotFoundErr(request, pkgPath + '/package.json'); + } throw e; } } } /** - * @param {string} request a relative or absolute file path - * @param {Array} paths file system directories to search as file paths - * @param {boolean} isMain if the request is the main app entry point + * Get the absolute path to a module. + * @param {string} request Relative or absolute file path + * @param {Array} paths Folders to search as file paths + * @param {boolean} isMain Whether the request is the main app entry point * @returns {string | false} */ Module._findPath = function(request, paths, isMain) { @@ -571,8 +671,9 @@ Module._findPath = function(request, paths, isMain) { const cacheKey = request + '\x00' + ArrayPrototypeJoin(paths, '\x00'); const entry = Module._pathCache[cacheKey]; - if (entry) + if (entry) { return entry; + } let exts; const trailingSlash = request.length > 0 && @@ -619,8 +720,9 @@ Module._findPath = function(request, paths, isMain) { if (!absoluteRequest) { const exportsResolved = resolveExports(curPath, request); - if (exportsResolved) + if (exportsResolved) { return exportsResolved; + } } const basePath = path.resolve(curPath, request); @@ -652,16 +754,18 @@ Module._findPath = function(request, paths, isMain) { if (!filename) { // Try it with each of the extensions - if (exts === undefined) + if (exts === undefined) { exts = ObjectKeys(Module._extensions); + } filename = tryExtensions(basePath, exts, isMain); } } if (!filename && rc === 1) { // Directory. // try it with each of the extensions at "index" - if (exts === undefined) + if (exts === undefined) { exts = ObjectKeys(Module._extensions); + } filename = tryPackage(basePath, exts, isMain, request); } @@ -680,11 +784,14 @@ Module._findPath = function(request, paths, isMain) { return false; }; -// 'node_modules' character codes reversed +/** `node_modules` character codes reversed */ const nmChars = [ 115, 101, 108, 117, 100, 111, 109, 95, 101, 100, 111, 110 ]; const nmLen = nmChars.length; if (isWindows) { - // 'from' is the __dirname of the module. + /** + * Get the paths to the `node_modules` folder for a given path. + * @param {string} from `__dirname` of the module + */ Module._nodeModulePaths = function(from) { // Guarantee that 'from' is absolute. from = path.resolve(from); @@ -697,9 +804,11 @@ if (isWindows) { // path.resolve will make sure from.length >=3 in Windows. if (StringPrototypeCharCodeAt(from, from.length - 1) === CHAR_BACKWARD_SLASH && - StringPrototypeCharCodeAt(from, from.length - 2) === CHAR_COLON) + StringPrototypeCharCodeAt(from, from.length - 2) === CHAR_COLON) { return [from + 'node_modules']; + } + /** @type {string[]} */ const paths = []; for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) { const code = StringPrototypeCharCodeAt(from, i); @@ -711,11 +820,12 @@ if (isWindows) { if (code === CHAR_BACKWARD_SLASH || code === CHAR_FORWARD_SLASH || code === CHAR_COLON) { - if (p !== nmLen) + if (p !== nmLen) { ArrayPrototypePush( paths, StringPrototypeSlice(from, 0, last) + '\\node_modules', ); + } last = i; p = 0; } else if (p !== -1) { @@ -730,27 +840,33 @@ if (isWindows) { return paths; }; } else { // posix - // 'from' is the __dirname of the module. + /** + * Get the paths to the `node_modules` folder for a given path. + * @param {string} from `__dirname` of the module + */ Module._nodeModulePaths = function(from) { // Guarantee that 'from' is absolute. from = path.resolve(from); // Return early not only to avoid unnecessary work, but to *avoid* returning // an array of two items for a root: [ '//node_modules', '/node_modules' ] - if (from === '/') + if (from === '/') { return ['/node_modules']; + } // note: this approach *only* works when the path is guaranteed // to be absolute. Doing a fully-edge-case-correct path.split // that works on both Windows and Posix is non-trivial. + /** @type {string[]} */ const paths = []; for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) { const code = StringPrototypeCharCodeAt(from, i); if (code === CHAR_FORWARD_SLASH) { - if (p !== nmLen) + if (p !== nmLen) { ArrayPrototypePush( paths, StringPrototypeSlice(from, 0, last) + '/node_modules', ); + } last = i; p = 0; } else if (p !== -1) { @@ -769,6 +885,11 @@ if (isWindows) { }; } +/** + * Get the paths for module resolution. + * @param {string} request + * @param {Module} parent + */ Module._resolveLookupPaths = function(request, parent) { if (BuiltinModule.normalizeRequirableId(request)) { debug('looking for %j in []', request); @@ -782,6 +903,7 @@ Module._resolveLookupPaths = function(request, parent) { StringPrototypeCharAt(request, 1) !== '/' && (!isWindows || StringPrototypeCharAt(request, 1) !== '\\'))) { + /** @type {string[]} */ let paths; if (parent?.paths?.length) { paths = ArrayPrototypeSlice(modulePaths); @@ -811,6 +933,10 @@ Module._resolveLookupPaths = function(request, parent) { return parentDir; }; +/** + * Emits a warning when a non-existent property of module exports is accessed inside a circular dependency. + * @param {string} prop The name of the non-existent property. + */ function emitCircularRequireWarning(prop) { process.emitWarning( `Accessing non-existent property '${String(prop)}' of module exports ` + @@ -827,19 +953,26 @@ const CircularRequirePrototypeWarningProxy = new Proxy({}, { // Allow __esModule access in any case because it is used in the output // of transpiled code to determine whether something comes from an // ES module, and is not used as a regular key of `module.exports`. - if (prop in target || prop === '__esModule') return target[prop]; + if (prop in target || prop === '__esModule') { return target[prop]; } emitCircularRequireWarning(prop); return undefined; }, getOwnPropertyDescriptor(target, prop) { - if (ObjectPrototypeHasOwnProperty(target, prop) || prop === '__esModule') + if (ObjectPrototypeHasOwnProperty(target, prop) || prop === '__esModule') { return ObjectGetOwnPropertyDescriptor(target, prop); + } emitCircularRequireWarning(prop); return undefined; }, }); +/** + * Returns the exports object for a module that has a circular `require`. + * If the exports object is a plain object, it is wrapped in a proxy that warns + * about circular dependencies. + * @param {Module} module The module instance + */ function getExportsForCircularRequire(module) { if (module.exports && !isProxy(module.exports) && @@ -857,13 +990,17 @@ function getExportsForCircularRequire(module) { return module.exports; } -// Check the cache for the requested file. -// 1. If a module already exists in the cache: return its exports object. -// 2. If the module is native: call -// `BuiltinModule.prototype.compileForPublicLoader()` and return the exports. -// 3. Otherwise, create a new module for the file and save it to the cache. -// Then have it load the file contents before returning its exports -// object. +/** + * Load a module from cache if it exists, otherwise create a new module instance. + * 1. If a module already exists in the cache: return its exports object. + * 2. If the module is native: call + * `BuiltinModule.prototype.compileForPublicLoader()` and return the exports. + * 3. Otherwise, create a new module for the file and save it to the cache. + * Then have it load the file contents before returning its exports object. + * @param {string} request Specifier of module to load via `require` + * @param {string} parent Absolute path of the module importing the child + * @param {boolean} isMain Whether the module is the main entry point + */ Module._load = function(request, parent, isMain) { let relResolveCacheIdentifier; if (parent) { @@ -878,8 +1015,9 @@ Module._load = function(request, parent, isMain) { const cachedModule = Module._cache[filename]; if (cachedModule !== undefined) { updateChildren(parent, cachedModule, true); - if (!cachedModule.loaded) + if (!cachedModule.loaded) { return getExportsForCircularRequire(cachedModule); + } return cachedModule.exports; } delete relativeResolveCache[relResolveCacheIdentifier]; @@ -904,8 +1042,9 @@ Module._load = function(request, parent, isMain) { updateChildren(parent, cachedModule, true); if (!cachedModule.loaded) { const parseCachedModule = cjsParseCache.get(cachedModule); - if (!parseCachedModule || parseCachedModule.loaded) + if (!parseCachedModule || parseCachedModule.loaded) { return getExportsForCircularRequire(cachedModule); + } parseCachedModule.loaded = true; } else { return cachedModule.exports; @@ -961,6 +1100,15 @@ Module._load = function(request, parent, isMain) { return module.exports; }; +/** + * Given a `require` string and its context, get its absolute file path. + * @param {string} request The specifier to resolve + * @param {Module} parent The module containing the `require` call + * @param {boolean} isMain Whether the module is the main entry point + * @param {ResolveFilenameOptions} options Options object + * @typedef {object} ResolveFilenameOptions + * @property {string[]} paths Paths to search for modules in + */ Module._resolveFilename = function(request, parent, isMain, options) { if (BuiltinModule.normalizeRequirableId(request)) { return request; @@ -988,8 +1136,9 @@ Module._resolveFilename = function(request, parent, isMain, options) { const lookupPaths = Module._resolveLookupPaths(request, fakeParent); for (let j = 0; j < lookupPaths.length; j++) { - if (!ArrayPrototypeIncludes(paths, lookupPaths[j])) + if (!ArrayPrototypeIncludes(paths, lookupPaths[j])) { ArrayPrototypePush(paths, lookupPaths[j]); + } } } } @@ -1013,8 +1162,9 @@ Module._resolveFilename = function(request, parent, isMain, options) { getCjsConditions()), parentPath, pkg.path); } catch (e) { - if (e.code === 'ERR_MODULE_NOT_FOUND') + if (e.code === 'ERR_MODULE_NOT_FOUND') { throw createEsmNotFoundErr(request); + } throw e; } } @@ -1032,7 +1182,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { // Look up the filename first, since that's the cache key. const filename = Module._findPath(request, paths, isMain); - if (filename) return filename; + if (filename) { return filename; } const requireStack = []; for (let cursor = parent; cursor; @@ -1051,31 +1201,50 @@ Module._resolveFilename = function(request, parent, isMain, options) { throw err; }; +/** + * Finishes resolving an ES module specifier into an absolute file path. + * @param {string} resolved The resolved module specifier + * @param {string} parentPath The path of the parent module + * @param {string} pkgPath The path of the package.json file + * @throws {ERR_INVALID_MODULE_SPECIFIER} If the resolved module specifier contains encoded `/` or `\\` characters + * @throws {Error} If the module cannot be found + */ function finalizeEsmResolution(resolved, parentPath, pkgPath) { const { encodedSepRegEx } = require('internal/modules/esm/resolve'); - if (RegExpPrototypeExec(encodedSepRegEx, resolved) !== null) + if (RegExpPrototypeExec(encodedSepRegEx, resolved) !== null) { throw new ERR_INVALID_MODULE_SPECIFIER( resolved, 'must not include encoded "/" or "\\" characters', parentPath); + } const filename = fileURLToPath(resolved); const actual = tryFile(filename); - if (actual) + if (actual) { return actual; + } const err = createEsmNotFoundErr(filename, path.resolve(pkgPath, 'package.json')); throw err; } +/** + * Creates an error object for when a requested ES module cannot be found. + * @param {string} request The name of the requested module + * @param {string} [path] The path to the requested module + */ function createEsmNotFoundErr(request, path) { // eslint-disable-next-line no-restricted-syntax const err = new Error(`Cannot find module '${request}'`); err.code = 'MODULE_NOT_FOUND'; - if (path) + if (path) { err.path = path; + } // TODO(BridgeAR): Add the requireStack as well. return err; } -// Given a file name, pass it to the proper extension handler. +/** + * Given a file name, pass it to the proper extension handler. + * @param {string} filename The `require` specifier + */ Module.prototype.load = function(filename) { debug('load %j for module %j', filename, this.id); @@ -1085,8 +1254,9 @@ Module.prototype.load = function(filename) { const extension = findLongestRegisteredExtension(filename); // allow .mjs to be overridden - if (StringPrototypeEndsWith(filename, '.mjs') && !Module._extensions['.mjs']) + if (StringPrototypeEndsWith(filename, '.mjs') && !Module._extensions['.mjs']) { throw new ERR_REQUIRE_ESM(filename, true); + } Module._extensions[extension](this, filename); this.loaded = true; @@ -1097,13 +1267,17 @@ Module.prototype.load = function(filename) { // Preemptively cache if ((module?.module === undefined || module.module.getStatus() < kEvaluated) && - !cascadedLoader.cjsCache.has(this)) + !cascadedLoader.cjsCache.has(this)) { cascadedLoader.cjsCache.set(this, exports); + } }; -// Loads a module at the given file path. Returns that module's -// `exports` property. -// Note: when using the experimental policy mechanism this function is overridden +/** + * Loads a module at the given file path. Returns that module's `exports` property. + * Note: when using the experimental policy mechanism this function is overridden. + * @param {string} id + * @throws {ERR_INVALID_ARG_TYPE} When `id` is not a string + */ Module.prototype.require = function(id) { validateString(id, 'id'); if (id === '') { @@ -1118,12 +1292,24 @@ 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) +/** + * 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} */ let Script; -function wrapSafe(filename, content, cjsModuleInstance) { + +/** + * Wraps the given content in a script and runs it in a new context. + * @param {string} filename The name of the file being loaded + * @param {string} content The content of the file being loaded + * @param {Module} cjsModuleInstance The CommonJS loader instance + * @param {object} codeCache The SEA code cache + */ +function wrapSafe(filename, content, cjsModuleInstance, codeCache) { if (patched) { const wrapper = Module.wrap(content); if (Script === undefined) { @@ -1158,6 +1344,7 @@ function wrapSafe(filename, content, cjsModuleInstance) { '__dirname', ], { filename, + cachedData: codeCache, importModuleDynamically(specifier, _, importAssertions) { const cascadedLoader = getCascadedLoader(); return cascadedLoader.import(specifier, normalizeReferrerURL(filename), @@ -1165,6 +1352,13 @@ function wrapSafe(filename, content, cjsModuleInstance) { }, }); + // The code cache is used for SEAs only. + if (codeCache && + result.cachedDataRejected !== false && + internalBinding('sea').isSea()) { + process.emitWarning('Code cache data rejected.'); + } + // Cache the source map for the module if present. if (result.sourceMapURL) { maybeCacheSourceMap(filename, content, this, false, undefined, result.sourceMapURL); @@ -1180,10 +1374,12 @@ function wrapSafe(filename, content, cjsModuleInstance) { } } -// Run the file contents in the correct scope or sandbox. Expose -// the correct helper variables (require, module, exports) to -// the file. -// Returns exception, if any. +/** + * Run the file contents in the correct scope or sandbox. Expose the correct helper variables (`require`, `module`, + * `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 + */ Module.prototype._compile = function(content, filename) { let moduleURL; let redirects; @@ -1225,7 +1421,7 @@ Module.prototype._compile = function(content, filename) { const exports = this.exports; const thisValue = exports; const module = this; - if (requireDepth === 0) statCache = new SafeMap(); + if (requireDepth === 0) { statCache = new SafeMap(); } if (inspectorWrapper) { result = inspectorWrapper(compiledWrapper, thisValue, exports, require, module, filename, dirname); @@ -1234,11 +1430,15 @@ Module.prototype._compile = function(content, filename) { [exports, require, module, filename, dirname]); } hasLoadedAnyUserCJSModule = true; - if (requireDepth === 0) statCache = null; + if (requireDepth === 0) { statCache = null; } return result; }; -// Native extension for .js +/** + * Native 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 cached = cjsParseCache.get(module); @@ -1287,8 +1487,11 @@ Module._extensions['.js'] = function(module, filename) { module._compile(content, filename); }; - -// Native extension for .json +/** + * Native handler for `.json` files. + * @param {Module} module The module to compile + * @param {string} filename The file path of the module + */ Module._extensions['.json'] = function(module, filename) { const content = fs.readFileSync(filename, 'utf8'); @@ -1306,8 +1509,11 @@ Module._extensions['.json'] = function(module, filename) { } }; - -// Native extension for .node +/** + * Native handler for `.node` files. + * @param {Module} module The module to compile + * @param {string} filename The file path of the module + */ Module._extensions['.node'] = function(module, filename) { const manifest = policy()?.manifest; if (manifest) { @@ -1319,6 +1525,10 @@ Module._extensions['.node'] = function(module, filename) { return process.dlopen(module, path.toNamespacedPath(filename)); }; +/** + * Creates a `require` function that can be used to load modules from the specified path. + * @param {string} filename The path to the module + */ function createRequireFromPath(filename) { // Allow a directory to be passed as the filename const trailingSlash = @@ -1339,6 +1549,12 @@ function createRequireFromPath(filename) { const createRequireError = 'must be a file URL object, file URL string, or ' + 'absolute path string'; +/** + * Creates a new `require` function that can be used to load modules. + * @param {string | URL} filename The path or URL to the module context for this `require` + * @throws {ERR_INVALID_ARG_VALUE} If `filename` is not a string or URL, or if it is a relative path that cannot be + * resolved to an absolute path. + */ function createRequire(filename) { let filepath; @@ -1360,6 +1576,9 @@ function createRequire(filename) { Module.createRequire = createRequire; +/** + * Define the paths to use for resolving a module. + */ Module._initPaths = function() { const homeDir = isWindows ? process.env.USERPROFILE : safeGetenv('HOME'); const nodePath = isWindows ? process.env.NODE_PATH : safeGetenv('NODE_PATH'); @@ -1390,9 +1609,12 @@ Module._initPaths = function() { Module.globalPaths = ArrayPrototypeSlice(modulePaths); }; +/** + * Handle modules loaded via `--require`. + * @param {string[]} requests The values of `--require` + */ Module._preloadModules = function(requests) { - if (!ArrayIsArray(requests)) - return; + if (!ArrayIsArray(requests)) { return; } isPreloading = true; @@ -1408,11 +1630,16 @@ Module._preloadModules = function(requests) { throw e; } } - for (let n = 0; n < requests.length; n++) + for (let n = 0; n < requests.length; n++) { internalRequire(parent, requests[n]); + } isPreloading = false; }; +/** + * If the user has overridden an export from a builtin module, this function can ensure that the override is used in + * both CommonJS and ES module contexts. + */ Module.syncBuiltinESMExports = function syncBuiltinESMExports() { for (const mod of BuiltinModule.map.values()) { if (BuiltinModule.canBeRequiredWithoutScheme(mod.id)) { @@ -1421,5 +1648,14 @@ Module.syncBuiltinESMExports = function syncBuiltinESMExports() { } }; +ObjectDefineProperty(Module.prototype, 'constructor', { + __proto__: null, + get: function() { + return policy() ? undefined : Module; + }, + configurable: false, + enumerable: false, +}); + // Backwards compatibility Module.Module = Module; diff --git a/lib/internal/modules/esm/create_dynamic_module.js b/lib/internal/modules/esm/create_dynamic_module.js index 26ccd38be1ad6f..2eac81a82211ee 100644 --- a/lib/internal/modules/esm/create_dynamic_module.js +++ b/lib/internal/modules/esm/create_dynamic_module.js @@ -11,12 +11,21 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { debug = fn; }); +/** + * Creates an import statement for a given module path and index. + * @param {string} impt - The module path to import. + * @param {number} index - The index of the import statement. + */ function createImport(impt, index) { const imptPath = JSONStringify(impt); return `import * as $import_${index} from ${imptPath}; import.meta.imports[${imptPath}] = $import_${index};`; } +/** + * Creates an export for a given module. + * @param {string} expt - The name of the export. + */ function createExport(expt) { const name = `${expt}`; return `let $${name}; @@ -27,6 +36,17 @@ import.meta.exports.${name} = { };`; } +/** + * Creates a dynamic module with the given imports, exports, URL, and evaluate function. + * @param {string[]} imports - An array of imports. + * @param {string[]} exports - An array of exports. + * @param {string} [url=''] - The URL of the module. + * @param {(reflect: DynamicModuleReflect) => void} evaluate - The function to evaluate the module. + * @typedef {object} DynamicModuleReflect + * @property {string[]} imports - The imports of the module. + * @property {string[]} exports - The exports of the module. + * @property {(cb: (reflect: DynamicModuleReflect) => void) => void} onReady - Callback to evaluate the module. + */ const createDynamicModule = (imports, exports, url = '', evaluate) => { debug('creating ESM facade for %s with exports: %j', url, exports); const source = ` @@ -38,19 +58,23 @@ import.meta.done(); const m = new ModuleWrap(`${url}`, undefined, source, 0, 0); const readyfns = new SafeSet(); + /** @type {DynamicModuleReflect} */ const reflect = { exports: { __proto__: null }, onReady: (cb) => { readyfns.add(cb); }, }; - if (imports.length) + if (imports.length) { reflect.imports = { __proto__: null }; - const { setCallbackForWrap } = require('internal/modules/esm/utils'); - setCallbackForWrap(m, { + } + const { registerModule } = require('internal/modules/esm/utils'); + registerModule(m, { + __proto__: null, initializeImportMeta: (meta, wrap) => { meta.exports = reflect.exports; - if (reflect.imports) + if (reflect.imports) { meta.imports = reflect.imports; + } meta.done = () => { evaluate(reflect); reflect.onReady = (cb) => cb(reflect); diff --git a/lib/internal/modules/esm/fetch_module.js b/lib/internal/modules/esm/fetch_module.js index 74d2d2599dbd45..21b7456899604f 100644 --- a/lib/internal/modules/esm/fetch_module.js +++ b/lib/internal/modules/esm/fetch_module.js @@ -44,37 +44,56 @@ const cacheForGET = new SafeMap(); // [2] Creating a new agent instead of using the gloabl agent improves // performance and precludes the agent becoming tainted. +/** @type {import('https').Agent} The Cached HTTP Agent for **secure** HTTP requests. */ let HTTPSAgent; -function HTTPSGet(url, opts) { +/** + * Make a HTTPs GET request (handling agent setup if needed, caching the agent to avoid + * redudant instantiations). + * @param {Parameters[0]} input - The URI to fetch. + * @param {Parameters[1]} options - See https.get() options. + */ +function HTTPSGet(input, options) { const https = require('https'); // [1] HTTPSAgent ??= new https.Agent({ // [2] keepAlive: true, }); - return https.get(url, { + return https.get(input, { agent: HTTPSAgent, - ...opts, + ...options, }); } +/** @type {import('https').Agent} The Cached HTTP Agent for **insecure** HTTP requests. */ let HTTPAgent; -function HTTPGet(url, opts) { +/** + * Make a HTTP GET request (handling agent setup if needed, caching the agent to avoid + * redudant instantiations). + * @param {Parameters[0]} input - The URI to fetch. + * @param {Parameters[1]} options - See http.get() options. + */ +function HTTPGet(input, options) { const http = require('http'); // [1] HTTPAgent ??= new http.Agent({ // [2] keepAlive: true, }); - return http.get(url, { + return http.get(input, { agent: HTTPAgent, - ...opts, + ...options, }); } -function dnsLookup(name, opts) { +/** @type {import('../../dns/promises.js').lookup} */ +function dnsLookup(hostname, options) { // eslint-disable-next-line no-func-assign dnsLookup = require('dns/promises').lookup; - return dnsLookup(name, opts); + return dnsLookup(hostname, options); } let zlib; +/** + * Create a decompressor for the Brotli format. + * @returns {import('zlib').BrotliDecompress} + */ function createBrotliDecompress() { zlib ??= require('zlib'); // [1] // eslint-disable-next-line no-func-assign @@ -82,6 +101,10 @@ function createBrotliDecompress() { return createBrotliDecompress(); } +/** + * Create an unzip handler. + * @returns {import('zlib').Unzip} + */ function createUnzip() { zlib ??= require('zlib'); // [1] // eslint-disable-next-line no-func-assign @@ -144,7 +167,7 @@ function fetchWithRedirects(parsed) { return entry; } if (res.statusCode === 404) { - const err = new ERR_MODULE_NOT_FOUND(parsed.href, null); + const err = new ERR_MODULE_NOT_FOUND(parsed.href, null, parsed); err.message = `Cannot find module '${parsed.href}', HTTP 404`; throw err; } diff --git a/lib/internal/modules/esm/formats.js b/lib/internal/modules/esm/formats.js index 63742914597c46..4ab9aa6f032b7e 100644 --- a/lib/internal/modules/esm/formats.js +++ b/lib/internal/modules/esm/formats.js @@ -26,12 +26,12 @@ if (experimentalWasmModules) { function mimeToFormat(mime) { if ( RegExpPrototypeExec( - /\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?/i, + /^\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?$/i, mime, ) !== null - ) return 'module'; - if (mime === 'application/json') return 'json'; - if (experimentalWasmModules && mime === 'application/wasm') return 'wasm'; + ) { return 'module'; } + if (mime === 'application/json') { return 'json'; } + if (experimentalWasmModules && mime === 'application/wasm') { return 'wasm'; } return null; } diff --git a/lib/internal/modules/esm/get_format.js b/lib/internal/modules/esm/get_format.js index 4ac9c011d153f4..b3c8a56c06c1cc 100644 --- a/lib/internal/modules/esm/get_format.js +++ b/lib/internal/modules/esm/get_format.js @@ -79,7 +79,7 @@ function getFileProtocolModuleFormat(url, context, ignoreErrors) { } const format = extensionFormatMap[ext]; - if (format) return format; + if (format) { return format; } // Explicit undefined return indicates load hook should rerun format check if (ignoreErrors) { return undefined; } diff --git a/lib/internal/modules/esm/handle_process_exit.js b/lib/internal/modules/esm/handle_process_exit.js index 9d6b609ef1cfc3..4689ef6bb204c0 100644 --- a/lib/internal/modules/esm/handle_process_exit.js +++ b/lib/internal/modules/esm/handle_process_exit.js @@ -2,9 +2,11 @@ const { exitCodes: { kUnfinishedTopLevelAwait } } = internalBinding('errors'); -// Handle a Promise from running code that potentially does Top-Level Await. -// In that case, it makes sense to set the exit code to a specific non-zero -// value if the main code never finishes running. +/** + * Handle a Promise from running code that potentially does Top-Level Await. + * In that case, it makes sense to set the exit code to a specific non-zero value + * if the main code never finishes running. + */ function handleProcessExit() { process.exitCode ??= kUnfinishedTopLevelAwait; } diff --git a/lib/internal/modules/esm/hooks.js b/lib/internal/modules/esm/hooks.js index cef2897bd68967..8ad4d00bbfe06f 100644 --- a/lib/internal/modules/esm/hooks.js +++ b/lib/internal/modules/esm/hooks.js @@ -2,7 +2,7 @@ const { ArrayPrototypePush, - FunctionPrototypeCall, + ArrayPrototypePushApply, Int32Array, ObjectAssign, ObjectDefineProperty, @@ -30,6 +30,7 @@ const { ERR_INVALID_RETURN_PROPERTY_VALUE, ERR_INVALID_RETURN_VALUE, ERR_LOADER_CHAIN_INCOMPLETE, + ERR_METHOD_NOT_IMPLEMENTED, ERR_WORKER_UNSERIALIZABLE_ERROR, } = require('internal/errors').codes; const { exitCodes: { kUnfinishedTopLevelAwait } } = internalBinding('errors'); @@ -44,8 +45,9 @@ const { validateObject, validateString, } = require('internal/validators'); - -const { kEmptyObject } = require('internal/util'); +const { + kEmptyObject, +} = require('internal/util'); const { defaultResolve, @@ -63,11 +65,10 @@ const { let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { debug = fn; }); - +let importMetaInitializer; /** * @typedef {object} ExportedHooks - * @property {Function} globalPreload Global preload hook. * @property {Function} resolve Resolve hook. * @property {Function} load Load hook. */ @@ -80,16 +81,8 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { // [2] `validate...()`s throw the wrong error - class Hooks { #chains = { - /** - * Prior to ESM loading. These are called once before any modules are started. - * @private - * @property {KeyedHook[]} globalPreload Last-in-first-out list of preload hooks. - */ - globalPreload: [], - /** * Phase 1 of 2 in ESM loading. * The output of the `resolve` chain of hooks is passed into the `load` chain of hooks. @@ -119,88 +112,49 @@ class Hooks { // Cache URLs we've already validated to avoid repeated validation #validatedUrls = new SafeSet(); + allowImportMetaResolve = false; + /** * Import and register custom/user-defined module loader hook(s). * @param {string} urlOrSpecifier * @param {string} parentURL + * @param {any} [data] Arbitrary data to be passed from the custom + * loader (user-land) to the worker. */ - async register(urlOrSpecifier, parentURL) { + async register(urlOrSpecifier, parentURL, data) { const moduleLoader = require('internal/process/esm_loader').esmLoader; - const keyedExports = await moduleLoader.import( urlOrSpecifier, parentURL, kEmptyObject, ); - - this.addCustomLoader(urlOrSpecifier, keyedExports); + await this.addCustomLoader(urlOrSpecifier, keyedExports, data); } /** * Collect custom/user-defined module loader hook(s). - * After all hooks have been collected, the global preload hook(s) must be initialized. * @param {string} url Custom loader specifier * @param {Record} exports + * @param {any} [data] Arbitrary data to be passed from the custom loader (user-land) + * to the worker. + * @returns {any | Promise} User data, ignored unless it's a promise, in which case it will be awaited. */ - addCustomLoader(url, exports) { + addCustomLoader(url, exports, data) { const { - globalPreload, + initialize, resolve, load, } = pluckHooks(exports); - if (globalPreload) { - ArrayPrototypePush(this.#chains.globalPreload, { fn: globalPreload, url }); - } if (resolve) { - ArrayPrototypePush(this.#chains.resolve, { fn: resolve, url }); + const next = this.#chains.resolve[this.#chains.resolve.length - 1]; + ArrayPrototypePush(this.#chains.resolve, { __proto__: null, fn: resolve, url, next }); } if (load) { - ArrayPrototypePush(this.#chains.load, { fn: load, url }); + const next = this.#chains.load[this.#chains.load.length - 1]; + ArrayPrototypePush(this.#chains.load, { __proto__: null, fn: load, url, next }); } - } - - /** - * Initialize `globalPreload` hooks. - */ - initializeGlobalPreload() { - const preloadScripts = []; - for (let i = this.#chains.globalPreload.length - 1; i >= 0; i--) { - const { MessageChannel } = require('internal/worker/io'); - const channel = new MessageChannel(); - const { - port1: insidePreload, - port2: insideLoader, - } = channel; - - insidePreload.unref(); - insideLoader.unref(); - - const { - fn: preload, - url: specifier, - } = this.#chains.globalPreload[i]; - - const preloaded = preload({ - port: insideLoader, - }); - - if (preloaded == null) { continue; } - - if (typeof preloaded !== 'string') { // [2] - throw new ERR_INVALID_RETURN_VALUE( - 'a string', - `${specifier} globalPreload`, - preload, - ); - } - - ArrayPrototypePush(preloadScripts, { - code: preloaded, - port: insidePreload, - }); - } - return preloadScripts; + return initialize?.(data); } /** @@ -233,7 +187,6 @@ class Hooks { chainFinished: null, context, hookErrIdentifier: '', - hookIndex: chain.length - 1, hookName: 'resolve', shortCircuited: false, }; @@ -244,7 +197,7 @@ class Hooks { `${hookErrIdentifier} specifier`, ); // non-strings can be coerced to a URL string - if (ctx) validateObject(ctx, `${hookErrIdentifier} context`); + if (ctx) { validateObject(ctx, `${hookErrIdentifier} context`); } }; const validateOutput = (hookErrIdentifier, output) => { if (typeof output !== 'object' || output === null) { // [2] @@ -256,7 +209,7 @@ class Hooks { } }; - const nextResolve = nextHookFactory(chain, meta, { validateArgs, validateOutput }); + const nextResolve = nextHookFactory(chain[chain.length - 1], meta, { validateArgs, validateOutput }); const resolution = await nextResolve(originalSpecifier, context); const { hookErrIdentifier } = meta; // Retrieve the value after all settled @@ -333,6 +286,10 @@ class Hooks { }; } + resolveSync(_originalSpecifier, _parentURL, _importAssertions) { + throw new ERR_METHOD_NOT_IMPLEMENTED('resolveSync()'); + } + /** * Provide source that is understood by one of Node's translators. * @@ -349,7 +306,6 @@ class Hooks { chainFinished: null, context, hookErrIdentifier: '', - hookIndex: chain.length - 1, hookName: 'load', shortCircuited: false, }; @@ -391,7 +347,7 @@ class Hooks { } }; - const nextLoad = nextHookFactory(chain, meta, { validateArgs, validateOutput }); + const nextLoad = nextHookFactory(chain[chain.length - 1], meta, { validateArgs, validateOutput }); const loaded = await nextLoad(url, context); const { hookErrIdentifier } = meta; // Retrieve the value after all settled @@ -466,6 +422,16 @@ class Hooks { source, }; } + + forceLoadHooks() { + // No-op + } + + importMetaInitialize(meta, context, loader) { + importMetaInitializer ??= require('internal/modules/esm/initialize_import_meta').initializeImportMeta; + meta = importMetaInitializer(meta, context, loader); + return meta; + } } ObjectSetPrototypeOf(Hooks.prototype, null); @@ -521,31 +487,47 @@ class HooksProxy { this.#worker.on('exit', process.exit); } - #waitForWorker() { + waitForWorker() { if (!this.#isReady) { const { kIsOnline } = require('internal/worker'); if (!this.#worker[kIsOnline]) { debug('wait for signal from worker'); AtomicsWait(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 0); const response = this.#worker.receiveMessageSync(); - if (response.message.status === 'exit') { return; } - const { preloadScripts } = this.#unwrapMessage(response); - this.#executePreloadScripts(preloadScripts); + if (response == null || response.message.status === 'exit') { return; } + + // ! This line catches initialization errors in the worker thread. + this.#unwrapMessage(response); } this.#isReady = true; } } - async makeAsyncRequest(method, ...args) { - this.#waitForWorker(); + /** + * Invoke a remote method asynchronously. + * @param {string} method Method to invoke + * @param {any[]} [transferList] Objects in `args` to be transferred + * @param {any[]} args Arguments to pass to `method` + * @returns {Promise} + */ + async makeAsyncRequest(method, transferList, ...args) { + this.waitForWorker(); MessageChannel ??= require('internal/worker/io').MessageChannel; const asyncCommChannel = new MessageChannel(); // Pass work to the worker. - debug('post async message to worker', { method, args }); - this.#worker.postMessage({ method, args, port: asyncCommChannel.port2 }, [asyncCommChannel.port2]); + debug('post async message to worker', { method, args, transferList }); + const finalTransferList = [asyncCommChannel.port2]; + if (transferList) { + ArrayPrototypePushApply(finalTransferList, transferList); + } + this.#worker.postMessage({ + __proto__: null, + method, args, + port: asyncCommChannel.port2, + }, finalTransferList); if (this.#numberOfPendingAsyncResponses++ === 0) { // On the next lines, the main thread will await a response from the worker thread that might @@ -577,12 +559,19 @@ class HooksProxy { return body; } - makeSyncRequest(method, ...args) { - this.#waitForWorker(); + /** + * Invoke a remote method synchronously. + * @param {string} method Method to invoke + * @param {any[]} [transferList] Objects in `args` to be transferred + * @param {any[]} args Arguments to pass to `method` + * @returns {any} + */ + makeSyncRequest(method, transferList, ...args) { + this.waitForWorker(); // Pass work to the worker. - debug('post sync message to worker', { method, args }); - this.#worker.postMessage({ method, args }); + debug('post sync message to worker', { method, args, transferList }); + this.#worker.postMessage({ __proto__: null, method, args }, transferList); let response; do { @@ -608,7 +597,7 @@ class HooksProxy { } const { status, body } = response.message; if (status === 'error') { - if (body == null || typeof body !== 'object') throw body; + if (body == null || typeof body !== 'object') { throw body; } if (body.serializationFailed || body.serialized == null) { throw ERR_WORKER_UNSERIALIZABLE_ERROR(); } @@ -620,40 +609,17 @@ class HooksProxy { } } - #executePreloadScripts(preloadScripts) { - for (let i = 0; i < preloadScripts.length; i++) { - const { code, port } = preloadScripts[i]; - const { compileFunction } = require('vm'); - const preloadInit = compileFunction( - code, - ['getBuiltin', 'port'], - { - filename: '', - }, - ); - const { BuiltinModule } = require('internal/bootstrap/realm'); - // Calls the compiled preload source text gotten from the hook - // Since the parameters are named we use positional parameters - // see compileFunction above to cross reference the names - FunctionPrototypeCall( - preloadInit, - globalThis, - // Param getBuiltin - (builtinName) => { - if (BuiltinModule.canBeRequiredByUsers(builtinName) && - BuiltinModule.canBeRequiredWithoutScheme(builtinName)) { - return require(builtinName); - } - throw new ERR_INVALID_ARG_VALUE('builtinName', builtinName); - }, - // Param port - port, - ); - } + #importMetaInitializer = require('internal/modules/esm/initialize_import_meta').initializeImportMeta; + + importMetaInitialize(meta, context, loader) { + this.#importMetaInitializer(meta, context, loader); } } ObjectSetPrototypeOf(HooksProxy.prototype, null); +// TODO(JakobJingleheimer): Remove this when loaders go "stable". +let globalPreloadWarningWasEmitted = false; + /** * A utility function to pluck the hooks from a user-defined loader. * @param {import('./loader.js).ModuleExports} exports @@ -661,14 +627,12 @@ ObjectSetPrototypeOf(HooksProxy.prototype, null); */ function pluckHooks({ globalPreload, + initialize, resolve, load, }) { const acceptedHooks = { __proto__: null }; - if (globalPreload) { - acceptedHooks.globalPreload = globalPreload; - } if (resolve) { acceptedHooks.resolve = resolve; } @@ -676,6 +640,16 @@ function pluckHooks({ acceptedHooks.load = load; } + if (initialize) { + acceptedHooks.initialize = initialize; + } else if (globalPreload && !globalPreloadWarningWasEmitted) { + process.emitWarning( + '`globalPreload` has been removed; use `initialize` instead.', + 'UnsupportedWarning', + ); + globalPreloadWarningWasEmitted = true; + } + return acceptedHooks; } @@ -684,15 +658,14 @@ function pluckHooks({ * A utility function to iterate through a hook chain, track advancement in the * chain, and generate and supply the `next` argument to the custom * hook. - * @param {KeyedHook[]} chain The whole hook chain. + * @param {Hook} current The (currently) first hook in the chain (this shifts + * on every call). * @param {object} meta Properties that change as the current hook advances * along the chain. * @param {boolean} meta.chainFinished Whether the end of the chain has been * reached AND invoked. * @param {string} meta.hookErrIdentifier A user-facing identifier to help * pinpoint where an error occurred. Ex "file:///foo.mjs 'resolve'". - * @param {number} meta.hookIndex A non-negative integer tracking the current - * position in the hook chain. * @param {string} meta.hookName The kind of hook the chain is (ex 'resolve') * @param {boolean} meta.shortCircuited Whether a hook signaled a short-circuit. * @param {(hookErrIdentifier, hookArgs) => void} validate A wrapper function @@ -700,13 +673,14 @@ function pluckHooks({ * validation within MUST throw. * @returns {function next(...hookArgs)} The next hook in the chain. */ -function nextHookFactory(chain, meta, { validateArgs, validateOutput }) { +function nextHookFactory(current, meta, { validateArgs, validateOutput }) { // First, prepare the current const { hookName } = meta; const { fn: hook, url: hookFilePath, - } = chain[meta.hookIndex]; + next, + } = current; // ex 'nextResolve' const nextHookName = `next${ @@ -714,16 +688,9 @@ function nextHookFactory(chain, meta, { validateArgs, validateOutput }) { StringPrototypeSlice(hookName, 1) }`; - // When hookIndex is 0, it's reached the default, which does not call next() - // so feed it a noop that blows up if called, so the problem is obvious. - const generatedHookIndex = meta.hookIndex; let nextNextHook; - if (meta.hookIndex > 0) { - // Now, prepare the next: decrement the pointer so the next call to the - // factory generates the next link in the chain. - meta.hookIndex--; - - nextNextHook = nextHookFactory(chain, meta, { validateArgs, validateOutput }); + if (next) { + nextNextHook = nextHookFactory(next, meta, { validateArgs, validateOutput }); } else { // eslint-disable-next-line func-name-matching nextNextHook = function chainAdvancedTooFar() { @@ -740,17 +707,16 @@ function nextHookFactory(chain, meta, { validateArgs, validateOutput }) { validateArgs(`${meta.hookErrIdentifier} hook's ${nextHookName}()`, arg0, context); - const outputErrIdentifier = `${chain[generatedHookIndex].url} '${hookName}' hook's ${nextHookName}()`; + const outputErrIdentifier = `${hookFilePath} '${hookName}' hook's ${nextHookName}()`; // Set when next is actually called, not just generated. - if (generatedHookIndex === 0) { meta.chainFinished = true; } + if (!next) { meta.chainFinished = true; } if (context) { // `context` has already been validated, so no fancy check needed. ObjectAssign(meta.context, context); } const output = await hook(arg0, meta.context, nextNextHook); - validateOutput(outputErrIdentifier, output); if (output?.shortCircuit === true) { meta.shortCircuited = true; } diff --git a/lib/internal/modules/esm/initialize_import_meta.js b/lib/internal/modules/esm/initialize_import_meta.js index c548f71bef837a..f55f60a5b7647a 100644 --- a/lib/internal/modules/esm/initialize_import_meta.js +++ b/lib/internal/modules/esm/initialize_import_meta.js @@ -5,25 +5,38 @@ const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta /** * Generate a function to be used as import.meta.resolve for a particular module. - * @param {string} defaultParentUrl The default base to use for resolution + * @param {string} defaultParentURL The default base to use for resolution * @param {typeof import('./loader.js').ModuleLoader} loader Reference to the current module loader - * @returns {(specifier: string, parentUrl?: string) => string} Function to assign to import.meta.resolve + * @param {bool} allowParentURL Whether to permit parentURL second argument for contextual resolution + * @returns {(specifier: string) => string} Function to assign to import.meta.resolve */ -function createImportMetaResolve(defaultParentUrl, loader) { - return function resolve(specifier, parentUrl = defaultParentUrl) { +function createImportMetaResolve(defaultParentURL, loader, allowParentURL) { + /** + * @param {string} specifier + * @param {URL['href']} [parentURL] When `--experimental-import-meta-resolve` is specified, a + * second argument can be provided. + */ + return function resolve(specifier, parentURL = defaultParentURL) { let url; + if (!allowParentURL) { + parentURL = defaultParentURL; + } + try { - ({ url } = loader.resolve(specifier, parentUrl)); + ({ url } = loader.resolveSync(specifier, parentURL)); + return url; } catch (error) { - if (error?.code === 'ERR_UNSUPPORTED_DIR_IMPORT') { - ({ url } = error); - } else { - throw error; + switch (error?.code) { + case 'ERR_UNSUPPORTED_DIR_IMPORT': + case 'ERR_MODULE_NOT_FOUND': + ({ url } = error); + if (url) { + return url; + } } + throw error; } - - return url; }; } @@ -38,8 +51,8 @@ function initializeImportMeta(meta, context, loader) { const { url } = context; // Alphabetical - if (experimentalImportMetaResolve && loader.loaderType !== 'internal') { - meta.resolve = createImportMetaResolve(url, loader); + if (!loader || loader.allowImportMetaResolve) { + meta.resolve = createImportMetaResolve(url, loader, experimentalImportMetaResolve); } meta.url = url; diff --git a/lib/internal/modules/esm/load.js b/lib/internal/modules/esm/load.js index fbd86e2881c0f0..d064296d11c463 100644 --- a/lib/internal/modules/esm/load.js +++ b/lib/internal/modules/esm/load.js @@ -10,6 +10,7 @@ const { kEmptyObject } = require('internal/util'); const { defaultGetFormat } = require('internal/modules/esm/get_format'); const { validateAssertions } = require('internal/modules/esm/assert'); const { getOptionValue } = require('internal/options'); +const { readFileSync } = require('fs'); // Do not eagerly grab .manifest, it may be in TDZ const policy = getOptionValue('--experimental-policy') ? @@ -69,12 +70,40 @@ async function getSource(url, context) { return { __proto__: null, responseURL, source }; } +/** + * @param {URL} url URL to the module + * @param {ESModuleContext} context used to decorate error messages + * @returns {{ responseURL: string, source: string | BufferView }} + */ +function getSourceSync(url, context) { + const { protocol, href } = url; + const responseURL = href; + let source; + if (protocol === 'file:') { + source = readFileSync(url); + } else if (protocol === 'data:') { + const match = RegExpPrototypeExec(DATA_URL_PATTERN, url.pathname); + if (!match) { + throw new ERR_INVALID_URL(responseURL); + } + const { 1: base64, 2: body } = match; + source = BufferFrom(decodeURIComponent(body), base64 ? 'base64' : 'utf8'); + } else { + const supportedSchemes = ['file', 'data']; + throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(url, supportedSchemes); + } + if (policy?.manifest) { + policy.manifest.assertIntegrity(url, source); + } + return { __proto__: null, responseURL, source }; +} + /** * Node.js default load hook. * @param {string} url - * @param {object} context - * @returns {object} + * @param {LoadContext} context + * @returns {LoadReturn} */ async function defaultLoad(url, context = kEmptyObject) { let responseURL = url; @@ -108,6 +137,55 @@ async function defaultLoad(url, context = kEmptyObject) { source, }; } +/** + * @typedef LoadContext + * @property {string} [format] A hint (possibly returned from `resolve`) + * @property {string | Buffer | ArrayBuffer} [source] source + * @property {Record} [importAssertions] import attributes + */ + +/** + * @typedef LoadReturn + * @property {string} format format + * @property {URL['href']} responseURL The module's fully resolved URL + * @property {Buffer} source source + */ + +/** + * @param {URL['href']} url + * @param {LoadContext} [context] + * @returns {LoadReturn} + */ +function defaultLoadSync(url, context = kEmptyObject) { + let responseURL = url; + const { importAssertions } = context; + let { + format, + source, + } = context; + + const urlInstance = new URL(url); + + throwIfUnsupportedURLScheme(urlInstance, false); + + format ??= defaultGetFormat(urlInstance, context); + + validateAssertions(url, format, importAssertions); + + if (format === 'builtin') { + source = null; + } else if (source == null) { + ({ responseURL, source } = getSourceSync(urlInstance, context)); + } + + return { + __proto__: null, + format, + responseURL, + source, + }; +} + /** * throws an error if the protocol is not one of the protocols @@ -160,5 +238,6 @@ function throwUnknownModuleFormat(url, format) { module.exports = { defaultLoad, + defaultLoadSync, throwUnknownModuleFormat, }; diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index b73ba2eb3c8154..0b08db7ffef7ec 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -4,29 +4,52 @@ require('internal/modules/cjs/loader'); const { + ArrayPrototypeJoin, + ArrayPrototypeMap, + ArrayPrototypeReduce, FunctionPrototypeCall, + JSONStringify, ObjectSetPrototypeOf, - PromisePrototypeThen, + RegExpPrototypeSymbolReplace, SafeWeakMap, + encodeURIComponent, + hardenRegExp, } = primordials; const { - ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE, + ERR_REQUIRE_ESM, ERR_UNKNOWN_MODULE_FORMAT, } = require('internal/errors').codes; const { getOptionValue } = require('internal/options'); -const { pathToFileURL } = require('internal/url'); +const { pathToFileURL, isURL } = require('internal/url'); const { emitExperimentalWarning } = require('internal/util'); const { getDefaultConditions, } = require('internal/modules/esm/utils'); -let defaultResolve, defaultLoad, importMetaInitializer; +let defaultResolve, defaultLoad, defaultLoadSync, importMetaInitializer; -function newModuleMap() { - const ModuleMap = require('internal/modules/esm/module_map'); - return new ModuleMap(); +/** + * Lazy loads the module_map module and returns a new instance of ResolveCache. + * @returns {import('./module_map.js').ResolveCache')} + */ +function newResolveCache() { + const { ResolveCache } = require('internal/modules/esm/module_map'); + return new ResolveCache(); +} + +/** + * Generate a load cache (to store the final result of a load-chain for a particular module). + * @returns {import('./module_map.js').LoadCache')} + */ +function newLoadCache() { + const { LoadCache } = require('internal/modules/esm/module_map'); + return new LoadCache(); } +/** + * Lazy-load translators to avoid potentially unnecessary work at startup (ex if ESM is not used). + * @returns {import('./translators.js').Translators} + */ function getTranslators() { const { translators } = require('internal/modules/esm/translators'); return translators; @@ -52,12 +75,12 @@ let hooksProxy; * @typedef {ArrayBuffer|TypedArray|string} ModuleSource */ - /** - * This class covers the default case of an module loader instance where no custom user loaders are used. - * The below CustomizedModuleLoader class extends this one to support custom user loader hooks. + * This class covers the base machinery of module loading. To add custom + * behavior you can pass a customizations object and this object will be + * used to do the loading/resolving/registration process. */ -class DefaultModuleLoader { +class ModuleLoader { /** * The conditions for resolving packages if `--conditions` is not used. */ @@ -73,10 +96,15 @@ class DefaultModuleLoader { */ evalIndex = 0; + /** + * Registry of resolved specifiers + */ + #resolveCache = newResolveCache(); + /** * Registry of loaded modules, akin to `require.cache` */ - moduleMap = newModuleMap(); + loadCache = newLoadCache(); /** * Methods which translate input code or other information into ES modules @@ -84,15 +112,85 @@ class DefaultModuleLoader { translators = getTranslators(); /** - * Type of loader. - * @type {'default' | 'internal'} + * Truthy to allow the use of `import.meta.resolve`. This is needed + * currently because the `Hooks` class does not have `resolveSync` + * implemented and `import.meta.resolve` requires it. */ - loaderType = 'default'; + allowImportMetaResolve; - constructor() { + /** + * Customizations to pass requests to. + * + * Note that this value _MUST_ be set with `setCustomizations` + * because it needs to copy `customizations.allowImportMetaResolve` + * to this property and failure to do so will cause undefined + * behavior when invoking `import.meta.resolve`. + * @see {ModuleLoader.setCustomizations} + */ + #customizations; + + constructor(customizations) { if (getOptionValue('--experimental-network-imports')) { emitExperimentalWarning('Network Imports'); } + this.setCustomizations(customizations); + } + + /** + * Change the currently activate customizations for this module + * loader to be the provided `customizations`. + * + * If present, this class customizes its core functionality to the + * `customizations` object, including registration, loading, and resolving. + * There are some responsibilities that this class _always_ takes + * care of, like validating outputs, so that the customizations object + * does not have to do so. + * + * The customizations object has the shape: + * + * ```ts + * interface LoadResult { + * format: ModuleFormat; + * source: ModuleSource; + * } + * + * interface ResolveResult { + * format: string; + * url: URL['href']; + * } + * + * interface Customizations { + * allowImportMetaResolve: boolean; + * load(url: string, context: object): Promise + * resolve( + * originalSpecifier: + * string, parentURL: string, + * importAssertions: Record + * ): Promise + * resolveSync( + * originalSpecifier: + * string, parentURL: string, + * importAssertions: Record + * ) ResolveResult; + * register(specifier: string, parentURL: string): any; + * forceLoadHooks(): void; + * } + * ``` + * + * Note that this class _also_ implements the `Customizations` + * interface, as does `CustomizedModuleLoader` and `Hooks`. + * + * Calling this function alters how modules are loaded and should be + * invoked with care. + * @param {object} customizations + */ + setCustomizations(customizations) { + this.#customizations = customizations; + if (customizations) { + this.allowImportMetaResolve = customizations.allowImportMetaResolve; + } else { + this.allowImportMetaResolve = true; + } } async eval( @@ -101,9 +199,10 @@ class DefaultModuleLoader { ) { const evalInstance = (url) => { const { ModuleWrap } = internalBinding('module_wrap'); - const { setCallbackForWrap } = require('internal/modules/esm/utils'); + const { registerModule } = require('internal/modules/esm/utils'); const module = new ModuleWrap(url, undefined, source, 0, 0); - setCallbackForWrap(module, { + registerModule(module, { + __proto__: null, initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }), importModuleDynamically: (specifier, { url }, importAssertions) => { return this.import(specifier, url, importAssertions); @@ -115,7 +214,7 @@ class DefaultModuleLoader { const ModuleJob = require('internal/modules/esm/module_job'); const job = new ModuleJob( this, url, undefined, evalInstance, false, false); - this.moduleMap.set(url, undefined, job); + this.loadCache.set(url, undefined, job); const { module } = await job.run(); return { @@ -135,26 +234,30 @@ class DefaultModuleLoader { * point. * @param {Record} importAssertions Validations for the * module import. - * @returns {ModuleJob} The (possibly pending) module job + * @returns {Promise} The (possibly pending) module job */ - getModuleJob(specifier, parentURL, importAssertions) { - const resolveResult = this.resolve(specifier, parentURL, importAssertions); + async getModuleJob(specifier, parentURL, importAssertions) { + const resolveResult = await this.resolve(specifier, parentURL, importAssertions); return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions); } - getJobFromResolveResult(resolveResult, parentURL, importAssertions) { + getModuleJobSync(specifier, parentURL, importAssertions) { + const resolveResult = this.resolveSync(specifier, parentURL, importAssertions); + return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions, true); + } + + getJobFromResolveResult(resolveResult, parentURL, importAssertions, sync) { const { url, format } = resolveResult; const resolvedImportAssertions = resolveResult.importAssertions ?? importAssertions; - - let job = this.moduleMap.get(url, resolvedImportAssertions.type); + let job = this.loadCache.get(url, resolvedImportAssertions.type); // CommonJS will set functions for lazy job evaluation. if (typeof job === 'function') { - this.moduleMap.set(url, undefined, job = job()); + this.loadCache.set(url, undefined, job = job()); } if (job === undefined) { - job = this.#createModuleJob(url, resolvedImportAssertions, parentURL, format); + job = this.#createModuleJob(url, resolvedImportAssertions, parentURL, format, sync); } return job; @@ -171,17 +274,8 @@ class DefaultModuleLoader { * `resolve` hook * @returns {Promise} The (possibly pending) module job */ - #createModuleJob(url, importAssertions, parentURL, format) { - const moduleProvider = async (url, isMain) => { - const { - format: finalFormat, - responseURL, - source, - } = await this.load(url, { - format, - importAssertions, - }); - + #createModuleJob(url, importAssertions, parentURL, format, sync) { + const callTranslator = ({ format: finalFormat, responseURL, source }, isMain) => { const translator = getTranslators().get(finalFormat); if (!translator) { @@ -190,6 +284,10 @@ class DefaultModuleLoader { return FunctionPrototypeCall(translator, this, responseURL, source, isMain); }; + const context = { format, importAssertions }; + const moduleProvider = sync ? + (url, isMain) => callTranslator(this.loadSync(url, context), isMain) : + async (url, isMain) => callTranslator(await this.load(url, context), isMain); const inspectBrk = ( parentURL === undefined && @@ -208,9 +306,10 @@ class DefaultModuleLoader { moduleProvider, parentURL === undefined, inspectBrk, + sync, ); - this.moduleMap.set(url, importAssertions.type, job); + this.loadCache.set(url, importAssertions.type, job); return job; } @@ -225,11 +324,25 @@ class DefaultModuleLoader { * @returns {Promise} */ async import(specifier, parentURL, importAssertions) { - const moduleJob = this.getModuleJob(specifier, parentURL, importAssertions); + const moduleJob = await this.getModuleJob(specifier, parentURL, importAssertions); const { module } = await moduleJob.run(); return module.getNamespace(); } + /** + * @see {@link CustomizedModuleLoader.register} + */ + register(specifier, parentURL, data, transferList) { + if (!this.#customizations) { + // `CustomizedModuleLoader` is defined at the bottom of this file and + // available well before this line is ever invoked. This is here in + // order to preserve the git diff instead of moving the class. + // eslint-disable-next-line no-use-before-define + this.setCustomizations(new CustomizedModuleLoader()); + } + return this.#customizations.register(`${specifier}`, `${parentURL}`, data, transferList); + } + /** * Resolve the location of the module. * @param {string} originalSpecifier The specified URL path of the module to @@ -240,6 +353,36 @@ class DefaultModuleLoader { * @returns {{ format: string, url: URL['href'] }} */ resolve(originalSpecifier, parentURL, importAssertions) { + if (this.#customizations) { + return this.#customizations.resolve(originalSpecifier, parentURL, importAssertions); + } + const requestKey = this.#resolveCache.serializeKey(originalSpecifier, importAssertions); + const cachedResult = this.#resolveCache.get(requestKey, parentURL); + if (cachedResult != null) { + return cachedResult; + } + const result = this.defaultResolve(originalSpecifier, parentURL, importAssertions); + this.#resolveCache.set(requestKey, parentURL, result); + return result; + } + + /** + * Just like `resolve` except synchronous. This is here specifically to support + * `import.meta.resolve` which must happen synchronously. + */ + resolveSync(originalSpecifier, parentURL, importAssertions) { + if (this.#customizations) { + return this.#customizations.resolveSync(originalSpecifier, parentURL, importAssertions); + } + return this.defaultResolve(originalSpecifier, parentURL, importAssertions); + } + + /** + * Our `defaultResolve` is synchronous and can be used in both + * `resolve` and `resolveSync`. This function is here just to avoid + * repeating the same code block twice in those functions. + */ + defaultResolve(originalSpecifier, parentURL, importAssertions) { defaultResolve ??= require('internal/modules/esm/resolve').defaultResolve; const context = { @@ -260,12 +403,31 @@ class DefaultModuleLoader { */ async load(url, context) { defaultLoad ??= require('internal/modules/esm/load').defaultLoad; - - const result = await defaultLoad(url, context); + const result = this.#customizations ? + await this.#customizations.load(url, context) : + await defaultLoad(url, context); this.validateLoadResult(url, result?.format); return result; } + loadSync(url, context) { + defaultLoadSync ??= require('internal/modules/esm/load').defaultLoadSync; + + let result = this.#customizations ? + this.#customizations.loadSync(url, context) : + defaultLoadSync(url, context); + let format = result?.format; + if (format === 'module') { + throw new ERR_REQUIRE_ESM(url, true); + } + if (format === 'commonjs') { + format = 'require-commonjs'; + result = { __proto__: result, format }; + } + this.validateLoadResult(url, format); + return result; + } + validateLoadResult(url, format) { if (format == null) { require('internal/modules/esm/load').throwUnknownModuleFormat(url, format); @@ -273,21 +435,31 @@ class DefaultModuleLoader { } importMetaInitialize(meta, context) { + if (this.#customizations) { + return this.#customizations.importMetaInitialize(meta, context, this); + } importMetaInitializer ??= require('internal/modules/esm/initialize_import_meta').initializeImportMeta; meta = importMetaInitializer(meta, context, this); return meta; } + + /** + * No-op when no hooks have been supplied. + */ + forceLoadHooks() { + this.#customizations?.forceLoadHooks(); + } } -ObjectSetPrototypeOf(DefaultModuleLoader.prototype, null); +ObjectSetPrototypeOf(ModuleLoader.prototype, null); +class CustomizedModuleLoader { + + allowImportMetaResolve = true; -class CustomizedModuleLoader extends DefaultModuleLoader { /** * Instantiate a module loader that uses user-provided custom loader hooks. */ constructor() { - super(); - getHooksProxy(); } @@ -297,10 +469,13 @@ class CustomizedModuleLoader extends DefaultModuleLoader { * be registered. * @param {string} parentURL The parent URL from where the loader will be * registered if using it package name as specifier + * @param {any} [data] Arbitrary data to be passed from the custom loader + * (user-land) to the worker. + * @param {any[]} [transferList] Objects in `data` that are changing ownership * @returns {{ format: string, url: URL['href'] }} */ - register(originalSpecifier, parentURL) { - return hooksProxy.makeSyncRequest('register', originalSpecifier, parentURL); + register(originalSpecifier, parentURL, data, transferList) { + return hooksProxy.makeSyncRequest('register', transferList, originalSpecifier, parentURL, data); } /** @@ -313,28 +488,12 @@ class CustomizedModuleLoader extends DefaultModuleLoader { * @returns {{ format: string, url: URL['href'] }} */ resolve(originalSpecifier, parentURL, importAssertions) { - return hooksProxy.makeSyncRequest('resolve', originalSpecifier, parentURL, importAssertions); + return hooksProxy.makeAsyncRequest('resolve', undefined, originalSpecifier, parentURL, importAssertions); } - async #getModuleJob(specifier, parentURL, importAssertions) { - const resolveResult = await hooksProxy.makeAsyncRequest('resolve', specifier, parentURL, importAssertions); - - return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions); - } - getModuleJob(specifier, parentURL, importAssertions) { - const jobPromise = this.#getModuleJob(specifier, parentURL, importAssertions); - - return { - run() { - return PromisePrototypeThen(jobPromise, (job) => job.run()); - }, - get modulePromise() { - return PromisePrototypeThen(jobPromise, (job) => job.modulePromise); - }, - get linked() { - return PromisePrototypeThen(jobPromise, (job) => job.linked); - }, - }; + resolveSync(originalSpecifier, parentURL, importAssertions) { + // This happens only as a result of `import.meta.resolve` calls, which must be sync per spec. + return hooksProxy.makeSyncRequest('resolve', undefined, originalSpecifier, parentURL, importAssertions); } /** @@ -343,41 +502,65 @@ class CustomizedModuleLoader extends DefaultModuleLoader { * @param {object} [context] Metadata about the module * @returns {Promise<{ format: ModuleFormat, source: ModuleSource }>} */ - async load(url, context) { - const result = await hooksProxy.makeAsyncRequest('load', url, context); - this.validateLoadResult(url, result?.format); + load(url, context) { + return hooksProxy.makeAsyncRequest('load', undefined, url, context); + } + loadSync(url, context) { + return hooksProxy.makeSyncRequest('load', undefined, url, context); + } - return result; + importMetaInitialize(meta, context, loader) { + hooksProxy.importMetaInitialize(meta, context, loader); } -} + forceLoadHooks() { + hooksProxy.waitForWorker(); + } +} -let emittedExperimentalWarning = false; +let emittedLoaderFlagWarning = false; /** * A loader instance is used as the main entry point for loading ES modules. Currently, this is a singleton; there is * only one used for loading the main module and everything in its dependency graph, though separate instances of this * class might be instantiated as part of bootstrap for other purposes. * @param {boolean} useCustomLoadersIfPresent If the user has provided loaders via the --loader flag, use them. - * @returns {DefaultModuleLoader | CustomizedModuleLoader} + * @returns {ModuleLoader} */ function createModuleLoader(useCustomLoadersIfPresent = true) { + let customizations = null; if (useCustomLoadersIfPresent && // Don't spawn a new worker if we're already in a worker thread created by instantiating CustomizedModuleLoader; // doing so would cause an infinite loop. !require('internal/modules/esm/utils').isLoaderWorker()) { const userLoaderPaths = getOptionValue('--experimental-loader'); if (userLoaderPaths.length > 0) { - if (!emittedExperimentalWarning) { - emitExperimentalWarning('Custom ESM Loaders'); - emittedExperimentalWarning = true; + if (!emittedLoaderFlagWarning) { + const readableURIEncode = (string) => ArrayPrototypeReduce( + [ + [/'/g, '%27'], // We need to URL-encode the single quote as it's the delimiter for the --import flag. + [/%22/g, '"'], // We can decode the double quotes to improve readability. + [/%2F/ig, '/'], // We can decode the slashes to improve readability. + ], + (str, { 0: regex, 1: replacement }) => RegExpPrototypeSymbolReplace(hardenRegExp(regex), str, replacement), + encodeURIComponent(string)); + process.emitWarning( + '`--experimental-loader` may be removed in the future; instead use `register()`:\n' + + `--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; ${ArrayPrototypeJoin( + ArrayPrototypeMap(userLoaderPaths, (loader) => `register(${readableURIEncode(JSONStringify(loader))}, pathToFileURL("./"))`), + '; ', + )};'`, + 'ExperimentalWarning', + ); + emittedLoaderFlagWarning = true; } - return new CustomizedModuleLoader(); + customizations = new CustomizedModuleLoader(); } } - return new DefaultModuleLoader(); + return new ModuleLoader(customizations); } + /** * Get the HooksProxy instance. If it is not defined, then create a new one. * @returns {HooksProxy} @@ -393,30 +576,48 @@ function getHooksProxy() { /** * Register a single loader programmatically. - * @param {string} specifier - * @param {string} [parentURL] - * @returns {void} + * @param {string|import('url').URL} specifier + * @param {string|import('url').URL} [parentURL] Base to use when resolving `specifier`; optional if + * `specifier` is absolute. Same as `options.parentUrl`, just inline + * @param {object} [options] Additional options to apply, described below. + * @param {string|import('url').URL} [options.parentURL] Base to use when resolving `specifier` + * @param {any} [options.data] Arbitrary data passed to the loader's `initialize` hook + * @param {any[]} [options.transferList] Objects in `data` that are changing ownership + * @returns {void} We want to reserve the return value for potential future extension of the API. * @example * ```js * register('./myLoader.js'); + * register('ts-node/esm', { parentURL: import.meta.url }); + * register('./myLoader.js', { parentURL: import.meta.url }); * register('ts-node/esm', import.meta.url); * register('./myLoader.js', import.meta.url); * register(new URL('./myLoader.js', import.meta.url)); + * register('./myLoader.js', { + * parentURL: import.meta.url, + * data: { banana: 'tasty' }, + * }); + * register('./myLoader.js', { + * parentURL: import.meta.url, + * data: someArrayBuffer, + * transferList: [someArrayBuffer], + * }); * ``` */ -function register(specifier, parentURL = 'data:') { - // TODO: Remove this limitation in a follow-up before `register` is released publicly - if (getOptionValue('--experimental-loader').length < 1) { - throw new ERR_ESM_LOADER_REGISTRATION_UNAVAILABLE(); - } - +function register(specifier, parentURL = undefined, options) { const moduleLoader = require('internal/process/esm_loader').esmLoader; - - moduleLoader.register(`${specifier}`, parentURL); + if (parentURL != null && typeof parentURL === 'object' && !isURL(parentURL)) { + options = parentURL; + parentURL = options.parentURL; + } + moduleLoader.register( + specifier, + parentURL ?? 'data:', + options?.data, + options?.transferList, + ); } module.exports = { - DefaultModuleLoader, createModuleLoader, getHooksProxy, register, diff --git a/lib/internal/modules/esm/module_job.js b/lib/internal/modules/esm/module_job.js index 2cf2813a6dcf7f..ff284367d0d49e 100644 --- a/lib/internal/modules/esm/module_job.js +++ b/lib/internal/modules/esm/module_job.js @@ -21,7 +21,7 @@ const { const { ModuleWrap } = internalBinding('module_wrap'); -const { decorateErrorStack } = require('internal/util'); +const { decorateErrorStack, kEmptyObject } = require('internal/util'); const { getSourceMapsEnabled, } = require('internal/source_map/source_map_cache'); @@ -51,17 +51,26 @@ class ModuleJob { // `loader` is the Loader instance used for loading dependencies. // `moduleProvider` is a function constructor(loader, url, importAssertions = { __proto__: null }, - moduleProvider, isMain, inspectBrk) { + moduleProvider, isMain, inspectBrk, sync = false) { this.loader = loader; this.importAssertions = importAssertions; this.isMain = isMain; this.inspectBrk = inspectBrk; + this.url = url; + this.module = undefined; // Expose the promise to the ModuleWrap directly for linking below. // `this.module` is also filled in below. this.modulePromise = ReflectApply(moduleProvider, loader, [url, isMain]); + if (sync) { + this.module = this.modulePromise; + this.modulePromise = PromiseResolve(this.module); + } else { + this.modulePromise = PromiseResolve(this.modulePromise); + } + // Wait for the ModuleWrap instance being linked with all dependencies. const link = async () => { this.module = await this.modulePromise; @@ -72,14 +81,15 @@ class ModuleJob { // so that circular dependencies can't cause a deadlock by two of // these `link` callbacks depending on each other. const dependencyJobs = []; - const promises = this.module.link((specifier, assertions) => { - const job = this.loader.getModuleJob(specifier, url, assertions); + const promises = this.module.link(async (specifier, assertions) => { + const job = await this.loader.getModuleJob(specifier, url, assertions); ArrayPrototypePush(dependencyJobs, job); return job.modulePromise; }); - if (promises !== undefined) + if (promises !== undefined) { await SafePromiseAllReturnVoid(promises); + } return SafePromiseAllReturnArrayLike(dependencyJobs); }; @@ -140,7 +150,9 @@ class ModuleJob { /module '(.*)' does not provide an export named '(.+)'/, e.message); const { url: childFileURL } = await this.loader.resolve( - childSpecifier, parentFileUrl, + childSpecifier, + parentFileUrl, + kEmptyObject, ); let format; try { @@ -184,6 +196,20 @@ class ModuleJob { } } + runSync() { + assert(this.module instanceof ModuleWrap); + if (this.instantiated !== undefined) { + return { __proto__: null, module: this.module }; + } + + this.module.instantiate(); + this.instantiated = PromiseResolve(); + const timeout = -1; + const breakOnSigint = false; + this.module.evaluate(timeout, breakOnSigint); + return { __proto__: null, module: this.module }; + } + async run() { await this.instantiate(); const timeout = -1; diff --git a/lib/internal/modules/esm/module_map.js b/lib/internal/modules/esm/module_map.js index ac6d95445ae757..12a1a526178a7e 100644 --- a/lib/internal/modules/esm/module_map.js +++ b/lib/internal/modules/esm/module_map.js @@ -1,17 +1,92 @@ 'use strict'; -const { kImplicitAssertType } = require('internal/modules/esm/assert'); const { + ArrayPrototypeJoin, + ArrayPrototypeMap, + ArrayPrototypeSort, + JSONStringify, + ObjectKeys, SafeMap, } = primordials; +const { kImplicitAssertType } = require('internal/modules/esm/assert'); let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { debug = fn; }); const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; const { validateString } = require('internal/validators'); -// Tracks the state of the loader-level module cache -class ModuleMap extends SafeMap { +/** + * Cache the results of the `resolve` step of the module resolution and loading process. + * Future resolutions of the same input (specifier, parent URL and import assertions) + * must return the same result if the first attempt was successful, per + * https://tc39.es/ecma262/#sec-HostLoadImportedModule. + * This cache is *not* used when custom loaders are registered. + */ +class ResolveCache extends SafeMap { + constructor(i) { super(i); } // eslint-disable-line no-useless-constructor + + /** + * Generates the internal serialized cache key and returns it along the actual cache object. + * + * It is exposed to allow more efficient read and overwrite a cache entry. + * @param {string} specifier + * @param {Record} importAssertions + * @returns {string} + */ + serializeKey(specifier, importAssertions) { + // To serialize the ModuleRequest (specifier + list of import assertions), + // we need to sort the assertions by key, then stringifying, + // so that different import statements with the same assertions are always treated + // as identical. + const keys = ObjectKeys(importAssertions); + + if (keys.length === 0) { + return specifier + '::'; + } + + return specifier + '::' + ArrayPrototypeJoin( + ArrayPrototypeMap( + ArrayPrototypeSort(keys), + (key) => JSONStringify(key) + JSONStringify(importAssertions[key])), + ','); + } + + #getModuleCachedImports(parentURL) { + let internalCache = super.get(parentURL); + if (internalCache == null) { + super.set(parentURL, internalCache = { __proto__: null }); + } + return internalCache; + } + + /** + * @param {string} serializedKey + * @param {string} parentURL + * @returns {import('./loader').ModuleExports | Promise} + */ + get(serializedKey, parentURL) { + return this.#getModuleCachedImports(parentURL)[serializedKey]; + } + + /** + * @param {string} serializedKey + * @param {string} parentURL + * @param {{ format: string, url: URL['href'] }} result + */ + set(serializedKey, parentURL, result) { + this.#getModuleCachedImports(parentURL)[serializedKey] = result; + return this; + } + + has(serializedKey, parentURL) { + return serializedKey in this.#getModuleCachedImports(parentURL); + } +} + +/** + * Cache the results of the `load` step of the module resolution and loading process. + */ +class LoadCache extends SafeMap { constructor(i) { super(i); } // eslint-disable-line no-useless-constructor get(url, type = kImplicitAssertType) { validateString(url, 'url'); @@ -29,7 +104,7 @@ class ModuleMap extends SafeMap { } debug(`Storing ${url} (${ type === kImplicitAssertType ? 'implicit type' : type - }) in ModuleMap`); + }) in ModuleLoadMap`); const cachedJobsForUrl = super.get(url) ?? { __proto__: null }; cachedJobsForUrl[type] = job; return super.set(url, cachedJobsForUrl); @@ -40,4 +115,8 @@ class ModuleMap extends SafeMap { return super.get(url)?.[type] !== undefined; } } -module.exports = ModuleMap; + +module.exports = { + LoadCache, + ResolveCache, +}; diff --git a/lib/internal/modules/esm/package_config.js b/lib/internal/modules/esm/package_config.js index 4ca701d4810f74..5da47764c9de2c 100644 --- a/lib/internal/modules/esm/package_config.js +++ b/lib/internal/modules/esm/package_config.js @@ -7,8 +7,23 @@ const { URL, fileURLToPath } = require('internal/url'); const packageJsonReader = require('internal/modules/package_json_reader'); /** - * @param {URL | string} resolved - * @returns {PackageConfig} + * @typedef {object} PackageConfig + * @property {string} pjsonPath - The path to the package.json file. + * @property {boolean} exists - Whether the package.json file exists. + * @property {'none' | 'commonjs' | 'module'} type - The type of the package. + * @property {string} [name] - The name of the package. + * @property {string} [main] - The main entry point of the package. + * @property {PackageTarget} [exports] - The exports configuration of the package. + * @property {Record>} [imports] - The imports configuration of the package. + */ +/** + * @typedef {string | string[] | Record>} PackageTarget + */ + +/** + * Returns the package configuration for the given resolved URL. + * @param {URL | string} resolved - The resolved URL. + * @returns {PackageConfig} - The package configuration. */ function getPackageScopeConfig(resolved) { let packageJSONUrl = new URL('./package.json', resolved); diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index ce5e4e27fd5128..0d277915b3a01f 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -37,6 +37,7 @@ const experimentalNetworkImports = getOptionValue('--experimental-network-imports'); const typeFlag = getOptionValue('--input-type'); const { URL, pathToFileURL, fileURLToPath, isURL } = require('internal/url'); +const { getCWDURL } = require('internal/util'); const { canParse: URLCanParse } = internalBinding('url'); const { legacyMainResolve: FSLegacyMainResolve } = internalBinding('fs'); const { @@ -66,10 +67,16 @@ const { internalModuleStat } = internalBinding('fs'); const emittedPackageWarnings = new SafeSet(); +/** + * Emits a deprecation warning for the use of a deprecated trailing slash pattern mapping in the "exports" field + * module resolution of a package. + * @param {string} match - The deprecated trailing slash pattern mapping. + * @param {string} pjsonUrl - The URL of the package.json file. + * @param {string} base - The URL of the module that imported the package. + */ function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) { const pjsonPath = fileURLToPath(pjsonUrl); - if (emittedPackageWarnings.has(pjsonPath + '|' + match)) - return; + if (emittedPackageWarnings.has(pjsonPath + '|' + match)) { return; } emittedPackageWarnings.add(pjsonPath + '|' + match); process.emitWarning( `Use of deprecated trailing slash pattern mapping "${match}" in the ` + @@ -83,6 +90,16 @@ function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) { const doubleSlashRegEx = /[/\\][/\\]/; +/** + * Emits a deprecation warning for invalid segment in module resolution. + * @param {string} target - The target module. + * @param {string} request - The requested module. + * @param {string} match - The matched module. + * @param {string} pjsonUrl - The package.json URL. + * @param {boolean} internal - Whether the module is in the "imports" or "exports" field. + * @param {string} base - The base URL. + * @param {boolean} isTarget - Whether the target is a module. + */ function emitInvalidSegmentDeprecation(target, request, match, pjsonUrl, internal, base, isTarget) { const pjsonPath = fileURLToPath(pjsonUrl); const double = RegExpPrototypeExec(doubleSlashRegEx, isTarget ? target : request) !== null; @@ -98,16 +115,16 @@ function emitInvalidSegmentDeprecation(target, request, match, pjsonUrl, interna } /** - * @param {URL} url - * @param {URL} packageJSONUrl - * @param {string | URL | undefined} base - * @param {string} [main] - * @returns {void} + * Emits a deprecation warning if the given URL is a module and + * the package.json file does not define a "main" or "exports" field. + * @param {URL} url - The URL of the module being resolved. + * @param {URL} packageJSONUrl - The URL of the package.json file for the module. + * @param {string | URL} [base] - The base URL for the module being resolved. + * @param {string} [main] - The "main" field from the package.json file. */ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) { const format = defaultGetFormatWithoutErrors(url); - if (format !== 'module') - return; + if (format !== 'module') { return; } const path = fileURLToPath(url); const pkgPath = fileURLToPath(new URL('.', packageJSONUrl)); const basePath = fileURLToPath(base); @@ -197,34 +214,46 @@ function legacyMainResolve(packageJSONUrl, packageConfig, base) { const encodedSepRegEx = /%2F|%5C/i; /** - * @param {URL} resolved - * @param {string | URL | undefined} base - * @param {boolean} preserveSymlinks - * @returns {URL | undefined} + * Finalizes the resolution of a module specifier by checking if the resolved pathname contains encoded "/" or "\\" + * characters, checking if the resolved pathname is a directory or file, and resolving any symlinks if necessary. + * @param {URL} resolved - The resolved URL object. + * @param {string | URL | undefined} base - The base URL object. + * @param {boolean} preserveSymlinks - Whether to preserve symlinks or not. + * @returns {URL} - The finalized URL object. + * @throws {ERR_INVALID_MODULE_SPECIFIER} - If the resolved pathname contains encoded "/" or "\\" characters. + * @throws {ERR_UNSUPPORTED_DIR_IMPORT} - If the resolved pathname is a directory. + * @throws {ERR_MODULE_NOT_FOUND} - If the resolved pathname is not a file. */ function finalizeResolution(resolved, base, preserveSymlinks) { - if (RegExpPrototypeExec(encodedSepRegEx, resolved.pathname) !== null) + if (RegExpPrototypeExec(encodedSepRegEx, resolved.pathname) !== null) { throw new ERR_INVALID_MODULE_SPECIFIER( resolved.pathname, 'must not include encoded "/" or "\\" characters', fileURLToPath(base)); + } - const path = fileURLToPath(resolved); + let path; + try { + path = fileURLToPath(resolved); + } catch (err) { + const { setOwnProperty } = require('internal/util'); + setOwnProperty(err, 'input', `${resolved}`); + setOwnProperty(err, 'module', `${base}`); + throw err; + } const stats = internalModuleStat(toNamespacedPath(StringPrototypeEndsWith(path, '/') ? StringPrototypeSlice(path, -1) : path)); // Check for stats.isDirectory() if (stats === 1) { - const err = new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base)); - err.url = String(resolved); - throw err; + throw new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base), String(resolved)); } else if (stats !== 0) { // Check for !stats.isFile() if (process.env.WATCH_REPORT_DEPENDENCIES && process.send) { process.send({ 'watch:require': [path || resolved.pathname] }); } throw new ERR_MODULE_NOT_FOUND( - path || resolved.pathname, base && fileURLToPath(base), 'module'); + path || resolved.pathname, base && fileURLToPath(base), resolved); } if (!preserveSymlinks) { @@ -242,9 +271,11 @@ function finalizeResolution(resolved, base, preserveSymlinks) { } /** - * @param {string} specifier - * @param {URL} packageJSONUrl - * @param {string | URL | undefined} base + * Returns an error object indicating that the specified import is not defined. + * @param {string} specifier - The import specifier that is not defined. + * @param {URL} packageJSONUrl - The URL of the package.json file, or null if not available. + * @param {string | URL | undefined} base - The base URL to use for resolving relative URLs. + * @returns {ERR_PACKAGE_IMPORT_NOT_DEFINED} - The error object. */ function importNotDefined(specifier, packageJSONUrl, base) { return new ERR_PACKAGE_IMPORT_NOT_DEFINED( @@ -253,9 +284,11 @@ function importNotDefined(specifier, packageJSONUrl, base) { } /** - * @param {string} subpath - * @param {URL} packageJSONUrl - * @param {string | URL | undefined} base + * Returns an error object indicating that the specified subpath was not exported by the package. + * @param {string} subpath - The subpath that was not exported. + * @param {URL} packageJSONUrl - The URL of the package.json file. + * @param {string | URL | undefined} [base] - The base URL to use for resolving the subpath. + * @returns {ERR_PACKAGE_PATH_NOT_EXPORTED} - The error object. */ function exportsNotFound(subpath, packageJSONUrl, base) { return new ERR_PACKAGE_PATH_NOT_EXPORTED( @@ -264,12 +297,13 @@ function exportsNotFound(subpath, packageJSONUrl, base) { } /** - * - * @param {string} request - * @param {string} match - * @param {URL} packageJSONUrl - * @param {boolean} internal - * @param {string | URL | undefined} base + * Throws an error indicating that the given request is not a valid subpath match for the specified pattern. + * @param {string} request - The request that failed to match the pattern. + * @param {string} match - The pattern that the request was compared against. + * @param {URL} packageJSONUrl - The URL of the package.json file being resolved. + * @param {boolean} internal - Whether the resolution is for an "imports" or "exports" field in package.json. + * @param {string | URL | undefined} base - The base URL for the resolution. + * @throws {ERR_INVALID_MODULE_SPECIFIER} When the request is not a valid match for the pattern. */ function throwInvalidSubpath(request, match, packageJSONUrl, internal, base) { const reason = `request is not a valid match in pattern "${match}" for the "${ @@ -279,6 +313,15 @@ function throwInvalidSubpath(request, match, packageJSONUrl, internal, base) { base && fileURLToPath(base)); } +/** + * Creates an error object for an invalid package target. + * @param {string} subpath - The subpath. + * @param {import('internal/modules/esm/package_config.js').PackageTarget} target - The target. + * @param {URL} packageJSONUrl - The URL of the package.json file. + * @param {boolean} internal - Whether the package is internal. + * @param {string | URL | undefined} base - The base URL. + * @returns {ERR_INVALID_PACKAGE_TARGET} - The error object. + */ function invalidPackageTarget( subpath, target, packageJSONUrl, internal, base) { if (typeof target === 'object' && target !== null) { @@ -297,17 +340,19 @@ const invalidPackageNameRegEx = /^\.|%|\\/; const patternRegEx = /\*/g; /** - * - * @param {string} target - * @param {*} subpath - * @param {*} match - * @param {*} packageJSONUrl - * @param {*} base - * @param {*} pattern - * @param {*} internal - * @param {*} isPathMap - * @param {*} conditions - * @returns {URL} + * Resolves the package target string to a URL object. + * @param {string} target - The target string to resolve. + * @param {string} subpath - The subpath to append to the resolved URL. + * @param {RegExpMatchArray} match - The matched string array from the import statement. + * @param {string} packageJSONUrl - The URL of the package.json file. + * @param {string} base - The base URL to resolve the target against. + * @param {RegExp} pattern - The pattern to replace in the target string. + * @param {boolean} internal - Whether the target is internal to the package. + * @param {boolean} isPathMap - Whether the target is a path map. + * @param {string[]} conditions - The import conditions. + * @returns {URL} - The resolved URL object. + * @throws {ERR_INVALID_PACKAGE_TARGET} - If the target is invalid. + * @throws {ERR_INVALID_SUBPATH} - If the subpath is invalid. */ function resolvePackageTargetString( target, @@ -321,8 +366,9 @@ function resolvePackageTargetString( conditions, ) { - if (subpath !== '' && !pattern && target[target.length - 1] !== '/') + if (subpath !== '' && !pattern && target[target.length - 1] !== '/') { throw invalidPackageTarget(match, target, packageJSONUrl, internal, base); + } if (!StringPrototypeStartsWith(target, './')) { if (internal && !StringPrototypeStartsWith(target, '../') && @@ -359,10 +405,11 @@ function resolvePackageTargetString( const resolvedPath = resolved.pathname; const packagePath = new URL('.', packageJSONUrl).pathname; - if (!StringPrototypeStartsWith(resolvedPath, packagePath)) + if (!StringPrototypeStartsWith(resolvedPath, packagePath)) { throw invalidPackageTarget(match, target, packageJSONUrl, internal, base); + } - if (subpath === '') return resolved; + if (subpath === '') { return resolved; } if (RegExpPrototypeExec(invalidSegmentRegEx, subpath) !== null) { const request = pattern ? StringPrototypeReplace(match, '*', () => subpath) : match + subpath; @@ -388,27 +435,28 @@ function resolvePackageTargetString( } /** - * @param {string} key - * @returns {boolean} + * Checks if the given key is a valid array index. + * @param {string} key - The key to check. + * @returns {boolean} - Returns `true` if the key is a valid array index, else `false`. */ function isArrayIndex(key) { const keyNum = +key; - if (`${keyNum}` !== key) return false; + if (`${keyNum}` !== key) { return false; } return keyNum >= 0 && keyNum < 0xFFFF_FFFF; } /** - * - * @param {*} packageJSONUrl - * @param {string|[string]} target - * @param {*} subpath - * @param {*} packageSubpath - * @param {*} base - * @param {*} pattern - * @param {*} internal - * @param {*} isPathMap - * @param {*} conditions - * @returns {URL|null} + * Resolves the target of a package based on the provided parameters. + * @param {string} packageJSONUrl - The URL of the package.json file. + * @param {import('internal/modules/esm/package_config.js').PackageTarget} target - The target to resolve. + * @param {string} subpath - The subpath to resolve. + * @param {string} packageSubpath - The subpath of the package to resolve. + * @param {string} base - The base path to resolve. + * @param {RegExp} pattern - The pattern to match. + * @param {boolean} internal - Whether the package is internal. + * @param {boolean} isPathMap - Whether the package is a path map. + * @param {Set} conditions - The conditions to match. + * @returns {URL | null | undefined} - The resolved target, or null if not found, or undefined if not resolvable. */ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, base, pattern, internal, isPathMap, conditions) { @@ -445,8 +493,9 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, } return resolveResult; } - if (lastException === undefined || lastException === null) + if (lastException === undefined || lastException === null) { return lastException; + } throw lastException; } else if (typeof target === 'object' && target !== null) { const keys = ObjectGetOwnPropertyNames(target); @@ -465,8 +514,7 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, const resolveResult = resolvePackageTarget( packageJSONUrl, conditionalTarget, subpath, packageSubpath, base, pattern, internal, isPathMap, conditions); - if (resolveResult === undefined) - continue; + if (resolveResult === undefined) { continue; } return resolveResult; } } @@ -479,15 +527,14 @@ function resolvePackageTarget(packageJSONUrl, target, subpath, packageSubpath, } /** - * - * @param {import('internal/modules/esm/package_config.js').Exports} exports - * @param {URL} packageJSONUrl - * @param {string | URL | undefined} base - * @returns {boolean} + * Is the given exports object using the shorthand syntax? + * @param {import('internal/modules/esm/package_config.js').PackageConfig['exports']} exports + * @param {URL} packageJSONUrl The URL of the package.json file. + * @param {string | URL | undefined} base The base URL. */ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { - if (typeof exports === 'string' || ArrayIsArray(exports)) return true; - if (typeof exports !== 'object' || exports === null) return false; + if (typeof exports === 'string' || ArrayIsArray(exports)) { return true; } + if (typeof exports !== 'object' || exports === null) { return false; } const keys = ObjectGetOwnPropertyNames(exports); let isConditionalSugar = false; @@ -509,18 +556,20 @@ function isConditionalExportsMainSugar(exports, packageJSONUrl, base) { } /** - * @param {URL} packageJSONUrl - * @param {string} packageSubpath - * @param {PackageConfig} packageConfig - * @param {string | URL | undefined} base - * @param {Set} conditions - * @returns {URL} + * Resolves the exports of a package. + * @param {URL} packageJSONUrl - The URL of the package.json file. + * @param {string} packageSubpath - The subpath of the package to resolve. + * @param {import('internal/modules/esm/package_config.js').PackageConfig} packageConfig - The package metadata. + * @param {string | URL | undefined} base - The base path to resolve from. + * @param {Set} conditions - An array of conditions to match. + * @returns {URL} - The resolved package target. */ function packageExportsResolve( packageJSONUrl, packageSubpath, packageConfig, base, conditions) { let exports = packageConfig.exports; - if (isConditionalExportsMainSugar(exports, packageJSONUrl, base)) + if (isConditionalExportsMainSugar(exports, packageJSONUrl, base)) { exports = { '.': exports }; + } if (ObjectPrototypeHasOwnProperty(exports, packageSubpath) && !StringPrototypeIncludes(packageSubpath, '*') && @@ -553,9 +602,10 @@ function packageExportsResolve( // throwInvalidSubpath(packageSubpath) // // To match "imports" and the spec. - if (StringPrototypeEndsWith(packageSubpath, '/')) + if (StringPrototypeEndsWith(packageSubpath, '/')) { emitTrailingSlashPatternDeprecation(packageSubpath, packageJSONUrl, base); + } const patternTrailer = StringPrototypeSlice(key, patternIndex + 1); if (packageSubpath.length >= key.length && StringPrototypeEndsWith(packageSubpath, patternTrailer) && @@ -591,25 +641,35 @@ function packageExportsResolve( throw exportsNotFound(packageSubpath, packageJSONUrl, base); } +/** + * Compares two strings that may contain a wildcard character ('*') and returns a value indicating their order. + * @param {string} a - The first string to compare. + * @param {string} b - The second string to compare. + * @returns {number} - A negative number if `a` should come before `b`, a positive number if `a` should come after `b`, + * or 0 if they are equal. + */ function patternKeyCompare(a, b) { const aPatternIndex = StringPrototypeIndexOf(a, '*'); const bPatternIndex = StringPrototypeIndexOf(b, '*'); const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1; const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1; - if (baseLenA > baseLenB) return -1; - if (baseLenB > baseLenA) return 1; - if (aPatternIndex === -1) return 1; - if (bPatternIndex === -1) return -1; - if (a.length > b.length) return -1; - if (b.length > a.length) return 1; + if (baseLenA > baseLenB) { return -1; } + if (baseLenB > baseLenA) { return 1; } + if (aPatternIndex === -1) { return 1; } + if (bPatternIndex === -1) { return -1; } + if (a.length > b.length) { return -1; } + if (b.length > a.length) { return 1; } return 0; } /** - * @param {string} name - * @param {string | URL | undefined} base - * @param {Set} conditions - * @returns {URL} + * Resolves the given import name for a package. + * @param {string} name - The name of the import to resolve. + * @param {string | URL | undefined} base - The base URL to resolve the import from. + * @param {Set} conditions - An object containing the import conditions. + * @throws {ERR_INVALID_MODULE_SPECIFIER} If the import name is not valid. + * @throws {ERR_PACKAGE_IMPORT_NOT_DEFINED} If the import name cannot be resolved. + * @returns {URL} The resolved import URL. */ function packageImportsResolve(name, base, conditions) { if (name === '#' || StringPrototypeStartsWith(name, '#/') || @@ -672,8 +732,8 @@ function packageImportsResolve(name, base, conditions) { } /** - * @param {URL} url - * @returns {import('internal/modules/esm/package_config.js').PackageType} + * Returns the package type for a given URL. + * @param {URL} url - The URL to get the package type for. */ function getPackageType(url) { const packageConfig = getPackageScopeConfig(url); @@ -681,9 +741,9 @@ function getPackageType(url) { } /** - * @param {string} specifier - * @param {string | URL | undefined} base - * @returns {{ packageName: string, packageSubpath: string, isScoped: boolean }} + * Parse a package name from a specifier. + * @param {string} specifier - The import specifier. + * @param {string | URL | undefined} base - The parent URL. */ function parsePackageName(specifier, base) { let separatorIndex = StringPrototypeIndexOf(specifier, '/'); @@ -704,8 +764,9 @@ function parsePackageName(specifier, base) { // Package name cannot have leading . and cannot have percent-encoding or // \\ separators. - if (RegExpPrototypeExec(invalidPackageNameRegEx, packageName) !== null) + if (RegExpPrototypeExec(invalidPackageNameRegEx, packageName) !== null) { validPackageName = false; + } if (!validPackageName) { throw new ERR_INVALID_MODULE_SPECIFIER( @@ -719,10 +780,11 @@ function parsePackageName(specifier, base) { } /** - * @param {string} specifier - * @param {string | URL | undefined} base - * @param {Set} conditions - * @returns {resolved: URL, format? : string} + * Resolves a package specifier to a URL. + * @param {string} specifier - The package specifier to resolve. + * @param {string | URL | undefined} base - The base URL to use for resolution. + * @param {Set} conditions - An object containing the conditions for resolution. + * @returns {URL} - The resolved URL. */ function packageResolve(specifier, base, conditions) { if (BuiltinModule.canBeRequiredWithoutScheme(specifier)) { @@ -779,39 +841,47 @@ function packageResolve(specifier, base, conditions) { // eslint can't handle the above code. // eslint-disable-next-line no-unreachable - throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)); + throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null); } /** - * @param {string} specifier - * @returns {boolean} + * Checks if a specifier is a bare specifier. + * @param {string} specifier - The specifier to check. */ function isBareSpecifier(specifier) { return specifier[0] && specifier[0] !== '/' && specifier[0] !== '.'; } +/** + * Determines whether a specifier is a relative path. + * @param {string} specifier - The specifier to check. + */ function isRelativeSpecifier(specifier) { if (specifier[0] === '.') { - if (specifier.length === 1 || specifier[1] === '/') return true; + if (specifier.length === 1 || specifier[1] === '/') { return true; } if (specifier[1] === '.') { - if (specifier.length === 2 || specifier[2] === '/') return true; + if (specifier.length === 2 || specifier[2] === '/') { return true; } } } return false; } +/** + * Determines whether a specifier should be treated as a relative or absolute path. + * @param {string} specifier - The specifier to check. + */ function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { - if (specifier === '') return false; - if (specifier[0] === '/') return true; + if (specifier === '') { return false; } + if (specifier[0] === '/') { return true; } return isRelativeSpecifier(specifier); } /** - * @param {string} specifier - * @param {string | URL | undefined} base - * @param {Set} conditions - * @param {boolean} preserveSymlinks - * @returns {url: URL, format?: string} + * Resolves a module specifier to a URL. + * @param {string} specifier - The module specifier to resolve. + * @param {string | URL | undefined} base - The base URL to resolve against. + * @param {Set} conditions - An object containing environment conditions. + * @param {boolean} preserveSymlinks - Whether to preserve symlinks in the resolved URL. */ function moduleResolve(specifier, base, conditions, preserveSymlinks) { const isRemote = base.protocol === 'http:' || @@ -839,10 +909,9 @@ function moduleResolve(specifier, base, conditions, preserveSymlinks) { } /** - * Try to resolve an import as a CommonJS module - * @param {string} specifier - * @param {string} parentURL - * @returns {boolean|string} + * Try to resolve an import as a CommonJS module. + * @param {string} specifier - The specifier to resolve. + * @param {string} parentURL - The base URL. */ function resolveAsCommonJS(specifier, parentURL) { try { @@ -884,7 +953,14 @@ function resolveAsCommonJS(specifier, parentURL) { } } -// TODO(@JakobJingleheimer): de-dupe `specifier` & `parsed` +/** + * Throw an error if an import is not allowed. + * TODO(@JakobJingleheimer): de-dupe `specifier` & `parsed` + * @param {string} specifier - The import specifier. + * @param {URL} parsed - The parsed URL of the import specifier. + * @param {URL} parsedParentURL - The parsed URL of the parent module. + * @throws {ERR_NETWORK_IMPORT_DISALLOWED} - If the import is disallowed. + */ function checkIfDisallowedImport(specifier, parsed, parsedParentURL) { if (parsedParentURL) { // Avoid accessing the `protocol` property due to the lazy getters. @@ -930,6 +1006,7 @@ function checkIfDisallowedImport(specifier, parsed, parsedParentURL) { /** * Validate user-input in `context` supplied by a custom loader. + * @param {string | URL | undefined} parentURL - The parent URL. */ function throwIfInvalidParentURL(parentURL) { if (parentURL === undefined) { @@ -940,7 +1017,15 @@ function throwIfInvalidParentURL(parentURL) { } } - +/** + * Resolves the given specifier using the provided context, which includes the parent URL and conditions. + * Throws an error if the parent URL is invalid or if the resolution is disallowed by the policy manifest. + * Otherwise, attempts to resolve the specifier and returns the resulting URL and format. + * @param {string} specifier - The specifier to resolve. + * @param {object} [context={}] - The context object containing the parent URL and conditions. + * @param {string} [context.parentURL] - The URL of the parent module. + * @param {string[]} [context.conditions] - The conditions for resolving the specifier. + */ function defaultResolve(specifier, context = {}) { let { parentURL, conditions } = context; throwIfInvalidParentURL(parentURL); @@ -1011,15 +1096,15 @@ function defaultResolve(specifier, context = {}) { parsedParentURL, ); - if (maybeReturn) return maybeReturn; + if (maybeReturn) { return maybeReturn; } // This must come after checkIfDisallowedImport - if (parsed && parsed.protocol === 'node:') return { __proto__: null, url: specifier }; + if (parsed && parsed.protocol === 'node:') { return { __proto__: null, url: specifier }; } const isMain = parentURL === undefined; if (isMain) { - parentURL = pathToFileURL(`${process.cwd()}/`).href; + parentURL = getCWDURL().href; // This is the initial entry point to the program, and --input-type has // been passed as an option; but --input-type can only be used with @@ -1027,7 +1112,7 @@ function defaultResolve(specifier, context = {}) { // input, to avoid user confusion over how expansive the effect of the // flag should be (i.e. entry point only, package scope surrounding the // entry point, etc.). - if (typeFlag) throw new ERR_INPUT_TYPE_NOT_ALLOWED(); + if (typeFlag) { throw new ERR_INPUT_TYPE_NOT_ALLOWED(); } } conditions = getConditionsSet(conditions); diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 267d89f1d44730..bd67593f993e07 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -1,13 +1,13 @@ 'use strict'; const { - ArrayPrototypeForEach, ArrayPrototypeMap, Boolean, JSONParse, ObjectGetPrototypeOf, ObjectPrototypeHasOwnProperty, ObjectKeys, + ReflectApply, SafeArrayIterator, SafeMap, SafeSet, @@ -18,14 +18,19 @@ const { globalThis: { WebAssembly }, } = primordials; +/** @type {import('internal/util/types')} */ let _TYPES = null; +/** + * Lazily loads and returns the internal/util/types module. + */ function lazyTypes() { - if (_TYPES !== null) return _TYPES; + if (_TYPES !== null) { return _TYPES; } return _TYPES = require('internal/util/types'); } +const assert = require('internal/assert'); const { readFileSync } = require('fs'); -const { extname, isAbsolute } = require('path'); +const { dirname, extname, isAbsolute } = require('path'); const { hasEsmSyntax, loadBuiltinModule, @@ -35,11 +40,11 @@ const { Module: CJSModule, cjsParseCache, } = require('internal/modules/cjs/loader'); -const { fileURLToPath, URL } = require('internal/url'); +const { fileURLToPath, pathToFileURL, URL } = require('internal/url'); let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { debug = fn; }); -const { emitExperimentalWarning } = require('internal/util'); +const { emitExperimentalWarning, kEmptyObject, setOwnProperty } = require('internal/util'); const { ERR_UNKNOWN_BUILTIN_MODULE, ERR_INVALID_RETURN_PROPERTY_VALUE, @@ -49,8 +54,15 @@ const moduleWrap = internalBinding('module_wrap'); const { ModuleWrap } = moduleWrap; const asyncESM = require('internal/process/esm_loader'); const { emitWarningSync } = require('internal/process/warning'); +const { internalCompileFunction } = require('internal/vm'); +/** @type {import('deps/cjs-module-lexer/lexer.js').parse} */ let cjsParse; +/** + * Initializes the CommonJS module lexer parser. + * If WebAssembly is available, it uses the optimized version from the dist folder. + * Otherwise, it falls back to the JavaScript version from the lexer folder. + */ async function initCJSParse() { if (typeof WebAssembly === 'undefined') { cjsParse = require('internal/deps/cjs-module-lexer/lexer').parse; @@ -71,6 +83,14 @@ exports.translators = translators; exports.enrichCJSError = enrichCJSError; let DECODER = null; +/** + * Asserts that the given body is a buffer source (either a string, array buffer, or typed array). + * Throws an error if the body is not a buffer source. + * @param {string | ArrayBufferView | ArrayBuffer} body - The body to check. + * @param {boolean} allowString - Whether or not to allow a string as a valid buffer source. + * @param {string} hookName - The name of the hook being called. + * @throws {ERR_INVALID_RETURN_PROPERTY_VALUE} If the body is not a buffer source. + */ function assertBufferSource(body, allowString, hookName) { if (allowString && typeof body === 'string') { return; @@ -87,14 +107,23 @@ function assertBufferSource(body, allowString, hookName) { ); } +/** + * Converts a buffer or buffer-like object to a string. + * @param {string | ArrayBuffer | ArrayBufferView} body - The buffer or buffer-like object to convert to a string. + * @returns {string} The resulting string. + */ function stringify(body) { - if (typeof body === 'string') return body; + if (typeof body === 'string') { return body; } assertBufferSource(body, false, 'transformSource'); const { TextDecoder } = require('internal/encoding'); DECODER = DECODER === null ? new TextDecoder() : DECODER; return DECODER.decode(body); } +/** + * Converts a URL to a file path if the URL protocol is 'file:'. + * @param {string} url - The URL to convert. + */ function errPath(url) { const parsed = new URL(url); if (parsed.protocol === 'file:') { @@ -103,6 +132,14 @@ function errPath(url) { return url; } +/** + * Dynamically imports a module using the ESM loader. + * @param {string} specifier - The module specifier to import. + * @param {object} options - An object containing options for the import. + * @param {string} options.url - The URL of the module requesting the import. + * @param {Record} [assertions] - An object containing assertions for the import. + * @returns {Promise} The imported module. + */ async function importModuleDynamically(specifier, { url }, assertions) { return asyncESM.esmLoader.import(specifier, url, assertions); } @@ -114,8 +151,9 @@ translators.set('module', async function moduleStrategy(url, source, isMain) { maybeCacheSourceMap(url, source); debug(`Translating StandardModule ${url}`); const module = new ModuleWrap(url, undefined, source, 0, 0); - const { setCallbackForWrap } = require('internal/modules/esm/utils'); - setCallbackForWrap(module, { + const { registerModule } = require('internal/modules/esm/utils'); + registerModule(module, { + __proto__: null, initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }), importModuleDynamically, }); @@ -123,6 +161,7 @@ translators.set('module', async function moduleStrategy(url, source, isMain) { }); /** + * Provide a more informative error for CommonJS imports. * @param {Error | any} err * @param {string} [content] Content of the file, if known. * @param {string} [filename] Useful only if `content` is unknown. @@ -140,39 +179,121 @@ function enrichCJSError(err, content, filename) { } } -// Strategy for loading a node-style CommonJS module -const isWindows = process.platform === 'win32'; -translators.set('commonjs', async function commonjsStrategy(url, source, - isMain) { +/** + * Loads a CommonJS module via the ESM Loader sync CommonJS translator. + * This translator creates its own version of the `require` function passed into CommonJS modules. + * Any monkey patches applied to the CommonJS Loader will not affect this module. + * Any `require` calls in this module will load all children in the same way. + * @param {import('internal/modules/cjs/loader').Module} module - The module to load. + * @param {string} source - The source code of the module. + * @param {string} url - The URL of the module. + * @param {string} filename - The filename of the module. + */ +function loadCJSModule(module, source, url, filename) { + let compiledWrapper; + try { + compiledWrapper = internalCompileFunction(source, [ + 'exports', + 'require', + 'module', + '__filename', + '__dirname', + ], { + filename, + importModuleDynamically(specifier, _, importAssertions) { + return asyncESM.esmLoader.import(specifier, url, importAssertions); + }, + }).function; + } catch (err) { + enrichCJSError(err, source, url); + throw err; + } + + const __dirname = dirname(filename); + // eslint-disable-next-line func-name-matching,func-style + const requireFn = function require(specifier) { + let importAssertions = kEmptyObject; + if (!StringPrototypeStartsWith(specifier, 'node:')) { + // TODO: do not depend on the monkey-patchable CJS loader here. + const path = CJSModule._resolveFilename(specifier, module); + if (specifier !== path) { + switch (extname(path)) { + case '.json': + importAssertions = { __proto__: null, type: 'json' }; + break; + case '.node': + return CJSModule._load(specifier, module); + default: + // fall through + } + specifier = `${pathToFileURL(path)}`; + } + } + const job = asyncESM.esmLoader.getModuleJobSync(specifier, url, importAssertions); + job.runSync(); + return cjsCache.get(job.url).exports; + }; + setOwnProperty(requireFn, 'resolve', function resolve(specifier) { + if (!StringPrototypeStartsWith(specifier, 'node:')) { + const path = CJSModule._resolveFilename(specifier, module); + if (specifier !== path) { + specifier = `${pathToFileURL(path)}`; + } + } + const { url: resolvedURL } = asyncESM.esmLoader.resolveSync(specifier, url, kEmptyObject); + return StringPrototypeStartsWith(resolvedURL, 'file://') ? fileURLToPath(resolvedURL) : resolvedURL; + }); + setOwnProperty(requireFn, 'main', process.mainModule); + + ReflectApply(compiledWrapper, module.exports, + [module.exports, requireFn, module, filename, __dirname]); + setOwnProperty(module, 'loaded', true); +} + +// TODO: can we use a weak map instead? +const cjsCache = new SafeMap(); +/** + * Creates a ModuleWrap object for a CommonJS module. + * @param {string} url - The URL of the module. + * @param {string} source - The source code of the module. + * @param {boolean} isMain - Whether the module is the main module. + * @param {typeof loadCJSModule} [loadCJS=loadCJSModule] - The function to load the CommonJS module. + * @returns {ModuleWrap} The ModuleWrap object for the CommonJS module. + */ +function createCJSModuleWrap(url, source, isMain, loadCJS = loadCJSModule) { debug(`Translating CJSModule ${url}`); - const filename = fileURLToPath(new URL(url)); + const filename = StringPrototypeStartsWith(url, 'file://') ? fileURLToPath(url) : url; + source = stringify(source); - if (!cjsParse) await initCJSParse(); - const { module, exportNames } = cjsPreparseModuleExports(filename); + const { exportNames, module } = cjsPreparseModuleExports(filename, source); + cjsCache.set(url, module); const namesWithDefault = exportNames.has('default') ? [...exportNames] : ['default', ...exportNames]; + if (isMain) { + setOwnProperty(process, 'mainModule', module); + } + return new ModuleWrap(url, undefined, namesWithDefault, function() { debug(`Loading CJSModule ${url}`); + if (!module.loaded) { + loadCJS(module, source, url, filename); + } + let exports; if (asyncESM.esmLoader.cjsCache.has(module)) { exports = asyncESM.esmLoader.cjsCache.get(module); asyncESM.esmLoader.cjsCache.delete(module); } else { - try { - exports = CJSModule._load(filename, undefined, isMain); - } catch (err) { - enrichCJSError(err, undefined, filename); - throw err; - } + ({ exports } = module); } - for (const exportName of exportNames) { if (!ObjectPrototypeHasOwnProperty(exports, exportName) || - exportName === 'default') + exportName === 'default') { continue; + } // We might trigger a getter -> dont fail. let value; try { @@ -184,14 +305,61 @@ translators.set('commonjs', async function commonjsStrategy(url, source, } this.setExport('default', exports); }); + +} + +// Handle CommonJS modules referenced by `require` calls. +// This translator function must be sync, as `require` is sync. +translators.set('require-commonjs', (url, source, isMain) => { + assert(cjsParse); + + return createCJSModuleWrap(url, source); +}); + +// Handle CommonJS modules referenced by `import` statements or expressions, +// or as the initial entry point when the ESM loader handles a CommonJS entry. +translators.set('commonjs', async function commonjsStrategy(url, source, + isMain) { + if (!cjsParse) { + await initCJSParse(); + } + + // For backward-compatibility, it's possible to return a nullish value for + // CJS source associated with a file: URL. In this case, the source is + // obtained by calling the monkey-patchable CJS loader. + const cjsLoader = source == null ? (module, source, url, filename) => { + try { + assert(module === CJSModule._cache[filename]); + CJSModule._load(filename); + } catch (err) { + enrichCJSError(err, source, url); + throw err; + } + } : loadCJSModule; + + try { + // We still need to read the FS to detect the exports. + source ??= readFileSync(new URL(url), 'utf8'); + } catch { + // Continue regardless of error. + } + return createCJSModuleWrap(url, source, isMain, cjsLoader); + }); -function cjsPreparseModuleExports(filename) { +/** + * Pre-parses a CommonJS module's exports and re-exports. + * @param {string} filename - The filename of the module. + * @param {string} [source] - The source code of the module. + */ +function cjsPreparseModuleExports(filename, source) { + // TODO: Do we want to keep hitting the user mutable CJS loader here? let module = CJSModule._cache[filename]; if (module) { const cached = cjsParseCache.get(module); - if (cached) + if (cached) { return { module, exportNames: cached.exportNames }; + } } const loaded = Boolean(module); if (!loaded) { @@ -201,13 +369,6 @@ function cjsPreparseModuleExports(filename) { CJSModule._cache[filename] = module; } - let source; - try { - source = readFileSync(filename, 'utf8'); - } catch { - // Continue regardless of error. - } - let exports, reexports; try { ({ exports, reexports } = cjsParse(source || '')); @@ -219,38 +380,54 @@ function cjsPreparseModuleExports(filename) { const exportNames = new SafeSet(new SafeArrayIterator(exports)); // Set first for cycles. - cjsParseCache.set(module, { source, exportNames, loaded }); + cjsParseCache.set(module, { source, exportNames }); if (reexports.length) { module.filename = filename; module.paths = CJSModule._nodeModulePaths(module.path); - } - ArrayPrototypeForEach(reexports, (reexport) => { - let resolved; - try { - resolved = CJSModule._resolveFilename(reexport, module); - } catch { - return; - } - const ext = extname(resolved); - if ((ext === '.js' || ext === '.cjs' || !CJSModule._extensions[ext]) && - isAbsolute(resolved)) { - const { exportNames: reexportNames } = cjsPreparseModuleExports(resolved); - for (const name of reexportNames) - exportNames.add(name); + for (let i = 0; i < reexports.length; i++) { + const reexport = reexports[i]; + let resolved; + try { + // TODO: this should be calling the `resolve` hook chain instead. + // Doing so would mean dropping support for CJS in the loader thread, as + // this call needs to be sync from the perspective of the main thread, + // which we can do via HooksProxy and Atomics, but we can't do within + // the loaders thread. Until this is done, the lexer will use the + // monkey-patchable CJS loader to get the path to the module file to + // load (which may or may not be aligned with the URL that the `resolve` + // hook have returned). + resolved = CJSModule._resolveFilename(reexport, module); + } catch { + continue; + } + // TODO: this should be calling the `load` hook chain and check if it returns + // `format: 'commonjs'` instead of relying on file extensions. + const ext = extname(resolved); + if ((ext === '.js' || ext === '.cjs' || !CJSModule._extensions[ext]) && + isAbsolute(resolved)) { + // TODO: this should be calling the `load` hook chain to get the source + // (and fallback to reading the FS only if the source is nullish). + const source = readFileSync(resolved, 'utf-8'); + const { exportNames: reexportNames } = cjsPreparseModuleExports(resolved, source); + for (const name of reexportNames) { + exportNames.add(name); + } + } } - }); + } return { module, exportNames }; } // Strategy for loading a node builtin CommonJS module that isn't // through normal resolution -translators.set('builtin', async function builtinStrategy(url) { +translators.set('builtin', function builtinStrategy(url) { debug(`Translating BuiltinModule ${url}`); // Slice 'node:' scheme const id = StringPrototypeSlice(url, 5); const module = loadBuiltinModule(id, url); + cjsCache.set(url, module); if (!StringPrototypeStartsWith(url, 'node:') || !module) { throw new ERR_UNKNOWN_BUILTIN_MODULE(url); } @@ -259,7 +436,8 @@ translators.set('builtin', async function builtinStrategy(url) { }); // Strategy for loading a JSON file -translators.set('json', async function jsonStrategy(url, source) { +const isWindows = process.platform === 'win32'; +translators.set('json', function jsonStrategy(url, source) { emitExperimentalWarning('Importing JSON modules'); assertBufferSource(source, true, 'load'); debug(`Loading JSONModule ${url}`); @@ -283,6 +461,7 @@ translators.set('json', async function jsonStrategy(url, source) { // A require call could have been called on the same file during loading and // that resolves synchronously. To make sure we always return the identical // export, we have to check again if the module already exists or not. + // TODO: remove CJS loader from here as well. module = CJSModule._cache[modulePath]; if (module && module.loaded) { const exports = module.exports; @@ -308,6 +487,7 @@ translators.set('json', async function jsonStrategy(url, source) { if (pathname) { CJSModule._cache[modulePath] = module; } + cjsCache.set(url, module); return new ModuleWrap(url, undefined, ['default'], function() { debug(`Parsing JSONModule ${url}`); this.setExport('default', module.exports); @@ -341,7 +521,8 @@ translators.set('wasm', async function(url, source) { 'internal/modules/esm/create_dynamic_module'); return createDynamicModule(imports, exports, url, (reflect) => { const { exports } = new WebAssembly.Instance(compiled, reflect.imports); - for (const expt of ObjectKeys(exports)) + for (const expt of ObjectKeys(exports)) { reflect.exports[expt].set(exports[expt]); + } }).module; }); diff --git a/lib/internal/modules/esm/utils.js b/lib/internal/modules/esm/utils.js index 4e919cd833011c..af4e975566c83a 100644 --- a/lib/internal/modules/esm/utils.js +++ b/lib/internal/modules/esm/utils.js @@ -2,46 +2,55 @@ const { ArrayIsArray, - PromisePrototypeThen, SafeSet, SafeWeakMap, ObjectFreeze, } = primordials; +const { + privateSymbols: { + host_defined_option_symbol, + }, +} = internalBinding('util'); const { ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, ERR_INVALID_ARG_VALUE, } = require('internal/errors').codes; const { getOptionValue } = require('internal/options'); -const { pathToFileURL } = require('internal/url'); -const { kEmptyObject } = require('internal/util'); +const { + loadPreloadModules, + initializeFrozenIntrinsics, +} = require('internal/process/pre_execution'); +const { getCWDURL } = require('internal/util'); const { setImportModuleDynamicallyCallback, setInitializeImportMetaObjectCallback, } = internalBinding('module_wrap'); -const { - getModuleFromWrap, -} = require('internal/vm/module'); const assert = require('internal/assert'); -const callbackMap = new SafeWeakMap(); -function setCallbackForWrap(wrap, data) { - callbackMap.set(wrap, data); -} - let defaultConditions; +/** + * Returns the default conditions for ES module loading. + */ function getDefaultConditions() { assert(defaultConditions !== undefined); return defaultConditions; } +/** @type {Set} */ let defaultConditionsSet; +/** + * Returns the default conditions for ES module loading, as a Set. + */ function getDefaultConditionsSet() { assert(defaultConditionsSet !== undefined); return defaultConditionsSet; } -// This function is called during pre-execution, before any user code is run. +/** + * Initializes the default conditions for ESM module loading. + * This function is called during pre-execution, before any user code is run. + */ function initializeDefaultConditions() { const userConditions = getOptionValue('--conditions'); const noAddons = getOptionValue('--no-addons'); @@ -71,29 +80,98 @@ function getConditionsSet(conditions) { return getDefaultConditionsSet(); } -function initializeImportMetaObject(wrap, meta) { - if (callbackMap.has(wrap)) { - const { initializeImportMeta } = callbackMap.get(wrap); +/** + * @callback ImportModuleDynamicallyCallback + * @param {string} specifier + * @param {ModuleWrap|ContextifyScript|Function|vm.Module} callbackReferrer + * @param {object} assertions + * @returns { Promise } + */ + +/** + * @callback InitializeImportMetaCallback + * @param {object} meta + * @param {ModuleWrap|ContextifyScript|Function|vm.Module} callbackReferrer + */ + +/** + * @typedef {{ + * callbackReferrer: ModuleWrap|ContextifyScript|Function|vm.Module + * initializeImportMeta? : InitializeImportMetaCallback, + * importModuleDynamically? : ImportModuleDynamicallyCallback + * }} ModuleRegistry + */ + +/** + * @type {WeakMap} + */ +const moduleRegistries = new SafeWeakMap(); + +/** + * V8 would make sure that as long as import() can still be initiated from + * the referrer, the symbol referenced by |host_defined_option_symbol| should + * be alive, which in term would keep the settings object alive through the + * WeakMap, and in turn that keeps the referrer object alive, which would be + * passed into the callbacks. + * The reference goes like this: + * [v8::internal::Script] (via host defined options) ----1--> [idSymbol] + * [callbackReferrer] (via host_defined_option_symbol) ------2------^ | + * ^----------3---- (via WeakMap)------ + * 1+3 makes sure that as long as import() can still be initiated, the + * referrer wrap is still around and can be passed into the callbacks. + * 2 is only there so that we can get the id symbol to configure the + * weak map. + * @param {ModuleWrap|ContextifyScript|Function} referrer The referrer to + * get the id symbol from. This is different from callbackReferrer which + * could be set by the caller. + * @param {ModuleRegistry} registry + */ +function registerModule(referrer, registry) { + const idSymbol = referrer[host_defined_option_symbol]; + // To prevent it from being GC'ed. + registry.callbackReferrer ??= referrer; + moduleRegistries.set(idSymbol, registry); +} + +/** + * Defines the `import.meta` object for a given module. + * @param {symbol} symbol - Reference to the module. + * @param {Record} meta - The import.meta object to initialize. + */ +function initializeImportMetaObject(symbol, meta) { + if (moduleRegistries.has(symbol)) { + const { initializeImportMeta, callbackReferrer } = moduleRegistries.get(symbol); if (initializeImportMeta !== undefined) { - meta = initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap); + meta = initializeImportMeta(meta, callbackReferrer); } } } -async function importModuleDynamicallyCallback(wrap, specifier, assertions) { - if (callbackMap.has(wrap)) { - const { importModuleDynamically } = callbackMap.get(wrap); +/** + * Asynchronously imports a module dynamically using a callback function. The native callback. + * @param {symbol} symbol - Reference to the module. + * @param {string} specifier - The module specifier string. + * @param {Record} assertions - The import assertions object. + * @returns {Promise} - The imported module object. + * @throws {ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING} - If the callback function is missing. + */ +async function importModuleDynamicallyCallback(symbol, specifier, assertions) { + if (moduleRegistries.has(symbol)) { + const { importModuleDynamically, callbackReferrer } = moduleRegistries.get(symbol); if (importModuleDynamically !== undefined) { - return importModuleDynamically( - specifier, getModuleFromWrap(wrap) || wrap, assertions); + return importModuleDynamically(specifier, callbackReferrer, assertions); } } throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING(); } -// This is configured during pre-execution. Specifically it's set to true for -// the loader worker in internal/main/worker_thread.js. let _isLoaderWorker = false; +/** + * Initializes handling of ES modules. + * This is configured during pre-execution. Specifically it's set to true for + * the loader worker in internal/main/worker_thread.js. + * @param {boolean} [isLoaderWorker=false] - A boolean indicating whether the loader is a worker or not. + */ function initializeESM(isLoaderWorker = false) { _isLoaderWorker = isLoaderWorker; initializeDefaultConditions(); @@ -103,72 +181,49 @@ function initializeESM(isLoaderWorker = false) { setImportModuleDynamicallyCallback(importModuleDynamicallyCallback); } +/** + * Determine whether the current process is a loader worker. + * @returns {boolean} Whether the current process is a loader worker. + */ function isLoaderWorker() { return _isLoaderWorker; } +/** + * Register module customization hooks. + */ async function initializeHooks() { const customLoaderURLs = getOptionValue('--experimental-loader'); - let cwd; - try { - // `process.cwd()` can fail if the parent directory is deleted while the process runs. - cwd = process.cwd() + '/'; - } catch { - cwd = '/'; - } - - const { Hooks } = require('internal/modules/esm/hooks'); - const hooks = new Hooks(); - - const { DefaultModuleLoader } = require('internal/modules/esm/loader'); - class ModuleLoader extends DefaultModuleLoader { - loaderType = 'internal'; - async #getModuleJob(specifier, parentURL, importAssertions) { - const resolveResult = await hooks.resolve(specifier, parentURL, importAssertions); - return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions); - } - getModuleJob(specifier, parentURL, importAssertions) { - const jobPromise = this.#getModuleJob(specifier, parentURL, importAssertions); - return { - run() { - return PromisePrototypeThen(jobPromise, (job) => job.run()); - }, - get modulePromise() { - return PromisePrototypeThen(jobPromise, (job) => job.modulePromise); - }, - get linked() { - return PromisePrototypeThen(jobPromise, (job) => job.linked); - }, - }; - } - load(url, context) { return hooks.load(url, context); } - } - const privateModuleLoader = new ModuleLoader(); - const parentURL = pathToFileURL(cwd).href; + const esmLoader = require('internal/process/esm_loader').esmLoader; - // TODO(jlenon7): reuse the `Hooks.register()` method for registering loaders. + const hooks = new Hooks(); + esmLoader.setCustomizations(hooks); + + // We need the loader customizations to be set _before_ we start invoking + // `--require`, otherwise loops can happen because a `--require` script + // might call `register(...)` before we've installed ourselves. These + // global values are magically set in `setupUserModules` just for us and + // we call them in the correct order. + // N.B. This block appears here specifically in order to ensure that + // `--require` calls occur before `--loader` ones do. + loadPreloadModules(); + initializeFrozenIntrinsics(); + + const parentURL = getCWDURL().href; for (let i = 0; i < customLoaderURLs.length; i++) { - const customLoaderURL = customLoaderURLs[i]; - - // Importation must be handled by internal loader to avoid polluting user-land - const keyedExports = await privateModuleLoader.import( - customLoaderURL, + await hooks.register( + customLoaderURLs[i], parentURL, - kEmptyObject, ); - - hooks.addCustomLoader(customLoaderURL, keyedExports); } - const preloadScripts = hooks.initializeGlobalPreload(); - - return { __proto__: null, hooks, preloadScripts }; + return hooks; } module.exports = { - setCallbackForWrap, + registerModule, initializeESM, initializeHooks, getDefaultConditions, diff --git a/lib/internal/modules/esm/worker.js b/lib/internal/modules/esm/worker.js index f31820aa8f8d29..433cb9446a2897 100644 --- a/lib/internal/modules/esm/worker.js +++ b/lib/internal/modules/esm/worker.js @@ -32,8 +32,13 @@ const { const { initializeHooks } = require('internal/modules/esm/utils'); const { isMarkedAsUntransferable } = require('internal/buffer'); +/** + * Transfers an ArrayBuffer, TypedArray, or DataView to a worker thread. + * @param {boolean} hasError - Whether an error occurred during transfer. + * @param {ArrayBuffer | TypedArray | DataView} source - The data to transfer. + */ function transferArrayBuffer(hasError, source) { - if (hasError || source == null) return; + if (hasError || source == null) { return; } let arrayBuffer; if (isArrayBuffer(source)) { arrayBuffer = source; @@ -47,6 +52,11 @@ function transferArrayBuffer(hasError, source) { } } +/** + * Wraps a message with a status and body, and serializes the body if necessary. + * @param {string} status - The status of the message. + * @param {unknown} body - The body of the message. + */ function wrapMessage(status, body) { if (status === 'success' || body === null || (typeof body !== 'object' && @@ -73,8 +83,17 @@ function wrapMessage(status, body) { }; } +/** + * Initializes a worker thread for a customized module loader. + * @param {SharedArrayBuffer} lock - The lock used to synchronize communication between the worker and the main thread. + * @param {MessagePort} syncCommPort - The message port used for synchronous communication between the worker and the + * main thread. + * @param {(err: Error, origin?: string) => void} errorHandler - The function to use for uncaught exceptions. + * @returns {Promise} A promise that resolves when the worker thread has been initialized. + */ async function customizedModuleWorker(lock, syncCommPort, errorHandler) { - let hooks, preloadScripts, initializationError; + let hooks; + let initializationError; let hasInitializationError = false; { @@ -91,9 +110,7 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) { try { - const initResult = await initializeHooks(); - hooks = initResult.hooks; - preloadScripts = initResult.preloadScripts; + hooks = await initializeHooks(); } catch (exception) { // If there was an error while parsing and executing a user loader, for example if because a // loader contained a syntax error, then we need to send the error to the main thread so it can @@ -107,7 +124,7 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) { if (hasInitializationError) { syncCommPort.postMessage(wrapMessage('error', initializationError)); } else { - syncCommPort.postMessage(wrapMessage('success', { preloadScripts }), preloadScripts.map(({ port }) => port)); + syncCommPort.postMessage(wrapMessage('success')); } // We're ready, so unlock the main thread. @@ -115,6 +132,9 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) { AtomicsNotify(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION); let immediate; + /** + * Checks for messages on the syncCommPort and handles them asynchronously. + */ function checkForMessages() { immediate = setImmediate(checkForMessages).unref(); // We need to let the event loop tick a few times to give the main thread a chance to send @@ -148,6 +168,13 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) { setImmediate(() => {}); }); + /** + * Handles incoming messages from the main thread or other workers. + * @param {object} options - The options object. + * @param {string} options.method - The name of the hook. + * @param {Array} options.args - The arguments to pass to the method. + * @param {MessagePort} options.port - The message port to use for communication. + */ async function handleMessage({ method, args, port }) { // Each potential exception needs to be caught individually so that the correct error is sent to // the main thread. @@ -206,11 +233,19 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) { } /** + * Initializes a worker thread for a module with customized hooks. * ! Run everything possible within this function so errors get reported. + * @param {{lock: SharedArrayBuffer}} workerData - The lock used to synchronize with the main thread. + * @param {MessagePort} syncCommPort - The communication port used to communicate with the main thread. */ module.exports = function setupModuleWorker(workerData, syncCommPort) { const lock = new Int32Array(workerData.lock); + /** + * Handles errors that occur in the worker thread. + * @param {Error} err - The error that occurred. + * @param {string} [origin='unhandledRejection'] - The origin of the error. + */ function errorHandler(err, origin = 'unhandledRejection') { AtomicsAdd(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 1); AtomicsNotify(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION); diff --git a/lib/internal/modules/helpers.js b/lib/internal/modules/helpers.js index 3cdffe9e49d74c..cc32e95c4eb413 100644 --- a/lib/internal/modules/helpers.js +++ b/lib/internal/modules/helpers.js @@ -14,6 +14,7 @@ const { StringPrototypeStartsWith, } = primordials; const { + ERR_INVALID_ARG_TYPE, ERR_MANIFEST_DEPENDENCY_MISSING, ERR_UNKNOWN_BUILTIN_MODULE, } = require('internal/errors').codes; @@ -36,7 +37,13 @@ let debug = require('internal/util/debuglog').debuglog('module', (fn) => { debug = fn; }); +/** @typedef {import('internal/modules/cjs/loader.js').Module} Module */ + +/** @type {Set} */ let cjsConditions; +/** + * Define the conditions that apply to the CommonJS loader. + */ function initializeCjsConditions() { const userConditions = getOptionValue('--conditions'); const noAddons = getOptionValue('--no-addons'); @@ -50,6 +57,9 @@ function initializeCjsConditions() { ]); } +/** + * Get the conditions that apply to the CommonJS loader. + */ function getCjsConditions() { if (cjsConditions === undefined) { initializeCjsConditions(); @@ -57,24 +67,53 @@ function getCjsConditions() { return cjsConditions; } -function loadBuiltinModule(filename, request) { - if (!BuiltinModule.canBeRequiredByUsers(filename)) { +/** + * Provide one of Node.js' public modules to user code. + * @param {string} id - The identifier/specifier of the builtin module to load + * @param {string} request - The module requiring or importing the builtin module + */ +function loadBuiltinModule(id, request) { + if (!BuiltinModule.canBeRequiredByUsers(id)) { return; } - const mod = BuiltinModule.map.get(filename); + /** @type {import('internal/bootstrap/realm.js').BuiltinModule} */ + const mod = BuiltinModule.map.get(id); debug('load built-in module %s', request); // compileForPublicLoader() throws if canBeRequiredByUsers is false: mod.compileForPublicLoader(); return mod; } -// Invoke with makeRequireFunction(module) where |module| is the Module object -// to use as the context for the require() function. -// Use redirects to set up a mapping from a policy and restrict dependencies +/** @type {Module} */ +let $Module = null; +/** + * Import the Module class on first use. + */ +function lazyModule() { + $Module = $Module || require('internal/modules/cjs/loader').Module; + return $Module; +} + +/** + * Invoke with `makeRequireFunction(module)` where `module` is the `Module` object to use as the context for the + * `require()` function. + * Use redirects to set up a mapping from a policy and restrict dependencies. + */ const urlToFileCache = new SafeMap(); +/** + * Create the module-scoped `require` function to pass into CommonJS modules. + * @param {Module} mod - The module to create the `require` function for. + * @param {ReturnType} redirects + * @typedef {(specifier: string) => unknown} RequireFunction + */ function makeRequireFunction(mod, redirects) { - const Module = mod.constructor; + // lazy due to cycle + const Module = lazyModule(); + if (mod instanceof Module !== true) { + throw new ERR_INVALID_ARG_TYPE('mod', 'Module', mod); + } + /** @type {RequireFunction} */ let require; if (redirects) { const id = mod.filename || mod.id; @@ -120,6 +159,11 @@ function makeRequireFunction(mod, redirects) { }; } + /** + * The `resolve` method that gets attached to module-scope `require`. + * @param {string} request + * @param {Parameters[3]} options + */ function resolve(request, options) { validateString(request, 'request'); return Module._resolveFilename(request, mod, false, options); @@ -127,6 +171,10 @@ function makeRequireFunction(mod, redirects) { require.resolve = resolve; + /** + * The `paths` method that gets attached to module-scope `require`. + * @param {string} request + */ function paths(request) { validateString(request, 'request'); return Module._resolveLookupPaths(request, mod); @@ -148,6 +196,7 @@ function makeRequireFunction(mod, redirects) { * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) * because the buffer-to-string conversion in `fs.readFileSync()` * translates it to FEFF, the UTF-16 BOM. + * @param {string} content */ function stripBOM(content) { if (StringPrototypeCharCodeAt(content) === 0xFEFF) { @@ -156,6 +205,11 @@ function stripBOM(content) { return content; } +/** + * Add built-in modules to a global or REPL scope object. + * @param {Record} object - The object such as `globalThis` to add the built-in modules to. + * @param {string} dummyModuleName - The label representing the set of built-in modules to add. + */ function addBuiltinLibsToObject(object, dummyModuleName) { // Make built-in modules available directly (loaded lazily). const Module = require('internal/modules/cjs/loader').Module; @@ -216,9 +270,8 @@ function addBuiltinLibsToObject(object, dummyModuleName) { } /** - * + * If a referrer is an URL instance or absolute path, convert it into an URL string. * @param {string | URL} referrer - * @returns {string} */ function normalizeReferrerURL(referrer) { if (typeof referrer === 'string' && path.isAbsolute(referrer)) { @@ -227,7 +280,10 @@ function normalizeReferrerURL(referrer) { return new URL(referrer).href; } -// For error messages only - used to check if ESM syntax is in use. +/** + * For error messages only, check if ESM syntax is in use. + * @param {string} code + */ function hasEsmSyntax(code) { debug('Checking for ESM syntax'); const parser = require('internal/deps/acorn/acorn/dist/acorn').Parser; diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js index 0bfe7b11241416..ac1ffef0412b17 100644 --- a/lib/internal/modules/run_main.js +++ b/lib/internal/modules/run_main.js @@ -7,22 +7,30 @@ const { const { getOptionValue } = require('internal/options'); const path = require('path'); +/** + * Get the absolute path to the main entry point. + * @param {string} main Entry point path + */ function resolveMainPath(main) { // Note extension resolution for the main entry point can be deprecated in a // future major. // Module._findPath is monkey-patchable here. const { Module, toRealPath } = require('internal/modules/cjs/loader'); let mainPath = Module._findPath(path.resolve(main), null, true); - if (!mainPath) - return; + if (!mainPath) { return; } const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); - if (!preserveSymlinksMain) + if (!preserveSymlinksMain) { mainPath = toRealPath(mainPath); + } return mainPath; } +/** + * Determine whether the main entry point should be loaded through the ESM Loader. + * @param {string} mainPath Absolute path to the main entry point + */ function shouldUseESMLoader(mainPath) { /** * @type {string[]} userLoaders A list of custom loaders registered by the user @@ -34,18 +42,19 @@ function shouldUseESMLoader(mainPath) { * (or an empty list when none have been registered). */ const userImports = getOptionValue('--import'); - if (userLoaders.length > 0 || userImports.length > 0) - return true; + if (userLoaders.length > 0 || userImports.length > 0) { return true; } const { readPackageScope } = require('internal/modules/cjs/loader'); // Determine the module format of the main - if (mainPath && StringPrototypeEndsWith(mainPath, '.mjs')) - return true; - if (!mainPath || StringPrototypeEndsWith(mainPath, '.cjs')) - return false; + if (mainPath && StringPrototypeEndsWith(mainPath, '.mjs')) { return true; } + if (!mainPath || StringPrototypeEndsWith(mainPath, '.cjs')) { return false; } const pkg = readPackageScope(mainPath); return pkg && pkg.data.type === 'module'; } +/** + * Run the main entry point through the ESM Loader. + * @param {string} mainPath Absolute path to the main entry point + */ function runMainESM(mainPath) { const { loadESM } = require('internal/process/esm_loader'); const { pathToFileURL } = require('internal/url'); @@ -57,6 +66,10 @@ function runMainESM(mainPath) { })); } +/** + * Handle process exit events around the main entry point promise. + * @param {Promise} promise Main entry point promise + */ async function handleMainPromise(promise) { const { handleProcessExit, @@ -69,9 +82,12 @@ async function handleMainPromise(promise) { } } -// For backwards compatibility, we have to run a bunch of -// monkey-patchable code that belongs to the CJS loader (exposed by -// `require('module')`) even when the entry point is ESM. +/** + * Parse the CLI main entry point string and run it. + * For backwards compatibility, we have to run a bunch of monkey-patchable code that belongs to the CJS loader (exposed + * by `require('module')`) even when the entry point is ESM. + * @param {string} main CLI main entry point string + */ function executeUserEntryPoint(main = process.argv[1]) { const resolvedMain = resolveMainPath(main); const useESMLoader = shouldUseESMLoader(resolvedMain); diff --git a/lib/internal/net.js b/lib/internal/net.js index bcbaaa94989e28..8b04d5f226eb17 100644 --- a/lib/internal/net.js +++ b/lib/internal/net.js @@ -11,22 +11,22 @@ const { writeBuffer } = internalBinding('fs'); const errors = require('internal/errors'); // IPv4 Segment -const v4Seg = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; -const v4Str = `(${v4Seg}[.]){3}${v4Seg}`; +const v4Seg = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])'; +const v4Str = `(?:${v4Seg}\\.){3}${v4Seg}`; const IPv4Reg = new RegExp(`^${v4Str}$`); // IPv6 Segment const v6Seg = '(?:[0-9a-fA-F]{1,4})'; -const IPv6Reg = new RegExp('^(' + +const IPv6Reg = new RegExp('^(?:' + `(?:${v6Seg}:){7}(?:${v6Seg}|:)|` + `(?:${v6Seg}:){6}(?:${v4Str}|:${v6Seg}|:)|` + - `(?:${v6Seg}:){5}(?::${v4Str}|(:${v6Seg}){1,2}|:)|` + - `(?:${v6Seg}:){4}(?:(:${v6Seg}){0,1}:${v4Str}|(:${v6Seg}){1,3}|:)|` + - `(?:${v6Seg}:){3}(?:(:${v6Seg}){0,2}:${v4Str}|(:${v6Seg}){1,4}|:)|` + - `(?:${v6Seg}:){2}(?:(:${v6Seg}){0,3}:${v4Str}|(:${v6Seg}){1,5}|:)|` + - `(?:${v6Seg}:){1}(?:(:${v6Seg}){0,4}:${v4Str}|(:${v6Seg}){1,6}|:)|` + - `(?::((?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))` + -')(%[0-9a-zA-Z-.:]{1,})?$'); + `(?:${v6Seg}:){5}(?::${v4Str}|(?::${v6Seg}){1,2}|:)|` + + `(?:${v6Seg}:){4}(?:(?::${v6Seg}){0,1}:${v4Str}|(?::${v6Seg}){1,3}|:)|` + + `(?:${v6Seg}:){3}(?:(?::${v6Seg}){0,2}:${v4Str}|(?::${v6Seg}){1,4}|:)|` + + `(?:${v6Seg}:){2}(?:(?::${v6Seg}){0,3}:${v4Str}|(?::${v6Seg}){1,5}|:)|` + + `(?:${v6Seg}:){1}(?:(?::${v6Seg}){0,4}:${v4Str}|(?::${v6Seg}){1,6}|:)|` + + `(?::(?:(?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))` + +')(?:%[0-9a-zA-Z-.:]{1,})?$'); function isIPv4(s) { // TODO(aduh95): Replace RegExpPrototypeTest with RegExpPrototypeExec when it diff --git a/lib/internal/perf/utils.js b/lib/internal/perf/utils.js index a92e177e4246e9..a0b7955c70481c 100644 --- a/lib/internal/perf/utils.js +++ b/lib/internal/perf/utils.js @@ -1,33 +1,33 @@ 'use strict'; -const binding = internalBinding('performance'); const { + constants: { + NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN, + }, milestones, - getTimeOrigin, -} = binding; +} = internalBinding('performance'); -// TODO(joyeecheung): we may want to warn about access to -// this during snapshot building. -let timeOrigin = getTimeOrigin(); +function getTimeOrigin() { + // Do not cache this to prevent it from being serialized into the + // snapshot. + return milestones[NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN] / 1e6; +} +// Returns the time relative to the process start time in milliseconds. function now() { const hr = process.hrtime(); - return (hr[0] * 1000 + hr[1] / 1e6) - timeOrigin; + return (hr[0] * 1000 + hr[1] / 1e6) - getTimeOrigin(); } +// Returns the milestone relative to the process start time in milliseconds. function getMilestoneTimestamp(milestoneIdx) { const ns = milestones[milestoneIdx]; if (ns === -1) return ns; - return ns / 1e6 - timeOrigin; -} - -function refreshTimeOrigin() { - timeOrigin = getTimeOrigin(); + return ns / 1e6 - getTimeOrigin(); } module.exports = { now, getMilestoneTimestamp, - refreshTimeOrigin, }; diff --git a/lib/internal/process/esm_loader.js b/lib/internal/process/esm_loader.js index 9a84ed944e87c4..a3451ddab307f2 100644 --- a/lib/internal/process/esm_loader.js +++ b/lib/internal/process/esm_loader.js @@ -9,8 +9,7 @@ const { getOptionValue } = require('internal/options'); const { hasUncaughtExceptionCaptureCallback, } = require('internal/process/execution'); -const { pathToFileURL } = require('internal/url'); -const { kEmptyObject } = require('internal/util'); +const { kEmptyObject, getCWDURL } = require('internal/util'); let esmLoader; @@ -23,19 +22,14 @@ module.exports = { try { const userImports = getOptionValue('--import'); if (userImports.length > 0) { - let cwd; - try { - // `process.cwd()` can fail if the parent directory is deleted while the process runs. - cwd = process.cwd() + '/'; - } catch { - cwd = '/'; - } - const parentURL = pathToFileURL(cwd).href; + const parentURL = getCWDURL().href; await SafePromiseAllReturnVoid(userImports, (specifier) => esmLoader.import( specifier, parentURL, kEmptyObject, )); + } else { + esmLoader.forceLoadHooks(); } await callback(esmLoader); } catch (err) { diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index afe2ba2c2c977b..4b77aa47c2cb35 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -54,7 +54,7 @@ function evalModule(source, print) { function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) { const CJSModule = require('internal/modules/cjs/loader').Module; const { kVmBreakFirstLineSymbol } = require('internal/util'); - const { pathToFileURL } = require('url'); + const { pathToFileURL } = require('internal/url'); const cwd = tryGetCwd(); const origModule = globalThis.module; // Set e.g. when called from the REPL. diff --git a/lib/internal/process/policy.js b/lib/internal/process/policy.js index 075c4c9299a428..8e07cb92118c84 100644 --- a/lib/internal/process/policy.js +++ b/lib/internal/process/policy.js @@ -7,6 +7,7 @@ const { } = primordials; const { + ERR_ACCESS_DENIED, ERR_MANIFEST_TDZ, } = require('internal/errors').codes; const { Manifest } = require('internal/policy/manifest'); @@ -32,6 +33,15 @@ module.exports = ObjectFreeze({ return o; }); manifest = new Manifest(json, url); + + // process.binding() is deprecated (DEP0111) and trivially allows bypassing + // policies, so if policies are enabled, make this API unavailable. + process.binding = function binding(_module) { + throw new ERR_ACCESS_DENIED('process.binding'); + }; + process._linkedBinding = function _linkedBinding(_module) { + throw new ERR_ACCESS_DENIED('process._linkedBinding'); + }; }, get manifest() { diff --git a/lib/internal/process/pre_execution.js b/lib/internal/process/pre_execution.js index 54258c572c07f6..1f4a08515b5ae9 100644 --- a/lib/internal/process/pre_execution.js +++ b/lib/internal/process/pre_execution.js @@ -2,15 +2,23 @@ const { ArrayPrototypeForEach, + Date, + DatePrototypeGetDate, + DatePrototypeGetFullYear, + DatePrototypeGetHours, + DatePrototypeGetMinutes, + DatePrototypeGetMonth, + DatePrototypeGetSeconds, NumberParseInt, ObjectDefineProperties, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, SafeMap, + String, StringPrototypeStartsWith, Symbol, - SymbolDispose, SymbolAsyncDispose, + SymbolDispose, globalThis, } = primordials; @@ -33,6 +41,7 @@ const { ERR_MANIFEST_ASSERT_INTEGRITY, ERR_NO_CRYPTO, ERR_MISSING_OPTION, + ERR_ACCESS_DENIED, } = require('internal/errors').codes; const assert = require('internal/assert'); const { @@ -67,7 +76,6 @@ function prepareExecution(options) { // Patch the process object with legacy properties and normalizations patchProcessObject(expandArgv1); setupTraceCategoryState(); - setupPerfHooks(); setupInspectorHooks(); setupWarningHandler(); setupFetch(); @@ -155,6 +163,10 @@ function setupUserModules(isLoaderWorker = false) { initializeESMLoader(isLoaderWorker); const CJSLoader = require('internal/modules/cjs/loader'); assert(!CJSLoader.hasLoadedAnyUserCJSModule); + // Loader workers are responsible for doing this themselves. + if (isLoaderWorker) { + return; + } loadPreloadModules(); // Need to be done after --require setup. initializeFrozenIntrinsics(); @@ -174,7 +186,7 @@ function patchProcessObject(expandArgv1) { __proto__: null, enumerable: true, // Only set it to true during snapshot building. - configurable: getOptionValue('--build-snapshot'), + configurable: isBuildingSnapshot(), value: process.argv[0], }); @@ -396,6 +408,7 @@ function initializeReportSignalHandlers() { function initializeHeapSnapshotSignalHandlers() { const signal = getOptionValue('--heapsnapshot-signal'); + const diagnosticDir = getOptionValue('--diagnostic-dir'); if (!signal) return; @@ -404,7 +417,8 @@ function initializeHeapSnapshotSignalHandlers() { const { writeHeapSnapshot } = require('v8'); function doWriteHeapSnapshot() { - writeHeapSnapshot(); + const heapSnapshotFilename = getHeapSnapshotFilename(diagnosticDir); + writeHeapSnapshot(heapSnapshotFilename); } process.on(signal, doWriteHeapSnapshot); @@ -423,10 +437,6 @@ function setupTraceCategoryState() { toggleTraceCategoryState(isTraceCategoryEnabled('node.async_hooks')); } -function setupPerfHooks() { - require('internal/perf/utils').refreshTimeOrigin(); -} - function setupInspectorHooks() { // If Debugger.setAsyncCallStackDepth is sent during bootstrap, // we cannot immediately call into JS to enable the hooks, which could @@ -537,6 +547,9 @@ function initializeClusterIPC() { function initializePermission() { const experimentalPermission = getOptionValue('--experimental-permission'); if (experimentalPermission) { + process.binding = function binding(_module) { + throw new ERR_ACCESS_DENIED('process.binding'); + }; process.emitWarning('Permission is an experimental feature', 'ExperimentalWarning'); const { has, deny } = require('internal/process/permission'); @@ -551,6 +564,22 @@ function initializePermission() { 'It could invalidate the permission model.', 'SecurityWarning'); } } + const warnCommaFlags = [ + '--allow-fs-read', + '--allow-fs-write', + ]; + for (const flag of warnCommaFlags) { + const value = getOptionValue(flag); + if (value.length === 1 && value[0].includes(',')) { + process.emitWarning( + `The ${flag} CLI flag has changed. ` + + 'Passing a comma-separated list of paths is no longer valid. ' + + 'Documentation can be found at ' + + 'https://nodejs.org/api/permissions.html#file-system-permissions', + 'Warning', + ); + } + } ObjectDefineProperty(process, 'permission', { __proto__: null, @@ -569,7 +598,8 @@ function initializePermission() { '--allow-worker', ]; ArrayPrototypeForEach(availablePermissionFlags, (flag) => { - if (getOptionValue(flag)) { + const value = getOptionValue(flag); + if (value.length) { throw new ERR_MISSING_OPTION('--experimental-permission'); } }); @@ -586,7 +616,7 @@ function readPolicyFromDisk() { // no bare specifiers for now let manifestURL; if (require('path').isAbsolute(experimentalPolicy)) { - manifestURL = new URL(`file://${experimentalPolicy}`); + manifestURL = pathToFileURL(experimentalPolicy); } else { const cwdURL = pathToFileURL(process.cwd()); cwdURL.pathname += '/'; @@ -680,9 +710,36 @@ function markBootstrapComplete() { internalBinding('performance').markBootstrapComplete(); } +// Sequence number for diagnostic filenames +let sequenceNumOfheapSnapshot = 0; + +// To generate the HeapSnapshotFilename while using custom diagnosticDir +function getHeapSnapshotFilename(diagnosticDir) { + if (!diagnosticDir) return undefined; + + const date = new Date(); + + const year = DatePrototypeGetFullYear(date); + const month = String(DatePrototypeGetMonth(date) + 1).padStart(2, '0'); + const day = String(DatePrototypeGetDate(date)).padStart(2, '0'); + const hours = String(DatePrototypeGetHours(date)).padStart(2, '0'); + const minutes = String(DatePrototypeGetMinutes(date)).padStart(2, '0'); + const seconds = String(DatePrototypeGetSeconds(date)).padStart(2, '0'); + + const dateString = `${year}${month}${day}`; + const timeString = `${hours}${minutes}${seconds}`; + const pid = process.pid; + const threadId = internalBinding('worker').threadId; + const fileSequence = (++sequenceNumOfheapSnapshot).toString().padStart(3, '0'); + + return `${diagnosticDir}/Heap.${dateString}.${timeString}.${pid}.${threadId}.${fileSequence}.heapsnapshot`; +} + module.exports = { setupUserModules, prepareMainThreadExecution, prepareWorkerThreadExecution, markBootstrapComplete, + loadPreloadModules, + initializeFrozenIntrinsics, }; diff --git a/lib/internal/readline/utils.js b/lib/internal/readline/utils.js index a546516d76b66c..124a5382a0ddae 100644 --- a/lib/internal/readline/utils.js +++ b/lib/internal/readline/utils.js @@ -148,8 +148,10 @@ function* emitKeys(stream) { * * - `;5` part is optional, e.g. it could be `\x1b[24~` * - first part can contain one or two digits + * - there is also special case when there can be 3 digits + * but without modifier. They are the case of paste bracket mode * - * So the generic regexp is like /^\d\d?(;\d)?[~^$]$/ + * So the generic regexp is like /^(?:\d\d?(;\d)?[~^$]|\d{3}~)$/ * * * 2. `\x1b[1;5H` should be parsed as { code: '[H', modifier: 5 } @@ -170,6 +172,10 @@ function* emitKeys(stream) { if (ch >= '0' && ch <= '9') { s += (ch = yield); + + if (ch >= '0' && ch <= '9') { + s += (ch = yield); + } } } @@ -189,9 +195,13 @@ function* emitKeys(stream) { const cmd = StringPrototypeSlice(s, cmdStart); let match; - if ((match = RegExpPrototypeExec(/^(\d\d?)(;(\d))?([~^$])$/, cmd))) { - code += match[1] + match[4]; - modifier = (match[3] || 1) - 1; + if ((match = RegExpPrototypeExec(/^(?:(\d\d?)(?:;(\d))?([~^$])|(\d{3}~))$/, cmd))) { + if (match[4]) { + code += match[4]; + } else { + code += match[1] + match[3]; + modifier = (match[2] || 1) - 1; + } } else if ( (match = RegExpPrototypeExec(/^((\d;)?(\d))?([A-Za-z])$/, cmd)) ) { @@ -228,6 +238,10 @@ function* emitKeys(stream) { case '[13~': key.name = 'f3'; break; case '[14~': key.name = 'f4'; break; + /* paste bracket mode */ + case '[200~': key.name = 'paste-start'; break; + case '[201~': key.name = 'paste-end'; break; + /* from Cygwin and used in libuv */ case '[[A': key.name = 'f1'; break; case '[[B': key.name = 'f2'; break; diff --git a/lib/internal/streams/lazy_transform.js b/lib/internal/streams/lazy_transform.js index d9d1407a819594..ab5746ce6a4cf8 100644 --- a/lib/internal/streams/lazy_transform.js +++ b/lib/internal/streams/lazy_transform.js @@ -11,10 +11,6 @@ const { const stream = require('stream'); -const { - getDefaultEncoding, -} = require('internal/crypto/util'); - module.exports = LazyTransform; function LazyTransform(options) { @@ -27,11 +23,6 @@ function makeGetter(name) { return function() { stream.Transform.call(this, this._options); this._writableState.decodeStrings = false; - - if (!this._options || !this._options.defaultEncoding) { - this._writableState.defaultEncoding = getDefaultEncoding(); - } - return this[name]; }; } diff --git a/lib/internal/streams/operators.js b/lib/internal/streams/operators.js index 8f4797da5dd519..74c67b028012d4 100644 --- a/lib/internal/streams/operators.js +++ b/lib/internal/streams/operators.js @@ -32,6 +32,7 @@ const { NumberIsNaN, Promise, PromiseReject, + PromiseResolve, PromisePrototypeThen, Symbol, } = primordials; @@ -81,7 +82,15 @@ function map(fn, options) { concurrency = MathFloor(options.concurrency); } - validateInteger(concurrency, 'concurrency', 1); + let highWaterMark = concurrency - 1; + if (options?.highWaterMark != null) { + highWaterMark = MathFloor(options.highWaterMark); + } + + validateInteger(concurrency, 'options.concurrency', 1); + validateInteger(highWaterMark, 'options.highWaterMark', 0); + + highWaterMark += concurrency; return async function* map() { const signal = AbortSignal.any([options?.signal].filter(Boolean)); @@ -92,9 +101,28 @@ function map(fn, options) { let next; let resume; let done = false; + let cnt = 0; - function onDone() { + function onCatch() { done = true; + afterItemProcessed(); + } + + function afterItemProcessed() { + cnt -= 1; + maybeResume(); + } + + function maybeResume() { + if ( + resume && + !done && + cnt < concurrency && + queue.length < highWaterMark + ) { + resume(); + resume = null; + } } async function pump() { @@ -110,17 +138,19 @@ function map(fn, options) { try { val = fn(val, signalOpt); + + if (val === kEmpty) { + continue; + } + + val = PromiseResolve(val); } catch (err) { val = PromiseReject(err); } - if (val === kEmpty) { - continue; - } + cnt += 1; - if (typeof val?.catch === 'function') { - val.catch(onDone); - } + PromisePrototypeThen(val, afterItemProcessed, onCatch); queue.push(val); if (next) { @@ -128,7 +158,7 @@ function map(fn, options) { next = null; } - if (!done && queue.length && queue.length >= concurrency) { + if (!done && (queue.length >= highWaterMark || cnt >= concurrency)) { await new Promise((resolve) => { resume = resolve; }); @@ -137,7 +167,7 @@ function map(fn, options) { queue.push(kEof); } catch (err) { const val = PromiseReject(err); - PromisePrototypeThen(val, undefined, onDone); + PromisePrototypeThen(val, afterItemProcessed, onCatch); queue.push(val); } finally { done = true; @@ -168,10 +198,7 @@ function map(fn, options) { } queue.shift(); - if (resume) { - resume(); - resume = null; - } + maybeResume(); } await new Promise((resolve) => { diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js index 1b40192d9458ba..49df23cba9f4c2 100644 --- a/lib/internal/streams/readable.js +++ b/lib/internal/streams/readable.js @@ -83,6 +83,75 @@ const nop = () => {}; const { errorOrDestroy } = destroyImpl; +const kObjectMode = 1 << 0; +const kEnded = 1 << 1; +const kEndEmitted = 1 << 2; +const kReading = 1 << 3; +const kConstructed = 1 << 4; +const kSync = 1 << 5; +const kNeedReadable = 1 << 6; +const kEmittedReadable = 1 << 7; +const kReadableListening = 1 << 8; +const kResumeScheduled = 1 << 9; +const kErrorEmitted = 1 << 10; +const kEmitClose = 1 << 11; +const kAutoDestroy = 1 << 12; +const kDestroyed = 1 << 13; +const kClosed = 1 << 14; +const kCloseEmitted = 1 << 15; +const kMultiAwaitDrain = 1 << 16; +const kReadingMore = 1 << 17; +const kDataEmitted = 1 << 18; + +// TODO(benjamingr) it is likely slower to do it this way than with free functions +function makeBitMapDescriptor(bit) { + return { + enumerable: false, + get() { return (this.state & bit) !== 0; }, + set(value) { + if (value) this.state |= bit; + else this.state &= ~bit; + }, + }; +} +ObjectDefineProperties(ReadableState.prototype, { + objectMode: makeBitMapDescriptor(kObjectMode), + ended: makeBitMapDescriptor(kEnded), + endEmitted: makeBitMapDescriptor(kEndEmitted), + reading: makeBitMapDescriptor(kReading), + // Stream is still being constructed and cannot be + // destroyed until construction finished or failed. + // Async construction is opt in, therefore we start as + // constructed. + constructed: makeBitMapDescriptor(kConstructed), + // A flag to be able to tell if the event 'readable'/'data' is emitted + // immediately, or on a later tick. We set this to true at first, because + // any actions that shouldn't happen until "later" should generally also + // not happen before the first read call. + sync: makeBitMapDescriptor(kSync), + // Whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + needReadable: makeBitMapDescriptor(kNeedReadable), + emittedReadable: makeBitMapDescriptor(kEmittedReadable), + readableListening: makeBitMapDescriptor(kReadableListening), + resumeScheduled: makeBitMapDescriptor(kResumeScheduled), + // True if the error was already emitted and should not be thrown again. + errorEmitted: makeBitMapDescriptor(kErrorEmitted), + emitClose: makeBitMapDescriptor(kEmitClose), + autoDestroy: makeBitMapDescriptor(kAutoDestroy), + // Has it been destroyed. + destroyed: makeBitMapDescriptor(kDestroyed), + // Indicates whether the stream has finished destroying. + closed: makeBitMapDescriptor(kClosed), + // True if close has been emitted or would have been emitted + // depending on emitClose. + closeEmitted: makeBitMapDescriptor(kCloseEmitted), + multiAwaitDrain: makeBitMapDescriptor(kMultiAwaitDrain), + // If true, a maybeReadMore has been scheduled. + readingMore: makeBitMapDescriptor(kReadingMore), + dataEmitted: makeBitMapDescriptor(kDataEmitted), +}); + function ReadableState(options, stream, isDuplex) { // Duplex streams are both readable and writable, but share // the same options object. @@ -92,13 +161,15 @@ function ReadableState(options, stream, isDuplex) { if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Stream.Duplex; + // Bit map field to store ReadableState more effciently with 1 bit per field + // instead of a V8 slot per field. + this.state = kEmitClose | kAutoDestroy | kConstructed | kSync; // Object stream flag. Used to make read(n) ignore n and to // make all the buffer merging and length checks go away. - this.objectMode = !!(options && options.objectMode); + if (options && options.objectMode) this.state |= kObjectMode; - if (isDuplex) - this.objectMode = this.objectMode || - !!(options && options.readableObjectMode); + if (isDuplex && options && options.readableObjectMode) + this.state |= kObjectMode; // The point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" @@ -113,41 +184,15 @@ function ReadableState(options, stream, isDuplex) { this.length = 0; this.pipes = []; this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // Stream is still being constructed and cannot be - // destroyed until construction finished or failed. - // Async construction is opt in, therefore we start as - // constructed. - this.constructed = true; - // A flag to be able to tell if the event 'readable'/'data' is emitted - // immediately, or on a later tick. We set this to true at first, because - // any actions that shouldn't happen until "later" should generally also - // not happen before the first read call. - this.sync = true; - - // Whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; this[kPaused] = null; - // True if the error was already emitted and should not be thrown again. - this.errorEmitted = false; - // Should close be emitted on destroy. Defaults to true. - this.emitClose = !options || options.emitClose !== false; + if (options && options.emitClose === false) this.state &= ~kEmitClose; // Should .destroy() be called after 'end' (and potentially 'finish'). - this.autoDestroy = !options || options.autoDestroy !== false; + if (options && options.autoDestroy === false) this.state &= ~kAutoDestroy; - // Has it been destroyed. - this.destroyed = false; // Indicates whether the stream has errored. When true no further // _read calls, 'data' or 'readable' events should occur. This is needed @@ -155,12 +200,6 @@ function ReadableState(options, stream, isDuplex) { // stream has failed. this.errored = null; - // Indicates whether the stream has finished destroying. - this.closed = false; - - // True if close has been emitted or would have been emitted - // depending on emitClose. - this.closeEmitted = false; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. @@ -177,12 +216,6 @@ function ReadableState(options, stream, isDuplex) { // Ref the piped dest which we need a drain event on it // type: null | Writable | Set. this.awaitDrainWriters = null; - this.multiAwaitDrain = false; - - // If true, a maybeReadMore has been scheduled. - this.readingMore = false; - - this.dataEmitted = false; this.decoder = null; this.encoding = null; @@ -263,7 +296,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { const state = stream._readableState; let err; - if (!state.objectMode) { + if ((state.state & kObjectMode) === 0) { if (typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; if (state.encoding !== encoding) { @@ -290,11 +323,11 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { if (err) { errorOrDestroy(stream, err); } else if (chunk === null) { - state.reading = false; + state.state &= ~kReading; onEofChunk(stream, state); - } else if (state.objectMode || (chunk && chunk.length > 0)) { + } else if (((state.state & kObjectMode) !== 0) || (chunk && chunk.length > 0)) { if (addToFront) { - if (state.endEmitted) + if ((state.state & kEndEmitted) !== 0) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT()); else if (state.destroyed || state.errored) return false; @@ -305,7 +338,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { } else if (state.destroyed || state.errored) { return false; } else { - state.reading = false; + state.state &= ~kReading; if (state.decoder && !encoding) { chunk = state.decoder.write(chunk); if (state.objectMode || chunk.length !== 0) @@ -317,7 +350,7 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { } } } else if (!addToFront) { - state.reading = false; + state.state &= ~kReading; maybeReadMore(stream, state); } @@ -333,7 +366,7 @@ function addChunk(stream, state, chunk, addToFront) { stream.listenerCount('data') > 0) { // Use the guard to avoid creating `Set()` repeatedly // when we have multiple pipes. - if (state.multiAwaitDrain) { + if ((state.state & kMultiAwaitDrain) !== 0) { state.awaitDrainWriters.clear(); } else { state.awaitDrainWriters = null; @@ -349,7 +382,7 @@ function addChunk(stream, state, chunk, addToFront) { else state.buffer.push(chunk); - if (state.needReadable) + if ((state.state & kNeedReadable) !== 0) emitReadable(stream); } maybeReadMore(stream, state); @@ -404,7 +437,7 @@ function computeNewHighWaterMark(n) { function howMuchToRead(n, state) { if (n <= 0 || (state.length === 0 && state.ended)) return 0; - if (state.objectMode) + if ((state.state & kObjectMode) !== 0) return 1; if (NumberIsNaN(n)) { // Only flow one buffer at a time. @@ -435,7 +468,7 @@ Readable.prototype.read = function(n) { state.highWaterMark = computeNewHighWaterMark(n); if (n !== 0) - state.emittedReadable = false; + state.state &= ~kEmittedReadable; // If we're doing read(0) to trigger a readable event, but we // already have a bunch of data in the buffer, then just trigger @@ -486,7 +519,7 @@ Readable.prototype.read = function(n) { // 3. Actually pull the requested chunks out of the buffer and return. // if we need a readable event, then we need to do some reading. - let doRead = state.needReadable; + let doRead = (state.state & kNeedReadable) !== 0; debug('need readable', doRead); // If we currently have less than the highWaterMark, then also read some. @@ -504,11 +537,10 @@ Readable.prototype.read = function(n) { debug('reading, ended or constructing', doRead); } else if (doRead) { debug('do read'); - state.reading = true; - state.sync = true; + state.state |= kReading | kSync; // If the length is currently zero, then we *need* a readable event. if (state.length === 0) - state.needReadable = true; + state.state |= kNeedReadable; // Call internal read method try { @@ -516,8 +548,8 @@ Readable.prototype.read = function(n) { } catch (err) { errorOrDestroy(this, err); } + state.state &= ~kSync; - state.sync = false; // If _read pushed data synchronously, then `reading` will be false, // and we need to re-evaluate how much data we can return to the user. if (!state.reading) diff --git a/lib/internal/test_runner/coverage.js b/lib/internal/test_runner/coverage.js index a20055fa91b601..7727ab006052ba 100644 --- a/lib/internal/test_runner/coverage.js +++ b/lib/internal/test_runner/coverage.js @@ -13,6 +13,7 @@ const { StringPrototypeIncludes, StringPrototypeLocaleCompare, StringPrototypeStartsWith, + MathMax, } = primordials; const { copyFileSync, @@ -24,7 +25,7 @@ const { const { setupCoverageHooks } = require('internal/util'); const { tmpdir } = require('os'); const { join, resolve } = require('path'); -const { fileURLToPath } = require('url'); +const { fileURLToPath } = require('internal/url'); const kCoverageFileRegex = /^coverage-(\d+)-(\d{13})-(\d+)\.json$/; const kIgnoreRegex = /\/\* node:coverage ignore next (?\d+ )?\*\//; const kLineEndingRegex = /\r?\n$/u; @@ -43,6 +44,7 @@ class CoverageLine { this.startOffset = startOffset; this.endOffset = startOffset + src.length - newlineLength; this.ignore = false; + this.count = 0; this.#covered = true; } @@ -118,6 +120,8 @@ class TestCoverage { let totalFunctions = 0; let branchesCovered = 0; let functionsCovered = 0; + const functionReports = []; + const branchReports = []; const lines = ArrayPrototypeMap(linesWithBreaks, (line, i) => { const startOffset = offset; @@ -159,12 +163,20 @@ class TestCoverage { for (let j = 0; j < functions.length; ++j) { const { isBlockCoverage, ranges } = functions[j]; + let maxCountPerFunction = 0; for (let k = 0; k < ranges.length; ++k) { const range = ranges[k]; + maxCountPerFunction = MathMax(maxCountPerFunction, range.count); mapRangeToLines(range, lines); if (isBlockCoverage) { + ArrayPrototypePush(branchReports, { + __proto__: null, + line: range.lines[0].line, + count: range.count, + }); + if (range.count !== 0 || range.ignoredLines === range.lines.length) { branchesCovered++; @@ -177,6 +189,13 @@ class TestCoverage { if (j > 0 && ranges.length > 0) { const range = ranges[0]; + ArrayPrototypePush(functionReports, { + __proto__: null, + name: functions[j].functionName, + count: maxCountPerFunction, + line: range.lines[0].line, + }); + if (range.count !== 0 || range.ignoredLines === range.lines.length) { functionsCovered++; } @@ -186,15 +205,19 @@ class TestCoverage { } let coveredCnt = 0; - const uncoveredLineNums = []; + const lineReports = []; for (let j = 0; j < lines.length; ++j) { const line = lines[j]; - + if (!line.ignore) { + ArrayPrototypePush(lineReports, { + __proto__: null, + line: line.line, + count: line.count, + }); + } if (line.covered || line.ignore) { coveredCnt++; - } else { - ArrayPrototypePush(uncoveredLineNums, line.line); } } @@ -210,7 +233,9 @@ class TestCoverage { coveredLinePercent: toPercentage(coveredCnt, lines.length), coveredBranchPercent: toPercentage(branchesCovered, totalBranches), coveredFunctionPercent: toPercentage(functionsCovered, totalFunctions), - uncoveredLineNumbers: uncoveredLineNums, + functions: functionReports, + branches: branchReports, + lines: lineReports, }); coverageSummary.totals.totalLineCount += lines.length; @@ -250,7 +275,7 @@ class TestCoverage { let dir; try { - mkdirSync(this.originalCoverageDirectory, { recursive: true }); + mkdirSync(this.originalCoverageDirectory, { __proto__: null, recursive: true }); dir = opendirSync(this.coverageDirectory); for (let entry; (entry = dir.readSync()) !== null;) { @@ -313,13 +338,18 @@ function mapRangeToLines(range, lines) { mid = MathFloor((start + end) / 2); let line = lines[mid]; - if (startOffset >= line.startOffset && startOffset <= line.endOffset) { + if (startOffset >= line?.startOffset && startOffset <= line?.endOffset) { while (endOffset > line?.startOffset) { // If the range is not covered, and the range covers the entire line, // then mark that line as not covered. if (count === 0 && startOffset <= line.startOffset && endOffset >= line.endOffset) { line.covered = false; + line.count = 0; + } + if (count > 0 && startOffset <= line.startOffset && + endOffset >= line.endOffset) { + line.count = count; } ArrayPrototypePush(mappedLines, line); @@ -333,7 +363,7 @@ function mapRangeToLines(range, lines) { } break; - } else if (startOffset >= line.endOffset) { + } else if (startOffset >= line?.endOffset) { start = mid + 1; } else { end = mid - 1; @@ -508,4 +538,4 @@ function doesRangeContainOtherRange(range, otherRange) { range.endOffset >= otherRange.endOffset; } -module.exports = { setupCoverage }; +module.exports = { setupCoverage, TestCoverage }; diff --git a/lib/internal/test_runner/harness.js b/lib/internal/test_runner/harness.js index 246620f6628d88..2f18b0bcf091ac 100644 --- a/lib/internal/test_runner/harness.js +++ b/lib/internal/test_runner/harness.js @@ -5,6 +5,7 @@ const { PromiseResolve, SafeMap, } = primordials; +const { getCallerLocation } = internalBinding('util'); const { createHook, executionAsyncId, @@ -20,12 +21,15 @@ const { kEmptyObject } = require('internal/util'); const { kCancelledByParent, Test, Suite } = require('internal/test_runner/test'); const { parseCommandLine, + reporterScope, setupTestReporters, } = require('internal/test_runner/utils'); const { bigint: hrtime } = process.hrtime; const testResources = new SafeMap(); +testResources.set(reporterScope.asyncId(), reporterScope); + function createTestTree(options = kEmptyObject) { return setup(new Test({ __proto__: null, ...options, name: '' })); } @@ -39,9 +43,14 @@ function createProcessEventHandler(eventName, rootTest) { throw err; } - // Check if this error is coming from a test. If it is, fail the test. const test = testResources.get(executionAsyncId()); + // Check if this error is coming from a reporter. If it is, throw it. + if (test === reporterScope) { + throw err; + } + + // Check if this error is coming from a test. If it is, fail the test. if (!test || test.finished) { // If the test is already finished or the resource that created the error // is not mapped to a Test, report this as a top level diagnostic. @@ -116,6 +125,7 @@ function setup(root) { const globalOptions = parseCommandLine(); const hook = createHook({ + __proto__: null, init(asyncId, type, triggerAsyncId, resource) { if (resource instanceof Test) { testResources.set(asyncId, resource); @@ -140,8 +150,8 @@ function setup(root) { const rejectionHandler = createProcessEventHandler('unhandledRejection', root); const coverage = configureCoverage(root, globalOptions); - const exitHandler = async () => { - await root.run(new ERR_TEST_FAILURE( + const exitHandler = () => { + root.postRun(new ERR_TEST_FAILURE( 'Promise resolution is still pending but the event loop has already resolved', kCancelledByParent)); @@ -150,8 +160,8 @@ function setup(root) { process.removeListener('uncaughtException', exceptionHandler); }; - const terminationHandler = async () => { - await exitHandler(); + const terminationHandler = () => { + exitHandler(); process.exit(); }; @@ -190,8 +200,10 @@ let reportersSetup; function getGlobalRoot() { if (!globalRoot) { globalRoot = createTestTree(); - globalRoot.reporter.once('test:fail', () => { - process.exitCode = kGenericUserError; + globalRoot.reporter.on('test:fail', (data) => { + if (data.todo === undefined || data.todo === false) { + process.exitCode = kGenericUserError; + } }); reportersSetup = setupTestReporters(globalRoot); } @@ -214,9 +226,24 @@ function runInParentContext(Factory) { return PromiseResolve(); } - const test = (name, options, fn) => run(name, options, fn); + const test = (name, options, fn) => { + const overrides = { + __proto__: null, + loc: getCallerLocation(), + }; + + return run(name, options, fn, overrides); + }; ArrayPrototypeForEach(['skip', 'todo', 'only'], (keyword) => { - test[keyword] = (name, options, fn) => run(name, options, fn, { [keyword]: true }); + test[keyword] = (name, options, fn) => { + const overrides = { + __proto__: null, + [keyword]: true, + loc: getCallerLocation(), + }; + + return run(name, options, fn, overrides); + }; }); return test; } @@ -224,7 +251,13 @@ function runInParentContext(Factory) { function hook(hook) { return (fn, options) => { const parent = testResources.get(executionAsyncId()) || getGlobalRoot(); - parent.createHook(hook, fn, options); + parent.createHook(hook, fn, { + __proto__: null, + ...options, + parent, + hookType: hook, + loc: getCallerLocation(), + }); }; } diff --git a/lib/internal/test_runner/mock/mock.js b/lib/internal/test_runner/mock/mock.js index 71363154c88328..838a530ddd4902 100644 --- a/lib/internal/test_runner/mock/mock.js +++ b/lib/internal/test_runner/mock/mock.js @@ -45,19 +45,36 @@ class MockFunctionContext { this.#times = times; } + /** + * Gets an array of recorded calls made to the mock function. + * @returns {Array} An array of recorded calls. + */ get calls() { return ArrayPrototypeSlice(this.#calls, 0); } + /** + * Retrieves the number of times the mock function has been called. + * @returns {number} The call count. + */ callCount() { return this.#calls.length; } + /** + * Sets a new implementation for the mock function. + * @param {Function} implementation - The new implementation for the mock function. + */ mockImplementation(implementation) { validateFunction(implementation, 'implementation'); this.#implementation = implementation; } + /** + * Replaces the implementation of the function only once. + * @param {Function} implementation - The substitute function. + * @param {number} [onCall] - The call index to be replaced. + */ mockImplementationOnce(implementation, onCall) { validateFunction(implementation, 'implementation'); const nextCall = this.#calls.length; @@ -66,6 +83,9 @@ class MockFunctionContext { this.#mocks.set(call, implementation); } + /** + * Restores the original function that was mocked. + */ restore() { const { descriptor, object, original, methodName } = this.#restore; @@ -79,14 +99,25 @@ class MockFunctionContext { } } + /** + * Resets the recorded calls to the mock function + */ resetCalls() { this.#calls = []; } + /** + * Tracks a call made to the mock function. + * @param {object} call - The call details. + */ trackCall(call) { ArrayPrototypePush(this.#calls, call); } + /** + * Gets the next implementation to use for the mock function. + * @returns {Function} The next implementation. + */ nextImpl() { const nextCall = this.#calls.length; const mock = this.#mocks.get(nextCall); @@ -109,11 +140,23 @@ class MockTracker { #mocks = []; #timers; + /** + * Returns the mock timers of this MockTracker instance. + * @returns {MockTimers} The mock timers instance. + */ get timers() { this.#timers ??= new MockTimers(); return this.#timers; } + /** + * Creates a mock function tracker. + * @param {Function} [original] - The original function to be tracked. + * @param {Function} [implementation] - An optional replacement function for the original one. + * @param {object} [options] - Additional tracking options. + * @param {number} [options.times=Infinity] - The maximum number of times the mock function can be called. + * @returns {ProxyConstructor} The mock function tracker. + */ fn( original = function() {}, implementation = original, @@ -133,10 +176,21 @@ class MockTracker { validateObject(options, 'options'); const { times = Infinity } = options; validateTimes(times, 'options.times'); - const ctx = new MockFunctionContext(implementation, { original }, times); + const ctx = new MockFunctionContext(implementation, { __proto__: null, original }, times); return this.#setupMock(ctx, original); } + /** + * Creates a method tracker for a specified object or function. + * @param {(object | Function)} objectOrFunction - The object or function containing the method to be tracked. + * @param {string} methodName - The name of the method to be tracked. + * @param {Function} [implementation] - An optional replacement function for the original method. + * @param {object} [options] - Additional tracking options. + * @param {boolean} [options.getter=false] - Indicates whether this is a getter method. + * @param {boolean} [options.setter=false] - Indicates whether this is a setter method. + * @param {number} [options.times=Infinity] - The maximum number of times the mock method can be called. + * @returns {ProxyConstructor} The mock method tracker. + */ method( objectOrFunction, methodName, @@ -189,7 +243,7 @@ class MockTracker { ); } - const restore = { descriptor, object: objectOrFunction, methodName }; + const restore = { __proto__: null, descriptor, object: objectOrFunction, methodName }; const impl = implementation === kDefaultFunction ? original : implementation; const ctx = new MockFunctionContext(impl, restore, times); @@ -216,6 +270,18 @@ class MockTracker { return mock; } + /** + * Mocks a getter method of an object. + * This is a syntax sugar for the MockTracker.method with options.getter set to true + * @param {object} object - The target object. + * @param {string} methodName - The name of the getter method to be mocked. + * @param {Function} [implementation] - An optional replacement function for the targeted method. + * @param {object} [options] - Additional tracking options. + * @param {boolean} [options.getter=true] - Indicates whether this is a getter method. + * @param {boolean} [options.setter=false] - Indicates whether this is a setter method. + * @param {number} [options.times=Infinity] - The maximum number of times the mock method can be called. + * @returns {ProxyConstructor} The mock method tracker. + */ getter( object, methodName, @@ -238,11 +304,24 @@ class MockTracker { } return this.method(object, methodName, implementation, { + __proto__: null, ...options, getter, }); } + /** + * Mocks a setter method of an object. + * This function is a syntax sugar for MockTracker.method with options.setter set to true. + * @param {object} object - The target object. + * @param {string} methodName - The setter method to be mocked. + * @param {Function} [implementation] - An optional replacement function for the targeted method. + * @param {object} [options] - Additional tracking options. + * @param {boolean} [options.getter=false] - Indicates whether this is a getter method. + * @param {boolean} [options.setter=true] - Indicates whether this is a setter method. + * @param {number} [options.times=Infinity] - The maximum number of times the mock method can be called. + * @returns {ProxyConstructor} The mock method tracker. + */ setter( object, methodName, @@ -265,17 +344,24 @@ class MockTracker { } return this.method(object, methodName, implementation, { + __proto__: null, ...options, setter, }); } + /** + * Resets the mock tracker, restoring all mocks and clearing timers. + */ reset() { this.restoreAll(); this.#timers?.reset(); this.#mocks = []; } + /** + * Restore all mocks created by this MockTracker instance. + */ restoreAll() { for (let i = 0; i < this.#mocks.length; i++) { FunctionPrototypeCall(restore, this.#mocks[i]); @@ -297,6 +383,7 @@ class MockTracker { throw err; } finally { FunctionPrototypeCall(trackCall, ctx, { + __proto__: null, arguments: argList, error, result, @@ -321,6 +408,7 @@ class MockTracker { throw err; } finally { FunctionPrototypeCall(trackCall, ctx, { + __proto__: null, arguments: argList, error, result, diff --git a/lib/internal/test_runner/mock/mock_timers.js b/lib/internal/test_runner/mock/mock_timers.js index 790c48e663b387..1ff6489885fe30 100644 --- a/lib/internal/test_runner/mock/mock_timers.js +++ b/lib/internal/test_runner/mock/mock_timers.js @@ -11,6 +11,8 @@ const { DateNow, FunctionPrototypeApply, FunctionPrototypeBind, + ObjectDefineProperty, + ObjectGetOwnPropertyDescriptor, Promise, SymbolAsyncIterator, SymbolDispose, @@ -45,16 +47,22 @@ function setPosition(node, pos) { } function abortIt(signal) { - return new AbortError(undefined, { cause: signal.reason }); + return new AbortError(undefined, { __proto__: null, cause: signal.reason }); } -const SUPPORTED_TIMERS = ['setTimeout', 'setInterval']; +const SUPPORTED_TIMERS = ['setTimeout', 'setInterval', 'setImmediate']; +const TIMERS_DEFAULT_INTERVAL = { + __proto__: null, + setImmediate: -1, +}; class MockTimers { #realSetTimeout; #realClearTimeout; #realSetInterval; #realClearInterval; + #realSetImmediate; + #realClearImmediate; #realPromisifiedSetTimeout; #realPromisifiedSetInterval; @@ -63,6 +71,9 @@ class MockTimers { #realTimersClearTimeout; #realTimersSetInterval; #realTimersClearInterval; + #realTimersSetImmediate; + #realTimersClearImmediate; + #realPromisifiedSetImmediate; #timersInContext = []; #isEnabled = false; @@ -76,6 +87,16 @@ class MockTimers { #setInterval = FunctionPrototypeBind(this.#createTimer, this, true); #clearInterval = FunctionPrototypeBind(this.#clearTimer, this); + #setImmediate = (callback, ...args) => { + return this.#createTimer( + false, + callback, + TIMERS_DEFAULT_INTERVAL.setImmediate, + ...args, + ); + }; + + #clearImmediate = FunctionPrototypeBind(this.#clearTimer, this); constructor() { emitExperimentalWarning('The MockTimers API'); } @@ -158,7 +179,7 @@ class MockTimers { yield* iterator; } - #setTimeoutPromisified(ms, result, options) { + #promisifyTimer({ timerFn, clearFn, ms, result, options }) { return new Promise((resolve, reject) => { if (options?.signal) { try { @@ -173,12 +194,12 @@ class MockTimers { } const onabort = () => { - this.#clearTimeout(id); + clearFn(id); return reject(abortIt(options.signal)); }; - const id = this.#setTimeout(() => { - return resolve(result || id); + const id = timerFn(() => { + return resolve(result); }, ms); if (options?.signal) { @@ -192,15 +213,35 @@ class MockTimers { }); } + #setImmediatePromisified(result, options) { + return this.#promisifyTimer({ + __proto__: null, + timerFn: FunctionPrototypeBind(this.#setImmediate, this), + clearFn: FunctionPrototypeBind(this.#clearImmediate, this), + ms: TIMERS_DEFAULT_INTERVAL.setImmediate, + result, + options, + }); + } + + #setTimeoutPromisified(ms, result, options) { + return this.#promisifyTimer({ + __proto__: null, + timerFn: FunctionPrototypeBind(this.#setTimeout, this), + clearFn: FunctionPrototypeBind(this.#clearTimeout, this), + ms, + result, + options, + }); + } + #toggleEnableTimers(activate) { const options = { + __proto__: null, toFake: { + __proto__: null, setTimeout: () => { - this.#realSetTimeout = globalThis.setTimeout; - this.#realClearTimeout = globalThis.clearTimeout; - this.#realTimersSetTimeout = nodeTimers.setTimeout; - this.#realTimersClearTimeout = nodeTimers.clearTimeout; - this.#realPromisifiedSetTimeout = nodeTimersPromises.setTimeout; + this.#storeOriginalSetTimeout(); globalThis.setTimeout = this.#setTimeout; globalThis.clearTimeout = this.#clearTimeout; @@ -214,11 +255,7 @@ class MockTimers { ); }, setInterval: () => { - this.#realSetInterval = globalThis.setInterval; - this.#realClearInterval = globalThis.clearInterval; - this.#realTimersSetInterval = nodeTimers.setInterval; - this.#realTimersClearInterval = nodeTimers.clearInterval; - this.#realPromisifiedSetInterval = nodeTimersPromises.setInterval; + this.#storeOriginalSetInterval(); globalThis.setInterval = this.#setInterval; globalThis.clearInterval = this.#clearInterval; @@ -231,25 +268,31 @@ class MockTimers { this, ); }, + setImmediate: () => { + this.#storeOriginalSetImmediate(); + + globalThis.setImmediate = this.#setImmediate; + globalThis.clearImmediate = this.#clearImmediate; + + nodeTimers.setImmediate = this.#setImmediate; + nodeTimers.clearImmediate = this.#clearImmediate; + + nodeTimersPromises.setImmediate = FunctionPrototypeBind( + this.#setImmediatePromisified, + this, + ); + }, }, toReal: { + __proto__: null, setTimeout: () => { - globalThis.setTimeout = this.#realSetTimeout; - globalThis.clearTimeout = this.#realClearTimeout; - - nodeTimers.setTimeout = this.#realTimersSetTimeout; - nodeTimers.clearTimeout = this.#realTimersClearTimeout; - - nodeTimersPromises.setTimeout = this.#realPromisifiedSetTimeout; + this.#restoreOriginalSetTimeout(); }, setInterval: () => { - globalThis.setInterval = this.#realSetInterval; - globalThis.clearInterval = this.#realClearInterval; - - nodeTimers.setInterval = this.#realTimersSetInterval; - nodeTimers.clearInterval = this.#realTimersClearInterval; - - nodeTimersPromises.setInterval = this.#realPromisifiedSetInterval; + this.#restoreOriginalSetInterval(); + }, + setImmediate: () => { + this.#restoreSetImmediate(); }, }, }; @@ -259,6 +302,166 @@ class MockTimers { this.#isEnabled = activate; } + #restoreSetImmediate() { + ObjectDefineProperty( + globalThis, + 'setImmediate', + this.#realSetImmediate, + ); + ObjectDefineProperty( + globalThis, + 'clearImmediate', + this.#realClearImmediate, + ); + ObjectDefineProperty( + nodeTimers, + 'setImmediate', + this.#realTimersSetImmediate, + ); + ObjectDefineProperty( + nodeTimers, + 'clearImmediate', + this.#realTimersClearImmediate, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setImmediate', + this.#realPromisifiedSetImmediate, + ); + } + + #restoreOriginalSetInterval() { + ObjectDefineProperty( + globalThis, + 'setInterval', + this.#realSetInterval, + ); + ObjectDefineProperty( + globalThis, + 'clearInterval', + this.#realClearInterval, + ); + ObjectDefineProperty( + nodeTimers, + 'setInterval', + this.#realTimersSetInterval, + ); + ObjectDefineProperty( + nodeTimers, + 'clearInterval', + this.#realTimersClearInterval, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setInterval', + this.#realPromisifiedSetInterval, + ); + } + + #restoreOriginalSetTimeout() { + ObjectDefineProperty( + globalThis, + 'setTimeout', + this.#realSetTimeout, + ); + ObjectDefineProperty( + globalThis, + 'clearTimeout', + this.#realClearTimeout, + ); + ObjectDefineProperty( + nodeTimers, + 'setTimeout', + this.#realTimersSetTimeout, + ); + ObjectDefineProperty( + nodeTimers, + 'clearTimeout', + this.#realTimersClearTimeout, + ); + ObjectDefineProperty( + nodeTimersPromises, + 'setTimeout', + this.#realPromisifiedSetTimeout, + ); + } + + #storeOriginalSetImmediate() { + this.#realSetImmediate = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setImmediate', + ); + this.#realClearImmediate = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearImmediate', + ); + this.#realTimersSetImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setImmediate', + ); + this.#realTimersClearImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearImmediate', + ); + this.#realPromisifiedSetImmediate = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setImmediate', + ); + } + + #storeOriginalSetInterval() { + this.#realSetInterval = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setInterval', + ); + this.#realClearInterval = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearInterval', + ); + this.#realTimersSetInterval = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setInterval', + ); + this.#realTimersClearInterval = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearInterval', + ); + this.#realPromisifiedSetInterval = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setInterval', + ); + } + + #storeOriginalSetTimeout() { + this.#realSetTimeout = ObjectGetOwnPropertyDescriptor( + globalThis, + 'setTimeout', + ); + this.#realClearTimeout = ObjectGetOwnPropertyDescriptor( + globalThis, + 'clearTimeout', + ); + this.#realTimersSetTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'setTimeout', + ); + this.#realTimersClearTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimers, + 'clearTimeout', + ); + this.#realPromisifiedSetTimeout = ObjectGetOwnPropertyDescriptor( + nodeTimersPromises, + 'setTimeout', + ); + } + + /** + * Advances the virtual time of MockTimers by the specified duration (in milliseconds). + * This method simulates the passage of time and triggers any scheduled timers that are due. + * @param {number} [time=1] - The amount of time (in milliseconds) to advance the virtual time. + * @throws {ERR_INVALID_STATE} If MockTimers are not enabled. + * @throws {ERR_INVALID_ARG_VALUE} If a negative time value is provided. + */ tick(time = 1) { if (!this.#isEnabled) { throw new ERR_INVALID_STATE( @@ -292,6 +495,12 @@ class MockTimers { } } + /** + * Enables MockTimers for the specified timers. + * @param {string[]} timers - An array of timer types to enable, e.g., ['setTimeout', 'setInterval']. + * @throws {ERR_INVALID_STATE} If MockTimers are already enabled. + * @throws {ERR_INVALID_ARG_VALUE} If an unsupported timer type is specified. + */ enable(timers = SUPPORTED_TIMERS) { if (this.#isEnabled) { throw new ERR_INVALID_STATE( @@ -317,10 +526,17 @@ class MockTimers { this.#toggleEnableTimers(true); } + /** + * An alias for `this.reset()`, allowing the disposal of the `MockTimers` instance. + */ [SymbolDispose]() { this.reset(); } + /** + * Resets MockTimers, disabling any enabled timers and clearing the execution queue. + * Does nothing if MockTimers are not enabled. + */ reset() { // Ignore if not enabled if (!this.#isEnabled) return; @@ -335,6 +551,10 @@ class MockTimers { } } + /** + * Runs all scheduled timers until there are no more pending timers. + * @throws {ERR_INVALID_STATE} If MockTimers are not enabled. + */ runAll() { if (!this.#isEnabled) { throw new ERR_INVALID_STATE( diff --git a/lib/internal/test_runner/reporter/junit.js b/lib/internal/test_runner/reporter/junit.js new file mode 100644 index 00000000000000..b45c233861c000 --- /dev/null +++ b/lib/internal/test_runner/reporter/junit.js @@ -0,0 +1,158 @@ +'use strict'; +const { + ArrayPrototypeFilter, + ArrayPrototypeMap, + ArrayPrototypeJoin, + ArrayPrototypePush, + ArrayPrototypeSome, + NumberPrototypeToFixed, + ObjectEntries, + RegExpPrototypeSymbolReplace, + String, + StringPrototypeRepeat, +} = primordials; + +const { inspectWithNoCustomRetry } = require('internal/errors'); +const { hostname } = require('os'); + +const inspectOptions = { __proto__: null, colors: false, breakLength: Infinity }; +const HOSTNAME = hostname(); + +function escapeAttribute(s = '') { + return escapeContent(RegExpPrototypeSymbolReplace(/"/g, RegExpPrototypeSymbolReplace(/\n/g, s, ''), '"')); +} + +function escapeContent(s = '') { + return RegExpPrototypeSymbolReplace(/\n`; + } + const attrsString = ArrayPrototypeJoin(ArrayPrototypeMap(ObjectEntries(attrs) + , ({ 0: key, 1: value }) => `${key}="${escapeAttribute(String(value))}"`) + , ' '); + if (!children?.length) { + return `${indent}<${tag} ${attrsString}/>\n`; + } + const childrenString = ArrayPrototypeJoin(ArrayPrototypeMap(children ?? [], treeToXML), ''); + return `${indent}<${tag} ${attrsString}>\n${childrenString}${indent}\n`; +} + +function isFailure(node) { + return (node?.children && ArrayPrototypeSome(node.children, (c) => c.tag === 'failure')) || node?.attrs?.failures; +} + +function isSkipped(node) { + return (node?.children && ArrayPrototypeSome(node.children, (c) => c.tag === 'skipped')) || node?.attrs?.failures; +} + +module.exports = async function* junitReporter(source) { + yield '\n'; + yield '\n'; + let currentSuite = null; + const roots = []; + + function startTest(event) { + const originalSuite = currentSuite; + currentSuite = { + __proto__: null, + attrs: { __proto__: null, name: event.data.name }, + nesting: event.data.nesting, + parent: currentSuite, + children: [], + }; + if (originalSuite?.children) { + ArrayPrototypePush(originalSuite.children, currentSuite); + } + if (!currentSuite.parent) { + ArrayPrototypePush(roots, currentSuite); + } + } + + for await (const event of source) { + switch (event.type) { + case 'test:start': { + startTest(event); + break; + } + case 'test:pass': + case 'test:fail': { + if (!currentSuite) { + startTest({ __proto__: null, data: { __proto__: null, name: 'root', nesting: 0 } }); + } + if (currentSuite.attrs.name !== event.data.name || + currentSuite.nesting !== event.data.nesting) { + startTest(event); + } + const currentTest = currentSuite; + if (currentSuite?.nesting === event.data.nesting) { + currentSuite = currentSuite.parent; + } + currentTest.attrs.time = NumberPrototypeToFixed(event.data.details.duration_ms / 1000, 6); + const nonCommentChildren = ArrayPrototypeFilter(currentTest.children, (c) => c.comment == null); + if (nonCommentChildren.length > 0) { + currentTest.tag = 'testsuite'; + currentTest.attrs.disabled = 0; + currentTest.attrs.errors = 0; + currentTest.attrs.tests = nonCommentChildren.length; + currentTest.attrs.failures = ArrayPrototypeFilter(currentTest.children, isFailure).length; + currentTest.attrs.skipped = ArrayPrototypeFilter(currentTest.children, isSkipped).length; + currentTest.attrs.hostname = HOSTNAME; + } else { + currentTest.tag = 'testcase'; + currentTest.attrs.classname = event.data.classname ?? 'test'; + if (event.data.skip) { + ArrayPrototypePush(currentTest.children, { + __proto__: null, nesting: event.data.nesting + 1, tag: 'skipped', + attrs: { __proto__: null, type: 'skipped', message: event.data.skip }, + }); + } + if (event.data.todo) { + ArrayPrototypePush(currentTest.children, { + __proto__: null, nesting: event.data.nesting + 1, tag: 'skipped', + attrs: { __proto__: null, type: 'todo', message: event.data.todo }, + }); + } + if (event.type === 'test:fail') { + const error = event.data.details?.error; + currentTest.children.push({ + __proto__: null, + nesting: event.data.nesting + 1, + tag: 'failure', + attrs: { __proto__: null, type: error?.failureType || error?.code, message: error?.message ?? '' }, + children: [inspectWithNoCustomRetry(error, inspectOptions)], + }); + currentTest.failures = 1; + currentTest.attrs.failure = error?.message ?? ''; + } + } + break; + } + case 'test:diagnostic': { + const parent = currentSuite?.children ?? roots; + ArrayPrototypePush(parent, { + __proto__: null, nesting: event.data.nesting, comment: event.data.message, + }); + break; + } default: + break; + } + } + for (const suite of roots) { + yield treeToXML(suite); + } + yield '\n'; +}; diff --git a/lib/internal/test_runner/reporter/spec.js b/lib/internal/test_runner/reporter/spec.js index 16cbdf1d5aa901..0c5a3e95c7c75a 100644 --- a/lib/internal/test_runner/reporter/spec.js +++ b/lib/internal/test_runner/reporter/spec.js @@ -17,6 +17,7 @@ const { inspectWithNoCustomRetry } = require('internal/errors'); const { green, blue, red, white, gray, shouldColorize } = require('internal/util/colors'); const { kSubtestsFailed } = require('internal/test_runner/test'); const { getCoverageReport } = require('internal/test_runner/utils'); +const { relative } = require('path'); const inspectOptions = { __proto__: null, colors: shouldColorize(process.stdout), breakLength: Infinity }; @@ -40,9 +41,10 @@ class SpecReporter extends Transform { #reported = []; #indentMemo = new SafeMap(); #failedTests = []; + #cwd = process.cwd(); constructor() { - super({ writableObjectMode: true }); + super({ __proto__: null, writableObjectMode: true }); } #indent(nesting) { @@ -64,17 +66,24 @@ class SpecReporter extends Transform { ), `\n${indent} `); return `\n${indent} ${message}\n`; } - #formatTestReport(type, data, prefix = '', indent = '', hasChildren = false, skippedSubtest = false) { + #formatTestReport(type, data, prefix = '', indent = '', hasChildren = false) { let color = colors[type] ?? white; let symbol = symbols[type] ?? ' '; + const { skip, todo } = data; const duration_ms = data.details?.duration_ms ? ` ${gray}(${data.details.duration_ms}ms)${white}` : ''; - const title = `${data.name}${duration_ms}${skippedSubtest ? ' # SKIP' : ''}`; + let title = `${data.name}${duration_ms}`; + + if (skip !== undefined) { + title += ` # ${typeof skip === 'string' && skip.length ? skip : 'SKIP'}`; + } else if (todo !== undefined) { + title += ` # ${typeof todo === 'string' && todo.length ? todo : 'TODO'}`; + } if (hasChildren) { // If this test has had children - it was already reported, so slightly modify the output return `${prefix}${indent}${color}${symbols['arrow:right']}${white}${title}\n`; } const error = this.#formatError(data.details?.error, indent); - if (skippedSubtest) { + if (skip !== undefined) { color = gray; symbol = symbols['hyphen:minus']; } @@ -101,9 +110,8 @@ class SpecReporter extends Transform { ArrayPrototypeShift(this.#reported); hasChildren = true; } - const skippedSubtest = subtest && data.skip && data.skip !== undefined; const indent = this.#indent(data.nesting); - return `${this.#formatTestReport(type, data, prefix, indent, hasChildren, skippedSubtest)}\n`; + return `${this.#formatTestReport(type, data, prefix, indent, hasChildren)}\n`; } #handleEvent({ type, data }) { switch (type) { @@ -127,7 +135,7 @@ class SpecReporter extends Transform { } } _transform({ type, data }, encoding, callback) { - callback(null, this.#handleEvent({ type, data })); + callback(null, this.#handleEvent({ __proto__: null, type, data })); } _flush(callback) { if (this.#failedTests.length === 0) { @@ -136,10 +144,12 @@ class SpecReporter extends Transform { } const results = [`\n${colors['test:fail']}${symbols['test:fail']}failing tests:${white}\n`]; for (let i = 0; i < this.#failedTests.length; i++) { - ArrayPrototypePush(results, this.#formatTestReport( - 'test:fail', - this.#failedTests[i], - )); + const test = this.#failedTests[i]; + const relPath = relative(this.#cwd, test.file); + const formattedErr = this.#formatTestReport('test:fail', test); + const location = `test at ${relPath}:${test.line}:${test.column}`; + + ArrayPrototypePush(results, location, formattedErr); } callback(null, ArrayPrototypeJoin(results, '\n')); } diff --git a/lib/internal/test_runner/reporter/tap.js b/lib/internal/test_runner/reporter/tap.js index 4aec4ba072d954..1f60cfa619886e 100644 --- a/lib/internal/test_runner/reporter/tap.js +++ b/lib/internal/test_runner/reporter/tap.js @@ -18,7 +18,7 @@ const kDefaultIndent = ' '; // 4 spaces const kFrameStartRegExp = /^ {4}at /; const kLineBreakRegExp = /\n|\r\n/; const kDefaultTAPVersion = 13; -const inspectOptions = { colors: false, breakLength: Infinity }; +const inspectOptions = { __proto__: null, colors: false, breakLength: Infinity }; let testModule; // Lazy loaded due to circular dependency. function lazyLoadTest() { @@ -31,13 +31,14 @@ async function * tapReporter(source) { yield `TAP version ${kDefaultTAPVersion}\n`; for await (const { type, data } of source) { switch (type) { - case 'test:fail': + case 'test:fail': { yield reportTest(data.nesting, data.testNumber, 'not ok', data.name, data.skip, data.todo); - yield reportDetails(data.nesting, data.details); + const location = `${data.file}:${data.line}:${data.column}`; + yield reportDetails(data.nesting, data.details, location); break; - case 'test:pass': + } case 'test:pass': yield reportTest(data.nesting, data.testNumber, 'ok', data.name, data.skip, data.todo); - yield reportDetails(data.nesting, data.details); + yield reportDetails(data.nesting, data.details, null); break; case 'test:plan': yield `${indent(data.nesting)}1..${data.count}\n`; @@ -81,13 +82,18 @@ function reportTest(nesting, testNumber, status, name, skip, todo) { return line; } -function reportDetails(nesting, data = kEmptyObject) { +function reportDetails(nesting, data = kEmptyObject, location) { const { error, duration_ms } = data; const _indent = indent(nesting); let details = `${_indent} ---\n`; details += jsToYaml(_indent, 'duration_ms', duration_ms); details += jsToYaml(_indent, 'type', data.type); + + if (location) { + details += jsToYaml(_indent, 'location', location); + } + details += jsToYaml(_indent, null, error, new SafeSet()); details += `${_indent} ...\n`; return details; @@ -171,7 +177,7 @@ function jsToYaml(indent, name, value, seen) { } if (isErrorObj) { - const { kTestCodeFailure, kUnwrapErrors } = lazyLoadTest(); + const { kUnwrapErrors } = lazyLoadTest(); const { cause, code, @@ -198,15 +204,14 @@ function jsToYaml(indent, name, value, seen) { errStack = cause?.stack ?? errStack; errCode = cause?.code ?? errCode; errName = cause?.name ?? errName; + errMsg = cause?.message ?? errMsg; + if (isAssertionLike(cause)) { errExpected = cause.expected; errActual = cause.actual; errOperator = cause.operator ?? errOperator; errIsAssertion = true; } - if (failureType === kTestCodeFailure) { - errMsg = cause?.message ?? errMsg; - } } result += jsToYaml(indent, 'error', errMsg, seen); diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index 87f76b68501248..08f9b48dda10d3 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -110,14 +110,17 @@ function filterExecArgv(arg, i, arr) { !ArrayPrototypeSome(kFilterArgValues, (p) => arg === p || (i > 0 && arr[i - 1] === p) || StringPrototypeStartsWith(arg, `${p}=`)); } -function getRunArgs({ path, inspectPort, testNamePatterns }) { +function getRunArgs(path, { inspectPort, testNamePatterns, only }) { const argv = ArrayPrototypeFilter(process.execArgv, filterExecArgv); if (isUsingInspector()) { ArrayPrototypePush(argv, `--inspect-port=${getInspectPort(inspectPort)}`); } - if (testNamePatterns) { + if (testNamePatterns != null) { ArrayPrototypeForEach(testNamePatterns, (pattern) => ArrayPrototypePush(argv, `--test-name-pattern=${pattern}`)); } + if (only === true) { + ArrayPrototypePush(argv, '--test-only'); + } ArrayPrototypePush(argv, path); return argv; @@ -301,21 +304,21 @@ class FileTest extends Test { } } -function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) { +function runTestFile(path, filesWatcher, opts) { const watchMode = filesWatcher != null; - const subtest = root.createSubtest(FileTest, path, async (t) => { - const args = getRunArgs({ path, inspectPort, testNamePatterns }); + const subtest = opts.root.createSubtest(FileTest, path, async (t) => { + const args = getRunArgs(path, opts); const stdio = ['pipe', 'pipe', 'pipe']; - const env = { ...process.env, NODE_TEST_CONTEXT: 'child-v8' }; + const env = { __proto__: null, ...process.env, NODE_TEST_CONTEXT: 'child-v8' }; if (watchMode) { stdio.push('ipc'); env.WATCH_REPORT_DEPENDENCIES = '1'; } - if (root.harness.shouldColorizeTestFiles) { + if (opts.root.harness.shouldColorizeTestFiles) { env.FORCE_COLOR = '1'; } - const child = spawn(process.execPath, args, { signal: t.signal, encoding: 'utf8', env, stdio }); + const child = spawn(process.execPath, args, { __proto__: null, signal: t.signal, encoding: 'utf8', env, stdio }); if (watchMode) { filesWatcher.runningProcesses.set(path, child); filesWatcher.watcher.watchChildProcessModules(child, path); @@ -332,7 +335,7 @@ function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) { subtest.parseMessage(data); }); - const rl = createInterface({ input: child.stderr }); + const rl = createInterface({ __proto__: null, input: child.stderr }); rl.on('line', (line) => { if (isInspectorMessage(line)) { process.stderr.write(line + '\n'); @@ -350,15 +353,15 @@ function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) { }); const { 0: { 0: code, 1: signal } } = await SafePromiseAll([ - once(child, 'exit', { signal: t.signal }), - finished(child.stdout, { signal: t.signal }), + once(child, 'exit', { __proto__: null, signal: t.signal }), + finished(child.stdout, { __proto__: null, signal: t.signal }), ]); if (watchMode) { filesWatcher.runningProcesses.delete(path); filesWatcher.runningSubtests.delete(path); if (filesWatcher.runningSubtests.size === 0) { - root.reporter[kEmitMessage]('test:watch:drained'); + opts.root.reporter[kEmitMessage]('test:watch:drained'); } } @@ -381,10 +384,10 @@ function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) { return subtest.start(); } -function watchFiles(testFiles, root, inspectPort, signal, testNamePatterns) { +function watchFiles(testFiles, opts) { const runningProcesses = new SafeMap(); const runningSubtests = new SafeMap(); - const watcher = new FilesWatcher({ throttle: 500, mode: 'filter', signal }); + const watcher = new FilesWatcher({ __proto__: null, debounce: 200, mode: 'filter', signal: opts.signal }); const filesWatcher = { __proto__: null, watcher, runningProcesses, runningSubtests }; watcher.on('changed', ({ owners }) => { @@ -400,19 +403,19 @@ function watchFiles(testFiles, root, inspectPort, signal, testNamePatterns) { } if (!runningSubtests.size) { // Reset the topLevel counter - root.harness.counters.topLevel = 0; + opts.root.harness.counters.topLevel = 0; } await runningSubtests.get(file); - runningSubtests.set(file, runTestFile(file, root, inspectPort, filesWatcher, testNamePatterns)); + runningSubtests.set(file, runTestFile(file, filesWatcher, opts)); }, undefined, (error) => { triggerUncaughtException(error, true /* fromPromise */); })); }); - if (signal) { + if (opts.signal) { kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation; - signal.addEventListener( + opts.signal.addEventListener( 'abort', - () => root.postRun(), + () => opts.root.postRun(), { __proto__: null, once: true, [kResistStopPropagation]: true }, ); } @@ -425,7 +428,7 @@ function run(options) { options = kEmptyObject; } let { testNamePatterns, shard } = options; - const { concurrency, timeout, signal, files, inspectPort, watch, setup } = options; + const { concurrency, timeout, signal, files, inspectPort, watch, setup, only } = options; if (files != null) { validateArray(files, 'options.files'); @@ -433,6 +436,9 @@ function run(options) { if (watch != null) { validateBoolean(watch, 'options.watch'); } + if (only != null) { + validateBoolean(only, 'options.only'); + } if (shard != null) { validateObject(shard, 'options.shard'); // Avoid re-evaluating the shard object in case it's a getter @@ -469,7 +475,7 @@ function run(options) { }); } - const root = createTestTree({ concurrency, timeout, signal }); + const root = createTestTree({ __proto__: null, concurrency, timeout, signal }); let testFiles = files ?? createTestFileList(); if (shard) { @@ -478,14 +484,15 @@ function run(options) { let postRun = () => root.postRun(); let filesWatcher; + const opts = { __proto__: null, root, signal, inspectPort, testNamePatterns, only }; if (watch) { - filesWatcher = watchFiles(testFiles, root, inspectPort, signal, testNamePatterns); + filesWatcher = watchFiles(testFiles, opts); postRun = undefined; } const runFiles = () => { root.harness.bootstrapComplete = true; return SafePromiseAllSettledReturnVoid(testFiles, (path) => { - const subtest = runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns); + const subtest = runTestFile(path, filesWatcher, opts); filesWatcher?.runningSubtests.set(path, subtest); return subtest; }); diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index f5cc0fb98f6271..4afb93f4a60df0 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -13,16 +13,20 @@ const { ObjectSeal, PromisePrototypeThen, PromiseResolve, + SafePromisePrototypeFinally, ReflectApply, RegExpPrototypeExec, SafeMap, SafeSet, SafePromiseAll, SafePromiseRace, + SymbolDispose, + ObjectDefineProperty, Symbol, } = primordials; +const { getCallerLocation } = internalBinding('util'); +const { addAbortListener } = require('events'); const { AsyncResource } = require('async_hooks'); -const { once } = require('events'); const { AbortController } = require('internal/abort_controller'); const { codes: { @@ -51,7 +55,7 @@ const { validateOneOf, validateUint32, } = require('internal/validators'); -const { setTimeout } = require('timers/promises'); +const { setTimeout } = require('timers'); const { TIMEOUT_MAX } = require('internal/timers'); const { availableParallelism } = require('os'); const { bigint: hrtime } = process.hrtime; @@ -75,15 +79,42 @@ const { testNamePatterns, testOnlyFlag } = parseCommandLine(); let kResistStopPropagation; function stopTest(timeout, signal) { + const deferred = createDeferredPromise(); + const abortListener = addAbortListener(signal, deferred.resolve); + let timer; + let disposeFunction; + if (timeout === kDefaultTimeout) { - return once(signal, 'abort'); + disposeFunction = abortListener[SymbolDispose]; + } if (timeout !== kDefaultTimeout) { + timer = setTimeout(() => deferred.resolve(), timeout); + timer.unref(); + + ObjectDefineProperty(deferred, 'promise', { + __proto__: null, + configurable: true, + writable: true, + value: PromisePrototypeThen(deferred.promise, () => { + throw new ERR_TEST_FAILURE( + `test timed out after ${timeout}ms`, + kTestTimeoutFailure, + ); + }), + }); + + disposeFunction = () => { + abortListener[SymbolDispose](); + timer[SymbolDispose](); + }; } - return PromisePrototypeThen(setTimeout(timeout, null, { ref: false, signal }), () => { - throw new ERR_TEST_FAILURE( - `test timed out after ${timeout}ms`, - kTestTimeoutFailure, - ); + + ObjectDefineProperty(deferred.promise, SymbolDispose, { + __proto__: null, + configurable: true, + writable: true, + value: disposeFunction, }); + return deferred.promise; } class TestContext { @@ -123,8 +154,15 @@ class TestContext { } test(name, options, fn) { - // eslint-disable-next-line no-use-before-define - const subtest = this.#test.createSubtest(Test, name, options, fn); + const overrides = { + __proto__: null, + loc: getCallerLocation(), + }; + + const subtest = this.#test.createSubtest( + // eslint-disable-next-line no-use-before-define + Test, name, options, fn, overrides, + ); return subtest.start(); } @@ -163,15 +201,15 @@ class SuiteContext { } class Test extends AsyncResource { - #abortController; - #outerSignal; + abortController; + outerSignal; #reportedSubtest; constructor(options) { super('Test'); let { fn, name, parent, skip } = options; - const { concurrency, only, timeout, todo, signal } = options; + const { concurrency, loc, only, timeout, todo, signal } = options; if (typeof fn !== 'function') { fn = noop; @@ -262,16 +300,16 @@ class Test extends AsyncResource { fn = noop; } - this.#abortController = new AbortController(); - this.#outerSignal = signal; - this.signal = this.#abortController.signal; + this.abortController = new AbortController(); + this.outerSignal = signal; + this.signal = this.abortController.signal; validateAbortSignal(signal, 'options.signal'); if (signal) { kResistStopPropagation ??= require('internal/event_target').kResistStopPropagation; } - this.#outerSignal?.addEventListener( + this.outerSignal?.addEventListener( 'abort', this.#abortHandler, { __proto__: null, [kResistStopPropagation]: true }, @@ -281,8 +319,8 @@ class Test extends AsyncResource { this.harness = null; // Configured on the root test by the test harness. this.mock = null; this.cancelled = false; - this.skipped = !!skip; - this.isTodo = !!todo; + this.skipped = skip !== undefined && skip !== false; + this.isTodo = todo !== undefined && todo !== false; this.startTime = null; this.endTime = null; this.passed = false; @@ -302,6 +340,17 @@ class Test extends AsyncResource { "'only' and 'runOnly' require the --test-only command-line option."; this.diagnostic(warning); } + + if (loc === undefined || kFilename === undefined) { + this.loc = undefined; + } else { + this.loc = { + __proto__: null, + line: loc[0], + column: loc[1], + file: loc[2], + }; + } } matchesTestNamePatterns() { @@ -321,7 +370,7 @@ class Test extends AsyncResource { while (this.pendingSubtests.length > 0 && this.hasConcurrency()) { const deferred = ArrayPrototypeShift(this.pendingSubtests); const test = deferred.test; - this.reporter.dequeue(test.nesting, kFilename, test.name); + this.reporter.dequeue(test.nesting, test.loc, test.name); await test.run(); deferred.resolve(); } @@ -411,7 +460,7 @@ class Test extends AsyncResource { } #abortHandler = () => { - const error = this.#outerSignal?.reason || new AbortError('The test was aborted'); + const error = this.outerSignal?.reason || new AbortError('The test was aborted'); error.failureType = kAborted; this.#cancel(error); }; @@ -429,7 +478,7 @@ class Test extends AsyncResource { ); this.startTime = this.startTime || this.endTime; // If a test was canceled before it was started, e.g inside a hook this.cancelled = true; - this.#abortController.abort(); + this.abortController.abort(); } createHook(name, fn, options) { @@ -480,7 +529,7 @@ class Test extends AsyncResource { // If there is enough available concurrency to run the test now, then do // it. Otherwise, return a Promise to the caller and mark the test as // pending for later execution. - this.reporter.enqueue(this.nesting, kFilename, this.name); + this.reporter.enqueue(this.nesting, this.loc, this.name); if (!this.parent.hasConcurrency()) { const deferred = createDeferredPromise(); @@ -489,7 +538,7 @@ class Test extends AsyncResource { return deferred.promise; } - this.reporter.dequeue(this.nesting, kFilename, this.name); + this.reporter.dequeue(this.nesting, this.loc, this.name); return this.run(); } @@ -497,7 +546,7 @@ class Test extends AsyncResource { if (this.signal.aborted) { return true; } - if (this.#outerSignal?.aborted) { + if (this.outerSignal?.aborted) { this.#abortHandler(); return true; } @@ -505,7 +554,7 @@ class Test extends AsyncResource { getRunArgs() { const ctx = new TestContext(this); - return { ctx, args: [ctx] }; + return { __proto__: null, ctx, args: [ctx] }; } async runHook(hook, args) { @@ -525,7 +574,7 @@ class Test extends AsyncResource { } } - async run(pendingSubtestsError) { + async run() { if (this.parent !== null) { this.parent.activeSubtests++; } @@ -539,23 +588,25 @@ class Test extends AsyncResource { const { args, ctx } = this.getRunArgs(); const after = async () => { if (this.hooks.after.length > 0) { - await this.runHook('after', { args, ctx }); + await this.runHook('after', { __proto__: null, args, ctx }); } }; const afterEach = runOnce(async () => { if (this.parent?.hooks.afterEach.length > 0) { - await this.parent.runHook('afterEach', { args, ctx }); + await this.parent.runHook('afterEach', { __proto__: null, args, ctx }); } }); + let stopPromise; + try { if (this.parent?.hooks.before.length > 0) { await this.parent.runHook('before', this.parent.getRunArgs()); } if (this.parent?.hooks.beforeEach.length > 0) { - await this.parent.runHook('beforeEach', { args, ctx }); + await this.parent.runHook('beforeEach', { __proto__: null, args, ctx }); } - const stopPromise = stopTest(this.timeout, this.signal); + stopPromise = stopTest(this.timeout, this.signal); const runArgs = ArrayPrototypeSlice(args); ArrayPrototypeUnshift(runArgs, this.fn, ctx); @@ -601,11 +652,26 @@ class Test extends AsyncResource { } else { this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure)); } + } finally { + stopPromise?.[SymbolDispose](); + + // Do not abort hooks and the root test as hooks instance are shared between tests suite so aborting them will + // cause them to not run for further tests. + if (this.parent !== null) { + this.abortController.abort(); + } } - // Clean up the test. Then, try to report the results and execute any - // tests that were pending due to available concurrency. - this.postRun(pendingSubtestsError); + if (this.parent !== null || typeof this.hookType === 'string') { + // Clean up the test. Then, try to report the results and execute any + // tests that were pending due to available concurrency. + // + // The root test is skipped here because it is a special case. Its + // postRun() method is called when the process is getting ready to exit. + // This helps catch any asynchronous activity that occurs after the tests + // have finished executing. + this.postRun(); + } } postRun(pendingSubtestsError) { @@ -627,7 +693,7 @@ class Test extends AsyncResource { subtest.#cancel(pendingSubtestsError); subtest.postRun(pendingSubtestsError); } - if (!subtest.passed) { + if (!subtest.passed && !subtest.isTodo) { failed++; } } @@ -639,7 +705,7 @@ class Test extends AsyncResource { this.fail(new ERR_TEST_FAILURE(msg, kSubtestsFailed)); } - this.#outerSignal?.removeEventListener('abort', this.#abortHandler); + this.outerSignal?.removeEventListener('abort', this.#abortHandler); this.mock?.reset(); if (this.parent !== null) { @@ -647,30 +713,50 @@ class Test extends AsyncResource { this.parent.addReadySubtest(this); this.parent.processReadySubtestRange(false); this.parent.processPendingSubtests(); + + if (this.parent === this.root && + this.root.activeSubtests === 0 && + this.root.pendingSubtests.length === 0 && + this.root.readySubtests.size === 0 && + this.root.hooks.after.length > 0) { + // This is done so that any global after() hooks are run. At this point + // all of the tests have finished running. However, there might be + // ref'ed handles keeping the event loop alive. This gives the global + // after() hook a chance to clean them up. + this.root.run(); + } } else if (!this.reported) { + const { + diagnostics, + harness, + loc, + nesting, + reporter, + } = this; + this.reported = true; - this.reporter.plan(this.nesting, kFilename, this.root.harness.counters.topLevel); + reporter.plan(nesting, loc, harness.counters.topLevel); - for (let i = 0; i < this.diagnostics.length; i++) { - this.reporter.diagnostic(this.nesting, kFilename, this.diagnostics[i]); + // Call this harness.coverage() before collecting diagnostics, since failure to collect coverage is a diagnostic. + const coverage = harness.coverage(); + for (let i = 0; i < diagnostics.length; i++) { + reporter.diagnostic(nesting, loc, diagnostics[i]); } - this.reporter.diagnostic(this.nesting, kFilename, `tests ${this.root.harness.counters.all}`); - this.reporter.diagnostic(this.nesting, kFilename, `suites ${this.root.harness.counters.suites}`); - this.reporter.diagnostic(this.nesting, kFilename, `pass ${this.root.harness.counters.passed}`); - this.reporter.diagnostic(this.nesting, kFilename, `fail ${this.root.harness.counters.failed}`); - this.reporter.diagnostic(this.nesting, kFilename, `cancelled ${this.root.harness.counters.cancelled}`); - this.reporter.diagnostic(this.nesting, kFilename, `skipped ${this.root.harness.counters.skipped}`); - this.reporter.diagnostic(this.nesting, kFilename, `todo ${this.root.harness.counters.todo}`); - this.reporter.diagnostic(this.nesting, kFilename, `duration_ms ${this.#duration()}`); - - const coverage = this.harness.coverage(); + reporter.diagnostic(nesting, loc, `tests ${harness.counters.all}`); + reporter.diagnostic(nesting, loc, `suites ${harness.counters.suites}`); + reporter.diagnostic(nesting, loc, `pass ${harness.counters.passed}`); + reporter.diagnostic(nesting, loc, `fail ${harness.counters.failed}`); + reporter.diagnostic(nesting, loc, `cancelled ${harness.counters.cancelled}`); + reporter.diagnostic(nesting, loc, `skipped ${harness.counters.skipped}`); + reporter.diagnostic(nesting, loc, `todo ${harness.counters.todo}`); + reporter.diagnostic(nesting, loc, `duration_ms ${this.duration()}`); if (coverage) { - this.reporter.coverage(this.nesting, kFilename, coverage); + reporter.coverage(nesting, loc, coverage); } - this.reporter.end(); + reporter.end(); } } @@ -698,7 +784,7 @@ class Test extends AsyncResource { this.finished = true; } - #duration() { + duration() { // Duration is recorded in BigInt nanoseconds. Convert to milliseconds. return Number(this.endTime - this.startTime) / 1_000_000; } @@ -706,12 +792,12 @@ class Test extends AsyncResource { report() { countCompletedTest(this); if (this.subtests.length > 0) { - this.reporter.plan(this.subtests[0].nesting, kFilename, this.subtests.length); + this.reporter.plan(this.subtests[0].nesting, this.loc, this.subtests.length); } else { this.reportStarted(); } let directive; - const details = { __proto__: null, duration_ms: this.#duration() }; + const details = { __proto__: null, duration_ms: this.duration() }; if (this.skipped) { directive = this.reporter.getSkip(this.message); @@ -724,14 +810,14 @@ class Test extends AsyncResource { } if (this.passed) { - this.reporter.ok(this.nesting, kFilename, this.testNumber, this.name, details, directive); + this.reporter.ok(this.nesting, this.loc, this.testNumber, this.name, details, directive); } else { details.error = this.error; - this.reporter.fail(this.nesting, kFilename, this.testNumber, this.name, details, directive); + this.reporter.fail(this.nesting, this.loc, this.testNumber, this.name, details, directive); } for (let i = 0; i < this.diagnostics.length; i++) { - this.reporter.diagnostic(this.nesting, kFilename, this.diagnostics[i]); + this.reporter.diagnostic(this.nesting, this.loc, this.diagnostics[i]); } } @@ -741,7 +827,7 @@ class Test extends AsyncResource { } this.#reportedSubtest = true; this.parent.reportStarted(); - this.reporter.start(this.nesting, kFilename, this.name); + this.reporter.start(this.nesting, this.loc, this.name); } } @@ -751,10 +837,21 @@ class TestHook extends Test { if (options === null || typeof options !== 'object') { options = kEmptyObject; } - const { timeout, signal } = options; - super({ __proto__: null, fn, timeout, signal }); + const { loc, timeout, signal } = options; + super({ __proto__: null, fn, loc, timeout, signal }); + + this.parentTest = options.parent ?? null; + this.hookType = options.hookType; } run(args) { + if (this.error && !this.outerSignal?.aborted) { + this.passed = false; + this.error = null; + this.abortController.abort(); + this.abortController = new AbortController(); + this.signal = this.abortController.signal; + } + this.#args = args; return super.run(); } @@ -765,6 +862,22 @@ class TestHook extends Test { return true; } postRun() { + const { error, loc, parentTest: parent } = this; + + // Report failures in the root test's after() hook. + if (error && parent !== null && + parent === parent.root && this.hookType === 'after') { + + if (isTestFailureError(error)) { + error.failureType = kHookFailure; + } + + parent.reporter.fail(0, loc, parent.subtests.length + 1, loc.file, { + __proto__: null, + duration_ms: this.duration(), + error, + }, undefined); + } } } @@ -783,27 +896,34 @@ class Suite extends Test { const { ctx, args } = this.getRunArgs(); const runArgs = [this.fn, ctx]; ArrayPrototypePushApply(runArgs, args); - this.buildSuite = PromisePrototypeThen( - PromiseResolve(ReflectApply(this.runInAsyncScope, this, runArgs)), - undefined, - (err) => { - this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure)); - }); + this.buildSuite = SafePromisePrototypeFinally( + PromisePrototypeThen( + PromiseResolve(ReflectApply(this.runInAsyncScope, this, runArgs)), + undefined, + (err) => { + this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure)); + }), + () => { + this.buildPhaseFinished = true; + }, + ); } catch (err) { this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure)); + + this.buildPhaseFinished = true; } this.fn = () => {}; - this.buildPhaseFinished = true; } getRunArgs() { const ctx = new SuiteContext(this); - return { ctx, args: [ctx] }; + return { __proto__: null, ctx, args: [ctx] }; } async run() { const hookArgs = this.getRunArgs(); + let stopPromise; try { this.parent.activeSubtests++; await this.buildSuite; @@ -815,9 +935,13 @@ class Suite extends Test { return; } + if (this.parent.hooks.before.length > 0) { + await this.parent.runHook('before', this.parent.getRunArgs()); + } + await this.runHook('before', hookArgs); - const stopPromise = stopTest(this.timeout, this.signal); + stopPromise = stopTest(this.timeout, this.signal); const subtests = this.skipped || this.error ? [] : this.subtests; const promise = SafePromiseAll(subtests, (subtests) => subtests.start()); @@ -831,6 +955,8 @@ class Suite extends Test { } else { this.fail(new ERR_TEST_FAILURE(err, kTestCodeFailure)); } + } finally { + stopPromise?.[SymbolDispose](); } this.postRun(); diff --git a/lib/internal/test_runner/tests_stream.js b/lib/internal/test_runner/tests_stream.js index 20e7d458704b20..f7730caac00fa7 100644 --- a/lib/internal/test_runner/tests_stream.js +++ b/lib/internal/test_runner/tests_stream.js @@ -12,7 +12,7 @@ class TestsStream extends Readable { #canPush; constructor() { - super({ objectMode: true }); + super({ __proto__: null, objectMode: true }); this.#buffer = []; this.#canPush = true; } @@ -29,16 +29,37 @@ class TestsStream extends Readable { } } - fail(nesting, file, testNumber, name, details, directive) { - this[kEmitMessage]('test:fail', { __proto__: null, name, nesting, file, testNumber, details, ...directive }); + fail(nesting, loc, testNumber, name, details, directive) { + this[kEmitMessage]('test:fail', { + __proto__: null, + name, + nesting, + testNumber, + details, + ...loc, + ...directive, + }); } - ok(nesting, file, testNumber, name, details, directive) { - this[kEmitMessage]('test:pass', { __proto__: null, name, nesting, file, testNumber, details, ...directive }); + ok(nesting, loc, testNumber, name, details, directive) { + this[kEmitMessage]('test:pass', { + __proto__: null, + name, + nesting, + testNumber, + details, + ...loc, + ...directive, + }); } - plan(nesting, file, count) { - this[kEmitMessage]('test:plan', { __proto__: null, nesting, file, count }); + plan(nesting, loc, count) { + this[kEmitMessage]('test:plan', { + __proto__: null, + nesting, + count, + ...loc, + }); } getSkip(reason = undefined) { @@ -49,32 +70,57 @@ class TestsStream extends Readable { return { __proto__: null, todo: reason ?? true }; } - enqueue(nesting, file, name) { - this[kEmitMessage]('test:enqueue', { __proto__: null, nesting, file, name }); + enqueue(nesting, loc, name) { + this[kEmitMessage]('test:enqueue', { + __proto__: null, + nesting, + name, + ...loc, + }); } - dequeue(nesting, file, name) { - this[kEmitMessage]('test:dequeue', { __proto__: null, nesting, file, name }); + dequeue(nesting, loc, name) { + this[kEmitMessage]('test:dequeue', { + __proto__: null, + nesting, + name, + ...loc, + }); } - start(nesting, file, name) { - this[kEmitMessage]('test:start', { __proto__: null, nesting, file, name }); + start(nesting, loc, name) { + this[kEmitMessage]('test:start', { + __proto__: null, + nesting, + name, + ...loc, + }); } - diagnostic(nesting, file, message) { - this[kEmitMessage]('test:diagnostic', { __proto__: null, nesting, file, message }); + diagnostic(nesting, loc, message) { + this[kEmitMessage]('test:diagnostic', { + __proto__: null, + nesting, + message, + ...loc, + }); } - stderr(file, message) { - this[kEmitMessage]('test:stderr', { __proto__: null, file, message }); + stderr(loc, message) { + this[kEmitMessage]('test:stderr', { __proto__: null, message, ...loc }); } - stdout(file, message) { - this[kEmitMessage]('test:stdout', { __proto__: null, file, message }); + stdout(loc, message) { + this[kEmitMessage]('test:stdout', { __proto__: null, message, ...loc }); } - coverage(nesting, file, summary) { - this[kEmitMessage]('test:coverage', { __proto__: null, nesting, file, summary }); + coverage(nesting, loc, summary) { + this[kEmitMessage]('test:coverage', { + __proto__: null, + nesting, + summary, + ...loc, + }); } end() { @@ -83,6 +129,8 @@ class TestsStream extends Readable { [kEmitMessage](type, data) { this.emit(type, data); + // Disabling as this going to the user-land + // eslint-disable-next-line node-core/set-proto-to-null-in-object this.#tryPush({ type, data }); } diff --git a/lib/internal/test_runner/utils.js b/lib/internal/test_runner/utils.js index 69b59b25410ff6..b70ca649c8b8df 100644 --- a/lib/internal/test_runner/utils.js +++ b/lib/internal/test_runner/utils.js @@ -2,6 +2,7 @@ const { ArrayPrototypeJoin, ArrayPrototypeMap, + ArrayPrototypeFlatMap, ArrayPrototypePush, ArrayPrototypeReduce, ObjectGetOwnPropertyDescriptor, @@ -19,6 +20,7 @@ const { StringPrototypeSlice, } = primordials; +const { AsyncResource } = require('async_hooks'); const { relative } = require('path'); const { createWriteStream } = require('fs'); const { pathToFileURL } = require('internal/url'); @@ -75,7 +77,7 @@ function createDeferredCallback() { resolve(); }; - return { promise, cb }; + return { __proto__: null, promise, cb }; } function isTestFailureError(err) { @@ -109,6 +111,7 @@ const kBuiltinReporters = new SafeMap([ ['spec', 'internal/test_runner/reporter/spec'], ['dot', 'internal/test_runner/reporter/dot'], ['tap', 'internal/test_runner/reporter/tap'], + ['junit', 'internal/test_runner/reporter/junit'], ]); const kDefaultReporter = process.stdout.isTTY ? 'spec' : 'tap'; @@ -161,15 +164,15 @@ async function getReportersMap(reporters, destinations, rootTest) { }); } - -async function setupTestReporters(rootTest) { +const reporterScope = new AsyncResource('TestReporterScope'); +const setupTestReporters = reporterScope.bind(async (rootTest) => { const { reporters, destinations } = parseCommandLine(); const reportersMap = await getReportersMap(reporters, destinations, rootTest); for (let i = 0; i < reportersMap.length; i++) { const { reporter, destination } = reportersMap[i]; compose(rootTest.reporter, reporter).pipe(destination); } -} +}); let globalTestOptions; @@ -297,6 +300,10 @@ function formatLinesToRanges(values) { }, []), (range) => ArrayPrototypeJoin(range, '-')); } +function getUncoveredLines(lines) { + return ArrayPrototypeFlatMap(lines, (line) => (line.count === 0 ? line.line : [])); +} + function formatUncoveredLines(lines, table) { if (table) return ArrayPrototypeJoin(formatLinesToRanges(lines), ' '); return ArrayPrototypeJoin(lines, ', '); @@ -326,7 +333,7 @@ function getCoverageReport(pad, summary, symbol, color, table) { const columnsWidth = ArrayPrototypeReduce(columnPadLengths, (acc, columnPadLength) => acc + columnPadLength + 3, 0); uncoveredLinesPadLength = table && ArrayPrototypeReduce(summary.files, (acc, file) => - MathMax(acc, formatUncoveredLines(file.uncoveredLineNumbers, table).length), 0); + MathMax(acc, formatUncoveredLines(getUncoveredLines(file.lines), table).length), 0); uncoveredLinesPadLength = MathMax(uncoveredLinesPadLength, 'uncovered lines'.length); const uncoveredLinesWidth = uncoveredLinesPadLength + 2; @@ -388,7 +395,7 @@ function getCoverageReport(pad, summary, symbol, color, table) { report += `${prefix}${getCell(relativePath, filePadLength, StringPrototypePadEnd, truncateStart, fileCoverage)}${kSeparator}` + `${ArrayPrototypeJoin(ArrayPrototypeMap(coverages, (coverage, j) => getCell(NumberPrototypeToFixed(coverage, 2), columnPadLengths[j], StringPrototypePadStart, false, coverage)), kSeparator)}${kSeparator}` + - `${getCell(formatUncoveredLines(file.uncoveredLineNumbers, table), uncoveredLinesPadLength, false, truncateEnd)}\n`; + `${getCell(formatUncoveredLines(getUncoveredLines(file.lines), table), uncoveredLinesPadLength, false, truncateEnd)}\n`; } // Foot @@ -411,6 +418,7 @@ module.exports = { isTestFailureError, kDefaultPattern, parseCommandLine, + reporterScope, setupTestReporters, getCoverageReport, }; diff --git a/lib/internal/url.js b/lib/internal/url.js index 8b1cbe457af7a2..92d5e84e87c71f 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -753,13 +753,13 @@ ObjectDefineProperties(URLSearchParams.prototype, { * We use `href` and `protocol` as they are the only properties that are * easy to retrieve and calculate due to the lazy nature of the getters. * - * We check for auth attribute to distinguish legacy url instance with + * We check for `auth` and `path` attribute to distinguish legacy url instance with * WHATWG URL instance. * @param {*} self * @returns {self is URL} */ function isURL(self) { - return Boolean(self?.href && self.protocol && self.auth === undefined); + return Boolean(self?.href && self.protocol && self.auth === undefined && self.path === undefined); } class URL { @@ -1054,10 +1054,12 @@ class URL { url = `${url}`; if (base !== undefined) { - base = `${base}`; + return bindingUrl.canParse(url, `${base}`); } - return bindingUrl.canParse(url, base); + // It is important to differentiate the canParse call statements + // since they resolve into different v8 fast api overloads. + return bindingUrl.canParse(url); } } @@ -1422,37 +1424,39 @@ const backslashRegEx = /\\/g; const newlineRegEx = /\n/g; const carriageReturnRegEx = /\r/g; const tabRegEx = /\t/g; +const questionRegex = /\?/g; +const hashRegex = /#/g; function encodePathChars(filepath) { - if (StringPrototypeIncludes(filepath, '%')) + if (StringPrototypeIndexOf(filepath, '%') !== -1) filepath = RegExpPrototypeSymbolReplace(percentRegEx, filepath, '%25'); // In posix, backslash is a valid character in paths: - if (!isWindows && StringPrototypeIncludes(filepath, '\\')) + if (!isWindows && StringPrototypeIndexOf(filepath, '\\') !== -1) filepath = RegExpPrototypeSymbolReplace(backslashRegEx, filepath, '%5C'); - if (StringPrototypeIncludes(filepath, '\n')) + if (StringPrototypeIndexOf(filepath, '\n') !== -1) filepath = RegExpPrototypeSymbolReplace(newlineRegEx, filepath, '%0A'); - if (StringPrototypeIncludes(filepath, '\r')) + if (StringPrototypeIndexOf(filepath, '\r') !== -1) filepath = RegExpPrototypeSymbolReplace(carriageReturnRegEx, filepath, '%0D'); - if (StringPrototypeIncludes(filepath, '\t')) + if (StringPrototypeIndexOf(filepath, '\t') !== -1) filepath = RegExpPrototypeSymbolReplace(tabRegEx, filepath, '%09'); return filepath; } function pathToFileURL(filepath) { - const outURL = new URL('file://'); if (isWindows && StringPrototypeStartsWith(filepath, '\\\\')) { + const outURL = new URL('file://'); // UNC path format: \\server\share\resource const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', 2); if (hostnameEndIndex === -1) { throw new ERR_INVALID_ARG_VALUE( - 'filepath', + 'path', filepath, 'Missing UNC resource path', ); } if (hostnameEndIndex === 2) { throw new ERR_INVALID_ARG_VALUE( - 'filepath', + 'path', filepath, 'Empty UNC servername', ); @@ -1461,18 +1465,29 @@ function pathToFileURL(filepath) { outURL.hostname = domainToASCII(hostname); outURL.pathname = encodePathChars( RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/')); - } else { - let resolved = path.resolve(filepath); - // path.resolve strips trailing slashes so we must add them back - const filePathLast = StringPrototypeCharCodeAt(filepath, - filepath.length - 1); - if ((filePathLast === CHAR_FORWARD_SLASH || - (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) && - resolved[resolved.length - 1] !== path.sep) - resolved += '/'; - outURL.pathname = encodePathChars(resolved); - } - return outURL; + return outURL; + } + let resolved = path.resolve(filepath); + // path.resolve strips trailing slashes so we must add them back + const filePathLast = StringPrototypeCharCodeAt(filepath, + filepath.length - 1); + if ((filePathLast === CHAR_FORWARD_SLASH || + (isWindows && filePathLast === CHAR_BACKWARD_SLASH)) && + resolved[resolved.length - 1] !== path.sep) + resolved += '/'; + + // Call encodePathChars first to avoid encoding % again for ? and #. + resolved = encodePathChars(resolved); + + // Question and hash character should be included in pathname. + // Therefore, encoding is required to eliminate parsing them in different states. + // This is done as an optimization to not creating a URL instance and + // later triggering pathname setter, which impacts performance + if (StringPrototypeIndexOf(resolved, '?') !== -1) + resolved = RegExpPrototypeSymbolReplace(questionRegex, resolved, '%3F'); + if (StringPrototypeIndexOf(resolved, '#') !== -1) + resolved = RegExpPrototypeSymbolReplace(hashRegex, resolved, '%23'); + return new URL(`file://${resolved}`); } function toPathIfFileURL(fileURLOrPath) { diff --git a/lib/internal/util.js b/lib/internal/util.js index 1e1a647e693876..558a5da69773bb 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -33,6 +33,7 @@ const { SafeMap, SafeSet, SafeWeakMap, + SafeWeakRef, StringPrototypeReplace, StringPrototypeToLowerCase, StringPrototypeToUpperCase, @@ -62,7 +63,7 @@ const { sleep: _sleep, toUSVString: _toUSVString, } = internalBinding('util'); -const { isNativeError } = internalBinding('types'); +const { isNativeError, isPromise } = internalBinding('types'); const { getOptionValue } = require('internal/options'); const noCrypto = !process.versions.openssl; @@ -357,6 +358,36 @@ function getConstructorOf(obj) { return null; } +let cachedURL; +let cachedCWD; + +/** + * Get the current working directory while accounting for the possibility that it has been deleted. + * `process.cwd()` can fail if the parent directory is deleted while the process runs. + * @returns {URL} The current working directory or the volume root if it cannot be determined. + */ +function getCWDURL() { + const { sep } = require('path'); + const { pathToFileURL } = require('internal/url'); + + let cwd; + + try { + // The implementation of `process.cwd()` already uses proper cache when it can. + // It's a relatively cheap call performance-wise for the most common use case. + cwd = process.cwd(); + } catch { + cachedURL ??= pathToFileURL(sep); + } + + if (cwd != null && cwd !== cachedCWD) { + cachedURL = pathToFileURL(cwd + sep); + cachedCWD = cwd; + } + + return cachedURL; +} + function getSystemErrorName(err) { const entry = uvErrmapGet(err); return entry ? entry[0] : `Unknown system error ${err}`; @@ -408,7 +439,10 @@ function promisify(original) { resolve(values[0]); } }); - ReflectApply(original, this, args); + if (isPromise(ReflectApply(original, this, args))) { + process.emitWarning('Calling promisify on a function that returns a Promise is likely a mistake.', + 'DeprecationWarning', 'DEP0174'); + } }); } @@ -797,6 +831,38 @@ function guessHandleType(fd) { return handleTypes[type]; } +class WeakReference { + #weak = null; + #strong = null; + #refCount = 0; + constructor(object) { + this.#weak = new SafeWeakRef(object); + } + + incRef() { + this.#refCount++; + if (this.#refCount === 1) { + const derefed = this.#weak.deref(); + if (derefed !== undefined) { + this.#strong = derefed; + } + } + return this.#refCount; + } + + decRef() { + this.#refCount--; + if (this.#refCount === 0) { + this.#strong = null; + } + return this.#refCount; + } + + get() { + return this.#weak.deref(); + } +} + module.exports = { getLazy, assertCrypto, @@ -817,6 +883,7 @@ module.exports = { filterDuplicateStrings, filterOwnProperties, getConstructorOf, + getCWDURL, getInternalGlobal, getSystemErrorMap, getSystemErrorName, @@ -855,4 +922,5 @@ module.exports = { kEnumerableProperty, setOwnProperty, pendingDeprecate, + WeakReference, }; diff --git a/lib/internal/util/embedding.js b/lib/internal/util/embedding.js index e2e67202477bc7..be310f401ad115 100644 --- a/lib/internal/util/embedding.js +++ b/lib/internal/util/embedding.js @@ -1,7 +1,8 @@ 'use strict'; -const { codes: { ERR_UNKNOWN_BUILTIN_MODULE } } = require('internal/errors'); const { BuiltinModule: { normalizeRequirableId } } = require('internal/bootstrap/realm'); const { Module, wrapSafe } = require('internal/modules/cjs/loader'); +const { codes: { ERR_UNKNOWN_BUILTIN_MODULE } } = require('internal/errors'); +const { getCodeCache, getCodePath, isSea } = internalBinding('sea'); // This is roughly the same as: // @@ -15,7 +16,11 @@ const { Module, wrapSafe } = require('internal/modules/cjs/loader'); function embedderRunCjs(contents) { const filename = process.execPath; - const compiledWrapper = wrapSafe(filename, contents); + const compiledWrapper = wrapSafe( + isSea() ? getCodePath() : filename, + contents, + undefined, + getCodeCache()); const customModule = new Module(filename, null); customModule.filename = filename; diff --git a/lib/internal/util/inspector.js b/lib/internal/util/inspector.js index 0d9580c83224e4..6ff042af71f124 100644 --- a/lib/internal/util/inspector.js +++ b/lib/internal/util/inspector.js @@ -12,6 +12,7 @@ const { } = primordials; const { validatePort } = require('internal/validators'); +const permission = require('internal/process/permission'); const kMinPort = 1024; const kMaxPort = 65535; @@ -47,6 +48,10 @@ let session; function sendInspectorCommand(cb, onError) { const { hasInspector } = internalBinding('config'); if (!hasInspector) return onError(); + // Do not preview when the permission model is enabled + // because this feature require access to the inspector, + // which is unavailable in this case. + if (permission.isEnabled()) return onError(); const inspector = require('inspector'); if (session === undefined) session = new inspector.Session(); session.connect(); diff --git a/lib/internal/vm.js b/lib/internal/vm.js index b14ba13e7e4cfb..ba5e2324667374 100644 --- a/lib/internal/vm.js +++ b/lib/internal/vm.js @@ -100,9 +100,10 @@ function internalCompileFunction(code, params, options) { const { importModuleDynamicallyWrap } = require('internal/vm/module'); const wrapped = importModuleDynamicallyWrap(importModuleDynamically); const func = result.function; - const { setCallbackForWrap } = require('internal/modules/esm/utils'); - setCallbackForWrap(result.cacheKey, { - importModuleDynamically: (s, _k, i) => wrapped(s, func, i), + const { registerModule } = require('internal/modules/esm/utils'); + registerModule(func, { + __proto__: null, + importModuleDynamically: wrapped, }); } diff --git a/lib/internal/vm/module.js b/lib/internal/vm/module.js index 3d2d25064b62cd..c77ee9b107e0ad 100644 --- a/lib/internal/vm/module.js +++ b/lib/internal/vm/module.js @@ -11,7 +11,6 @@ const { ObjectSetPrototypeOf, ReflectApply, SafePromiseAllReturnVoid, - SafeWeakMap, Symbol, SymbolToStringTag, TypeError, @@ -69,7 +68,6 @@ const STATUS_MAP = { let globalModuleId = 0; const defaultModuleName = 'vm:module'; -const wrapToModuleMap = new SafeWeakMap(); const kWrap = Symbol('kWrap'); const kContext = Symbol('kContext'); @@ -120,17 +118,18 @@ class Module { }); } + let registry = { __proto__: null }; if (sourceText !== undefined) { this[kWrap] = new ModuleWrap(identifier, context, sourceText, options.lineOffset, options.columnOffset, options.cachedData); - const { setCallbackForWrap } = require('internal/modules/esm/utils'); - setCallbackForWrap(this[kWrap], { + registry = { + __proto__: null, initializeImportMeta: options.initializeImportMeta, importModuleDynamically: options.importModuleDynamically ? importModuleDynamicallyWrap(options.importModuleDynamically) : undefined, - }); + }; } else { assert(syntheticEvaluationSteps); this[kWrap] = new ModuleWrap(identifier, context, @@ -138,7 +137,11 @@ class Module { syntheticEvaluationSteps); } - wrapToModuleMap.set(this[kWrap], this); + // This will take precedence over the referrer as the object being + // passed into the callbacks. + registry.callbackReferrer = this; + const { registerModule } = require('internal/modules/esm/utils'); + registerModule(this[kWrap], registry); this[kContext] = context; } @@ -445,5 +448,4 @@ module.exports = { SourceTextModule, SyntheticModule, importModuleDynamicallyWrap, - getModuleFromWrap: (wrap) => wrapToModuleMap.get(wrap), }; diff --git a/lib/internal/watch_mode/files_watcher.js b/lib/internal/watch_mode/files_watcher.js index 848c17f4115616..895c6ec138d131 100644 --- a/lib/internal/watch_mode/files_watcher.js +++ b/lib/internal/watch_mode/files_watcher.js @@ -14,7 +14,7 @@ const { TIMEOUT_MAX } = require('internal/timers'); const EventEmitter = require('events'); const { watch } = require('fs'); -const { fileURLToPath } = require('url'); +const { fileURLToPath } = require('internal/url'); const { resolve, dirname } = require('path'); const { setTimeout } = require('timers'); @@ -24,19 +24,19 @@ const supportsRecursiveWatching = process.platform === 'win32' || class FilesWatcher extends EventEmitter { #watchers = new SafeMap(); #filteredFiles = new SafeSet(); - #throttling = new SafeSet(); + #debouncing = new SafeSet(); #depencencyOwners = new SafeMap(); #ownerDependencies = new SafeMap(); - #throttle; + #debounce; #mode; #signal; - constructor({ throttle = 500, mode = 'filter', signal } = kEmptyObject) { + constructor({ debounce = 200, mode = 'filter', signal } = kEmptyObject) { super(); - validateNumber(throttle, 'options.throttle', 0, TIMEOUT_MAX); + validateNumber(debounce, 'options.debounce', 0, TIMEOUT_MAX); validateOneOf(mode, 'options.mode', ['filter', 'all']); - this.#throttle = throttle; + this.#debounce = debounce; this.#mode = mode; this.#signal = signal; @@ -74,16 +74,18 @@ class FilesWatcher extends EventEmitter { } #onChange(trigger) { - if (this.#throttling.has(trigger)) { + if (this.#debouncing.has(trigger)) { return; } if (this.#mode === 'filter' && !this.#filteredFiles.has(trigger)) { return; } - this.#throttling.add(trigger); + this.#debouncing.add(trigger); const owners = this.#depencencyOwners.get(trigger); - this.emit('changed', { owners }); - setTimeout(() => this.#throttling.delete(trigger), this.#throttle).unref(); + setTimeout(() => { + this.#debouncing.delete(trigger); + this.emit('changed', { owners }); + }, this.#debounce).unref(); } get watchedPaths() { diff --git a/lib/internal/webstreams/queuingstrategies.js b/lib/internal/webstreams/queuingstrategies.js index 8fbc87642ebc0c..cb2adefdacaee9 100644 --- a/lib/internal/webstreams/queuingstrategies.js +++ b/lib/internal/webstreams/queuingstrategies.js @@ -69,7 +69,7 @@ class ByteLengthQueuingStrategy { constructor(init) { validateObject(init, 'init'); if (init.highWaterMark === undefined) - throw new ERR_MISSING_OPTION('options.highWaterMark'); + throw new ERR_MISSING_OPTION('init.highWaterMark'); // The highWaterMark value is not checked until the strategy // is actually used, per the spec. @@ -121,7 +121,7 @@ class CountQueuingStrategy { constructor(init) { validateObject(init, 'init'); if (init.highWaterMark === undefined) - throw new ERR_MISSING_OPTION('options.highWaterMark'); + throw new ERR_MISSING_OPTION('init.highWaterMark'); // The highWaterMark value is not checked until the strategy // is actually used, per the spec. diff --git a/lib/internal/webstreams/readablestream.js b/lib/internal/webstreams/readablestream.js index 9e754309557b49..4bdd1fa4862a8f 100644 --- a/lib/internal/webstreams/readablestream.js +++ b/lib/internal/webstreams/readablestream.js @@ -14,7 +14,6 @@ const { ObjectCreate, ObjectDefineProperties, ObjectSetPrototypeOf, - Promise, PromisePrototypeThen, PromiseResolve, PromiseReject, @@ -111,6 +110,8 @@ const { nonOpCancel, nonOpPull, nonOpStart, + getIterator, + iteratorNext, kType, kState, } = require('internal/webstreams/util'); @@ -130,6 +131,8 @@ const { writableStreamDefaultWriterWrite, } = require('internal/webstreams/writablestream'); +const { Buffer } = require('buffer'); + const assert = require('internal/assert'); const kCancel = Symbol('kCancel'); @@ -138,6 +141,7 @@ const kChunk = Symbol('kChunk'); const kError = Symbol('kError'); const kPull = Symbol('kPull'); const kRelease = Symbol('kRelease'); +const kSkipThrow = Symbol('kSkipThrow'); let releasedError; let releasingError; @@ -314,6 +318,10 @@ class ReadableStream { return isReadableStreamLocked(this); } + static from(iterable) { + return readableStreamFromIterable(iterable); + } + /** * @param {any} [reason] * @returns { Promise } @@ -468,9 +476,13 @@ class ReadableStream { // eslint-disable-next-line no-use-before-define const reader = new ReadableStreamDefaultReader(this); - let done = false; + + // No __proto__ here to avoid the performance hit. + const state = { + done: false, + current: undefined, + }; let started = false; - let current; // The nextSteps function is not an async function in order // to make it more efficient. Because nextSteps explicitly @@ -479,7 +491,7 @@ class ReadableStream { // unnecessary Promise allocations to occur, which just add // cost. function nextSteps() { - if (done) + if (state.done) return PromiseResolve({ done: true, value: undefined }); if (reader[kState].stream === undefined) { @@ -489,31 +501,15 @@ class ReadableStream { } const promise = createDeferredPromise(); - readableStreamDefaultReaderRead(reader, { - [kChunk](chunk) { - current = undefined; - promise.resolve({ value: chunk, done: false }); - }, - [kClose]() { - current = undefined; - done = true; - readableStreamReaderGenericRelease(reader); - promise.resolve({ done: true, value: undefined }); - }, - [kError](error) { - current = undefined; - done = true; - readableStreamReaderGenericRelease(reader); - promise.reject(error); - }, - }); + // eslint-disable-next-line no-use-before-define + readableStreamDefaultReaderRead(reader, new ReadableStreamAsyncIteratorReadRequest(reader, state, promise)); return promise.promise; } async function returnSteps(value) { - if (done) + if (state.done) return { done: true, value }; // eslint-disable-line node-core/avoid-prototype-pollution - done = true; + state.done = true; if (reader[kState].stream === undefined) { throw new ERR_INVALID_STATE.TypeError( @@ -550,19 +546,19 @@ class ReadableStream { // need to investigate if it's a bug in our impl or // the spec. if (!started) { - current = PromiseResolve(); + state.current = PromiseResolve(); started = true; } - current = current !== undefined ? - PromisePrototypeThen(current, nextSteps, nextSteps) : + state.current = state.current !== undefined ? + PromisePrototypeThen(state.current, nextSteps, nextSteps) : nextSteps(); - return current; + return state.current; }, return(error) { - return current ? + return state.current ? PromisePrototypeThen( - current, + state.current, () => returnSteps(error), () => returnSteps(error)) : returnSteps(error); @@ -669,8 +665,10 @@ TransferredReadableStream.prototype[kDeserialize] = () => {}; class ReadableStreamBYOBRequest { [kType] = 'ReadableStreamBYOBRequest'; - constructor() { - throw new ERR_ILLEGAL_CONSTRUCTOR(); + constructor(skipThrowSymbol = undefined) { + if (skipThrowSymbol !== kSkipThrow) { + throw new ERR_ILLEGAL_CONSTRUCTOR(); + } } /** @@ -752,17 +750,41 @@ ObjectDefineProperties(ReadableStreamBYOBRequest.prototype, { }); function createReadableStreamBYOBRequest(controller, view) { - return ReflectConstruct( - function() { - this[kType] = 'ReadableStreamBYOBRequest'; - this[kState] = { - controller, - view, - }; - }, - [], - ReadableStreamBYOBRequest, - ); + const stream = new ReadableStreamBYOBRequest(kSkipThrow); + + stream[kState] = { + controller, + view, + }; + + return stream; +} + +class ReadableStreamAsyncIteratorReadRequest { + constructor(reader, state, promise) { + this.reader = reader; + this.state = state; + this.promise = promise; + } + + [kChunk](chunk) { + this.state.current = undefined; + this.promise.resolve({ value: chunk, done: false }); + } + + [kClose]() { + this.state.current = undefined; + this.state.done = true; + readableStreamReaderGenericRelease(this.reader); + this.promise.resolve({ done: true, value: undefined }); + } + + [kError](error) { + this.state.current = undefined; + this.state.done = true; + readableStreamReaderGenericRelease(this.reader); + this.promise.reject(error); + } } class DefaultReadRequest { @@ -1012,9 +1034,12 @@ ObjectDefineProperties(ReadableStreamBYOBReader.prototype, { class ReadableStreamDefaultController { [kType] = 'ReadableStreamDefaultController'; + [kState] = {}; - constructor() { - throw new ERR_ILLEGAL_CONSTRUCTOR(); + constructor(skipThrowSymbol = undefined) { + if (skipThrowSymbol !== kSkipThrow) { + throw new ERR_ILLEGAL_CONSTRUCTOR(); + } } /** @@ -1070,22 +1095,14 @@ ObjectDefineProperties(ReadableStreamDefaultController.prototype, { [SymbolToStringTag]: getNonWritablePropertyDescriptor(ReadableStreamDefaultController.name), }); -function createReadableStreamDefaultController() { - return ReflectConstruct( - function() { - this[kType] = 'ReadableStreamDefaultController'; - this[kState] = {}; - }, - [], - ReadableStreamDefaultController, - ); -} - class ReadableByteStreamController { [kType] = 'ReadableByteStreamController'; + [kState] = {}; - constructor() { - throw new ERR_ILLEGAL_CONSTRUCTOR(); + constructor(skipThrowSymbol = undefined) { + if (skipThrowSymbol !== kSkipThrow) { + throw new ERR_ILLEGAL_CONSTRUCTOR(); + } } /** @@ -1196,45 +1213,41 @@ ObjectDefineProperties(ReadableByteStreamController.prototype, { [SymbolToStringTag]: getNonWritablePropertyDescriptor(ReadableByteStreamController.name), }); -function createReadableByteStreamController() { - return ReflectConstruct( - function() { - this[kType] = 'ReadableByteStreamController'; - this[kState] = {}; +function TeeReadableStream(start, pull, cancel) { + markTransferMode(this, false, true); + this[kType] = 'ReadableStream'; + this[kState] = { + disturbed: false, + state: 'readable', + storedError: undefined, + stream: undefined, + transfer: { + writable: undefined, + port: undefined, + promise: undefined, }, - [], - ReadableByteStreamController, - ); + }; + this[kIsClosedPromise] = createDeferredPromise(); + setupReadableStreamDefaultControllerFromSource( + this, + ObjectCreate(null, { + start: { __proto__: null, value: start }, + pull: { __proto__: null, value: pull }, + cancel: { __proto__: null, value: cancel }, + }), + 1, + () => 1); } +ObjectSetPrototypeOf(TeeReadableStream.prototype, ReadableStream.prototype); +ObjectSetPrototypeOf(TeeReadableStream, ReadableStream); + function createTeeReadableStream(start, pull, cancel) { - return ReflectConstruct( - function() { - markTransferMode(this, false, true); - this[kType] = 'ReadableStream'; - this[kState] = { - disturbed: false, - state: 'readable', - storedError: undefined, - stream: undefined, - transfer: { - writable: undefined, - port: undefined, - promise: undefined, - }, - }; - this[kIsClosedPromise] = createDeferredPromise(); - setupReadableStreamDefaultControllerFromSource( - this, - ObjectCreate(null, { - start: { __proto__: null, value: start }, - pull: { __proto__: null, value: pull }, - cancel: { __proto__: null, value: cancel }, - }), - 1, - () => 1); - }, [], ReadableStream, - ); + const tee = new TeeReadableStream(start, pull, cancel); + + // For spec compliance the Tee must be a ReadableStream + tee.constructor = ReadableStream; + return tee; } const isReadableStream = @@ -1250,6 +1263,59 @@ const isReadableStreamBYOBReader = // ---- ReadableStream Implementation +function readableStreamFromIterable(iterable) { + let stream; + const iteratorRecord = getIterator(iterable, 'async'); + + const startAlgorithm = nonOpStart; + + async function pullAlgorithm() { + const nextResult = iteratorNext(iteratorRecord); + const nextPromise = PromiseResolve(nextResult); + return PromisePrototypeThen(nextPromise, (iterResult) => { + if (typeof iterResult !== 'object' || iterResult === null) { + throw new ERR_INVALID_STATE.TypeError( + 'The promise returned by the iterator.next() method must fulfill with an object'); + } + if (iterResult.done) { + readableStreamDefaultControllerClose(stream[kState].controller); + } else { + readableStreamDefaultControllerEnqueue(stream[kState].controller, iterResult.value); + } + }); + } + + async function cancelAlgorithm(reason) { + const iterator = iteratorRecord.iterator; + const returnMethod = iterator.return; + if (returnMethod === undefined) { + return PromiseResolve(); + } + const returnResult = FunctionPrototypeCall(returnMethod, iterator, reason); + const returnPromise = PromiseResolve(returnResult); + return PromisePrototypeThen(returnPromise, (iterResult) => { + if (typeof iterResult !== 'object' || iterResult === null) { + throw new ERR_INVALID_STATE.TypeError( + 'The promise returned by the iterator.return() method must fulfill with an object'); + } + return undefined; + }); + } + + stream = new ReadableStream({ + start: startAlgorithm, + pull: pullAlgorithm, + cancel: cancelAlgorithm, + }, { + size() { + return 1; + }, + highWaterMark: 0, + }); + + return stream; +} + function readableStreamPipeTo( source, dest, @@ -1284,7 +1350,9 @@ function readableStreamPipeTo( const promise = createDeferredPromise(); - let currentWrite = PromiseResolve(); + const state = { + currentWrite: PromiseResolve(), + }; // The error here can be undefined. The rejected arg // tells us that the promise must be rejected even @@ -1301,9 +1369,9 @@ function readableStreamPipeTo( } async function waitForCurrentWrite() { - const write = currentWrite; + const write = state.currentWrite; await write; - if (write !== currentWrite) + if (write !== state.currentWrite) await waitForCurrentWrite(); } @@ -1394,20 +1462,14 @@ function readableStreamPipeTo( async function step() { if (shuttingDown) return true; + await writer[kState].ready.promise; - return new Promise((resolve, reject) => { - readableStreamDefaultReaderRead( - reader, - { - [kChunk](chunk) { - currentWrite = writableStreamDefaultWriterWrite(writer, chunk); - setPromiseHandled(currentWrite); - resolve(false); - }, - [kClose]: () => resolve(true), - [kError]: reject, - }); - }); + + const promise = createDeferredPromise(); + // eslint-disable-next-line no-use-before-define + readableStreamDefaultReaderRead(reader, new PipeToReadableStreamReadRequest(writer, state, promise)); + + return promise.promise; } async function run() { @@ -1469,6 +1531,28 @@ function readableStreamPipeTo( return promise.promise; } +class PipeToReadableStreamReadRequest { + constructor(writer, state, promise) { + this.writer = writer; + this.state = state; + this.promise = promise; + } + + [kChunk](chunk) { + this.state.currentWrite = writableStreamDefaultWriterWrite(this.writer, chunk); + setPromiseHandled(this.state.currentWrite); + this.promise.resolve(false); + } + + [kClose]() { + this.promise.resolve(true); + } + + [kError](error) { + this.promise.reject(error); + } +} + function readableStreamTee(stream, cloneForBranch2) { if (isReadableByteStreamController(stream[kState].controller)) { return readableByteStreamTee(stream); @@ -1861,6 +1945,11 @@ function readableByteStreamControllerConvertPullIntoDescriptor(desc) { throw new ERR_INVALID_STATE.RangeError('The buffer size is invalid'); assert(!(bytesFilled % elementSize)); const transferredBuffer = transferArrayBuffer(buffer); + + if (ctor === Buffer) { + return Buffer.from(transferredBuffer, byteOffset, bytesFilled / elementSize); + } + return new ctor(transferredBuffer, byteOffset, bytesFilled / elementSize); } @@ -2356,7 +2445,7 @@ function setupReadableStreamDefaultControllerFromSource( source, highWaterMark, sizeAlgorithm) { - const controller = createReadableStreamDefaultController(); + const controller = new ReadableStreamDefaultController(kSkipThrow); const start = source?.start; const pull = source?.pull; const cancel = source?.cancel; @@ -3154,7 +3243,7 @@ function setupReadableByteStreamControllerFromSource( stream, source, highWaterMark) { - const controller = createReadableByteStreamController(); + const controller = new ReadableByteStreamController(kSkipThrow); const start = source?.start; const pull = source?.pull; const cancel = source?.cancel; diff --git a/lib/internal/webstreams/transformstream.js b/lib/internal/webstreams/transformstream.js index c5b2aa90ffae5f..7a8f20a6eece38 100644 --- a/lib/internal/webstreams/transformstream.js +++ b/lib/internal/webstreams/transformstream.js @@ -8,6 +8,7 @@ const { PromiseResolve, ReflectConstruct, SymbolToStringTag, + Symbol, } = primordials; const { @@ -65,6 +66,8 @@ const { const assert = require('internal/assert'); +const kSkipThrow = Symbol('kSkipThrow'); + const getNonWritablePropertyDescriptor = (value) => { return { __proto__: null, @@ -268,8 +271,10 @@ TransferredTransformStream.prototype[kDeserialize] = () => {}; class TransformStreamDefaultController { [kType] = 'TransformStreamDefaultController'; - constructor() { - throw new ERR_ILLEGAL_CONSTRUCTOR(); + constructor(skipThrowSymbol = undefined) { + if (skipThrowSymbol !== kSkipThrow) { + throw new ERR_ILLEGAL_CONSTRUCTOR(); + } } /** @@ -330,15 +335,6 @@ ObjectDefineProperties(TransformStreamDefaultController.prototype, { [SymbolToStringTag]: getNonWritablePropertyDescriptor(TransformStreamDefaultController.name), }); -function createTransformStreamDefaultController() { - return ReflectConstruct( - function() { - this[kType] = 'TransformStreamDefaultController'; - }, - [], - TransformStreamDefaultController); -} - const isTransformStream = isBrandCheck('TransformStream'); const isTransformStreamDefaultController = @@ -453,7 +449,7 @@ function setupTransformStreamDefaultController( function setupTransformStreamDefaultControllerFromTransformer( stream, transformer) { - const controller = createTransformStreamDefaultController(); + const controller = new TransformStreamDefaultController(kSkipThrow); const transform = transformer?.transform || defaultTransformAlgorithm; const flush = transformer?.flush || nonOpFlush; const transformAlgorithm = diff --git a/lib/internal/webstreams/util.js b/lib/internal/webstreams/util.js index abc064170926dd..1979c55667b167 100644 --- a/lib/internal/webstreams/util.js +++ b/lib/internal/webstreams/util.js @@ -13,6 +13,8 @@ const { PromiseReject, ReflectGet, Symbol, + SymbolAsyncIterator, + SymbolIterator, Uint8Array, } = primordials; @@ -20,6 +22,7 @@ const { codes: { ERR_INVALID_ARG_VALUE, ERR_OPERATION_FAILED, + ERR_INVALID_STATE, }, } = require('internal/errors'); @@ -217,6 +220,54 @@ function lazyTransfer() { return transfer; } +function createAsyncFromSyncIterator(syncIteratorRecord) { + const syncIterable = { + [SymbolIterator]: () => syncIteratorRecord.iterator, + }; + + const asyncIterator = (async function* () { + return yield* syncIterable; + }()); + + const nextMethod = asyncIterator.next; + return { iterator: asyncIterator, nextMethod, done: false }; +} + +function getIterator(obj, kind = 'sync', method) { + if (method === undefined) { + if (kind === 'async') { + method = obj[SymbolAsyncIterator]; + if (method === undefined) { + const syncMethod = obj[SymbolIterator]; + const syncIteratorRecord = getIterator(obj, 'sync', syncMethod); + return createAsyncFromSyncIterator(syncIteratorRecord); + } + } else { + method = obj[SymbolIterator]; + } + } + + const iterator = FunctionPrototypeCall(method, obj); + if (typeof iterator !== 'object' || iterator === null) { + throw new ERR_INVALID_STATE.TypeError('The iterator method must return an object'); + } + const nextMethod = iterator.next; + return { iterator, nextMethod, done: false }; +} + +function iteratorNext(iteratorRecord, value) { + let result; + if (value === undefined) { + result = FunctionPrototypeCall(iteratorRecord.nextMethod, iteratorRecord.iterator); + } else { + result = FunctionPrototypeCall(iteratorRecord.nextMethod, iteratorRecord.iterator, [value]); + } + if (typeof result !== 'object' || result === null) { + throw new ERR_INVALID_STATE.TypeError('The iterator.next() method must return an object'); + } + return result; +} + module.exports = { ArrayBufferViewGetBuffer, ArrayBufferViewGetByteLength, @@ -243,6 +294,8 @@ module.exports = { nonOpPull, nonOpStart, nonOpWrite, + getIterator, + iteratorNext, kType, kState, }; diff --git a/lib/internal/webstreams/writablestream.js b/lib/internal/webstreams/writablestream.js index 2544c179f53952..46d6ae28772c32 100644 --- a/lib/internal/webstreams/writablestream.js +++ b/lib/internal/webstreams/writablestream.js @@ -81,6 +81,7 @@ const assert = require('internal/assert'); const kAbort = Symbol('kAbort'); const kCloseSentinel = Symbol('kCloseSentinel'); const kError = Symbol('kError'); +const kSkipThrow = Symbol('kSkipThrow'); let releasedError; @@ -522,8 +523,10 @@ ObjectDefineProperties(WritableStreamDefaultWriter.prototype, { class WritableStreamDefaultController { [kType] = 'WritableStreamDefaultController'; - constructor() { - throw new ERR_ILLEGAL_CONSTRUCTOR(); + constructor(skipThrowSymbol = undefined) { + if (skipThrowSymbol !== kSkipThrow) { + throw new ERR_ILLEGAL_CONSTRUCTOR(); + } } [kAbort](reason) { @@ -569,14 +572,6 @@ ObjectDefineProperties(WritableStreamDefaultController.prototype, { [SymbolToStringTag]: getNonWritablePropertyDescriptor(WritableStreamDefaultController.name), }); -function createWritableStreamDefaultController() { - return ReflectConstruct( - function() { - this[kType] = 'WritableStreamDefaultController'; - }, - [], WritableStreamDefaultController); -} - const isWritableStream = isBrandCheck('WritableStream'); const isWritableStreamDefaultWriter = @@ -1233,7 +1228,7 @@ function setupWritableStreamDefaultControllerFromSink( sink, highWaterMark, sizeAlgorithm) { - const controller = createWritableStreamDefaultController(); + const controller = new WritableStreamDefaultController(kSkipThrow); const start = sink?.start; const write = sink?.write; const close = sink?.close; diff --git a/lib/internal/worker/io.js b/lib/internal/worker/io.js index f3dce214c8a5c1..6f4348f11d2ddb 100644 --- a/lib/internal/worker/io.js +++ b/lib/internal/worker/io.js @@ -22,6 +22,7 @@ const { const { kEmptyObject, kEnumerableProperty, + setOwnProperty, } = require('internal/util'); const { @@ -302,15 +303,15 @@ function setupPortReferencing(port, eventEmitter, eventName) { if (name === eventName) removeListener(eventEmitter.listenerCount(name)); }); const origNewListener = eventEmitter[kNewListener]; - eventEmitter[kNewListener] = function(size, type, ...args) { + setOwnProperty(eventEmitter, kNewListener, function(size, type, ...args) { if (type === eventName) newListener(size - 1); return ReflectApply(origNewListener, this, arguments); - }; + }); const origRemoveListener = eventEmitter[kRemoveListener]; - eventEmitter[kRemoveListener] = function(size, type, ...args) { + setOwnProperty(eventEmitter, kRemoveListener, function(size, type, ...args) { if (type === eventName) removeListener(size); return ReflectApply(origRemoveListener, this, arguments); - }; + }); function newListener(size) { if (size === 0) { diff --git a/lib/repl.js b/lib/repl.js index 2a63050923b198..931ae5087c8fb3 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -204,6 +204,7 @@ const domainSet = new SafeWeakSet(); const kBufferedCommandSymbol = Symbol('bufferedCommand'); const kContextId = Symbol('contextId'); +const kLoadingSymbol = Symbol('loading'); let addedNewListener = false; @@ -467,7 +468,7 @@ function REPLServer(prompt, if (e.name === 'SyntaxError') { let parentURL; try { - const { pathToFileURL } = require('url'); + const { pathToFileURL } = require('internal/url'); // Adding `/repl` prevents dynamic imports from loading relative // to the parent of `process.cwd()`. parentURL = pathToFileURL(path.join(process.cwd(), 'repl')).href; @@ -508,7 +509,7 @@ function REPLServer(prompt, if (err === null) { let parentURL; try { - const { pathToFileURL } = require('url'); + const { pathToFileURL } = require('internal/url'); // Adding `/repl` prevents dynamic imports from loading relative // to the parent of `process.cwd()`. parentURL = pathToFileURL(path.join(process.cwd(), 'repl')).href; @@ -882,7 +883,7 @@ function REPLServer(prompt, self[kBufferedCommandSymbol] += cmd + '\n'; // code alignment - const matches = self._sawKeyPress ? + const matches = self._sawKeyPress && !self[kLoadingSymbol] ? RegExpPrototypeExec(/^\s+/, cmd) : null; if (matches) { const prefix = matches[0]; @@ -1801,8 +1802,10 @@ function defineDefaultCommands(repl) { const stats = fs.statSync(file); if (stats && stats.isFile()) { _turnOnEditorMode(this); + this[kLoadingSymbol] = true; const data = fs.readFileSync(file, 'utf8'); this.write(data); + this[kLoadingSymbol] = false; _turnOffEditorMode(this); this.write('\n'); } else { diff --git a/lib/test/reporters.js b/lib/test/reporters.js index 287c07510bc13a..06a0b27ee58275 100644 --- a/lib/test/reporters.js +++ b/lib/test/reporters.js @@ -1,8 +1,9 @@ 'use strict'; -const { ObjectDefineProperties } = primordials; +const { ObjectDefineProperties, ReflectConstruct } = primordials; let dot; +let junit; let spec; let tap; @@ -17,13 +18,22 @@ ObjectDefineProperties(module.exports, { return dot; }, }, - spec: { + junit: { __proto__: null, configurable: true, enumerable: true, get() { + junit ??= require('internal/test_runner/reporter/junit'); + return junit; + }, + }, + spec: { + __proto__: null, + configurable: true, + enumerable: true, + value: function value() { spec ??= require('internal/test_runner/reporter/spec'); - return spec; + return ReflectConstruct(spec, arguments); }, }, tap: { diff --git a/lib/url.js b/lib/url.js index 2cb51ff362a295..b6b5376c379a6c 100644 --- a/lib/url.js +++ b/lib/url.js @@ -53,7 +53,7 @@ const { domainToASCII, domainToUnicode, fileURLToPath, - pathToFileURL, + pathToFileURL: _pathToFileURL, urlToHttpOptions, unsafeProtocol, hostlessProtocol, @@ -401,10 +401,7 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { // It only converts parts of the domain name that // have non-ASCII characters, i.e. it doesn't matter if // you call it with a domain that already is ASCII-only. - - // Use lenient mode (`true`) to try to support even non-compliant - // URLs. - this.hostname = toASCII(this.hostname, true); + this.hostname = toASCII(this.hostname); // Prevent two potential routes of hostname spoofing. // 1. If this.hostname is empty, it must have become empty due to toASCII @@ -1020,6 +1017,15 @@ Url.prototype.parseHost = function parseHost() { if (host) this.hostname = host; }; +// When used internally, we are not obligated to associate TypeError with +// this function, so non-strings can be rejected by underlying implementation. +// Public API has to validate input and throw appropriate error. +function pathToFileURL(path) { + validateString(path, 'path'); + + return _pathToFileURL(path); +} + module.exports = { // Original API Url, diff --git a/lib/vm.js b/lib/vm.js index b48e79c282541b..4b9bedec3f4934 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -30,7 +30,6 @@ const { const { ContextifyScript, - MicrotaskQueue, makeContext, constants, measureMemory: _measureMemory, @@ -106,8 +105,9 @@ class Script extends ContextifyScript { validateFunction(importModuleDynamically, 'options.importModuleDynamically'); const { importModuleDynamicallyWrap } = require('internal/vm/module'); - const { setCallbackForWrap } = require('internal/modules/esm/utils'); - setCallbackForWrap(this, { + const { registerModule } = require('internal/modules/esm/utils'); + registerModule(this, { + __proto__: null, importModuleDynamically: importModuleDynamicallyWrap(importModuleDynamically), }); @@ -238,9 +238,7 @@ function createContext(contextObject = {}, options = kEmptyObject) { validateOneOf(microtaskMode, 'options.microtaskMode', ['afterEvaluate', undefined]); - const microtaskQueue = microtaskMode === 'afterEvaluate' ? - new MicrotaskQueue() : - null; + const microtaskQueue = (microtaskMode === 'afterEvaluate'); makeContext(contextObject, name, origin, strings, wasm, microtaskQueue); return contextObject; diff --git a/node.gyp b/node.gyp index cf016ef468c275..93e4235a0f3efd 100644 --- a/node.gyp +++ b/node.gyp @@ -10,6 +10,7 @@ 'node_use_v8_platform%': 'true', 'node_use_bundled_v8%': 'true', 'node_shared%': 'false', + 'node_write_snapshot_as_string_literals': 'true', 'force_dynamic_crt%': 0, 'ossfuzz' : 'false', 'node_module_version%': '', @@ -100,6 +101,7 @@ 'src/node_contextify.cc', 'src/node_credentials.cc', 'src/node_dir.cc', + 'src/node_dotenv.cc', 'src/node_env_var.cc', 'src/node_errors.cc', 'src/node_external_reference.cc', @@ -214,6 +216,7 @@ 'src/node_context_data.h', 'src/node_contextify.h', 'src/node_dir.h', + 'src/node_dotenv.h', 'src/node_errors.h', 'src/node_exit_code.h', 'src/node_external_reference.h', @@ -253,7 +256,6 @@ 'src/node_stat_watcher.h', 'src/node_union_bytes.h', 'src/node_url.h', - 'src/node_util.h', 'src/node_version.h', 'src/node_v8.h', 'src/node_v8_platform-inl.h', @@ -374,6 +376,38 @@ 'src/quic/tokens.h', 'src/quic/transportparams.h', ], + 'node_cctest_sources': [ + 'src/node_snapshot_stub.cc', + 'test/cctest/node_test_fixture.cc', + 'test/cctest/node_test_fixture.h', + 'test/cctest/test_aliased_buffer.cc', + 'test/cctest/test_base64.cc', + 'test/cctest/test_base_object_ptr.cc', + 'test/cctest/test_cppgc.cc', + 'test/cctest/test_node_postmortem_metadata.cc', + 'test/cctest/test_environment.cc', + 'test/cctest/test_linked_binding.cc', + 'test/cctest/test_node_api.cc', + 'test/cctest/test_per_process.cc', + 'test/cctest/test_platform.cc', + 'test/cctest/test_report.cc', + 'test/cctest/test_json_utils.cc', + 'test/cctest/test_sockaddr.cc', + 'test/cctest/test_traced_value.cc', + 'test/cctest/test_util.cc', + 'test/cctest/test_dataqueue.cc', + ], + 'node_cctest_openssl_sources': [ + 'test/cctest/test_crypto_clienthello.cc', + 'test/cctest/test_node_crypto.cc', + 'test/cctest/test_node_crypto_env.cc', + 'test/cctest/test_quic_cid.cc', + 'test/cctest/test_quic_tokens.cc', + ], + 'node_cctest_inspector_sources': [ + 'test/cctest/test_inspector_socket.cc', + 'test/cctest/test_inspector_socket_server.cc', + ], 'node_mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)node_mksnapshot<(EXECUTABLE_SUFFIX)', 'node_js2c_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)node_js2c<(EXECUTABLE_SUFFIX)', 'conditions': [ @@ -885,9 +919,6 @@ 'node_target_type=="executable"', { 'defines': [ 'NODE_ENABLE_LARGE_CODE_PAGES=1' ], }], - ['OS in "linux mac"', { - 'defines': [ 'NODE_MKSNAPSHOT_USE_STRING_LITERALS' ], - }], [ 'use_openssl_def==1', { # TODO(bnoordhuis) Make all platforms export the same list of symbols. # Teach mkssldef.py to generate linker maps that UNIX linkers understand. @@ -1040,48 +1071,20 @@ 'NODE_WANT_INTERNALS=1', ], - 'sources': [ - 'src/node_snapshot_stub.cc', - 'test/cctest/node_test_fixture.cc', - 'test/cctest/node_test_fixture.h', - 'test/cctest/test_aliased_buffer.cc', - 'test/cctest/test_base64.cc', - 'test/cctest/test_base_object_ptr.cc', - 'test/cctest/test_node_postmortem_metadata.cc', - 'test/cctest/test_environment.cc', - 'test/cctest/test_linked_binding.cc', - 'test/cctest/test_node_api.cc', - 'test/cctest/test_per_process.cc', - 'test/cctest/test_platform.cc', - 'test/cctest/test_report.cc', - 'test/cctest/test_json_utils.cc', - 'test/cctest/test_sockaddr.cc', - 'test/cctest/test_traced_value.cc', - 'test/cctest/test_util.cc', - 'test/cctest/test_dataqueue.cc', - ], + 'sources': [ '<@(node_cctest_sources)' ], 'conditions': [ [ 'node_use_openssl=="true"', { 'defines': [ 'HAVE_OPENSSL=1', ], - 'sources': [ - 'test/cctest/test_crypto_clienthello.cc', - 'test/cctest/test_node_crypto.cc', - 'test/cctest/test_node_crypto_env.cc', - 'test/cctest/test_quic_cid.cc', - 'test/cctest/test_quic_tokens.cc', - ] + 'sources': [ '<@(node_cctest_openssl_sources)' ], }], ['v8_enable_inspector==1', { - 'sources': [ - 'test/cctest/test_inspector_socket.cc', - 'test/cctest/test_inspector_socket_server.cc' - ], 'defines': [ 'HAVE_INSPECTOR=1', ], + 'sources': [ '<@(node_cctest_inspector_sources)' ], }, { 'defines': [ 'HAVE_INSPECTOR=0', @@ -1256,6 +1259,9 @@ ], 'conditions': [ + ['node_write_snapshot_as_array_literals=="true"', { + 'defines': [ 'NODE_MKSNAPSHOT_USE_ARRAY_LITERALS=1' ], + }], [ 'node_use_openssl=="true"', { 'defines': [ 'HAVE_OPENSSL=1', diff --git a/onboarding.md b/onboarding.md index 1e912f0c8a4379..be393a64f3fc67 100644 --- a/onboarding.md +++ b/onboarding.md @@ -10,7 +10,7 @@ onboarding session. possible to add them to the organization if they are not using two-factor authentication. If they cannot receive SMS messages from GitHub, try [using a TOTP mobile app][]. -* Suggest the new Collaborator install [`node-core-utils`][] and +* Suggest the new Collaborator install [`@node-core/utils`][] and [set up the credentials][] for it. ## Fifteen minutes before the onboarding session @@ -230,7 +230,7 @@ needs to be pointed out separately during the onboarding. request. * Be sure to add the `PR-URL: ` and appropriate `Reviewed-By:` metadata. - * [`node-core-utils`][] automates the generation of metadata and the landing + * [`@node-core/utils`][] automates the generation of metadata and the landing process. See the documentation of [`git-node`][]. * [`core-validate-commit`][] automates the validation of commit messages. This will be run during `git node land --final` of the [`git-node`][] @@ -260,10 +260,10 @@ needs to be pointed out separately during the onboarding. [Labels]: doc/contributing/collaborator-guide.md#labels [Landing pull requests]: doc/contributing/collaborator-guide.md#landing-pull-requests [Publicizing or hiding organization membership]: https://help.github.com/articles/publicizing-or-hiding-organization-membership/ +[`@node-core/utils`]: https://github.com/nodejs/node-core-utils [`author-ready`]: doc/contributing/collaborator-guide.md#author-ready-pull-requests [`core-validate-commit`]: https://github.com/nodejs/core-validate-commit [`git-node`]: https://github.com/nodejs/node-core-utils/blob/HEAD/docs/git-node.md -[`node-core-utils`]: https://github.com/nodejs/node-core-utils [set up the credentials]: https://github.com/nodejs/node-core-utils#setting-up-github-credentials [static-analysis]: doc/contributing/static-analysis.md [two-factor authentication]: https://help.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/ diff --git a/pyproject.toml b/pyproject.toml index 6b51197ad66c2e..d0c3a056f2e92c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ select = [ exclude = [ "deps", "tools/inspector_protocol", + "tools/node_modules", ] ignore = [ "E401", diff --git a/src/README.md b/src/README.md index 15317f06ae0ca3..5853e1efa2396b 100644 --- a/src/README.md +++ b/src/README.md @@ -574,8 +574,7 @@ void InitializeHttpParser(Local target, Local context, void* priv) { Realm* realm = Realm::GetCurrent(context); - BindingData* const binding_data = - realm->AddBindingData(context, target); + BindingData* const binding_data = realm->AddBindingData(target); if (binding_data == nullptr) return; Local t = NewFunctionTemplate(realm->isolate(), Parser::New); diff --git a/src/api/environment.cc b/src/api/environment.cc index 2128ca6c4ebb75..6a6164b6d29443 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -408,8 +408,6 @@ void FreeIsolateData(IsolateData* isolate_data) { delete isolate_data; } -InspectorParentHandle::~InspectorParentHandle() {} - // Hide the internal handle class from the public API. #if HAVE_INSPECTOR struct InspectorParentHandleImpl : public InspectorParentHandle { diff --git a/src/base_object-inl.h b/src/base_object-inl.h index 99a438a4963717..2ca432e2dfd3c6 100644 --- a/src/base_object-inl.h +++ b/src/base_object-inl.h @@ -70,23 +70,28 @@ Realm* BaseObject::realm() const { return realm_; } -bool BaseObject::IsBaseObject(v8::Local obj) { +bool BaseObject::IsBaseObject(IsolateData* isolate_data, + v8::Local obj) { if (obj->InternalFieldCount() < BaseObject::kInternalFieldCount) { return false; } - void* ptr = - obj->GetAlignedPointerFromInternalField(BaseObject::kEmbedderType); - return ptr == &kNodeEmbedderId; + + uint16_t* ptr = static_cast( + obj->GetAlignedPointerFromInternalField(BaseObject::kEmbedderType)); + return ptr == isolate_data->embedder_id_for_non_cppgc(); } -void BaseObject::TagBaseObject(v8::Local object) { +void BaseObject::TagBaseObject(IsolateData* isolate_data, + v8::Local object) { DCHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount); - object->SetAlignedPointerInInternalField(BaseObject::kEmbedderType, - &kNodeEmbedderId); + object->SetAlignedPointerInInternalField( + BaseObject::kEmbedderType, isolate_data->embedder_id_for_non_cppgc()); } -void BaseObject::SetInternalFields(v8::Local object, void* slot) { - TagBaseObject(object); +void BaseObject::SetInternalFields(IsolateData* isolate_data, + v8::Local object, + void* slot) { + TagBaseObject(isolate_data, object); object->SetAlignedPointerInInternalField(BaseObject::kSlot, slot); } @@ -130,7 +135,8 @@ template void BaseObject::InternalFieldGet( v8::Local property, const v8::PropertyCallbackInfo& info) { - info.GetReturnValue().Set(info.This()->GetInternalField(Field)); + info.GetReturnValue().Set( + info.This()->GetInternalField(Field).As()); } template diff --git a/src/base_object.cc b/src/base_object.cc index 9fb3efe03869ab..58ceecca2f91d7 100644 --- a/src/base_object.cc +++ b/src/base_object.cc @@ -22,7 +22,7 @@ BaseObject::BaseObject(Realm* realm, Local object) : persistent_handle_(realm->isolate(), object), realm_(realm) { CHECK_EQ(false, object.IsEmpty()); CHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount); - SetInternalFields(object, static_cast(this)); + SetInternalFields(realm->isolate_data(), object, static_cast(this)); realm->AddCleanupHook(DeleteMe, static_cast(this)); realm->modify_base_object_count(1); } @@ -71,18 +71,13 @@ void BaseObject::MakeWeak() { WeakCallbackType::kParameter); } -// This just has to be different from the Chromium ones: -// https://source.chromium.org/chromium/chromium/src/+/main:gin/public/gin_embedders.h;l=18-23;drc=5a758a97032f0b656c3c36a3497560762495501a -// Otherwise, when Node is loaded in an isolate which uses cppgc, cppgc will -// misinterpret the data stored in the embedder fields and try to garbage -// collect them. -uint16_t kNodeEmbedderId = 0x90de; - void BaseObject::LazilyInitializedJSTemplateConstructor( const FunctionCallbackInfo& args) { DCHECK(args.IsConstructCall()); CHECK_GE(args.This()->InternalFieldCount(), BaseObject::kInternalFieldCount); - SetInternalFields(args.This(), nullptr); + Environment* env = Environment::GetCurrent(args); + DCHECK_NOT_NULL(env); + SetInternalFields(env->isolate_data(), args.This(), nullptr); } Local BaseObject::MakeLazilyInitializedJSTemplate( diff --git a/src/base_object.h b/src/base_object.h index de66a83e7fff76..b0ada1d7f38fed 100644 --- a/src/base_object.h +++ b/src/base_object.h @@ -41,8 +41,6 @@ namespace worker { class TransferData; } -extern uint16_t kNodeEmbedderId; - class BaseObject : public MemoryRetainer { public: enum InternalFields { kEmbedderType, kSlot, kInternalFieldCount }; @@ -74,10 +72,13 @@ class BaseObject : public MemoryRetainer { // was also passed to the `BaseObject()` constructor initially. // This may return `nullptr` if the C++ object has not been constructed yet, // e.g. when the JS object used `MakeLazilyInitializedJSTemplate`. - static inline void SetInternalFields(v8::Local object, + static inline void SetInternalFields(IsolateData* isolate_data, + v8::Local object, void* slot); - static inline bool IsBaseObject(v8::Local object); - static inline void TagBaseObject(v8::Local object); + static inline bool IsBaseObject(IsolateData* isolate_data, + v8::Local object); + static inline void TagBaseObject(IsolateData* isolate_data, + v8::Local object); static void LazilyInitializedJSTemplateConstructor( const v8::FunctionCallbackInfo& args); static inline BaseObject* FromJSObject(v8::Local object); diff --git a/src/base_object_types.h b/src/base_object_types.h index bb7a0e064b0b72..cb034f1d62b681 100644 --- a/src/base_object_types.h +++ b/src/base_object_types.h @@ -28,8 +28,7 @@ namespace node { // The first argument should match what the type passes to // SET_OBJECT_ID(), the second argument should match the C++ class // name. -#define SERIALIZABLE_NON_BINDING_TYPES(V) \ - V(util_weak_reference, util::WeakReference) +#define SERIALIZABLE_NON_BINDING_TYPES(V) // Helper list of all binding data wrapper types. #define BINDING_TYPES(V) \ diff --git a/src/blob_serializer_deserializer.h b/src/blob_serializer_deserializer.h index aa07bee54fd1bc..fe7989e22a3536 100644 --- a/src/blob_serializer_deserializer.h +++ b/src/blob_serializer_deserializer.h @@ -39,7 +39,7 @@ class BlobDeserializer : public BlobSerializerDeserializer { public: explicit BlobDeserializer(bool is_debug_v, std::string_view s) : BlobSerializerDeserializer(is_debug_v), sink(s) {} - ~BlobDeserializer() {} + ~BlobDeserializer() = default; size_t read_total = 0; std::string_view sink; @@ -85,7 +85,7 @@ class BlobSerializer : public BlobSerializerDeserializer { public: explicit BlobSerializer(bool is_debug_v) : BlobSerializerDeserializer(is_debug_v) {} - ~BlobSerializer() {} + ~BlobSerializer() = default; Impl* impl() { return static_cast(this); } const Impl* impl() const { return static_cast(this); } diff --git a/src/callback_queue.h b/src/callback_queue.h index e5694d5e1fe56a..9b649c04d7e106 100644 --- a/src/callback_queue.h +++ b/src/callback_queue.h @@ -4,6 +4,7 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include +#include namespace node { diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 96aee6df99850f..8b037356360729 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); - return 0; + return ARES_SUCCESS; } int ATraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_a); - return 0; + return ARES_SUCCESS; } int AaaaTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_aaaa); - return 0; + return ARES_SUCCESS; } int CaaTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, T_CAA); - return 0; + return ARES_SUCCESS; } int CnameTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_cname); - return 0; + return ARES_SUCCESS; } int MxTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_mx); - return 0; + return ARES_SUCCESS; } int NsTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_ns); - return 0; + return ARES_SUCCESS; } int TxtTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_txt); - return 0; + return ARES_SUCCESS; } int SrvTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_srv); - return 0; + return ARES_SUCCESS; } int PtrTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_ptr); - return 0; + return ARES_SUCCESS; } int NaptrTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_naptr); - return 0; + return ARES_SUCCESS; } int SoaTraits::Send(QueryWrap* wrap, const char* name) { wrap->AresQuery(name, ns_c_in, ns_t_soa); - return 0; + return ARES_SUCCESS; } int AnyTraits::Parse( @@ -1052,7 +1052,7 @@ int AnyTraits::Parse( return status; wrap->CallOnComplete(ret); - return 0; + return ARES_SUCCESS; } int ATraits::Parse( @@ -1086,7 +1086,7 @@ int ATraits::Parse( Local ttls = AddrTTLToArray(env, addrttls, naddrttls); wrap->CallOnComplete(ret, ttls); - return 0; + return ARES_SUCCESS; } int AaaaTraits::Parse( @@ -1120,7 +1120,7 @@ int AaaaTraits::Parse( Local ttls = AddrTTLToArray(env, addrttls, naddrttls); wrap->CallOnComplete(ret, ttls); - return 0; + return ARES_SUCCESS; } int CaaTraits::Parse( @@ -1142,7 +1142,7 @@ int CaaTraits::Parse( return status; wrap->CallOnComplete(ret); - return 0; + return ARES_SUCCESS; } int CnameTraits::Parse( @@ -1165,7 +1165,7 @@ int CnameTraits::Parse( return status; wrap->CallOnComplete(ret); - return 0; + return ARES_SUCCESS; } int MxTraits::Parse( @@ -1188,7 +1188,7 @@ int MxTraits::Parse( return status; wrap->CallOnComplete(mx_records); - return 0; + return ARES_SUCCESS; } int NsTraits::Parse( @@ -1211,7 +1211,7 @@ int NsTraits::Parse( return status; wrap->CallOnComplete(names); - return 0; + return ARES_SUCCESS; } int TxtTraits::Parse( @@ -1233,7 +1233,7 @@ int TxtTraits::Parse( return status; wrap->CallOnComplete(txt_records); - return 0; + return ARES_SUCCESS; } int SrvTraits::Parse( @@ -1255,7 +1255,7 @@ int SrvTraits::Parse( return status; wrap->CallOnComplete(srv_records); - return 0; + return ARES_SUCCESS; } int PtrTraits::Parse( @@ -1279,7 +1279,7 @@ int PtrTraits::Parse( return status; wrap->CallOnComplete(aliases); - return 0; + return ARES_SUCCESS; } int NaptrTraits::Parse( @@ -1301,7 +1301,7 @@ int NaptrTraits::Parse( return status; wrap->CallOnComplete(naptr_records); - return 0; + return ARES_SUCCESS; } int SoaTraits::Parse( @@ -1352,7 +1352,7 @@ int SoaTraits::Parse( ares_free_data(soa_out); wrap->CallOnComplete(soa_record); - return 0; + return ARES_SUCCESS; } int ReverseTraits::Send(GetHostByAddrWrap* wrap, const char* name) { @@ -1381,7 +1381,7 @@ int ReverseTraits::Send(GetHostByAddrWrap* wrap, const char* name) { family, GetHostByAddrWrap::Callback, wrap->MakeCallbackPointer()); - return 0; + return ARES_SUCCESS; } int ReverseTraits::Parse( @@ -1396,7 +1396,7 @@ int ReverseTraits::Parse( HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); wrap->CallOnComplete(HostentToNames(env, host)); - return 0; + return ARES_SUCCESS; } namespace { diff --git a/src/cleanup_queue-inl.h b/src/cleanup_queue-inl.h index d1fbd8241d9919..dad23ecf3aec24 100644 --- a/src/cleanup_queue-inl.h +++ b/src/cleanup_queue-inl.h @@ -26,8 +26,8 @@ bool CleanupQueue::empty() const { } void CleanupQueue::Add(Callback cb, void* arg) { - auto insertion_info = cleanup_hooks_.emplace( - CleanupHookCallback{cb, arg, cleanup_hook_counter_++}); + auto insertion_info = + cleanup_hooks_.emplace(cb, arg, cleanup_hook_counter_++); // Make sure there was no existing element with these values. CHECK_EQ(insertion_info.second, true); } diff --git a/src/cleanup_queue.h b/src/cleanup_queue.h index 2ca333aca855ff..15451ab9473c81 100644 --- a/src/cleanup_queue.h +++ b/src/cleanup_queue.h @@ -18,7 +18,7 @@ class CleanupQueue : public MemoryRetainer { public: typedef void (*Callback)(void*); - CleanupQueue() {} + CleanupQueue() = default; // Not copyable. CleanupQueue(const CleanupQueue&) = delete; diff --git a/src/crypto/crypto_aes.cc b/src/crypto/crypto_aes.cc index c1c5bf762a765f..de058d077d1f45 100644 --- a/src/crypto/crypto_aes.cc +++ b/src/crypto/crypto_aes.cc @@ -381,7 +381,7 @@ bool ValidateAuthTag( AESCipherConfig* params) { switch (cipher_mode) { case kWebCryptoCipherDecrypt: { - if (!IsAnyByteSource(value)) { + if (!IsAnyBufferSource(value)) { THROW_ERR_CRYPTO_INVALID_TAG_LENGTH(env); return false; } @@ -419,7 +419,7 @@ bool ValidateAdditionalData( Local value, AESCipherConfig* params) { // Additional Data - if (IsAnyByteSource(value)) { + if (IsAnyBufferSource(value)) { ArrayBufferOrViewContents additional(value); if (UNLIKELY(!additional.CheckSizeInt32())) { THROW_ERR_OUT_OF_RANGE(env, "additionalData is too big"); diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc index 415464be04db6b..860d5048db7611 100644 --- a/src/crypto/crypto_ec.cc +++ b/src/crypto/crypto_ec.cc @@ -130,8 +130,6 @@ void ECDH::MemoryInfo(MemoryTracker* tracker) const { tracker->TrackFieldWithSize("key", key_ ? kSizeOf_EC_KEY : 0); } -ECDH::~ECDH() {} - void ECDH::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -195,7 +193,7 @@ ECPointPointer ECDH::BufferToPoint(Environment* env, void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - CHECK(IsAnyByteSource(args[0])); + CHECK(IsAnyBufferSource(args[0])); ECDH* ecdh; ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); @@ -349,7 +347,7 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo& args) { ECDH* ecdh; ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); - CHECK(IsAnyByteSource(args[0])); + CHECK(IsAnyBufferSource(args[0])); MarkPopErrorOnReturn mark_pop_error_on_return; @@ -395,7 +393,7 @@ void ECDH::ConvertKey(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK_EQ(args.Length(), 3); - CHECK(IsAnyByteSource(args[0])); + CHECK(IsAnyBufferSource(args[0])); ArrayBufferOrViewContents args0(args[0]); if (UNLIKELY(!args0.CheckSizeInt32())) diff --git a/src/crypto/crypto_ec.h b/src/crypto/crypto_ec.h index 9782ce0bf35a66..f9570bd41f92eb 100644 --- a/src/crypto/crypto_ec.h +++ b/src/crypto/crypto_ec.h @@ -20,7 +20,7 @@ int GetOKPCurveFromName(const char* name); class ECDH final : public BaseObject { public: - ~ECDH() override; + ~ECDH() override = default; static void Initialize(Environment* env, v8::Local target); static void RegisterExternalReferences(ExternalReferenceRegistry* registry); diff --git a/src/crypto/crypto_hkdf.cc b/src/crypto/crypto_hkdf.cc index 7663dd69374db7..0dd9b42473ca73 100644 --- a/src/crypto/crypto_hkdf.cc +++ b/src/crypto/crypto_hkdf.cc @@ -51,8 +51,8 @@ Maybe HKDFTraits::AdditionalConfig( CHECK(args[offset]->IsString()); // Hash CHECK(args[offset + 1]->IsObject()); // Key - CHECK(IsAnyByteSource(args[offset + 2])); // Salt - CHECK(IsAnyByteSource(args[offset + 3])); // Info + CHECK(IsAnyBufferSource(args[offset + 2])); // Salt + CHECK(IsAnyBufferSource(args[offset + 3])); // Info CHECK(args[offset + 4]->IsUint32()); // Length Utf8Value hash(env->isolate(), args[offset]); diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index 1b8e9b25a6991b..8d2774ff61a64c 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -699,7 +699,7 @@ ManagedEVPPKey::GetPrivateKeyEncodingFromJs( (*offset)++; } - if (IsAnyByteSource(args[*offset])) { + if (IsAnyBufferSource(args[*offset])) { CHECK_IMPLIES(context != kKeyContextInput, result.cipher_ != nullptr); ArrayBufferOrViewContents passphrase(args[*offset]); if (UNLIKELY(!passphrase.CheckSizeInt32())) { @@ -730,7 +730,7 @@ ManagedEVPPKey ManagedEVPPKey::GetPrivateKeyFromJs( const FunctionCallbackInfo& args, unsigned int* offset, bool allow_key_object) { - if (args[*offset]->IsString() || IsAnyByteSource(args[*offset])) { + if (args[*offset]->IsString() || IsAnyBufferSource(args[*offset])) { Environment* env = Environment::GetCurrent(args); ByteSource key = ByteSource::FromStringOrBuffer(env, args[(*offset)++]); NonCopyableMaybe config = @@ -756,7 +756,7 @@ ManagedEVPPKey ManagedEVPPKey::GetPrivateKeyFromJs( ManagedEVPPKey ManagedEVPPKey::GetPublicOrPrivateKeyFromJs( const FunctionCallbackInfo& args, unsigned int* offset) { - if (IsAnyByteSource(args[*offset])) { + if (IsAnyBufferSource(args[*offset])) { Environment* env = Environment::GetCurrent(args); ArrayBufferOrViewContents data(args[(*offset)++]); if (UNLIKELY(!data.CheckSizeInt32())) { diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc index 9850104cd607f8..245f3529186964 100644 --- a/src/crypto/crypto_random.cc +++ b/src/crypto/crypto_random.cc @@ -39,7 +39,7 @@ Maybe RandomBytesTraits::AdditionalConfig( const FunctionCallbackInfo& args, unsigned int offset, RandomBytesConfig* params) { - CHECK(IsAnyByteSource(args[offset])); // Buffer to fill + CHECK(IsAnyBufferSource(args[offset])); // Buffer to fill CHECK(args[offset + 1]->IsUint32()); // Offset CHECK(args[offset + 2]->IsUint32()); // Size diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index 47a42246eddfc7..3f8499457cf107 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -321,7 +321,7 @@ Maybe RSACipherTraits::AdditionalConfig( return Nothing(); } - if (IsAnyByteSource(args[offset + 2])) { + if (IsAnyBufferSource(args[offset + 2])) { ArrayBufferOrViewContents label(args[offset + 2]); if (UNLIKELY(!label.CheckSizeInt32())) { THROW_ERR_OUT_OF_RANGE(env, "label is too big"); diff --git a/src/crypto/crypto_timing.cc b/src/crypto/crypto_timing.cc index 8904f6b140dbb5..3d876fc4c3035f 100644 --- a/src/crypto/crypto_timing.cc +++ b/src/crypto/crypto_timing.cc @@ -21,13 +21,13 @@ void TimingSafeEqual(const FunctionCallbackInfo& args) { // to V8 inlining certain parts of the wrapper. Therefore, keep them in C++. // Refs: https://github.com/nodejs/node/issues/34073. Environment* env = Environment::GetCurrent(args); - if (!IsAnyByteSource(args[0])) { + if (!IsAnyBufferSource(args[0])) { THROW_ERR_INVALID_ARG_TYPE( env, "The \"buf1\" argument must be an instance of " "ArrayBuffer, Buffer, TypedArray, or DataView."); return; } - if (!IsAnyByteSource(args[1])) { + if (!IsAnyBufferSource(args[1])) { THROW_ERR_INVALID_ARG_TYPE( env, "The \"buf2\" argument must be an instance of " "ArrayBuffer, Buffer, TypedArray, or DataView."); diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index 028b251b3e7799..43a661cca7c313 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -357,12 +357,15 @@ TLSWrap::TLSWrap(Environment* env, Local obj, Kind kind, StreamBase* stream, - SecureContext* sc) + SecureContext* sc, + UnderlyingStreamWriteStatus under_stream_ws) : AsyncWrap(env, obj, AsyncWrap::PROVIDER_TLSWRAP), StreamBase(env), env_(env), kind_(kind), - sc_(sc) { + sc_(sc), + has_active_write_issued_by_prev_listener_( + under_stream_ws == UnderlyingStreamWriteStatus::kHasActive) { MakeWeak(); CHECK(sc_); ssl_ = sc_->CreateSSL(); @@ -472,14 +475,19 @@ void TLSWrap::InitSSL() { void TLSWrap::Wrap(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - CHECK_EQ(args.Length(), 3); + CHECK_EQ(args.Length(), 4); CHECK(args[0]->IsObject()); CHECK(args[1]->IsObject()); CHECK(args[2]->IsBoolean()); + CHECK(args[3]->IsBoolean()); Local sc = args[1].As(); Kind kind = args[2]->IsTrue() ? Kind::kServer : Kind::kClient; + UnderlyingStreamWriteStatus under_stream_ws = + args[3]->IsTrue() ? UnderlyingStreamWriteStatus::kHasActive + : UnderlyingStreamWriteStatus::kVacancy; + StreamBase* stream = StreamBase::FromObject(args[0].As()); CHECK_NOT_NULL(stream); @@ -490,7 +498,8 @@ void TLSWrap::Wrap(const FunctionCallbackInfo& args) { return; } - TLSWrap* res = new TLSWrap(env, obj, kind, stream, Unwrap(sc)); + TLSWrap* res = new TLSWrap( + env, obj, kind, stream, Unwrap(sc), under_stream_ws); args.GetReturnValue().Set(res->object()); } @@ -596,6 +605,13 @@ void TLSWrap::EncOut() { return; } + if (UNLIKELY(has_active_write_issued_by_prev_listener_)) { + Debug(this, + "Returning from EncOut(), " + "has_active_write_issued_by_prev_listener_ is true"); + return; + } + // Split-off queue if (established_ && current_write_) { Debug(this, "EncOut() write is scheduled"); @@ -666,6 +682,15 @@ void TLSWrap::EncOut() { void TLSWrap::OnStreamAfterWrite(WriteWrap* req_wrap, int status) { Debug(this, "OnStreamAfterWrite(status = %d)", status); + + if (UNLIKELY(has_active_write_issued_by_prev_listener_)) { + Debug(this, "Notify write finish to the previous_listener_"); + CHECK_EQ(write_size_, 0); // we must have restrained writes + + previous_listener_->OnStreamAfterWrite(req_wrap, status); + return; + } + if (current_empty_write_) { Debug(this, "Had empty write"); BaseObjectPtr current_empty_write = @@ -2021,6 +2046,16 @@ void TLSWrap::GetALPNNegotiatedProto(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(result); } +void TLSWrap::WritesIssuedByPrevListenerDone( + const FunctionCallbackInfo& args) { + TLSWrap* w; + ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); + + Debug(w, "WritesIssuedByPrevListenerDone is called"); + w->has_active_write_issued_by_prev_listener_ = false; + w->EncOut(); // resume all of our restrained writes +} + void TLSWrap::Cycle() { // Prevent recursion if (++cycle_depth_ > 1) @@ -2098,6 +2133,10 @@ void TLSWrap::Initialize( SetProtoMethod(isolate, t, "setSession", SetSession); SetProtoMethod(isolate, t, "setVerifyMode", SetVerifyMode); SetProtoMethod(isolate, t, "start", Start); + SetProtoMethod(isolate, + t, + "writesIssuedByPrevListenerDone", + WritesIssuedByPrevListenerDone); SetProtoMethodNoSideEffect( isolate, t, "exportKeyingMaterial", ExportKeyingMaterial); @@ -2180,6 +2219,7 @@ void TLSWrap::RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetSharedSigalgs); registry->Register(GetTLSTicket); registry->Register(VerifyError); + registry->Register(WritesIssuedByPrevListenerDone); #ifdef SSL_set_max_send_fragment registry->Register(SetMaxSendFragment); diff --git a/src/crypto/crypto_tls.h b/src/crypto/crypto_tls.h index a1a7f2ef240cc0..b65cea22255248 100644 --- a/src/crypto/crypto_tls.h +++ b/src/crypto/crypto_tls.h @@ -48,6 +48,8 @@ class TLSWrap : public AsyncWrap, kServer }; + enum class UnderlyingStreamWriteStatus { kHasActive, kVacancy }; + static void Initialize(v8::Local target, v8::Local unused, v8::Local context, @@ -136,7 +138,8 @@ class TLSWrap : public AsyncWrap, v8::Local obj, Kind kind, StreamBase* stream, - SecureContext* sc); + SecureContext* sc, + UnderlyingStreamWriteStatus under_stream_ws); static void SSLInfoCallback(const SSL* ssl_, int where, int ret); void InitSSL(); @@ -217,6 +220,8 @@ class TLSWrap : public AsyncWrap, static void Start(const v8::FunctionCallbackInfo& args); static void VerifyError(const v8::FunctionCallbackInfo& args); static void Wrap(const v8::FunctionCallbackInfo& args); + static void WritesIssuedByPrevListenerDone( + const v8::FunctionCallbackInfo& args); #ifdef SSL_set_max_send_fragment static void SetMaxSendFragment( @@ -284,6 +289,8 @@ class TLSWrap : public AsyncWrap, BIOPointer bio_trace_; + bool has_active_write_issued_by_prev_listener_ = false; + public: std::vector alpn_protos_; // Accessed by SelectALPNCallback. bool alpn_callback_enabled_ = false; // Accessed by SelectALPNCallback. diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc index 8cc62279fabbab..5734d8fdc5505e 100644 --- a/src/crypto/crypto_util.cc +++ b/src/crypto/crypto_util.cc @@ -402,8 +402,8 @@ ByteSource ByteSource::FromEncodedString(Environment* env, ByteSource ByteSource::FromStringOrBuffer(Environment* env, Local value) { - return IsAnyByteSource(value) ? FromBuffer(value) - : FromString(env, value.As()); + return IsAnyBufferSource(value) ? FromBuffer(value) + : FromString(env, value.As()); } ByteSource ByteSource::FromString(Environment* env, Local str, @@ -429,9 +429,9 @@ ByteSource ByteSource::FromSecretKeyBytes( // A key can be passed as a string, buffer or KeyObject with type 'secret'. // If it is a string, we need to convert it to a buffer. We are not doing that // in JS to avoid creating an unprotected copy on the heap. - return value->IsString() || IsAnyByteSource(value) ? - ByteSource::FromStringOrBuffer(env, value) : - ByteSource::FromSymmetricKeyObjectHandle(value); + return value->IsString() || IsAnyBufferSource(value) + ? ByteSource::FromStringOrBuffer(env, value) + : ByteSource::FromSymmetricKeyObjectHandle(value); } ByteSource ByteSource::NullTerminatedCopy(Environment* env, diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index bf19334cf61fa4..1ce5f35a70a7c8 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -676,7 +676,8 @@ void array_push_back(const TypeName* evp_ref, } #endif -inline bool IsAnyByteSource(v8::Local arg) { +// WebIDL AllowSharedBufferSource. +inline bool IsAnyBufferSource(v8::Local arg) { return arg->IsArrayBufferView() || arg->IsArrayBuffer() || arg->IsSharedArrayBuffer(); @@ -694,7 +695,7 @@ class ArrayBufferOrViewContents { return; } - CHECK(IsAnyByteSource(buf)); + CHECK(IsAnyBufferSource(buf)); if (buf->IsArrayBufferView()) { auto view = buf.As(); offset_ = view->ByteOffset(); diff --git a/src/dataqueue/queue.cc b/src/dataqueue/queue.cc index 8ae28f9d0a791b..994b82a8751f6e 100644 --- a/src/dataqueue/queue.cc +++ b/src/dataqueue/queue.cc @@ -876,12 +876,12 @@ class FdEntry final : public EntryImpl { } Realm* realm = entry->env()->principal_realm(); return std::make_shared( - BaseObjectPtr(fs::FileHandle::New( - realm->GetBindingData(realm->context()), - file, - Local(), - entry->start_, - entry->end_ - entry->start_)), + BaseObjectPtr( + fs::FileHandle::New(realm->GetBindingData(), + file, + Local(), + entry->start_, + entry->end_ - entry->start_)), entry); } diff --git a/src/debug_utils.h b/src/debug_utils.h index 31c929f122cd1f..280b4cb39c780a 100644 --- a/src/debug_utils.h +++ b/src/debug_utils.h @@ -51,6 +51,7 @@ void NODE_EXTERN_PRIVATE FWrite(FILE* file, const std::string& str); V(SEA) \ V(WASI) \ V(MKSNAPSHOT) \ + V(SNAPSHOT_SERDES) \ V(PERMISSION_MODEL) enum class DebugCategory : unsigned int { diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc index 0cf588295405ac..97ddd59fb661c8 100644 --- a/src/encoding_binding.cc +++ b/src/encoding_binding.cc @@ -62,7 +62,7 @@ bool BindingData::PrepareForSerialization(Local context, } InternalFieldInfoBase* BindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = internal_field_info_; internal_field_info_ = nullptr; return info; @@ -72,23 +72,24 @@ void BindingData::Deserialize(Local context, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); v8::HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); // Recreate the buffer in the constructor. InternalFieldInfo* casted_info = static_cast(info); BindingData* binding = - realm->AddBindingData(context, holder, casted_info); + realm->AddBindingData(holder, casted_info); CHECK_NOT_NULL(binding); } void BindingData::EncodeInto(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - Isolate* isolate = env->isolate(); CHECK_GE(args.Length(), 2); CHECK(args[0]->IsString()); CHECK(args[1]->IsUint8Array()); - BindingData* binding_data = Realm::GetBindingData(args); + + Realm* realm = Realm::GetCurrent(args); + Isolate* isolate = realm->isolate(); + BindingData* binding_data = realm->GetBindingData(); Local source = args[0].As(); @@ -232,7 +233,7 @@ void BindingData::CreatePerContextProperties(Local target, Local context, void* priv) { Realm* realm = Realm::GetCurrent(context); - realm->AddBindingData(context, target); + realm->AddBindingData(target); } void BindingData::RegisterTimerExternalReferences( diff --git a/src/env-inl.h b/src/env-inl.h index 43fc11217133c2..793dc72e0dbad8 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -34,6 +34,7 @@ #include "node_realm-inl.h" #include "util-inl.h" #include "uv.h" +#include "v8-cppgc.h" #include "v8.h" #include @@ -61,6 +62,39 @@ inline uv_loop_t* IsolateData::event_loop() const { return event_loop_; } +inline void IsolateData::SetCppgcReference(v8::Isolate* isolate, + v8::Local object, + void* wrappable) { + v8::CppHeap* heap = isolate->GetCppHeap(); + CHECK_NOT_NULL(heap); + v8::WrapperDescriptor descriptor = heap->wrapper_descriptor(); + uint16_t required_size = std::max(descriptor.wrappable_instance_index, + descriptor.wrappable_type_index); + CHECK_GT(object->InternalFieldCount(), required_size); + + uint16_t* id_ptr = nullptr; + { + Mutex::ScopedLock lock(isolate_data_mutex_); + auto it = + wrapper_data_map_.find(descriptor.embedder_id_for_garbage_collected); + CHECK_NE(it, wrapper_data_map_.end()); + id_ptr = &(it->second->cppgc_id); + } + + object->SetAlignedPointerInInternalField(descriptor.wrappable_type_index, + id_ptr); + object->SetAlignedPointerInInternalField(descriptor.wrappable_instance_index, + wrappable); +} + +inline uint16_t* IsolateData::embedder_id_for_cppgc() const { + return &(wrapper_data_->cppgc_id); +} + +inline uint16_t* IsolateData::embedder_id_for_non_cppgc() const { + return &(wrapper_data_->non_cppgc_id); +} + inline NodeArrayBufferAllocator* IsolateData::node_allocator() const { return node_allocator_; } @@ -359,16 +393,6 @@ inline AliasedInt32Array& Environment::stream_base_state() { return stream_base_state_; } -inline uint32_t Environment::get_next_module_id() { - return module_id_counter_++; -} -inline uint32_t Environment::get_next_script_id() { - return script_id_counter_++; -} -inline uint32_t Environment::get_next_function_id() { - return function_id_counter_++; -} - ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope( Environment* env) : env_(env) { diff --git a/src/env.cc b/src/env.cc index 56f4344d9e1b5d..1d8df40c3446ac 100644 --- a/src/env.cc +++ b/src/env.cc @@ -12,6 +12,7 @@ #include "node_options-inl.h" #include "node_process-inl.h" #include "node_shadow_realm.h" +#include "node_snapshotable.h" #include "node_v8_platform-inl.h" #include "node_worker.h" #include "req_wrap-inl.h" @@ -19,6 +20,7 @@ #include "tracing/agent.h" #include "tracing/traced_value.h" #include "util-inl.h" +#include "v8-cppgc.h" #include "v8-profiler.h" #include @@ -28,6 +30,7 @@ #include #include #include +#include namespace node { @@ -35,6 +38,8 @@ using errors::TryCatchScope; using v8::Array; using v8::Boolean; using v8::Context; +using v8::CppHeap; +using v8::CppHeapCreateParams; using v8::EmbedderGraph; using v8::EscapableHandleScope; using v8::Function; @@ -59,6 +64,7 @@ using v8::TracingController; using v8::TryCatch; using v8::Undefined; using v8::Value; +using v8::WrapperDescriptor; using worker::Worker; int const ContextEmbedderTag::kNodeContextTag = 0x6e6f64; @@ -497,6 +503,11 @@ void IsolateData::CreateProperties() { contextify::ContextifyContext::InitializeGlobalTemplates(this); } +constexpr uint16_t kDefaultCppGCEmebdderID = 0x90de; +Mutex IsolateData::isolate_data_mutex_; +std::unordered_map> + IsolateData::wrapper_data_map_; + IsolateData::IsolateData(Isolate* isolate, uv_loop_t* event_loop, MultiIsolatePlatform* platform, @@ -510,6 +521,54 @@ IsolateData::IsolateData(Isolate* isolate, snapshot_data_(snapshot_data) { options_.reset( new PerIsolateOptions(*(per_process::cli_options->per_isolate))); + v8::CppHeap* cpp_heap = isolate->GetCppHeap(); + + uint16_t cppgc_id = kDefaultCppGCEmebdderID; + if (cpp_heap != nullptr) { + // The general convention of the wrappable layout for cppgc in the + // ecosystem is: + // [ 0 ] -> embedder id + // [ 1 ] -> wrappable instance + // If the Isolate includes a CppHeap attached by another embedder, + // And if they also use the field 0 for the ID, we DCHECK that + // the layout matches our layout, and record the embedder ID for cppgc + // to avoid accidentally enabling cppgc on non-cppgc-managed wrappers . + v8::WrapperDescriptor descriptor = cpp_heap->wrapper_descriptor(); + if (descriptor.wrappable_type_index == BaseObject::kEmbedderType) { + cppgc_id = descriptor.embedder_id_for_garbage_collected; + DCHECK_EQ(descriptor.wrappable_instance_index, BaseObject::kSlot); + } + // If the CppHeap uses the slot we use to put non-cppgc-traced BaseObject + // for embedder ID, V8 could accidentally enable cppgc on them. So + // safe guard against this. + DCHECK_NE(descriptor.wrappable_type_index, BaseObject::kSlot); + } else { + cpp_heap_ = CppHeap::Create( + platform, + CppHeapCreateParams{ + {}, + WrapperDescriptor( + BaseObject::kEmbedderType, BaseObject::kSlot, cppgc_id)}); + isolate->AttachCppHeap(cpp_heap_.get()); + } + // We do not care about overflow since we just want this to be different + // from the cppgc id. + uint16_t non_cppgc_id = cppgc_id + 1; + + { + // GC could still be run after the IsolateData is destroyed, so we store + // the ids in a static map to ensure pointers to them are still valid + // then. In practice there should be very few variants of the cppgc id + // in one process so the size of this map should be very small. + node::Mutex::ScopedLock lock(isolate_data_mutex_); + auto it = wrapper_data_map_.find(cppgc_id); + if (it == wrapper_data_map_.end()) { + auto pair = wrapper_data_map_.emplace( + cppgc_id, new PerIsolateWrapperData{cppgc_id, non_cppgc_id}); + it = pair.first; + } + wrapper_data_ = it->second.get(); + } if (snapshot_data == nullptr) { CreateProperties(); @@ -518,6 +577,21 @@ IsolateData::IsolateData(Isolate* isolate, } } +IsolateData::~IsolateData() { + if (cpp_heap_ != nullptr) { + // The CppHeap must be detached before being terminated. + isolate_->DetachCppHeap(); + cpp_heap_->Terminate(); + } +} + +// Public API +void SetCppgcReference(Isolate* isolate, + Local object, + void* wrappable) { + IsolateData::SetCppgcReference(isolate, object, wrappable); +} + void IsolateData::MemoryInfo(MemoryTracker* tracker) const { #define V(PropertyName, StringValue) \ tracker->TrackField(#PropertyName, PropertyName()); @@ -572,10 +646,6 @@ void Environment::AssignToContext(Local context, context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kEnvironment, this); context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kRealm, realm); - // Used to retrieve bindings - context->SetAlignedPointerInEmbedderData( - ContextEmbedderIndex::kBindingDataStoreIndex, - realm->binding_data_store()); // ContextifyContexts will update this to a pointer to the native object. context->SetAlignedPointerInEmbedderData( @@ -598,8 +668,6 @@ void Environment::UnassignFromContext(Local context) { nullptr); context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kRealm, nullptr); - context->SetAlignedPointerInEmbedderData( - ContextEmbedderIndex::kBindingDataStoreIndex, nullptr); context->SetAlignedPointerInEmbedderData( ContextEmbedderIndex::kContextifyContext, nullptr); } @@ -616,7 +684,7 @@ void Environment::TryLoadAddon( } } -std::string Environment::GetCwd() { +std::string Environment::GetCwd(const std::string& exec_path) { char cwd[PATH_MAX_BYTES]; size_t size = PATH_MAX_BYTES; const int err = uv_cwd(cwd, &size); @@ -628,7 +696,6 @@ std::string Environment::GetCwd() { // This can fail if the cwd is deleted. In that case, fall back to // exec_path. - const std::string& exec_path = exec_path_; return exec_path.substr(0, exec_path.find_last_of(kPathSeparator)); } @@ -662,7 +729,7 @@ std::unique_ptr Environment::release_managed_buffer( return bs; } -std::string GetExecPath(const std::vector& argv) { +std::string Environment::GetExecPath(const std::vector& argv) { char exec_path_buf[2 * PATH_MAX]; size_t exec_path_len = sizeof(exec_path_buf); std::string exec_path; @@ -704,7 +771,7 @@ Environment::Environment(IsolateData* isolate_data, timer_base_(uv_now(isolate_data->event_loop())), exec_argv_(exec_args), argv_(args), - exec_path_(GetExecPath(args)), + exec_path_(Environment::GetExecPath(args)), exit_info_( isolate_, kExitInfoFieldCount, MAYBE_FIELD_PTR(env_info, exit_info)), should_abort_on_uncaught_toggle_( @@ -783,7 +850,7 @@ Environment::Environment(IsolateData* isolate_data, destroy_async_id_list_.reserve(512); performance_state_ = std::make_unique( - isolate, MAYBE_FIELD_PTR(env_info, performance_state)); + isolate, time_origin_, MAYBE_FIELD_PTR(env_info, performance_state)); if (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( TRACING_CATEGORY_NODE1(environment)) != 0) { @@ -803,19 +870,17 @@ Environment::Environment(IsolateData* isolate_data, if (options_->experimental_permission) { permission()->EnablePermissions(); - // If any permission is set the process shouldn't be able to neither + // The process shouldn't be able to neither // spawn/worker nor use addons or enable inspector // unless explicitly allowed by the user - if (!options_->allow_fs_read.empty() || !options_->allow_fs_write.empty()) { - options_->allow_native_addons = false; - flags_ = flags_ | EnvironmentFlags::kNoCreateInspector; - permission()->Apply("*", permission::PermissionScope::kInspector); - if (!options_->allow_child_process) { - permission()->Apply("*", permission::PermissionScope::kChildProcess); - } - if (!options_->allow_worker_threads) { - permission()->Apply("*", permission::PermissionScope::kWorkerThreads); - } + options_->allow_native_addons = false; + flags_ = flags_ | EnvironmentFlags::kNoCreateInspector; + permission()->Apply({"*"}, permission::PermissionScope::kInspector); + if (!options_->allow_child_process) { + permission()->Apply({"*"}, permission::PermissionScope::kChildProcess); + } + if (!options_->allow_worker_threads) { + permission()->Apply({"*"}, permission::PermissionScope::kWorkerThreads); } if (!options_->allow_fs_read.empty()) { @@ -1696,7 +1761,7 @@ void Environment::EnqueueDeserializeRequest(DeserializeRequestCallback cb, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); DeserializeRequest request{cb, {isolate(), holder}, index, info}; deserialize_requests_.push_back(std::move(request)); } @@ -1732,7 +1797,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) { immediate_info_.Deserialize(ctx); timeout_info_.Deserialize(ctx); tick_info_.Deserialize(ctx); - performance_state_->Deserialize(ctx); + performance_state_->Deserialize(ctx, time_origin_); exit_info_.Deserialize(ctx); stream_base_state_.Deserialize(ctx); should_abort_on_uncaught_toggle_.Deserialize(ctx); @@ -1856,7 +1921,7 @@ size_t Environment::NearHeapLimitCallback(void* data, std::string dir = env->options()->diagnostic_dir; if (dir.empty()) { - dir = env->GetCwd(); + dir = Environment::GetCwd(env->exec_path_); } DiagnosticFilename name(env, "Heap", "heapsnapshot"); std::string filename = dir + kPathSeparator + (*name); diff --git a/src/env.h b/src/env.h index 231ca64db38e90..afe67d2237ae69 100644 --- a/src/env.h +++ b/src/env.h @@ -62,6 +62,10 @@ #include #include +namespace v8 { +class CppHeap; +} + namespace node { namespace shadow_realm { @@ -124,6 +128,11 @@ struct IsolateDataSerializeInfo { const IsolateDataSerializeInfo& i); }; +struct PerIsolateWrapperData { + uint16_t cppgc_id; + uint16_t non_cppgc_id; +}; + class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { public: IsolateData(v8::Isolate* isolate, @@ -131,6 +140,8 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { MultiIsolatePlatform* platform = nullptr, ArrayBufferAllocator* node_allocator = nullptr, const SnapshotData* snapshot_data = nullptr); + ~IsolateData(); + SET_MEMORY_INFO_NAME(IsolateData) SET_SELF_SIZE(IsolateData) void MemoryInfo(MemoryTracker* tracker) const override; @@ -139,6 +150,13 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { bool is_building_snapshot() const { return is_building_snapshot_; } void set_is_building_snapshot(bool value) { is_building_snapshot_ = value; } + uint16_t* embedder_id_for_cppgc() const; + uint16_t* embedder_id_for_non_cppgc() const; + + static inline void SetCppgcReference(v8::Isolate* isolate, + v8::Local object, + void* wrappable); + inline uv_loop_t* event_loop() const; inline MultiIsolatePlatform* platform() const; inline const SnapshotData* snapshot_data() const; @@ -220,9 +238,15 @@ class NODE_EXTERN_PRIVATE IsolateData : public MemoryRetainer { NodeArrayBufferAllocator* const node_allocator_; MultiIsolatePlatform* platform_; const SnapshotData* snapshot_data_; + std::unique_ptr cpp_heap_; std::shared_ptr options_; worker::Worker* worker_context_ = nullptr; bool is_building_snapshot_ = false; + PerIsolateWrapperData* wrapper_data_; + + static Mutex isolate_data_mutex_; + static std::unordered_map> + wrapper_data_map_; }; struct ContextInfo { @@ -564,6 +588,9 @@ class Environment : public MemoryRetainer { SET_MEMORY_INFO_NAME(Environment) + static std::string GetExecPath(const std::vector& argv); + static std::string GetCwd(const std::string& exec_path); + inline size_t SelfSize() const override; bool IsRootNode() const override { return true; } void MemoryInfo(MemoryTracker* tracker) const override; @@ -580,8 +607,6 @@ class Environment : public MemoryRetainer { // Should be called before InitializeInspector() void InitializeDiagnostics(); - std::string GetCwd(); - #if HAVE_INSPECTOR // If the environment is created for a worker, pass parent_handle and // the ownership if transferred into the Environment. @@ -721,14 +746,6 @@ class Environment : public MemoryRetainer { builtins::BuiltinLoader* builtin_loader(); std::unordered_multimap hash_to_module_map; - std::unordered_map id_to_module_map; - std::unordered_map - id_to_script_map; - std::unordered_map id_to_function_map; - - inline uint32_t get_next_module_id(); - inline uint32_t get_next_script_id(); - inline uint32_t get_next_function_id(); EnabledDebugList* enabled_debug_list() { return &enabled_debug_list_; } diff --git a/src/env_properties.h b/src/env_properties.h index 687422d1a4fb0b..db471d4efb8d1d 100644 --- a/src/env_properties.h +++ b/src/env_properties.h @@ -22,6 +22,7 @@ V(contextify_context_private_symbol, "node:contextify:context") \ V(decorated_private_symbol, "node:decorated") \ V(transfer_mode_private_symbol, "node:transfer_mode") \ + V(host_defined_option_symbol, "node:host_defined_option_symbol") \ V(js_transferable_wrapper_private_symbol, "node:js_transferable_wrapper") \ V(napi_type_tag, "node:napi:type_tag") \ V(napi_wrapper, "node:napi:wrapper") \ @@ -342,7 +343,6 @@ V(blocklist_constructor_template, v8::FunctionTemplate) \ V(contextify_global_template, v8::ObjectTemplate) \ V(contextify_wrapper_template, v8::ObjectTemplate) \ - V(compiled_fn_entry_template, v8::ObjectTemplate) \ V(crypto_key_object_handle_constructor, v8::FunctionTemplate) \ V(env_proxy_template, v8::ObjectTemplate) \ V(env_proxy_ctor_template, v8::FunctionTemplate) \ diff --git a/src/heap_utils.cc b/src/heap_utils.cc index b423d97345e956..e385955a5d5fce 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -456,7 +456,9 @@ void TriggerHeapSnapshot(const FunctionCallbackInfo& args) { if (filename_v->IsUndefined()) { DiagnosticFilename name(env, "Heap", "heapsnapshot"); THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, env->GetCwd()); + env, + permission::PermissionScope::kFileSystemWrite, + Environment::GetCwd(env->exec_path())); if (WriteSnapshot(env, *name, options).IsNothing()) return; if (String::NewFromUtf8(isolate, *name).ToLocal(&filename_v)) { args.GetReturnValue().Set(filename_v); diff --git a/src/inspector/node_string.cc b/src/inspector/node_string.cc index 6b59cd73f9742d..0f780f46c8ebdd 100644 --- a/src/inspector/node_string.cc +++ b/src/inspector/node_string.cc @@ -1,6 +1,5 @@ #include "node_string.h" #include "node/inspector/protocol/Protocol.h" -#include "node_util.h" #include "simdutf.h" #include "util-inl.h" diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index fe1e573242f6e2..f0b4cc43c864ae 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -687,7 +687,7 @@ Agent::Agent(Environment* env) debug_options_(env->options()->debug_options()), host_port_(env->inspector_host_port()) {} -Agent::~Agent() {} +Agent::~Agent() = default; bool Agent::Start(const std::string& path, const DebugOptions& options, diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index 56e588ceefa17a..307049bf7c83c5 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -431,7 +431,8 @@ void StartProfilers(Environment* env) { if (env->options()->cpu_prof) { const std::string& dir = env->options()->cpu_prof_dir; env->set_cpu_prof_interval(env->options()->cpu_prof_interval); - env->set_cpu_prof_dir(dir.empty() ? env->GetCwd() : dir); + env->set_cpu_prof_dir(dir.empty() ? Environment::GetCwd(env->exec_path()) + : dir); if (env->options()->cpu_prof_name.empty()) { DiagnosticFilename filename(env, "CPU", "cpuprofile"); env->set_cpu_prof_name(*filename); @@ -446,7 +447,8 @@ void StartProfilers(Environment* env) { if (env->options()->heap_prof) { const std::string& dir = env->options()->heap_prof_dir; env->set_heap_prof_interval(env->options()->heap_prof_interval); - env->set_heap_prof_dir(dir.empty() ? env->GetCwd() : dir); + env->set_heap_prof_dir(dir.empty() ? Environment::GetCwd(env->exec_path()) + : dir); if (env->options()->heap_prof_name.empty()) { DiagnosticFilename filename(env, "Heap", "heapprofile"); env->set_heap_prof_name(*filename); diff --git a/src/js_native_api_v8.h b/src/js_native_api_v8.h index f7646778311bfd..1ac738af2adb88 100644 --- a/src/js_native_api_v8.h +++ b/src/js_native_api_v8.h @@ -10,8 +10,8 @@ namespace v8impl { class RefTracker { public: - RefTracker() {} - virtual ~RefTracker() {} + RefTracker() = default; + virtual ~RefTracker() = default; virtual void Finalize() {} typedef RefTracker RefList; @@ -268,14 +268,6 @@ inline napi_status napi_set_last_error(napi_env env, } \ } while (0) -#define RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env, condition, status) \ - do { \ - if (!(condition)) { \ - return napi_set_last_error( \ - (env), try_catch.HasCaught() ? napi_pending_exception : (status)); \ - } \ - } while (0) - #define CHECK_MAYBE_EMPTY_WITH_PREAMBLE(env, maybe, status) \ RETURN_STATUS_IF_FALSE_WITH_PREAMBLE((env), !((maybe).IsEmpty()), (status)) diff --git a/src/json_parser.cc b/src/json_parser.cc index a9973c099087e5..1e19e174833fa5 100644 --- a/src/json_parser.cc +++ b/src/json_parser.cc @@ -4,7 +4,6 @@ #include "util-inl.h" namespace node { -using v8::ArrayBuffer; using v8::Context; using v8::Isolate; using v8::Local; @@ -12,26 +11,8 @@ using v8::Object; using v8::String; using v8::Value; -static Isolate* NewIsolate(v8::ArrayBuffer::Allocator* allocator) { - Isolate* isolate = Isolate::Allocate(); - CHECK_NOT_NULL(isolate); - per_process::v8_platform.Platform()->RegisterIsolate(isolate, - uv_default_loop()); - Isolate::CreateParams params; - params.array_buffer_allocator = allocator; - Isolate::Initialize(isolate, params); - return isolate; -} - -void JSONParser::FreeIsolate(Isolate* isolate) { - per_process::v8_platform.Platform()->UnregisterIsolate(isolate); - isolate->Dispose(); -} - JSONParser::JSONParser() - : allocator_(ArrayBuffer::Allocator::NewDefaultAllocator()), - isolate_(NewIsolate(allocator_.get())), - handle_scope_(isolate_.get()), + : handle_scope_(isolate_.get()), context_(isolate_.get(), Context::New(isolate_.get())), context_scope_(context_.Get(isolate_.get())) {} diff --git a/src/json_parser.h b/src/json_parser.h index 555f539acf3076..f2e7d592d9aaa7 100644 --- a/src/json_parser.h +++ b/src/json_parser.h @@ -16,7 +16,7 @@ namespace node { class JSONParser { public: JSONParser(); - ~JSONParser() {} + ~JSONParser() = default; bool Parse(const std::string& content); std::optional GetTopLevelStringField(std::string_view field); std::optional GetTopLevelBoolField(std::string_view field); @@ -24,9 +24,7 @@ class JSONParser { private: // We might want a lighter-weight JSON parser for this use case. But for now // using V8 is good enough. - static void FreeIsolate(v8::Isolate* isolate); - std::unique_ptr allocator_; - DeleteFnPtr isolate_; + RAIIIsolate isolate_; v8::HandleScope handle_scope_; v8::Global context_; v8::Context::Scope context_scope_; diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 77ee0dc9109ebb..9f40d679d1e83e 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -38,13 +38,13 @@ using v8::MaybeLocal; using v8::MicrotaskQueue; using v8::Module; using v8::ModuleRequest; -using v8::Number; using v8::Object; using v8::PrimitiveArray; using v8::Promise; using v8::ScriptCompiler; using v8::ScriptOrigin; using v8::String; +using v8::Symbol; using v8::UnboundModuleScript; using v8::Undefined; using v8::Value; @@ -52,23 +52,28 @@ using v8::Value; ModuleWrap::ModuleWrap(Environment* env, Local object, Local module, - Local url) - : BaseObject(env, object), - module_(env->isolate(), module), - id_(env->get_next_module_id()) { - env->id_to_module_map.emplace(id_, this); - - Local undefined = Undefined(env->isolate()); + Local url, + Local context_object, + Local synthetic_evaluation_step) + : BaseObject(env, object), + module_(env->isolate(), module), + module_hash_(module->GetIdentityHash()) { + object->SetInternalField(kModuleSlot, module); object->SetInternalField(kURLSlot, url); - object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined); - object->SetInternalField(kContextObjectSlot, undefined); + object->SetInternalField(kSyntheticEvaluationStepsSlot, + synthetic_evaluation_step); + object->SetInternalField(kContextObjectSlot, context_object); + + if (!synthetic_evaluation_step->IsUndefined()) { + synthetic_ = true; + } + MakeWeak(); + module_.SetWeak(); } ModuleWrap::~ModuleWrap() { HandleScope scope(env()->isolate()); - Local module = module_.Get(env()->isolate()); - env()->id_to_module_map.erase(id_); - auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash()); + auto range = env()->hash_to_module_map.equal_range(module_hash_); for (auto it = range.first; it != range.second; ++it) { if (it->second == this) { env()->hash_to_module_map.erase(it); @@ -78,8 +83,10 @@ ModuleWrap::~ModuleWrap() { } Local ModuleWrap::context() const { - Local obj = object()->GetInternalField(kContextObjectSlot); - if (obj.IsEmpty()) return {}; + Local obj = object()->GetInternalField(kContextObjectSlot).As(); + // If this fails, there is likely a bug e.g. ModuleWrap::context() is accessed + // before the ModuleWrap constructor completes. + CHECK(obj->IsObject()); return obj.As()->GetCreationContext().ToLocalChecked(); } @@ -94,14 +101,6 @@ ModuleWrap* ModuleWrap::GetFromModule(Environment* env, return nullptr; } -ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) { - auto module_wrap_it = env->id_to_module_map.find(id); - if (module_wrap_it == env->id_to_module_map.end()) { - return nullptr; - } - return module_wrap_it->second; -} - // new ModuleWrap(url, context, source, lineOffset, columnOffset) // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction) void ModuleWrap::New(const FunctionCallbackInfo& args) { @@ -146,8 +145,8 @@ void ModuleWrap::New(const FunctionCallbackInfo& args) { Local host_defined_options = PrimitiveArray::New(isolate, HostDefinedOptions::kLength); - host_defined_options->Set(isolate, HostDefinedOptions::kType, - Number::New(isolate, ScriptType::kModule)); + Local id_symbol = Symbol::New(isolate, url); + host_defined_options->Set(isolate, HostDefinedOptions::kID, id_symbol); ShouldNotAbortOnUncaughtScope no_abort_scope(env); TryCatchScope try_catch(env); @@ -227,25 +226,25 @@ void ModuleWrap::New(const FunctionCallbackInfo& args) { return; } - ModuleWrap* obj = new ModuleWrap(env, that, module, url); - - if (synthetic) { - obj->synthetic_ = true; - obj->object()->SetInternalField(kSyntheticEvaluationStepsSlot, args[3]); + if (that->SetPrivate(context, env->host_defined_option_symbol(), id_symbol) + .IsNothing()) { + return; } // Use the extras object as an object whose GetCreationContext() will be the // original `context`, since the `Context` itself strictly speaking cannot // be stored in an internal field. - obj->object()->SetInternalField(kContextObjectSlot, - context->GetExtrasBindingObject()); + Local context_object = context->GetExtrasBindingObject(); + Local synthetic_evaluation_step = + synthetic ? args[3] : Undefined(env->isolate()).As(); + + ModuleWrap* obj = new ModuleWrap( + env, that, module, url, context_object, synthetic_evaluation_step); + obj->contextify_context_ = contextify_context; env->hash_to_module_map.emplace(module->GetIdentityHash(), obj); - host_defined_options->Set(isolate, HostDefinedOptions::kID, - Number::New(isolate, obj->id())); - that->SetIntegrityLevel(context, IntegrityLevel::kFrozen); args.GetReturnValue().Set(that); } @@ -361,7 +360,7 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo& args) { Local module = obj->module_.Get(isolate); ContextifyContext* contextify_context = obj->contextify_context_; - std::shared_ptr microtask_queue; + MicrotaskQueue* microtask_queue = nullptr; if (contextify_context != nullptr) microtask_queue = contextify_context->microtask_queue(); @@ -578,37 +577,16 @@ static MaybeLocal ImportModuleDynamically( return handle_scope.Escape(resolver->GetPromise()); } - Local object; - - int type = options->Get(context, HostDefinedOptions::kType) - .As() - ->Int32Value(context) - .ToChecked(); - uint32_t id = options->Get(context, HostDefinedOptions::kID) - .As() - ->Uint32Value(context) - .ToChecked(); - if (type == ScriptType::kScript) { - contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second; - object = wrap->object(); - } else if (type == ScriptType::kModule) { - ModuleWrap* wrap = ModuleWrap::GetFromID(env, id); - object = wrap->object(); - } else if (type == ScriptType::kFunction) { - auto it = env->id_to_function_map.find(id); - CHECK_NE(it, env->id_to_function_map.end()); - object = it->second->object(); - } else { - UNREACHABLE(); - } + Local id = + options->Get(context, HostDefinedOptions::kID).As(); Local assertions = createImportAssertionContainer(env, isolate, import_assertions); Local import_args[] = { - object, - Local(specifier), - assertions, + id, + Local(specifier), + assertions, }; Local result; @@ -652,7 +630,13 @@ void ModuleWrap::HostInitializeImportMetaObjectCallback( Local wrap = module_wrap->object(); Local callback = env->host_initialize_import_meta_object_callback(); - Local args[] = { wrap, meta }; + Local id; + if (!wrap->GetPrivate(context, env->host_defined_option_symbol()) + .ToLocal(&id)) { + return; + } + DCHECK(id->IsSymbol()); + Local args[] = {id, meta}; TryCatchScope try_catch(env); USE(callback->Call( context, Undefined(env->isolate()), arraysize(args), args)); @@ -684,7 +668,9 @@ MaybeLocal ModuleWrap::SyntheticModuleEvaluationStepsCallback( TryCatchScope try_catch(env); Local synthetic_evaluation_steps = - obj->object()->GetInternalField(kSyntheticEvaluationStepsSlot) + obj->object() + ->GetInternalField(kSyntheticEvaluationStepsSlot) + .As() .As(); obj->object()->SetInternalField( kSyntheticEvaluationStepsSlot, Undefined(isolate)); diff --git a/src/module_wrap.h b/src/module_wrap.h index c609ba5509dcd0..6435bad40936fe 100644 --- a/src/module_wrap.h +++ b/src/module_wrap.h @@ -26,15 +26,14 @@ enum ScriptType : int { }; enum HostDefinedOptions : int { - kType = 8, - kID = 9, - kLength = 10, + kID = 8, + kLength = 9, }; class ModuleWrap : public BaseObject { public: enum InternalFields { - kModuleWrapBaseField = BaseObject::kInternalFieldCount, + kModuleSlot = BaseObject::kInternalFieldCount, kURLSlot, kSyntheticEvaluationStepsSlot, kContextObjectSlot, // Object whose creation context is the target Context @@ -55,9 +54,7 @@ class ModuleWrap : public BaseObject { tracker->TrackField("resolve_cache", resolve_cache_); } - inline uint32_t id() { return id_; } v8::Local context() const; - static ModuleWrap* GetFromID(node::Environment*, uint32_t id); SET_MEMORY_INFO_NAME(ModuleWrap) SET_SELF_SIZE(ModuleWrap) @@ -72,7 +69,9 @@ class ModuleWrap : public BaseObject { ModuleWrap(Environment* env, v8::Local object, v8::Local module, - v8::Local url); + v8::Local url, + v8::Local context_object, + v8::Local synthetic_evaluation_step); ~ModuleWrap() override; static void New(const v8::FunctionCallbackInfo& args); @@ -107,7 +106,7 @@ class ModuleWrap : public BaseObject { contextify::ContextifyContext* contextify_context_ = nullptr; bool synthetic_ = false; bool linked_ = false; - uint32_t id_; + int module_hash_; }; } // namespace loader diff --git a/src/node.cc b/src/node.cc index f483e59dd155a8..89e0e5524c2102 100644 --- a/src/node.cc +++ b/src/node.cc @@ -20,6 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. #include "node.h" +#include "node_dotenv.h" // ========== local headers ========== @@ -62,6 +63,8 @@ #endif // NODE_USE_V8_PLATFORM #include "v8-profiler.h" +#include "cppgc/platform.h" + #if HAVE_INSPECTOR #include "inspector/worker_inspector.h" // ParentInspectorHandle #endif @@ -138,6 +141,10 @@ using v8::Value; namespace per_process { +// node_dotenv.h +// Instance is used to store environment variables including NODE_OPTIONS. +node::Dotenv dotenv_file = Dotenv(); + // node_revert.h // Bit flag used to track security reverts. unsigned int reverted_cve = 0; @@ -292,6 +299,21 @@ MaybeLocal StartExecution(Environment* env, StartExecutionCallback cb) { CHECK(!env->isolate_data()->is_building_snapshot()); +#ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION + if (sea::IsSingleExecutable()) { + sea::SeaResource sea = sea::FindSingleExecutableResource(); + // The SEA preparation blob building process should already enforce this, + // this check is just here to guard against the unlikely case where + // the SEA preparation blob has been manually modified by someone. + CHECK_IMPLIES(sea.use_snapshot(), + !env->snapshot_deserialize_main().IsEmpty()); + } +#endif + + if (env->options()->has_env_file_string) { + per_process::dotenv_file.SetEnvironment(env); + } + // TODO(joyeecheung): move these conditions into JS land and let the // deserialize main function take precedence. For workers, we need to // move the pre-execution part into a different file that can be @@ -816,13 +838,32 @@ static ExitCode InitializeNodeWithArgsInternal( V8::SetFlagsFromString(NODE_V8_OPTIONS, sizeof(NODE_V8_OPTIONS) - 1); #endif + // Specify this explicitly to avoid being affected by V8 changes to the + // default value. + V8::SetFlagsFromString("--rehash-snapshot"); + HandleEnvOptions(per_process::cli_options->per_isolate->per_env); + std::string node_options; + auto file_paths = node::Dotenv::GetPathFromArgs(*argv); + + if (!file_paths.empty()) { + CHECK(!per_process::v8_initialized); + auto cwd = Environment::GetCwd(Environment::GetExecPath(*argv)); + + for (const auto& file_path : file_paths) { + std::string path = cwd + kPathSeparator + file_path; + per_process::dotenv_file.ParsePath(path); + } + + per_process::dotenv_file.AssignNodeOptionsIfAvailable(&node_options); + } + #if !defined(NODE_WITHOUT_NODE_OPTIONS) if (!(flags & ProcessInitializationFlags::kDisableNodeOptionsEnv)) { - std::string node_options; - - if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) { + // NODE_OPTIONS environment variable is preferred over the file one. + if (credentials::SafeGetenv("NODE_OPTIONS", &node_options) || + !node_options.empty()) { std::vector env_argv = ParseNodeOptionsEnvVar(node_options, errors); @@ -875,9 +916,14 @@ static ExitCode InitializeNodeWithArgsInternal( // Initialize ICU. // If icu_data_dir is empty here, it will load the 'minimal' data. - if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) { - errors->push_back("could not initialize ICU " - "(check NODE_ICU_DATA or --icu-data-dir parameters)\n"); + std::string icu_error; + if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir, + &icu_error)) { + errors->push_back(icu_error + + ": Could not initialize ICU. " + "Check the directory specified by NODE_ICU_DATA or " + "--icu-data-dir contains " U_ICUDATA_NAME ".dat and " + "it's readable\n"); return ExitCode::kInvalidCommandLineArgument; } per_process::metadata.versions.InitializeIntlVersions(); @@ -1085,6 +1131,14 @@ InitializeOncePerProcessInternal(const std::vector& args, V8::Initialize(); } + if (!(flags & ProcessInitializationFlags::kNoInitializeCppgc)) { + v8::PageAllocator* allocator = nullptr; + if (result->platform_ != nullptr) { + allocator = result->platform_->GetPageAllocator(); + } + cppgc::InitializeProcess(allocator); + } + performance::performance_v8_start = PERFORMANCE_NOW(); per_process::v8_initialized = true; @@ -1104,6 +1158,10 @@ void TearDownOncePerProcess() { ResetSignalHandlers(); } + if (!(flags & ProcessInitializationFlags::kNoInitializeCppgc)) { + cppgc::ShutdownProcess(); + } + per_process::v8_initialized = false; if (!(flags & ProcessInitializationFlags::kNoInitializeV8)) { V8::Dispose(); @@ -1127,9 +1185,6 @@ void TearDownOncePerProcess() { } } -InitializationResult::~InitializationResult() {} -InitializationResultImpl::~InitializationResultImpl() {} - ExitCode GenerateAndWriteSnapshotData(const SnapshotData** snapshot_data_ptr, const InitializationResultImpl* result) { ExitCode exit_code = result->exit_code_enum(); @@ -1198,49 +1253,66 @@ ExitCode GenerateAndWriteSnapshotData(const SnapshotData** snapshot_data_ptr, return exit_code; } -ExitCode LoadSnapshotDataAndRun(const SnapshotData** snapshot_data_ptr, - const InitializationResultImpl* result) { - ExitCode exit_code = result->exit_code_enum(); +bool LoadSnapshotData(const SnapshotData** snapshot_data_ptr) { // nullptr indicates there's no snapshot data. DCHECK_NULL(*snapshot_data_ptr); + + bool is_sea = false; +#ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION + if (sea::IsSingleExecutable()) { + is_sea = true; + sea::SeaResource sea = sea::FindSingleExecutableResource(); + if (sea.use_snapshot()) { + std::unique_ptr read_data = + std::make_unique(); + std::string_view snapshot = sea.main_code_or_snapshot; + if (SnapshotData::FromBlob(read_data.get(), snapshot)) { + *snapshot_data_ptr = read_data.release(); + return true; + } else { + fprintf(stderr, "Invalid snapshot data in single executable binary\n"); + return false; + } + } + } +#endif + // --snapshot-blob indicates that we are reading a customized snapshot. - if (!per_process::cli_options->snapshot_blob.empty()) { + // Ignore it when we are loading from SEA. + if (!is_sea && !per_process::cli_options->snapshot_blob.empty()) { std::string filename = per_process::cli_options->snapshot_blob; FILE* fp = fopen(filename.c_str(), "rb"); if (fp == nullptr) { fprintf(stderr, "Cannot open %s", filename.c_str()); - exit_code = ExitCode::kStartupSnapshotFailure; - return exit_code; + return false; } std::unique_ptr read_data = std::make_unique(); bool ok = SnapshotData::FromFile(read_data.get(), fp); fclose(fp); if (!ok) { - // If we fail to read the customized snapshot, - // simply exit with kStartupSnapshotFailure. - exit_code = ExitCode::kStartupSnapshotFailure; - return exit_code; + return false; } *snapshot_data_ptr = read_data.release(); - } else if (per_process::cli_options->node_snapshot) { - // If --snapshot-blob is not specified, we are reading the embedded - // snapshot, but we will skip it if --no-node-snapshot is specified. + return true; + } + + if (per_process::cli_options->node_snapshot) { + // If --snapshot-blob is not specified or if the SEA contains no snapshot, + // we are reading the embedded snapshot, but we will skip it if + // --no-node-snapshot is specified. const node::SnapshotData* read_data = SnapshotBuilder::GetEmbeddedSnapshotData(); - if (read_data != nullptr && read_data->Check()) { + if (read_data != nullptr) { + if (!read_data->Check()) { + return false; + } // If we fail to read the embedded snapshot, treat it as if Node.js // was built without one. *snapshot_data_ptr = read_data; } } - NodeMainInstance main_instance(*snapshot_data_ptr, - uv_default_loop(), - per_process::v8_platform.Platform(), - result->args(), - result->exec_args()); - exit_code = main_instance.Run(); - return exit_code; + return true; } static ExitCode StartInternal(int argc, char** argv) { @@ -1275,7 +1347,8 @@ static ExitCode StartInternal(int argc, char** argv) { std::string sea_config = per_process::cli_options->experimental_sea_config; if (!sea_config.empty()) { - return sea::BuildSingleExecutableBlob(sea_config); + return sea::BuildSingleExecutableBlob( + sea_config, result->args(), result->exec_args()); } // --build-snapshot indicates that we are in snapshot building mode. @@ -1290,7 +1363,15 @@ static ExitCode StartInternal(int argc, char** argv) { } // Without --build-snapshot, we are in snapshot loading mode. - return LoadSnapshotDataAndRun(&snapshot_data, result.get()); + if (!LoadSnapshotData(&snapshot_data)) { + return ExitCode::kStartupSnapshotFailure; + } + NodeMainInstance main_instance(snapshot_data, + uv_default_loop(), + per_process::v8_platform.Platform(), + result->args(), + result->exec_args()); + return main_instance.Run(); } int Start(int argc, char** argv) { diff --git a/src/node.h b/src/node.h index 846ec413f8e1fc..ca01c42e8af484 100644 --- a/src/node.h +++ b/src/node.h @@ -261,6 +261,10 @@ enum Flags : uint32_t { kNoUseLargePages = 1 << 11, // Skip printing output for --help, --version, --v8-options. kNoPrintHelpOrVersionOutput = 1 << 12, + // Do not perform cppgc initialization. If set, the embedder must call + // cppgc::InitializeProcess() before creating a Node.js environment + // and call cppgc::ShutdownProcess() before process shutdown. + kNoInitializeCppgc = 1 << 13, // Emulate the behavior of InitializeNodeWithArgs() when passing // a flags argument to the InitializeOncePerProcess() replacement @@ -269,7 +273,7 @@ enum Flags : uint32_t { kNoStdioInitialization | kNoDefaultSignalHandling | kNoInitializeV8 | kNoInitializeNodeV8Platform | kNoInitOpenSSL | kNoParseGlobalDebugVariables | kNoAdjustResourceLimits | - kNoUseLargePages | kNoPrintHelpOrVersionOutput, + kNoUseLargePages | kNoPrintHelpOrVersionOutput | kNoInitializeCppgc, }; } // namespace ProcessInitializationFlags namespace ProcessFlags = ProcessInitializationFlags; // Legacy alias. @@ -285,7 +289,7 @@ enum Flags : uint32_t { class NODE_EXTERN InitializationResult { public: - virtual ~InitializationResult(); + virtual ~InitializationResult() = default; // Returns a suggested process exit code. virtual int exit_code() const = 0; @@ -654,7 +658,7 @@ enum Flags : uint64_t { } // namespace EnvironmentFlags struct InspectorParentHandle { - virtual ~InspectorParentHandle(); + virtual ~InspectorParentHandle() = default; }; // TODO(addaleax): Maybe move per-Environment options parsing here. @@ -1486,6 +1490,25 @@ void RegisterSignalHandler(int signal, bool reset_handler = false); #endif // _WIN32 +// Configure the layout of the JavaScript object with a cppgc::GarbageCollected +// instance so that when the JavaScript object is reachable, the garbage +// collected instance would have its Trace() method invoked per the cppgc +// contract. To make it work, the process must have called +// cppgc::InitializeProcess() before, which is usually the case for addons +// loaded by the stand-alone Node.js executable. Embedders of Node.js can use +// either need to call it themselves or make sure that +// ProcessInitializationFlags::kNoInitializeCppgc is *not* set for cppgc to +// work. +// If the CppHeap is owned by Node.js, which is usually the case for addon, +// the object must be created with at least two internal fields available, +// and the first two internal fields would be configured by Node.js. +// This may be superseded by a V8 API in the future, see +// https://bugs.chromium.org/p/v8/issues/detail?id=13960. Until then this +// serves as a helper for Node.js isolates. +NODE_EXTERN void SetCppgcReference(v8::Isolate* isolate, + v8::Local object, + void* wrappable); + } // namespace node #endif // SRC_NODE_H_ diff --git a/src/node_api.cc b/src/node_api.cc index 1f1cfb916a7f1e..d86e8b29b093e4 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -82,9 +82,8 @@ void node_napi_env__::trigger_fatal_exception(v8::Local local_err) { node::errors::TriggerUncaughtException(isolate, local_err, local_msg); } -// option enforceUncaughtExceptionPolicy is added for not breaking existing -// running n-api add-ons, and should be deprecated in the next major Node.js -// release. +// The option enforceUncaughtExceptionPolicy is added for not breaking existing +// running Node-API add-ons. template void node_napi_env__::CallbackIntoModule(T&& call) { CallIntoModule(call, [](napi_env env_, v8::Local local_err) { @@ -93,19 +92,24 @@ void node_napi_env__::CallbackIntoModule(T&& call) { return; } node::Environment* node_env = env->node_env(); - if (!node_env->options()->force_node_api_uncaught_exceptions_policy && + // If the module api version is less than NAPI_VERSION_EXPERIMENTAL, + // and the option --force-node-api-uncaught-exceptions-policy is not + // specified, emit a warning about the uncaught exception instead of + // triggering uncaught exception event. + if (env->module_api_version < NAPI_VERSION_EXPERIMENTAL && + !node_env->options()->force_node_api_uncaught_exceptions_policy && !enforceUncaughtExceptionPolicy) { ProcessEmitDeprecationWarning( node_env, "Uncaught N-API callback exception detected, please run node " - "with option --force-node-api-uncaught-exceptions-policy=true" + "with option --force-node-api-uncaught-exceptions-policy=true " "to handle those exceptions properly.", "DEP0168"); return; } // If there was an unhandled exception in the complete callback, // report it as a fatal exception. (There is no JavaScript on the - // callstack that can possibly handle it.) + // call stack that can possibly handle it.) env->trigger_fatal_exception(local_err); }); } diff --git a/src/node_api.h b/src/node_api.h index 03454683c401d4..27acc6a0df43be 100644 --- a/src/node_api.h +++ b/src/node_api.h @@ -30,7 +30,7 @@ struct uv_loop_s; // Forward declaration. typedef napi_value(NAPI_CDECL* napi_addon_register_func)(napi_env env, napi_value exports); -typedef int32_t(NAPI_CDECL* node_api_addon_get_api_version_func)(); +typedef int32_t(NAPI_CDECL* node_api_addon_get_api_version_func)(void); // Used by deprecated registration method napi_module_register. typedef struct napi_module { @@ -66,7 +66,7 @@ typedef struct napi_module { #define NAPI_MODULE_INIT() \ EXTERN_C_START \ - NAPI_MODULE_EXPORT int32_t NODE_API_MODULE_GET_API_VERSION() { \ + NAPI_MODULE_EXPORT int32_t NODE_API_MODULE_GET_API_VERSION(void) { \ return NAPI_VERSION; \ } \ NAPI_MODULE_EXPORT napi_value NAPI_MODULE_INITIALIZER(napi_env env, \ diff --git a/src/node_blob.cc b/src/node_blob.cc index 1a69b99965f81a..d5475de36d7738 100644 --- a/src/node_blob.cc +++ b/src/node_blob.cc @@ -130,7 +130,7 @@ void Blob::CreatePerContextProperties(Local target, Local context, void* priv) { Realm* realm = Realm::GetCurrent(context); - realm->AddBindingData(context, target); + realm->AddBindingData(target); } Local Blob::GetConstructorTemplate(Environment* env) { @@ -400,20 +400,22 @@ std::unique_ptr Blob::CloneForMessaging() const { } void Blob::StoreDataObject(const v8::FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - BlobBindingData* binding_data = Realm::GetBindingData(args); + Realm* realm = Realm::GetCurrent(args); CHECK(args[0]->IsString()); // ID key - CHECK(Blob::HasInstance(env, args[1])); // Blob + CHECK(Blob::HasInstance(realm->env(), args[1])); // Blob CHECK(args[2]->IsUint32()); // Length CHECK(args[3]->IsString()); // Type - Utf8Value key(env->isolate(), args[0]); + BlobBindingData* binding_data = realm->GetBindingData(); + Isolate* isolate = realm->isolate(); + + Utf8Value key(isolate, args[0]); Blob* blob; ASSIGN_OR_RETURN_UNWRAP(&blob, args[1]); size_t length = args[2].As()->Value(); - Utf8Value type(env->isolate(), args[3]); + Utf8Value type(isolate, args[3]); binding_data->store_data_object( std::string(*key, key.length()), @@ -427,9 +429,11 @@ void Blob::StoreDataObject(const v8::FunctionCallbackInfo& args) { void Blob::RevokeObjectURL(const FunctionCallbackInfo& args) { CHECK_GE(args.Length(), 1); CHECK(args[0]->IsString()); - BlobBindingData* binding_data = Realm::GetBindingData(args); - Environment* env = Environment::GetCurrent(args); - Utf8Value input(env->isolate(), args[0].As()); + Realm* realm = Realm::GetCurrent(args); + BlobBindingData* binding_data = realm->GetBindingData(); + Isolate* isolate = realm->isolate(); + + Utf8Value input(isolate, args[0].As()); auto out = ada::parse(input.ToStringView()); if (!out) { @@ -449,36 +453,30 @@ void Blob::RevokeObjectURL(const FunctionCallbackInfo& args) { } void Blob::GetDataObject(const v8::FunctionCallbackInfo& args) { - BlobBindingData* binding_data = Realm::GetBindingData(args); - - Environment* env = Environment::GetCurrent(args); CHECK(args[0]->IsString()); + Realm* realm = Realm::GetCurrent(args); + BlobBindingData* binding_data = realm->GetBindingData(); + Isolate* isolate = realm->isolate(); - Utf8Value key(env->isolate(), args[0]); + Utf8Value key(isolate, args[0]); BlobBindingData::StoredDataObject stored = binding_data->get_data_object(std::string(*key, key.length())); if (stored.blob) { Local type; - if (!String::NewFromUtf8( - env->isolate(), - stored.type.c_str(), - v8::NewStringType::kNormal, - static_cast(stored.type.length())).ToLocal(&type)) { + if (!String::NewFromUtf8(isolate, + stored.type.c_str(), + v8::NewStringType::kNormal, + static_cast(stored.type.length())) + .ToLocal(&type)) { return; } - Local values[] = { - stored.blob->object(), - Uint32::NewFromUnsigned(env->isolate(), stored.length), - type - }; + Local values[] = {stored.blob->object(), + Uint32::NewFromUnsigned(isolate, stored.length), + type}; - args.GetReturnValue().Set( - Array::New( - env->isolate(), - values, - arraysize(values))); + args.GetReturnValue().Set(Array::New(isolate, values, arraysize(values))); } } @@ -532,11 +530,10 @@ void BlobBindingData::Deserialize(Local context, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); - BlobBindingData* binding = - realm->AddBindingData(context, holder); + BlobBindingData* binding = realm->AddBindingData(holder); CHECK_NOT_NULL(binding); } @@ -549,7 +546,7 @@ bool BlobBindingData::PrepareForSerialization(Local context, } InternalFieldInfoBase* BlobBindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = InternalFieldInfoBase::New(type()); return info; diff --git a/src/node_builtins.cc b/src/node_builtins.cc index 875fb0979950b7..84815969b6d1fa 100644 --- a/src/node_builtins.cc +++ b/src/node_builtins.cc @@ -82,8 +82,8 @@ Local BuiltinLoader::GetConfigString(Isolate* isolate) { return config_.ToStringChecked(isolate); } -std::vector BuiltinLoader::GetBuiltinIds() const { - std::vector ids; +std::vector BuiltinLoader::GetBuiltinIds() const { + std::vector ids; auto source = source_.read(); ids.reserve(source->size()); for (auto const& x : *source) { @@ -95,7 +95,7 @@ std::vector BuiltinLoader::GetBuiltinIds() const { BuiltinLoader::BuiltinCategories BuiltinLoader::GetBuiltinCategories() const { BuiltinCategories builtin_categories; - std::vector prefixes = { + const std::vector prefixes = { #if !HAVE_OPENSSL "internal/crypto/", "internal/debugger/", @@ -254,7 +254,7 @@ MaybeLocal BuiltinLoader::LookupAndCompileInternal( Local context, const char* id, std::vector>* parameters, - BuiltinLoader::Result* result) { + Realm* optional_realm) { Isolate* isolate = context->GetIsolate(); EscapableHandleScope scope(isolate); @@ -320,9 +320,13 @@ MaybeLocal BuiltinLoader::LookupAndCompileInternal( // will never be in any of these two sets, but the two sets are only for // testing anyway. - *result = (has_cache && !script_source.GetCachedData()->rejected) - ? Result::kWithCache - : Result::kWithoutCache; + Result result = (has_cache && !script_source.GetCachedData()->rejected) + ? Result::kWithCache + : Result::kWithoutCache; + if (optional_realm != nullptr) { + DCHECK_EQ(this, optional_realm->env()->builtin_loader()); + RecordResult(id, result, optional_realm); + } if (has_cache) { per_process::Debug(DebugCategory::CODE_CACHE, @@ -336,28 +340,35 @@ MaybeLocal BuiltinLoader::LookupAndCompileInternal( : "is accepted"); } - if (*result == Result::kWithoutCache) { + if (result == Result::kWithoutCache && optional_realm != nullptr && + !optional_realm->env()->isolate_data()->is_building_snapshot()) { // We failed to accept this cache, maybe because it was rejected, maybe // because it wasn't present. Either way, we'll attempt to replace this // code cache info with a new one. - std::shared_ptr new_cached_data( - ScriptCompiler::CreateCodeCacheForFunction(fun)); - CHECK_NOT_NULL(new_cached_data); - - { - RwLock::ScopedLock lock(code_cache_->mutex); - code_cache_->map.insert_or_assign( - id, BuiltinCodeCacheData(std::move(new_cached_data))); - } + // This is only done when the isolate is not being serialized because + // V8 does not support serializing code cache with an unfinalized read-only + // space (which is what isolates pending to be serialized have). + SaveCodeCache(id, fun); } return scope.Escape(fun); } +void BuiltinLoader::SaveCodeCache(const char* id, Local fun) { + std::shared_ptr new_cached_data( + ScriptCompiler::CreateCodeCacheForFunction(fun)); + CHECK_NOT_NULL(new_cached_data); + + { + RwLock::ScopedLock lock(code_cache_->mutex); + code_cache_->map.insert_or_assign( + id, BuiltinCodeCacheData(std::move(new_cached_data))); + } +} + MaybeLocal BuiltinLoader::LookupAndCompile(Local context, const char* id, Realm* optional_realm) { - Result result; std::vector> parameters; Isolate* isolate = context->GetIsolate(); // Detects parameters of the scripts based on module ids. @@ -403,11 +414,7 @@ MaybeLocal BuiltinLoader::LookupAndCompile(Local context, } MaybeLocal maybe = - LookupAndCompileInternal(context, id, ¶meters, &result); - if (optional_realm != nullptr) { - DCHECK_EQ(this, optional_realm->env()->builtin_loader()); - RecordResult(id, result, optional_realm); - } + LookupAndCompileInternal(context, id, ¶meters, optional_realm); return maybe; } @@ -475,7 +482,7 @@ MaybeLocal BuiltinLoader::CompileAndCall(Local context, } bool BuiltinLoader::CompileAllBuiltins(Local context) { - std::vector ids = GetBuiltinIds(); + std::vector ids = GetBuiltinIds(); bool all_succeeded = true; std::string v8_tools_prefix = "internal/deps/v8/tools/"; for (const auto& id : ids) { @@ -483,13 +490,17 @@ bool BuiltinLoader::CompileAllBuiltins(Local context) { continue; } v8::TryCatch bootstrapCatch(context->GetIsolate()); - USE(LookupAndCompile(context, id.c_str(), nullptr)); + auto fn = LookupAndCompile(context, id.data(), nullptr); if (bootstrapCatch.HasCaught()) { per_process::Debug(DebugCategory::CODE_CACHE, "Failed to compile code cache for %s\n", - id.c_str()); + id.data()); all_succeeded = false; PrintCaughtException(context->GetIsolate(), context, bootstrapCatch); + } else { + // This is used by the snapshot builder, so save the code cache + // unconditionally. + SaveCodeCache(id.data(), fn.ToLocalChecked()); } } return all_succeeded; @@ -607,7 +618,7 @@ void BuiltinLoader::BuiltinIdsGetter(Local property, Environment* env = Environment::GetCurrent(info); Isolate* isolate = env->isolate(); - std::vector ids = env->builtin_loader()->GetBuiltinIds(); + std::vector ids = env->builtin_loader()->GetBuiltinIds(); info.GetReturnValue().Set( ToV8Value(isolate->GetCurrentContext(), ids).ToLocalChecked()); } diff --git a/src/node_builtins.h b/src/node_builtins.h index 5e634254fc6560..9f2fbc1e539374 100644 --- a/src/node_builtins.h +++ b/src/node_builtins.h @@ -126,7 +126,7 @@ class NODE_EXTERN_PRIVATE BuiltinLoader { void LoadJavaScriptSource(); // Loads data into source_ UnionBytes GetConfig(); // Return data for config.gypi - std::vector GetBuiltinIds() const; + std::vector GetBuiltinIds() const; struct BuiltinCategories { std::set can_be_required; @@ -147,7 +147,8 @@ class NODE_EXTERN_PRIVATE BuiltinLoader { v8::Local context, const char* id, std::vector>* parameters, - Result* result); + Realm* optional_realm); + void SaveCodeCache(const char* id, v8::Local fn); static void RecordResult(const char* id, BuiltinLoader::Result result, diff --git a/src/node_context_data.h b/src/node_context_data.h index 009d46c34dc4ef..1854eb879ee9ff 100644 --- a/src/node_context_data.h +++ b/src/node_context_data.h @@ -51,7 +51,6 @@ enum ContextEmbedderIndex { kEnvironment = NODE_CONTEXT_EMBEDDER_DATA_INDEX, kSandboxObject = NODE_CONTEXT_SANDBOX_OBJECT_INDEX, kAllowWasmCodeGeneration = NODE_CONTEXT_ALLOW_WASM_CODE_GENERATION_INDEX, - kBindingDataStoreIndex = NODE_BINDING_DATA_STORE_INDEX, kAllowCodeGenerationFromStrings = NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX, kContextifyContext = NODE_CONTEXT_CONTEXTIFY_CONTEXT_INDEX, diff --git a/src/node_contextify.cc b/src/node_contextify.cc index f8bd2d9b7cd71d..b64faf812c6c47 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -60,7 +60,6 @@ using v8::MicrotasksPolicy; using v8::Name; using v8::NamedPropertyHandlerConfiguration; using v8::Nothing; -using v8::Number; using v8::Object; using v8::ObjectTemplate; using v8::PrimitiveArray; @@ -73,11 +72,11 @@ using v8::Script; using v8::ScriptCompiler; using v8::ScriptOrigin; using v8::String; +using v8::Symbol; using v8::Uint32; using v8::UnboundScript; using v8::Value; using v8::WeakCallbackInfo; -using v8::WeakCallbackType; // The vm module executes code in a sandboxed environment with a different // global object than the rest of the code. This is achieved by applying @@ -110,17 +109,15 @@ Local Uint32ToName(Local context, uint32_t index) { } // anonymous namespace BaseObjectPtr ContextifyContext::New( - Environment* env, - Local sandbox_obj, - const ContextOptions& options) { + Environment* env, Local sandbox_obj, ContextOptions* options) { HandleScope scope(env->isolate()); Local object_template = env->contextify_global_template(); DCHECK(!object_template.IsEmpty()); const SnapshotData* snapshot_data = env->isolate_data()->snapshot_data(); MicrotaskQueue* queue = - options.microtask_queue_wrap - ? options.microtask_queue_wrap->microtask_queue().get() + options->own_microtask_queue + ? options->own_microtask_queue.get() : env->isolate()->GetCurrentContext()->GetMicrotaskQueue(); Local v8_context; @@ -132,19 +129,16 @@ BaseObjectPtr ContextifyContext::New( return New(v8_context, env, sandbox_obj, options); } -void ContextifyContext::MemoryInfo(MemoryTracker* tracker) const { - if (microtask_queue_wrap_) { - tracker->TrackField("microtask_queue_wrap", - microtask_queue_wrap_->object()); - } -} +void ContextifyContext::MemoryInfo(MemoryTracker* tracker) const {} ContextifyContext::ContextifyContext(Environment* env, Local wrapper, Local v8_context, - const ContextOptions& options) + ContextOptions* options) : BaseObject(env, wrapper), - microtask_queue_wrap_(options.microtask_queue_wrap) { + microtask_queue_(options->own_microtask_queue + ? options->own_microtask_queue.release() + : nullptr) { context_.Reset(env->isolate(), v8_context); // This should only be done after the initial initializations of the context // global object is finished. @@ -240,7 +234,7 @@ BaseObjectPtr ContextifyContext::New( Local v8_context, Environment* env, Local sandbox_obj, - const ContextOptions& options) { + ContextOptions* options) { HandleScope scope(env->isolate()); // This only initializes part of the context. The primordials are // only initialized when needed because even deserializing them slows @@ -268,14 +262,14 @@ BaseObjectPtr ContextifyContext::New( v8_context->AllowCodeGenerationFromStrings(false); v8_context->SetEmbedderData( ContextEmbedderIndex::kAllowCodeGenerationFromStrings, - options.allow_code_gen_strings); + options->allow_code_gen_strings); v8_context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration, - options.allow_code_gen_wasm); + options->allow_code_gen_wasm); - Utf8Value name_val(env->isolate(), options.name); + Utf8Value name_val(env->isolate(), options->name); ContextInfo info(*name_val); - if (!options.origin.IsEmpty()) { - Utf8Value origin_val(env->isolate(), options.origin); + if (!options->origin.IsEmpty()) { + Utf8Value origin_val(env->isolate(), options->origin); info.origin = *origin_val; } @@ -374,16 +368,14 @@ void ContextifyContext::MakeContext(const FunctionCallbackInfo& args) { CHECK(args[4]->IsBoolean()); options.allow_code_gen_wasm = args[4].As(); - if (args[5]->IsObject() && - !env->microtask_queue_ctor_template().IsEmpty() && - env->microtask_queue_ctor_template()->HasInstance(args[5])) { - options.microtask_queue_wrap.reset( - Unwrap(args[5].As())); + if (args[5]->IsBoolean() && args[5]->BooleanValue(env->isolate())) { + options.own_microtask_queue = + MicrotaskQueue::New(env->isolate(), MicrotasksPolicy::kExplicit); } TryCatchScope try_catch(env); BaseObjectPtr context_ptr = - ContextifyContext::New(env, sandbox, options); + ContextifyContext::New(env, sandbox, &options); if (try_catch.HasCaught()) { if (!try_catch.HasTerminated()) @@ -824,10 +816,9 @@ void ContextifyScript::New(const FunctionCallbackInfo& args) { Local host_defined_options = PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength); - host_defined_options->Set(isolate, loader::HostDefinedOptions::kType, - Number::New(isolate, loader::ScriptType::kScript)); - host_defined_options->Set(isolate, loader::HostDefinedOptions::kID, - Number::New(isolate, contextify_script->id())); + Local id_symbol = Symbol::New(isolate, filename); + host_defined_options->Set( + isolate, loader::HostDefinedOptions::kID, id_symbol); ScriptOrigin origin(isolate, filename, @@ -864,13 +855,22 @@ void ContextifyScript::New(const FunctionCallbackInfo& args) { "ContextifyScript::New"); return; } + contextify_script->script_.Reset(isolate, v8_script); + contextify_script->script_.SetWeak(); + contextify_script->object()->SetInternalField(kUnboundScriptSlot, v8_script); std::unique_ptr new_cached_data; if (produce_cached_data) { new_cached_data.reset(ScriptCompiler::CreateCodeCache(v8_script)); } + if (contextify_script->object() + ->SetPrivate(context, env->host_defined_option_symbol(), id_symbol) + .IsNothing()) { + return; + } + if (StoreCodeCacheResult(env, args.This(), compile_options, @@ -935,6 +935,22 @@ Maybe StoreCodeCacheResult( return Just(true); } +// TODO(RaisinTen): Reuse in ContextifyContext::CompileFunction(). +MaybeLocal CompileFunction(Local context, + Local filename, + Local content, + std::vector>* parameters) { + ScriptOrigin script_origin(context->GetIsolate(), filename, 0, 0, true); + ScriptCompiler::Source script_source(content, script_origin); + + return ScriptCompiler::CompileFunction(context, + &script_source, + parameters->size(), + parameters->data(), + 0, + nullptr); +} + bool ContextifyScript::InstanceOf(Environment* env, const Local& value) { return !value.IsEmpty() && @@ -971,7 +987,7 @@ void ContextifyScript::RunInContext(const FunctionCallbackInfo& args) { CHECK(args[0]->IsObject() || args[0]->IsNull()); Local context; - std::shared_ptr microtask_queue; + v8::MicrotaskQueue* microtask_queue = nullptr; if (args[0]->IsObject()) { Local sandbox = args[0].As(); @@ -1020,7 +1036,7 @@ bool ContextifyScript::EvalMachine(Local context, const bool display_errors, const bool break_on_sigint, const bool break_on_first_line, - std::shared_ptr mtask_queue, + MicrotaskQueue* mtask_queue, const FunctionCallbackInfo& args) { Context::Scope context_scope(context); @@ -1052,7 +1068,7 @@ bool ContextifyScript::EvalMachine(Local context, bool received_signal = false; auto run = [&]() { MaybeLocal result = script->Run(context); - if (!result.IsEmpty() && mtask_queue) + if (!result.IsEmpty() && mtask_queue != nullptr) mtask_queue->PerformCheckpoint(env->isolate()); return result; }; @@ -1106,19 +1122,12 @@ bool ContextifyScript::EvalMachine(Local context, return true; } - ContextifyScript::ContextifyScript(Environment* env, Local object) - : BaseObject(env, object), - id_(env->get_next_script_id()) { + : BaseObject(env, object) { MakeWeak(); - env->id_to_script_map.emplace(id_, this); -} - - -ContextifyScript::~ContextifyScript() { - env()->id_to_script_map.erase(id_); } +ContextifyScript::~ContextifyScript() {} void ContextifyContext::CompileFunction( const FunctionCallbackInfo& args) { @@ -1188,18 +1197,12 @@ void ContextifyContext::CompileFunction( data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); } - // Get the function id - uint32_t id = env->get_next_function_id(); - // Set host_defined_options Local host_defined_options = PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength); + Local id_symbol = Symbol::New(isolate, filename); host_defined_options->Set( - isolate, - loader::HostDefinedOptions::kType, - Number::New(isolate, loader::ScriptType::kFunction)); - host_defined_options->Set( - isolate, loader::HostDefinedOptions::kID, Number::New(isolate, id)); + isolate, loader::HostDefinedOptions::kID, id_symbol); ScriptOrigin origin(isolate, filename, @@ -1264,21 +1267,14 @@ void ContextifyContext::CompileFunction( } return; } - - Local cache_key; - if (!env->compiled_fn_entry_template()->NewInstance( - context).ToLocal(&cache_key)) { + if (fn->SetPrivate(context, env->host_defined_option_symbol(), id_symbol) + .IsNothing()) { return; } - CompiledFnEntry* entry = new CompiledFnEntry(env, cache_key, id, fn); - env->id_to_function_map.emplace(id, entry); Local result = Object::New(isolate); if (result->Set(parsing_context, env->function_string(), fn).IsNothing()) return; - if (result->Set(parsing_context, env->cache_key_string(), cache_key) - .IsNothing()) - return; if (result ->Set(parsing_context, env->source_map_url_string(), @@ -1303,25 +1299,6 @@ void ContextifyContext::CompileFunction( args.GetReturnValue().Set(result); } -void CompiledFnEntry::WeakCallback( - const WeakCallbackInfo& data) { - CompiledFnEntry* entry = data.GetParameter(); - delete entry; -} - -CompiledFnEntry::CompiledFnEntry(Environment* env, - Local object, - uint32_t id, - Local fn) - : BaseObject(env, object), id_(id), fn_(env->isolate(), fn) { - fn_.SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter); -} - -CompiledFnEntry::~CompiledFnEntry() { - env()->id_to_function_map.erase(id_); - fn_.ClearWeak(); -} - static void StartSigintWatchdog(const FunctionCallbackInfo& args) { int ret = SigintWatchdogHelper::GetInstance()->Start(); args.GetReturnValue().Set(ret == 0); @@ -1360,46 +1337,12 @@ static void MeasureMemory(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(promise); } -MicrotaskQueueWrap::MicrotaskQueueWrap(Environment* env, Local obj) - : BaseObject(env, obj), - microtask_queue_( - MicrotaskQueue::New(env->isolate(), MicrotasksPolicy::kExplicit)) { - MakeWeak(); -} - -const std::shared_ptr& -MicrotaskQueueWrap::microtask_queue() const { - return microtask_queue_; -} - -void MicrotaskQueueWrap::New(const FunctionCallbackInfo& args) { - CHECK(args.IsConstructCall()); - new MicrotaskQueueWrap(Environment::GetCurrent(args), args.This()); -} - -void MicrotaskQueueWrap::CreatePerIsolateProperties( - IsolateData* isolate_data, Local target) { - Isolate* isolate = isolate_data->isolate(); - HandleScope scope(isolate); - Local tmpl = NewFunctionTemplate(isolate, New); - tmpl->InstanceTemplate()->SetInternalFieldCount( - ContextifyScript::kInternalFieldCount); - isolate_data->set_microtask_queue_ctor_template(tmpl); - SetConstructorFunction(isolate, target, "MicrotaskQueue", tmpl); -} - -void MicrotaskQueueWrap::RegisterExternalReferences( - ExternalReferenceRegistry* registry) { - registry->Register(New); -} - void CreatePerIsolateProperties(IsolateData* isolate_data, Local target) { Isolate* isolate = isolate_data->isolate(); ContextifyContext::CreatePerIsolateProperties(isolate_data, target); ContextifyScript::CreatePerIsolateProperties(isolate_data, target); - MicrotaskQueueWrap::CreatePerIsolateProperties(isolate_data, target); SetMethod(isolate, target, "startSigintWatchdog", StartSigintWatchdog); SetMethod(isolate, target, "stopSigintWatchdog", StopSigintWatchdog); @@ -1407,14 +1350,6 @@ void CreatePerIsolateProperties(IsolateData* isolate_data, SetMethodNoSideEffect( isolate, target, "watchdogHasPendingSigint", WatchdogHasPendingSigint); - { - Local tpl = FunctionTemplate::New(isolate); - tpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "CompiledFnEntry")); - tpl->InstanceTemplate()->SetInternalFieldCount( - CompiledFnEntry::kInternalFieldCount); - - isolate_data->set_compiled_fn_entry_template(tpl->InstanceTemplate()); - } SetMethod(isolate, target, "measureMemory", MeasureMemory); } @@ -1454,7 +1389,6 @@ static void CreatePerContextProperties(Local target, void RegisterExternalReferences(ExternalReferenceRegistry* registry) { ContextifyContext::RegisterExternalReferences(registry); ContextifyScript::RegisterExternalReferences(registry); - MicrotaskQueueWrap::RegisterExternalReferences(registry); registry->Register(StartSigintWatchdog); registry->Register(StopSigintWatchdog); diff --git a/src/node_contextify.h b/src/node_contextify.h index 3160160521e0fe..d1dddbf374d563 100644 --- a/src/node_contextify.h +++ b/src/node_contextify.h @@ -12,34 +12,12 @@ class ExternalReferenceRegistry; namespace contextify { -class MicrotaskQueueWrap : public BaseObject { - public: - MicrotaskQueueWrap(Environment* env, v8::Local obj); - - const std::shared_ptr& microtask_queue() const; - - static void CreatePerIsolateProperties(IsolateData* isolate_data, - v8::Local target); - static void RegisterExternalReferences(ExternalReferenceRegistry* registry); - static void New(const v8::FunctionCallbackInfo& args); - - // This could have methods for running the microtask queue, if we ever decide - // to make that fully customizable from userland. - - SET_NO_MEMORY_INFO() - SET_MEMORY_INFO_NAME(MicrotaskQueueWrap) - SET_SELF_SIZE(MicrotaskQueueWrap) - - private: - std::shared_ptr microtask_queue_; -}; - struct ContextOptions { v8::Local name; v8::Local origin; v8::Local allow_code_gen_strings; v8::Local allow_code_gen_wasm; - BaseObjectPtr microtask_queue_wrap; + std::unique_ptr own_microtask_queue; }; class ContextifyContext : public BaseObject { @@ -47,7 +25,7 @@ class ContextifyContext : public BaseObject { ContextifyContext(Environment* env, v8::Local wrapper, v8::Local v8_context, - const ContextOptions& options); + ContextOptions* options); ~ContextifyContext(); void MemoryInfo(MemoryTracker* tracker) const override; @@ -80,9 +58,8 @@ class ContextifyContext : public BaseObject { .As(); } - inline std::shared_ptr microtask_queue() const { - if (!microtask_queue_wrap_) return {}; - return microtask_queue_wrap_->microtask_queue(); + inline v8::MicrotaskQueue* microtask_queue() const { + return microtask_queue_.get(); } template @@ -94,12 +71,12 @@ class ContextifyContext : public BaseObject { private: static BaseObjectPtr New(Environment* env, v8::Local sandbox_obj, - const ContextOptions& options); + ContextOptions* options); // Initialize a context created from CreateV8Context() static BaseObjectPtr New(v8::Local ctx, Environment* env, v8::Local sandbox_obj, - const ContextOptions& options); + ContextOptions* options); static bool IsStillInitializing(const ContextifyContext* ctx); static void MakeContext(const v8::FunctionCallbackInfo& args); @@ -146,11 +123,16 @@ class ContextifyContext : public BaseObject { const v8::PropertyCallbackInfo& args); v8::Global context_; - BaseObjectPtr microtask_queue_wrap_; + std::unique_ptr microtask_queue_; }; class ContextifyScript : public BaseObject { public: + enum InternalFields { + kUnboundScriptSlot = BaseObject::kInternalFieldCount, + kInternalFieldCount + }; + SET_NO_MEMORY_INFO() SET_MEMORY_INFO_NAME(ContextifyScript) SET_SELF_SIZE(ContextifyScript) @@ -171,35 +153,11 @@ class ContextifyScript : public BaseObject { const bool display_errors, const bool break_on_sigint, const bool break_on_first_line, - std::shared_ptr microtask_queue, + v8::MicrotaskQueue* microtask_queue, const v8::FunctionCallbackInfo& args); - inline uint32_t id() { return id_; } - private: v8::Global script_; - uint32_t id_; -}; - -class CompiledFnEntry final : public BaseObject { - public: - SET_NO_MEMORY_INFO() - SET_MEMORY_INFO_NAME(CompiledFnEntry) - SET_SELF_SIZE(CompiledFnEntry) - - CompiledFnEntry(Environment* env, - v8::Local object, - uint32_t id, - v8::Local fn); - ~CompiledFnEntry(); - - bool IsNotIndicativeOfMemoryLeakAtExit() const override { return true; } - - private: - uint32_t id_; - v8::Global fn_; - - static void WeakCallback(const v8::WeakCallbackInfo& data); }; v8::Maybe StoreCodeCacheResult( @@ -210,6 +168,12 @@ v8::Maybe StoreCodeCacheResult( bool produce_cached_data, std::unique_ptr new_cached_data); +v8::MaybeLocal CompileFunction( + v8::Local context, + v8::Local filename, + v8::Local content, + std::vector>* parameters); + } // namespace contextify } // namespace node diff --git a/src/node_credentials.cc b/src/node_credentials.cc index 52abaab7a635db..c1f7a4f2acbdf6 100644 --- a/src/node_credentials.cc +++ b/src/node_credentials.cc @@ -123,7 +123,6 @@ bool SafeGetenv(const char* key, } fail: - text->clear(); return false; } diff --git a/src/node_dir.cc b/src/node_dir.cc index 0bef2b8927639b..10cde6067899c7 100644 --- a/src/node_dir.cc +++ b/src/node_dir.cc @@ -53,7 +53,7 @@ static const char* get_dir_func_name_by_type(uv_fs_type req_type) { FS_TYPE_TO_NAME(CLOSEDIR, "closedir") #undef FS_TYPE_TO_NAME default: - return "unknow"; + return "unknown"; } } @@ -397,6 +397,32 @@ static void OpenDir(const FunctionCallbackInfo& args) { } } +static void OpenDirSync(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + Isolate* isolate = env->isolate(); + + CHECK_GE(args.Length(), 1); + + BufferValue path(isolate, args[0]); + CHECK_NOT_NULL(*path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); + + uv_fs_t req; + auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); + FS_DIR_SYNC_TRACE_BEGIN(opendir); + int err = uv_fs_opendir(nullptr, &req, *path, nullptr); + FS_DIR_SYNC_TRACE_END(opendir); + if (err < 0) { + return env->ThrowUVException(err, "opendir"); + } + + uv_dir_t* dir = static_cast(req.ptr); + DirHandle* handle = DirHandle::New(env, dir); + + args.GetReturnValue().Set(handle->object().As()); +} + void Initialize(Local target, Local unused, Local context, @@ -405,6 +431,7 @@ void Initialize(Local target, Isolate* isolate = env->isolate(); SetMethod(context, target, "opendir", OpenDir); + SetMethod(context, target, "opendirSync", OpenDirSync); // Create FunctionTemplate for DirHandle Local dir = NewFunctionTemplate(isolate, DirHandle::New); @@ -419,6 +446,7 @@ void Initialize(Local target, void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(OpenDir); + registry->Register(OpenDirSync); registry->Register(DirHandle::New); registry->Register(DirHandle::Read); registry->Register(DirHandle::Close); diff --git a/src/node_dotenv.cc b/src/node_dotenv.cc new file mode 100644 index 00000000000000..0633ef51269959 --- /dev/null +++ b/src/node_dotenv.cc @@ -0,0 +1,169 @@ +#include "node_dotenv.h" +#include "env-inl.h" +#include "node_file.h" +#include "uv.h" + +namespace node { + +using v8::NewStringType; +using v8::String; + +std::vector Dotenv::GetPathFromArgs( + const std::vector& args) { + const auto find_match = [](const std::string& arg) { + const std::string_view flag = "--env-file"; + return strncmp(arg.c_str(), flag.data(), flag.size()) == 0; + }; + std::vector paths; + auto path = std::find_if(args.begin(), args.end(), find_match); + + while (path != args.end()) { + auto equal_char = path->find('='); + + if (equal_char != std::string::npos) { + paths.push_back(path->substr(equal_char + 1)); + } else { + auto next_path = std::next(path); + + if (next_path == args.end()) { + return paths; + } + + paths.push_back(*next_path); + } + + path = std::find_if(++path, args.end(), find_match); + } + + return paths; +} + +void Dotenv::SetEnvironment(node::Environment* env) { + if (store_.empty()) { + return; + } + + auto isolate = env->isolate(); + + for (const auto& entry : store_) { + auto key = entry.first; + auto value = entry.second; + + auto existing = env->env_vars()->Get(key.data()); + + if (existing.IsNothing()) { + env->env_vars()->Set( + isolate, + v8::String::NewFromUtf8( + isolate, key.data(), NewStringType::kNormal, key.size()) + .ToLocalChecked(), + v8::String::NewFromUtf8( + isolate, value.data(), NewStringType::kNormal, value.size()) + .ToLocalChecked()); + } + } +} + +void Dotenv::ParsePath(const std::string_view path) { + uv_fs_t req; + auto defer_req_cleanup = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); + + uv_file file = uv_fs_open(nullptr, &req, path.data(), 0, 438, nullptr); + if (req.result < 0) { + // req will be cleaned up by scope leave. + return; + } + uv_fs_req_cleanup(&req); + + auto defer_close = OnScopeLeave([file]() { + uv_fs_t close_req; + CHECK_EQ(0, uv_fs_close(nullptr, &close_req, file, nullptr)); + uv_fs_req_cleanup(&close_req); + }); + + std::string result{}; + char buffer[8192]; + uv_buf_t buf = uv_buf_init(buffer, sizeof(buffer)); + + while (true) { + auto r = uv_fs_read(nullptr, &req, file, &buf, 1, -1, nullptr); + if (req.result < 0) { + // req will be cleaned up by scope leave. + return; + } + uv_fs_req_cleanup(&req); + if (r <= 0) { + break; + } + result.append(buf.base, r); + } + + using std::string_view_literals::operator""sv; + auto lines = SplitString(result, "\n"sv); + + for (const auto& line : lines) { + ParseLine(line); + } +} + +void Dotenv::AssignNodeOptionsIfAvailable(std::string* node_options) { + auto match = store_.find("NODE_OPTIONS"); + + if (match != store_.end()) { + *node_options = match->second; + } +} + +void Dotenv::ParseLine(const std::string_view line) { + auto equal_index = line.find('='); + + if (equal_index == std::string_view::npos) { + return; + } + + auto key = line.substr(0, equal_index); + + // Remove leading and trailing space characters from key. + while (!key.empty() && std::isspace(key.front())) key.remove_prefix(1); + while (!key.empty() && std::isspace(key.back())) key.remove_suffix(1); + + // Omit lines with comments + if (key.front() == '#' || key.empty()) { + return; + } + + auto value = std::string(line.substr(equal_index + 1)); + + // Might start and end with `"' characters. + auto quotation_index = value.find_first_of("`\"'"); + + if (quotation_index == 0) { + auto quote_character = value[quotation_index]; + value.erase(0, 1); + + auto end_quotation_index = value.find_last_of(quote_character); + + // We couldn't find the closing quotation character. Terminate. + if (end_quotation_index == std::string::npos) { + return; + } + + value.erase(end_quotation_index); + } else { + auto hash_index = value.find('#'); + + // Remove any inline comments + if (hash_index != std::string::npos) { + value.erase(hash_index); + } + + // Remove any leading/trailing spaces from unquoted values. + while (!value.empty() && std::isspace(value.front())) value.erase(0, 1); + while (!value.empty() && std::isspace(value.back())) + value.erase(value.size() - 1); + } + + store_.insert_or_assign(std::string(key), value); +} + +} // namespace node diff --git a/src/node_dotenv.h b/src/node_dotenv.h new file mode 100644 index 00000000000000..ee74f9ff84a353 --- /dev/null +++ b/src/node_dotenv.h @@ -0,0 +1,37 @@ +#ifndef SRC_NODE_DOTENV_H_ +#define SRC_NODE_DOTENV_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "util-inl.h" + +#include + +namespace node { + +class Dotenv { + public: + Dotenv() = default; + Dotenv(const Dotenv& d) = default; + Dotenv(Dotenv&& d) noexcept = default; + Dotenv& operator=(Dotenv&& d) noexcept = default; + Dotenv& operator=(const Dotenv& d) = default; + ~Dotenv() = default; + + void ParsePath(const std::string_view path); + void AssignNodeOptionsIfAvailable(std::string* node_options); + void SetEnvironment(Environment* env); + + static std::vector GetPathFromArgs( + const std::vector& args); + + private: + void ParseLine(const std::string_view line); + std::map store_; +}; + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_NODE_DOTENV_H_ diff --git a/src/node_external_reference.h b/src/node_external_reference.h index 1586b15553d6a2..ae37094c8e117e 100644 --- a/src/node_external_reference.h +++ b/src/node_external_reference.h @@ -19,8 +19,12 @@ using CFunctionCallbackWithInt64 = void (*)(v8::Local receiver, int64_t); using CFunctionCallbackWithBool = void (*)(v8::Local receiver, bool); -using CFunctionCallbackWithStrings = +using CFunctionCallbackWithString = bool (*)(v8::Local, const v8::FastOneByteString& input); +using CFunctionCallbackWithStrings = + bool (*)(v8::Local, + const v8::FastOneByteString& input, + const v8::FastOneByteString& base); using CFunctionWithUint32 = uint32_t (*)(v8::Local, const uint32_t input); @@ -36,6 +40,7 @@ class ExternalReferenceRegistry { V(CFunctionCallbackReturnDouble) \ V(CFunctionCallbackWithInt64) \ V(CFunctionCallbackWithBool) \ + V(CFunctionCallbackWithString) \ V(CFunctionCallbackWithStrings) \ V(CFunctionWithUint32) \ V(const v8::CFunctionInfo*) \ diff --git a/src/node_file-inl.h b/src/node_file-inl.h index 2ba5906d614f1c..cdf21a4b3a6c22 100644 --- a/src/node_file-inl.h +++ b/src/node_file-inl.h @@ -277,9 +277,10 @@ FSReqBase* GetReqWrap(const v8::FunctionCallbackInfo& args, return Unwrap(value.As()); } - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = binding_data->env(); - if (value->StrictEquals(env->fs_use_promises_symbol())) { + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + + if (value->StrictEquals(realm->isolate_data()->fs_use_promises_symbol())) { if (use_bigint) { return FSReqPromise::New(binding_data, use_bigint); } else { diff --git a/src/node_file.cc b/src/node_file.cc index 4106918512e93c..b76eb385295836 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -156,7 +156,7 @@ static const char* get_fs_func_name_by_type(uv_fs_type req_type) { FS_TYPE_TO_NAME(LUTIME, "lutime") #undef FS_TYPE_TO_NAME default: - return "unknow"; + return "unknown"; } } @@ -264,17 +264,17 @@ FileHandle* FileHandle::New(BindingData* binding_data, } void FileHandle::New(const FunctionCallbackInfo& args) { - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = binding_data->env(); CHECK(args.IsConstructCall()); CHECK(args[0]->IsInt32()); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); std::optional maybeOffset = std::nullopt; std::optional maybeLength = std::nullopt; if (args[1]->IsNumber()) - maybeOffset = args[1]->IntegerValue(env->context()).FromJust(); + maybeOffset = args[1]->IntegerValue(realm->context()).FromJust(); if (args[2]->IsNumber()) - maybeLength = args[2]->IntegerValue(env->context()).FromJust(); + maybeLength = args[2]->IntegerValue(realm->context()).FromJust(); FileHandle::New(binding_data, args[0].As()->Value(), @@ -456,9 +456,8 @@ MaybeLocal FileHandle::ClosePromise() { Local context = env()->context(); Local close_resolver = - object()->GetInternalField(FileHandle::kClosingPromiseSlot); - if (!close_resolver.IsEmpty() && !close_resolver->IsUndefined()) { - CHECK(close_resolver->IsPromise()); + object()->GetInternalField(FileHandle::kClosingPromiseSlot).As(); + if (close_resolver->IsPromise()) { return close_resolver.As(); } @@ -997,6 +996,31 @@ void Access(const FunctionCallbackInfo& args) { } } +static void AccessSync(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + Isolate* isolate = env->isolate(); + + const int argc = args.Length(); + CHECK_GE(argc, 2); + + CHECK(args[1]->IsInt32()); + int mode = args[1].As()->Value(); + + BufferValue path(isolate, args[0]); + CHECK_NOT_NULL(*path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); + + uv_fs_t req; + FS_SYNC_TRACE_BEGIN(access); + int err = uv_fs_access(nullptr, &req, *path, mode, nullptr); + uv_fs_req_cleanup(&req); + FS_SYNC_TRACE_END(access); + + if (err) { + return env->ThrowUVException(err, "access", nullptr, path.out()); + } +} void Close(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -1022,6 +1046,54 @@ void Close(const FunctionCallbackInfo& args) { } } +static void CloseSync(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + CHECK_GE(args.Length(), 1); + CHECK(args[0]->IsInt32()); + + int fd = args[0].As()->Value(); + env->RemoveUnmanagedFd(fd); + + uv_fs_t req; + FS_SYNC_TRACE_BEGIN(close); + int err = uv_fs_close(nullptr, &req, fd, nullptr); + FS_SYNC_TRACE_END(close); + uv_fs_req_cleanup(&req); + + if (err < 0) { + return env->ThrowUVException(err, "close"); + } +} + +static void ExistsSync(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + Isolate* isolate = env->isolate(); + CHECK_GE(args.Length(), 1); + + BufferValue path(isolate, args[0]); + CHECK_NOT_NULL(*path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); + + uv_fs_t req; + auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); + FS_SYNC_TRACE_BEGIN(access); + int err = uv_fs_access(nullptr, &req, path.out(), 0, nullptr); + FS_SYNC_TRACE_END(access); + +#ifdef _WIN32 + // In case of an invalid symlink, `uv_fs_access` on win32 + // will **not** return an error and is therefore not enough. + // Double check with `uv_fs_stat()`. + if (err == 0) { + FS_SYNC_TRACE_BEGIN(stat); + err = uv_fs_stat(nullptr, &req, path.out(), nullptr); + FS_SYNC_TRACE_END(stat); + } +#endif // _WIN32 + + args.GetReturnValue().Set(err == 0); +} // Used to speed up module loading. Returns an array [string, boolean] static void InternalModuleReadJSON(const FunctionCallbackInfo& args) { @@ -1108,13 +1180,14 @@ static void InternalModuleStat(const FunctionCallbackInfo& args) { } static void Stat(const FunctionCallbackInfo& args) { - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = binding_data->env(); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Environment* env = realm->env(); const int argc = args.Length(); CHECK_GE(argc, 2); - BufferValue path(env->isolate(), args[0]); + BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); @@ -1142,14 +1215,50 @@ static void Stat(const FunctionCallbackInfo& args) { } } +static void StatSync(const FunctionCallbackInfo& args) { + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Environment* env = realm->env(); + + CHECK_GE(args.Length(), 3); + + BufferValue path(realm->isolate(), args[0]); + bool use_bigint = args[1]->IsTrue(); + bool do_not_throw_if_no_entry = args[2]->IsFalse(); + CHECK_NOT_NULL(*path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); + + env->PrintSyncTrace(); + + uv_fs_t req; + auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); + + FS_SYNC_TRACE_BEGIN(stat); + int err = uv_fs_stat(nullptr, &req, *path, nullptr); + FS_SYNC_TRACE_END(stat); + + if (err < 0) { + if (err == UV_ENOENT && do_not_throw_if_no_entry) { + return; + } + return env->ThrowUVException(err, "stat", nullptr, path.out()); + } + + Local arr = FillGlobalStatsArray( + binding_data, use_bigint, static_cast(req.ptr)); + args.GetReturnValue().Set(arr); +} + static void LStat(const FunctionCallbackInfo& args) { - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = binding_data->env(); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Environment* env = realm->env(); const int argc = args.Length(); CHECK_GE(argc, 3); - BufferValue path(env->isolate(), args[0]); + BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); bool use_bigint = args[1]->IsTrue(); @@ -1177,8 +1286,9 @@ static void LStat(const FunctionCallbackInfo& args) { } static void FStat(const FunctionCallbackInfo& args) { - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = binding_data->env(); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Environment* env = realm->env(); const int argc = args.Length(); CHECK_GE(argc, 2); @@ -1209,14 +1319,17 @@ static void FStat(const FunctionCallbackInfo& args) { } static void StatFs(const FunctionCallbackInfo& args) { - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = binding_data->env(); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Environment* env = realm->env(); const int argc = args.Length(); CHECK_GE(argc, 2); - BufferValue path(env->isolate(), args[0]); + BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); bool use_bigint = args[1]->IsTrue(); FSReqBase* req_wrap_async = GetReqWrap(args, 2, use_bigint); @@ -1250,6 +1363,34 @@ static void StatFs(const FunctionCallbackInfo& args) { } } +static void StatFsSync(const FunctionCallbackInfo& args) { + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Environment* env = realm->env(); + + CHECK_GE(args.Length(), 2); + + BufferValue path(realm->isolate(), args[0]); + bool use_bigint = args[1]->IsTrue(); + + CHECK_NOT_NULL(*path); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, path.ToStringView()); + + uv_fs_t req; + auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); + FS_SYNC_TRACE_BEGIN(statfs); + int err = uv_fs_statfs(nullptr, &req, *path, nullptr); + FS_SYNC_TRACE_END(statfs); + if (err < 0) { + return env->ThrowUVException(err, "statfs", *path, nullptr); + } + + Local arr = FillGlobalStatFsArray( + binding_data, use_bigint, static_cast(req.ptr)); + args.GetReturnValue().Set(arr); +} + static void Symlink(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Isolate* isolate = env->isolate(); @@ -1940,7 +2081,6 @@ static inline Maybe CheckOpenPermissions(Environment* env, const int write_as_side_effect = flags & (UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_TRUNC | UV_FS_O_TEMPORARY); - // TODO(rafaelgss): it can be optimized to avoid two permission checks auto pathView = path.ToStringView(); if (rwflags != UV_FS_O_WRONLY) { THROW_IF_INSUFFICIENT_PERMISSIONS( @@ -1959,66 +2099,6 @@ static inline Maybe CheckOpenPermissions(Environment* env, return JustVoid(); } -static void ReadFileSync(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - - CHECK_GE(args.Length(), 2); - - BufferValue path(env->isolate(), args[0]); - CHECK_NOT_NULL(*path); - - CHECK(args[1]->IsInt32()); - const int flags = args[1].As()->Value(); - - if (CheckOpenPermissions(env, path, flags).IsNothing()) return; - - uv_fs_t req; - auto defer_req_cleanup = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); - - FS_SYNC_TRACE_BEGIN(open); - uv_file file = uv_fs_open(nullptr, &req, *path, flags, 438, nullptr); - FS_SYNC_TRACE_END(open); - if (req.result < 0) { - // req will be cleaned up by scope leave. - return args.GetReturnValue().Set( - v8::Integer::New(env->isolate(), req.result)); - } - uv_fs_req_cleanup(&req); - - auto defer_close = OnScopeLeave([file]() { - uv_fs_t close_req; - CHECK_EQ(0, uv_fs_close(nullptr, &close_req, file, nullptr)); - uv_fs_req_cleanup(&close_req); - }); - - std::string result{}; - char buffer[8192]; - uv_buf_t buf = uv_buf_init(buffer, sizeof(buffer)); - - FS_SYNC_TRACE_BEGIN(read); - while (true) { - auto r = uv_fs_read(nullptr, &req, file, &buf, 1, -1, nullptr); - if (req.result < 0) { - FS_SYNC_TRACE_END(read); - // req will be cleaned up by scope leave. - return args.GetReturnValue().Set( - v8::Integer::New(env->isolate(), req.result)); - } - uv_fs_req_cleanup(&req); - if (r <= 0) { - break; - } - result.append(buf.base, r); - } - FS_SYNC_TRACE_END(read); - - args.GetReturnValue().Set(String::NewFromUtf8(env->isolate(), - result.data(), - v8::NewStringType::kNormal, - result.size()) - .ToLocalChecked()); -} - static void Open(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -2055,15 +2135,44 @@ static void Open(const FunctionCallbackInfo& args) { } } +static void OpenSync(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + const int argc = args.Length(); + CHECK_GE(argc, 3); + + BufferValue path(env->isolate(), args[0]); + CHECK_NOT_NULL(*path); + + CHECK(args[1]->IsInt32()); + const int flags = args[1].As()->Value(); + + CHECK(args[2]->IsInt32()); + const int mode = args[2].As()->Value(); + + if (CheckOpenPermissions(env, path, flags).IsNothing()) return; + + uv_fs_t req; + auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); }); + FS_SYNC_TRACE_BEGIN(open); + auto err = uv_fs_open(nullptr, &req, *path, flags, mode, nullptr); + FS_SYNC_TRACE_END(open); + if (err < 0) { + return env->ThrowUVException(err, "open", nullptr, path.out()); + } + env->AddUnmanagedFd(err); + args.GetReturnValue().Set(err); +} + static void OpenFileHandle(const FunctionCallbackInfo& args) { - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = binding_data->env(); - Isolate* isolate = env->isolate(); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Environment* env = realm->env(); const int argc = args.Length(); CHECK_GE(argc, 3); - BufferValue path(isolate, args[0]); + BufferValue path(realm->isolate(), args[0]); CHECK_NOT_NULL(*path); CHECK(args[1]->IsInt32()); @@ -2137,6 +2246,38 @@ static void CopyFile(const FunctionCallbackInfo& args) { } } +static void CopyFileSync(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + Isolate* isolate = env->isolate(); + + const int argc = args.Length(); + CHECK_GE(argc, 3); + + BufferValue src(isolate, args[0]); + CHECK_NOT_NULL(*src); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemRead, src.ToStringView()); + + BufferValue dest(isolate, args[1]); + CHECK_NOT_NULL(*dest); + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemWrite, dest.ToStringView()); + + CHECK(args[2]->IsInt32()); + const int flags = args[2].As()->Value(); + + uv_fs_t req; + FS_SYNC_TRACE_BEGIN(copyfile); + int err = + uv_fs_copyfile(nullptr, &req, src.out(), dest.out(), flags, nullptr); + uv_fs_req_cleanup(&req); + FS_SYNC_TRACE_END(copyfile); + + if (err) { + return env->ThrowUVException( + err, "copyfile", nullptr, src.out(), dest.out()); + } +} // Wrapper for write(2). // @@ -2399,6 +2540,69 @@ static void Read(const FunctionCallbackInfo& args) { } } +static void ReadFileUtf8(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + auto isolate = env->isolate(); + + CHECK_GE(args.Length(), 2); + + CHECK(args[1]->IsInt32()); + const int flags = args[1].As()->Value(); + + uv_file file; + uv_fs_t req; + + bool is_fd = args[0]->IsInt32(); + + // Check for file descriptor + if (is_fd) { + file = args[0].As()->Value(); + } else { + BufferValue path(env->isolate(), args[0]); + CHECK_NOT_NULL(*path); + if (CheckOpenPermissions(env, path, flags).IsNothing()) return; + + FS_SYNC_TRACE_BEGIN(open); + file = uv_fs_open(nullptr, &req, *path, flags, O_RDONLY, nullptr); + FS_SYNC_TRACE_END(open); + if (req.result < 0) { + uv_fs_req_cleanup(&req); + // req will be cleaned up by scope leave. + return env->ThrowUVException(req.result, "open", nullptr, path.out()); + } + } + + auto defer_close = OnScopeLeave([file, is_fd, &req]() { + if (!is_fd) { + FS_SYNC_TRACE_BEGIN(close); + CHECK_EQ(0, uv_fs_close(nullptr, &req, file, nullptr)); + FS_SYNC_TRACE_END(close); + } + uv_fs_req_cleanup(&req); + }); + + std::string result{}; + char buffer[8192]; + uv_buf_t buf = uv_buf_init(buffer, sizeof(buffer)); + + FS_SYNC_TRACE_BEGIN(read); + while (true) { + auto r = uv_fs_read(nullptr, &req, file, &buf, 1, -1, nullptr); + if (req.result < 0) { + FS_SYNC_TRACE_END(read); + // req will be cleaned up by scope leave. + return env->ThrowUVException(req.result, "read", nullptr); + } + if (r <= 0) { + break; + } + result.append(buf.base, r); + } + FS_SYNC_TRACE_END(read); + + args.GetReturnValue().Set( + ToV8Value(env->context(), result, isolate).ToLocalChecked()); +} // Wrapper for readv(2). // @@ -2511,7 +2715,6 @@ static void FChmod(const FunctionCallbackInfo& args) { } } - /* fs.chown(path, uid, gid); * Wrapper for chown(1) / EIO_CHOWN */ @@ -3034,10 +3237,11 @@ void BindingData::LegacyMainResolve(const FunctionCallbackInfo& args) { return; } - std::string err_module_message = - "Cannot find package '" + module_path + "' imported from " + module_base; env->isolate()->ThrowException( - ERR_MODULE_NOT_FOUND(env->isolate(), err_module_message.c_str())); + ERR_MODULE_NOT_FOUND(env->isolate(), + "Cannot find package '%s' imported from %s", + module_path, + module_base)); } void BindingData::MemoryInfo(MemoryTracker* tracker) const { @@ -3105,12 +3309,12 @@ void BindingData::Deserialize(Local context, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); InternalFieldInfo* casted_info = static_cast(info); BindingData* binding = - realm->AddBindingData(context, holder, casted_info); + realm->AddBindingData(holder, casted_info); CHECK_NOT_NULL(binding); } @@ -3133,7 +3337,7 @@ bool BindingData::PrepareForSerialization(Local context, } InternalFieldInfoBase* BindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = internal_field_info_; internal_field_info_ = nullptr; return info; @@ -3157,10 +3361,15 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, Isolate* isolate = isolate_data->isolate(); SetMethod(isolate, target, "access", Access); + SetMethodNoSideEffect(isolate, target, "accessSync", AccessSync); SetMethod(isolate, target, "close", Close); + SetMethod(isolate, target, "closeSync", CloseSync); + SetMethodNoSideEffect(isolate, target, "existsSync", ExistsSync); SetMethod(isolate, target, "open", Open); + SetMethod(isolate, target, "openSync", OpenSync); SetMethod(isolate, target, "openFileHandle", OpenFileHandle); SetMethod(isolate, target, "read", Read); + SetMethodNoSideEffect(isolate, target, "readFileUtf8", ReadFileUtf8); SetMethod(isolate, target, "readBuffers", ReadBuffers); SetMethod(isolate, target, "fdatasync", Fdatasync); SetMethod(isolate, target, "fsync", Fsync); @@ -3172,10 +3381,11 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, SetMethod(isolate, target, "internalModuleReadJSON", InternalModuleReadJSON); SetMethod(isolate, target, "internalModuleStat", InternalModuleStat); SetMethod(isolate, target, "stat", Stat); + SetMethod(isolate, target, "statSync", StatSync); SetMethod(isolate, target, "lstat", LStat); SetMethod(isolate, target, "fstat", FStat); - SetMethodNoSideEffect(isolate, target, "readFileSync", ReadFileSync); SetMethod(isolate, target, "statfs", StatFs); + SetMethod(isolate, target, "statfsSync", StatFsSync); SetMethod(isolate, target, "link", Link); SetMethod(isolate, target, "symlink", Symlink); SetMethod(isolate, target, "readlink", ReadLink); @@ -3185,6 +3395,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, SetMethod(isolate, target, "writeString", WriteString); SetMethod(isolate, target, "realpath", RealPath); SetMethod(isolate, target, "copyFile", CopyFile); + SetMethodNoSideEffect(isolate, target, "copyFileSync", CopyFileSync); SetMethod(isolate, target, "chmod", Chmod); SetMethod(isolate, target, "fchmod", FChmod); @@ -3263,7 +3474,7 @@ static void CreatePerContextProperties(Local target, Local context, void* priv) { Realm* realm = Realm::GetCurrent(context); - realm->AddBindingData(context, target); + realm->AddBindingData(target); } BindingData* FSReqBase::binding_data() { @@ -3272,13 +3483,18 @@ BindingData* FSReqBase::binding_data() { void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(Access); + registry->Register(AccessSync); StatWatcher::RegisterExternalReferences(registry); BindingData::RegisterExternalReferences(registry); registry->Register(Close); + registry->Register(CloseSync); + registry->Register(ExistsSync); registry->Register(Open); + registry->Register(OpenSync); registry->Register(OpenFileHandle); registry->Register(Read); + registry->Register(ReadFileUtf8); registry->Register(ReadBuffers); registry->Register(Fdatasync); registry->Register(Fsync); @@ -3290,10 +3506,11 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(InternalModuleReadJSON); registry->Register(InternalModuleStat); registry->Register(Stat); + registry->Register(StatSync); registry->Register(LStat); registry->Register(FStat); - registry->Register(ReadFileSync); registry->Register(StatFs); + registry->Register(StatFsSync); registry->Register(Link); registry->Register(Symlink); registry->Register(ReadLink); @@ -3303,6 +3520,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(WriteString); registry->Register(RealPath); registry->Register(CopyFile); + registry->Register(CopyFileSync); registry->Register(Chmod); registry->Register(FChmod); diff --git a/src/node_http2.cc b/src/node_http2.cc index 01d0eb3418b39f..070b40ae0a6ad6 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -2650,12 +2650,12 @@ void Http2Session::RefreshState(const FunctionCallbackInfo& args) { // Constructor for new Http2Session instances. void Http2Session::New(const FunctionCallbackInfo& args) { - Http2State* state = Realm::GetBindingData(args); - Environment* env = state->env(); + Realm* realm = Realm::GetCurrent(args); + Http2State* state = realm->GetBindingData(); + CHECK(args.IsConstructCall()); - SessionType type = - static_cast( - args[0]->Int32Value(env->context()).ToChecked()); + SessionType type = static_cast( + args[0]->Int32Value(realm->context()).ToChecked()); Http2Session* session = new Http2Session(state, args.This(), type); Debug(session, "session created"); } @@ -3180,7 +3180,7 @@ void Initialize(Local target, Isolate* isolate = env->isolate(); HandleScope handle_scope(isolate); - Http2State* const state = realm->AddBindingData(context, target); + Http2State* const state = realm->AddBindingData(target); if (state == nullptr) return; #define SET_STATE_TYPEDARRAY(name, field) \ diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index e1944d90557316..20c1bbb0bf9a06 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -84,8 +84,18 @@ const uint32_t kLenientNone = 0; const uint32_t kLenientHeaders = 1 << 0; const uint32_t kLenientChunkedLength = 1 << 1; const uint32_t kLenientKeepAlive = 1 << 2; -const uint32_t kLenientAll = kLenientHeaders | kLenientChunkedLength | - kLenientKeepAlive; +const uint32_t kLenientTransferEncoding = 1 << 3; +const uint32_t kLenientVersion = 1 << 4; +const uint32_t kLenientDataAfterClose = 1 << 5; +const uint32_t kLenientOptionalLFAfterCR = 1 << 6; +const uint32_t kLenientOptionalCRLFAfterChunk = 1 << 7; +const uint32_t kLenientOptionalCRBeforeLF = 1 << 8; +const uint32_t kLenientSpacesAfterChunkSize = 1 << 9; +const uint32_t kLenientAll = + kLenientHeaders | kLenientChunkedLength | kLenientKeepAlive | + kLenientTransferEncoding | kLenientVersion | kLenientDataAfterClose | + kLenientOptionalLFAfterCR | kLenientOptionalCRLFAfterChunk | + kLenientOptionalCRBeforeLF | kLenientSpacesAfterChunkSize; inline bool IsOWS(char c) { return c == ' ' || c == '\t'; @@ -930,6 +940,27 @@ class Parser : public AsyncWrap, public StreamListener { if (lenient_flags & kLenientKeepAlive) { llhttp_set_lenient_keep_alive(&parser_, 1); } + if (lenient_flags & kLenientTransferEncoding) { + llhttp_set_lenient_transfer_encoding(&parser_, 1); + } + if (lenient_flags & kLenientVersion) { + llhttp_set_lenient_version(&parser_, 1); + } + if (lenient_flags & kLenientDataAfterClose) { + llhttp_set_lenient_data_after_close(&parser_, 1); + } + if (lenient_flags & kLenientOptionalLFAfterCR) { + llhttp_set_lenient_optional_lf_after_cr(&parser_, 1); + } + if (lenient_flags & kLenientOptionalCRLFAfterChunk) { + llhttp_set_lenient_optional_crlf_after_chunk(&parser_, 1); + } + if (lenient_flags & kLenientOptionalCRBeforeLF) { + llhttp_set_lenient_optional_cr_before_lf(&parser_, 1); + } + if (lenient_flags & kLenientSpacesAfterChunkSize) { + llhttp_set_lenient_spaces_after_chunk_size(&parser_, 1); + } header_nread_ = 0; url_.Reset(); @@ -1203,8 +1234,7 @@ void InitializeHttpParser(Local target, Realm* realm = Realm::GetCurrent(context); Environment* env = realm->env(); Isolate* isolate = env->isolate(); - BindingData* const binding_data = - realm->AddBindingData(context, target); + BindingData* const binding_data = realm->AddBindingData(target); if (binding_data == nullptr) return; Local t = NewFunctionTemplate(isolate, Parser::New); @@ -1237,6 +1267,23 @@ void InitializeHttpParser(Local target, Integer::NewFromUnsigned(env->isolate(), kLenientChunkedLength)); t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientKeepAlive"), Integer::NewFromUnsigned(env->isolate(), kLenientKeepAlive)); + t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientTransferEncoding"), + Integer::NewFromUnsigned(env->isolate(), kLenientTransferEncoding)); + t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientVersion"), + Integer::NewFromUnsigned(env->isolate(), kLenientVersion)); + t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientDataAfterClose"), + Integer::NewFromUnsigned(env->isolate(), kLenientDataAfterClose)); + t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientOptionalLFAfterCR"), + Integer::NewFromUnsigned(env->isolate(), kLenientOptionalLFAfterCR)); + t->Set( + FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientOptionalCRLFAfterChunk"), + Integer::NewFromUnsigned(env->isolate(), kLenientOptionalCRLFAfterChunk)); + t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientOptionalCRBeforeLF"), + Integer::NewFromUnsigned(env->isolate(), kLenientOptionalCRBeforeLF)); + t->Set( + FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientSpacesAfterChunkSize"), + Integer::NewFromUnsigned(env->isolate(), kLenientSpacesAfterChunkSize)); + t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kLenientAll"), Integer::NewFromUnsigned(env->isolate(), kLenientAll)); diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 372df8d029fc4f..d45325954d9807 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -54,20 +54,21 @@ #include "util-inl.h" #include "v8.h" -#include #include +#include #include #include +#include #include #include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include #include -#include #ifdef NODE_HAVE_SMALL_ICU /* if this is defined, we have a 'secondary' entry point. @@ -569,8 +570,7 @@ ConverterObject::ConverterObject( } } - -bool InitializeICUDirectory(const std::string& path) { +bool InitializeICUDirectory(const std::string& path, std::string* error) { UErrorCode status = U_ZERO_ERROR; if (path.empty()) { #ifdef NODE_HAVE_SMALL_ICU @@ -583,7 +583,12 @@ bool InitializeICUDirectory(const std::string& path) { u_setDataDirectory(path.c_str()); u_init(&status); } - return status == U_ZERO_ERROR; + if (status == U_ZERO_ERROR) { + return true; + } + + *error = u_errorName(status); + return false; } void SetDefaultTimeZone(const char* tzid) { diff --git a/src/node_i18n.h b/src/node_i18n.h index f32ade831b17a0..e516282865fb18 100644 --- a/src/node_i18n.h +++ b/src/node_i18n.h @@ -38,7 +38,7 @@ namespace node { namespace i18n { -bool InitializeICUDirectory(const std::string& path); +bool InitializeICUDirectory(const std::string& path, std::string* error); void SetDefaultTimeZone(const char* tzid); diff --git a/src/node_internals.h b/src/node_internals.h index 9243344eb788b5..d7f78664615fcf 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -318,7 +318,7 @@ void MarkBootstrapComplete(const v8::FunctionCallbackInfo& args); class InitializationResultImpl final : public InitializationResult { public: - ~InitializationResultImpl(); + ~InitializationResultImpl() = default; int exit_code() const { return static_cast(exit_code_enum()); } ExitCode exit_code_enum() const { return exit_code_; } bool early_return() const { return early_return_; } diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc index 41e5bee353a579..e1e456cfad9325 100644 --- a/src/node_main_instance.cc +++ b/src/node_main_instance.cc @@ -68,6 +68,8 @@ NodeMainInstance::~NodeMainInstance() { return; } // This should only be done on a main instance that owns its isolate. + // IsolateData must be freed before UnregisterIsolate() is called. + isolate_data_.reset(); platform_->UnregisterIsolate(isolate_); isolate_->Dispose(); } @@ -92,12 +94,16 @@ void NodeMainInstance::Run(ExitCode* exit_code, Environment* env) { bool runs_sea_code = false; #ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION if (sea::IsSingleExecutable()) { - runs_sea_code = true; sea::SeaResource sea = sea::FindSingleExecutableResource(); - std::string_view code = sea.code; - LoadEnvironment(env, code); + if (!sea.use_snapshot()) { + runs_sea_code = true; + std::string_view code = sea.main_code_or_snapshot; + LoadEnvironment(env, code); + } } #endif + // Either there is already a snapshot main function from SEA, or it's not + // a SEA at all. if (!runs_sea_code) { LoadEnvironment(env, StartExecutionCallback{}); } diff --git a/src/node_messaging.cc b/src/node_messaging.cc index 15f6af079fdba7..d3d2070d623c80 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -307,7 +307,7 @@ class SerializerDelegate : public ValueSerializer::Delegate { bool HasCustomHostObject(Isolate* isolate) override { return true; } Maybe IsHostObject(Isolate* isolate, Local object) override { - if (BaseObject::IsBaseObject(object)) { + if (BaseObject::IsBaseObject(env_->isolate_data(), object)) { return Just(true); } @@ -315,7 +315,7 @@ class SerializerDelegate : public ValueSerializer::Delegate { } Maybe WriteHostObject(Isolate* isolate, Local object) override { - if (BaseObject::IsBaseObject(object)) { + if (BaseObject::IsBaseObject(env_->isolate_data(), object)) { return WriteHostObject( BaseObjectPtr { Unwrap(object) }); } @@ -529,7 +529,7 @@ Maybe Message::Serialize(Environment* env, return Nothing(); } BaseObjectPtr host_object; - if (BaseObject::IsBaseObject(entry)) { + if (BaseObject::IsBaseObject(env->isolate_data(), entry)) { host_object = BaseObjectPtr{Unwrap(entry)}; } else { if (!JSTransferable::IsJSTransferable(env, context, entry)) { @@ -1328,7 +1328,7 @@ JSTransferable::NestedTransferables() const { continue; } Local obj = value.As(); - if (BaseObject::IsBaseObject(obj)) { + if (BaseObject::IsBaseObject(env()->isolate_data(), obj)) { ret.emplace_back(Unwrap(obj)); continue; } diff --git a/src/node_options.cc b/src/node_options.cc index c02752464c4ab5..b544f1209143c0 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -173,7 +173,7 @@ void EnvironmentOptions::CheckOptions(std::vector* errors, } else if (force_repl) { errors->push_back("either --watch or --interactive " "can be used, not both"); - } else if (argv->size() < 1 || (*argv)[1].empty()) { + } else if (!test_runner && (argv->size() < 1 || (*argv)[1].empty())) { errors->push_back("--watch requires specifying a file"); } @@ -396,7 +396,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { &EnvironmentOptions::experimental_wasm_modules, kAllowedInEnvvar); AddOption("--experimental-import-meta-resolve", - "experimental ES Module import.meta.resolve() support", + "experimental ES Module import.meta.resolve() parentURL support", &EnvironmentOptions::experimental_import_meta_resolve, kAllowedInEnvvar); AddOption("--experimental-permission", @@ -575,6 +575,12 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { "write warnings to file instead of stderr", &EnvironmentOptions::redirect_warnings, kAllowedInEnvvar); + AddOption( + "[has_env_file_string]", "", &EnvironmentOptions::has_env_file_string); + AddOption("--env-file", + "set environment variables from supplied file", + &EnvironmentOptions::env_file); + Implies("--env-file", "[has_env_file_string]"); AddOption("--test", "launch test runner on startup", &EnvironmentOptions::test_runner); diff --git a/src/node_options.h b/src/node_options.h index bb8b68894b4430..bc18a45e681a3c 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -121,8 +121,8 @@ class EnvironmentOptions : public Options { std::string experimental_policy_integrity; bool has_policy_integrity_string = false; bool experimental_permission = false; - std::string allow_fs_read; - std::string allow_fs_write; + std::vector allow_fs_read; + std::vector allow_fs_write; bool allow_child_process = false; bool allow_worker_threads = false; bool experimental_repl_await = true; @@ -158,6 +158,8 @@ class EnvironmentOptions : public Options { #endif // HAVE_INSPECTOR std::string redirect_warnings; std::string diagnostic_dir; + std::string env_file; + bool has_env_file_string = false; bool test_runner = false; bool test_runner_coverage = false; std::vector test_name_pattern; diff --git a/src/node_perf.cc b/src/node_perf.cc index 555a90b0a76091..360cc8bf673073 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -20,7 +20,6 @@ using v8::Function; using v8::FunctionCallbackInfo; using v8::GCCallbackFlags; using v8::GCType; -using v8::Int32; using v8::Integer; using v8::Isolate; using v8::Local; @@ -43,6 +42,7 @@ const double performance_process_start_timestamp = uint64_t performance_v8_start; PerformanceState::PerformanceState(Isolate* isolate, + uint64_t time_origin, const PerformanceState::SerializeInfo* info) : root(isolate, sizeof(performance_state_internal), @@ -58,24 +58,51 @@ PerformanceState::PerformanceState(Isolate* isolate, root, MAYBE_FIELD_PTR(info, observers)) { if (info == nullptr) { - for (size_t i = 0; i < milestones.Length(); i++) milestones[i] = -1.; + // For performance states initialized from scratch, reset + // all the milestones and initialize the time origin. + // For deserialized performance states, we will do the + // initialization in the deserialize callback. + ResetMilestones(); + Initialize(time_origin); + } +} + +void PerformanceState::ResetMilestones() { + size_t milestones_length = milestones.Length(); + for (size_t i = 0; i < milestones_length; ++i) { + milestones[i] = -1; } } PerformanceState::SerializeInfo PerformanceState::Serialize( v8::Local context, v8::SnapshotCreator* creator) { + // Reset all the milestones to improve determinism in the snapshot. + // We'll re-initialize them after deserialization. + ResetMilestones(); + SerializeInfo info{root.Serialize(context, creator), milestones.Serialize(context, creator), observers.Serialize(context, creator)}; return info; } -void PerformanceState::Deserialize(v8::Local context) { +void PerformanceState::Initialize(uint64_t time_origin) { + // We are only reusing the milestone array to store the time origin, so do + // not use the Mark() method. The time origin milestone is not exposed + // to user land. + this->milestones[NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN] = + static_cast(time_origin); +} + +void PerformanceState::Deserialize(v8::Local context, + uint64_t time_origin) { + // Resets the pointers. root.Deserialize(context); - // This is just done to set up the pointers, we will actually reset - // all the milestones after deserialization. milestones.Deserialize(context); observers.Deserialize(context); + + // Re-initialize the time origin i.e. the process start time. + Initialize(time_origin); } std::ostream& operator<<(std::ostream& o, @@ -96,18 +123,6 @@ void PerformanceState::Mark(PerformanceMilestone milestone, uint64_t ts) { TRACE_EVENT_SCOPE_THREAD, ts / 1000); } -// Allows specific Node.js lifecycle milestones to be set from JavaScript -void MarkMilestone(const FunctionCallbackInfo& args) { - Realm* realm = Realm::GetCurrent(args); - // TODO(legendecas): Remove this check once the sub-realms are supported. - CHECK_EQ(realm->kind(), Realm::Kind::kPrincipal); - Environment* env = realm->env(); - PerformanceMilestone milestone = - static_cast(args[0].As()->Value()); - if (milestone != NODE_PERFORMANCE_MILESTONE_INVALID) - env->performance_state()->Mark(milestone); -} - void SetupPerformanceObservers(const FunctionCallbackInfo& args) { Realm* realm = Realm::GetCurrent(args); // TODO(legendecas): Remove this check once the sub-realms are supported. @@ -221,18 +236,6 @@ static void RemoveGarbageCollectionTracking( GarbageCollectionCleanupHook(env); } -// Gets the name of a function -inline Local GetName(Local fn) { - Local val = fn->GetDebugName(); - if (val.IsEmpty() || val->IsUndefined()) { - Local boundFunction = fn->GetBoundFunction(); - if (!boundFunction.IsEmpty() && !boundFunction->IsUndefined()) { - val = GetName(boundFunction.As()); - } - } - return val; -} - // Notify a custom PerformanceEntry to observers void Notify(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -275,12 +278,6 @@ void CreateELDHistogram(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(histogram->object()); } -void GetTimeOrigin(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - args.GetReturnValue().Set( - Number::New(args.GetIsolate(), env->time_origin() / NANOS_PER_MILLIS)); -} - void GetTimeOriginTimeStamp(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); args.GetReturnValue().Set(Number::New( @@ -300,7 +297,6 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, HistogramBase::Initialize(isolate_data, target); - SetMethod(isolate, target, "markMilestone", MarkMilestone); SetMethod(isolate, target, "setupObservers", SetupPerformanceObservers); SetMethod(isolate, target, @@ -312,7 +308,6 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, RemoveGarbageCollectionTracking); SetMethod(isolate, target, "notify", Notify); SetMethod(isolate, target, "loopIdleTime", LoopIdleTime); - SetMethod(isolate, target, "getTimeOrigin", GetTimeOrigin); SetMethod(isolate, target, "getTimeOriginTimestamp", GetTimeOriginTimeStamp); SetMethod(isolate, target, "createELDHistogram", CreateELDHistogram); SetMethod(isolate, target, "markBootstrapComplete", MarkBootstrapComplete); @@ -373,13 +368,11 @@ void CreatePerContextProperties(Local target, } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { - registry->Register(MarkMilestone); registry->Register(SetupPerformanceObservers); registry->Register(InstallGarbageCollectionTracking); registry->Register(RemoveGarbageCollectionTracking); registry->Register(Notify); registry->Register(LoopIdleTime); - registry->Register(GetTimeOrigin); registry->Register(GetTimeOriginTimeStamp); registry->Register(CreateELDHistogram); registry->Register(MarkBootstrapComplete); diff --git a/src/node_perf_common.h b/src/node_perf_common.h index d519222616a174..dd757651c09e9f 100644 --- a/src/node_perf_common.h +++ b/src/node_perf_common.h @@ -24,15 +24,15 @@ extern const uint64_t performance_process_start; extern const double performance_process_start_timestamp; extern uint64_t performance_v8_start; -#define NODE_PERFORMANCE_MILESTONES(V) \ - V(ENVIRONMENT, "environment") \ - V(NODE_START, "nodeStart") \ - V(V8_START, "v8Start") \ - V(LOOP_START, "loopStart") \ - V(LOOP_EXIT, "loopExit") \ +#define NODE_PERFORMANCE_MILESTONES(V) \ + V(TIME_ORIGIN, "timeOrigin") \ + V(ENVIRONMENT, "environment") \ + V(NODE_START, "nodeStart") \ + V(V8_START, "v8Start") \ + V(LOOP_START, "loopStart") \ + V(LOOP_EXIT, "loopExit") \ V(BOOTSTRAP_COMPLETE, "bootstrapComplete") - #define NODE_PERFORMANCE_ENTRY_TYPES(V) \ V(GC, "gc") \ V(HTTP, "http") \ @@ -62,10 +62,12 @@ class PerformanceState { AliasedBufferIndex observers; }; - explicit PerformanceState(v8::Isolate* isolate, const SerializeInfo* info); + explicit PerformanceState(v8::Isolate* isolate, + uint64_t time_origin, + const SerializeInfo* info); SerializeInfo Serialize(v8::Local context, v8::SnapshotCreator* creator); - void Deserialize(v8::Local context); + void Deserialize(v8::Local context, uint64_t time_origin); friend std::ostream& operator<<(std::ostream& o, const SerializeInfo& i); AliasedUint8Array root; @@ -79,6 +81,8 @@ class PerformanceState { uint64_t ts = PERFORMANCE_NOW()); private: + void Initialize(uint64_t time_origin); + void ResetMilestones(); struct performance_state_internal { // doubles first so that they are always sizeof(double)-aligned double milestones[NODE_PERFORMANCE_MILESTONE_INVALID]; diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc index eca0b343baef3a..34d3c3af4c3e10 100644 --- a/src/node_process_methods.cc +++ b/src/node_process_methods.cc @@ -552,7 +552,7 @@ bool BindingData::PrepareForSerialization(Local context, } InternalFieldInfoBase* BindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = InternalFieldInfoBase::New(type()); return info; @@ -562,11 +562,11 @@ void BindingData::Deserialize(Local context, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); v8::HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); // Recreate the buffer in the constructor. - BindingData* binding = realm->AddBindingData(context, holder); + BindingData* binding = realm->AddBindingData(holder); CHECK_NOT_NULL(binding); } @@ -607,7 +607,7 @@ static void CreatePerContextProperties(Local target, Local context, void* priv) { Realm* realm = Realm::GetCurrent(context); - realm->AddBindingData(context, target); + realm->AddBindingData(target); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { diff --git a/src/node_realm-inl.h b/src/node_realm-inl.h index 748ecfe262afa2..fe20ac2b2fea3a 100644 --- a/src/node_realm-inl.h +++ b/src/node_realm-inl.h @@ -66,25 +66,23 @@ inline T* Realm::GetBindingData( // static template inline T* Realm::GetBindingData(v8::Local context) { - BindingDataStore* map = - static_cast(context->GetAlignedPointerFromEmbedderData( - ContextEmbedderIndex::kBindingDataStoreIndex)); - DCHECK_NOT_NULL(map); + Realm* realm = GetCurrent(context); + return realm->GetBindingData(); +} + +template +inline T* Realm::GetBindingData() { constexpr size_t binding_index = static_cast(T::binding_type_int); static_assert(binding_index < std::tuple_size_v); - auto ptr = (*map)[binding_index]; + auto ptr = binding_data_store_[binding_index]; if (UNLIKELY(!ptr)) return nullptr; T* result = static_cast(ptr.get()); DCHECK_NOT_NULL(result); - DCHECK_EQ(result->realm(), GetCurrent(context)); return result; } template -inline T* Realm::AddBindingData(v8::Local context, - v8::Local target, - Args&&... args) { - DCHECK_EQ(GetCurrent(context), this); +inline T* Realm::AddBindingData(v8::Local target, Args&&... args) { // This won't compile if T is not a BaseObject subclass. static_assert(std::is_base_of_v); // The binding data must be weak so that it won't keep the realm reachable @@ -93,15 +91,11 @@ inline T* Realm::AddBindingData(v8::Local context, // reachable throughout the lifetime of the realm. BaseObjectWeakPtr item = MakeWeakBaseObject(this, target, std::forward(args)...); - DCHECK_EQ(context->GetAlignedPointerFromEmbedderData( - ContextEmbedderIndex::kBindingDataStoreIndex), - &binding_data_store_); constexpr size_t binding_index = static_cast(T::binding_type_int); static_assert(binding_index < std::tuple_size_v); - // Should not insert the binding twice. + // Each slot is expected to be assigned only once. CHECK(!binding_data_store_[binding_index]); binding_data_store_[binding_index] = item; - DCHECK_EQ(GetBindingData(context), item.get()); return item.get(); } diff --git a/src/node_realm.h b/src/node_realm.h index 6cca9d5041d3fb..51fbd502a10eb6 100644 --- a/src/node_realm.h +++ b/src/node_realm.h @@ -93,9 +93,7 @@ class Realm : public MemoryRetainer { // this scope can access the created T* object using // GetBindingData(args) later. template - T* AddBindingData(v8::Local context, - v8::Local target, - Args&&... args); + T* AddBindingData(v8::Local target, Args&&... args); template static inline T* GetBindingData(const v8::PropertyCallbackInfo& info); template @@ -103,6 +101,8 @@ class Realm : public MemoryRetainer { const v8::FunctionCallbackInfo& info); template static inline T* GetBindingData(v8::Local context); + template + inline T* GetBindingData(); inline BindingDataStore* binding_data_store(); // The BaseObject count is a debugging helper that makes sure that there are diff --git a/src/node_report.cc b/src/node_report.cc index dcaa6922070b92..88c9a97789e30b 100644 --- a/src/node_report.cc +++ b/src/node_report.cc @@ -857,9 +857,13 @@ std::string TriggerNodeReport(Isolate* isolate, // Determine the required report filename. In order of priority: // 1) supplied on API 2) configured on startup 3) default generated if (!name.empty()) { - THROW_IF_INSUFFICIENT_PERMISSIONS( - env, permission::PermissionScope::kFileSystemWrite, name, name); - // Filename was specified as API parameter. + // we may not always be in a great state when generating a node report + // allow for the case where we don't have an env + if (env != nullptr) { + THROW_IF_INSUFFICIENT_PERMISSIONS( + env, permission::PermissionScope::kFileSystemWrite, name, name); + // Filename was specified as API parameter. + } filename = name; } else { std::string report_filename; @@ -878,7 +882,7 @@ std::string TriggerNodeReport(Isolate* isolate, THROW_IF_INSUFFICIENT_PERMISSIONS( env, permission::PermissionScope::kFileSystemWrite, - std::string_view(env->GetCwd()), + std::string_view(Environment::GetCwd(env->exec_path())), filename); } } diff --git a/src/node_root_certs.h b/src/node_root_certs.h index f2608086aa9f1c..2d30eef6192d05 100644 --- a/src/node_root_certs.h +++ b/src/node_root_certs.h @@ -589,26 +589,6 @@ "dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=\n" "-----END CERTIFICATE-----", -/* Hongkong Post Root CA 1 */ -"-----BEGIN CERTIFICATE-----\n" -"MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNV\n" -"BAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4X\n" -"DTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT\n" -"DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjAN\n" -"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSS\n" -"HSL22oVyaf7XPwnU3ZG1ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8g\n" -"PW2iNr4joLFutbEnPzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7j\n" -"EAaPIpjhZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9\n" -"nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208\n" -"o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQE\n" -"AwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsCmEEIjEy82tvuJxuC52pF7BaL\n" -"T4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37piol7Yutmcn1KZJ/RyTZXaeQi/cImya\n" -"T/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgC\n" -"IDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES\n" -"7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4Jx\n" -"HYB0yvbiAmvZWg==\n" -"-----END CERTIFICATE-----", - /* SecureSign RootCA11 */ "-----BEGIN CERTIFICATE-----\n" "MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UE\n" @@ -1250,40 +1230,6 @@ "SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=\n" "-----END CERTIFICATE-----", -/* E-Tugra Certification Authority */ -"-----BEGIN CERTIFICATE-----\n" -"MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRS\n" -"MQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtu\n" -"b2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlm\n" -"aWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9y\n" -"aXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8w\n" -"DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xv\n" -"amlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWth\n" -"c3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5\n" -"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq98\n" -"99SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0b\n" -"QNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSFQ9OArqGIW66z6l7LFpp3RMih\n" -"9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+gElIwcxmOj+GMB6LDu0rw6h8VqO4l\n" -"zKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3\n" -"fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2o\n" -"MoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QO\n" -"XVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8\n" -"zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+LznrFpct1pH\n" -"XFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5dUyQ\n" -"5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB\n" -"/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQD\n" -"AgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd\n" -"0dCrfOAKkEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/\n" -"u6Au/U5Mh/jOXKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1\n" -"Q9Jauz1c77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3\n" -"+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5\n" -"TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4\n" -"R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDY\n" -"wKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186\n" -"zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9\n" -"I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==\n" -"-----END CERTIFICATE-----", - /* T-TeleSec GlobalRoot Class 2 */ "-----BEGIN CERTIFICATE-----\n" "MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNV\n" @@ -3268,56 +3214,6 @@ "Nzf43TNRnXCve1XYAS59BWQOhriR\n" "-----END CERTIFICATE-----", -/* E-Tugra Global Root CA RSA v3 */ -"-----BEGIN CERTIFICATE-----\n" -"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\n" -"3Qt6f4ueJiDPO++BcYNZ\n" -"-----END CERTIFICATE-----", - -/* E-Tugra Global Root CA ECC v3 */ -"-----BEGIN CERTIFICATE-----\n" -"MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJ\n" -"BgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4x\n" -"HTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2Jh\n" -"bCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQsw\n" -"CQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMu\n" -"MR0wGwYDVQQLExRFLVR1Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9i\n" -"YWwgUm9vdCBDQSBFQ0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8wo\n" -"LNheSBkQKczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK\n" -"fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYD\n" -"VR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGw\n" -"UYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZ\n" -"CL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4WAie3AjEA3VoXK3YdZUKWpqxdinlW\n" -"2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3\n" -"-----END CERTIFICATE-----", - /* Security Communication RootCA3 */ "-----BEGIN CERTIFICATE-----\n" "MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQ\n" @@ -3408,4 +3304,140 @@ "SG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l\n" "1lOWqzzIQNph91Oj9w==\n" "-----END CERTIFICATE-----", + +/* Sectigo Public Server Authentication Root E46 */ +"-----BEGIN CERTIFICATE-----\n" +"MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQG\n" +"EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp\n" +"YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYw\n" +"MzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYw\n" +"NAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYw\n" +"djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2q\n" +"w7LFeeyZYX8QeccCWvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVS\n" +"tSBDHBv+6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B\n" +"Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeX\n" +"lImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7y\n" +"n2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==\n" +"-----END CERTIFICATE-----", + +/* Sectigo Public Server Authentication Root R46 */ +"-----BEGIN CERTIFICATE-----\n" +"MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYD\n" +"VQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1\n" +"YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcN\n" +"NDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVk\n" +"MTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBS\n" +"NDYwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch\n" +"/cSV1UgrJnwUUxDaef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNt\n" +"JZlMKpnzSDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf\n" +"iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5Hw\n" +"cCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL5\n" +"0V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OASVYCmO2a0OYctyPDQ0RTp5A1N\n" +"DvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/AwSiItOkcyqex8Va3e0lMWeUgFaiE\n" +"Ain6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYw\n" +"jviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0\n" +"ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi\n" +"1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P\n" +"AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9cmTz8Bl6M\n" +"lC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYpE0RH\n" +"ap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4\n" +"exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yE\n" +"vJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5pa\n" +"PHxsnnVI84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD\n" +"9joiFgOgyY9mpFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7\n" +"G6aXD+u5dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65\n" +"LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk\n" +"50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOI\n" +"ijlBO8n9pu0f9GBj39ItVQGL\n" +"-----END CERTIFICATE-----", + +/* SSL.com TLS RSA Root CA 2022 */ +"-----BEGIN CERTIFICATE-----\n" +"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\n" +"kLGCenROmxMmtNVQZlR4rmA=\n" +"-----END CERTIFICATE-----", + +/* SSL.com TLS ECC Root CA 2022 */ +"-----BEGIN CERTIFICATE-----\n" +"MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQG\n" +"EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBF\n" +"Q0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkG\n" +"A1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBU\n" +"TFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9\n" +"qLFNoFs27iosU8NgCTWyJGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJY\n" +"WWf9lCcQZIxPBLFNSeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAf\n" +"BgNVHSMEGDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW\n" +"uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8e\n" +"lDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeNb0Igj762TVntd00p\n" +"xCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==\n" +"-----END CERTIFICATE-----", + +/* Atos TrustedRoot Root CA ECC TLS 2021 */ +"-----BEGIN CERTIFICATE-----\n" +"MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQD\n" +"DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9z\n" +"MQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNV\n" +"BAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0\n" +"b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHk\n" +"BQcfl+3oZIK59sRxUM6KDP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5K\n" +"TlbgmClBk1IQ1SQ4AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\n" +"DgQWBBR2KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD\n" +"aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rI\n" +"AjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo9H1/IISpQuQo\n" +"-----END CERTIFICATE-----", + +/* Atos TrustedRoot Root CA RSA TLS 2021 */ +"-----BEGIN CERTIFICATE-----\n" +"MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYD\n" +"VQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARB\n" +"dG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAs\n" +"BgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoM\n" +"BEF0b3MxCzAJBgNVBAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAO\n" +"xHm9BYx9sKOdTSJNy/BBl01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1m\n" +"x4QbZFc4nXUtVsYvYe+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3\n" +"W3WsgFWZkmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs\n" +"GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWp\n" +"o63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh3El+fsqyjW22v5Mv\n" +"oVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD0xeqqxmjLBvk1cbiZnrXghmm\n" +"OxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBYBr3JtuP2iV2J+axEoctr+hbxx1A9\n" +"JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842\n" +"mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct\n" +"+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n" +"HQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB\n" +"DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS4BjHeJi7\n" +"8+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCplQ3IM\n" +"98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX\n" +"AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee\n" +"7c9GslA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh\n" +"7tew2VktafcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng\n" +"33eU0aKAQv9qTFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEF\n" +"WDlN5LuYo7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5\n" +"dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDw\n" +"N/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==\n" +"-----END CERTIFICATE-----", #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/node_sea.cc b/src/node_sea.cc index 88741a5fce9d48..521f2f670b28c8 100644 --- a/src/node_sea.cc +++ b/src/node_sea.cc @@ -4,9 +4,14 @@ #include "debug_utils-inl.h" #include "env-inl.h" #include "json_parser.h" +#include "node_contextify.h" +#include "node_errors.h" #include "node_external_reference.h" #include "node_internals.h" +#include "node_snapshot_builder.h" #include "node_union_bytes.h" +#include "node_v8_platform-inl.h" +#include "util-inl.h" // The POSTJECT_SENTINEL_FUSE macro is a string of random characters selected by // the Node.js project that is present only once in the entire binary. It is @@ -25,10 +30,19 @@ #if !defined(DISABLE_SINGLE_EXECUTABLE_APPLICATION) using node::ExitCode; +using v8::ArrayBuffer; +using v8::BackingStore; using v8::Context; +using v8::DataView; +using v8::Function; using v8::FunctionCallbackInfo; +using v8::HandleScope; +using v8::Isolate; using v8::Local; +using v8::NewStringType; using v8::Object; +using v8::ScriptCompiler; +using v8::String; using v8::Value; namespace node { @@ -64,7 +78,7 @@ class SeaSerializer : public BlobSerializer { template <> size_t SeaSerializer::Write(const SeaResource& sea) { - sink.reserve(SeaResource::kHeaderSize + sea.code.size()); + sink.reserve(SeaResource::kHeaderSize + sea.main_code_or_snapshot.size()); Debug("Write SEA magic %x\n", kMagic); size_t written_total = WriteArithmetic(kMagic); @@ -74,10 +88,28 @@ size_t SeaSerializer::Write(const SeaResource& sea) { written_total += WriteArithmetic(flags); DCHECK_EQ(written_total, SeaResource::kHeaderSize); - Debug("Write SEA resource code %p, size=%zu\n", - sea.code.data(), - sea.code.size()); - written_total += WriteStringView(sea.code, StringLogMode::kAddressAndContent); + Debug("Write SEA code path %p, size=%zu\n", + sea.code_path.data(), + sea.code_path.size()); + written_total += + WriteStringView(sea.code_path, StringLogMode::kAddressAndContent); + + Debug("Write SEA resource %s %p, size=%zu\n", + sea.use_snapshot() ? "snapshot" : "code", + sea.main_code_or_snapshot.data(), + sea.main_code_or_snapshot.size()); + written_total += + WriteStringView(sea.main_code_or_snapshot, + sea.use_snapshot() ? StringLogMode::kAddressOnly + : StringLogMode::kAddressAndContent); + + if (sea.code_cache.has_value()) { + Debug("Write SEA resource code cache %p, size=%zu\n", + sea.code_cache->data(), + sea.code_cache->size()); + written_total += + WriteStringView(sea.code_cache.value(), StringLogMode::kAddressOnly); + } return written_total; } @@ -103,9 +135,29 @@ SeaResource SeaDeserializer::Read() { Debug("Read SEA flags %x\n", static_cast(flags)); CHECK_EQ(read_total, SeaResource::kHeaderSize); - std::string_view code = ReadStringView(StringLogMode::kAddressAndContent); - Debug("Read SEA resource code %p, size=%zu\n", code.data(), code.size()); - return {flags, code}; + std::string_view code_path = + ReadStringView(StringLogMode::kAddressAndContent); + Debug( + "Read SEA code path %p, size=%zu\n", code_path.data(), code_path.size()); + + bool use_snapshot = static_cast(flags & SeaFlags::kUseSnapshot); + std::string_view code = + ReadStringView(use_snapshot ? StringLogMode::kAddressOnly + : StringLogMode::kAddressAndContent); + + Debug("Read SEA resource %s %p, size=%zu\n", + use_snapshot ? "snapshot" : "code", + code.data(), + code.size()); + + std::string_view code_cache; + if (static_cast(flags & SeaFlags::kUseCodeCache)) { + code_cache = ReadStringView(StringLogMode::kAddressOnly); + Debug("Read SEA resource code cache %p, size=%zu\n", + code_cache.data(), + code_cache.size()); + } + return {flags, code_path, code, code_cache}; } std::string_view FindSingleExecutableBlob() { @@ -133,6 +185,10 @@ std::string_view FindSingleExecutableBlob() { } // anonymous namespace +bool SeaResource::use_snapshot() const { + return static_cast(flags & SeaFlags::kUseSnapshot); +} + SeaResource FindSingleExecutableResource() { static const SeaResource sea_resource = []() -> SeaResource { std::string_view blob = FindSingleExecutableBlob(); @@ -150,7 +206,18 @@ bool IsSingleExecutable() { return postject_has_resource(); } +void IsSea(const FunctionCallbackInfo& args) { + args.GetReturnValue().Set(IsSingleExecutable()); +} + void IsExperimentalSeaWarningNeeded(const FunctionCallbackInfo& args) { + bool is_building_sea = + !per_process::cli_options->experimental_sea_config.empty(); + if (is_building_sea) { + args.GetReturnValue().Set(true); + return; + } + if (!IsSingleExecutable()) { args.GetReturnValue().Set(false); return; @@ -161,6 +228,54 @@ void IsExperimentalSeaWarningNeeded(const FunctionCallbackInfo& args) { sea_resource.flags & SeaFlags::kDisableExperimentalSeaWarning)); } +void GetCodeCache(const FunctionCallbackInfo& args) { + if (!IsSingleExecutable()) { + return; + } + + Isolate* isolate = args.GetIsolate(); + + SeaResource sea_resource = FindSingleExecutableResource(); + + if (!static_cast(sea_resource.flags & SeaFlags::kUseCodeCache)) { + return; + } + + std::shared_ptr backing_store = ArrayBuffer::NewBackingStore( + const_cast( + static_cast(sea_resource.code_cache->data())), + sea_resource.code_cache->length(), + [](void* /* data */, size_t /* length */, void* /* deleter_data */) { + // The code cache data blob is not freed here because it is a static + // blob which is not allocated by the BackingStore allocator. + }, + nullptr); + Local array_buffer = ArrayBuffer::New(isolate, backing_store); + Local data_view = + DataView::New(array_buffer, 0, array_buffer->ByteLength()); + + args.GetReturnValue().Set(data_view); +} + +void GetCodePath(const FunctionCallbackInfo& args) { + DCHECK(IsSingleExecutable()); + + Isolate* isolate = args.GetIsolate(); + + SeaResource sea_resource = FindSingleExecutableResource(); + + Local code_path; + if (!String::NewFromUtf8(isolate, + sea_resource.code_path.data(), + NewStringType::kNormal, + sea_resource.code_path.length()) + .ToLocal(&code_path)) { + return; + } + + args.GetReturnValue().Set(code_path); +} + std::tuple FixupArgsForSEA(int argc, char** argv) { // Repeats argv[0] at position 1 on argv as a replacement for the missing // entry point file path. @@ -235,10 +350,122 @@ std::optional ParseSingleExecutableConfig( result.flags |= SeaFlags::kDisableExperimentalSeaWarning; } + std::optional use_snapshot = parser.GetTopLevelBoolField("useSnapshot"); + if (!use_snapshot.has_value()) { + FPrintF( + stderr, "\"useSnapshot\" field of %s is not a Boolean\n", config_path); + return std::nullopt; + } + if (use_snapshot.value()) { + result.flags |= SeaFlags::kUseSnapshot; + } + + std::optional use_code_cache = + parser.GetTopLevelBoolField("useCodeCache"); + if (!use_code_cache.has_value()) { + FPrintF( + stderr, "\"useCodeCache\" field of %s is not a Boolean\n", config_path); + return std::nullopt; + } + if (use_code_cache.value()) { + result.flags |= SeaFlags::kUseCodeCache; + } + return result; } -ExitCode GenerateSingleExecutableBlob(const SeaConfig& config) { +ExitCode GenerateSnapshotForSEA(const SeaConfig& config, + const std::vector& args, + const std::vector& exec_args, + const std::string& main_script, + std::vector* snapshot_blob) { + SnapshotData snapshot; + // TODO(joyeecheung): make the arguments configurable through the JSON + // config or a programmatic API. + std::vector patched_args = {args[0], config.main_path}; + ExitCode exit_code = SnapshotBuilder::Generate( + &snapshot, patched_args, exec_args, main_script); + if (exit_code != ExitCode::kNoFailure) { + return exit_code; + } + auto& persistents = snapshot.env_info.principal_realm.persistent_values; + auto it = std::find_if( + persistents.begin(), persistents.end(), [](const PropInfo& prop) { + return prop.name == "snapshot_deserialize_main"; + }); + if (it == persistents.end()) { + FPrintF( + stderr, + "%s does not invoke " + "v8.startupSnapshot.setDeserializeMainFunction(), which is required " + "for snapshot scripts used to build single executable applications." + "\n", + config.main_path); + return ExitCode::kGenericUserError; + } + // We need the temporary variable for copy elision. + std::vector temp = snapshot.ToBlob(); + *snapshot_blob = std::move(temp); + return ExitCode::kNoFailure; +} + +std::optional GenerateCodeCache(std::string_view main_path, + std::string_view main_script) { + RAIIIsolate raii_isolate(SnapshotBuilder::GetEmbeddedSnapshotData()); + Isolate* isolate = raii_isolate.get(); + + HandleScope handle_scope(isolate); + Local context = Context::New(isolate); + Context::Scope context_scope(context); + + errors::PrinterTryCatch bootstrapCatch( + isolate, errors::PrinterTryCatch::kPrintSourceLine); + + Local filename; + if (!String::NewFromUtf8(isolate, + main_path.data(), + NewStringType::kNormal, + main_path.length()) + .ToLocal(&filename)) { + return std::nullopt; + } + + Local content; + if (!String::NewFromUtf8(isolate, + main_script.data(), + NewStringType::kNormal, + main_script.length()) + .ToLocal(&content)) { + return std::nullopt; + } + + std::vector> parameters = { + FIXED_ONE_BYTE_STRING(isolate, "exports"), + FIXED_ONE_BYTE_STRING(isolate, "require"), + FIXED_ONE_BYTE_STRING(isolate, "module"), + FIXED_ONE_BYTE_STRING(isolate, "__filename"), + FIXED_ONE_BYTE_STRING(isolate, "__dirname"), + }; + + // TODO(RaisinTen): Using the V8 code cache prevents us from using `import()` + // in the SEA code. Support it. + // Refs: https://github.com/nodejs/node/pull/48191#discussion_r1213271430 + Local fn; + if (!contextify::CompileFunction(context, filename, content, ¶meters) + .ToLocal(&fn)) { + return std::nullopt; + } + + std::unique_ptr cache{ + ScriptCompiler::CreateCodeCacheForFunction(fn)}; + std::string code_cache(cache->data, cache->data + cache->length); + return code_cache; +} + +ExitCode GenerateSingleExecutableBlob( + const SeaConfig& config, + const std::vector& args, + const std::vector& exec_args) { std::string main_script; // TODO(joyeecheung): unify the file utils. int r = ReadFileSync(&main_script, config.main_path.c_str()); @@ -248,7 +475,42 @@ ExitCode GenerateSingleExecutableBlob(const SeaConfig& config) { return ExitCode::kGenericUserError; } - SeaResource sea{config.flags, main_script}; + std::vector snapshot_blob; + bool builds_snapshot_from_main = + static_cast(config.flags & SeaFlags::kUseSnapshot); + if (builds_snapshot_from_main) { + ExitCode exit_code = GenerateSnapshotForSEA( + config, args, exec_args, main_script, &snapshot_blob); + if (exit_code != ExitCode::kNoFailure) { + return exit_code; + } + } + + std::optional optional_sv_code_cache; + std::string code_cache; + if (static_cast(config.flags & SeaFlags::kUseCodeCache)) { + if (builds_snapshot_from_main) { + FPrintF(stderr, + "\"useCodeCache\" is redundant when \"useSnapshot\" is true\n"); + } else { + std::optional optional_code_cache = + GenerateCodeCache(config.main_path, main_script); + if (!optional_code_cache.has_value()) { + FPrintF(stderr, "Cannot generate V8 code cache\n"); + return ExitCode::kGenericUserError; + } + code_cache = optional_code_cache.value(); + optional_sv_code_cache = code_cache; + } + } + + SeaResource sea{ + config.flags, + config.main_path, + builds_snapshot_from_main + ? std::string_view{snapshot_blob.data(), snapshot_blob.size()} + : std::string_view{main_script.data(), main_script.size()}, + optional_sv_code_cache}; SeaSerializer serializer; serializer.Write(sea); @@ -269,11 +531,14 @@ ExitCode GenerateSingleExecutableBlob(const SeaConfig& config) { } // anonymous namespace -ExitCode BuildSingleExecutableBlob(const std::string& config_path) { +ExitCode BuildSingleExecutableBlob(const std::string& config_path, + const std::vector& args, + const std::vector& exec_args) { std::optional config_opt = ParseSingleExecutableConfig(config_path); if (config_opt.has_value()) { - ExitCode code = GenerateSingleExecutableBlob(config_opt.value()); + ExitCode code = + GenerateSingleExecutableBlob(config_opt.value(), args, exec_args); return code; } @@ -284,14 +549,20 @@ void Initialize(Local target, Local unused, Local context, void* priv) { + SetMethod(context, target, "isSea", IsSea); SetMethod(context, target, "isExperimentalSeaWarningNeeded", IsExperimentalSeaWarningNeeded); + SetMethod(context, target, "getCodePath", GetCodePath); + SetMethod(context, target, "getCodeCache", GetCodeCache); } void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(IsSea); registry->Register(IsExperimentalSeaWarningNeeded); + registry->Register(GetCodePath); + registry->Register(GetCodeCache); } } // namespace sea diff --git a/src/node_sea.h b/src/node_sea.h index 8b0877df3eb0d7..c443de9e4d0adc 100644 --- a/src/node_sea.h +++ b/src/node_sea.h @@ -6,8 +6,12 @@ #if !defined(DISABLE_SINGLE_EXECUTABLE_APPLICATION) #include +#include +#include #include #include +#include + #include "node_exit_code.h" namespace node { @@ -21,19 +25,27 @@ const uint32_t kMagic = 0x143da20; enum class SeaFlags : uint32_t { kDefault = 0, kDisableExperimentalSeaWarning = 1 << 0, + kUseSnapshot = 1 << 1, + kUseCodeCache = 1 << 2, }; struct SeaResource { SeaFlags flags = SeaFlags::kDefault; - std::string_view code; + std::string_view code_path; + std::string_view main_code_or_snapshot; + std::optional code_cache; + bool use_snapshot() const; static constexpr size_t kHeaderSize = sizeof(kMagic) + sizeof(SeaFlags); }; bool IsSingleExecutable(); SeaResource FindSingleExecutableResource(); std::tuple FixupArgsForSEA(int argc, char** argv); -node::ExitCode BuildSingleExecutableBlob(const std::string& config_path); +node::ExitCode BuildSingleExecutableBlob( + const std::string& config_path, + const std::vector& args, + const std::vector& exec_args); } // namespace sea } // namespace node diff --git a/src/node_snapshot_builder.h b/src/node_snapshot_builder.h index f433bc52c28864..66768cfd201b5e 100644 --- a/src/node_snapshot_builder.h +++ b/src/node_snapshot_builder.h @@ -18,10 +18,12 @@ struct SnapshotData; class NODE_EXTERN_PRIVATE SnapshotBuilder { public: - static ExitCode Generate(std::ostream& out, - const std::vector& args, - const std::vector& exec_args, - std::optional main_script); + static ExitCode GenerateAsSource( + const char* out_path, + const std::vector& args, + const std::vector& exec_args, + std::optional main_script_path = std::nullopt, + bool use_array_literals = false); // Generate the snapshot into out. static ExitCode Generate(SnapshotData* out, diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index 59bcea00d3e7a6..562a47ddcc9c8e 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -1,5 +1,6 @@ #include "node_snapshotable.h" +#include #include #include #include @@ -21,7 +22,6 @@ #include "node_process.h" #include "node_snapshot_builder.h" #include "node_url.h" -#include "node_util.h" #include "node_v8.h" #include "node_v8_platform-inl.h" #include "timers.h" @@ -42,7 +42,6 @@ using v8::MaybeLocal; using v8::Object; using v8::ObjectTemplate; using v8::ScriptCompiler; -using v8::ScriptOrigin; using v8::SnapshotCreator; using v8::StartupData; using v8::String; @@ -146,7 +145,8 @@ class SnapshotDeserializer : public BlobDeserializer { public: explicit SnapshotDeserializer(std::string_view v) : BlobDeserializer( - per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT), + per_process::enabled_debug_list.enabled( + DebugCategory::SNAPSHOT_SERDES), v) {} template { SnapshotSerializer() : BlobSerializer( per_process::enabled_debug_list.enabled( - DebugCategory::MKSNAPSHOT)) { + DebugCategory::SNAPSHOT_SERDES)) { // Currently the snapshot blob built with an empty script is around 4MB. // So use that as the default sink size. sink.reserve(4 * 1024 * 1024); @@ -585,7 +585,9 @@ size_t SnapshotSerializer::Write(const SnapshotMetadata& data) { // [ ... ] code_cache std::vector SnapshotData::ToBlob() const { + std::vector result; SnapshotSerializer w; + w.Debug("SnapshotData::ToBlob()\n"); size_t written_total = 0; @@ -603,7 +605,10 @@ std::vector SnapshotData::ToBlob() const { w.Debug("Write code_cache\n"); written_total += w.WriteVector(code_cache); w.Debug("SnapshotData::ToBlob() Wrote %d bytes\n", written_total); - return w.sink; + + // Return using the temporary value to enable copy elision. + std::swap(result, w.sink); + return result; } void SnapshotData::ToFile(FILE* out) const { @@ -711,13 +716,6 @@ SnapshotData::~SnapshotData() { } } -template -void WriteVector(std::ostream* ss, const T* vec, size_t size) { - for (size_t i = 0; i < size; i++) { - *ss << std::to_string(vec[i]) << (i == size - 1 ? '\n' : ','); - } -} - static std::string GetCodeCacheDefName(const std::string& id) { char buf[64] = {0}; size_t size = id.size(); @@ -742,48 +740,71 @@ static std::string FormatSize(size_t size) { return buf; } -#ifdef NODE_MKSNAPSHOT_USE_STRING_LITERALS -static void WriteDataAsCharString(std::ostream* ss, - const uint8_t* data, - size_t length) { - for (size_t i = 0; i < length; i++) { - const uint8_t ch = data[i]; - // We can print most printable characters directly. The exceptions are '\' - // (escape characters), " (would end the string), and ? (trigraphs). The - // latter may be overly conservative: we compile with C++17 which doesn't - // support trigraphs. - if (ch >= ' ' && ch <= '~' && ch != '\\' && ch != '"' && ch != '?') { - *ss << ch; - } else { - // All other characters are blindly output as octal. - const char c0 = '0' + ((ch >> 6) & 7); - const char c1 = '0' + ((ch >> 3) & 7); - const char c2 = '0' + (ch & 7); - *ss << "\\" << c0 << c1 << c2; - } - if (i % 64 == 63) { - // Go to a newline every 64 bytes since many text editors have - // problems with very long lines. - *ss << "\"\n\""; - } +std::string ToOctalString(const uint8_t ch) { + // We can print most printable characters directly. The exceptions are '\' + // (escape characters), " (would end the string), and ? (trigraphs). The + // latter may be overly conservative: we compile with C++17 which doesn't + // support trigraphs. + if (ch >= ' ' && ch <= '~' && ch != '\\' && ch != '"' && ch != '?') { + return std::string(1, static_cast(ch)); } + // All other characters are blindly output as octal. + const char c0 = '0' + ((ch >> 6) & 7); + const char c1 = '0' + ((ch >> 3) & 7); + const char c2 = '0' + (ch & 7); + return std::string("\\") + c0 + c1 + c2; } -static void WriteStaticCodeCacheDataAsStringLiteral( - std::ostream* ss, const builtins::CodeCacheInfo& info) { - *ss << "static const uint8_t *" << GetCodeCacheDefName(info.id) - << "= reinterpret_cast(\""; - WriteDataAsCharString(ss, info.data.data, info.data.length); - *ss << "\");\n"; +std::vector GetOctalTable() { + size_t size = 1 << 8; + std::vector code_table(size); + for (size_t i = 0; i < size; ++i) { + code_table[i] = ToOctalString(static_cast(i)); + } + return code_table; } -#else -static void WriteStaticCodeCacheDataAsArray( - std::ostream* ss, const builtins::CodeCacheInfo& info) { - *ss << "static const uint8_t " << GetCodeCacheDefName(info.id) << "[] = {\n"; - WriteVector(ss, info.data.data, info.data.length); - *ss << "};\n"; + +const std::string& GetOctalCode(uint8_t index) { + static std::vector table = GetOctalTable(); + return table[index]; +} + +template +void WriteByteVectorLiteral(std::ostream* ss, + const T* vec, + size_t size, + const char* var_name, + bool use_array_literals) { + constexpr bool is_uint8_t = std::is_same_v; + static_assert(is_uint8_t || std::is_same_v); + constexpr const char* type_name = is_uint8_t ? "uint8_t" : "char"; + if (!use_array_literals) { + const uint8_t* data = reinterpret_cast(vec); + *ss << "static const " << type_name << " *" << var_name << " = "; + *ss << (is_uint8_t ? R"(reinterpret_cast(")" : "\""); + for (size_t i = 0; i < size; i++) { + const uint8_t ch = data[i]; + *ss << GetOctalCode(ch); + if (i % 64 == 63) { + // Go to a newline every 64 bytes since many text editors have + // problems with very long lines. + *ss << "\"\n\""; + } + } + *ss << (is_uint8_t ? "\");\n" : "\";\n"); + } else { + *ss << "static const " << type_name << " " << var_name << "[] = {"; + for (size_t i = 0; i < size; i++) { + *ss << std::to_string(vec[i]) << (i == size - 1 ? '\n' : ','); + if (i % 64 == 63) { + // Print a newline every 64 units and a offset to improve + // readability. + *ss << " // " << (i / 64) << "\n"; + } + } + *ss << "};\n"; + } } -#endif static void WriteCodeCacheInitializer(std::ostream* ss, const std::string& id, @@ -796,7 +817,9 @@ static void WriteCodeCacheInitializer(std::ostream* ss, *ss << " },\n"; } -void FormatBlob(std::ostream& ss, const SnapshotData* data) { +void FormatBlob(std::ostream& ss, + const SnapshotData* data, + bool use_array_literals) { ss << R"(#include #include "env.h" #include "node_snapshot_builder.h" @@ -807,32 +830,24 @@ void FormatBlob(std::ostream& ss, const SnapshotData* data) { namespace node { )"; -#ifdef NODE_MKSNAPSHOT_USE_STRING_LITERALS - ss << R"(static const char *v8_snapshot_blob_data = ")"; - WriteDataAsCharString( - &ss, - reinterpret_cast(data->v8_snapshot_blob_data.data), - data->v8_snapshot_blob_data.raw_size); - ss << R"(";)"; -#else - ss << R"(static const char v8_snapshot_blob_data[] = {)"; - WriteVector(&ss, - data->v8_snapshot_blob_data.data, - data->v8_snapshot_blob_data.raw_size); - ss << R"(};)"; -#endif + WriteByteVectorLiteral(&ss, + data->v8_snapshot_blob_data.data, + data->v8_snapshot_blob_data.raw_size, + "v8_snapshot_blob_data", + use_array_literals); ss << R"(static const int v8_snapshot_blob_size = )" - << data->v8_snapshot_blob_data.raw_size << ";"; + << data->v8_snapshot_blob_data.raw_size << ";\n"; + // Windows can't deal with too many large vector initializers. + // Store the data into static arrays first. for (const auto& item : data->code_cache) { -#ifdef NODE_MKSNAPSHOT_USE_STRING_LITERALS - WriteStaticCodeCacheDataAsStringLiteral(&ss, item); -#else - // Windows can't deal with too many large vector initializers. - // Store the data into static arrays first. - WriteStaticCodeCacheDataAsArray(&ss, item); -#endif + std::string var_name = GetCodeCacheDefName(item.id); + WriteByteVectorLiteral(&ss, + item.data.data, + item.data.length, + var_name.c_str(), + use_array_literals); } ss << R"(const SnapshotData snapshot_data { @@ -897,7 +912,7 @@ void SnapshotBuilder::InitializeIsolateParams(const SnapshotData* data, const_cast(&(data->v8_snapshot_blob_data)); } -ExitCode SnapshotBuilder::Generate( +ExitCode BuildSnapshotWithoutCodeCache( SnapshotData* out, const std::vector& args, const std::vector& exec_args, @@ -919,8 +934,8 @@ ExitCode SnapshotBuilder::Generate( fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str()); return ExitCode::kBootstrapFailure; } - Isolate* isolate = setup->isolate(); + Isolate* isolate = setup->isolate(); { HandleScope scope(isolate); TryCatch bootstrapCatch(isolate); @@ -954,7 +969,66 @@ ExitCode SnapshotBuilder::Generate( } } - return CreateSnapshot(out, setup.get(), static_cast(snapshot_type)); + return SnapshotBuilder::CreateSnapshot( + out, setup.get(), static_cast(snapshot_type)); +} + +ExitCode BuildCodeCacheFromSnapshot(SnapshotData* out, + const std::vector& args, + const std::vector& exec_args) { + RAIIIsolate raii_isolate(out); + Isolate* isolate = raii_isolate.get(); + v8::Locker locker(isolate); + Isolate::Scope isolate_scope(isolate); + HandleScope handle_scope(isolate); + TryCatch bootstrapCatch(isolate); + + auto print_Exception = OnScopeLeave([&]() { + if (bootstrapCatch.HasCaught()) { + PrintCaughtException( + isolate, isolate->GetCurrentContext(), bootstrapCatch); + } + }); + + Local context = Context::New(isolate); + Context::Scope context_scope(context); + builtins::BuiltinLoader builtin_loader; + // Regenerate all the code cache. + if (!builtin_loader.CompileAllBuiltins(context)) { + return ExitCode::kGenericUserError; + } + builtin_loader.CopyCodeCache(&(out->code_cache)); + if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) { + for (const auto& item : out->code_cache) { + std::string size_str = FormatSize(item.data.length); + per_process::Debug(DebugCategory::MKSNAPSHOT, + "Generated code cache for %d: %s\n", + item.id.c_str(), + size_str.c_str()); + } + } + return ExitCode::kNoFailure; +} + +ExitCode SnapshotBuilder::Generate( + SnapshotData* out, + const std::vector& args, + const std::vector& exec_args, + std::optional main_script) { + ExitCode code = + BuildSnapshotWithoutCodeCache(out, args, exec_args, main_script); + if (code != ExitCode::kNoFailure) { + return code; + } + +#ifdef NODE_USE_NODE_CODE_CACHE + // Deserialize the snapshot to recompile code cache. We need to do this in the + // second pass because V8 requires the code cache to be compiled with a + // finalized read-only space. + return BuildCodeCacheFromSnapshot(out, args, exec_args); +#else + return ExitCode::kNoFailure; +#endif } ExitCode SnapshotBuilder::CreateSnapshot(SnapshotData* out, @@ -1007,21 +1081,6 @@ ExitCode SnapshotBuilder::CreateSnapshot(SnapshotData* out, out->isolate_data_info = setup->isolate_data()->Serialize(creator); out->env_info = env->Serialize(creator); -#ifdef NODE_USE_NODE_CODE_CACHE - // Regenerate all the code cache. - if (!env->builtin_loader()->CompileAllBuiltins(main_context)) { - return ExitCode::kGenericUserError; - } - env->builtin_loader()->CopyCodeCache(&(out->code_cache)); - for (const auto& item : out->code_cache) { - std::string size_str = FormatSize(item.data.length); - per_process::Debug(DebugCategory::MKSNAPSHOT, - "Generated code cache for %d: %s\n", - item.id.c_str(), - size_str.c_str()); - } -#endif - ResetContextSettingsBeforeSnapshot(main_context); } @@ -1069,17 +1128,45 @@ ExitCode SnapshotBuilder::CreateSnapshot(SnapshotData* out, return ExitCode::kNoFailure; } -ExitCode SnapshotBuilder::Generate( - std::ostream& out, +ExitCode SnapshotBuilder::GenerateAsSource( + const char* out_path, const std::vector& args, const std::vector& exec_args, - std::optional main_script) { + std::optional main_script_path, + bool use_array_literals) { + std::string main_script_content; + std::optional main_script_optional; + if (main_script_path.has_value()) { + int r = ReadFileSync(&main_script_content, main_script_path.value().data()); + if (r != 0) { + FPrintF(stderr, + "Cannot read main script %s for building snapshot. %s: %s", + main_script_path.value(), + uv_err_name(r), + uv_strerror(r)); + return ExitCode::kGenericUserError; + } + main_script_optional = main_script_content; + } + + std::ofstream out(out_path, std::ios::out | std::ios::binary); + if (!out) { + FPrintF(stderr, "Cannot open %s for output.\n", out_path); + return ExitCode::kGenericUserError; + } + SnapshotData data; - ExitCode exit_code = Generate(&data, args, exec_args, main_script); + ExitCode exit_code = Generate(&data, args, exec_args, main_script_optional); if (exit_code != ExitCode::kNoFailure) { return exit_code; } - FormatBlob(out, &data); + FormatBlob(out, &data, use_array_literals); + + if (!out) { + std::cerr << "Failed to write to " << out_path << "\n"; + exit_code = node::ExitCode::kGenericUserError; + } + return exit_code; } @@ -1103,25 +1190,33 @@ std::string SnapshotableObject::GetTypeName() const { void DeserializeNodeInternalFields(Local holder, int index, StartupData payload, - void* env) { + void* callback_data) { if (payload.raw_size == 0) { - holder->SetAlignedPointerInInternalField(index, nullptr); return; } + per_process::Debug(DebugCategory::MKSNAPSHOT, "Deserialize internal field %d of %p, size=%d\n", static_cast(index), (*holder), static_cast(payload.raw_size)); - if (payload.raw_size == 0) { - holder->SetAlignedPointerInInternalField(index, nullptr); + Environment* env = static_cast(callback_data); + + // To deserialize the first field, check the type and re-tag the object. + if (index == BaseObject::kEmbedderType) { + int size = sizeof(EmbedderTypeInfo); + DCHECK_EQ(payload.raw_size, size); + EmbedderTypeInfo read_data; + memcpy(&read_data, payload.data, size); + // For now we only support non-cppgc objects. + CHECK_EQ(read_data.mode, EmbedderTypeInfo::MemoryMode::kBaseObject); + BaseObject::TagBaseObject(env->isolate_data(), holder); return; } - DCHECK_EQ(index, BaseObject::kEmbedderType); - - Environment* env_ptr = static_cast(env); + // To deserialize the second field, enqueue a deserialize request. + DCHECK_IS_SNAPSHOT_SLOT(index); const InternalFieldInfoBase* info = reinterpret_cast(payload.data); // TODO(joyeecheung): we can add a constant kNodeEmbedderId to the @@ -1134,7 +1229,7 @@ void DeserializeNodeInternalFields(Local holder, "Object %p is %s\n", \ (*holder), \ #NativeTypeName); \ - env_ptr->EnqueueDeserializeRequest( \ + env->EnqueueDeserializeRequest( \ NativeTypeName::Deserialize, \ holder, \ index, \ @@ -1159,27 +1254,53 @@ void DeserializeNodeInternalFields(Local holder, StartupData SerializeNodeContextInternalFields(Local holder, int index, - void* env) { - // We only do one serialization for the kEmbedderType slot, the result - // contains everything necessary for deserializing the entire object, - // including the fields whose index is bigger than kEmbedderType - // (most importantly, BaseObject::kSlot). - // For Node.js this design is enough for all the native binding that are - // serializable. - if (index != BaseObject::kEmbedderType || !BaseObject::IsBaseObject(holder)) { + void* callback_data) { + // For the moment we do not set any internal fields in ArrayBuffer + // or ArrayBufferViews, so just return nullptr. + if (holder->IsArrayBuffer() || holder->IsArrayBufferView()) { + CHECK_NULL(holder->GetAlignedPointerFromInternalField(index)); + return StartupData{nullptr, 0}; + } + + // Use the V8 convention and serialize unknown objects verbatim. + Environment* env = static_cast(callback_data); + if (!BaseObject::IsBaseObject(env->isolate_data(), holder)) { + per_process::Debug(DebugCategory::MKSNAPSHOT, + "Serialize unknown object, index=%d, holder=%p\n", + static_cast(index), + *holder); return StartupData{nullptr, 0}; } per_process::Debug(DebugCategory::MKSNAPSHOT, - "Serialize internal field, index=%d, holder=%p\n", + "Serialize BaseObject, index=%d, holder=%p\n", static_cast(index), *holder); - void* native_ptr = - holder->GetAlignedPointerFromInternalField(BaseObject::kSlot); - per_process::Debug(DebugCategory::MKSNAPSHOT, "native = %p\n", native_ptr); - DCHECK(static_cast(native_ptr)->is_snapshotable()); - SnapshotableObject* obj = static_cast(native_ptr); + BaseObject* object_ptr = static_cast( + holder->GetAlignedPointerFromInternalField(BaseObject::kSlot)); + // If the native object is already set to null, ignore it. + if (object_ptr == nullptr) { + return StartupData{nullptr, 0}; + } + + DCHECK(object_ptr->is_snapshotable()); + SnapshotableObject* obj = static_cast(object_ptr); + + // To serialize the type field, save data in a EmbedderTypeInfo. + if (index == BaseObject::kEmbedderType) { + int size = sizeof(EmbedderTypeInfo); + char* data = new char[size]; + // We need to use placement new because V8 calls delete[] on the returned + // data. + // TODO(joyeecheung): support cppgc objects. + new (data) EmbedderTypeInfo(obj->type(), + EmbedderTypeInfo::MemoryMode::kBaseObject); + return StartupData{data, size}; + } + + // To serialize the slot field, invoke Serialize() method on the object. + DCHECK_IS_SNAPSHOT_SLOT(index); per_process::Debug(DebugCategory::MKSNAPSHOT, "Object %p is %s, ", @@ -1254,7 +1375,6 @@ void CompileSerializeMain(const FunctionCallbackInfo& args) { Local source = args[1].As(); Isolate* isolate = args.GetIsolate(); Local context = isolate->GetCurrentContext(); - ScriptOrigin origin(isolate, filename, 0, 0, true); // TODO(joyeecheung): do we need all of these? Maybe we would want a less // internal version of them. std::vector> parameters = { @@ -1262,15 +1382,8 @@ void CompileSerializeMain(const FunctionCallbackInfo& args) { FIXED_ONE_BYTE_STRING(isolate, "__filename"), FIXED_ONE_BYTE_STRING(isolate, "__dirname"), }; - ScriptCompiler::Source script_source(source, origin); Local fn; - if (ScriptCompiler::CompileFunction(context, - &script_source, - parameters.size(), - parameters.data(), - 0, - nullptr, - ScriptCompiler::kNoCompileOptions) + if (contextify::CompileFunction(context, filename, source, ¶meters) .ToLocal(&fn)) { args.GetReturnValue().Set(fn); } @@ -1343,7 +1456,7 @@ bool BindingData::PrepareForSerialization(Local context, } InternalFieldInfoBase* BindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = internal_field_info_; internal_field_info_ = nullptr; return info; @@ -1353,13 +1466,13 @@ void BindingData::Deserialize(Local context, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); v8::HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); // Recreate the buffer in the constructor. InternalFieldInfo* casted_info = static_cast(info); BindingData* binding = - realm->AddBindingData(context, holder, casted_info); + realm->AddBindingData(holder, casted_info); CHECK_NOT_NULL(binding); } @@ -1373,7 +1486,7 @@ void CreatePerContextProperties(Local target, Local context, void* priv) { Realm* realm = Realm::GetCurrent(context); - realm->AddBindingData(context, target); + realm->AddBindingData(target); } void CreatePerIsolateProperties(IsolateData* isolate_data, diff --git a/src/node_snapshotable.h b/src/node_snapshotable.h index eed572beef3a0c..d1f28ecf154d9b 100644 --- a/src/node_snapshotable.h +++ b/src/node_snapshotable.h @@ -68,6 +68,14 @@ struct InternalFieldInfoBase { InternalFieldInfoBase() = default; }; +struct EmbedderTypeInfo { + enum class MemoryMode : uint8_t { kBaseObject, kCppGC }; + EmbedderTypeInfo(EmbedderObjectType t, MemoryMode m) : type(t), mode(m) {} + EmbedderTypeInfo() = default; + EmbedderObjectType type; + MemoryMode mode; +}; + // An interface for snapshotable native objects to inherit from. // Use the SERIALIZABLE_OBJECT_METHODS() macro in the class to define // the following methods to implement: @@ -123,6 +131,8 @@ void SerializeSnapshotableObjects(Realm* realm, v8::SnapshotCreator* creator, RealmSerializeInfo* info); +#define DCHECK_IS_SNAPSHOT_SLOT(index) DCHECK_EQ(index, BaseObject::kSlot) + namespace mksnapshot { class BindingData : public SnapshotableObject { public: diff --git a/src/node_task_queue.cc b/src/node_task_queue.cc index 5d0e2b0d4c7ba1..0a5aba6e31fa79 100644 --- a/src/node_task_queue.cc +++ b/src/node_task_queue.cc @@ -43,28 +43,6 @@ static Maybe GetAssignedPromiseAsyncId(Environment* env, : v8::Just(AsyncWrap::kInvalidAsyncId); } -static Maybe GetAssignedPromiseWrapAsyncId(Environment* env, - Local promise, - Local id_symbol) { - // This check is imperfect. If the internal field is set, it should - // be an object. If it's not, we just ignore it. Ideally v8 would - // have had GetInternalField returning a MaybeLocal but this works - // for now. - Local promiseWrap = promise->GetInternalField(0); - if (promiseWrap->IsObject()) { - Local maybe_async_id; - if (!promiseWrap.As()->Get(env->context(), id_symbol) - .ToLocal(&maybe_async_id)) { - return v8::Just(AsyncWrap::kInvalidAsyncId); - } - return maybe_async_id->IsNumber() - ? maybe_async_id->NumberValue(env->context()) - : v8::Just(AsyncWrap::kInvalidAsyncId); - } else { - return v8::Just(AsyncWrap::kInvalidAsyncId); - } -} - void PromiseRejectCallback(PromiseRejectMessage message) { static std::atomic unhandledRejections{0}; static std::atomic rejectionsHandledAfter{0}; @@ -122,17 +100,6 @@ void PromiseRejectCallback(PromiseRejectMessage message) { if (!GetAssignedPromiseAsyncId(env, promise, env->trigger_async_id_symbol()) .To(&trigger_async_id)) return; - if (async_id == AsyncWrap::kInvalidAsyncId && - trigger_async_id == AsyncWrap::kInvalidAsyncId) { - // That means that promise might be a PromiseWrap, so we'll - // check there as well. - if (!GetAssignedPromiseWrapAsyncId(env, promise, env->async_id_symbol()) - .To(&async_id)) return; - if (!GetAssignedPromiseWrapAsyncId( - env, promise, env->trigger_async_id_symbol()) - .To(&trigger_async_id)) return; - } - if (async_id != AsyncWrap::kInvalidAsyncId && trigger_async_id != AsyncWrap::kInvalidAsyncId) { env->async_hooks()->push_async_context( diff --git a/src/node_url.cc b/src/node_url.cc index fceb3943901a3b..666492ca47cee3 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -54,7 +54,7 @@ bool BindingData::PrepareForSerialization(v8::Local context, } InternalFieldInfoBase* BindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = InternalFieldInfoBase::New(type()); return info; @@ -64,10 +64,10 @@ void BindingData::Deserialize(v8::Local context, v8::Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); v8::HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); - BindingData* binding = realm->AddBindingData(context, holder); + BindingData* binding = realm->AddBindingData(holder); CHECK_NOT_NULL(binding); } @@ -78,7 +78,7 @@ void BindingData::DomainToASCII(const FunctionCallbackInfo& args) { std::string input = Utf8Value(env->isolate(), args[0]).ToString(); if (input.empty()) { - return args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(env->isolate(), "")); + return args.GetReturnValue().Set(String::Empty(env->isolate())); } // It is important to have an initial value that contains a special scheme. @@ -87,7 +87,7 @@ void BindingData::DomainToASCII(const FunctionCallbackInfo& args) { auto out = ada::parse("ws://x"); DCHECK(out); if (!out->set_hostname(input)) { - return args.GetReturnValue().Set(FIXED_ONE_BYTE_STRING(env->isolate(), "")); + return args.GetReturnValue().Set(String::Empty(env->isolate())); } std::string host = out->get_hostname(); args.GetReturnValue().Set( @@ -100,14 +100,17 @@ void BindingData::DomainToUnicode(const FunctionCallbackInfo& args) { CHECK(args[0]->IsString()); std::string input = Utf8Value(env->isolate(), args[0]).ToString(); + if (input.empty()) { + return args.GetReturnValue().Set(String::Empty(env->isolate())); + } + // It is important to have an initial value that contains a special scheme. // Since it will change the implementation of `set_hostname` according to URL // spec. auto out = ada::parse("ws://x"); DCHECK(out); if (!out->set_hostname(input)) { - return args.GetReturnValue().Set( - String::NewFromUtf8(env->isolate(), "").ToLocalChecked()); + return args.GetReturnValue().Set(String::Empty(env->isolate())); } std::string result = ada::unicode::to_unicode(out->get_hostname()); @@ -170,7 +173,15 @@ bool BindingData::FastCanParse(Local receiver, return ada::can_parse(std::string_view(input.data, input.length)); } -CFunction BindingData::fast_can_parse_(CFunction::Make(FastCanParse)); +bool BindingData::FastCanParseWithBase(Local receiver, + const FastOneByteString& input, + const FastOneByteString& base) { + auto base_view = std::string_view(base.data, base.length); + return ada::can_parse(std::string_view(input.data, input.length), &base_view); +} + +CFunction BindingData::fast_can_parse_methods_[] = { + CFunction::Make(FastCanParse), CFunction::Make(FastCanParseWithBase)}; void BindingData::Format(const FunctionCallbackInfo& args) { CHECK_GT(args.Length(), 4); @@ -195,7 +206,7 @@ void BindingData::Format(const FunctionCallbackInfo& args) { out->hash = std::nullopt; } - if (unicode) { + if (unicode && out->has_hostname()) { out->host = ada::idna::to_unicode(out->get_hostname()); } @@ -221,17 +232,16 @@ void BindingData::Parse(const FunctionCallbackInfo& args) { CHECK(args[0]->IsString()); // input // args[1] // base url - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = Environment::GetCurrent(args); - HandleScope handle_scope(env->isolate()); - Context::Scope context_scope(env->context()); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Isolate* isolate = realm->isolate(); - Utf8Value input(env->isolate(), args[0]); + Utf8Value input(isolate, args[0]); ada::result base; ada::url_aggregator* base_pointer = nullptr; if (args[1]->IsString()) { - base = ada::parse( - Utf8Value(env->isolate(), args[1]).ToString()); + base = + ada::parse(Utf8Value(isolate, args[1]).ToString()); if (!base) { return args.GetReturnValue().Set(false); } @@ -247,8 +257,7 @@ void BindingData::Parse(const FunctionCallbackInfo& args) { binding_data->UpdateComponents(out->get_components(), out->type); args.GetReturnValue().Set( - ToV8Value(env->context(), out->get_href(), env->isolate()) - .ToLocalChecked()); + ToV8Value(realm->context(), out->get_href(), isolate).ToLocalChecked()); } void BindingData::Update(const FunctionCallbackInfo& args) { @@ -256,12 +265,12 @@ void BindingData::Update(const FunctionCallbackInfo& args) { CHECK(args[1]->IsNumber()); // action type CHECK(args[2]->IsString()); // new value - BindingData* binding_data = Realm::GetBindingData(args); - Environment* env = Environment::GetCurrent(args); - Isolate* isolate = env->isolate(); + Realm* realm = Realm::GetCurrent(args); + BindingData* binding_data = realm->GetBindingData(); + Isolate* isolate = realm->isolate(); enum url_update_action action = static_cast( - args[1]->Uint32Value(env->context()).FromJust()); + args[1]->Uint32Value(realm->context()).FromJust()); Utf8Value input(isolate, args[0].As()); Utf8Value new_value(isolate, args[2].As()); @@ -322,8 +331,7 @@ void BindingData::Update(const FunctionCallbackInfo& args) { binding_data->UpdateComponents(out->get_components(), out->type); args.GetReturnValue().Set( - ToV8Value(env->context(), out->get_href(), env->isolate()) - .ToLocalChecked()); + ToV8Value(realm->context(), out->get_href(), isolate).ToLocalChecked()); } void BindingData::UpdateComponents(const ada::url_components& components, @@ -351,7 +359,7 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data, SetMethod(isolate, target, "parse", Parse); SetMethod(isolate, target, "update", Update); SetFastMethodNoSideEffect( - isolate, target, "canParse", CanParse, &fast_can_parse_); + isolate, target, "canParse", CanParse, {fast_can_parse_methods_, 2}); } void BindingData::CreatePerContextProperties(Local target, @@ -359,7 +367,7 @@ void BindingData::CreatePerContextProperties(Local target, Local context, void* priv) { Realm* realm = Realm::GetCurrent(context); - realm->AddBindingData(context, target); + realm->AddBindingData(target); } void BindingData::RegisterExternalReferences( @@ -372,7 +380,11 @@ void BindingData::RegisterExternalReferences( registry->Register(Update); registry->Register(CanParse); registry->Register(FastCanParse); - registry->Register(fast_can_parse_.GetTypeInfo()); + registry->Register(FastCanParseWithBase); + + for (const CFunction& method : fast_can_parse_methods_) { + registry->Register(method.GetTypeInfo()); + } } std::string FromFilePath(const std::string_view file_path) { diff --git a/src/node_url.h b/src/node_url.h index 8849e59be1f79a..c485caa2eb0343 100644 --- a/src/node_url.h +++ b/src/node_url.h @@ -51,6 +51,9 @@ class BindingData : public SnapshotableObject { static void CanParse(const v8::FunctionCallbackInfo& args); static bool FastCanParse(v8::Local receiver, const v8::FastOneByteString& input); + static bool FastCanParseWithBase(v8::Local receiver, + const v8::FastOneByteString& input, + const v8::FastOneByteString& base); static void Format(const v8::FunctionCallbackInfo& args); static void GetOrigin(const v8::FunctionCallbackInfo& args); @@ -72,7 +75,7 @@ class BindingData : public SnapshotableObject { void UpdateComponents(const ada::url_components& components, const ada::scheme::type type); - static v8::CFunction fast_can_parse_; + static v8::CFunction fast_can_parse_methods_[]; }; std::string FromFilePath(const std::string_view file_path); diff --git a/src/node_util.cc b/src/node_util.cc index 2af3b5a7276aae..9b3ba203a3a8fc 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -1,4 +1,3 @@ -#include "node_util.h" #include "base_object-inl.h" #include "node_errors.h" #include "node_external_reference.h" @@ -17,8 +16,6 @@ using v8::CFunction; using v8::Context; using v8::External; using v8::FunctionCallbackInfo; -using v8::FunctionTemplate; -using v8::HandleScope; using v8::IndexFilter; using v8::Integer; using v8::Isolate; @@ -34,6 +31,8 @@ using v8::PropertyFilter; using v8::Proxy; using v8::SKIP_STRINGS; using v8::SKIP_SYMBOLS; +using v8::StackFrame; +using v8::StackTrace; using v8::String; using v8::Uint32; using v8::Value; @@ -140,6 +139,24 @@ static void GetProxyDetails(const FunctionCallbackInfo& args) { } } +static void GetCallerLocation(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + Local trace = StackTrace::CurrentStackTrace(isolate, 2); + + // This function is frame zero. The caller is frame one. If there aren't two + // stack frames, return undefined. + if (trace->GetFrameCount() != 2) { + return; + } + + Local frame = trace->GetFrame(isolate, 1); + Local ret[] = {Integer::New(isolate, frame->GetLineNumber()), + Integer::New(isolate, frame->GetColumn()), + frame->GetScriptNameOrSourceURL()}; + + args.GetReturnValue().Set(Array::New(args.GetIsolate(), ret, arraysize(ret))); +} + static void IsArrayBufferDetached(const FunctionCallbackInfo& args) { if (args[0]->IsArrayBuffer()) { auto buffer = args[0].As(); @@ -181,177 +198,44 @@ void ArrayBufferViewHasBuffer(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(args[0].As()->HasBuffer()); } -WeakReference::WeakReference(Realm* realm, - Local object, - Local target) - : WeakReference(realm, object, target, 0) {} - -WeakReference::WeakReference(Realm* realm, - Local object, - Local target, - uint64_t reference_count) - : SnapshotableObject(realm, object, type_int), - reference_count_(reference_count) { - MakeWeak(); - if (!target.IsEmpty()) { - target_.Reset(realm->isolate(), target); - if (reference_count_ == 0) { - target_.SetWeak(); - } - } -} - -bool WeakReference::PrepareForSerialization(Local context, - v8::SnapshotCreator* creator) { - if (target_.IsEmpty()) { - target_index_ = 0; - return true; - } - - // Users can still hold strong references to target in addition to the - // reference that we manage here, and they could expect that the referenced - // object remains the same as long as that external strong reference - // is alive. Since we have no way to know if there is any other reference - // keeping the target alive, the best we can do to maintain consistency is to - // simply save a reference to the target in the snapshot (effectively making - // it strong) during serialization, and restore it during deserialization. - // If there's no known counted reference from our side, we'll make the - // reference here weak upon deserialization so that it can be GC'ed if users - // do not hold additional references to it. - Local target = target_.Get(context->GetIsolate()); - target_index_ = creator->AddData(context, target); - DCHECK_NE(target_index_, 0); - target_.Reset(); - return true; -} - -InternalFieldInfoBase* WeakReference::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); - InternalFieldInfo* info = - InternalFieldInfoBase::New(type()); - info->target = target_index_; - info->reference_count = reference_count_; - return info; -} - -void WeakReference::Deserialize(Local context, - Local holder, - int index, - InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); - HandleScope scope(context->GetIsolate()); - - InternalFieldInfo* weak_info = reinterpret_cast(info); - Local target; - if (weak_info->target != 0) { - target = context->GetDataFromSnapshotOnce(weak_info->target) - .ToLocalChecked(); - } - new WeakReference( - Realm::GetCurrent(context), holder, target, weak_info->reference_count); -} - -void WeakReference::New(const FunctionCallbackInfo& args) { - Realm* realm = Realm::GetCurrent(args); - CHECK(args.IsConstructCall()); - CHECK(args[0]->IsObject()); - new WeakReference(realm, args.This(), args[0].As()); -} - -void WeakReference::Get(const FunctionCallbackInfo& args) { - WeakReference* weak_ref = Unwrap(args.Holder()); - Isolate* isolate = args.GetIsolate(); - if (!weak_ref->target_.IsEmpty()) - args.GetReturnValue().Set(weak_ref->target_.Get(isolate)); -} - -void WeakReference::IncRef(const FunctionCallbackInfo& args) { - WeakReference* weak_ref = Unwrap(args.Holder()); - weak_ref->reference_count_++; - if (weak_ref->target_.IsEmpty()) return; - if (weak_ref->reference_count_ == 1) weak_ref->target_.ClearWeak(); - args.GetReturnValue().Set( - v8::Number::New(args.GetIsolate(), weak_ref->reference_count_)); -} - -void WeakReference::DecRef(const FunctionCallbackInfo& args) { - WeakReference* weak_ref = Unwrap(args.Holder()); - CHECK_GE(weak_ref->reference_count_, 1); - weak_ref->reference_count_--; - if (weak_ref->target_.IsEmpty()) return; - if (weak_ref->reference_count_ == 0) weak_ref->target_.SetWeak(); - args.GetReturnValue().Set( - v8::Number::New(args.GetIsolate(), weak_ref->reference_count_)); -} - -static void GuessHandleType(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - int fd; - if (!args[0]->Int32Value(env->context()).To(&fd)) return; - CHECK_GE(fd, 0); - - uv_handle_type t = uv_guess_handle(fd); +static uint32_t GetUVHandleTypeCode(const uv_handle_type type) { // TODO(anonrig): We can use an enum here and then create the array in the // binding, which will remove the hard-coding in C++ and JS land. - uint32_t type{0}; // Currently, the return type of this function corresponds to the index of the // array defined in the JS land. This is done as an optimization to reduce the // string serialization overhead. - switch (t) { + switch (type) { case UV_TCP: - type = 0; - break; + return 0; case UV_TTY: - type = 1; - break; + return 1; case UV_UDP: - type = 2; - break; + return 2; case UV_FILE: - type = 3; - break; + return 3; case UV_NAMED_PIPE: - type = 4; - break; + return 4; case UV_UNKNOWN_HANDLE: - type = 5; - break; + return 5; default: ABORT(); } +} + +static void GuessHandleType(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + int fd; + if (!args[0]->Int32Value(env->context()).To(&fd)) return; + CHECK_GE(fd, 0); - args.GetReturnValue().Set(type); + uv_handle_type t = uv_guess_handle(fd); + args.GetReturnValue().Set(GetUVHandleTypeCode(t)); } static uint32_t FastGuessHandleType(Local receiver, const uint32_t fd) { uv_handle_type t = uv_guess_handle(fd); - uint32_t type{0}; - - switch (t) { - case UV_TCP: - type = 0; - break; - case UV_TTY: - type = 1; - break; - case UV_UDP: - type = 2; - break; - case UV_FILE: - type = 3; - break; - case UV_NAMED_PIPE: - type = 4; - break; - case UV_UNKNOWN_HANDLE: - type = 5; - break; - default: - ABORT(); - } - - return type; + return GetUVHandleTypeCode(t); } CFunction fast_guess_handle_type_(CFunction::Make(FastGuessHandleType)); @@ -393,6 +277,7 @@ static void ToUSVString(const FunctionCallbackInfo& args) { void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetPromiseDetails); registry->Register(GetProxyDetails); + registry->Register(GetCallerLocation); registry->Register(IsArrayBufferDetached); registry->Register(PreviewEntries); registry->Register(GetOwnNonIndexProperties); @@ -400,10 +285,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetExternalValue); registry->Register(Sleep); registry->Register(ArrayBufferViewHasBuffer); - registry->Register(WeakReference::New); - registry->Register(WeakReference::Get); - registry->Register(WeakReference::IncRef); - registry->Register(WeakReference::DecRef); registry->Register(GuessHandleType); registry->Register(FastGuessHandleType); registry->Register(fast_guess_handle_type_.GetTypeInfo()); @@ -494,6 +375,8 @@ void Initialize(Local target, SetMethodNoSideEffect( context, target, "getPromiseDetails", GetPromiseDetails); SetMethodNoSideEffect(context, target, "getProxyDetails", GetProxyDetails); + SetMethodNoSideEffect( + context, target, "getCallerLocation", GetCallerLocation); SetMethodNoSideEffect( context, target, "isArrayBufferDetached", IsArrayBufferDetached); SetMethodNoSideEffect(context, target, "previewEntries", PreviewEntries); @@ -515,15 +398,6 @@ void Initialize(Local target, env->should_abort_on_uncaught_toggle().GetJSArray()) .FromJust()); - Local weak_ref = - NewFunctionTemplate(isolate, WeakReference::New); - weak_ref->InstanceTemplate()->SetInternalFieldCount( - WeakReference::kInternalFieldCount); - SetProtoMethod(isolate, weak_ref, "get", WeakReference::Get); - SetProtoMethod(isolate, weak_ref, "incRef", WeakReference::IncRef); - SetProtoMethod(isolate, weak_ref, "decRef", WeakReference::DecRef); - SetConstructorFunction(context, target, "WeakReference", weak_ref); - SetFastMethodNoSideEffect(context, target, "guessHandleType", diff --git a/src/node_util.h b/src/node_util.h deleted file mode 100644 index 715686856db879..00000000000000 --- a/src/node_util.h +++ /dev/null @@ -1,52 +0,0 @@ - -#ifndef SRC_NODE_UTIL_H_ -#define SRC_NODE_UTIL_H_ - -#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS -#include "base_object.h" -#include "node_snapshotable.h" -#include "v8.h" - -namespace node { -namespace util { - -class WeakReference : public SnapshotableObject { - public: - SERIALIZABLE_OBJECT_METHODS() - - SET_OBJECT_ID(util_weak_reference) - - WeakReference(Realm* realm, - v8::Local object, - v8::Local target); - static void New(const v8::FunctionCallbackInfo& args); - static void Get(const v8::FunctionCallbackInfo& args); - static void IncRef(const v8::FunctionCallbackInfo& args); - static void DecRef(const v8::FunctionCallbackInfo& args); - - SET_MEMORY_INFO_NAME(WeakReference) - SET_SELF_SIZE(WeakReference) - SET_NO_MEMORY_INFO() - - struct InternalFieldInfo : public node::InternalFieldInfoBase { - SnapshotIndex target; - uint64_t reference_count; - }; - - private: - WeakReference(Realm* realm, - v8::Local object, - v8::Local target, - uint64_t reference_count); - v8::Global target_; - uint64_t reference_count_ = 0; - - SnapshotIndex target_index_ = 0; // 0 means target_ is not snapshotted -}; - -} // namespace util -} // namespace node - -#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS - -#endif // SRC_NODE_UTIL_H_ diff --git a/src/node_v8.cc b/src/node_v8.cc index 308d851ef62278..814efe3d69651c 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -152,18 +152,18 @@ void BindingData::Deserialize(Local context, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); // Recreate the buffer in the constructor. InternalFieldInfo* casted_info = static_cast(info); BindingData* binding = - realm->AddBindingData(context, holder, casted_info); + realm->AddBindingData(holder, casted_info); CHECK_NOT_NULL(binding); } InternalFieldInfoBase* BindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = internal_field_info_; internal_field_info_ = nullptr; return info; @@ -422,8 +422,7 @@ void Initialize(Local target, void* priv) { Realm* realm = Realm::GetCurrent(context); Environment* env = realm->env(); - BindingData* const binding_data = - realm->AddBindingData(context, target); + BindingData* const binding_data = realm->AddBindingData(target); if (binding_data == nullptr) return; SetMethodNoSideEffect( diff --git a/src/node_version.h b/src/node_version.h index 6768e5b1306fde..9001284dabf584 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -83,13 +83,20 @@ * We will, at times update the version of V8 shipped in the release line * if it can be made ABI compatible with the previous version. * + * Embedders building Node.js can define NODE_EMBEDDER_MODULE_VERSION to + * override the default value of NODE_MODULE_VERSION. + * * The registry of used NODE_MODULE_VERSION numbers is located at * https://github.com/nodejs/node/blob/HEAD/doc/abi_version_registry.json * Extenders, embedders and other consumers of Node.js that require ABI * version matching should open a pull request to reserve a number in this * registry. */ +#if defined(NODE_EMBEDDER_MODULE_VERSION) +#define NODE_MODULE_VERSION NODE_EMBEDDER_MODULE_VERSION +#else #define NODE_MODULE_VERSION 115 +#endif // The NAPI_VERSION supported by the runtime. This is the inclusive range of // versions which the Node.js binary being built supports. diff --git a/src/node_worker.cc b/src/node_worker.cc index 478e80be505bca..900674bbe4c90e 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -11,6 +11,7 @@ #include "node_snapshot_builder.h" #include "permission/permission.h" #include "util-inl.h" +#include "v8-cppgc.h" #include #include diff --git a/src/node_zlib.cc b/src/node_zlib.cc index fac116f9e6b3e2..0c4ae0fc794347 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -423,7 +423,8 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork { UpdateWriteResult(); // call the write() cb - Local cb = object()->GetInternalField(kWriteJSCallback); + Local cb = + object()->GetInternalField(kWriteJSCallback).template As(); MakeCallback(cb.As(), 0, nullptr); if (pending_close_) diff --git a/src/permission/child_process_permission.cc b/src/permission/child_process_permission.cc index 7151eb15f90da2..de078febf4bcd9 100644 --- a/src/permission/child_process_permission.cc +++ b/src/permission/child_process_permission.cc @@ -9,7 +9,7 @@ namespace permission { // Currently, ChildProcess manage a single state // Once denied, it's always denied -void ChildProcessPermission::Apply(const std::string& allow, +void ChildProcessPermission::Apply(const std::vector& allow, PermissionScope scope) { deny_all_ = true; } diff --git a/src/permission/child_process_permission.h b/src/permission/child_process_permission.h index b67169f1c4e180..cf0ec97d5021a3 100644 --- a/src/permission/child_process_permission.h +++ b/src/permission/child_process_permission.h @@ -12,7 +12,8 @@ namespace permission { class ChildProcessPermission final : public PermissionBase { public: - void Apply(const std::string& allow, PermissionScope scope) override; + void Apply(const std::vector& allow, + PermissionScope scope) override; bool is_granted(PermissionScope perm, const std::string_view& param = "") override; diff --git a/src/permission/fs_permission.cc b/src/permission/fs_permission.cc index a02f95ea55f3a2..fadf75968c779d 100644 --- a/src/permission/fs_permission.cc +++ b/src/permission/fs_permission.cc @@ -67,57 +67,60 @@ bool is_tree_granted(node::permission::FSPermission::RadixTree* granted_tree, return granted_tree->Lookup(param, true); } -} // namespace - -namespace node { - -namespace permission { - -void PrintTree(const FSPermission::RadixTree::Node* node, size_t spaces = 0) { +void PrintTree(const node::permission::FSPermission::RadixTree::Node* node, + size_t spaces = 0) { std::string whitespace(spaces, ' '); if (node == nullptr) { return; } if (node->wildcard_child != nullptr) { - per_process::Debug(DebugCategory::PERMISSION_MODEL, - "%s Wildcard: %s\n", - whitespace, - node->prefix); + node::per_process::Debug(node::DebugCategory::PERMISSION_MODEL, + "%s Wildcard: %s\n", + whitespace, + node->prefix); } else { - per_process::Debug(DebugCategory::PERMISSION_MODEL, - "%s Prefix: %s\n", - whitespace, - node->prefix); + node::per_process::Debug(node::DebugCategory::PERMISSION_MODEL, + "%s Prefix: %s\n", + whitespace, + node->prefix); if (node->children.size()) { size_t child = 0; for (const auto& pair : node->children) { ++child; - per_process::Debug(DebugCategory::PERMISSION_MODEL, - "%s Child(%s): %s\n", - whitespace, - child, - std::string(1, pair.first)); + node::per_process::Debug(node::DebugCategory::PERMISSION_MODEL, + "%s Child(%s): %s\n", + whitespace, + child, + std::string(1, pair.first)); PrintTree(pair.second, spaces + 2); } - per_process::Debug(DebugCategory::PERMISSION_MODEL, - "%s End of tree - child(%s)\n", - whitespace, - child); + node::per_process::Debug(node::DebugCategory::PERMISSION_MODEL, + "%s End of tree - child(%s)\n", + whitespace, + child); } else { - per_process::Debug(DebugCategory::PERMISSION_MODEL, - "%s End of tree: %s\n", - whitespace, - node->prefix); + node::per_process::Debug(node::DebugCategory::PERMISSION_MODEL, + "%s End of tree: %s\n", + whitespace, + node->prefix); } } } +} // namespace + +namespace node { + +namespace permission { + // allow = '*' // allow = '/tmp/,/home/example.js' -void FSPermission::Apply(const std::string& allow, PermissionScope scope) { +void FSPermission::Apply(const std::vector& allow, + PermissionScope scope) { using std::string_view_literals::operator""sv; - for (const std::string_view res : SplitString(allow, ","sv)) { + + for (const std::string_view res : allow) { if (res == "*"sv) { if (scope == PermissionScope::kFileSystemRead) { deny_all_in_ = false; diff --git a/src/permission/fs_permission.h b/src/permission/fs_permission.h index 217d0a92d6ce71..244e95727ad487 100644 --- a/src/permission/fs_permission.h +++ b/src/permission/fs_permission.h @@ -15,7 +15,8 @@ namespace permission { class FSPermission final : public PermissionBase { public: - void Apply(const std::string& allow, PermissionScope scope) override; + void Apply(const std::vector& allow, + PermissionScope scope) override; bool is_granted(PermissionScope perm, const std::string_view& param) override; struct RadixTree { diff --git a/src/permission/inspector_permission.cc b/src/permission/inspector_permission.cc index 3cff03433b4225..401d801ac0adb5 100644 --- a/src/permission/inspector_permission.cc +++ b/src/permission/inspector_permission.cc @@ -8,7 +8,7 @@ namespace permission { // Currently, Inspector manage a single state // Once denied, it's always denied -void InspectorPermission::Apply(const std::string& allow, +void InspectorPermission::Apply(const std::vector& allow, PermissionScope scope) { deny_all_ = true; } diff --git a/src/permission/inspector_permission.h b/src/permission/inspector_permission.h index 33eb25732c0d4d..e5c6d1b81677f5 100644 --- a/src/permission/inspector_permission.h +++ b/src/permission/inspector_permission.h @@ -12,7 +12,8 @@ namespace permission { class InspectorPermission final : public PermissionBase { public: - void Apply(const std::string& allow, PermissionScope scope) override; + void Apply(const std::vector& allow, + PermissionScope scope) override; bool is_granted(PermissionScope perm, const std::string_view& param = "") override; diff --git a/src/permission/permission.cc b/src/permission/permission.cc index 38767e46093f0b..4392f49b66e9b7 100644 --- a/src/permission/permission.cc +++ b/src/permission/permission.cc @@ -130,7 +130,8 @@ void Permission::EnablePermissions() { } } -void Permission::Apply(const std::string& allow, PermissionScope scope) { +void Permission::Apply(const std::vector& allow, + PermissionScope scope) { auto permission = nodes_.find(scope); if (permission != nodes_.end()) { permission->second->Apply(allow, scope); diff --git a/src/permission/permission.h b/src/permission/permission.h index 3252e8d540d306..942937a80cae28 100644 --- a/src/permission/permission.h +++ b/src/permission/permission.h @@ -49,7 +49,7 @@ class Permission { const std::string_view& res); // CLI Call - void Apply(const std::string& allow, PermissionScope scope); + void Apply(const std::vector& allow, PermissionScope scope); void EnablePermissions(); private: diff --git a/src/permission/permission_base.h b/src/permission/permission_base.h index c4728e40ce8f2c..c2f377424f6fc5 100644 --- a/src/permission/permission_base.h +++ b/src/permission/permission_base.h @@ -39,7 +39,8 @@ enum class PermissionScope { class PermissionBase { public: - virtual void Apply(const std::string& allow, PermissionScope scope) = 0; + virtual void Apply(const std::vector& allow, + PermissionScope scope) = 0; virtual bool is_granted(PermissionScope perm, const std::string_view& param = "") = 0; }; diff --git a/src/permission/worker_permission.cc b/src/permission/worker_permission.cc index 69c89a4a4fea87..a18938e5fe1efd 100644 --- a/src/permission/worker_permission.cc +++ b/src/permission/worker_permission.cc @@ -9,7 +9,8 @@ namespace permission { // Currently, PolicyDenyWorker manage a single state // Once denied, it's always denied -void WorkerPermission::Apply(const std::string& allow, PermissionScope scope) { +void WorkerPermission::Apply(const std::vector& allow, + PermissionScope scope) { deny_all_ = true; } diff --git a/src/permission/worker_permission.h b/src/permission/worker_permission.h index 71681a4485a82f..cdc224925c2291 100644 --- a/src/permission/worker_permission.h +++ b/src/permission/worker_permission.h @@ -12,7 +12,8 @@ namespace permission { class WorkerPermission final : public PermissionBase { public: - void Apply(const std::string& allow, PermissionScope scope) override; + void Apply(const std::vector& allow, + PermissionScope scope) override; bool is_granted(PermissionScope perm, const std::string_view& param = "") override; diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 944d7c3e72c534..738a51a140d0af 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -62,7 +62,6 @@ MaybeLocal PipeWrap::Instantiate(Environment* env, constructor->NewInstance(env->context(), 1, &type_value)); } - void PipeWrap::Initialize(Local target, Local unused, Local context, @@ -71,8 +70,7 @@ void PipeWrap::Initialize(Local target, Isolate* isolate = env->isolate(); Local t = NewFunctionTemplate(isolate, New); - t->InstanceTemplate() - ->SetInternalFieldCount(StreamBase::kInternalFieldCount); + t->InstanceTemplate()->SetInternalFieldCount(StreamBase::kInternalFieldCount); t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env)); @@ -102,9 +100,7 @@ void PipeWrap::Initialize(Local target, NODE_DEFINE_CONSTANT(constants, IPC); NODE_DEFINE_CONSTANT(constants, UV_READABLE); NODE_DEFINE_CONSTANT(constants, UV_WRITABLE); - target->Set(context, - env->constants_string(), - constants).Check(); + target->Set(context, env->constants_string(), constants).Check(); } void PipeWrap::RegisterExternalReferences(ExternalReferenceRegistry* registry) { @@ -152,7 +148,6 @@ void PipeWrap::New(const FunctionCallbackInfo& args) { new PipeWrap(env, args.This(), provider, ipc); } - PipeWrap::PipeWrap(Environment* env, Local object, ProviderType provider, @@ -163,16 +158,14 @@ PipeWrap::PipeWrap(Environment* env, // Suggestion: uv_pipe_init() returns void. } - void PipeWrap::Bind(const FunctionCallbackInfo& args) { PipeWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); node::Utf8Value name(args.GetIsolate(), args[0]); - int err = uv_pipe_bind(&wrap->handle_, *name); + int err = uv_pipe_bind2(&wrap->handle_, *name, name.length(), 0); args.GetReturnValue().Set(err); } - #ifdef _WIN32 void PipeWrap::SetPendingInstances(const FunctionCallbackInfo& args) { PipeWrap* wrap; @@ -183,7 +176,6 @@ void PipeWrap::SetPendingInstances(const FunctionCallbackInfo& args) { } #endif - void PipeWrap::Fchmod(const v8::FunctionCallbackInfo& args) { PipeWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); @@ -193,20 +185,17 @@ void PipeWrap::Fchmod(const v8::FunctionCallbackInfo& args) { args.GetReturnValue().Set(err); } - void PipeWrap::Listen(const FunctionCallbackInfo& args) { PipeWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); Environment* env = wrap->env(); int backlog; if (!args[0]->Int32Value(env->context()).To(&backlog)) return; - int err = uv_listen(reinterpret_cast(&wrap->handle_), - backlog, - OnConnection); + int err = uv_listen( + reinterpret_cast(&wrap->handle_), backlog, OnConnection); args.GetReturnValue().Set(err); } - void PipeWrap::Open(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -222,7 +211,6 @@ void PipeWrap::Open(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(err); } - void PipeWrap::Connect(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -237,10 +225,8 @@ void PipeWrap::Connect(const FunctionCallbackInfo& args) { ConnectWrap* req_wrap = new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_PIPECONNECTWRAP); - req_wrap->Dispatch(uv_pipe_connect, - &wrap->handle_, - *name, - AfterConnect); + req_wrap->Dispatch( + uv_pipe_connect2, &wrap->handle_, *name, name.length(), 0, AfterConnect); TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(TRACING_CATEGORY_NODE2(net, native), "connect", @@ -251,7 +237,6 @@ void PipeWrap::Connect(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(0); // uv_pipe_connect() doesn't return errors. } - } // namespace node NODE_BINDING_CONTEXT_AWARE_INTERNAL(pipe_wrap, node::PipeWrap::Initialize) diff --git a/src/quic/bindingdata.cc b/src/quic/bindingdata.cc index 13baa23c54250b..3e95372ba2fc37 100644 --- a/src/quic/bindingdata.cc +++ b/src/quic/bindingdata.cc @@ -25,7 +25,7 @@ using v8::Value; namespace quic { BindingData& BindingData::Get(Environment* env) { - return *Realm::GetBindingData(env->context()); + return *(env->principal_realm()->GetBindingData()); } BindingData::operator ngtcp2_mem() { @@ -59,8 +59,7 @@ void BindingData::DecreaseAllocatedSize(size_t size) { void BindingData::Initialize(Environment* env, Local target) { SetMethod(env->context(), target, "setCallbacks", SetCallbacks); SetMethod(env->context(), target, "flushPacketFreelist", FlushPacketFreelist); - Realm::GetCurrent(env->context()) - ->AddBindingData(env->context(), target); + Realm::GetCurrent(env->context())->AddBindingData(target); } void BindingData::RegisterExternalReferences( diff --git a/src/stream_base.cc b/src/stream_base.cc index 65dab1ccac7cde..cfb1e3ae6a2d7d 100644 --- a/src/stream_base.cc +++ b/src/stream_base.cc @@ -470,8 +470,9 @@ MaybeLocal StreamBase::CallJSOnreadMethod(ssize_t nread, AsyncWrap* wrap = GetAsyncWrap(); CHECK_NOT_NULL(wrap); - Local onread = wrap->object()->GetInternalField( - StreamBase::kOnReadFunctionField); + Local onread = wrap->object() + ->GetInternalField(StreamBase::kOnReadFunctionField) + .As(); CHECK(onread->IsFunction()); return wrap->MakeCallback(onread.As(), arraysize(argv), argv); } diff --git a/src/stream_base.h b/src/stream_base.h index e96ff036157ab9..8f6a7b22ea1f2f 100644 --- a/src/stream_base.h +++ b/src/stream_base.h @@ -225,7 +225,7 @@ class StreamResource { // These need to be implemented on the readable side of this stream: // Start reading from the underlying resource. This is called by the consumer - // when more data is desired. Use `EmitAlloc()` and `EmitData()` to + // when more data is desired. Use `EmitAlloc()` and `EmitRead()` to // pass data along to the consumer. virtual int ReadStart() = 0; // Stop reading from the underlying resource. This is called by the diff --git a/src/timers.cc b/src/timers.cc index 59b4770fa219e8..127806fbcdfd3e 100644 --- a/src/timers.cc +++ b/src/timers.cc @@ -94,7 +94,7 @@ bool BindingData::PrepareForSerialization(Local context, } InternalFieldInfoBase* BindingData::Serialize(int index) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = InternalFieldInfoBase::New(type()); return info; @@ -104,11 +104,11 @@ void BindingData::Deserialize(Local context, Local holder, int index, InternalFieldInfoBase* info) { - DCHECK_EQ(index, BaseObject::kEmbedderType); + DCHECK_IS_SNAPSHOT_SLOT(index); v8::HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); // Recreate the buffer in the constructor. - BindingData* binding = realm->AddBindingData(context, holder); + BindingData* binding = realm->AddBindingData(holder); CHECK_NOT_NULL(binding); } @@ -151,8 +151,7 @@ void BindingData::CreatePerContextProperties(Local target, void* priv) { Realm* realm = Realm::GetCurrent(context); Environment* env = realm->env(); - BindingData* const binding_data = - realm->AddBindingData(context, target); + BindingData* const binding_data = realm->AddBindingData(target); if (binding_data == nullptr) return; // TODO(joyeecheung): move these into BindingData. diff --git a/src/undici_version.h b/src/undici_version.h index af56664e3f04b3..d47c6d538b7355 100644 --- a/src/undici_version.h +++ b/src/undici_version.h @@ -2,5 +2,5 @@ // Refer to tools/update-undici.sh #ifndef SRC_UNDICI_VERSION_H_ #define SRC_UNDICI_VERSION_H_ -#define UNDICI_VERSION "5.22.1" +#define UNDICI_VERSION "5.25.2" #endif // SRC_UNDICI_VERSION_H_ diff --git a/src/util.cc b/src/util.cc index 91c69a98c49c41..19fb91c959a205 100644 --- a/src/util.cc +++ b/src/util.cc @@ -27,7 +27,8 @@ #include "node_buffer.h" #include "node_errors.h" #include "node_internals.h" -#include "node_util.h" +#include "node_snapshot_builder.h" +#include "node_v8_platform-inl.h" #include "string_bytes.h" #include "uv.h" @@ -55,6 +56,7 @@ static std::atomic_int seq = {0}; // Sequence number for diagnostic filenames. namespace node { +using v8::ArrayBuffer; using v8::ArrayBufferView; using v8::Context; using v8::FunctionTemplate; @@ -358,7 +360,7 @@ Local NewFunctionTemplate( void SetMethod(Local context, Local that, - const char* name, + const std::string_view name, v8::FunctionCallback callback) { Isolate* isolate = context->GetIsolate(); Local function = @@ -372,14 +374,15 @@ void SetMethod(Local context, // kInternalized strings are created in the old space. const v8::NewStringType type = v8::NewStringType::kInternalized; Local name_string = - v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked(); + v8::String::NewFromUtf8(isolate, name.data(), type, name.size()) + .ToLocalChecked(); that->Set(context, name_string, function).Check(); function->SetName(name_string); // NODE_SET_METHOD() compatibility. } void SetMethod(v8::Isolate* isolate, v8::Local that, - const char* name, + const std::string_view name, v8::FunctionCallback callback) { Local t = NewFunctionTemplate(isolate, @@ -390,13 +393,14 @@ void SetMethod(v8::Isolate* isolate, // kInternalized strings are created in the old space. const v8::NewStringType type = v8::NewStringType::kInternalized; Local name_string = - v8::String::NewFromUtf8(isolate, name, type).ToLocalChecked(); + v8::String::NewFromUtf8(isolate, name.data(), type, name.size()) + .ToLocalChecked(); that->Set(name_string, t); } void SetFastMethod(Isolate* isolate, Local