pike.git
/
src
/
modules
/
_Roxen
/
roxen.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/modules/_Roxen/roxen.c:1:
/* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
-
|| $Id$
+
*/ #define NO_PIKE_SHORTHAND #include "global.h" #include "config.h"
-
+
#include "machine.h"
-
#include <sys/types.h>
+
#include <sys/stat.h> #include <fcntl.h> #include <ctype.h>
-
#include <string.h>
+
#include <time.h>
-
#include <limits.h>
+
#include "fdlib.h" #include "stralloc.h" #include "pike_macros.h" #include "machine.h" #include "object.h" #include "constants.h" #include "interpret.h" #include "svalue.h" #include "mapping.h"
pike.git/src/modules/_Roxen/roxen.c:49:
#define THP ((struct header_buf *)Pike_fp->current_storage) struct header_buf { unsigned char *headers; unsigned char *pnt; ptrdiff_t hsize, left; int slash_n, tslash_n, spc; int mode; };
-
static void f_hp_init( struct object *o )
+
static void f_hp_init( struct object *
UNUSED(
o
)
)
{ THP->headers = NULL; THP->pnt = NULL; THP->hsize = 0; THP->left = 0; THP->spc = THP->slash_n = THP->tslash_n = 0; THP->mode = 0; }
-
static void f_hp_exit( struct object *o )
+
static void f_hp_exit( struct object *
UNUSED(
o
)
)
{ if( THP->headers ) free( THP->headers ); THP->headers = NULL; THP->pnt = NULL; THP->hsize = 0; } static void f_hp_feed( INT32 args ) /*! @decl array(string|mapping) feed(string data)
pike.git/src/modules/_Roxen/roxen.c:120:
hp->hsize = 0; hp->left = 0; hp->spc = hp->slash_n = 0; hp->pnt = NULL; Pike_error("Running out of memory in header parser\n"); } hp->left += 8192; hp->pnt = (hp->headers + hp->hsize - hp->left); }
-
MEMCPY
( hp->pnt, str->str, str_len );
+
memcpy
( hp->pnt, str->str, str_len );
pop_n_elems( args ); /* FIXME: The below does not support lines terminated with just \r. */ for( ep=(hp->pnt+str_len),pp=MAXIMUM(hp->headers,hp->pnt-3); pp<ep && slash_n<2; pp++ ) if( *pp == ' ' ) { spc++; slash_n = 0; }
pike.git/src/modules/_Roxen/roxen.c:275:
} THP->mode = 0; get_all_args("create",args,".%i",&THP->mode); THP->headers = xalloc( 8192 ); THP->pnt = THP->headers; THP->hsize = 8192; THP->left = 8192; THP->spc = THP->slash_n = 0;
-
pop_n_elems(args);
-
push_int(0);
+
} /*! @endclass */ static void f_make_http_headers( INT32 args ) /*! @decl string @ *! make_http_headers(mapping(string:string|array(string)) headers, @ *! int(0..1)|void no_terminator) */
pike.git/src/modules/_Roxen/roxen.c:368:
} if (terminator) { *(pnt++) = '\r'; *(pnt++) = '\n'; } pop_n_elems( args ); push_string( end_shared_string( res ) ); }
+
static p_wchar2 parse_hexchar(p_wchar2 hex)
+
{
+
if(hex>='0' && hex<='9')
+
return hex-'0';
+
hex |= 32;
+
return hex-'W';
+
}
+
static void f_http_decode_string(INT32 args) /*! @decl string http_decode_string(string encoded) *!
-
*! Decodes an http transport-encoded string.
+
*! 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
+
*! step.
*/ {
-
int proc
;
-
int size_shift
= 0;
-
int
adjust
_
len = 0
;
-
p_wchar0
*
foo,
*bar, *
end;
-
struct
pike_
string
*
newstr;
+
int proc = 0;
+
int
size
_
shift
;
+
PCHARP
foo, end;
+
struct
string
_
builder
newstr;
-
if (!args || TYPEOF(Pike_sp[-args]) != PIKE_T_STRING
||
-
Pike_sp[-args].u.string->size_shift
)
-
Pike_error("Invalid argument to http_decode_string(string
(8bit
)
);
\n");
+
if (!args || TYPEOF(Pike_sp[-args]) != PIKE_T_STRING)
+
Pike_error("Invalid argument to http_decode_string(string)
.
\n");
-
foo =
bar = STR0
(Pike_sp[-args].u.string);
-
end = foo
+
Pike_sp[-args].u.string->len;
+
foo =
MKPCHARP_STR
(Pike_sp[-args].u.string);
+
end =
ADD_PCHARP(
foo
,
Pike_sp[-args].u.string->len
)
;
-
/*
count
'%' and wide characters */
-
for (
proc=0
; foo<end;
foo++
) {
-
if
(
*
foo=
=
'%')
{
-
proc++;
-
if (foo
[
1
]
== 'u' ||
foo[1]
== 'U') {
+
size_shift = Pike_sp[-args].u.string->size_shift;
+
+
/*
Count
'%' and wide characters
.
+
*
+
* proc counts the number of characters that are to be removed.
+
*
/
+
for (;
COMPARE_PCHARP(
foo
,
<
,
end
)
;) {
+
p_wchar2 c = EXTRACT_PCHARP(foo);
+
INC_PCHARP(foo, 1);
+
if (
c !
=
'%')
continue;
+
/*
there
are
at
least
2
more
characters
*/
+
if (
SUBTRACT_PCHARP(end,
foo
) <=
1
)
+
Pike_error("Truncated http transport encoded string.\n");
+
c
=
EXTRACT_PCHARP(foo);
+
if (c
=
=
'u' ||
c
== 'U') {
+
if (SUBTRACT_PCHARP(end, foo) <= 4)
+
Pike_error("Truncated unicode sequence.\n");
+
INC_PCHARP(foo, 1);
+
if (!isxdigit(INDEX_PCHARP(foo, 0)) ||
+
!isxdigit(INDEX_PCHARP(foo, 1)) ||
+
!isxdigit(INDEX_PCHARP(foo, 2)) ||
+
!isxdigit(INDEX_PCHARP(foo, 3)))
+
Pike_error("Illegal transport encoding.\n");
/* %uXXXX */
-
if (foo
[2]
!= '0' || foo
[3]
!= '0') {
-
size_shift = 1;
+
if (
EXTRACT_PCHARP(
foo
)
!= '0' ||
INDEX_PCHARP(
foo
,
1)
!= '0') {
+
if
(!size_shift)
size_shift = 1;
}
-
foo
+= 5;
-
if
(foo
< end
)
{
-
adjust_len += 5
;
+
proc
+= 5;
+
INC_PCHARP
(foo
,
4
);
} else {
-
adjust
_
len
+=
end
-
(foo
- 4
);
+
if
(!isxdigit(INDEX_PCHARP(foo,
0))
||
+
!isxdigit(INDEX
_
PCHARP(foo,
1)))
+
Pike_error("Illegal transport encoding.\n");
+
proc
+=
2;
+
INC_PCHARP
(foo
,
2
);
}
-
} else {
-
foo += 2;
-
if (foo < end) {
-
adjust_len += 2;
-
} else {
-
adjust_len += end - (foo - 1);
+
}
-
}
-
}
-
}
+
if (!proc) { pop_n_elems(args-1); return; }
-
newstr = begin
_
wide
_
shared
_
string
(Pike_sp[-args].u.string->len -
adjust_len
,
+
init
_
string
_
builder
_
alloc
(
&newstr,
Pike_sp[-args].u.string->len -
proc
,
size_shift);
-
if (size_shift) {
-
p_wchar1 *dest = STR1(newstr);
+
-
for (
proc=0
;
bar
<end;
dest++
)
-
if (
*bar
=='%') {
-
if (
bar[1]
== 'u' ||
bar[1]
== 'U') {
-
if
(
bar<end-5
)
-
*dest
= (
((bar[2]<'A'
)
?(bar[2]&15):((bar[2]+9)&15))
<<12
)|
-
(
((bar[3]<'A'
)
?(bar[3]&15):((bar[3]+9)&15))
<<8
)|
-
(
((bar[
4
]<'A'
)
?(bar[4]&15):((bar[4]+9)&15))<<4)|
-
(
(bar[5]<'A'
)
?(bar[5]&15):((bar[5]+9)&15))
;
-
else
-
*dest
=
0
;
-
bar+=6
;
+
foo
=
MKPCHARP_STR(Pike_sp[-args].u.string);
+
+
for (;
COMPARE_PCHARP(foo,
<
,
end
)
;
INC_PCHARP(foo, 1
)
) {
+
p_wchar2
c
= INDEX_PCHARP(foo, 0);
+
if (
c
==
'%') {
+
c
=
INDEX_PCHARP(foo, 1);
+
/* The above loop checks that the following sequences
+
* are correct, i.e. that they are not truncated and consist
+
* of hexadecimal chars.
+
*/
+
if (
c
== 'u' ||
c
== 'U') {
+
p_wchar2
hex
=
INDEX_PCHARP
(
foo, 2
)
;
+
c
=
parse_hexchar
(
hex
)<<12
;
+
hex
=
INDEX_PCHARP(foo,
3);
+
c |= parse_hexchar
(
hex
)<<8
;
+
hex
=
INDEX_PCHARP(foo,
4)
;
+
c
|=
parse_hexchar
(
hex)
<
<4
;
+
hex
=
INDEX_PCHARP(foo, 5);
+
c
|=
parse_hexchar(hex)
;
+
INC_PCHARP(foo,
5)
;
} else {
-
if
(
bar<end-2
)
-
*dest
=(
((bar[1]<'A'
)
?(bar[1]&15):((bar[1]+9)&15))
<<4
)|
-
(
(bar[
2
]<'A'
)
?(bar[2]&15):((bar[2]+9)&15))
;
-
else
-
*dest
=
0
;
-
bar+=3
;
+
p_wchar2
hex
=
INDEX_PCHARP
(
foo, 1
)
;
+
c
=
parse_hexchar
(
hex
)<<4
;
+
hex
=
INDEX_PCHARP(foo,
2);
+
c
|=
parse_hexchar(hex)
;
+
INC_PCHARP(foo,
2)
;
}
-
} else {
-
*dest=*(bar++);
+
}
-
}
else
{
-
foo = STR0
(newstr
);
-
for (proc=0; bar<end; foo++
)
-
if (*bar=='%') {
-
if (bar[1] == 'u' || bar[1] == 'U') {
-
/* We know that the following two characters are zeros. */
-
bar+=3
;
+
string_builder_putchar
(
&
newstr
,
c
);
}
-
if (bar<end-2)
-
*foo=(((bar[1]<'A')?(bar[1]&15):((bar[1]+9)&15))<<4)|
-
((bar[2]<'A')?(bar[2]&15):((bar[2]+9)&15));
-
else
-
*foo=0;
-
bar+=3;
-
} else {
-
*foo=*(bar++);
-
}
-
}
+
pop_n_elems(args);
-
push_string(
end
_
shared_
string(newstr));
+
push_string(
finish
_
string
_
builder
(
&
newstr));
} static void f_html_encode_string( INT32 args ) /*! @decl string html_encode_string(mixed in) *! *! Encodes the @[in] data as an HTML safe string. */ { struct pike_string *str; int newlen;
-
+
INT32 min;
if( args != 1 ) Pike_error("Wrong number of arguments to html_encode_string\n" ); switch( TYPEOF(Pike_sp[-1]) ) { void o_cast_to_string(); case PIKE_T_INT:
-
/* Optimization, this is basically a inlined cast_int_to_string */
-
{
-
char buf[21], *b = buf+19;
-
int neg, i, j=0;
-
i = Pike_sp[-1].u.integer;
-
pop_stack();
-
if( i < 0 )
-
{
-
neg = 1;
-
i = -i;
-
}
-
else
-
neg = 0;
-
-
buf[20] = 0;
-
-
while( i >= 10 )
-
{
-
b[ -j++ ] = '0'+(i%10);
-
i /= 10;
-
}
-
b[ -j++ ] = '0'+(i%10);
-
if( neg ) b[ -j++ ] = '-';
-
push_text( b-j+1 );
-
}
-
return;
-
+
case PIKE_T_FLOAT: /* Optimization, no need to check the resultstring for * unsafe characters. */ o_cast_to_string(); return; default: o_cast_to_string(); case PIKE_T_STRING: break; } str = Pike_sp[-1].u.string; newlen = str->len;
-
+
check_string_range(str, 1, &min, NULL);
+
+
if (min > '>') return;
+
#define COUNT(T) { \ T *s = (T *)str->str; \ int i; \ for( i = 0; i<str->len; i++ ) \ switch( s[i] ) \ { \ case 0: /* � */ \ case '<': /* < */ \ case '>': newlen+=3; break;/* > */ \ case '&': /* & */ \