Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4fe96b1

Browse files
anonrigdanielleadams
authored andcommitted
src: avoid copying string in fs_permission
PR-URL:#47746Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>Reviewed-By: Luigi Pinca <luigipinca@gmail.com>Reviewed-By: Deokjin Kim <deokjin81.kim@gmail.com>Reviewed-By: Darshan Sen <raisinten@gmail.com>
1 parent7771b61 commit4fe96b1

File tree

2 files changed

+332
-0
lines changed

2 files changed

+332
-0
lines changed

‎src/permission/fs_permission.cc

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#include"fs_permission.h"
2+
#include"base_object-inl.h"
3+
#include"util.h"
4+
#include"v8.h"
5+
6+
#include<fcntl.h>
7+
#include<limits.h>
8+
#include<stdlib.h>
9+
#include<algorithm>
10+
#include<filesystem>
11+
#include<string>
12+
#include<vector>
13+
14+
namespace {
15+
16+
std::stringWildcardIfDir(const std::string& res)noexcept {
17+
uv_fs_t req;
18+
int rc =uv_fs_stat(nullptr, &req, res.c_str(),nullptr);
19+
if (rc ==0) {
20+
constuv_stat_t*const s =static_cast<constuv_stat_t*>(req.ptr);
21+
if (s->st_mode & S_IFDIR) {
22+
// add wildcard when directory
23+
if (res.back() == node::kPathSeparator) {
24+
return res +"*";
25+
}
26+
return res + node::kPathSeparator +"*";
27+
}
28+
}
29+
uv_fs_req_cleanup(&req);
30+
return res;
31+
}
32+
33+
voidFreeRecursivelyNode(
34+
node::permission::FSPermission::RadixTree::Node* node) {
35+
if (node ==nullptr) {
36+
return;
37+
}
38+
39+
if (node->children.size()) {
40+
for (auto& c : node->children) {
41+
FreeRecursivelyNode(c.second);
42+
}
43+
}
44+
45+
if (node->wildcard_child !=nullptr) {
46+
delete node->wildcard_child;
47+
}
48+
delete node;
49+
}
50+
51+
boolis_tree_granted(node::permission::FSPermission::RadixTree* granted_tree,
52+
const std::string_view& param) {
53+
#ifdef _WIN32
54+
// is UNC file path
55+
if (param.rfind("\\\\",0) ==0) {
56+
// return lookup with normalized param
57+
int starting_pos =4;// "\\?\"
58+
if (param.rfind("\\\\?\\UNC\\") ==0) {
59+
starting_pos +=4;// "UNC\"
60+
}
61+
auto normalized = param.substr(starting_pos);
62+
return granted_tree->Lookup(normalized,true);
63+
}
64+
#endif
65+
return granted_tree->Lookup(param,true);
66+
}
67+
68+
}// namespace
69+
70+
namespacenode {
71+
72+
namespacepermission {
73+
74+
// allow = '*'
75+
// allow = '/tmp/,/home/example.js'
76+
voidFSPermission::Apply(const std::string& allow, PermissionScope scope) {
77+
for (constauto& res :SplitString(allow,',')) {
78+
if (res =="*") {
79+
if (scope == PermissionScope::kFileSystemRead) {
80+
deny_all_in_ =false;
81+
allow_all_in_ =true;
82+
}else {
83+
deny_all_out_ =false;
84+
allow_all_out_ =true;
85+
}
86+
return;
87+
}
88+
GrantAccess(scope, res);
89+
}
90+
}
91+
92+
voidFSPermission::GrantAccess(PermissionScope perm,const std::string& res) {
93+
const std::string path =WildcardIfDir(res);
94+
if (perm == PermissionScope::kFileSystemRead) {
95+
granted_in_fs_.Insert(path);
96+
deny_all_in_ =false;
97+
}elseif (perm == PermissionScope::kFileSystemWrite) {
98+
granted_out_fs_.Insert(path);
99+
deny_all_out_ =false;
100+
}
101+
}
102+
103+
boolFSPermission::is_granted(PermissionScope perm,
104+
const std::string_view& param ="") {
105+
switch (perm) {
106+
case PermissionScope::kFileSystem:
107+
return allow_all_in_ && allow_all_out_;
108+
case PermissionScope::kFileSystemRead:
109+
return !deny_all_in_ &&
110+
((param.empty() && allow_all_in_) || allow_all_in_ ||
111+
is_tree_granted(&granted_in_fs_, param));
112+
case PermissionScope::kFileSystemWrite:
113+
return !deny_all_out_ &&
114+
((param.empty() && allow_all_out_) || allow_all_out_ ||
115+
is_tree_granted(&granted_out_fs_, param));
116+
default:
117+
returnfalse;
118+
}
119+
}
120+
121+
FSPermission::RadixTree::RadixTree() : root_node_(new Node("")) {}
122+
123+
FSPermission::RadixTree::~RadixTree() {
124+
FreeRecursivelyNode(root_node_);
125+
}
126+
127+
boolFSPermission::RadixTree::Lookup(const std::string_view& s,
128+
bool when_empty_return =false) {
129+
FSPermission::RadixTree::Node* current_node = root_node_;
130+
if (current_node->children.size() ==0) {
131+
return when_empty_return;
132+
}
133+
134+
unsignedint parent_node_prefix_len = current_node->prefix.length();
135+
const std::stringpath(s);
136+
auto path_len = path.length();
137+
138+
while (true) {
139+
if (parent_node_prefix_len == path_len && current_node->IsEndNode()) {
140+
returntrue;
141+
}
142+
143+
auto node = current_node->NextNode(path, parent_node_prefix_len);
144+
if (node ==nullptr) {
145+
returnfalse;
146+
}
147+
148+
current_node = node;
149+
parent_node_prefix_len += current_node->prefix.length();
150+
if (current_node->wildcard_child !=nullptr &&
151+
path_len >= (parent_node_prefix_len -2/* slash**/)) {
152+
returntrue;
153+
}
154+
}
155+
}
156+
157+
voidFSPermission::RadixTree::Insert(const std::string& path) {
158+
FSPermission::RadixTree::Node* current_node = root_node_;
159+
160+
unsignedint parent_node_prefix_len = current_node->prefix.length();
161+
int path_len = path.length();
162+
163+
for (int i =1; i <= path_len; ++i) {
164+
bool is_wildcard_node = path[i -1] =='*';
165+
bool is_last_char = i == path_len;
166+
167+
if (is_wildcard_node || is_last_char) {
168+
std::string node_path = path.substr(parent_node_prefix_len, i);
169+
current_node = current_node->CreateChild(node_path);
170+
}
171+
172+
if (is_wildcard_node) {
173+
current_node = current_node->CreateWildcardChild();
174+
parent_node_prefix_len = i;
175+
}
176+
}
177+
}
178+
179+
}// namespace permission
180+
}// namespace node

