Handling arbitrary strings in URLs: Escape, InternetCanonicalizeUrl, WinHttpCrackUrl and URI.EscapeUriString
Sometimes a web application might want to put arbitrary strings into a URL, and make it a valid URL. The VBScript and JScript escape and unescape functions do just that.
This sample shows how to use VBScript to escape and unescape a string. The escaped string looks like:
http%3A//a.com/default.htm%3Fthis%20is%20a%20test%20%21@%23%24%25%5E%26*%28%29
CLEAR ALL
CLEAR
SET SAFETY OFF
cScriptFile="t.vbs"
TEXT TO myvar TEXTMERGE
cURL = "https://a.com/default.htm?this is a test !@#$%^&*()"
cEscaped=escape(cURL)
msgbox cEscaped,0,"Escaped"
cUnescaped = Unescape(cEscaped)
msgbox cUnescaped,0,"UnEscaped"
ENDTEXT
STRTOFILE(myvar,cScriptFile)
PUBLIC x as wscript.shell
x=CREATEOBJECT("wscript.shell") && WSH
x.Exec("wscript "+cScriptFile)
The sample below shows two ways to decode encoded strings using InternetCanonicalizeUrl and WinHttpCrackUrl. Note that they both require complete URLs, and the second one can break down the URL into its constituent parts. Encoding is left as an exercise for the reader
Doing this with .Net is much simpler: just use the URI.EscapeUriString method
See also: Generating VBScript to read a blog
CLEAR
#define ICU_DECODE 0x10000000 &&// Convert %XX escape sequences to characters
#define ICU_ESCAPE 0x80000000
cString="Calvin%20Hsia%27s%20WebLog%20%3A%20How%20do%20I%20turn%20off%20the%20User%20Interface%20in%20an%20unattended%20application%3F"
cUrl="https://anything.com/anything.htm?"+cString
?Unescape(cUrl)
?Unescapex(cUrl)
PROCEDURE Unescape(cEncoded as String) as String
DECLARE InternetCanonicalizeUrl IN wininet string cUrl, string @ cResult, integer @ nBufSize, integer dwFlags
cBuf=SPACE(1000)
nBufsize=LEN(cBuf)
IF InternetCanonicalizeUrl(cEncoded, @cbuf,@nBufsize,ICU_DECODE)
cBuf=LEFT(cBuf,nBufsize)
ELSE
cBuf=""
ENDIF
RETURN cBuf
PROCEDURE Unescapex(cEncoded as String) as String
LOCAL cUrl, cStr
DECLARE integer GetLastError IN WIN32API
DECLARE integer GetProcessHeap IN win32api
DECLARE integer HeapAlloc IN WIN32API integer hHeap, integer dwFlags, integer dwBytes
DECLARE integer HeapFree IN WIN32API integer hHeap, integer dwFlags, integer lpMem
DECLARE integer WinHttpCrackUrl IN winhttp string wUrl, integer UrlLen,;
integer nFlags, string @ urlComps
#define NSIZE 1000
cStrAddr=HeapAlloc(GetProcessHeap(),8,NSIZE) && 8 = HEAP_ZERO_MEMORY
*Create the struct: 15 DWORDs. 1st member is sizeof struct. Last 2 are pointer to extra info and sized of extra info
cUComp=BINTOC(15*4,"4rs")+REPLICATE(CHR(0),12 * 4) + BINTOC(cStrAddr,"4rs")+BINTOC(NSIZE,"4rs")
* cUrl="https://anything.com/anything.htm?"+cEncoded && make it into a valid URL
cUrl=cEncoded
IF WinHttpCrackUrl(STRCONV(cUrl+CHR(0),5),0, ICU_DECODE, @ cUComp)=1
nLen=CTOBIN(SUBSTR(cUComp,14*4+1,4),"4rs")
cstr=SUBSTR(STRCONV(SYS(2600,cStrAddr,nLen*2),6),2) && skip over initial "?"
ELSE
?"crack failed",GetLastError()
cStr=""
ENDIF
HeapFree(GetProcessHeap(),0,cStrAddr)
RETURN cStr