Decode-CGI
[1/4] from: al::bri::xtra::co::nz at: 1-Jun-2002 14:03
I've noticed there's a problem with Rebol's standard decode-cgi function.
Here's the source:
>> source decode-cgi
decode-cgi: func [
{Converts CGI argument string to a list of words and value strings.}
args [any-string!] "Starts at first argument word"
/local list equate value name val
][
plus-to-space: func [arg /local seek chr] [
if any [none? arg empty? arg] [return ""]
seek: arg
while [seek: find seek #"+"] [
change seek #" "
seek: next seek
]
head arg
]
list: make block! 8
equate: [copy name to "=" "=" (append list to-set-word name) value]
value: ["&" (append list copy "") | [copy val to "&" "&" | copy val to
end]
(append list either none? val [copy ""] [form dehex plus-to-space
val])]
parse/all args [some equate | none]
list
]
Note that 'plus-to-space is created inside 'decode-cgi each time it's used.
It can also be easily replaced with 'replace/all. Also, CRLF aren't
converted to Rebol's newline. This replacement function should fix these
problems:
Decode-CGI: function [
{Converts CGI argument string to a block of set-words and value
strings.}
Args [any-string!] "Starts at first argument word."
] [
Block Name Value
] [
Block: make block! 10
parse/all Args [
any [
copy Name to #"=" skip (
append Block to-set-word Name
)
[
#"&" (
append Block copy ""
)
| [copy Value to "&" "&" | copy Value to end] (
append Block either none? Value [
copy ""
] [
replace/all dehex replace/all Value #"+" #" " CRLF
newline
]
)
]
]
end
]
Block
]
I've sent it in to feedback.
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[2/4] from: andreas:bolka:gmx at: 1-Jun-2002 14:27
Saturday, June 1, 2002, 4:03:14 AM, Andrew wrote:
> I've noticed there's a problem with Rebol's standard decode-cgi
> function.
[...source...]
> Note that 'plus-to-space is created inside 'decode-cgi each time
> it's used. It can also be easily replaced with 'replace/all.
actually plus-to-space is a scaled down version of replace/all (have a
look at source replace). however, in the sense of reuse, using replace
is ok ;)
> Also, CRLF aren't converted to Rebol's newline.
this is most likely an application level problem - normal CRLFs should
not pass up to decode-cgi, only CRLFs which are hex-encoded. and i
think those should be passed thru to the app.
HOWEVER, there are two more important problems (imho):
1. decode-cgi is not able to properly parse "empty params" like name2
in "name1=val1&name2&name3=val3"
>> decode-cgi "name1=val1&name2&name3=val3"
== [name1: "val1" name2&name3: "val3"]
2. decode-cgi requires post-processing when it parses a string
containing multiple parameters with the same name:
name=val1&name=val2
>> decode-cgi "name=val1&name=val2"
== [name: "val1" name: "val2"]
this list is quite ok, but it does not make sense to 'make object!
this or even 'do it. naturally, multiple parameters with the same name
map to a list, imho:
>> decode-cgi "name=val1&name=val2"
== [name: ["val1" "val2"]]
so here is another patched decode-cgi :) [also submitted to feedback]
; --- snip ---
decode-cgi: func [
{Converts CGI argument string to a list of words and value strings.}
args [any-string!] "Starts at first argument word"
/local list equate value name name-chars val plus-to-space
][
add-nv: func [ list name value /local val-ptr ] [
name: to-set-word name
value: either none? value
[ copy "" ]
[ form dehex (replace/all value "+" " ") ]
either none? val-ptr: find list name [
append list compose [ (name) (value) ]
] [
idx: index? next val-ptr
poke list idx compose [ (pick list idx) (value) ]
]
]
list: make block! 8
name-chars: complement charset "&="
equate: [ copy name some name-chars value]
value: [ "=" value
| "&" (add-nv list name "")
| [ copy val to "&" "&" | copy val to end ]
(add-nv list name val)
]
parse/all args [some equate | none]
list
]
; --- snap ---
--
Best regards,
Andreas mailto:[andreas--bolka--gmx--net]
[3/4] from: warp:reboot:ch at: 3-Jun-2002 19:26
Hello Andreas,
I get this error using your patch:
>> decode-cgi "name=val1&name=val2"
** Script Error: either expected false-block argument of type: block
** Where: add-nv
** Near: either none? val-ptr: find list
Am I doing something wrong?
Thank you and have a nice day
Will Arp
[warp--reboot--ch]
On 1.6.2002 14:27, Andreas Bolka <[andreas--bolka--gmx--net]> wrote:
[4/4] from: andreas:bolka:gmx at: 4-Jun-2002 23:03
Monday, June 3, 2002, 7:26:57 PM, Will wrote:
> I get this error using your patch:
[...]
strange set-word! handling differences betweend 2.5.0 and 2.5.2 -
appended version is working with 2.5.0 and 2.5.2.
--- snip ---
decode-cgi: func [
{Converts CGI argument string to a list of words and value strings.}
args [any-string!] "Starts at first argument word"
/local list equate value name name-chars val plus-to-space
] [
add-nv: func [ list name value /local val-ptr ] [
value: either none? value
[ copy "" ]
[ form dehex (replace/all value "+" " ") ]
either none? val-ptr: find list to-set-word name [
append list compose [ (to-set-word name) (value) ]
] [
idx: index? next val-ptr
poke list idx compose [ (pick list idx) (value) ]
]
]
list: make block! 8
name-chars: complement charset "&="
equate: [ copy name some name-chars value ]
value: [ "=" value
| "&" (add-nv list name "")
| [copy val to "&" "&" | copy val to end]
(add-nv list name val)
]
parse/all args [ some equate | none ]
list
]
--- snap ---
--
Best regards,
Andreas mailto:[andreas--bolka--gmx--net]