समस्या उन मामलों में है जहां सामग्री $x
को साफ नहीं किया गया है और इसमें ऐसे डेटा शामिल हैं जो संभावित रूप से ऐसे मामलों में हमलावर के नियंत्रण में हो सकते हैं जो शेल कोड अंत में एक विशेषाधिकार वृद्धि के संदर्भ में इस्तेमाल किया जा सकता है (उदाहरण के लिए एक स्क्रिप्ट द्वारा सेट की गई एक स्क्रिप्ट) अनुप्रयोग, एक सूडो स्क्रिप्ट या ऑफ-द-नेटवर्क डेटा (सीजीआई, डीएचसीपी हुक ...) को प्रत्यक्ष या अप्रत्यक्ष रूप से संसाधित करने के लिए उपयोग किया जाता है।
अगर:
x='(PATH=2)'
फिर:
x=$((1-$x)))
सेटिंग का साइड इफेक्ट PATH
है 2
(एक रिश्तेदार पथ जो हमलावर के नियंत्रण में हो सकता है)। आप के PATH
साथ LD_LIBRARY_PATH
या बदल सकते हैं IFS
... ऐसा ही होता x=$((1-x))
है bash, zsh या ksh में (डैश नहीं है और न ही यश है जो केवल वहाँ चर में संख्यात्मक स्थिरांक को स्वीकार करते हैं)।
ध्यान दें कि:
x=$((1-$x))
$x
कुछ गोले के नकारात्मक मूल्यों के लिए ठीक से काम नहीं करेगा जो कि (POSIX के अनुसार वैकल्पिक) --
(डीक्रिमेंट) ऑपरेटर को लागू करते हैं (जैसा x=-1
कि, इसका मतलब है कि शेल को 1--1
अंकगणितीय अभिव्यक्ति का मूल्यांकन करने के लिए पूछना )। अंकगणित मूल्यांकन के रूप में (पहले से नहीं) के "$((1-x))"
रूप x
में विस्तारित समस्या नहीं है ।
में bash
, zsh
और ksh
(नहीं dash
या yash
), यदि x
है:
x='a[0$(uname>&2)]'
फिर उस कमांड का विस्तार $((1-$x))
या $((1-x))
जिसके कारण uname
निष्पादित किया जाता है (के लिए zsh
, a
एक सरणी चर की आवश्यकता होती है, लेकिन कोई psvar
उस के लिए उदाहरण के लिए उपयोग कर सकता है)।
सारांश में, एक uninitialised नहीं उपयोग किसे करना चाहिए या गोले में गणित भाव में बाह्य डेटा (ध्यान दें कि अंकगणित मूल्यांकन करके किया जा सकता गैर स्वच्छ $((...))
(उर्फ $[...]
में bash
या zsh
), लेकिन यह भी में खोल के आधार पर let
, [
/ test
, declare/typeset/export...
, return
, break
, continue
, exit
, printf
, print
बिलिन, सरणी सूचकांकों, ((..))
और [[...]]
कुछ नाम के लिए निर्माण)।
यह जाँचने के लिए कि एक चर में शाब्दिक दशमलव पूर्णांक संख्या है, आप POSIXly का उपयोग कर सकते हैं:
case $var in
("" | - | *[!0123456789-]* | ?*-*) echo >&2 not a valid number; exit 1;;
esac
सावधान रहें कि [0-9]
कुछ स्थानों में 0123456789 से अधिक मेल खाता [[:digit:]]
है। ठीक होना चाहिए, लेकिन मैं इस पर दांव नहीं लगाऊंगा।
यह भी याद रखें कि अग्रणी शून्य के साथ संख्याओं को कुछ संदर्भों में अष्टक के रूप में माना जाता है ( 010
कभी-कभी 10, कभी-कभी 8) और सावधान रहें कि उपरोक्त जांच उन संख्याओं के माध्यम से जाने देगी जो संभवतः आपके सिस्टम द्वारा समर्थित अधिकतम पूर्णांक (या जो भी आपके द्वारा दिए गए एप्लिकेशन से बड़े हैं) उस पूर्णांक का उपयोग करें, उदाहरण के लिए बैश 18446744073709551616 को 0 के रूप में मानते हैं कि 2 64 है )। तो आप उस मामले के विवरण में अतिरिक्त जांच जोड़ना चाहेंगे:
(0?* | -0?*)
echo >&2 'Only decimal numbers without leading 0 accepted'; exit 1;;
(-??????????* | [!-]?????????*)
echo >&2 'Only numbers from -999999999 to 999999999 supported'; exit 1;;
उदाहरण:
$ export 'x=psvar[0$(uname>&2)]'
$ ksh93 -c 'echo "$((x))"'
Linux
ksh93: psvar: parameter not set
$ ksh93 -c '[ x -lt 2 ]'
Linux
ksh93: [: psvar: parameter not set
$ bash -c 'echo "$((x))"'
Linux
0
$ bash -c '[[ $x -lt 2 ]]'
Linux
$ bash -c 'typeset -i a; export a="$x"'
Linux
$ bash -c 'typeset -a a=([x]=1)'
Linux
$ bash -c '[ -v "$x" ]'
Linux
$ mksh -c '[[ $x -lt 2 ]]'
Linux
$ zsh -c 'echo "$((x))"'
Linux
0
$ zsh -c 'printf %d $x'
Linux
0
$ zsh -c 'integer x'
Linux
$ zsh -c 'exit $x'
Linux
अधिक पढ़ने पर:
x='P=3'; : $(($x + 5))
सेट हो जाएगाP
8 के लिए, लेकिनx='P=3'; : $((x + 5))
सेट हो जाएगाP
करने के लिए3
(मेंzsh
,ksh
याbash
)। "ऐसा ही होता है$((x + 1))
..." अभी सही नहीं है; यह पुराने के रूप में, केPATH
लिए सेट हो जाएगा2
।