xwt
2025-07-04 b76e716ff4656191d73eba398e9eb39ee975e13b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
'use strict';
 
var test = require('tape');
var keys = require('object-keys');
var semver = require('semver');
var mockProperty = require('mock-property');
 
var isCore = require('../');
var data = require('../core.json');
 
var supportsNodePrefix = semver.satisfies(process.versions.node, '^14.18 || >= 16', { includePrerelease: true });
 
test('core modules', function (t) {
    t.test('isCore()', function (st) {
        st.ok(isCore('fs'));
        st.ok(isCore('net'));
        st.ok(isCore('http'));
 
        st.ok(!isCore('seq'));
        st.ok(!isCore('../'));
 
        st.ok(!isCore('toString'));
 
        st.end();
    });
 
    t.test('core list', function (st) {
        var cores = keys(data);
        st.plan(cores.length);
 
        for (var i = 0; i < cores.length; ++i) {
            var mod = cores[i];
            var requireFunc = function () { require(mod); }; // eslint-disable-line no-loop-func
            if (isCore(mod)) {
                st.doesNotThrow(requireFunc, mod + ' supported; requiring does not throw');
            } else {
                st['throws'](requireFunc, mod + ' not supported; requiring throws');
            }
        }
 
        st.end();
    });
 
    t.test('core via repl module', { skip: !data.repl }, function (st) {
        var libs = require('repl')._builtinLibs; // eslint-disable-line no-underscore-dangle
        if (!libs) {
            st.skip('repl._builtinLibs does not exist');
        } else {
            for (var i = 0; i < libs.length; ++i) {
                var mod = libs[i];
                st.ok(data[mod], mod + ' is a core module');
                st.doesNotThrow(
                    function () { require(mod); }, // eslint-disable-line no-loop-func
                    'requiring ' + mod + ' does not throw'
                );
                if (mod.slice(0, 5) !== 'node:') {
                    if (supportsNodePrefix) {
                        st.doesNotThrow(
                            function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
                            'requiring node:' + mod + ' does not throw'
                        );
                    } else {
                        st['throws'](
                            function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
                            'requiring node:' + mod + ' throws'
                        );
                    }
                }
            }
        }
        st.end();
    });
 
    t.test('core via builtinModules list', { skip: !data.module }, function (st) {
        var Module = require('module');
        var libs = Module.builtinModules;
        if (!libs) {
            st.skip('module.builtinModules does not exist');
        } else {
            var excludeList = [
                '_debug_agent',
                'v8/tools/tickprocessor-driver',
                'v8/tools/SourceMap',
                'v8/tools/tickprocessor',
                'v8/tools/profile'
            ];
 
            // see https://github.com/nodejs/node/issues/42785
            if (semver.satisfies(process.version, '>= 18')) {
                libs = libs.concat('node:test');
            }
            if (semver.satisfies(process.version, '^20.12 || >= 21.7')) {
                libs = libs.concat('node:sea');
            }
            if (semver.satisfies(process.version, '>= 23.4')) {
                libs = libs.concat('node:sqlite');
            }
 
            for (var i = 0; i < libs.length; ++i) {
                var mod = libs[i];
                if (excludeList.indexOf(mod) === -1) {
                    st.ok(data[mod], mod + ' is a core module');
 
                    if (Module.isBuiltin) {
                        st.ok(Module.isBuiltin(mod), 'module.isBuiltin(' + mod + ') is true');
                    }
 
                    st.doesNotThrow(
                        function () { require(mod); }, // eslint-disable-line no-loop-func
                        'requiring ' + mod + ' does not throw'
                    );
 
                    if (process.getBuiltinModule) {
                        st.equal(
                            process.getBuiltinModule(mod),
                            require(mod),
                            'process.getBuiltinModule(' + mod + ') === require(' + mod + ')'
                        );
                    }
 
                    if (mod.slice(0, 5) !== 'node:') {
                        if (supportsNodePrefix) {
                            st.doesNotThrow(
                                function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
                                'requiring node:' + mod + ' does not throw'
                            );
                        } else {
                            st['throws'](
                                function () { require('node:' + mod); }, // eslint-disable-line no-loop-func
                                'requiring node:' + mod + ' throws'
                            );
                        }
                    }
                }
            }
        }
 
        st.end();
    });
 
    t.test('Object.prototype pollution', function (st) {
        var nonKey = 'not a core module';
        st.teardown(mockProperty(Object.prototype, 'fs', { value: false }));
        st.teardown(mockProperty(Object.prototype, 'path', { value: '>= 999999999' }));
        st.teardown(mockProperty(Object.prototype, 'http', { value: data.http }));
        st.teardown(mockProperty(Object.prototype, nonKey, { value: true }));
 
        st.equal(isCore('fs'), true, 'fs is a core module even if Object.prototype lies');
        st.equal(isCore('path'), true, 'path is a core module even if Object.prototype lies');
        st.equal(isCore('http'), true, 'path is a core module even if Object.prototype matches data');
        st.equal(isCore(nonKey), false, '"' + nonKey + '" is not a core module even if Object.prototype lies');
 
        st.end();
    });
 
    t.end();
});