aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library_fs.js5
-rw-r--r--tests/filesystem/bad_lookup.cpp101
-rw-r--r--tests/test_other.py4
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'))
+