| Server IP : 74.208.250.37 / Your IP : 216.73.216.114 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ubuntu 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64 User : miferval ( 1000) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /usr/include/nodejs/src/permission/ |
Upload File : |
#ifndef SRC_PERMISSION_FS_PERMISSION_H_
#define SRC_PERMISSION_FS_PERMISSION_H_
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "v8.h"
#include <unordered_map>
#include "permission/permission_base.h"
#include "util.h"
namespace node {
namespace permission {
class FSPermission final : public PermissionBase {
public:
void Apply(const std::string& allow, PermissionScope scope) override;
bool is_granted(PermissionScope perm, const std::string_view& param) override;
struct RadixTree {
struct Node {
std::string prefix;
std::unordered_map<char, Node*> children;
Node* wildcard_child;
explicit Node(const std::string& pre)
: prefix(pre), wildcard_child(nullptr) {}
Node() : wildcard_child(nullptr) {}
Node* CreateChild(std::string prefix) {
char label = prefix[0];
Node* child = children[label];
if (child == nullptr) {
children[label] = new Node(prefix);
return children[label];
}
// swap prefix
unsigned int i = 0;
unsigned int prefix_len = prefix.length();
for (; i < child->prefix.length(); ++i) {
if (i > prefix_len || prefix[i] != child->prefix[i]) {
std::string parent_prefix = child->prefix.substr(0, i);
std::string child_prefix = child->prefix.substr(i);
child->prefix = child_prefix;
Node* split_child = new Node(parent_prefix);
split_child->children[child_prefix[0]] = child;
children[parent_prefix[0]] = split_child;
return split_child->CreateChild(prefix.substr(i));
}
}
return child->CreateChild(prefix.substr(i));
}
Node* CreateWildcardChild() {
if (wildcard_child != nullptr) {
return wildcard_child;
}
wildcard_child = new Node();
return wildcard_child;
}
Node* NextNode(const std::string& path, unsigned int idx) {
if (idx >= path.length()) {
return nullptr;
}
auto it = children.find(path[idx]);
if (it == children.end()) {
return nullptr;
}
auto child = it->second;
// match prefix
unsigned int prefix_len = child->prefix.length();
for (unsigned int i = 0; i < path.length(); ++i) {
if (i >= prefix_len || child->prefix[i] == '*') {
return child;
}
// Handle optional trailing
// path = /home/subdirectory
// child = subdirectory/*
if (idx >= path.length() &&
child->prefix[i] == node::kPathSeparator) {
continue;
}
if (path[idx++] != child->prefix[i]) {
return nullptr;
}
}
return child;
}
// A node can be a *end* node and have children
// E.g: */slower*, */slown* are inserted:
// /slow
// ---> er
// ---> n
// If */slow* is inserted right after, it will create an
// empty node
// /slow
// ---> '\000' ASCII (0) || \0
// ---> er
// ---> n
bool IsEndNode() {
if (children.size() == 0) {
return true;
}
return children['\0'] != nullptr;
}
};
RadixTree();
~RadixTree();
void Insert(const std::string& s);
bool Lookup(const std::string_view& s) { return Lookup(s, false); }
bool Lookup(const std::string_view& s, bool when_empty_return);
private:
Node* root_node_;
};
private:
void GrantAccess(PermissionScope scope, const std::string& param);
// fs granted on startup
RadixTree granted_in_fs_;
RadixTree granted_out_fs_;
bool deny_all_in_ = true;
bool deny_all_out_ = true;
bool allow_all_in_ = false;
bool allow_all_out_ = false;
};
} // namespace permission
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_PERMISSION_FS_PERMISSION_H_