Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Ceres6 committed Oct 24, 2023
1 parent a69c6e8 commit 5b926e2
Show file tree
Hide file tree
Showing 14 changed files with 81 additions and 53 deletions.
12 changes: 8 additions & 4 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -858,20 +858,24 @@ Environment::Environment(IsolateData* isolate_data,
flags_ = flags_ | EnvironmentFlags::kNoCreateInspector;
permission()->Apply(this, "*", permission::PermissionScope::kInspector);
if (!options_->allow_child_process) {
permission()->Apply(this, "*", permission::PermissionScope::kChildProcess);
permission()->Apply(
this, "*", permission::PermissionScope::kChildProcess);
}
if (!options_->allow_worker_threads) {
permission()->Apply(this, "*", permission::PermissionScope::kWorkerThreads);
permission()->Apply(
this, "*", permission::PermissionScope::kWorkerThreads);
}
}

if (!options_->allow_fs_read.empty()) {
permission()->Apply(this, options_->allow_fs_read,
permission()->Apply(this,
options_->allow_fs_read,
permission::PermissionScope::kFileSystemRead);
}

if (!options_->allow_fs_write.empty()) {
permission()->Apply(this, options_->allow_fs_write,
permission()->Apply(this,
options_->allow_fs_write,
permission::PermissionScope::kFileSystemWrite);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/permission/child_process_permission.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ namespace permission {

// Currently, ChildProcess manage a single state
// Once denied, it's always denied
void ChildProcessPermission::Apply(Environment* env, const std::string& allow,
void ChildProcessPermission::Apply(Environment* env,
const std::string& allow,
PermissionScope scope) {
deny_all_ = true;
}
Expand Down
4 changes: 3 additions & 1 deletion src/permission/child_process_permission.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ namespace permission {

class ChildProcessPermission final : public PermissionBase {
public:
void Apply(Environment* env, const std::string& allow, PermissionScope scope) override;
void Apply(Environment* env,
const std::string& allow,
PermissionScope scope) override;
bool is_granted(PermissionScope perm,
const std::string_view& param = "") override;

Expand Down
9 changes: 4 additions & 5 deletions src/permission/fs_permission.cc
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ namespace permission {

// allow = '*'
// allow = '/tmp/,/home/example.js'
void FSPermission::Apply(Environment* env, const std::string& allow, PermissionScope scope) {
void FSPermission::Apply(Environment* env,
const std::string& allow,
PermissionScope scope) {
using std::string_view_literals::operator""sv;
for (const std::string_view res : SplitString(allow, ","sv)) {
if (res == "*"sv) {
Expand All @@ -129,10 +131,7 @@ void FSPermission::Apply(Environment* env, const std::string& allow, PermissionS
}
return;
}
GrantAccess(
scope,
PathResolve(env, { { res.data(), res.size() } })
);
GrantAccess(scope, PathResolve(env, {{res.data(), res.size()}}));
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/permission/fs_permission.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ namespace permission {

class FSPermission final : public PermissionBase {
public:
void Apply(Environment* env, const std::string& allow, PermissionScope scope) override;
void Apply(Environment* env,
const std::string& allow,
PermissionScope scope) override;
bool is_granted(PermissionScope perm, const std::string_view& param) override;

struct RadixTree {
Expand Down
3 changes: 2 additions & 1 deletion src/permission/inspector_permission.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace permission {

// Currently, Inspector manage a single state
// Once denied, it's always denied
void InspectorPermission::Apply(Environment* env, const std::string& allow,
void InspectorPermission::Apply(Environment* env,
const std::string& allow,
PermissionScope scope) {
deny_all_ = true;
}
Expand Down
4 changes: 3 additions & 1 deletion src/permission/inspector_permission.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ namespace permission {

class InspectorPermission final : public PermissionBase {
public:
void Apply(Environment* env, const std::string& allow, PermissionScope scope) override;
void Apply(Environment* env,
const std::string& allow,
PermissionScope scope) override;
bool is_granted(PermissionScope perm,
const std::string_view& param = "") override;

Expand Down
4 changes: 3 additions & 1 deletion src/permission/permission.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ void Permission::EnablePermissions() {
}
}

void Permission::Apply(Environment* env, const std::string& allow, PermissionScope scope) {
void Permission::Apply(Environment* env,
const std::string& allow,
PermissionScope scope) {
auto permission = nodes_.find(scope);
if (permission != nodes_.end()) {
permission->second->Apply(env, allow, scope);
Expand Down
4 changes: 3 additions & 1 deletion src/permission/permission_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ enum class PermissionScope {

class PermissionBase {
public:
virtual void Apply(Environment* env, const std::string& allow, PermissionScope scope) = 0;
virtual void Apply(Environment* env,
const std::string& allow,
PermissionScope scope) = 0;
virtual bool is_granted(PermissionScope perm,
const std::string_view& param = "") = 0;
};
Expand Down
4 changes: 3 additions & 1 deletion src/permission/worker_permission.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace permission {

// Currently, PolicyDenyWorker manage a single state
// Once denied, it's always denied
void WorkerPermission::Apply(Environment* env, const std::string& allow, PermissionScope scope) {
void WorkerPermission::Apply(Environment* env,
const std::string& allow,
PermissionScope scope) {
deny_all_ = true;
}

Expand Down
4 changes: 3 additions & 1 deletion src/permission/worker_permission.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ namespace permission {

class WorkerPermission final : public PermissionBase {
public:
void Apply(Environment* env, const std::string& allow, PermissionScope scope) override;
void Apply(Environment* env,
const std::string& allow,
PermissionScope scope) override;
bool is_granted(PermissionScope perm,
const std::string_view& param = "") override;

Expand Down
61 changes: 34 additions & 27 deletions src/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,9 @@ bool IsPathSeparator(const char c) {
}
#endif

std::string NormalizeString(const std::string path, bool allowAboveRoot, const std::string separator) {
std::string NormalizeString(const std::string path,
bool allowAboveRoot,
const std::string separator) {
std::string res = "";
int lastSegmentLength = 0;
int lastSlash = -1;
Expand All @@ -678,11 +680,12 @@ std::string NormalizeString(const std::string path, bool allowAboveRoot, const s
}

if (IsPathSeparator(code)) {
if (lastSlash == (int)(i - 1) || dots == 1) {
if (lastSlash == static_cast<int>(i - 1) || dots == 1) {
// NOOP
} else if (dots == 2) {
int len = res.length();
if (len < 2 || lastSegmentLength != 2 || res[len - 1] != '.' || res[len - 2] != '.') {
if (len < 2 || lastSegmentLength != 2 || res[len - 1] != '.' ||
res[len - 2] != '.') {
if (len > 2) {
auto lastSlashIndex = res.find_last_of(separator);
if (lastSlashIndex == std::string::npos) {
Expand Down Expand Up @@ -736,7 +739,8 @@ bool IsWindowsDeviceRoot(const char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}

std::string PathResolve(Environment* env, const std::vector<std::string_view>& paths) {
std::string PathResolve(Environment* env,
const std::vector<std::string_view>& paths) {
std::string resolvedDevice = "";
std::string resolvedTail = "";
bool resolvedAbsolute = false;
Expand All @@ -755,11 +759,13 @@ std::string PathResolve(Environment* env, const std::vector<std::string_view>& p
// absolute path, get cwd for that drive, or the process cwd if
// the drive cwd is not available. We're sure the device is not
// a UNC path at this points, because UNC paths are always absolute.
path = env->GetCwd(); // FIXME: how can I get envvar?
path = env->GetCwd(); // FIXME: how can I get envvar?

// Verify that a cwd was found and that it actually points
// to our drive. If not, default to the drive's root.
if (path.empty() || (ToLower(path.substr(0, 2)) != ToLower(resolvedDevice) && path[2] == '/')) {
if (path.empty() ||
(ToLower(path.substr(0, 2)) != ToLower(resolvedDevice) &&
path[2] == '/')) {
path = resolvedDevice + "\\";
}
}
Expand All @@ -772,7 +778,7 @@ std::string PathResolve(Environment* env, const std::vector<std::string_view>& p

// Try to match a root
if (len == 1) {
if(IsPathSeparator(code)) {
if (IsPathSeparator(code)) {
// `path` contains just a path separator
rootEnd = 1;
isAbsolute = true;
Expand Down Expand Up @@ -829,7 +835,7 @@ std::string PathResolve(Environment* env, const std::vector<std::string_view>& p

if (!device.empty()) {
if (!resolvedDevice.empty()) {
if(ToLower(device) != ToLower(resolvedDevice)) {
if (ToLower(device) != ToLower(resolvedDevice)) {
// This path points to another device so it is not applicable
continue;
}
Expand Down Expand Up @@ -870,28 +876,29 @@ std::string PathResolve(Environment* env, const std::vector<std::string_view>& p
}
#else
// posix
std::string PathResolve(Environment* env, const std::vector<std::string_view>& paths) {
std::string resolvedPath = "";
bool resolvedAbsolute = false;
const size_t numArgs = paths.size();

for (int i = numArgs - 1; i >= -1 && !resolvedAbsolute; i--) {
const std::string& path = (i >= 0) ? std::string(paths[i]) : env->GetCwd();
/* validateString(path, "paths[" + std::to_string(i) + "]"); */

if (!path.empty()) {
resolvedPath = std::string(path + "/" + resolvedPath);
resolvedAbsolute = (path[0] == '/');
}
}
std::string PathResolve(Environment* env,
const std::vector<std::string_view>& paths) {
std::string resolvedPath = "";
bool resolvedAbsolute = false;
const size_t numArgs = paths.size();

// Normalize the path
resolvedPath = NormalizeString(resolvedPath, !resolvedAbsolute, "/");
for (int i = numArgs - 1; i >= -1 && !resolvedAbsolute; i--) {
const std::string& path = (i >= 0) ? std::string(paths[i]) : env->GetCwd();
/* validateString(path, "paths[" + std::to_string(i) + "]"); */

if (resolvedAbsolute) {
return "/" + resolvedPath;
if (!path.empty()) {
resolvedPath = std::string(path + "/" + resolvedPath);
resolvedAbsolute = (path[0] == '/');
}
return (!resolvedPath.empty()) ? resolvedPath : ".";
}

// Normalize the path
resolvedPath = NormalizeString(resolvedPath, !resolvedAbsolute, "/");

if (resolvedAbsolute) {
return "/" + resolvedPath;
}
return (!resolvedPath.empty()) ? resolvedPath : ".";
}
#endif
} // namespace node
7 changes: 5 additions & 2 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -971,9 +971,12 @@ class RAIIIsolate {
v8::Isolate* isolate_;
};

std::string NormalizeString(const std::string path, bool allowAboveRoot, const std::string separator);
std::string NormalizeString(const std::string path,
bool allowAboveRoot,
const std::string separator);

std::string PathResolve(Environment* env, const std::vector<std::string_view>& args);
std::string PathResolve(Environment* env,
const std::vector<std::string_view>& args);

} // namespace node

Expand Down
11 changes: 5 additions & 6 deletions test/cctest/test_util.cc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "debug_utils-inl.h"
#include "env-inl.h"
#include "gtest/gtest.h"
#include "node_options.h"
#include "node_test_fixture.h"
#include "simdutf.h"
#include "util-inl.h"
#include "node_test_fixture.h"
#include "node_options.h"

using node::Calloc;
using node::Malloc;
Expand Down Expand Up @@ -311,8 +311,7 @@ TEST_F(UtilTest, PathResolve) {
"c:\\blah\\a");
EXPECT_EQ(PathResolve(*env, {"c:/ignore", "d:\\a/b\\c/d", "\\e.exe"}),
"d:\\e.exe");
EXPECT_EQ(PathResolve(*env, {"c:/ignore", "c:/some/file"}),
"c:\\some\\file");
EXPECT_EQ(PathResolve(*env, {"c:/ignore", "c:/some/file"}), "c:\\some\\file");
EXPECT_EQ(PathResolve(*env, {"d:/ignore", "d:some/dir//"}),
"d:\\ignore\\some\\dir");
EXPECT_EQ(PathResolve(*env, {"."}), (*env)->GetCwd());
Expand All @@ -334,10 +333,10 @@ TEST_F(UtilTest, PathResolve) {
Env env{handle_scope, argv, node::EnvironmentFlags::kNoBrowserGlobals};
EXPECT_EQ(PathResolve(*env, {"/var/lib", "../", "file/"}), "/var/file");
EXPECT_EQ(PathResolve(*env, {"/var/lib", "/../", "file/"}), "/file");
EXPECT_EQ(PathResolve(*env, {"a/b/c/", "../../.."}), (*env)->GetCwd()); //
EXPECT_EQ(PathResolve(*env, {"a/b/c/", "../../.."}), (*env)->GetCwd()); //
EXPECT_EQ(PathResolve(*env, {"."}), (*env)->GetCwd());
EXPECT_EQ(PathResolve(*env, {"/some/dir", ".", "/absolute/"}), "/absolute");
EXPECT_EQ(PathResolve(*env, {"/foo/tmp.3/", "../tmp.3/cycles/root.js"}),
"/foo/tmp.3/cycles/root.js");
#endif
}
}

0 comments on commit 5b926e2

Please sign in to comment.