Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Ceres6 committed Oct 23, 2023
1 parent 72365a4 commit 282946b
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 10 deletions.
2 changes: 0 additions & 2 deletions src/permission/fs_permission.cc
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ void FSPermission::Apply(Environment* env, const std::string& allow, PermissionS
}

void FSPermission::GrantAccess(PermissionScope perm, const std::string& res) {
std::cout << "Result: " << res << std::endl;

const std::string path = WildcardIfDir(res);
if (perm == PermissionScope::kFileSystemRead) {
granted_in_fs_.Insert(path);
Expand Down
165 changes: 158 additions & 7 deletions src/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,19 @@ RAIIIsolate::~RAIIIsolate() {
isolate_->Dispose();
}

#ifdef _WIN32
// windows

bool IsPathSeparator(const char c) {
return c == '\\' || c == '/';
}
#else
// posix

bool IsPathSeparator(const char c) {
return c == '/';
}
#endif

std::string NormalizeString(const std::string path, bool allowAboveRoot, const std::string separator) {
std::string res = "";
Expand All @@ -655,17 +668,17 @@ std::string NormalizeString(const std::string path, bool allowAboveRoot, const s
int dots = 0;
char code;
const auto pathLen = path.length();
for (int i = 0; i <= pathLen; ++i) {
for (uint i = 0; i <= pathLen; ++i) {
if (i < pathLen) {
code = path[i];
} else if (path[i] == node::kPathSeparator) {
} else if (IsPathSeparator(path[i])) {
break;
} else {
code = node::kPathSeparator;
}

if (code == node::kPathSeparator) {
if (lastSlash == (int)(i - 1) || dots == 0) {
if (IsPathSeparator(code)) {
if (lastSlash == (int)(i - 1) || dots == 1) {
// NOOP
} else if (dots == 2) {
int len = res.length();
Expand Down Expand Up @@ -713,15 +726,153 @@ std::string NormalizeString(const std::string path, bool allowAboveRoot, const s
}
}

std::cout << "Res is: " << res << std::endl;
return res;
}

#ifdef _WIN32
// windows

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 resolvedDevice = "";
std::string resolvedTail = "";
bool resolvedAbsolute = false;
const size_t numArgs = paths.size();

for (int i = numArgs - 1; i >= -1 && !resolvedAbsolute; i--) {
std::string path = "";
if (i >= 0) {
path = std::string(paths[i]);

} else if (resolvedDevice.empty()) {
path = env->GetCwd();
} else {
// Windows has the concept of drive-specific current working
// directories. If we've resolved a drive letter but not yet an
// 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?

// 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] == '/')) {
path = resolvedDevice + "\\";
}
}

const size_t len = path.length();
int rootEnd = 0;
std::string device = "";
bool isAbsolute = false;
const char code = path[0];

// Try to match a root
if (len == 1) {
if(IsPathSeparator(code)) {
// `path` contains just a path separator
rootEnd = 1;
isAbsolute = true;
}
} else if (IsPathSeparator(code)) {
// Possible UNC root

// If we started with a separator, we know we at least have an
// absolute path of some kind (UNC or otherwise)
isAbsolute = true;

if (IsPathSeparator(path[1])) {
// Matched double path separator at beginning
size_t j = 2;
size_t last = j;
// Match 1 or more non-path separators
while (j < len && !IsPathSeparator(path[j])) {
j++;
}
if (j < len && j != last) {
const std::string firstPart = path.substr(last, j - last);
// Matched!
last = j;
// Match 1 or more path separators
while (j < len && IsPathSeparator(path[j])) {
j++;
}
if (j < len && j != last) {
// Matched!
last = j;
// Match 1 or more non-path separators
while (j < len && !IsPathSeparator(path[j])) {
j++;
}
if (j == len || j != last) {
// We matched a UNC root
device = "\\\\" + firstPart + "\\" + path.substr(last, j - last);
rootEnd = j;
}
}
}
}
} else if (IsWindowsDeviceRoot(code) && path[1] == ':') {
// Possible device root
device = path.substr(0, 2);
rootEnd = 2;
if (len > 2 && IsPathSeparator(path[2])) {
// Treat separator following drive name as an absolute path
// indicator
isAbsolute = true;
rootEnd = 3;
}
}

if (!device.empty()) {
if (!resolvedDevice.empty()) {
if(ToLower(device) != ToLower(resolvedDevice)) {
// This path points to another device so it is not applicable
continue;
}
} else {
resolvedDevice = device;
}
}

if (resolvedAbsolute) {
if (!resolvedDevice.empty()) {
break;
} else {
resolvedTail = path.substr(rootEnd) + "\\" + resolvedTail;
resolvedAbsolute = isAbsolute;
if (isAbsolute && !resolvedDevice.empty()) {
break;
}
}
}
}

// At this point the path should be resolved to a full absolute path,
// but handle relative paths to be safe (might happen when process.cwd()
// fails)

// Normalize the tail path
resolvedTail = NormalizeString(resolvedTail, !resolvedAbsolute, "\\");

if (resolvedAbsolute) {
return resolvedDevice + "\\" + resolvedTail;
}

if (!resolvedDevice.empty() || !resolvedTail.empty()) {
return resolvedDevice + resolvedTail;
}

return ".";
}
#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--) {
Expand All @@ -742,5 +893,5 @@ std::string PathResolve(Environment* env, const std::vector<std::string_view>& p
}
return (!resolvedPath.empty()) ? resolvedPath : ".";
}

#endif
} // namespace node
2 changes: 1 addition & 1 deletion test/parallel/test-permission-fs-relative-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ const { spawnSync } = require('child_process');
);

const [fsWrite] = stdout.toString().split('\n');
assert.strictEqual(fsWrite, 'false');
assert.strictEqual(fsWrite, 'true');
assert.strictEqual(status, 0);
}

0 comments on commit 282946b

Please sign in to comment.