diff options
| -rw-r--r-- | fs/move.ts | 14 | ||||
| -rw-r--r-- | fs/utils.ts | 23 | ||||
| -rw-r--r-- | fs/utils_test.ts | 31 | ||||
| -rwxr-xr-x | test.ts | 1 |
4 files changed, 58 insertions, 11 deletions
diff --git a/fs/move.ts b/fs/move.ts index eb6352bd5..007e4520b 100644 --- a/fs/move.ts +++ b/fs/move.ts @@ -1,20 +1,12 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import * as path from "./path/mod.ts"; import { exists, existsSync } from "./exists.ts"; +import { isSubdir } from "./utils.ts"; interface MoveOptions { overwrite?: boolean; } -function isSrcSubdir(src: string, dest: string): boolean { - const srcArray = src.split(path.sep); - const destArray = dest.split(path.sep); - - return srcArray.reduce((acc, current, i) => { - return acc && destArray[i] === current; - }, true); -} - /** Moves a file or directory */ export async function move( src: string, @@ -26,7 +18,7 @@ export async function move( const srcStat = await Deno.stat(src); - if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + if (srcStat.isDirectory() && isSubdir(src, dest)) { throw new Error( `Cannot move '${src}' to a subdirectory of itself, '${dest}'.` ); @@ -56,7 +48,7 @@ export function moveSync( const srcStat = Deno.statSync(src); - if (srcStat.isDirectory() && isSrcSubdir(src, dest)) { + if (srcStat.isDirectory() && isSubdir(src, dest)) { throw new Error( `Cannot move '${src}' to a subdirectory of itself, '${dest}'.` ); diff --git a/fs/utils.ts b/fs/utils.ts new file mode 100644 index 000000000..dd7ee5fa4 --- /dev/null +++ b/fs/utils.ts @@ -0,0 +1,23 @@ +import * as path from "./path/mod.ts"; + +/** + * Test whether or not `dest` is a sub-directory of `src` + * @param src src file path + * @param dest dest file path + * @param sep path separator + */ +export function isSubdir( + src: string, + dest: string, + sep: string = path.sep +): boolean { + if (src === dest) { + return false; + } + const srcArray = src.split(sep); + const destArray = dest.split(sep); + + return srcArray.reduce((acc, current, i) => { + return acc && destArray[i] === current; + }, true); +} diff --git a/fs/utils_test.ts b/fs/utils_test.ts new file mode 100644 index 000000000..9d6959de5 --- /dev/null +++ b/fs/utils_test.ts @@ -0,0 +1,31 @@ +// Copyright the Browserify authors. MIT License. + +import { test } from "../testing/mod.ts"; +import { assertEquals } from "../testing/asserts.ts"; +import { isSubdir } from "./utils.ts"; +import * as path from "./path/mod.ts"; + +test(function _isSubdir() { + const pairs = [ + ["", "", false, path.posix.sep], + ["/first/second", "/first", false, path.posix.sep], + ["/first", "/first", false, path.posix.sep], + ["/first", "/first/second", true, path.posix.sep], + ["first", "first/second", true, path.posix.sep], + ["../first", "../first/second", true, path.posix.sep], + ["c:\\first", "c:\\first", false, path.win32.sep], + ["c:\\first", "c:\\first\\second", true, path.win32.sep] + ]; + + pairs.forEach(function(p) { + const src = p[0] as string; + const dest = p[1] as string; + const expected = p[2] as boolean; + const sep = p[3] as string; + assertEquals( + isSubdir(src, dest, sep), + expected, + `'${src}' should ${expected ? "" : "not"} be parent dir of '${dest}'` + ); + }); +}); @@ -20,6 +20,7 @@ import "./fs/ensure_file_test.ts"; import "./fs/move_test.ts"; import "./fs/read_json_test.ts"; import "./fs/write_json_test.ts"; +import "./fs/utils_test.ts"; import "./io/test.ts"; import "./http/server_test.ts"; import "./http/file_server_test.ts"; |
