Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gawk fragment: url decode and '\' escape filter

56 views
Skip to first unread message

Grant

unread,
Dec 29, 2009, 3:58:49 PM12/29/09
to
Hi there,

Seeing the rot13 thread reminded of the url filter I'm using for
a web .cgi script. Comments, Improvements welcome :) Golf?

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# urldecode module
# Copyright (C) 2008 Grant Coady <gr...@bugs.id.au> GPLv2
#
BEGIN {
for (i = 0; i < 16; i++) {
hexc[sprintf("%c", i + (i > 9 ? 55 : 48))] = i
}
for (i = 32; i < 127; i++) {
++charset[sprintf("%c", i)]
}
}
function urldecode(s, a, b, c, d, i)
{
d = ""
for (i = 1; i <= length(s); i++) {
c = substr(s, i, 1)
if (c == "%") {
a = toupper(substr(s, ++i, 1))
b = toupper(substr(s, ++i, 1))
c = sprintf("%c", hexc[a] * 16 + hexc[b])
}
else {
sub(/+/, " ", c)
}
d = d (c in charset ? c : " ")
}
return d
}
# read and decode url query string to global url_query_parm[]
function url_decode_query( a, i) # trashes $0 record buffer
{
$0 = ENVIRON["QUERY_STRING"]
gsub(/&/, " ") # get key=value pair fields
for (i = 1; i <= NF; i++) {
split($i, a, "=") # separate key, value, then decode
url_query_parm[a[1]] = urldecode(a[2])
}
}
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# filter most or all \ escapes
function escfilter(s, a, c, d, i, v)
{
d = ""
for (i = 1; i <= length(s); i++) {
c = substr(s, i, 1)
if (c == "\\") {
v = substr(s, i + 1, 1)
if (a || !(v == "\\" || v == "n" || v == "t")) {
c = "" # eat unwanted escapes
++i
}
}
sub(/"/, "\\\"", c) # escape '"'
d = d c
}
return d
}
# convenience wrappers for \ escape filter
function escfilter_most(s)
{
# allow \\, \t, \n
return escfilter(s, 0)
}
function escfilter_all(s)
{
# remove all escapes
return escfilter(s, 1)
}
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The above is part of the CGI handler for: http://bugs.id.au/cc2ip/

The url_decode_query function above is an (untested) example of usage,
simplified from actual full script usage shown here:

# get ISO8601 datestamp, user's query info
cmd = "date -u +%FT%TZ"; cmd | getline ds; close(cmd)
qs = ENVIRON["QUERY_STRING"]
addr = ENVIRON["REMOTE_ADDR"]
ua = ENVIRON["HTTP_USER_AGENT"]
...
# interpret the query
$0 = qs; gsub(/&/, " ")
for (i = 1; i <= NF; i++) {
split($i, a, "="); s = urldecode(a[2])
if (a[1] == "cc") {
cc = (cc ? cc "," s : s)
} else {
list[a[1]] = s
}
}

The escfilter function is used to make any user entered text fields safe:

comment = escfilter_all(list["comment"])
prefix = escfilter_all(list["prefix"])
postfix = escfilter_all(list["postfix"])

And I also detect urls in text entry fields with:

# no play with funny buggers wot put url in comment field
if (comment ~ /(f|ht)tp:\/\// || \
prefix ~ /(f|ht)tp:\/\// || \
postfix ~ /(f|ht)tp:\/\//) { query_error += 1 }

Grant.
--
http://bugs.id.au

0 new messages