LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 07-25-2003, 03:36 PM   #1
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,814
Blog Entries: 54

Rep: Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989
Bash, input validation: request for comments


Lo peeps,

I'm trying to find an way to have minimal input string validation in Bash. Declaring static_char_restr should really be done in the shells central profile, I'm not worried about performance right now (though I did set max chars) and input should be fed escaped where necessary wrt "the usual suspects". Be aware I'm also trying to minimize usage of GNU utils, like using "index" instead of grep. As far as I can see the only problem "index" has is wrt parenthesis.

If you see room for improvement, I would be gratefull for your comments*.

[code]
function valStr() {
declare -r static_char_restr="1234567890-_./@#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
declare -r str_len="256"
local str charPos charC; str=( $@ )
if [ -z "${str}" -o "${#str}" -gt "${str_len}" ]; then return 1; fi
let charC=${#str}-1; for charPos in $(seq 0 "$charC"); do
expr index "${str[0]:${charPos}:1}" " ${static_char_restr}" >/dev/null
case "$?" in 0) ;; 1|*) return 1;; esac; done; }
[code]


*To put it bluntly: those with a leetness complex or compulsive urge to post "use language x" oneliners and the like are respectfully requested to move on.
 
Old 07-25-2003, 05:18 PM   #2
TheLinuxDuck
Member
 
Registered: Sep 2002
Location: Tulsa, OK
Distribution: Slack, baby!
Posts: 349

Rep: Reputation: 33
One qool feature of bash is being able to do pattern matching/replacement with regexps. This would allow you to consolidate the restrictionchars, and simply remove anything not allowed, and/or react based on what was removed, or simply because something was removed.

Code:
#!/bin/bash

# define good (allowed) characters
good_chars="a-zA-Z0-9"

# loop through CL stuff
for i in "$@"; do
  echo -n "input: $i: "
  # we basically strip out anything that is not in the good_chars list
  #  the // means to replace and nothing after it but before the
  # } means to replace with nothing.
  newstring=${i/[^$good_chars]//}
  # if any chars were stripped out, they won't match any longer
  if [ "$newstring" == "$i" ]; then
    echo "is good!"
  else
    echo "is bad"
  fi
done
 
Old 07-25-2003, 05:54 PM   #3
TheLinuxDuck
Member
 
Registered: Sep 2002
Location: Tulsa, OK
Distribution: Slack, baby!
Posts: 349

Rep: Reputation: 33
And, which a minor change, you can check for maximum length, as well:

Code:
#!/bin/bash

good_chars="a-zA-Z0-9"
max_length=20

for i in "$@"; do
  echo -n "input: $i: "

  if [ ${#i} -gt $max_length ]; then
    echo "exceeds maximum length"
  else
    newstring=${i/[^$good_chars]//}
    if [ "$newstring" == "$i" ]; then
      echo "is good!"
    else
      echo "is bad"
    fi
  fi
done
Here is some sample usage:
Code:
~/shell/unspawn> ./regexp.sh fgdsag reggr egreg ere 35y 35y
e4t23 "&*$H(H$*H" "(" fdsfsd sfs sfsds fdfsdfdfsfsfsdfs
sdfsdfsdfsdfdsfsdfsdfsdfsdfsffdfsd fsdfsd
fsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsfsdfsdfsfsdf
sdfsdfsdfsdfsdfsdfsdfsdfsdfsdfs
input: fgdsag: is good!
input: reggr: is good!
input: egreg: is good!
input: ere: is good!
input: 35y: is good!
input: 35y: is good!
input: e4t23: is good!
input: &*(HH: is bad
input: (: is bad
input: fdsfsd: is good!
input: sfs: is good!
input: sfsds: is good!
input: fdfsdfdfsfsfsdfs: is good!
input: sdfsdfsdfsdfdsfsdfsdfsdfsdfsffdfsd: exceeds maximum length
input: fsdfsd: is good!
input: fsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsfsdfsdfsfsdf: exceeds maximum length
input: sdfsdfsdfsdfsdfsdfsdfsdfsdfsdfs: exceeds maximum length

---edit---

I just realized that you already have that in your script. Oh, well.. (=

Last edited by TheLinuxDuck; 07-25-2003 at 06:00 PM.
 
Old 07-25-2003, 09:03 PM   #4
unSpawn
Moderator
 
Registered: May 2001
Posts: 27,814
Blog Entries: 54

Original Poster
Rep: Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989Reputation: 2989
Thanks TheLinuxDuck! You showed me an excellent way to work around the index vs parenthesis gizmoidal thingoid.

Code:
-local str charPos charC; str=( $@ )
+local str charPos charC char; str=( $@ )
 if [ -z "${str}" -o "${#str}" -gt "${str_len}" ]; then return 1; fi
 let charC=${#str}-1; for charPos in $(seq 0 "$charC"); do
-expr index "${str[0]:${charPos}:1}" " ${static_char_restr}" >/dev/null
+char="${str[0]:${charPos}:1}"
+expr index "${char/[\(\)]/!}" "${static_char_restr} " >/dev/null
 case "$?" in 0) ;; 1|*) return 1;; esac; done; }
If you leave the "expensive" char by char parsing vs string comparison approach there, there are small but notable differences:
Code:
~/shell/duckie> ./regexp.sh "" ; echo $?
input: : is good!
0
Code:
[unsp tmp]$ . f_valStr
[unsp tmp]$ valStr ""; echo $?
1

Ok, ok, we should prolly note both examples where not optimized against this kind of abuse, and using "openssl rand 100000" instead of perl would be too much fun:
Code:
~/shell/duckie> ./regexp.sh "`perl -e 'print "0" x 100000'`" ; echo $?
0000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000:
(kept goin, CTRL+C after 4m7.550s)
130
Code:
[unsp tmp]$ . f_valStr
[unsp tmp]$ time valStr "`perl -e 'print "0" x 100000'`" ; echo $?
real    0m0.146s
user    0m0.140s
sys     0m0.000s
1

I sincerely hope you don't see this as me slagging off your codes, I just wanted to share that... If you or anyone else got more stuff that might help improve this, BMG!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Handy Runner - Request For Comments pcweirdo Programming 0 04-29-2005 04:36 AM
Comments request for "O'Reilly's Linux iptables Pocket Reference" carboncopy General 3 03-03-2005 10:24 PM
Request For Comments: E-mail security site chort Linux - Security 2 02-28-2004 05:43 PM
my mouse input is takes as keyboard input in BASH e1000 Slackware 5 12-08-2003 04:00 PM
bash-script input aizkorri Programming 7 07-08-2003 07:15 AM


All times are GMT -5. The time now is 10:37 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration