Skip to content

Commit

Permalink
Do not rimraf /, override with preserveRoot:false
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Jan 10, 2023
1 parent 2d03377 commit ad4f2db
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 18 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -23,6 +23,8 @@ Options:
* `tmp`: Temp folder to use to place files and folders for the Windows
implementation. Must be on the same physical device as the path being
deleted. Defaults to `dirname(f)`.
* `preserveRoot`: If set to boolean `false`, then allow the recursive
removal of the root directory. Otherwise, this is not allowed.

Any other options are provided to the native Node.js `fs.rm` implementation
when that is used.
Expand Down
20 changes: 10 additions & 10 deletions lib/index.js
Expand Up @@ -8,14 +8,14 @@ const {rimrafPosix, rimrafPosixSync} = require('./rimraf-posix.js')
const {useNative, useNativeSync} = require('./use-native.js')

const rimraf = (path, opts) => {
path = pathArg(path)
path = pathArg(path, opts)
opts = optsArg(opts)
return useNative(opts) ? rimrafNative(path, opts)
: rimrafManual(path, opts)
}

const rimrafSync = async (path, opts) => {
path = pathArg(path)
path = pathArg(path, opts)
opts = optsArg(opts)
return useNativeSync(opts) ? rimrafNativeSync(path, opts)
: rimrafManualSync(path, opts)
Expand All @@ -25,33 +25,33 @@ rimraf.rimraf = rimraf
rimraf.sync = rimraf.rimrafSync = rimrafSync

const native = async (path, opts) =>
rimrafNative(pathArg(path), optsArg(opts))
rimrafNative(pathArg(path, opts), optsArg(opts))
const nativeSync = (path, opts) =>
rimrafNativeSync(pathArg(path), optsArg(opts))
rimrafNativeSync(pathArg(path, opts), optsArg(opts))
native.sync = nativeSync
rimraf.native = native
rimraf.nativeSync = nativeSync

const manual = async (path, opts) =>
rimrafManual(pathArg(path), optsArg(opts))
rimrafManual(pathArg(path, opts), optsArg(opts))
const manualSync = (path, opts) =>
rimrafManualSync(pathArg(path), optsArg(opts))
rimrafManualSync(pathArg(path, opts), optsArg(opts))
manual.sync = manualSync
rimraf.manual = manual
rimraf.manualSync = manualSync

const windows = async (path, opts) =>
rimrafWindows(pathArg(path), optsArg(opts))
rimrafWindows(pathArg(path, opts), optsArg(opts))
const windowsSync = (path, opts) =>
rimrafWindowsSync(pathArg(path), optsArg(opts))
rimrafWindowsSync(pathArg(path, opts), optsArg(opts))
windows.sync = windowsSync
rimraf.windows = windows
rimraf.windowsSync = windowsSync

const posix = async (path, opts) =>
rimrafPosix(pathArg(path), optsArg(opts))
rimrafPosix(pathArg(path, opts), optsArg(opts))
const posixSync = (path, opts) =>
rimrafPosixSync(pathArg(path), optsArg(opts))
rimrafPosixSync(pathArg(path, opts), optsArg(opts))
posix.sync = posixSync
rimraf.posix = posix
rimraf.posixSync = posixSync
Expand Down
24 changes: 16 additions & 8 deletions lib/path-arg.js
@@ -1,18 +1,26 @@
const platform = require('./platform.js')
const { resolve, parse } = require('path')
const pathArg = path => {
const pathArg = (path, opts = {}) => {
if (/\0/.test(path)) {
// simulate same failure that node raises
throw Object.assign(
new TypeError('path must be a string without null bytes'),
{
path,
code: 'ERR_INVALID_ARG_VALUE',
}
)
const msg = 'path must be a string without null bytes'
throw Object.assign(new TypeError(msg), {
path,
code: 'ERR_INVALID_ARG_VALUE',
})
}

path = resolve(path)
const { root } = parse(path)

if (path === root && opts.preserveRoot !== false) {
const msg = 'refusing to remove root directory without preserveRoot:false'
throw Object.assign(new Error(msg), {
path,
code: 'ERR_PRESERVE_ROOT',
})
}

if (platform === 'win32') {
const badWinChars = /[*|"<>?:]/
const {root} = parse(path)
Expand Down
5 changes: 5 additions & 0 deletions test/path-arg.js
Expand Up @@ -37,3 +37,8 @@ if (platform === 'win32') {
t.throws(() => pathArg(path), er)
}
}

t.throws(() => pathArg('/'), { code: 'ERR_PRESERVE_ROOT' })
t.throws(() => pathArg('/', { preserveRoot: null }),
{ code: 'ERR_PRESERVE_ROOT' })
t.equal(pathArg('/', { preserveRoot: false }), resolve('/'))

0 comments on commit ad4f2db

Please sign in to comment.