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 = http://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=http://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=”http://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


 


 

Comments (3)

  1. don dodge says:

    Hi, where did you get the escape() from? is that VFP9? I wrote my own code to take a string and do all this. It took some investigation into what characters had to be escaped and what their escaped looked like.

    Don

  2. Damien Guard says:

    If you want a solution to decode URL’s in .NET take a look at the class I put up on my blog.

    As well as being pure .NET it also breaks the URL up into additional parts such as username, password, query string as a collection and schema.

    http://www.damieng.com/blog/archive/2006/07/07/URL_parsing_and_manipulation_in_.NET.aspx

    [)amien

  3. It takes a lot of work to create the blog posts and code samples that I put in my blog, and I was curious…