diff --git a/src/filesystem/implementation.js b/src/filesystem/implementation.js index 2ef72ca..4869e0a 100644 --- a/src/filesystem/implementation.js +++ b/src/filesystem/implementation.js @@ -136,7 +136,6 @@ function make_node(context, path, type, callback) { } else { parentNodeData = result; Node.create({ - path: path, guid: context.guid, type: type }, function(error, result) { @@ -335,8 +334,7 @@ function ensure_root_directory(context, callback) { Node.create({ guid: context.guid, id: superNode.rnode, - type: NODE_TYPE_DIRECTORY, - path: ROOT_DIRECTORY_NAME + type: NODE_TYPE_DIRECTORY }, function(error, result) { if(error) { callback(error); @@ -400,8 +398,7 @@ function make_directory(context, path, callback) { parentDirectoryData = result; Node.create({ guid: context.guid, - type: NODE_TYPE_DIRECTORY, - path: path + type: NODE_TYPE_DIRECTORY }, function(error, result) { if(error) { callback(error); @@ -641,8 +638,7 @@ function open_file(context, path, flags, callback) { function write_file_node() { Node.create({ guid: context.guid, - type: NODE_TYPE_FILE, - path: path + type: NODE_TYPE_FILE }, function(error, result) { if(error) { callback(error); @@ -1135,8 +1131,7 @@ function make_symbolic_link(context, srcpath, dstpath, callback) { function write_file_node() { Node.create({ guid: context.guid, - type: NODE_TYPE_SYMBOLIC_LINK, - path: dstpath + type: NODE_TYPE_SYMBOLIC_LINK }, function(error, result) { if(error) { callback(error); @@ -1144,8 +1139,17 @@ function make_symbolic_link(context, srcpath, dstpath, callback) { } fileNode = result; fileNode.nlinks += 1; + + // If the srcpath isn't absolute, resolve it relative to the dstpath + // but store both versions, since we'll use the relative one in readlink(). + if(!isAbsolutePath(srcpath)) { + fileNode.symlink_relpath = srcpath; + srcpath = Path.resolve(parentPath, srcpath); + } + fileNode.size = srcpath.length; fileNode.data = srcpath; + context.putObject(fileNode.id, fileNode, update_directory_data); }); } @@ -1201,14 +1205,17 @@ function read_link(context, path, callback) { } } - function check_if_symbolic(error, result) { + function check_if_symbolic(error, fileNode) { if(error) { callback(error); } else { - if(result.type != NODE_TYPE_SYMBOLIC_LINK) { + if(fileNode.type != NODE_TYPE_SYMBOLIC_LINK) { callback(new Errors.EINVAL('path not a symbolic link', path)); } else { - callback(null, result.data); + // If we were originally given a relative path, return that now vs. the + // absolute path we've generated and use elsewhere internally. + var target = fileNode.symlink_relpath ? fileNode.symlink_relpath : fileNode.data; + callback(null, target); } } } @@ -1571,14 +1578,19 @@ function validate_file_options(options, enc, fileMode){ return options; } -function pathCheck(path, callback) { +function pathCheck(path, allowRelative, callback) { var err; + if(typeof allowRelative === 'function') { + callback = allowRelative; + allowRelative = false; + } + if(!path) { err = new Errors.EINVAL('Path must be a string', path); } else if(isNullPath(path)) { err = new Errors.EINVAL('Path must be a string without null bytes.', path); - } else if(!isAbsolutePath(path)) { + } else if(!allowRelative && !isAbsolutePath(path)) { err = new Errors.EINVAL('Path must be absolute.', path); } @@ -2303,8 +2315,13 @@ function rename(fs, context, oldpath, newpath, callback) { function symlink(fs, context, srcpath, dstpath, type, callback) { // NOTE: we support passing the `type` arg, but ignore it. callback = arguments[arguments.length - 1]; - if(!pathCheck(srcpath, callback)) return; + + // Special Case: allow srcpath to be relative, which we normally don't permit. + // If the srcpath is relative, we assume it's relative to the dirpath of + // dstpath. + if(!pathCheck(srcpath, true, callback)) return; if(!pathCheck(dstpath, callback)) return; + make_symbolic_link(context, srcpath, dstpath, callback); } diff --git a/src/node.js b/src/node.js index fb80959..a8be4c7 100644 --- a/src/node.js +++ b/src/node.js @@ -1,6 +1,3 @@ -var path = require('./path.js'); -var hash32 = require('./encoding.js').hash32; - var NODE_TYPE_FILE = require('./constants.js').NODE_TYPE_FILE; var NODE_TYPE_DIRECTORY = require('./constants.js').NODE_TYPE_DIRECTORY; var NODE_TYPE_SYMBOLIC_LINK = require('./constants.js').NODE_TYPE_SYMBOLIC_LINK; diff --git a/tests/spec/node-js/simple/test-fs-null-bytes.js b/tests/spec/node-js/simple/test-fs-null-bytes.js index 37c5f7a..19ba73f 100644 --- a/tests/spec/node-js/simple/test-fs-null-bytes.js +++ b/tests/spec/node-js/simple/test-fs-null-bytes.js @@ -26,7 +26,7 @@ describe("node.js tests: https://github.com/joyent/node/blob/master/test/simple/ done(); } }); - + console.log('fn', fn); fn.apply(fs, args); } @@ -49,11 +49,10 @@ describe("node.js tests: https://github.com/joyent/node/blob/master/test/simple/ check(fs.appendFile, '/foo\u0000bar'); check(fs.truncate, '/foo\u0000bar'); check(fs.utimes, '/foo\u0000bar', 0, 0); - // TODO - need to be implemented still... - // check(fs.realpath, '/foo\u0000bar'); - // check(fs.chmod, '/foo\u0000bar', '0644'); - // check(fs.chown, '/foo\u0000bar', 12, 34); - // check(fs.realpath, '/foo\u0000bar'); +// Not implemented +// check(fs.realpath, '/foo\u0000bar'); + check(fs.chmod, '/foo\u0000bar', '0644'); + check(fs.chown, '/foo\u0000bar', 12, 34); checks.forEach(function(fn){ fn();