... | ... |
@@ -25,6 +25,11 @@ |
25 | 25 |
* You should have received a copy of the GNU General Public License |
26 | 26 |
* along with this program; if not, write to the Free Software |
27 | 27 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 |
+ * |
|
29 |
+ * History |
|
30 |
+ * ------ |
|
31 |
+ * 2003-01-18 un_escape function introduced for convenience of code needing |
|
32 |
+ * the complex&slow feature of unescaping |
|
28 | 33 |
*/ |
29 | 34 |
|
30 | 35 |
|
... | ... |
@@ -38,6 +43,7 @@ |
38 | 43 |
|
39 | 44 |
|
40 | 45 |
#include "dprint.h" |
46 |
+#include "str.h" |
|
41 | 47 |
|
42 | 48 |
|
43 | 49 |
struct sip_msg; |
... | ... |
@@ -225,4 +231,81 @@ inline static void sleep_us( unsigned int nusecs ) |
225 | 231 |
select(0, NULL, NULL, NULL, &tval ); |
226 | 232 |
} |
227 | 233 |
|
234 |
+inline static int hex2int(char hex_digit) |
|
235 |
+{ |
|
236 |
+ if (hex_digit>='0' && hex_digit<='9') |
|
237 |
+ return hex_digit-'0'; |
|
238 |
+ if (hex_digit>='a' && hex_digit<='f') |
|
239 |
+ return hex_digit-'a'+10; |
|
240 |
+ if (hex_digit>='A' && hex_digit<='F') |
|
241 |
+ return hex_digit-'A'+10; |
|
242 |
+ /* no valid hex digit ... */ |
|
243 |
+ LOG(L_ERR, "ERROR: hex2int: '%c' is no hex char\n", hex_digit ); |
|
244 |
+ return -1; |
|
245 |
+} |
|
246 |
+ |
|
247 |
+/* Un-escape URI user -- it takes a pointer to original user |
|
248 |
+ str, as well as the new, unescaped one, which MUST have |
|
249 |
+ an allocated buffer linked to the 'str' structure ; |
|
250 |
+ (the buffer can be allocated with the same length as |
|
251 |
+ the original string -- the output string is always |
|
252 |
+ shorter (if escaped characters occur) or same-long |
|
253 |
+ as the original one). |
|
254 |
+ |
|
255 |
+ only printeable characters are permitted |
|
256 |
+ |
|
257 |
+ <0 is returned on an uneascaping error, length of the |
|
258 |
+ unescaped string otherwise |
|
259 |
+*/ |
|
260 |
+inline static int un_escape(str *user, str *new_user ) |
|
261 |
+{ |
|
262 |
+ int i, j, value; |
|
263 |
+ int hi, lo; |
|
264 |
+ |
|
265 |
+ new_user->len = 0; |
|
266 |
+ j = 0; |
|
267 |
+ |
|
268 |
+ for (i = 0; i < user->len; i++) { |
|
269 |
+ if (user->s[i] == '%') { |
|
270 |
+ if (i + 2 >= user->len) { |
|
271 |
+ LOG(L_ERR, "ERROR: un_escape: escape sequence too short in" |
|
272 |
+ " '%.*s' @ %d\n", |
|
273 |
+ user->len, user->s, i ); |
|
274 |
+ goto error; |
|
275 |
+ } |
|
276 |
+ hi=hex2int(user->s[i + 1]); |
|
277 |
+ if (hi<0) { |
|
278 |
+ LOG(L_ERR, "ERROR: un_escape: non-hex high digit in an escape sequence in" |
|
279 |
+ " '%.*s' @ %d\n", |
|
280 |
+ user->len, user->s, i+1 ); |
|
281 |
+ goto error; |
|
282 |
+ } |
|
283 |
+ lo=hex2int(user->s[i + 2]); |
|
284 |
+ if (lo<0) { |
|
285 |
+ LOG(L_ERR, "ERROR: non-hex low digit in an escape sequence in " |
|
286 |
+ "'%.*s' @ %d\n", |
|
287 |
+ user->len, user->s, i+2 ); |
|
288 |
+ goto error; |
|
289 |
+ } |
|
290 |
+ value=(hi<<4)+lo; |
|
291 |
+ if (value < 32 || value > 126) { |
|
292 |
+ LOG(L_ERR, "ERROR: non-ASCII escaped character in '%.*s' @ %d\n", |
|
293 |
+ user->len, user->s, i ); |
|
294 |
+ goto error; |
|
295 |
+ } |
|
296 |
+ new_user->s[j] = value; |
|
297 |
+ i+=2; /* consume the two hex digits, for cycle will move to the next char */ |
|
298 |
+ } else { |
|
299 |
+ new_user->s[j] = user->s[i]; |
|
300 |
+ } |
|
301 |
+ j++; /* good -- we translated another character */ |
|
302 |
+ } |
|
303 |
+ new_user->len = j; |
|
304 |
+ return j; |
|
305 |
+ |
|
306 |
+error: |
|
307 |
+ new_user->len = j; |
|
308 |
+ return -1; |
|
309 |
+} |
|
310 |
+ |
|
228 | 311 |
#endif |