Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find out whether a file is within a directory with Node.js?

Given two absolute or relative paths, A and B, I want to find out whether B is "inside of" the directory A—not just in the directory itself, but potentially in a subdirectory. I'd like to do this without a potentially huge number of fs.readdir calls.

For instance, if A is / and B is /foo/bar/baz, it should be pretty obvious that B is within A; the recursive readdir approach would be extremely inefficient.

One obvious idea is to convert both paths to absolute form, then check if the string form of B's absolute path starts with the string form of A's. However, there are two problems:

  1. How do you convert the relative paths to absolute paths?
  2. What about symbolic links and such?

I'll accept answers that make calls to Linux utilities (other than rm -rf... which technically could be used to solve the problem) or third-party Node libraries.

like image 374
Trevor Burnham Avatar asked May 04 '11 18:05

Trevor Burnham


People also ask

How do you check if a file is a directory or a file in node JS?

The existsSync method of the fs module is used to check if a file or directory exists in the file system.

How do you check if a file is in a directory in JS?

isDirectory() method returns true if file path is Directory, otherwise returns false.


2 Answers

var fs = require('fs');

var a = fs.realpathSync('/home/mak/www'); // /var/www
var b = fs.realpathSync('/var/www/test/index.html');

var b_in_a = b.indexOf(a) == 0;

var a_is_dir = fs.statSync(a).isDirectory();

fs.*Sync also have asynchronous versions, see fs module.

fs.realpathSync and fs.statSyncwill throw if the path does not exist.

like image 158
mak Avatar answered Nov 07 '22 11:11

mak


I suggest this:

const path = require('path')

function isWithin(outer, inner) {
    const rel = path.relative(outer, inner);
    return !rel.startsWith('../') && rel !== '..';
}

It uses path.relative to compute the path of inner relative to outer. If it's not contained, the first component of the resulting path will be .., so that's what we check for.

like image 23
DS. Avatar answered Nov 07 '22 09:11

DS.