‎src/permission/fs_permission.h

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#ifndef SRC_PERMISSION_FS_PERMISSION_H_
2+
#defineSRC_PERMISSION_FS_PERMISSION_H_
3+
4+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5+
6+
#include"v8.h"
7+
8+
#include<unordered_map>
9+
#include<vector>
10+
#include"permission/permission_base.h"
11+
#include"util.h"
12+
13+
namespacenode {
14+
15+
namespacepermission {
16+
17+
classFSPermissionfinal : public PermissionBase {
18+
public:
19+
voidApply(const std::string& deny, PermissionScope scope)override;
20+
boolis_granted(PermissionScope perm,const std::string_view& param)override;
21+
22+
// For debugging purposes, use the gist function to print the whole tree
23+
// https://gist.github.com/RafaelGSS/5b4f09c559a54f53f9b7c8c030744d19
24+
structRadixTree {
25+
structNode {
26+
std::string prefix;
27+
std::unordered_map<char, Node*> children;
28+
Node* wildcard_child;
29+
30+
explicitNode(const std::string& pre)
31+
: prefix(pre), wildcard_child(nullptr) {}
32+
33+
Node() : wildcard_child(nullptr) {}
34+
35+
Node*CreateChild(std::string prefix) {
36+
char label = prefix[0];
37+
38+
Node* child = children[label];
39+
if (child ==nullptr) {
40+
children[label] =newNode(prefix);
41+
return children[label];
42+
}
43+
44+
// swap prefix
45+
unsignedint i =0;
46+
unsignedint prefix_len = prefix.length();
47+
for (; i < child->prefix.length(); ++i) {
48+
if (i > prefix_len || prefix[i] != child->prefix[i]) {
49+
std::string parent_prefix = child->prefix.substr(0, i);
50+
std::string child_prefix = child->prefix.substr(i);
51+
52+
child->prefix = child_prefix;
53+
Node* split_child =newNode(parent_prefix);
54+
split_child->children[child_prefix[0]] = child;
55+
children[parent_prefix[0]] = split_child;
56+
57+
return split_child->CreateChild(prefix.substr(i));
58+
}
59+
}
60+
return child->CreateChild(prefix.substr(i));
61+
}
62+
63+
Node*CreateWildcardChild() {
64+
if (wildcard_child !=nullptr) {
65+
return wildcard_child;
66+
}
67+
wildcard_child =newNode();
68+
return wildcard_child;
69+
}
70+
71+
Node*NextNode(const std::string& path,unsignedint idx) {
72+
if (idx >= path.length()) {
73+
returnnullptr;
74+
}
75+
76+
auto it = children.find(path[idx]);
77+
if (it == children.end()) {
78+
returnnullptr;
79+
}
80+
auto child = it->second;
81+
// match prefix
82+
unsignedint prefix_len = child->prefix.length();
83+
for (unsignedint i =0; i < path.length(); ++i) {
84+
if (i >= prefix_len || child->prefix[i] =='*') {
85+
return child;
86+
}
87+
88+
// Handle optional trailing
89+
// path = /home/subdirectory
90+
// child = subdirectory/*
91+
if (idx >= path.length() &&
92+
child->prefix[i] == node::kPathSeparator) {
93+
continue;
94+
}
95+
96+
if (path[idx++] != child->prefix[i]) {
97+
returnnullptr;
98+
}
99+
}
100+
return child;
101+
}
102+
103+
// A node can be a *end* node and have children
104+
// E.g: */slower*, */slown* are inserted:
105+
// /slow
106+
// ---> er
107+
// ---> n
108+
// If */slow* is inserted right after, it will create an
109+
// empty node
110+
// /slow
111+
// ---> '\000' ASCII (0) || \0
112+
// ---> er
113+
// ---> n
114+
boolIsEndNode() {
115+
if (children.size() ==0) {
116+
returntrue;
117+
}
118+
return children['\0'] !=nullptr;
119+
}
120+
};
121+
122+
RadixTree();
123+
~RadixTree();
124+
voidInsert(const std::string& s);
125+
boolLookup(const std::string_view& s) {returnLookup(s,false); }
126+
boolLookup(const std::string_view& s,bool when_empty_return);
127+
128+
private:
129+
Node* root_node_;
130+
};
131+
132+
private:
133+
voidGrantAccess(PermissionScope scope,const std::string& param);
134+
voidRestrictAccess(PermissionScope scope,
135+
const std::vector<std::string>& params);
136+
// fs granted on startup
137+
RadixTree granted_in_fs_;
138+
RadixTree granted_out_fs_;
139+
140+
bool deny_all_in_ =true;
141+
bool deny_all_out_ =true;
142+
143+
bool allow_all_in_ =false;
144+
bool allow_all_out_ =false;
145+
};
146+
147+
}// namespace permission
148+
149+
}// namespace node
150+
151+
#endif// defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
152+
#endif// SRC_PERMISSION_FS_PERMISSION_H_

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp