diff options
-rw-r--r-- | src/library_fs.js | 5 | ||||
-rw-r--r-- | tests/filesystem/bad_lookup.cpp | 101 | ||||
-rw-r--r-- | tests/test_other.py | 4 |
3 files changed, 109 insertions, 1 deletions
diff --git a/src/library_fs.js b/src/library_fs.js index a392e72e..df89339d 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -311,7 +311,10 @@ mergeInto(LibraryManager.library, { return 0; }, mayLookup: function(dir) { - return FS.nodePermissions(dir, 'x'); + var err = FS.nodePermissions(dir, 'x'); + if (err) return err; + if (!dir.node_ops.lookup) return ERRNO_CODES.EACCES; + return 0; }, mayCreate: function(dir, name) { try { diff --git a/tests/filesystem/bad_lookup.cpp b/tests/filesystem/bad_lookup.cpp new file mode 100644 index 00000000..282e5841 --- /dev/null +++ b/tests/filesystem/bad_lookup.cpp @@ -0,0 +1,101 @@ +#include <cerrno> +#include <cstring> +#include <iostream> +#include <string> +#include <sstream> + +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> + +using std::endl; + +//============================================================================ +// :: Helpers + +namespace +{ + //-------------------------------------------------------------------------- + // Helper to create an empty file with the given path. + void touch(const std::string& path, const mode_t mode) + { + std::cout + << "Touching file: " << path << " with mode=" << std::oct << mode + << std::dec << endl; + + const int fd = ::open(path.c_str(), O_CREAT | O_WRONLY, mode); + if (fd == -1) { + const int error = errno; + std::cout + << "Failed to touch file using open: " << path << "; errno=" << error + << ";" << std::strerror(error) << endl; + } + else { + ::close(fd); + } + } + + //-------------------------------------------------------------------------- + // Stats the given path and prints the mode. Returns true if the path + // exists; false otherwise. + bool exists(const std::string& path) + { + struct ::stat path_stat; + if (::lstat(path.c_str(), &path_stat) != 0) { + const int error = errno; + if (error == ENOENT) { + // Only bother logging if something other than the path not existing + // went wrong. + std::cout + << "Failed to lstat path: " << path << "; errno=" << error << "; " + << std::strerror(error) << endl; + } + return false; + } + + std::cout + << std::oct << "Mode for path=" << path << ": " << path_stat.st_mode + << std::dec << endl; + return true; + } +} + +//============================================================================ +// :: Entry Point + +int main() +{ + touch("file1", 0667); + if (not exists("file1")) { + std::cout << "Failed to create path: file1" << endl; + return 1; + } + if (exists("file1/dir")) { + std::cout << "Path should not exists: file1/dir" << endl; + return 1; + } + + touch("file2", 0676); + if (not exists("file2")) { + std::cout << "Failed to create path: file2" << endl; + return 1; + } + if (exists("file2/dir")) { + std::cout << "Path should not exists: file2/dir" << endl; + return 1; + } + + touch("file3", 0766); + if (not exists("file3")) { + std::cout << "Failed to create path: file3" << endl; + return 1; + } + if (exists("file3/dir")) { + std::cout << "Path should not exists: file3/dir" << endl; + return 1; + } + + std::cout << "ok." << endl; + return 0; +} + diff --git a/tests/test_other.py b/tests/test_other.py index 398975fc..b7a7bd7a 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -3270,3 +3270,7 @@ main() assert os.path.exists('a.out.js') # build should succeed self.assertContained('segmentation fault loading 4 bytes from address 0', run_js('a.out.js', assert_returncode=None, stderr=PIPE)) # program should segfault + def test_bad_lookup(self): + Popen([PYTHON, EMXX, path_from_root('tests', 'filesystem', 'bad_lookup.cpp')]).communicate() + self.assertContained('ok.', run_js('a.out.js')) + |