Don't click here unless you want to be banned.

LSL Wiki : llEscapeURL

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl801.us.archive.org
string llEscapeURL(string url)

Returns the string that is the URL-escaped version of url (replacing spaces with %20, etc).
This function returns the UTF-8 encoded escape codes for selected characters.

Only numbers and ASCII letters are not escaped: [^0-9a-zA-Z]

As of 1.9.0(21) this function only returns a string with 254 characters, this is unacceptable. If all your characters need escaping then this will only allow the user to work with 84 bytes. If those 84 bytes represent 6byte characters (top of the UTF-8 range) then you will only be able to decode 14 characters.- BW
As of 1.18.3(5) the above still applies. - KeikoRau
As of 1.19.1.81992, the function returns more than 254 characters - GwynethLlewelyn

WARNING: This function only encodes to a total length of 254 characters. If you are trying to send more data via an HTTP request, consider putting that data into the body of the HTTP request and using a shorter URL.

See llUnescapeURL.


This article wasn't helpful for you? Maybe the related article at the LSL Portal is able to bring enlightenment.

Functions
Comments [Hide comments/form]
What happenes when this function encounters a unicode character that can't be represented in a byte (%FF)? does it go for %uXXXX or does it split it into two (or more) UTF-8 bytes? (Apologies, can't test this IW at the moment).
-- ChristopherOmega (2006-04-06 19:47:51)
It returns the UTF-8 character representation. So if fed the string "ф" it would return "%D1%84" and if you inturn feed "%D1%84" to llUnescapeURL you get "ф". On the unicode page you will find character encoding functions that build unicode characters with these two functions.
-- BlindWanderer (2006-04-07 23:40:48)
To work around the 254 character limit, break down the URL...

IE:
(LSL)
        string strURL2Use = URL_POLL_DATA;
        strURL2Use += llEscapeURL("?proj=" + strExpenseProjectData);
        strURL2Use += llEscapeURL("?type=" + strExpenseTypeData);
        strURL2Use += llEscapeURL("?amount=" + strExpenseAmount);
        strURL2Use += llEscapeURL("?note=" + strExpenseTypeNote);
-- NewOddity (2006-08-08 20:42:57)
thats like cheating :P
still a good idea.
it doesn't help you if you are parsing really big strings as paramaters.
-- BlindWanderer (2006-08-10 12:03:20)
i was really annoyed with the 254 character limit, which was way too short for what i wanted, so i wrote my own EscapeURL function, which replaces the most common characters:

// klEscapeURL(string src)
// Returns the string src with URL escaping. (Replaces spaces by %20, etc)
string klEscapeURL(string src)
{
    string tmp;
    integer pos;
    // i read somewhere that jumps were more efficient than for loops. Haven't tested it myself, but using them anyway.
    @loop0;
    pos = llSubStringIndex(src, "%");
    if(pos != -1)
    {
        // There's probably a more effecient way to do this, but i wrote this quickly without thinking too much up front.
        // Can't do llSubStringIndex() constantly because it would keep returning the first, replacing it with %25 and then
        // reporting the % in that one, so making an endless loop. So i take the first part of the string out and store it 
        // temporarily, then continue on the remaining part until there's no more %'s in it.
       tmp += llGetSubString(src, 0, --pos) + "%25";
       src = llDeleteSubString(src, 0, ++pos);
       jump loop0;
    }
    src = tmp + src;
    @loop1;
    pos = llSubStringIndex(src, " ");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%20");
        jump loop1;
    }
    @loop2;
    pos = llSubStringIndex(src, "<");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%3C");
        jump loop2;
    }
    @loop3;
    pos = llSubStringIndex(src, ">");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%3E");
        jump loop3;
    }
    @loop4;
    pos = llSubStringIndex(src, "#");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%23");
        jump loop4;
    }
    @loop5;
    pos = llSubStringIndex(src, "{");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%7B");
        jump loop5;
    }
    @loop6;
    pos = llSubStringIndex(src, "}");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%7D");
        jump loop6;
    }
    @loop7;
    pos = llSubStringIndex(src, "|");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%7C");
        jump loop7;
    }
    @loop8;
    pos = llSubStringIndex(src, "\\");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%5C");
        jump loop8;
    }
    @loop9;
    pos = llSubStringIndex(src, "^");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%5E");
        jump loop9;
    }
    @loop10;
    pos = llSubStringIndex(src, "~");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%7E");
        jump loop10;
    }
    @loop11;
    pos = llSubStringIndex(src, "[");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%5B");
        jump loop11;
    }
    @loop12;
    pos = llSubStringIndex(src, "]");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%5D");
        jump loop12;
    }
    @loop13;
    pos = llSubStringIndex(src, "`");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%60");
        jump loop13;
    }
    @loop14;
    pos = llSubStringIndex(src, ";");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%3B");
        jump loop14;
    }
    @loop15;
    pos = llSubStringIndex(src, "/");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%2F");
        jump loop15;
    }
    @loop16;
    pos = llSubStringIndex(src, "?");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%3F");
        jump loop16;
    }
    @loop17;
    pos = llSubStringIndex(src, ":");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%3A");
        jump loop17;
    }
    @loop18;
    pos = llSubStringIndex(src, "@");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%40");
        jump loop18;
    }
    @loop19;
    pos = llSubStringIndex(src, "=");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%3D");
        jump loop19;
    }
    @loop20;
    pos = llSubStringIndex(src, "&");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%26");
        jump loop20;
    }
    @loop21;
    pos = llSubStringIndex(src, "$");
    if(pos != -1)
    {
        src = llDeleteSubString(src, pos, pos);
        src = llInsertString(src, pos, "%24");
        jump loop21;
    }
    return src;
}

It's a lot slower than llEscapeURL, but i still got decent speed results with mine even on big strings.
-- KayleeLykin (2007-05-24 01:36:08)
I just ran into this problem (again) today, and decided to try my hand at solving it. This version should do everything that Kaylee's version does, in a fraction of the time (gah, that sounds so presumptuous, I'm sorry!):
list chars = [
    "%", "%25", // MUST BE FIRST.
    "\n", "%0A",
    " ", "%20",
    "#", "%23",
    "$", "%24",
    "&", "%26",
    "+", "%2B",
    ",", "%2C",
    "/", "%2F",
    ":", "%3A",
    ";", "%3B",
    "<", "%3C",
    "=", "%3D",
    ">", "%3E",
    "?", "%3F",
    "@", "%40",
    "[", "%5B",
    "\\", "%5C",
    "]", "%5D",
    "^", "%5E",
    "`", "%60",
    "{", "%7B",
    "|", "%7C",
    "}", "%7D",
    "~", "%7E"
];
// Replaces all instances of toReplace in str with replaceWith.
string replaceAll(string str, string toReplace, string replaceWith) {
    return llDumpList2String(llParseStringKeepNulls(str, [toReplace], []), replaceWith);
}

string escapeURL(string src) {
    integer i; integer len = llGetListLength(chars);
    for (i = 0; i < len; i += 2) {
        src = replaceAll(src, llList2String(chars, i), llList2String(chars, i+1));
    }
    return src;
}

For something more thorough:
string hexc="0123456789ABCDEF";

string int2hex(integer x) 
{
    integer x0 = x & 0xF;
    string res = llGetSubString(hexc, x0, x0);
    x = (x >> 4) & 0x0FFFFFFF; //otherwise we get infinite loop on negatives.
    while( x != 0 )
    {
        x0 = x & 0xF;
        res = llGetSubString(hexc, x0, x0) + res;
        x = x >> 4;
    } 
    return res;
}

// Replaces all instances of toReplace in str with replaceWith.
string replaceAll(string str, string toReplace, string replaceWith) {
    return llDumpList2String(llParseStringKeepNulls(str, [toReplace], []), replaceWith);
}

string escapeURL(string src) {
    integer i;
    for (i = 0; i < 256; ++i) {
        string escaped = int2hex(i);
        if (llStringLength(escaped) == 1)
            escaped = "0" + escaped;
        escaped = "%" + escaped;
        string char = llUnescapeURL(escaped);
        if (llEscapeURL(char) == escaped) {
            src = replaceAll(src, char, escaped);
        }
    }
    return src;
}

The latter iterates through every character from 0 to 255 and checks if llEncodeURL encodes it, if it does, then it replaces the char in the string. Unfortunately, this function is about tenfold slower then the former. Someone (*cough* BW *cough*) please make a better one :-)
-- ChristopherOmega (2007-07-21 20:00:42)
I just ran into this problem (again) today, and decided to try my hand at solving it. This version should do everything that Kaylee's version does, in a fraction of the time (gah, that sounds so presumptuous, I'm sorry!):

