[REBOL] Re: decode-cgi bug (?)
From: tomc:darkwing:uoregon at: 9-Feb-2004 15:02
howdy,
I was fiddling with this recently hoping to get an improved version into
view 1.3. there are different thoughts on 'decode-cgi should be a
higher/lower level function my belief is it should be pretty dumb and
just break strings up on a structural basis. but that leads to newby
biting which is not good. so here are two functions:
the first 'vet-word attempts to return as much of an input string! that
can be formed into a valid rebol word! making char replacements as needed.
the second is dumb but a robust decode-cgi that should handle all sorts
of malformed query strings, which by default calls vet-word to filter
out funny stuff but can be called with a /raw refinement to skip it
if you feel you do not need the extra checks.
mind the wrap
vet-word: func[{return as much of a string is suitable to form a word
assumes no chars below 31 20x}
str[string!]
/local valid invalid result token
][
invalid: make bitset! [#"@" #"#" #"$" #"%" #"^^" #"," #"[" #"]" #"("
#")" #"{" #"}" #"^"" #":" #";" #"/" #" " #"^/"]
valid: complement invalid
result: make string! length? str
number: [copy token [opt["+" | "-"][integer! opt ["." integer!]]|["."
integer!]]
(insert tail result join "number_" token)
]
parse/all str[
opt number
any[ opt [[some invalid] (insert tail result "!")]
copy token [some valid] (insert tail result token)
]
]
if empty? result[result: "!"] ; if the string had no valid chars return
surprise
if not equal? str result[print["IN-PUT " str newline "OUTPUT " result]];
debugging
result
]
;;;----------------------------------------------------------------------------------------
decode-cgi: func [args [any-string!] /raw
/local cgi-block name value mark here
][
all[empty? args return ""]
structural: make bitset! "+&=%"
non-struct: complement structural
xchar: make bitset! {0123456789ABCDEFabcdef}
safe-xchar: make bitset! {23456789ABCDEFabcdef}
cgi-block: make block! 16
spc: [mark: #"+" (change :mark " ")]
hex: [mark: #"%" 2 xchar (change/part :mark dehex copy/part :mark 3 3)
:mark]
safe-hex: [mark: #"%"
[safe-xchar xchar (change/part :mark dehex copy/part
:mark 3 3) :mark] |
[2 xchar (change :mark "!" )]
]
parse/all args [
opt "&"
any[(name: copy "" value: copy "" here: copy "")
copy name some [non-struct | spc | safe-hex]
(all[not raw name: vet-word trim name]
either none? here: find cgi-block to set-word! name[
insert/only tail cgi-block to set-word! name
insert/only here: tail cgi-block none
][here: next here])
opt[#"="
opt[copy value some [non-struct | spc | hex]
(either none? first here
[change here value]
[either not block? first here
[poke here 1 to block! reduce[first here value]]
[insert/only tail first here value]
]
)
]
]
[ #"&" | end]
]
]
cgi-block
]
On Mon, 9 Feb 2004, Hallvard Ystad wrote: