`[ "$1" -eq "$1" ]` accepts more than a natural number: a leading `+`, and leading or trailing whitespace, and in ksh it evaluates its operands as arithmetic expressions, so words like `install` and expressions like `1+1` or `V=1` pass too. Values with any non-digit character are now rejected before that test. The sunos and aix branches of `nvm_get_make_jobs` count cores with `wc -l`, which on those platforms pads the count with whitespace, so that count is now stripped of whitespace before it is checked Discovered by Anthropic's OSS Scanner, as bug ANT-2026-SYLQD6PZ; the scanner correctly classified it as not a vulnerability.
160 lines
3.9 KiB
Bash
Executable File
160 lines
3.9 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# `nvm_get_make_jobs` sets the global `NVM_MAKE_JOBS` instead of echoing it, so
|
|
# every case runs it in this shell, with its output captured to files.
|
|
|
|
ORIG_PATH="${PATH}"
|
|
TMP_DIR="$(mktemp -d)"
|
|
|
|
# the probe shims live under `mktemp -d` rather than `.`, because this directory
|
|
# is shared with every other unit test and a leaked `getconf` would poison them
|
|
SHIMS="${TMP_DIR}/bin"
|
|
OUT="${TMP_DIR}/out"
|
|
ERR="${TMP_DIR}/err"
|
|
|
|
cleanup () {
|
|
export PATH="${ORIG_PATH}"
|
|
rm -rf "${TMP_DIR}"
|
|
}
|
|
|
|
die () { cleanup; echo "$@" ; exit 1; }
|
|
|
|
: nvm.sh
|
|
\. ../../../nvm.sh
|
|
|
|
mkdir -p "${SHIMS}"
|
|
|
|
shim () {
|
|
{
|
|
echo '#!/bin/sh'
|
|
echo "$2"
|
|
} > "${SHIMS}/$1"
|
|
chmod +x "${SHIMS}/$1"
|
|
}
|
|
|
|
# a probe that behaves as if it were not installed, and whose complaint must
|
|
# never reach the user
|
|
shim_absent () {
|
|
shim "$1" "echo 'PROBE_NOISE: $1' >&2; exit 127"
|
|
}
|
|
|
|
REAL_OS="$(nvm_get_os)"
|
|
|
|
FAKE_OS=''
|
|
nvm_get_os () {
|
|
nvm_echo "${FAKE_OS}"
|
|
}
|
|
|
|
run () {
|
|
FAKE_OS="$1"
|
|
shift
|
|
NVM_MAKE_JOBS=''
|
|
nvm_get_make_jobs "$@" >"${OUT}" 2>"${ERR}"
|
|
}
|
|
|
|
assert_jobs () {
|
|
[ "_${NVM_MAKE_JOBS}" = "_$1" ] \
|
|
|| die "${2}: expected NVM_MAKE_JOBS ${1}, got '${NVM_MAKE_JOBS}'"
|
|
}
|
|
|
|
assert_stdout () {
|
|
ACTUAL="$(cat "${OUT}")"
|
|
[ "_${ACTUAL}" = "_$1" ] \
|
|
|| die "${2}: expected stdout '${1}', got '${ACTUAL}'"
|
|
}
|
|
|
|
# deliberately narrower than "stderr is empty": ksh93 has no `local`, so every
|
|
# nvm.sh function already sprays `local: not found` here (see #574)
|
|
assert_no_probe_noise () {
|
|
! nvm_grep -q 'PROBE_NOISE' "${ERR}" \
|
|
|| die "${1}: a failed probe leaked to stderr: '$(cat "${ERR}")'"
|
|
}
|
|
|
|
assert_not_nagged () {
|
|
! nvm_grep -q 'Please report an issue on GitHub' "${ERR}" \
|
|
|| die "${1}: unexpected report-an-issue message"
|
|
}
|
|
|
|
assert_nagged () {
|
|
nvm_grep -q 'Please report an issue on GitHub' "${ERR}" \
|
|
|| die "${1}: expected the report-an-issue message, got '$(cat "${ERR}")'"
|
|
}
|
|
|
|
export PATH="${SHIMS}:${ORIG_PATH}"
|
|
|
|
# an OS the `case` does not name still gets a real core count
|
|
shim getconf 'echo 4'
|
|
shim_absent nproc
|
|
|
|
run win
|
|
assert_jobs 3 'win'
|
|
assert_stdout 'Detected that you have 4 CPU core(s)
|
|
Running with 3 threads to speed up the build' 'win'
|
|
assert_not_nagged 'win'
|
|
assert_no_probe_noise 'win'
|
|
|
|
run ''
|
|
assert_jobs 3 'unknown OS'
|
|
assert_not_nagged 'unknown OS'
|
|
|
|
# Solaris and NetBSD spell the `getconf` variable without the leading underscore
|
|
shim getconf 'case "$1" in NPROCESSORS_ONLN) echo 4 ;; *) exit 1 ;; esac'
|
|
run win
|
|
assert_jobs 3 'unprefixed getconf name'
|
|
assert_not_nagged 'unprefixed getconf name'
|
|
|
|
# with no `getconf`, `nproc` answers
|
|
shim_absent getconf
|
|
shim nproc 'echo 4'
|
|
run win
|
|
assert_jobs 3 'nproc'
|
|
assert_not_nagged 'nproc'
|
|
assert_no_probe_noise 'nproc'
|
|
|
|
# Cygwin/MSYS/MinGW inherit `NUMBER_OF_PROCESSORS` from Windows
|
|
shim_absent nproc
|
|
NUMBER_OF_PROCESSORS=4
|
|
run win
|
|
assert_jobs 3 'NUMBER_OF_PROCESSORS'
|
|
assert_not_nagged 'NUMBER_OF_PROCESSORS'
|
|
assert_no_probe_noise 'NUMBER_OF_PROCESSORS'
|
|
|
|
# with nothing to probe, nvm still says so instead of guessing
|
|
unset NUMBER_OF_PROCESSORS
|
|
run win
|
|
assert_jobs 1 'no probes'
|
|
assert_nagged 'no probes'
|
|
|
|
# the named arms keep priority: darwin asks `sysctl`, not `getconf`
|
|
shim getconf 'echo 99'
|
|
shim sysctl 'echo 4'
|
|
run darwin
|
|
assert_jobs 3 'darwin uses sysctl'
|
|
assert_not_nagged 'darwin uses sysctl'
|
|
|
|
# BSD-derived `wc`s right-align the count
|
|
shim wc "echo ' 4'"
|
|
shim psrinfo 'echo 0; echo 1; echo 2; echo 3'
|
|
run sunos
|
|
assert_jobs 3 'sunos with a padded wc'
|
|
assert_not_nagged 'sunos with a padded wc'
|
|
|
|
shim pmcycles 'echo 0; echo 1; echo 2; echo 3'
|
|
run aix
|
|
assert_jobs 3 'aix with a padded wc'
|
|
assert_not_nagged 'aix with a padded wc'
|
|
|
|
export PATH="${ORIG_PATH}"
|
|
|
|
# an explicit count short-circuits detection entirely
|
|
run '' 7
|
|
assert_jobs 7 'explicit jobs'
|
|
assert_stdout 'number of `make` jobs: 7' 'explicit jobs'
|
|
|
|
# on the real host, detected or not, the result is always usable
|
|
run "${REAL_OS}"
|
|
nvm_is_natural_num "${NVM_MAKE_JOBS}" \
|
|
|| die "real host: expected a natural number, got '${NVM_MAKE_JOBS}'"
|
|
|
|
cleanup
|