pike.git
/
src
/
modules
/
_Roxen
/
roxen.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/modules/_Roxen/roxen.c:372:
pop_n_elems( args ); push_string( end_shared_string( res ) ); } static void f_http_decode_string(INT32 args) /*! @decl string http_decode_string(string encoded) *! *! Decodes an http transport-encoded string. Knows about %XX and *! %uXXXX syntax. Treats %UXXXX as %uXXXX. It will treat '+' as '+'
-
*! and not ' ', so form decoding needs to replace that in a
second
+
*! and not ' ', so form decoding needs to replace that in a
prior
*! step.
-
+
*!
+
*! @note
+
*! Performs a best-effort decoding. Invalid and truncated escapes
+
*! will still be decoded.
*/ { int proc = 0;
-
+
int trunc = 0;
int size_shift; PCHARP foo, end; struct string_builder newstr; if (!args || TYPEOF(Pike_sp[-args]) != PIKE_T_STRING) Pike_error("Invalid argument to http_decode_string(string).\n"); foo = MKPCHARP_STR(Pike_sp[-args].u.string); end = ADD_PCHARP(foo, Pike_sp[-args].u.string->len); size_shift = Pike_sp[-args].u.string->size_shift; /* Count '%' and wide characters. *
-
*
proc
counts the number of characters that are to be removed.
+
*
trunc
counts the number of characters that are to be removed.
*/
-
for (; COMPARE_PCHARP(foo, <, end);
INC_PCHARP(foo, 1
)
)
{
-
p_wchar2 c =
INDEX
_PCHARP(foo,
0
);
-
if (c =
=
'%') {
-
c
=
INDEX
_PCHARP(
foo
,
1
);
+
for (; COMPARE_PCHARP(foo, <, end);) {
+
p_wchar2 c =
EXTRACT
_PCHARP(foo
);
+
INC_PCHARP(foo
,
1
);
+
if (c
!
= '%')
continue;
+
proc++;
+
/* there are at least 2 more characters */
+
if (SUBTRACT_PCHARP(end, foo) < 2)
{
+
trunc
+
=
SUBTRACT
_PCHARP(
end
,
foo
);
+
break;
+
}
+
c = EXTRACT_PCHARP(foo);
if (c == 'u' || c == 'U') {
-
+
if (SUBTRACT_PCHARP(end, foo) < 5) {
+
trunc += SUBTRACT_PCHARP(end, foo);
+
break;
+
}
/* %uXXXX */
-
if (
INDEX
_PCHARP(foo
, 2
) != '0' || INDEX_PCHARP(foo,
3
) != '0') {
+
if (
EXTRACT
_PCHARP(foo) != '0' || INDEX_PCHARP(foo,
1
) != '0') {
if (!size_shift) size_shift = 1; }
-
proc
+= 5;
+
trunc
+= 5;
INC_PCHARP(foo, 5); } else {
-
proc
+= 2;
+
trunc
+= 2;
INC_PCHARP(foo, 2); } }
-
}
+
if (!proc) { pop_n_elems(args-1); return; }
-
init_string_builder_alloc(&newstr, Pike_sp[-args].u.string->len -
proc
,
+
init_string_builder_alloc(&newstr, Pike_sp[-args].u.string->len -
trunc
,
size_shift); foo = MKPCHARP_STR(Pike_sp[-args].u.string); for (; COMPARE_PCHARP(foo, <, end); INC_PCHARP(foo, 1)) {
-
p_wchar2 c =
INDEX
_PCHARP(foo
, 0
);
+
p_wchar2 c =
EXTRACT
_PCHARP(foo);
if (c == '%') { c = INDEX_PCHARP(foo, 1); if (c == 'u' || c == 'U') { c = 0; if (SUBTRACT_PCHARP(end, foo) > 5) { p_wchar2 hex = INDEX_PCHARP(foo, 2); c = (((hex<'A')?hex:(hex + 9)) & 15)<<12; hex = INDEX_PCHARP(foo, 3); c |= (((hex<'A')?hex:(hex + 9)) & 15)<<8; hex = INDEX_PCHARP(foo, 4);