| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 452011b commit fad1793
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -139,7 +139,7 @@ const { | |||
| 139 | 139 | const assert = require('internal/assert'); | |
| 140 | 140 | const fs = require('fs'); | |
| 141 | 141 | const path = require('path'); | |
| 142 | - const { internalModuleStat } = internalBinding('fs'); | ||
| 142 | + const internalFsBinding = internalBinding('fs'); | ||
| 143 | 143 | const { safeGetenv } = internalBinding('credentials'); | |
| 144 | 144 | const { | |
| 145 | 145 | getCjsConditions, | |
@@ -225,7 +225,7 @@ function stat(filename) { | |||
| 225 | 225 | const result = statCache.get(filename); | |
| 226 | 226 | if (result !== undefined) { return result; } | |
| 227 | 227 | } | |
| 228 | - const result = internalModuleStat(filename); | ||
| 228 | + const result = internalFsBinding.internalModuleStat(filename); | ||
| 229 | 229 | if (statCache !== null && result >= 0) { | |
| 230 | 230 | // Only set cache when `internalModuleStat(filename)` succeeds. | |
| 231 | 231 | statCache.set(filename, result); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -54,7 +54,7 @@ const { | |||
| 54 | 54 | const { Module: CJSModule } = require('internal/modules/cjs/loader'); | |
| 55 | 55 | const { getConditionsSet } = require('internal/modules/esm/utils'); | |
| 56 | 56 | const packageJsonReader = require('internal/modules/package_json_reader'); | |
| 57 | - const { internalModuleStat } = internalBinding('fs'); | ||
| 57 | + const internalFsBinding = internalBinding('fs'); | ||
| 58 | 58 | ||
| 59 | 59 | /** | |
| 60 | 60 | * @typedef {import('internal/modules/esm/package_config.js').PackageConfig} PackageConfig | |
@@ -246,7 +246,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) { | |||
| 246 | 246 | throw err; | |
| 247 | 247 | } | |
| 248 | 248 | ||
| 249 | - const stats = internalModuleStat(toNamespacedPath(StringPrototypeEndsWith(path, '/') ? | ||
| 249 | + const stats = internalFsBinding.internalModuleStat(toNamespacedPath(StringPrototypeEndsWith(path, '/') ? | ||
| 250 | 250 | StringPrototypeSlice(path, -1) : path)); | |
| 251 | 251 | ||
| 252 | 252 | // Check for stats.isDirectory() | |
@@ -806,8 +806,9 @@ function packageResolve(specifier, base, conditions) { | |||
| 806 | 806 | let packageJSONPath = fileURLToPath(packageJSONUrl); | |
| 807 | 807 | let lastPath; | |
| 808 | 808 | do { | |
| 809 | - const stat = internalModuleStat(toNamespacedPath(StringPrototypeSlice(packageJSONPath, 0, | ||
| 810 | - packageJSONPath.length - 13))); | ||
| 809 | + const stat = internalFsBinding.internalModuleStat( | ||
| 810 | + toNamespacedPath(StringPrototypeSlice(packageJSONPath, 0, packageJSONPath.length - 13)), | ||
| 811 | + ); | ||
| 811 | 812 | // Check for !stat.isDirectory() | |
| 812 | 813 | if (stat !== 1) { | |
| 813 | 814 | lastPath = packageJSONPath; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,6 +15,11 @@ using CFunctionCallbackWithOneByteString = | |||
| 15 | 15 | using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver); | |
| 16 | 16 | using CFunctionCallbackReturnDouble = | |
| 17 | 17 | double (*)(v8::Local<v8::Object> receiver); | |
| 18 | + using CFunctionCallbackReturnInt32 = | ||
| 19 | + int32_t (*)(v8::Local<v8::Object> receiver, | ||
| 20 | + const v8::FastOneByteString& input, | ||
| 21 | + // NOLINTNEXTLINE(runtime/references) This is V8 api. | ||
| 22 | + v8::FastApiCallbackOptions& options); | ||
| 18 | 23 | using CFunctionCallbackValueReturnDouble = | |
| 19 | 24 | double (*)(v8::Local<v8::Value> receiver); | |
| 20 | 25 | using CFunctionCallbackWithInt64 = void (*)(v8::Local<v8::Object> receiver, | |
@@ -55,6 +60,7 @@ class ExternalReferenceRegistry { | |||
| 55 | 60 | V(CFunctionCallback) \ | |
| 56 | 61 | V(CFunctionCallbackWithOneByteString) \ | |
| 57 | 62 | V(CFunctionCallbackReturnDouble) \ | |
| 63 | + V(CFunctionCallbackReturnInt32) \ | ||
| 58 | 64 | V(CFunctionCallbackValueReturnDouble) \ | |
| 59 | 65 | V(CFunctionCallbackWithInt64) \ | |
| 60 | 66 | V(CFunctionCallbackWithBool) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,6 +39,9 @@ | |||
| 39 | 39 | #include "stream_base-inl.h" | |
| 40 | 40 | #include "string_bytes.h" | |
| 41 | 41 | #include "uv.h" | |
| 42 | + #include "v8-fast-api-calls.h" | ||
| 43 | + | ||
| 44 | + #include <filesystem> | ||
| 42 | 45 | ||
| 43 | 46 | #if defined(__MINGW32__) || defined(_MSC_VER) | |
| 44 | 47 | # include <io.h> | |
@@ -52,6 +55,8 @@ using v8::Array; | |||
| 52 | 55 | using v8::BigInt; | |
| 53 | 56 | using v8::Context; | |
| 54 | 57 | using v8::EscapableHandleScope; | |
| 58 | + using v8::FastApiCallbackOptions; | ||
| 59 | + using v8::FastOneByteString; | ||
| 55 | 60 | using v8::Function; | |
| 56 | 61 | using v8::FunctionCallbackInfo; | |
| 57 | 62 | using v8::FunctionTemplate; | |
@@ -1038,6 +1043,33 @@ static void InternalModuleStat(const FunctionCallbackInfo<Value>& args) { | |||
| 1038 | 1043 | args.GetReturnValue().Set(rc); | |
| 1039 | 1044 | } | |
| 1040 | 1045 | ||
| 1046 | + static int32_t FastInternalModuleStat( | ||
| 1047 | + Local<Object> recv, | ||
| 1048 | + const FastOneByteString& input, | ||
| 1049 | + // NOLINTNEXTLINE(runtime/references) This is V8 api. | ||
| 1050 | + FastApiCallbackOptions& options) { | ||
| 1051 | + Environment* env = Environment::GetCurrent(recv->GetCreationContextChecked()); | ||
| 1052 | + | ||
| 1053 | + auto path = std::filesystem::path(input.data, input.data + input.length); | ||
| 1054 | + if (UNLIKELY(!env->permission()->is_granted( | ||
| 1055 | + env, permission::PermissionScope::kFileSystemRead, path.string()))) { | ||
| 1056 | + options.fallback = true; | ||
| 1057 | + return -1; | ||
| 1058 | + } | ||
| 1059 | + | ||
| 1060 | + switch (std::filesystem::status(path).type()) { | ||
| 1061 | + case std::filesystem::file_type::directory: | ||
| 1062 | + return 1; | ||
| 1063 | + case std::filesystem::file_type::regular: | ||
| 1064 | + return 0; | ||
| 1065 | + default: | ||
| 1066 | + return -1; | ||
| 1067 | + } | ||
| 1068 | + } | ||
| 1069 | + | ||
| 1070 | + v8::CFunction fast_internal_module_stat_( | ||
| 1071 | + v8::CFunction::Make(FastInternalModuleStat)); | ||
| 1072 | + | ||
| 1041 | 1073 | constexpr bool is_uv_error_except_no_entry(int result) { | |
| 1042 | 1074 | return result < 0 && result != UV_ENOENT; | |
| 1043 | 1075 | } | |
@@ -3261,7 +3293,11 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, | |||
| 3261 | 3293 | SetMethod(isolate, target, "rmdir", RMDir); | |
| 3262 | 3294 | SetMethod(isolate, target, "mkdir", MKDir); | |
| 3263 | 3295 | SetMethod(isolate, target, "readdir", ReadDir); | |
| 3264 | - SetMethod(isolate, target, "internalModuleStat", InternalModuleStat); | ||
| 3296 | + SetFastMethod(isolate, | ||
| 3297 | + target, | ||
| 3298 | + "internalModuleStat", | ||
| 3299 | + InternalModuleStat, | ||
| 3300 | + &fast_internal_module_stat_); | ||
| 3265 | 3301 | SetMethod(isolate, target, "stat", Stat); | |
| 3266 | 3302 | SetMethod(isolate, target, "lstat", LStat); | |
| 3267 | 3303 | SetMethod(isolate, target, "fstat", FStat); | |
@@ -3382,6 +3418,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |||
| 3382 | 3418 | registry->Register(MKDir); | |
| 3383 | 3419 | registry->Register(ReadDir); | |
| 3384 | 3420 | registry->Register(InternalModuleStat); | |
| 3421 | + registry->Register(FastInternalModuleStat); | ||
| 3422 | + registry->Register(fast_internal_module_stat_.GetTypeInfo()); | ||
| 3385 | 3423 | registry->Register(Stat); | |
| 3386 | 3424 | registry->Register(LStat); | |
| 3387 | 3425 | registry->Register(FStat); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,26 @@ | |||
| 1 | + // Flags: --expose-internals --experimental-permission --allow-fs-read=test/common* --allow-fs-read=tools* --allow-fs-read=test/parallel* --allow-child-process | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + const common = require('../common'); | ||
| 5 | + common.skipIfWorker(); | ||
| 6 | + | ||
| 7 | + if (!common.hasCrypto) { | ||
| 8 | + common.skip('no crypto'); | ||
| 9 | + } | ||
| 10 | + | ||
| 11 | + const { internalBinding } = require('internal/test/binding'); | ||
| 12 | + const assert = require('node:assert'); | ||
| 13 | + const fixtures = require('../common/fixtures'); | ||
| 14 | + | ||
| 15 | + const blockedFile = fixtures.path('permission', 'deny', 'protected-file.md'); | ||
| 16 | + const internalFsBinding = internalBinding('fs'); | ||
| 17 | + | ||
| 18 | + // Run this inside a for loop to trigger the fast API | ||
| 19 | + for (let i = 0; i < 10_000; i++) { | ||
| 20 | + assert.throws(() => { | ||
| 21 | + internalFsBinding.internalModuleStat(blockedFile); | ||
| 22 | + }, { | ||
| 23 | + code: 'ERR_ACCESS_DENIED', | ||
| 24 | + permission: 'FileSystemRead', | ||
| 25 | + }); | ||
| 26 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments