aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/lluri.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/lluri.cpp')
-rw-r--r--linden/indra/llcommon/lluri.cpp87
1 files changed, 67 insertions, 20 deletions
diff --git a/linden/indra/llcommon/lluri.cpp b/linden/indra/llcommon/lluri.cpp
index 536d5b9..7db8f3b 100644
--- a/linden/indra/llcommon/lluri.cpp
+++ b/linden/indra/llcommon/lluri.cpp
@@ -14,12 +14,12 @@
14 * ("GPL"), unless you have obtained a separate licensing agreement 14 * ("GPL"), unless you have obtained a separate licensing agreement
15 * ("Other License"), formally executed by you and Linden Lab. Terms of 15 * ("Other License"), formally executed by you and Linden Lab. Terms of
16 * the GPL can be found in doc/GPL-license.txt in this distribution, or 16 * the GPL can be found in doc/GPL-license.txt in this distribution, or
17 * online at http://secondlife.com/developers/opensource/gplv2 17 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
18 * 18 *
19 * There are special exceptions to the terms and conditions of the GPL as 19 * There are special exceptions to the terms and conditions of the GPL as
20 * it is applied to this Source Code. View the full text of the exception 20 * it is applied to this Source Code. View the full text of the exception
21 * in the file doc/FLOSS-exception.txt in this software distribution, or 21 * in the file doc/FLOSS-exception.txt in this software distribution, or
22 * online at http://secondlife.com/developers/opensource/flossexception 22 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
23 * 23 *
24 * By copying, modifying or distributing this software, you acknowledge 24 * By copying, modifying or distributing this software, you acknowledge
25 * that you have read and understood your obligations described above, 25 * that you have read and understood your obligations described above,
@@ -43,28 +43,68 @@
43// system includes 43// system includes
44#include <boost/tokenizer.hpp> 44#include <boost/tokenizer.hpp>
45 45
46void encode_character(std::ostream& ostr, std::string::value_type val)
47{
48 ostr << "%" << std::uppercase << std::hex << std::setw(2) << std::setfill('0')
49 // VWR-4010 Cannot cast to U32 because sign-extension on
50 // chars > 128 will result in FFFFFFC3 instead of F3.
51 << static_cast<S32>(static_cast<U8>(val));
52}
53
46// static 54// static
47std::string LLURI::escape(const std::string& str, const std::string & allowed) 55std::string LLURI::escape(
56 const std::string& str,
57 const std::string& allowed,
58 bool is_allowed_sorted)
48{ 59{
49 std::ostringstream ostr; 60 // *NOTE: This size determination feels like a good value to
61 // me. If someone wante to come up with a more precise heuristic
62 // with some data to back up the assertion that 'sort is good'
63 // then feel free to change this test a bit.
64 if(!is_allowed_sorted && (str.size() > 2 * allowed.size()))
65 {
66 // if it's already sorted, or if the url is quite long, we
67 // want to optimize this process.
68 std::string sorted_allowed(allowed);
69 std::sort(sorted_allowed.begin(), sorted_allowed.end());
70 return escape(str, sorted_allowed, true);
71 }
50 72
73 std::ostringstream ostr;
51 std::string::const_iterator it = str.begin(); 74 std::string::const_iterator it = str.begin();
52 std::string::const_iterator end = str.end(); 75 std::string::const_iterator end = str.end();
53 for(; it != end; ++it) 76 std::string::value_type c;
77 if(is_allowed_sorted)
54 { 78 {
55 std::string::value_type c = *it; 79 std::string::const_iterator allowed_begin(allowed.begin());
56 if(allowed.find(c) == std::string::npos) 80 std::string::const_iterator allowed_end(allowed.end());
57 { 81 for(; it != end; ++it)
58 ostr << "%" 82 {
59 << std::uppercase << std::hex << std::setw(2) << std::setfill('0') 83 c = *it;
60 // VWR-4010 Cannot cast to U32 because sign-extension on 84 if(std::binary_search(allowed_begin, allowed_end, c))
61 // chars > 128 will result in FFFFFFC3 instead of F3. 85 {
62 << static_cast<S32>(static_cast<U8>(c)); 86 ostr << c;
63 } 87 }
64 else 88 else
65 { 89 {
66 ostr << c; 90 encode_character(ostr, c);
67 } 91 }
92 }
93 }
94 else
95 {
96 for(; it != end; ++it)
97 {
98 c = *it;
99 if(allowed.find(c) == std::string::npos)
100 {
101 encode_character(ostr, c);
102 }
103 else
104 {
105 ostr << c;
106 }
107 }
68 } 108 }
69 return ostr.str(); 109 return ostr.str();
70} 110}
@@ -121,11 +161,18 @@ namespace
121 { return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@" 161 { return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@"
122} 162}
123 163
124// TODO: USE CURL!! After http textures gets merged everywhere. 164// *TODO: Consider using curl. After http textures gets merged everywhere.
125// static 165// static
126std::string LLURI::escape(const std::string& str) 166std::string LLURI::escape(const std::string& str)
127{ 167{
128 return escape(str,unreserved() + ":@!$'()*+,="); 168 static std::string default_allowed(unreserved() + ":@!$'()*+,=/?&#;");
169 static bool initialized = false;
170 if(!initialized)
171 {
172 std::sort(default_allowed.begin(), default_allowed.end());
173 initialized = true;
174 }
175 return escape(str, default_allowed, true);
129} 176}
130 177
131LLURI::LLURI() 178LLURI::LLURI()