list chars = [
    "%", "%25", // MUST BE FIRST.
    "\n", "%0A",
    " ", "%20",
    "#", "%23",
    "$", "%24",
    "&", "%26",
    "+", "%2B",
    ",", "%2C",
    "/", "%2F",
    ":", "%3A",
    ";", "%3B",
    "<", "%3C",
    "=", "%3D",
    ">", "%3E",
    "?", "%3F",
    "@", "%40",
    "[", "%5B",
    "\\", "%5C",
    "]", "%5D",
    "^", "%5E",
    "`", "%60",
    "{", "%7B",
    "|", "%7C",
    "}", "%7D",
    "~", "%7E"
];
// Replaces all instances of toReplace in str with replaceWith.
string replaceAll(string str, string toReplace, string replaceWith) {
    return llDumpList2String(llParseStringKeepNulls(str, [toReplace], []), replaceWith);
}

string escapeURL(string src) {
    integer i; integer len = llGetListLength(chars);
    for (i = 0; i < len; i += 2) {
        src = replaceAll(src, llList2String(chars, i), llList2String(chars, i+1));
    }
    return src;
}

For something more thorough:
string hexc="0123456789ABCDEF";

string int2hex(integer x) 
{
    integer x0 = x & 0xF;
    string res = llGetSubString(hexc, x0, x0);
    x = (x >> 4) & 0x0FFFFFFF; //otherwise we get infinite loop on negatives.
    while( x != 0 )
    {
        x0 = x & 0xF;
        res = llGetSubString(hexc, x0, x0) + res;
        x = x >> 4;
    } 
    return res;
}

// Replaces all instances of toReplace in str with replaceWith.
string replaceAll(string str, string toReplace, string replaceWith) {
    return llDumpList2String(llParseStringKeepNulls(str, [toReplace], []), replaceWith);
}

string escapeURL(string src) {
    integer i;
    // first handle %
    src = replaceAll(src, "%", "%25");
    // before %
    for (i = 0x0; i < 0x25; ++i) {
        string encoded = int2hex(i);
        if (llStringLength(encoded) == 1)
            encoded = "0" + encoded;
        encoded = "%" + encoded;
        string char = llUnescapeURL(encoded);
        if (llEscapeURL(char) == encoded) {
            src = replaceAll(src, char, encoded);
        }
    }
    // after %
    for (i = 0x26; i < 0xFF; ++i) {
        string encoded = int2hex(i);
        if (llStringLength(encoded) == 1)
            encoded = "0" + encoded;
        encoded = "%" + encoded;
        string char = llUnescapeURL(encoded);
        if (llEscapeURL(char) == encoded) {
            src = replaceAll(src, char, encoded);
        }
    }
    return src;
}
The latter iterates through every character from 0 to 255 and checks if llEscapeURL encodes it, if it does, then it replaces the char in the string. Unfortunately, this function is about tenfold slower then the former. Someone (*cough* BW *cough*) please make a better one :-)
-- ChristopherOmega (2007-07-22 00:18:25)
I thought about using some of these functions in my own script to get around this problem, but they look big and I didnt want to use up any more memory than I had to... What about a different approach? Instead of replicating the broken llEscapeURL, perhaps it would be simpler to write a function that can break a string into chunks small enough for llEscapeURL to handle and then reassemble it at the end.
-- syd-nxg-pr1.tpgi.com.au (2007-10-05 13:29:24)
I thought about using some of these functions in my own script to get around this problem, but they look big and I didnt want to use up any more memory than I had to... What about a different approach? Instead of replicating the broken llEscapeURL, perhaps it would be simpler to write a function that can break a string into chunks small enough for llEscapeURL to handle and then reassemble it at the end.
-- KeikoRau (2007-10-05 13:34:51)
Ok, heres what I came up with. Its not a general solution, its specific to my needs, but perhaps someone else may be inspired.

In my case, I have some long data strings, delimited by "^" and some shorter strings containing commands etc. I need the encoding to be EXACTLY the same as llEscapeURL, so I wasn't sure about recreating the encoding, and concentrated on the string length problem. Because my data strings are delimited, it was fairly easy to break them up for encoding. A more general solution might break a long string into substrings. Once the segments have been encoded, they are reassembled and returned. I use this function wherever I would normally have used llEscapeURL.

string myEscapeURL(string str)
{
    if (llSubStringIndex(str, "^") != -1) {
        list out = [];
        list data = llParseStringKeepNulls(str, ["^"], []);
        integer len = llGetListLength(data);
        integer i;
        for (i = 0; i < len; i++) {
            out += [llEscapeURL(llList2String(data,i))];
        }
        return llDumpList2String(out, llEscapeURL("^"));
    } else {
        return llEscapeURL(str);
    }
}
Hope this helps.
-- KeikoRau (2007-10-07 09:23:28)
Attach a comment to this page: