From 813b5f6dcc70d286f5cc7a0cc5f5a04712fc955d Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 18 Oct 2026 23:08:21 -0700 Subject: [PATCH] [Fix] `nvm_is_natural_num`: reject anything but digits `[ "$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. --- nvm.sh | 6 ++++-- test/fast/Unit tests/nvm_get_make_jobs | 12 ++++++++++++ test/fast/Unit tests/nvm_is_natural_num | 6 ++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/nvm.sh b/nvm.sh index 5e7211f3..62cecfce 100755 --- a/nvm.sh +++ b/nvm.sh @@ -3247,10 +3247,11 @@ nvm_get_make_jobs() { NVM_CPU_CORES="$(sysctl -n hw.ncpu)" ;; "_sunos") - NVM_CPU_CORES="$(psrinfo | wc -l)" + # some `wc`s pad the count with whitespace + NVM_CPU_CORES="$(psrinfo | wc -l | command tr -d '[:space:]')" ;; "_aix") - NVM_CPU_CORES="$(pmcycles -m | wc -l)" + NVM_CPU_CORES="$(pmcycles -m | wc -l | command tr -d '[:space:]')" ;; *) # `_NPROCESSORS_ONLN` is how glibc, FreeBSD, macOS, and Cygwin spell it; @@ -3690,6 +3691,7 @@ nvm_is_natural_num() { case "$1" in 0) return 1 ;; -*) return 3 ;; # some BSDs return false positives for double-negated args + *[!0-9]*) return 2 ;; # `-eq` also accepts signs and whitespace, and in ksh, any arithmetic expression *) [ "$1" -eq "$1" ] 2>/dev/null # returns 2 if it doesn't match ;; diff --git a/test/fast/Unit tests/nvm_get_make_jobs b/test/fast/Unit tests/nvm_get_make_jobs index 481e1363..4147b0aa 100755 --- a/test/fast/Unit tests/nvm_get_make_jobs +++ b/test/fast/Unit tests/nvm_get_make_jobs @@ -132,6 +132,18 @@ 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 diff --git a/test/fast/Unit tests/nvm_is_natural_num b/test/fast/Unit tests/nvm_is_natural_num index caf56cf9..b50f01b4 100755 --- a/test/fast/Unit tests/nvm_is_natural_num +++ b/test/fast/Unit tests/nvm_is_natural_num @@ -12,6 +12,12 @@ die () { echo "$@" ; exit 1; } ! nvm_is_natural_num --1 || 'double negative number is not false' ! nvm_is_natural_num 1.2 || 'decimal number is not false' ! nvm_is_natural_num 0 || die 'zero is not false' +! nvm_is_natural_num +3 || die 'explicitly positive number is not false' +! nvm_is_natural_num ' 3' || die 'leading whitespace is not false' +! nvm_is_natural_num '3 ' || die 'trailing whitespace is not false' +! nvm_is_natural_num install || die 'a word is not false' +! nvm_is_natural_num V=1 || die 'an assignment is not false' +! nvm_is_natural_num 1+1 || die 'an expression is not false' nvm_is_natural_num 1 || die '1 is not true' nvm_is_natural_num 2 || die '2 is not true'