diff options
Diffstat (limited to 'linden/indra/llcommon/lluri.cpp')
-rw-r--r-- | linden/indra/llcommon/lluri.cpp | 87 |
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 | ||
46 | void 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 |
47 | std::string LLURI::escape(const std::string& str, const std::string & allowed) | 55 | std::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 |
126 | std::string LLURI::escape(const std::string& str) | 166 | std::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 | ||
131 | LLURI::LLURI() | 178 | LLURI::LLURI() |