@@ -64,8 +64,11 @@ using v8::HandleScope;
64
64
using v8::Int32;
65
65
using v8::Integer;
66
66
using v8::Isolate;
67
+ using v8::JustVoid;
67
68
using v8::Local;
69
+ using v8::Maybe;
68
70
using v8::MaybeLocal;
71
+ using v8::Nothing;
69
72
using v8::Number;
70
73
using v8::Object;
71
74
using v8::ObjectTemplate;
@@ -1949,6 +1952,37 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
1949
1952
}
1950
1953
}
1951
1954
1955
+ static inline Maybe<void > CheckOpenPermissions (Environment* env,
1956
+ const BufferValue& path,
1957
+ int flags) {
1958
+ // These flags capture the intention of the open() call.
1959
+ const int rwflags = flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR);
1960
+
1961
+ // These flags have write-like side effects even with O_RDONLY, at least on
1962
+ // some operating systems. On Windows, for example, O_RDONLY | O_TEMPORARY
1963
+ // can be used to delete a file. Bizarre.
1964
+ const int write_as_side_effect = flags & (UV_FS_O_APPEND | UV_FS_O_CREAT |
1965
+ UV_FS_O_TRUNC | UV_FS_O_TEMPORARY);
1966
+
1967
+ // TODO(rafaelgss): it can be optimized to avoid two permission checks
1968
+ auto pathView = path.ToStringView ();
1969
+ if (rwflags != UV_FS_O_WRONLY) {
1970
+ THROW_IF_INSUFFICIENT_PERMISSIONS (
1971
+ env,
1972
+ permission::PermissionScope::kFileSystemRead ,
1973
+ pathView,
1974
+ Nothing<void >());
1975
+ }
1976
+ if (rwflags != UV_FS_O_RDONLY || write_as_side_effect) {
1977
+ THROW_IF_INSUFFICIENT_PERMISSIONS (
1978
+ env,
1979
+ permission::PermissionScope::kFileSystemWrite ,
1980
+ pathView,
1981
+ Nothing<void >());
1982
+ }
1983
+ return JustVoid ();
1984
+ }
1985
+
1952
1986
static void Open (const FunctionCallbackInfo<Value>& args) {
1953
1987
Environment* env = Environment::GetCurrent (args);
1954
1988
@@ -1964,22 +1998,7 @@ static void Open(const FunctionCallbackInfo<Value>& args) {
1964
1998
CHECK (args[2 ]->IsInt32 ());
1965
1999
const int mode = args[2 ].As <Int32>()->Value ();
1966
2000
1967
- auto pathView = path.ToStringView ();
1968
- // Open can be called either in write or read
1969
- if (flags == O_RDWR) {
1970
- // TODO(rafaelgss): it can be optimized to avoid O(2*n)
1971
- THROW_IF_INSUFFICIENT_PERMISSIONS (
1972
- env, permission::PermissionScope::kFileSystemRead , pathView);
1973
- THROW_IF_INSUFFICIENT_PERMISSIONS (
1974
- env, permission::PermissionScope::kFileSystemWrite , pathView);
1975
- } else if ((flags & ~(UV_FS_O_RDONLY | UV_FS_O_SYNC)) == 0 ) {
1976
- THROW_IF_INSUFFICIENT_PERMISSIONS (
1977
- env, permission::PermissionScope::kFileSystemRead , pathView);
1978
- } else if ((flags & (UV_FS_O_APPEND | UV_FS_O_TRUNC | UV_FS_O_CREAT |
1979
- UV_FS_O_WRONLY)) != 0 ) {
1980
- THROW_IF_INSUFFICIENT_PERMISSIONS (
1981
- env, permission::PermissionScope::kFileSystemWrite , pathView);
1982
- }
2001
+ if (CheckOpenPermissions (env, path, flags).IsNothing ()) return ;
1983
2002
1984
2003
FSReqBase* req_wrap_async = GetReqWrap (args, 3 );
1985
2004
if (req_wrap_async != nullptr ) { // open(path, flags, mode, req)
@@ -2010,31 +2029,14 @@ static void OpenFileHandle(const FunctionCallbackInfo<Value>& args) {
2010
2029
2011
2030
BufferValue path (isolate, args[0 ]);
2012
2031
CHECK_NOT_NULL (*path);
2013
- auto pathView = path.ToStringView ();
2014
- THROW_IF_INSUFFICIENT_PERMISSIONS (
2015
- env, permission::PermissionScope::kFileSystemRead , pathView);
2016
2032
2017
2033
CHECK (args[1 ]->IsInt32 ());
2018
2034
const int flags = args[1 ].As <Int32>()->Value ();
2019
2035
2020
2036
CHECK (args[2 ]->IsInt32 ());
2021
2037
const int mode = args[2 ].As <Int32>()->Value ();
2022
2038
2023
- // Open can be called either in write or read
2024
- if (flags == O_RDWR) {
2025
- // TODO(rafaelgss): it can be optimized to avoid O(2*n)
2026
- THROW_IF_INSUFFICIENT_PERMISSIONS (
2027
- env, permission::PermissionScope::kFileSystemRead , pathView);
2028
- THROW_IF_INSUFFICIENT_PERMISSIONS (
2029
- env, permission::PermissionScope::kFileSystemWrite , pathView);
2030
- } else if ((flags & ~(UV_FS_O_RDONLY | UV_FS_O_SYNC)) == 0 ) {
2031
- THROW_IF_INSUFFICIENT_PERMISSIONS (
2032
- env, permission::PermissionScope::kFileSystemRead , pathView);
2033
- } else if ((flags & (UV_FS_O_APPEND | UV_FS_O_TRUNC | UV_FS_O_CREAT |
2034
- UV_FS_O_WRONLY)) != 0 ) {
2035
- THROW_IF_INSUFFICIENT_PERMISSIONS (
2036
- env, permission::PermissionScope::kFileSystemWrite , pathView);
2037
- }
2039
+ if (CheckOpenPermissions (env, path, flags).IsNothing ()) return ;
2038
2040
2039
2041
FSReqBase* req_wrap_async = GetReqWrap (args, 3 );
2040
2042
if (req_wrap_async != nullptr ) { // openFileHandle(path, flags, mode, req)
0 commit comments