diff -Nura php-5.0.4/acinclude.m4 hardening-patch-5.0.4-0.4.1/acinclude.m4
--- php-5.0.4/acinclude.m4	2005-01-25 14:02:45.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/acinclude.m4	2005-08-04 12:06:45.000000000 +0200
@@ -1169,6 +1169,36 @@
   fi
 ])
 
+dnl
+dnl Check for broken realpath()
+dnl
+dnl realpath("/etc/hosts/../passwd",XXX) should not return 
+dnl "/etc/passwd"
+dnl
+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
+  AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
+    AC_TRY_RUN([
+main() {
+	char buf[4096+1];
+	buf[0] = 0;
+	realpath("/etc/hosts/../passwd", buf);
+	exit(strcmp(buf, "/etc/passwd")==0); 
+}
+    ],[
+      ac_cv_broken_realpath=no
+    ],[
+      ac_cv_broken_realpath=yes
+    ],[
+      ac_cv_broken_realpath=no
+    ])
+  ])
+  if test "$ac_cv_broken_realpath" = "yes"; then
+    AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
+  else
+    AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
+  fi
+])
+
 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
 dnl
 dnl Basically sets up the link-stage for building module-name
diff -Nura php-5.0.4/configure hardening-patch-5.0.4-0.4.1/configure
--- php-5.0.4/configure	2005-04-03 11:42:50.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/configure	2005-08-04 12:06:45.000000000 +0200
@@ -401,6 +401,16 @@
 ac_default_prefix=/usr/local
 # Any additions from configure.in:
 ac_help="$ac_help
+  --disable-hardening-patch-mm-protect    Disable the Memory Manager protection."
+ac_help="$ac_help
+  --disable-hardening-patch-ll-protect    Disable the Linked List protection."
+ac_help="$ac_help
+  --disable-hardening-patch-inc-protect   Disable include/require protection."
+ac_help="$ac_help
+  --disable-hardening-patch-fmt-protect   Disable format string protection."
+ac_help="$ac_help
+  --disable-hardening-patch-hash-protect  Disable Zend HashTable DTOR protection."
+ac_help="$ac_help
 
 SAPI modules:
 "
@@ -857,6 +867,8 @@
 ac_help="$ac_help
   --disable-tokenizer     Disable tokenizer support"
 ac_help="$ac_help
+  --disable-varfilter     Disable Hardening-Patch's variable filter"
+ac_help="$ac_help
   --enable-wddx           Enable WDDX support."
 ac_help="$ac_help
   --disable-xml           Disable XML support."
@@ -2749,6 +2761,157 @@
 
 
 
+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
+if test "${enable_hardening_patch_mm_protect+set}" = set; then
+  enableval="$enable_hardening_patch_mm_protect"
+  
+  DO_HARDENING_PATCH_MM_PROTECT=$enableval
+
+else
+  
+  DO_HARDENING_PATCH_MM_PROTECT=yes
+
+fi
+
+
+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
+if test "${enable_hardening_patch_ll_protect+set}" = set; then
+  enableval="$enable_hardening_patch_ll_protect"
+  
+  DO_HARDENING_PATCH_LL_PROTECT=$enableval
+
+else
+  
+  DO_HARDENING_PATCH_LL_PROTECT=yes
+
+fi
+
+
+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
+if test "${enable_hardening_patch_inc_protect+set}" = set; then
+  enableval="$enable_hardening_patch_inc_protect"
+  
+  DO_HARDENING_PATCH_INC_PROTECT=$enableval
+
+else
+  
+  DO_HARDENING_PATCH_INC_PROTECT=yes
+
+fi
+
+
+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
+  enableval="$enable_hardening_patch_fmt_protect"
+  
+  DO_HARDENING_PATCH_FMT_PROTECT=$enableval
+
+else
+  
+  DO_HARDENING_PATCH_FMT_PROTECT=yes
+
+fi
+
+
+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
+if test "${enable_hardening_patch_hash_protect+set}" = set; then
+  enableval="$enable_hardening_patch_hash_protect"
+  
+  DO_HARDENING_PATCH_HASH_PROTECT=$enableval
+
+else
+  
+  DO_HARDENING_PATCH_HASH_PROTECT=yes
+
+fi
+
+
+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
+
+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
+
+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
+echo "configure:2733: checking whether to protect include/require statements" >&5
+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
+
+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
+
+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
+
+
+cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH 1
+EOF
+
+
+
+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_MM_PROTECT 1
+EOF
+
+else
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_MM_PROTECT 0
+EOF
+
+fi
+
+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_LL_PROTECT 1
+EOF
+
+else
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_LL_PROTECT 0
+EOF
+
+fi
+
+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_INC_PROTECT 1
+EOF
+
+else
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_INC_PROTECT 0
+EOF
+
+fi
+
+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_FMT_PROTECT 1
+EOF
+
+else
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_FMT_PROTECT 0
+EOF
+
+fi
+
+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_HASH_PROTECT 1
+EOF
+
+else
+  cat >> confdefs.h <<\EOF
+#define HARDENING_PATCH_HASH_PROTECT 0
+EOF
+
+fi
 
 
 
@@ -17390,6 +17553,62 @@
 fi
 
 
+  echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
+echo "configure:14928: checking whether realpath is broken" >&5
+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    if test "$cross_compiling" = yes; then
+  
+      ac_cv_broken_realpath=no
+    
+else
+  cat > conftest.$ac_ext <<EOF
+#line 14939 "configure"
+#include "confdefs.h"
+
+main() {
+	char buf[4096+1];
+	buf[0] = 0;
+	realpath("/etc/hosts/../passwd", buf);
+	exit(strcmp(buf, "/etc/passwd")==0); 
+}
+    
+EOF
+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  
+      ac_cv_broken_realpath=no
+    
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  
+      ac_cv_broken_realpath=yes
+    
+fi
+rm -fr conftest*
+fi
+
+  
+fi
+
+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
+  if test "$ac_cv_broken_realpath" = "yes"; then
+    cat >> confdefs.h <<\EOF
+#define PHP_BROKEN_REALPATH 1
+EOF
+
+  else
+    cat >> confdefs.h <<\EOF
+#define PHP_BROKEN_REALPATH 0
+EOF
+
+  fi
+
+
   echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
 echo "configure:17395: checking for declared timezone" >&5
 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
@@ -86878,6 +87097,265 @@
 fi
 
 
+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
+# Check whether --enable-varfilter or --disable-varfilter was given.
+if test "${enable_varfilter+set}" = set; then
+  enableval="$enable_varfilter"
+  PHP_VARFILTER=$enableval
+else
+  
+  PHP_VARFILTER=yes
+
+  if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
+    PHP_VARFILTER=$PHP_ENABLE_ALL
+  fi
+
+fi
+
+
+
+ext_output="yes, shared"
+ext_shared=yes
+case $PHP_VARFILTER in
+shared,*)
+  PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
+  ;;
+shared)
+  PHP_VARFILTER=yes
+  ;;
+no)
+  ext_output=no
+  ext_shared=no
+  ;;
+*)
+  ext_output=yes
+  ext_shared=no
+  ;;
+esac
+
+
+
+echo "$ac_t""$ext_output" 1>&6
+
+
+
+
+if test "$PHP_VARFILTER" != "no"; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_VARFILTER 1
+EOF
+
+  
+  ext_builddir=ext/varfilter
+  ext_srcdir=$abs_srcdir/ext/varfilter
+
+  ac_extra=
+
+  if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
+
+    
+  
+  case ext/varfilter in
+  "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
+  /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
+  *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
+  esac
+  
+  
+
+  b_c_pre=$php_c_pre
+  b_cxx_pre=$php_cxx_pre
+  b_c_meta=$php_c_meta
+  b_cxx_meta=$php_cxx_meta
+  b_c_post=$php_c_post
+  b_cxx_post=$php_cxx_post
+  b_lo=$php_lo
+
+
+  old_IFS=$IFS
+  for ac_src in varfilter.c; do
+  
+      IFS=.
+      set $ac_src
+      ac_obj=$1
+      IFS=$old_IFS
+      
+      PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
+
+      case $ac_src in
+	  *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
+	  *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
+      esac
+
+	  cat >>Makefile.objects<<EOF
+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
+	$ac_comp
+EOF
+  done
+
+
+    EXT_STATIC="$EXT_STATIC varfilter"
+    if test "$ext_shared" != "nocli"; then
+      EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
+    fi
+  else
+    if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
+      
+  case ext/varfilter in
+  "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
+  /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
+  *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
+  esac
+  
+  
+
+  b_c_pre=$shared_c_pre
+  b_cxx_pre=$shared_cxx_pre
+  b_c_meta=$shared_c_meta
+  b_cxx_meta=$shared_cxx_meta
+  b_c_post=$shared_c_post
+  b_cxx_post=$shared_cxx_post
+  b_lo=$shared_lo
+
+
+  old_IFS=$IFS
+  for ac_src in varfilter.c; do
+  
+      IFS=.
+      set $ac_src
+      ac_obj=$1
+      IFS=$old_IFS
+      
+      shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
+
+      case $ac_src in
+	  *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
+	  *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
+      esac
+
+	  cat >>Makefile.objects<<EOF
+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
+	$ac_comp
+EOF
+  done
+
+      
+  install_modules="install-modules"
+  PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
+  
+  PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
+
+  cat >>Makefile.objects<<EOF
+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
+	\$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
+
+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
+	\$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
+
+EOF
+
+      cat >> confdefs.h <<EOF
+#define COMPILE_DL_VARFILTER 1
+EOF
+
+    fi
+  fi
+
+  if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
+    if test "$PHP_SAPI" = "cgi"; then
+      
+  
+  case ext/varfilter in
+  "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
+  /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
+  *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
+  esac
+  
+  
+
+  b_c_pre=$php_c_pre
+  b_cxx_pre=$php_cxx_pre
+  b_c_meta=$php_c_meta
+  b_cxx_meta=$php_cxx_meta
+  b_c_post=$php_c_post
+  b_cxx_post=$php_cxx_post
+  b_lo=$php_lo
+
+
+  old_IFS=$IFS
+  for ac_src in varfilter.c; do
+  
+      IFS=.
+      set $ac_src
+      ac_obj=$1
+      IFS=$old_IFS
+      
+      PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
+
+      case $ac_src in
+	  *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
+	  *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
+      esac
+
+	  cat >>Makefile.objects<<EOF
+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
+	$ac_comp
+EOF
+  done
+
+
+      EXT_STATIC="$EXT_STATIC varfilter"
+    else
+      
+  
+  case ext/varfilter in
+  "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
+  /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
+  *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
+  esac
+  
+  
+
+  b_c_pre=$php_c_pre
+  b_cxx_pre=$php_cxx_pre
+  b_c_meta=$php_c_meta
+  b_cxx_meta=$php_cxx_meta
+  b_c_post=$php_c_post
+  b_cxx_post=$php_cxx_post
+  b_lo=$php_lo
+
+
+  old_IFS=$IFS
+  for ac_src in varfilter.c; do
+  
+      IFS=.
+      set $ac_src
+      ac_obj=$1
+      IFS=$old_IFS
+      
+      PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
+
+      case $ac_src in
+	  *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
+	  *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
+      esac
+
+	  cat >>Makefile.objects<<EOF
+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
+	$ac_comp
+EOF
+  done
+
+
+    fi
+    EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
+  fi
+  
+  BUILD_DIR="$BUILD_DIR $ext_builddir"
+
+
+fi
 
 
 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
@@ -97351,7 +97829,7 @@
        php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
        strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
        network.c php_open_temporary_file.c php_logos.c \
-       output.c ; do
+       output.c hardening_patch.c ; do
   
       IFS=.
       set $ac_src
@@ -97579,7 +98057,7 @@
     zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
     zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
-    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do
+    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do
   
       IFS=.
       set $ac_src
diff -Nura php-5.0.4/configure.in hardening-patch-5.0.4-0.4.1/configure.in
--- php-5.0.4/configure.in	2005-03-30 23:43:12.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/configure.in	2005-08-04 12:06:45.000000000 +0200
@@ -235,7 +235,7 @@
 sinclude(Zend/acinclude.m4)
 sinclude(Zend/Zend.m4)
 sinclude(TSRM/tsrm.m4)
-
+sinclude(main/hardening_patch.m4)
 
 
 divert(2)
@@ -620,6 +620,7 @@
 AC_FUNC_ALLOCA
 dnl PHP_AC_BROKEN_SPRINTF
 dnl PHP_AC_BROKEN_SNPRINTF
+PHP_AC_BROKEN_REALPATH
 PHP_DECLARED_TIMEZONE
 PHP_TIME_R_TYPE
 PHP_READDIR_R_TYPE
@@ -1262,7 +1263,7 @@
        php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
        strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
        network.c php_open_temporary_file.c php_logos.c \
-       output.c )
+       output.c hardening_patch.c )
 
 PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
        plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c)
@@ -1280,7 +1281,7 @@
     zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
     zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
-    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
+    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c )
 
 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
   PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
diff -Nura php-5.0.4/ext/fbsql/php_fbsql.c hardening-patch-5.0.4-0.4.1/ext/fbsql/php_fbsql.c
--- php-5.0.4/ext/fbsql/php_fbsql.c	2005-02-09 20:32:45.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/fbsql/php_fbsql.c	2005-08-04 12:06:45.000000000 +0200
@@ -1852,8 +1852,24 @@
 	}
 	else if (fbcmdErrorsFound(md))
 	{
+#if HARDENING_PATCH
+		char*	query_copy;
+		int i;
+#endif
 		FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
 		char*             emg = fbcemdAllErrorMessages(emd);
+#if HARDENING_PATCH
+		query_copy=estrdup(query_copy);
+		for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
+		php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
+		efree(query_copy);
+		if (HG(hphp_sql_bailout_on_error)) {
+			free(emg);
+			fbcemdRelease(emd);
+			result = 0;
+			zend_bailout();
+		}
+#endif
 		if (FB_SQL_G(generateWarnings))
 		{
 			if (emg)
diff -Nura php-5.0.4/ext/mysql/php_mysql.c hardening-patch-5.0.4-0.4.1/ext/mysql/php_mysql.c
--- php-5.0.4/ext/mysql/php_mysql.c	2005-02-22 15:59:30.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/mysql/php_mysql.c	2005-08-04 12:06:45.000000000 +0200
@@ -1221,6 +1221,8 @@
 {
 	php_mysql_conn *mysql;
 	MYSQL_RES *mysql_result;
+	char *copy_query;
+	int i;
 	
 	ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
 	
@@ -1271,6 +1273,13 @@
 				php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); 
 			}
 		}
+		copy_query = estrdup(Z_STRVAL_PP(query));
+		for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
+		php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
+		efree(copy_query);
+		if (HG(hphp_sql_bailout_on_error)) {
+			zend_bailout();
+		}
 		RETURN_FALSE;
 	}
 #else
@@ -1281,6 +1290,13 @@
 				php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn)); 
 			}
 		}
+		copy_query = estrdup(Z_STRVAL_PP(query));
+		for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
+		php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
+		efree(copy_query);
+		if (HG(hphp_sql_bailout_on_error)) {
+			zend_bailout();
+		}
 		RETURN_FALSE;
 	}
 #endif
diff -Nura php-5.0.4/ext/mysqli/mysqli_nonapi.c hardening-patch-5.0.4-0.4.1/ext/mysqli/mysqli_nonapi.c
--- php-5.0.4/ext/mysqli/mysqli_nonapi.c	2005-02-25 00:59:49.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/mysqli/mysqli_nonapi.c	2005-08-04 12:06:45.000000000 +0200
@@ -228,6 +228,17 @@
 	if (mysql_real_query(mysql->mysql, query, query_len)) {
 		char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
 		unsigned int s_errno;
+#if HARDENING_PATCH
+		char *query_copy = estrdup(query);
+		int i;
+		
+		for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
+		php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_errno, query_copy);
+		efree(query_copy);
+		if (HG(hphp_sql_bailout_on_error)) {
+			zend_bailout();
+		}
+#endif
 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
 
 		/* we have to save error information, cause 
@@ -268,6 +279,17 @@
 	MYSQLI_DISABLE_MQ;
 
 	if (mysql_real_query(mysql->mysql, query, query_len)) {
+#if HARDENING_PATCH
+		char *query_copy = estrdup(query);
+		int i;
+		
+		for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
+		php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_errno, query_copy);
+		efree(query_copy);
+		if (HG(hphp_sql_bailout_on_error)) {
+			zend_bailout();
+		}
+#endif
 		MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
 		RETURN_FALSE;
 	}
diff -Nura php-5.0.4/ext/pgsql/pgsql.c hardening-patch-5.0.4-0.4.1/ext/pgsql/pgsql.c
--- php-5.0.4/ext/pgsql/pgsql.c	2004-05-12 18:49:47.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/ext/pgsql/pgsql.c	2005-08-04 12:06:45.000000000 +0200
@@ -1076,10 +1076,28 @@
 		case PGRES_EMPTY_QUERY:
 		case PGRES_BAD_RESPONSE:
 		case PGRES_NONFATAL_ERROR:
-		case PGRES_FATAL_ERROR:
-			PHP_PQ_ERROR("Query failed: %s", pgsql);
-			PQclear(pgsql_result);
-			RETURN_FALSE;
+		case PGRES_FATAL_ERROR: 
+			{
+#if HARDENING_PATCH
+				int i;
+				char *query_copy;
+#endif				
+				char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
+				PQclear(pgsql_result);
+#if HARDENING_PATCH
+				query_copy = estrdup(Z_STRVAL_PP(query));
+				for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
+				php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
+				efree(query_copy);
+				if (HG(hphp_sql_bailout_on_error)) {
+					efree(msgbuf);
+					zend_bailout();
+				}
+#endif				
+				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
+				efree(msgbuf);
+				RETURN_FALSE;
+			}
 			break;
 		case PGRES_COMMAND_OK: /* successful command that did not return rows */
 		default:
diff -Nura php-5.0.4/ext/sqlite/sqlite.c hardening-patch-5.0.4-0.4.1/ext/sqlite/sqlite.c
--- php-5.0.4/ext/sqlite/sqlite.c	2004-09-26 03:41:40.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/ext/sqlite/sqlite.c	2005-08-04 12:06:45.000000000 +0200
@@ -1473,6 +1473,19 @@
 	db->last_err_code = ret;
 
 	if (ret != SQLITE_OK) {
+#if HARDENING_PATCH
+		char *query_copy;
+		int i;
+
+		query_copy = estrdup(sql);
+		for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
+		php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy);
+		efree(query_copy);
+		if (HG(hphp_sql_bailout_on_error)) {
+			sqlite_freemem(errtext);
+			zend_bailout();
+		}
+#endif
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
 		sqlite_freemem(errtext);
 		goto terminate;
diff -Nura php-5.0.4/ext/standard/array.c hardening-patch-5.0.4-0.4.1/ext/standard/array.c
--- php-5.0.4/ext/standard/array.c	2005-03-12 11:12:49.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/standard/array.c	2005-08-04 12:06:45.000000000 +0200
@@ -1255,6 +1255,32 @@
 			}
 		}
 	}
+
+	if (var_name[0] == 'H') {
+		if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
+		    (strcmp(var_name, "HTTP_POST_VARS")==0)||
+		    (strcmp(var_name, "HTTP_POST_FILES")==0)||
+		    (strcmp(var_name, "HTTP_ENV_VARS")==0)||
+		    (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
+		    (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
+		    (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
+		    (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
+		    return 0;
+		}
+	} else if (var_name[0] == '_') {
+		if ((strcmp(var_name, "_COOKIE")==0)||
+		    (strcmp(var_name, "_ENV")==0)||
+		    (strcmp(var_name, "_FILES")==0)||
+		    (strcmp(var_name, "_GET")==0)||
+		    (strcmp(var_name, "_POST")==0)||
+		    (strcmp(var_name, "_REQUEST")==0)||
+		    (strcmp(var_name, "_SESSION")==0)||
+		    (strcmp(var_name, "_SERVER")==0)) {
+		    return 0;
+		}
+	} else if (strcmp(var_name, "GLOBALS")==0) {
+		return 0;
+	}
 	
 	return 1;
 }
diff -Nura php-5.0.4/ext/standard/basic_functions.c hardening-patch-5.0.4-0.4.1/ext/standard/basic_functions.c
--- php-5.0.4/ext/standard/basic_functions.c	2005-03-10 13:10:57.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/standard/basic_functions.c	2005-08-06 10:33:50.000000000 +0200
@@ -142,12 +142,14 @@
 typedef struct _php_shutdown_function_entry {
 	zval **arguments;
 	int arg_count;
+	zend_bool created_by_eval;
 } php_shutdown_function_entry;
 
 typedef struct _user_tick_function_entry {
 	zval **arguments;
 	int arg_count;
 	int calling;
+	zend_bool created_by_eval;
 } user_tick_function_entry;
 
 /* some prototypes for local functions */
@@ -617,7 +619,7 @@
 	PHP_FALIAS(socket_get_status, stream_get_meta_data,						NULL)
 
 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
-	PHP_FE(realpath,														NULL)
+	PHP_STATIC_FE("realpath",		zif_real_path,							NULL)
 #endif
 
 #ifdef HAVE_FNMATCH
@@ -2103,7 +2105,13 @@
 static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC)
 {
 	zval retval;
+#if HARDENING_PATCH	
+	zend_uint orig_code_type = EG(in_code_type);
 
+	if (shutdown_function_entry->created_by_eval) {
+		EG(in_code_type) = ZEND_EVAL_CODE;
+	}
+#endif
 	if (call_user_function(	EG(function_table), NULL,
 							shutdown_function_entry->arguments[0],
 							&retval, 
@@ -2115,6 +2123,9 @@
 	} else {
 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0]));
 	}
+#if HARDENING_PATCH	
+	EG(in_code_type) = orig_code_type;
+#endif
 	return 0;
 }
 
@@ -2122,6 +2133,13 @@
 {
 	zval retval;
 	zval *function = tick_fe->arguments[0];
+#if HARDENING_PATCH	
+	zend_uint orig_code_type = EG(in_code_type);
+
+	if (tick_fe->created_by_eval) {
+		EG(in_code_type) = ZEND_EVAL_CODE;
+	}
+#endif
 	
 	/* Prevent reentrant calls to the same user ticks function */
 	if (! tick_fe->calling) {
@@ -2153,6 +2171,9 @@
 	
 		tick_fe->calling = 0;
 	}
+#if HARDENING_PATCH	
+	EG(in_code_type) = orig_code_type;
+#endif
 }
 
 static void run_user_tick_functions(int tick_count)
@@ -2215,6 +2236,13 @@
 	}
 
 	shutdown_function_entry.arguments = (pval **) safe_emalloc(sizeof(pval *), shutdown_function_entry.arg_count, 0);
+#if HARDENING_PATCH
+	if (EG(in_code_type)==ZEND_EVAL_CODE) {
+		shutdown_function_entry.created_by_eval = 1;
+	} else {
+		shutdown_function_entry.created_by_eval = 0;
+	}
+#endif	
 
 	if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
 		RETURN_FALSE;
@@ -2836,6 +2864,13 @@
 	}
 
 	tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
+#if HARDENING_PATCH
+	if (EG(in_code_type)==ZEND_EVAL_CODE) {
+		tick_fe.created_by_eval = 1;
+	} else {
+		tick_fe.created_by_eval = 0;
+	}
+#endif	
 
 	if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
 		RETURN_FALSE;
@@ -3124,6 +3159,35 @@
 	memcpy(new_key, prefix, prefix_len);
 	memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
 
+	if (new_key[0] == 'H') {
+		if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
+		    (strcmp(new_key, "HTTP_POST_VARS")==0)||
+		    (strcmp(new_key, "HTTP_POST_FILES")==0)||
+		    (strcmp(new_key, "HTTP_ENV_VARS")==0)||
+		    (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
+		    (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
+		    (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
+		    (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
+		    efree(new_key);
+		    return 0;
+		}
+	} else if (new_key[0] == '_') {
+		if ((strcmp(new_key, "_COOKIE")==0)||
+		    (strcmp(new_key, "_ENV")==0)||
+		    (strcmp(new_key, "_FILES")==0)||
+		    (strcmp(new_key, "_GET")==0)||
+		    (strcmp(new_key, "_POST")==0)||
+		    (strcmp(new_key, "_REQUEST")==0)||
+		    (strcmp(new_key, "_SESSION")==0)||
+		    (strcmp(new_key, "_SERVER")==0)) {
+		    efree(new_key);
+		    return 0;
+		}
+	} else if (strcmp(new_key, "GLOBALS")==0) {
+		efree(new_key);
+		return 0;
+	}
+
 	zend_hash_del(&EG(symbol_table), new_key, new_key_len);
 	ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
 
diff -Nura php-5.0.4/ext/standard/dl.c hardening-patch-5.0.4-0.4.1/ext/standard/dl.c
--- php-5.0.4/ext/standard/dl.c	2005-03-21 09:34:37.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/standard/dl.c	2005-08-04 20:28:21.000000000 +0200
@@ -177,8 +177,35 @@
 		RETURN_FALSE;
 	}
 	module_entry = get_module();
+
+	/* check if Hardening-Patch is installed */
+	if (module_entry->zend_api < 1000000000) {
+		php_error_docref(NULL TSRMLS_CC, error_type,
+				  "%s: Unable to initialize module\n"
+				  "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
+				  "PHP    compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
+				  "These options need to match\n",
+				  module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
+				  HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
+		DL_UNLOAD(handle);
+		RETURN_FALSE;
+	}
+
+	/* check if correct Hardening-Patch is installed */
+	if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
+		php_error_docref(NULL TSRMLS_CC, error_type,
+				  "%s: Unable to initialize module\n"
+				  "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
+				  "PHP    compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
+				  "These options need to match\n",
+				  module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
+				  HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
+		DL_UNLOAD(handle);
+		RETURN_FALSE;
+	}
+
 	if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
-		|| (module_entry->zend_api != ZEND_MODULE_API_NO)) {
+		|| (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
 		/* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
 			struct pre_4_1_0_module_entry {
 				  char *name;
@@ -212,7 +239,7 @@
 				zts        = ((struct pre_4_1_0_module_entry *)module_entry)->zts; 
 			} else {			
 				name       = module_entry->name;
-				zend_api   = module_entry->zend_api;
+				zend_api   = module_entry->real_zend_api;
 				zend_debug = module_entry->zend_debug;
 				zts        = module_entry->zts; 
 			}
diff -Nura php-5.0.4/ext/standard/file.c hardening-patch-5.0.4-0.4.1/ext/standard/file.c
--- php-5.0.4/ext/standard/file.c	2005-03-27 17:53:30.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/ext/standard/file.c	2005-08-04 12:06:45.000000000 +0200
@@ -2044,7 +2044,7 @@
 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
 /* {{{ proto string realpath(string path)
    Return the resolved path */
-PHP_FUNCTION(realpath)
+PHP_FUNCTION(real_path)
 {
 	zval **path;
 	char resolved_path_buff[MAXPATHLEN];
diff -Nura php-5.0.4/ext/standard/file.h hardening-patch-5.0.4-0.4.1/ext/standard/file.h
--- php-5.0.4/ext/standard/file.h	2004-06-21 23:08:05.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/ext/standard/file.h	2005-08-04 12:06:45.000000000 +0200
@@ -60,7 +60,7 @@
 PHP_FUNCTION(fd_set);
 PHP_FUNCTION(fd_isset);
 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
-PHP_FUNCTION(realpath);
+PHP_FUNCTION(real_path);
 PHP_FUNCTION(fnmatch);
 #endif
 PHP_NAMED_FUNCTION(php_if_ftruncate);
diff -Nura php-5.0.4/ext/standard/ftp_fopen_wrapper.c hardening-patch-5.0.4-0.4.1/ext/standard/ftp_fopen_wrapper.c
--- php-5.0.4/ext/standard/ftp_fopen_wrapper.c	2005-03-21 09:42:34.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/standard/ftp_fopen_wrapper.c	2005-08-04 12:06:45.000000000 +0200
@@ -113,7 +113,7 @@
 {
 	php_stream *stream = NULL, *reuseid = NULL;
 	php_url *resource = NULL;
-	int result, use_ssl, use_ssl_on_data = 0;
+	int result, use_ssl, use_ssl_on_data = 0, tmp_len;
 	char *scratch;
 	char tmp_line[512];
 
@@ -206,10 +206,25 @@
 #endif
 	}
 
+#define PHP_FTP_CNTRL_CHK(val, val_len, err_msg) {	\
+	unsigned char *s = val, *e = s + val_len;	\
+	while (s < e) {	\
+		if (iscntrl(*s)) {	\
+			php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, err_msg, val);	\
+			goto connect_errexit;	\
+		}	\
+		s++;	\
+	}	\
+}
+
 	/* send the user name */
 	php_stream_write_string(stream, "USER ");
 	if (resource->user != NULL) {
-		php_raw_url_decode(resource->user, strlen(resource->user));
+		unsigned char *s, *e;
+		tmp_len = php_raw_url_decode(resource->user, strlen(resource->user));
+		
+		PHP_FTP_CNTRL_CHK(resource->user, tmp_len, "Invalid login %s")
+		
 		php_stream_write_string(stream, resource->user);
 	} else {
 		php_stream_write_string(stream, "anonymous");
@@ -225,7 +240,10 @@
 
 		php_stream_write_string(stream, "PASS ");
 		if (resource->pass != NULL) {
-			php_raw_url_decode(resource->pass, strlen(resource->pass));
+			tmp_len = php_raw_url_decode(resource->pass, strlen(resource->pass));
+		
+			PHP_FTP_CNTRL_CHK(resource->pass, tmp_len, "Invalid password %s")
+			
 			php_stream_write_string(stream, resource->pass);
 		} else {
 			/* if the user has configured who they are,
diff -Nura php-5.0.4/ext/standard/head.c hardening-patch-5.0.4-0.4.1/ext/standard/head.c
--- php-5.0.4/ext/standard/head.c	2005-01-07 22:16:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/standard/head.c	2005-08-04 12:06:45.000000000 +0200
@@ -45,10 +45,31 @@
 {
 	zend_bool rep = 1;
 	sapi_header_line ctr = {0};
+#if HARDENING_PATCH
+	int i;
+#endif
 	
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
 				&ctr.line_len, &rep, &ctr.response_code) == FAILURE)
 		return;
+
+#if HARDENING_PATCH
+	if (!HG(hphp_multiheader)) {
+		for (i=0; i<ctr.line_len; i++) {
+			if (ctr.line[i]==0) {
+				php_security_log(S_MISC, "header(): headerline truncated by an ASCII-NUL char");
+				ctr.line_len=i;
+				break;
+			} else if (ctr.line[i]=='\n') {
+				if (i>0 && (i<ctr.line_len-1) && (ctr.line[i+1]==' ' || ctr.line[i+1]=='\t')) {
+					continue;
+				}
+				php_security_log(S_MISC, "header(): headerline contains more than one header");
+				ctr.line_len=i;
+			}
+		}
+	}
+#endif
 	
 	sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
 }
diff -Nura php-5.0.4/ext/standard/info.c hardening-patch-5.0.4-0.4.1/ext/standard/info.c
--- php-5.0.4/ext/standard/info.c	2004-05-02 15:23:30.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/ext/standard/info.c	2005-08-04 12:06:45.000000000 +0200
@@ -394,7 +394,7 @@
 
 	if (flag & PHP_INFO_GENERAL) {
 		char *zend_version = get_zend_version();
-		char temp_api[10];
+		char temp_api[11];
 		char *logo_guid;
 
 		php_uname = php_get_uname('a');
@@ -415,11 +415,22 @@
 			PUTS("\" alt=\"PHP Logo\" /></a>");
 		}
 
+#if HARDENING_PATCH
+		if (!sapi_module.phpinfo_as_text) {
+			php_printf("<h1 class=\"p\">PHP Version %s with Hardening-Patch %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
+		} else {
+			char temp_ver[40];	
+		
+			snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
+			php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
+		}
+#else
 		if (!sapi_module.phpinfo_as_text) {
 			php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
 		} else {
 			php_info_print_table_row(2, "PHP Version", PHP_VERSION);
-		}	
+		}
+#endif
 		php_info_print_box_end();
 		php_info_print_table_start();
 		php_info_print_table_row(2, "System", php_uname );
diff -Nura php-5.0.4/ext/standard/syslog.c hardening-patch-5.0.4-0.4.1/ext/standard/syslog.c
--- php-5.0.4/ext/standard/syslog.c	2004-07-30 16:39:18.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/ext/standard/syslog.c	2005-08-04 12:06:45.000000000 +0200
@@ -42,6 +42,7 @@
  */
 PHP_MINIT_FUNCTION(syslog)
 {
+#if !HARDENING_PATCH
 	/* error levels */
 	REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
 	REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
@@ -97,7 +98,7 @@
 	/* AIX doesn't have LOG_PERROR */
 	REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
 #endif
-
+#endif
 	return SUCCESS;
 }
 /* }}} */
diff -Nura php-5.0.4/ext/varfilter/config.m4 hardening-patch-5.0.4-0.4.1/ext/varfilter/config.m4
--- php-5.0.4/ext/varfilter/config.m4	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/varfilter/config.m4	2005-08-04 12:06:45.000000000 +0200
@@ -0,0 +1,11 @@
+dnl
+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
+dnl
+
+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
+[  --disable-varfilter     Disable Hardening-Patch's variable filter], yes)
+
+if test "$PHP_VARFILTER" != "no"; then
+  AC_DEFINE(HAVE_VARFILTER, 1, [ ])
+  PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
+fi
diff -Nura php-5.0.4/ext/varfilter/CREDITS hardening-patch-5.0.4-0.4.1/ext/varfilter/CREDITS
--- php-5.0.4/ext/varfilter/CREDITS	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/varfilter/CREDITS	2005-08-04 12:06:45.000000000 +0200
@@ -0,0 +1,2 @@
+varfilter
+Stefan Esser
\ Kein Zeilenumbruch am Dateiende.
diff -Nura php-5.0.4/ext/varfilter/php_varfilter.h hardening-patch-5.0.4-0.4.1/ext/varfilter/php_varfilter.h
--- php-5.0.4/ext/varfilter/php_varfilter.h	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/varfilter/php_varfilter.h	2005-08-04 12:54:06.000000000 +0200
@@ -0,0 +1,111 @@
+/*
+  +----------------------------------------------------------------------+
+  | Hardened-PHP Project's varfilter extension                           |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2004-2005 Stefan Esser                                 |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | license@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author: Stefan Esser <sesser@hardened-php.net>                       |
+  +----------------------------------------------------------------------+
+
+  $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $ 
+*/
+
+#ifndef PHP_VARFILTER_H
+#define PHP_VARFILTER_H
+
+extern zend_module_entry varfilter_module_entry;
+#define phpext_varfilter_ptr &varfilter_module_entry
+
+#ifdef PHP_WIN32
+#define PHP_VARFILTER_API __declspec(dllexport)
+#else
+#define PHP_VARFILTER_API
+#endif
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#include "SAPI.h"
+
+#include "php_variables.h"
+
+
+PHP_MINIT_FUNCTION(varfilter);
+PHP_MSHUTDOWN_FUNCTION(varfilter);
+PHP_RINIT_FUNCTION(varfilter);
+PHP_RSHUTDOWN_FUNCTION(varfilter);
+PHP_MINFO_FUNCTION(varfilter);
+
+
+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
+/*	request variables */
+	long  max_request_variables;
+	long  cur_request_variables;
+	long  max_varname_length;
+	long  max_totalname_length;
+	long  max_value_length;
+	long  max_array_depth;
+	long  max_array_index_length;
+/*	cookie variables */
+	long  max_cookie_vars;
+	long  cur_cookie_vars;
+	long  max_cookie_name_length;
+	long  max_cookie_totalname_length;
+	long  max_cookie_value_length;
+	long  max_cookie_array_depth;
+	long  max_cookie_array_index_length;
+/*	get variables */
+	long  max_get_vars;
+	long  cur_get_vars;
+	long  max_get_name_length;
+	long  max_get_totalname_length;
+	long  max_get_value_length;
+	long  max_get_array_depth;
+	long  max_get_array_index_length;
+/*	post variables */
+	long  max_post_vars;
+	long  cur_post_vars;
+	long  max_post_name_length;
+	long  max_post_totalname_length;
+	long  max_post_value_length;
+	long  max_post_array_depth;
+	long  max_post_array_index_length;
+/*	fileupload */
+	long  max_uploads;
+	long  cur_uploads;
+	zend_bool  disallow_elf_files;
+	char *verification_script;
+	
+ZEND_END_MODULE_GLOBALS(varfilter)
+
+
+#ifdef ZTS
+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
+#else
+#define VARFILTER_G(v) (varfilter_globals.v)
+#endif
+
+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
+
+#endif	/* PHP_VARFILTER_H */
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff -Nura php-5.0.4/ext/varfilter/varfilter.c hardening-patch-5.0.4-0.4.1/ext/varfilter/varfilter.c
--- php-5.0.4/ext/varfilter/varfilter.c	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/ext/varfilter/varfilter.c	2005-08-04 12:54:06.000000000 +0200
@@ -0,0 +1,602 @@
+/*
+  +----------------------------------------------------------------------+
+  | Hardened-PHP Project's varfilter extension                           |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2004-2005 Stefan Esser                                 |
+  +----------------------------------------------------------------------+
+  | This source file is subject to version 2.02 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available at through the world-wide-web at                           |
+  | http://www.php.net/license/2_02.txt.                                 |
+  | If you did not receive a copy of the PHP license and are unable to   |
+  | obtain it through the world-wide-web, please send a note to          |
+  | license@php.net so we can mail you a copy immediately.               |
+  +----------------------------------------------------------------------+
+  | Author: Stefan Esser <sesser@hardened-php.net>                       |
+  +----------------------------------------------------------------------+
+
+  $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $ 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_varfilter.h"
+#include "hardening_patch.h"
+
+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
+
+/* True global resources - no need for thread safety here */
+static int le_varfilter;
+
+/* {{{ varfilter_module_entry
+ */
+zend_module_entry varfilter_module_entry = {
+#if ZEND_MODULE_API_NO >= 20010901
+	STANDARD_MODULE_HEADER,
+#endif
+	"varfilter",
+	NULL,
+	PHP_MINIT(varfilter),
+	PHP_MSHUTDOWN(varfilter),
+	PHP_RINIT(varfilter),		/* Replace with NULL if there's nothing to do at request start */
+	PHP_RSHUTDOWN(varfilter),	/* Replace with NULL if there's nothing to do at request end */
+	PHP_MINFO(varfilter),
+#if ZEND_MODULE_API_NO >= 20010901
+	"0.3.2", /* Replace with version number for your extension */
+#endif
+	STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_VARFILTER
+ZEND_GET_MODULE(varfilter)
+#endif
+
+/* {{{ PHP_INI
+ */
+PHP_INI_BEGIN()
+    /* for backward compatibility */
+    STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
+
+    STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
+
+    STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.cookie.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_index_length, zend_varfilter_globals, varfilter_globals)
+
+    STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.get.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_array_index_length, zend_varfilter_globals, varfilter_globals)
+
+    STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.post.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_array_index_length, zend_varfilter_globals, varfilter_globals)
+
+    STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
+    STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
+
+
+PHP_INI_END()
+/* }}} */
+
+/* {{{ php_varfilter_init_globals
+ */
+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
+{
+	varfilter_globals->max_request_variables = 200;
+	varfilter_globals->max_varname_length = 64;
+	varfilter_globals->max_value_length = 10000;
+	varfilter_globals->max_array_depth = 100;
+	varfilter_globals->max_totalname_length = 256;
+	varfilter_globals->max_array_index_length = 64;
+	
+	varfilter_globals->max_cookie_vars = 100;
+	varfilter_globals->max_cookie_name_length = 64;
+	varfilter_globals->max_cookie_totalname_length = 256;
+	varfilter_globals->max_cookie_value_length = 10000;
+	varfilter_globals->max_cookie_array_depth = 100;
+	varfilter_globals->max_cookie_array_index_length = 64;
+	
+	varfilter_globals->max_get_vars = 100;
+	varfilter_globals->max_get_name_length = 64;
+	varfilter_globals->max_get_totalname_length = 256;
+	varfilter_globals->max_get_value_length = 512;
+	varfilter_globals->max_get_array_depth = 50;
+	varfilter_globals->max_get_array_index_length = 64;
+	
+	varfilter_globals->max_post_vars = 200;
+	varfilter_globals->max_post_name_length = 64;
+	varfilter_globals->max_post_totalname_length = 256;
+	varfilter_globals->max_post_value_length = 65000;
+	varfilter_globals->max_post_array_depth = 100;
+	varfilter_globals->max_post_array_index_length = 64;
+
+	varfilter_globals->max_uploads = 25;
+	varfilter_globals->disallow_elf_files = 1;
+	varfilter_globals->verification_script = NULL;
+}
+/* }}} */
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+PHP_MINIT_FUNCTION(varfilter)
+{
+	ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
+	REGISTER_INI_ENTRIES();
+
+	sapi_register_input_filter(varfilter_input_filter);
+	sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
+	sapi_register_upload_content_filter(varfilter_upload_content_filter);
+	sapi_register_post_upload_filter(varfilter_post_upload_filter);
+	
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+PHP_MSHUTDOWN_FUNCTION(varfilter)
+{
+	UNREGISTER_INI_ENTRIES();
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request start */
+/* {{{ PHP_RINIT_FUNCTION
+ */
+PHP_RINIT_FUNCTION(varfilter)
+{
+	VARFILTER_G(cur_request_variables) = 0;
+	VARFILTER_G(cur_get_vars) = 0;
+	VARFILTER_G(cur_post_vars) = 0;
+	VARFILTER_G(cur_cookie_vars) = 0;
+	
+	VARFILTER_G(cur_uploads) = 0;
+	
+	return SUCCESS;
+}
+/* }}} */
+
+/* Remove if there's nothing to do at request end */
+/* {{{ PHP_RSHUTDOWN_FUNCTION
+ */
+PHP_RSHUTDOWN_FUNCTION(varfilter)
+{
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MINFO_FUNCTION
+ */
+PHP_MINFO_FUNCTION(varfilter)
+{
+	php_info_print_table_start();
+	php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
+	php_info_print_table_end();
+
+	DISPLAY_INI_ENTRIES();
+}
+/* }}} */
+
+/* {{{ normalize_varname
+ */
+static void normalize_varname(char *varname)
+{
+	char *s=varname, *index=NULL, *indexend=NULL, *p;
+	
+	/* overjump leading space */
+	while (*s == ' ') {
+		s++;
+	}
+	
+	/* and remove it */
+	if (s != varname) {
+		memmove(varname, s, strlen(s)+1);
+	}
+
+	for (p=varname; *p && *p != '['; p++) {
+		switch(*p) {
+			case ' ':
+			case '.':
+				*p='_';
+				break;
+		}
+	}
+
+	/* find index */
+	index = strchr(varname, '[');
+	if (index) {
+		index++;
+		s=index;
+	} else {
+		return;
+	}
+
+	/* done? */
+	while (index) {
+
+		while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
+			index++;
+		}
+		indexend = strchr(index, ']');
+		indexend = indexend ? indexend + 1 : index + strlen(index);
+		
+		if (s != index) {
+			memmove(s, index, strlen(index)+1);
+			s += indexend-index;
+		} else {
+			s = indexend;
+		}
+
+		if (*s == '[') {
+			s++;
+			index = s;
+		} else {
+			index = NULL;
+		}	
+	}
+	*s++='\0';
+}
+/* }}} */
+
+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
+ */
+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
+{
+	/* Drop this fileupload if the limit is reached */
+	if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
+		php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
+		return FAILURE;
+	}
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
+ */
+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
+{
+
+	if (VARFILTER_G(disallow_elf_files)) {
+
+		if (offset == 0 && buffer_len > 10) {
+			
+			if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
+				php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
+				return FAILURE;
+			}
+		}
+	
+	}
+
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
+ */
+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
+{
+	int retval = SUCCESS;
+
+	if (VARFILTER_G(verification_script)) {
+		char cmd[8192];
+		FILE *in;
+		int first=1;
+		
+		ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
+
+		if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
+			php_security_log(S_FILES, "unable to execute fileupload verification script - file dropped");
+			return FAILURE;
+		}
+		
+		retval = FAILURE;
+		
+		/* read and forget the result */
+		while (1) {
+			int readbytes = fread(cmd, 1, sizeof(cmd), in);
+			if (readbytes<=0) {
+				break;
+			}
+			if (first) {
+				retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
+				first = 0;
+			}
+		}
+		pclose(in);
+	}
+
+	if (retval != SUCCESS) {
+		php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
+		return FAILURE;
+	}
+
+	VARFILTER_G(cur_uploads)++;
+	return SUCCESS;
+}
+/* }}} */
+
+/* {{{ SAPI_INPUT_FILTER_FUNC
+ */
+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
+{
+	char *index, *prev_index = NULL, *copy_var;
+	unsigned int var_len, total_len, depth = 0, rv;
+
+	/* Drop this variable if the limit is reached */
+	if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
+		php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
+		return 0;
+	}
+	switch (arg) {
+	    case PARSE_GET:
+			if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
+				php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_COOKIE:
+			if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
+				php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_POST:
+			if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
+				php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	}
+	
+	
+	/* Drop this variable if it exceeds the value length limit */
+	if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
+		php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
+		return 0;
+	}
+	switch (arg) {
+	    case PARSE_GET:
+			if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
+				php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_COOKIE:
+			if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
+				php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_POST:
+			if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
+				php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	}
+	
+	/* Normalize the variable name */
+	normalize_varname(var);
+	
+	/* Find length of variable name */
+	index = strchr(var, '[');
+	total_len = strlen(var);
+	var_len = index ? index-var : total_len;
+	
+	/* Drop this variable if it exceeds the varname/total length limit */
+	if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
+		php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
+		return 0;
+	}
+	if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
+		php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
+		return 0;
+	}
+	switch (arg) {
+	    case PARSE_GET:
+			if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
+				php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
+				php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_COOKIE:
+			if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
+				php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
+				php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_POST:
+			if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
+				php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
+				php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	}
+	
+	/* Find out array depth */
+	while (index) {
+		unsigned int index_length;
+		
+		depth++;
+		index = strchr(index+1, '[');
+		
+		if (prev_index) {
+			index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
+			
+			if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
+				php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
+				return 0;
+			} 
+			switch (arg) {
+			    case PARSE_GET:
+					if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
+						php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
+						return 0;
+					} 
+					break;
+			    case PARSE_COOKIE:
+					if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
+						php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
+						return 0;
+					} 
+					break;
+			    case PARSE_POST:
+					if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
+						php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
+						return 0;
+					} 
+					break;
+			}
+			prev_index = index;
+		}
+		
+	}
+	
+	/* Drop this variable if it exceeds the array depth limit */
+	if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
+		php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
+		return 0;
+	}
+	switch (arg) {
+	    case PARSE_GET:
+			if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
+				php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_COOKIE:
+			if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
+				php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	    case PARSE_POST:
+			if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
+				php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
+				return 0;
+			}
+			break;
+	}
+	
+	/* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
+	/* This is to protect several silly scripts that do globalizing themself */
+	
+	switch (var_len) {
+	    case 18:
+		if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
+		break;
+	    case 17:
+		if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
+		break;
+	    case 16:
+		if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
+		if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
+		break;
+	    case 15:
+		if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
+		break;
+	    case 14:
+		if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
+		break;
+	    case 13:
+		if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
+		if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
+		break;
+	    case 8:
+		if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
+		if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
+		break;
+	    case 7:
+		if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
+		if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
+		if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
+		break;
+	    case 6:
+		if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
+		break;
+	    case 5:
+		if (memcmp(var, "_POST", 5)==0) goto protected_varname;
+		break;
+	    case 4:
+		if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
+		if (memcmp(var, "_GET", 4)==0) goto protected_varname;
+		break;
+	}
+
+	/* Okay let PHP register this variable */
+	VARFILTER_G(cur_request_variables)++;
+	switch (arg) {
+	    case PARSE_GET:
+			VARFILTER_G(cur_get_vars)++;
+			break;
+	    case PARSE_COOKIE:
+			VARFILTER_G(cur_cookie_vars)++;
+			break;
+	    case PARSE_POST:
+			VARFILTER_G(cur_post_vars)++;
+			break;
+	}
+	
+	if (new_val_len) {
+		*new_val_len = val_len;
+	}
+
+	return 1;
+protected_varname:
+	php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
+	return 0;	
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
+
+
diff -Nura php-5.0.4/main/fopen_wrappers.c hardening-patch-5.0.4-0.4.1/main/fopen_wrappers.c
--- php-5.0.4/main/fopen_wrappers.c	2005-03-11 07:55:22.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/fopen_wrappers.c	2005-08-04 12:06:45.000000000 +0200
@@ -163,6 +163,21 @@
 		char *pathbuf;
 		char *ptr;
 		char *end;
+		char path_copy[MAXPATHLEN];
+		int path_len;
+
+		/* Special case path ends with a trailing slash */
+		path_len = strlen(path);
+		if (path_len >= MAXPATHLEN) {
+			errno = EPERM; /* we deny permission to open it */
+			return -1;
+		}
+		if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
+			memcpy(path_copy, path, path_len+1);
+			while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
+			path_copy[path_len] = '\0';
+			path = (const char *)&path_copy;
+		}
 
 		pathbuf = estrdup(PG(open_basedir));
 
diff -Nura php-5.0.4/main/hardened_globals.h hardening-patch-5.0.4-0.4.1/main/hardened_globals.h
--- php-5.0.4/main/hardened_globals.h	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/hardened_globals.h	2005-08-04 18:22:49.000000000 +0200
@@ -0,0 +1,60 @@
+/*
+   +----------------------------------------------------------------------+
+   | Hardening-Patch for PHP                                              |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 2004-2005 Stefan Esser                                 |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Stefan Esser <sesser@hardened-php.net>                       |
+   +----------------------------------------------------------------------+
+ */
+
+#ifndef HARDENED_GLOBALS_H
+#define HARDENED_GLOBALS_H
+
+typedef struct _hardened_globals hardened_globals_struct;
+
+#ifdef ZTS
+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
+extern int hardened_globals_id;
+#else
+# define HG(v) (hardened_globals.v)
+extern struct _hardened_globals hardened_globals;
+#endif
+
+
+struct _hardened_globals {
+#if HARDENING_PATCH_MM_PROTECT
+	unsigned int canary_1;
+	unsigned int canary_2;
+#endif
+#if HARDENING_PATCH_LL_PROTECT
+	unsigned int canary_3;
+	unsigned int canary_4;
+	unsigned int ll_canary_inited;
+#endif
+	zend_bool hphp_sql_bailout_on_error;
+	zend_bool hphp_multiheader;
+	HashTable *eval_whitelist;
+	HashTable *eval_blacklist;
+	HashTable *func_whitelist;
+	HashTable *func_blacklist;
+	unsigned int dummy;
+};
+
+
+#endif /* HARDENED_GLOBALS_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff -Nura php-5.0.4/main/hardening_patch.c hardening-patch-5.0.4-0.4.1/main/hardening_patch.c
--- php-5.0.4/main/hardening_patch.c	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/hardening_patch.c	2005-08-04 14:19:00.000000000 +0200
@@ -0,0 +1,322 @@
+/*
+   +----------------------------------------------------------------------+
+   | Hardening Patch for PHP                                              |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 2004-2005 Stefan Esser                                 |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Stefan Esser <sesser@hardened-php.net>                       |
+   +----------------------------------------------------------------------+
+ */
+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
+
+#include "php.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include "SAPI.h"
+#include "php_globals.h"
+
+#if HARDENING_PATCH
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
+#undef AF_UNIX
+#endif
+
+#if defined(AF_UNIX)
+#include <sys/un.h>
+#endif
+
+#define SYSLOG_PATH  "/dev/log"
+
+#include "snprintf.h"
+
+#include "hardening_patch.h"
+
+#ifdef ZTS
+#include "hardened_globals.h"
+int hardened_globals_id;
+#else
+struct _hardened_globals hardened_globals;
+#endif
+
+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
+{
+	memset(hardened_globals, 0, sizeof(*hardened_globals));
+}
+
+
+PHPAPI void hardened_startup()
+{
+#ifdef ZTS
+	ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
+#else
+	hardened_globals_ctor(&hardened_globals TSRMLS_CC);
+#endif
+}
+
+char *loglevel2string(int loglevel)
+{
+	switch (loglevel) {
+	    case S_FILES:
+		return "FILES";
+	    case S_INCLUDE:
+		return "INCLUDE";
+	    case S_MEMORY:
+		return "MEMORY";
+	    case S_MISC:
+		return "MISC";
+	    case S_SQL:
+		return "SQL";
+	    case S_EXECUTOR:
+		return "EXECUTOR";
+	    case S_VARS:
+		return "VARS";
+	    default:
+		return "UNKNOWN";    
+	}
+}
+
+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
+{
+#if defined(AF_UNIX)
+	int s, r, i=0;
+	struct sockaddr_un saun;
+	char buf[4096+64];
+	char error[4096+100];
+	char *ip_address;
+	char *fname;
+	int lineno;
+	va_list ap;
+	TSRMLS_FETCH();
+	
+	if (EG(hphp_log_use_x_forwarded_for)) {
+		ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
+		if (ip_address == NULL) {
+			ip_address = "X-FORWARDED-FOR not set";
+		}
+	} else {
+		ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
+		if (ip_address == NULL) {
+			ip_address = "REMOTE_ADDR not set";
+		}
+	}
+	
+	
+	va_start(ap, fmt);
+	ap_php_vsnprintf(error, sizeof(error), fmt, ap);
+	va_end(ap);
+	while (error[i]) {
+		if (error[i] < 32) error[i] = '.';
+		i++;
+	}
+	
+	if (zend_is_executing(TSRMLS_C)) {
+		lineno = zend_get_executed_lineno(TSRMLS_C);
+		fname = zend_get_executed_filename(TSRMLS_C);
+		ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
+	} else {
+		fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
+		if (fname==NULL) {
+			fname = "unknown";
+		}
+		ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
+	}
+			
+	/* Syslog-Logging disabled? */
+	if ((EG(hphp_log_syslog) & loglevel)==0) {
+		goto log_sapi;
+	}	
+	
+	ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
+
+	s = socket(AF_UNIX, SOCK_DGRAM, 0);
+	if (s == -1) {
+		goto log_sapi;
+	}
+	
+	memset(&saun, 0, sizeof(saun));
+	saun.sun_family = AF_UNIX;
+	strcpy(saun.sun_path, SYSLOG_PATH);
+	/*saun.sun_len = sizeof(saun);*/
+	
+	r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
+	if (r) {
+		close(s);
+    		s = socket(AF_UNIX, SOCK_STREAM, 0);
+		if (s == -1) {
+			goto log_sapi;
+		}
+	
+		memset(&saun, 0, sizeof(saun));
+		saun.sun_family = AF_UNIX;
+		strcpy(saun.sun_path, SYSLOG_PATH);
+		/*saun.sun_len = sizeof(saun);*/
+
+		r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
+		if (r) { 
+			close(s);
+			goto log_sapi;
+		}
+	}
+	send(s, error, strlen(error), 0);
+	
+	close(s);
+
+log_sapi:
+	/* SAPI Logging activated? */
+	if ((EG(hphp_log_syslog) & loglevel)!=0) {
+		sapi_module.log_message(buf);
+	}
+
+log_script:
+	/* script logging activaed? */
+	if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
+		char cmd[8192], *cmdpos, *bufpos;
+		FILE *in;
+		int space;
+		
+		ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
+		space = sizeof(cmd) - strlen(cmd);
+		cmdpos = cmd + strlen(cmd);
+		bufpos = buf;
+		if (space <= 1) return;
+		while (space > 2 && *bufpos) {
+			if (*bufpos == '\'') {
+				if (space<=5) break;
+				*cmdpos++ = '\'';
+				*cmdpos++ = '\\';
+				*cmdpos++ = '\'';
+				*cmdpos++ = '\'';
+				bufpos++;
+				space-=4;
+			} else {
+				*cmdpos++ = *bufpos++;
+				space--;
+			}
+		}
+		*cmdpos++ = '\'';
+		*cmdpos = 0;
+		
+		if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
+			return;
+		}
+		/* read and forget the result */
+		while (1) {
+			int readbytes = fread(cmd, 1, sizeof(cmd), in);
+			if (readbytes<=0) {
+				break;
+			}
+		}
+		pclose(in);
+	}
+
+#endif
+}
+#endif
+
+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
+
+/* will be replaced later with more compatible method */
+PHPAPI unsigned int php_canary()
+{
+	time_t t;
+	unsigned int canary;
+	int fd;
+	
+	fd = open("/dev/urandom", 0);
+	if (fd != -1) {
+		int r = read(fd, &canary, sizeof(canary));
+		close(fd);
+		if (r == sizeof(canary)) {
+			return (canary);
+		}
+	}
+	/* not good but we never want to do this */
+	time(&t);
+	canary = *(unsigned int *)&t + getpid() << 16;
+	return (canary);
+}
+#endif
+
+#if HARDENING_PATCH_INC_PROTECT
+
+PHPAPI int php_is_valid_include(zval *z)
+{
+	char *filename;
+	int len, i;
+	TSRMLS_FETCH();
+	
+	/* must be of type string */
+	if (z->type != IS_STRING || z->value.str.val == NULL) {
+		return (0);
+	}
+	
+	/* short cut */
+	filename = z->value.str.val;
+	len = z->value.str.len;
+	
+	/* 1. must be shorter than MAXPATHLEN */
+	if (len > MAXPATHLEN) {
+		char *fname = estrndup(filename, len);
+		for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
+		php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
+		efree(fname);
+		return (0);
+	}
+	
+	/* 2. must not be cutted */
+	if (len != strlen(filename)) {
+		char *fname = estrndup(filename, len);
+		for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
+		php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
+		efree(fname);
+		return (0);
+	}
+	
+	/* 3. must not be a URL */
+	if (strstr(filename, "://")) {
+		char *fname = estrndup(filename, len);
+		for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
+		php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
+		efree(fname);
+		return (0);
+	}
+	
+	/* 4. must not be an uploaded file */
+	if (SG(rfc1867_uploaded_files)) {
+		if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
+			php_security_log(S_INCLUDE, "Include filename is an uploaded file");
+			return (0);
+		}
+	}
+	
+	/* passed all tests */
+	return (1);
+}
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */
diff -Nura php-5.0.4/main/hardening_patch.h hardening-patch-5.0.4-0.4.1/main/hardening_patch.h
--- php-5.0.4/main/hardening_patch.h	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/hardening_patch.h	2005-08-06 09:40:46.000000000 +0200
@@ -0,0 +1,46 @@
+/*
+   +----------------------------------------------------------------------+
+   | Hardening Patch for PHP                                              |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 2004-2005 Stefan Esser                                 |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Stefan Esser <sesser@hardened-php.net>                       |
+   +----------------------------------------------------------------------+
+ */
+
+#ifndef HARDENING_PATCH_H
+#define HARDENING_PATCH_H
+
+#include "zend.h"
+
+#if HARDENING_PATCH
+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
+PHPAPI void hardened_startup();
+#define HARDENING_PATCH_VERSION "0.4.1"
+
+#endif
+
+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
+PHPAPI unsigned int php_canary();
+#endif
+
+#if HARDENING_PATCH_INC_PROTECT
+PHPAPI int php_is_valid_include(zval *z);
+#endif
+
+#endif /* HARDENING_PATCH_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff -Nura php-5.0.4/main/hardening_patch.m4 hardening-patch-5.0.4-0.4.1/main/hardening_patch.m4
--- php-5.0.4/main/hardening_patch.m4	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/hardening_patch.m4	2005-08-04 12:06:45.000000000 +0200
@@ -0,0 +1,95 @@
+dnl
+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
+dnl
+dnl This file contains Hardening Patch for PHP specific autoconf functions.
+dnl
+
+AC_ARG_ENABLE(hardening-patch-mm-protect,
+[  --disable-hardening-patch-mm-protect    Disable the Memory Manager protection.],[
+  DO_HARDENING_PATCH_MM_PROTECT=$enableval
+],[
+  DO_HARDENING_PATCH_MM_PROTECT=yes
+])
+
+AC_ARG_ENABLE(hardening-patch-ll-protect,
+[  --disable-hardening-patch-ll-protect    Disable the Linked List protection.],[
+  DO_HARDENING_PATCH_LL_PROTECT=$enableval
+],[
+  DO_HARDENING_PATCH_LL_PROTECT=yes
+])
+
+AC_ARG_ENABLE(hardening-patch-inc-protect,
+[  --disable-hardening-patch-inc-protect   Disable include/require protection.],[
+  DO_HARDENING_PATCH_INC_PROTECT=$enableval
+],[
+  DO_HARDENING_PATCH_INC_PROTECT=yes
+])
+
+AC_ARG_ENABLE(hardening-patch-fmt-protect,
+[  --disable-hardening-patch-fmt-protect   Disable format string protection.],[
+  DO_HARDENING_PATCH_FMT_PROTECT=$enableval
+],[
+  DO_HARDENING_PATCH_FMT_PROTECT=yes
+])
+
+AC_ARG_ENABLE(hardening-patch-hash-protect,
+[  --disable-hardening-patch-hash-protect  Disable HashTable destructor protection.],[
+  DO_HARDENING_PATCH_HASH_PROTECT=$enableval
+],[
+  DO_HARDENING_PATCH_HASH_PROTECT=yes
+])
+
+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
+
+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
+
+AC_MSG_CHECKING(whether to protect include/require statements)
+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
+
+AC_MSG_CHECKING(whether to protect PHP Format String functions)
+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
+
+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
+
+
+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
+
+
+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
+dnl  AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
+  AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
+else
+  AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
+fi
+
+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
+dnl    AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
+  AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
+else
+  AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
+fi
+
+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
+dnl    AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
+  AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
+else
+  AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
+fi
+
+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
+dnl    AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
+  AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
+else
+  AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
+fi
+
+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
+dnl    AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
+  AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
+else
+  AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
+fi
+
diff -Nura php-5.0.4/main/main.c hardening-patch-5.0.4-0.4.1/main/main.c
--- php-5.0.4/main/main.c	2005-03-24 02:11:35.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/main.c	2005-08-04 12:06:45.000000000 +0200
@@ -92,6 +92,10 @@
 
 #include "SAPI.h"
 #include "rfc1867.h"
+#if HARDENING_PATCH
+#include "hardened_globals.h"
+#endif
+
 /* }}} */
 
 #ifndef ZTS
@@ -116,10 +120,33 @@
  */
 static PHP_INI_MH(OnChangeMemoryLimit)
 {
+#if HARDENING_PATCH
+	long orig_memory_limit;
+	
+	if (entry->modified) {
+		orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);	
+	} else {
+		orig_memory_limit = 1<<30;
+	}
+	if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
+		orig_memory_limit = 1<<30;
+	}
+#endif
 	if (new_value) {
 		PG(memory_limit) = zend_atoi(new_value, new_value_length);
+#if HARDENING_PATCH
+		if (PG(memory_limit) > orig_memory_limit) {
+			PG(memory_limit) = orig_memory_limit;
+			php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
+			return FAILURE;
+		}
+#endif		
 	} else {
+#if HARDENING_PATCH
+		PG(memory_limit) = orig_memory_limit;
+#else
 		PG(memory_limit) = 1<<30;		/* effectively, no limit */
+#endif
 	}
 	return zend_set_memory_limit(PG(memory_limit));
 }
@@ -1313,6 +1340,10 @@
 	tsrm_ls = ts_resource(0);
 #endif
 
+#if HARDENING_PATCH
+	hardened_startup();
+#endif
+
 	module_shutdown = 0;
 	module_startup = 1;
 	sapi_initialize_empty_request(TSRMLS_C);
@@ -1326,6 +1357,12 @@
 
 	php_output_startup();
 
+#if HARDENING_PATCH_INC_PROTECT
+	zuf.is_valid_include = php_is_valid_include;
+#endif
+#if HARDENING_PATCH
+	zuf.security_log_function = php_security_log;
+#endif
 	zuf.error_function = php_error_cb;
 	zuf.printf_function = php_printf;
 	zuf.write_function = php_body_write_wrapper;
@@ -1429,6 +1466,10 @@
 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR, sizeof(PHP_CONFIG_FILE_SCAN_DIR)-1, CONST_PERSISTENT | CONST_CS);
 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
+#if HARDENING_PATCH
+	REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
+#endif
 	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
 	php_output_register_constants(TSRMLS_C);
 	php_rfc1867_register_constants(TSRMLS_C);
diff -Nura php-5.0.4/main/php_config.h.in hardening-patch-5.0.4-0.4.1/main/php_config.h.in
--- php-5.0.4/main/php_config.h.in	2005-04-03 11:42:53.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/main/php_config.h.in	2005-08-04 12:06:45.000000000 +0200
@@ -746,6 +746,39 @@
 /* hardcode for each of the cross compiler host */
 #undef PHP_UNAME
 
+/* Hardening-Patch for PHP */
+#undef HARDENING_PATCH
+
+/* Memory Manager Protection */
+#undef HARDENING_PATCH_MM_PROTECT
+
+/* Memory Manager Protection */
+#undef HARDENING_PATCH_MM_PROTECT
+
+/* Linked List Protection */
+#undef HARDENING_PATCH_LL_PROTECT
+
+/* Linked List Protection */
+#undef HARDENING_PATCH_LL_PROTECT
+
+/* Include/Require Protection */
+#undef HARDENING_PATCH_INC_PROTECT
+
+/* Include/Require Protection */
+#undef HARDENING_PATCH_INC_PROTECT
+
+/* Fmt String Protection */
+#undef HARDENING_PATCH_FMT_PROTECT
+
+/* Fmt String Protection */
+#undef HARDENING_PATCH_FMT_PROTECT
+
+/* HashTable DTOR Protection */
+#undef HARDENING_PATCH_HASH_PROTECT
+
+/* HashTable DTOR Protection */
+#undef HARDENING_PATCH_HASH_PROTECT
+
 /* Whether you have AOLserver */
 #undef HAVE_AOLSERVER
 
@@ -1077,6 +1110,12 @@
 /* Define if you have the getaddrinfo function */
 #undef HAVE_GETADDRINFO
 
+/* Whether realpath is broken */
+#undef PHP_BROKEN_REALPATH
+
+/* Whether realpath is broken */
+#undef PHP_BROKEN_REALPATH
+
 /* Whether system headers declare timezone */
 #undef HAVE_DECLARED_TIMEZONE
 
diff -Nura php-5.0.4/main/php.h hardening-patch-5.0.4-0.4.1/main/php.h
--- php-5.0.4/main/php.h	2005-03-14 10:41:39.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/php.h	2005-08-04 13:04:21.000000000 +0200
@@ -35,11 +35,19 @@
 #include "zend_qsort.h"
 #include "php_compat.h"
 
+
 #include "zend_API.h"
 
 #undef sprintf
 #define sprintf php_sprintf
 
+#if HARDENING_PATCH
+#if HAVE_REALPATH
+#undef realpath
+#define realpath php_realpath
+#endif
+#endif
+
 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
 #undef PHP_DEBUG
 #define PHP_DEBUG ZEND_DEBUG
@@ -341,6 +349,7 @@
 #define PHP_FUNCTION			ZEND_FUNCTION
 #define PHP_METHOD  			ZEND_METHOD
 
+#define PHP_STATIC_FE	ZEND_STATIC_FE
 #define PHP_NAMED_FE	ZEND_NAMED_FE
 #define PHP_FE			ZEND_FE
 #define PHP_FALIAS		ZEND_FALIAS
@@ -446,6 +455,10 @@
 #endif
 #endif /* !XtOffsetOf */
 
+#if HARDENING_PATCH
+#include "hardening_patch.h"
+#endif
+
 #endif
 
 /*
diff -Nura php-5.0.4/main/php_variables.c hardening-patch-5.0.4-0.4.1/main/php_variables.c
--- php-5.0.4/main/php_variables.c	2005-02-17 05:46:10.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/php_variables.c	2005-08-04 12:06:45.000000000 +0200
@@ -493,7 +493,7 @@
  */
 static inline void php_register_server_variables(TSRMLS_D)
 {
-	zval *array_ptr=NULL;
+	zval *array_ptr=NULL, *vptr;
 	/* turn off magic_quotes while importing server variables */
 	int magic_quotes_gpc = PG(magic_quotes_gpc);
 
@@ -506,6 +506,16 @@
 	/* Server variables */
 	if (sapi_module.register_server_variables) {
 		sapi_module.register_server_variables(array_ptr TSRMLS_CC);
+		if (zend_hash_find(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), (void **)&vptr)==SUCCESS) {
+			char *str;
+			if (vptr->type != IS_STRING) {
+				str = "Array";
+			} else {
+				str = vptr->value.str.val;
+			}
+			php_security_log(S_VARS, "Attacker tried to overwrite HTTP_RAW_POST_DATA with '%s' through a HTTP header", str);
+			zend_hash_del(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"));
+		}
 	}
 
 	/* PHP Authentication support */
diff -Nura php-5.0.4/main/rfc1867.c hardening-patch-5.0.4-0.4.1/main/rfc1867.c
--- php-5.0.4/main/rfc1867.c	2005-02-15 01:26:35.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/rfc1867.c	2005-08-04 12:06:45.000000000 +0200
@@ -131,6 +131,7 @@
 #define UPLOAD_ERROR_C    3  /* Partially uploaded */
 #define UPLOAD_ERROR_D    4  /* No file uploaded */
 #define UPLOAD_ERROR_E    6  /* Missing /tmp or similar directory */
+#define UPLOAD_ERROR_F    7  /* Filter forbids upload */
 
 void php_rfc1867_register_constants(TSRMLS_D)
 {
@@ -140,6 +141,7 @@
 	REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_PARTIAL",    UPLOAD_ERROR_C,  CONST_CS | CONST_PERSISTENT);
 	REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE",    UPLOAD_ERROR_D,  CONST_CS | CONST_PERSISTENT);
 	REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E,  CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER",     UPLOAD_ERROR_F,  CONST_CS | CONST_PERSISTENT);
 }
 
 static void normalize_protected_variable(char *varname TSRMLS_DC)
@@ -849,6 +851,7 @@
 		char buff[FILLUNIT];
 		char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
 		int blen=0, wlen=0;
+		unsigned long offset;
 
 		zend_llist_clean(&header);
 
@@ -988,6 +991,11 @@
 				cancel_upload = UPLOAD_ERROR_D;
 			}
 
+			if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
+				cancel_upload = UPLOAD_ERROR_F;
+			}
+
+			offset = 0;
 			while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff) TSRMLS_CC)))
 			{
 				if (PG(upload_max_filesize) > 0 && total_bytes > PG(upload_max_filesize)) {
@@ -1001,6 +1009,11 @@
 #endif
 					cancel_upload = UPLOAD_ERROR_B;
 				} else if (blen > 0) {
+				
+					if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
+						cancel_upload = UPLOAD_ERROR_F;
+					}
+			
 					wlen = fwrite(buff, 1, blen, fp);
 			
 					if (wlen < blen) {
@@ -1024,6 +1037,10 @@
 			}
 #endif		
 
+			if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
+				cancel_upload = UPLOAD_ERROR_F;
+			}
+
 			if (cancel_upload) {
 				if (temp_filename) {
 					if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
diff -Nura php-5.0.4/main/SAPI.c hardening-patch-5.0.4-0.4.1/main/SAPI.c
--- php-5.0.4/main/SAPI.c	2005-02-22 15:46:15.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/SAPI.c	2005-08-04 12:06:45.000000000 +0200
@@ -821,6 +821,30 @@
 	zend_hash_del(&known_post_content_types, post_entry->content_type, post_entry->content_type_len+1);
 }
 
+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC))
+{
+	sapi_module.input_filter = input_filter;
+	return SUCCESS;
+}
+
+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
+{
+	sapi_module.pre_upload_filter = pre_upload_filter;
+	return SUCCESS;
+}
+
+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC))
+{
+	sapi_module.upload_content_filter = upload_content_filter;
+	return SUCCESS;
+}
+
+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
+{
+	sapi_module.post_upload_filter = post_upload_filter;
+	return SUCCESS;
+}
+
 
 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
 {
@@ -835,11 +859,6 @@
 	return SUCCESS;
 }
 
-SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC))
-{
-	sapi_module.input_filter = input_filter;
-	return SUCCESS;
-}
 
 SAPI_API int sapi_flush(TSRMLS_D)
 {
diff -Nura php-5.0.4/main/SAPI.h hardening-patch-5.0.4-0.4.1/main/SAPI.h
--- php-5.0.4/main/SAPI.h	2004-01-08 18:33:04.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/SAPI.h	2005-08-04 12:06:45.000000000 +0200
@@ -103,9 +103,10 @@
 	char *current_user;
 	int current_user_length;
 
-    /* this is necessary for CLI module */
-    int argc;
-    char **argv;
+	/* this is necessary for CLI module */
+	int argc;
+	char **argv;
+	
 } sapi_request_info;
 
 
@@ -183,6 +184,10 @@
 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
 SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC));
 
+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC));
+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
+
 SAPI_API int sapi_flush(TSRMLS_D);
 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);
@@ -245,6 +250,10 @@
 	int (*get_target_gid)(gid_t * TSRMLS_DC);
 
 	unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
+
+	unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
+	unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
+	unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
 	
 	void (*ini_defaults)(HashTable *configuration_hash);
 	int phpinfo_as_text;
@@ -270,7 +279,11 @@
 
 #define SAPI_DEFAULT_MIMETYPE		"text/html"
 #define SAPI_DEFAULT_CHARSET		""
+#if HARDENING_PATCH
+#define SAPI_PHP_VERSION_HEADER		"X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
+#else
 #define SAPI_PHP_VERSION_HEADER		"X-Powered-By: PHP/" PHP_VERSION
+#endif
 
 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
@@ -278,6 +291,10 @@
 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
 #define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC)
 
+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
+#define SAPI_UPLOAD_CONTENT_FILTER_FUNC(upload_content_filter) unsigned int upload_content_filter(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC)
+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
+
 BEGIN_EXTERN_C()
 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
diff -Nura php-5.0.4/main/snprintf.c hardening-patch-5.0.4-0.4.1/main/snprintf.c
--- php-5.0.4/main/snprintf.c	2004-11-16 00:14:40.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/main/snprintf.c	2005-08-04 12:06:45.000000000 +0200
@@ -1013,7 +1013,11 @@
 
 
 				case 'n':
+#if HARDENING_PATCH_FMT_PROTECT
+					php_security_log(S_MISC, "'n' specifier within format string");
+#else
 					*(va_arg(ap, int *)) = cc;
+#endif
 					break;
 
 					/*
diff -Nura php-5.0.4/main/spprintf.c hardening-patch-5.0.4-0.4.1/main/spprintf.c
--- php-5.0.4/main/spprintf.c	2004-04-16 01:04:49.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/main/spprintf.c	2005-08-04 12:06:45.000000000 +0200
@@ -630,7 +630,11 @@
 
 
 				case 'n':
+#if HARDENING_PATCH_FMT_PROTECT
+					php_security_log(S_MISC, "'n' specifier within format string");
+#else
 					*(va_arg(ap, int *)) = xbuf->len;
+#endif
 					break;
 
 					/*
diff -Nura php-5.0.4/pear/go-pear-list.php hardening-patch-5.0.4-0.4.1/pear/go-pear-list.php
--- php-5.0.4/pear/go-pear-list.php	2005-03-18 02:59:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/pear/go-pear-list.php	2005-08-04 12:06:45.000000000 +0200
@@ -8,7 +8,7 @@
 $packages  = array(
 // required packages for the installer
 "PEAR"                  =>    "1.3.5",
-"XML_RPC"               =>    "1.2.2",
+"XML_RPC"               =>    "1.3.1",
 "Console_Getopt"        =>    "1.2",
 "Archive_Tar"           =>    "1.3.1",
 
diff -Nura php-5.0.4/pear/packages/XML_RPC-1.2.2.tar hardening-patch-5.0.4-0.4.1/pear/packages/XML_RPC-1.2.2.tar
--- php-5.0.4/pear/packages/XML_RPC-1.2.2.tar	2005-03-28 19:05:50.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/pear/packages/XML_RPC-1.2.2.tar	1970-01-01 01:00:00.000000000 +0100
@@ -1,3393 +0,0 @@
-package2.xml100666      0      0       24326 10213112551   6327 <?xml version="1.0"?>
-<package packagerversion="1.4.0a1" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0     http://pear.php.net/dtd/tasks-1.0.xsd     http://pear.php.net/dtd/package-2.0     http://pear.php.net/dtd/package-2.0.xsd">
- <name>XML_RPC</name>
- <channel>pear.php.net</channel>
- <summary>PHP implementation of the XML-RPC protocol</summary>
- <description>A PEAR-ified version of Useful Inc&apos;s XML-RPC for PHP.
-
-It has support for HTTP/HTTPS transport, proxies and authentication.</description>
- <lead>
-  <name>Stig Bakken</name>
-  <user>ssb</user>
-  <email>stig@php.net</email>
-  <active>no</active>
- </lead>
- <lead>
-  <name>Daniel Convissor</name>
-  <user>danielc</user>
-  <email>danielc@php.net</email>
-  <active>yes</active>
- </lead>
- <date>2005-03-07</date>
- <time>12:54:49</time>
- <version>
-  <release>1.2.2</release>
-  <api>1.2.0</api>
- </version>
- <stability>
-  <release>stable</release>
-  <api>stable</api>
- </stability>
- <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
- <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec.  Bug 3679.</notes>
- <contents>
-  <dir name="/">
-   <file md5sum="9aca4434f486b517a75c7f2878fb1e9c" name="tests/protoport.php" role="test">
-    <tasks:replace from="@package_version@" to="version" type="package-info" />
-   </file>
-   <file md5sum="49639b76a2296777a1dfa076ae41024a" name="tests/test_Dump.php" role="test">
-    <tasks:replace from="@package_version@" to="version" type="package-info" />
-   </file>
-   <file baseinstalldir="XML/RPC" md5sum="2fb141b1f8927ef27ab0c222f2117d77" name="Dump.php" role="php">
-    <tasks:replace from="@package_version@" to="version" type="package-info" />
-   </file>
-   <file baseinstalldir="XML" md5sum="fbfa3c674175786cc95893cc5192d910" name="RPC.php" role="php">
-    <tasks:replace from="@package_version@" to="version" type="package-info" />
-   </file>
-   <file baseinstalldir="XML/RPC" md5sum="6fc2498def65f09d4ae535fa5f987f62" name="Server.php" role="php">
-    <tasks:replace from="@package_version@" to="version" type="package-info" />
-   </file>
-  </dir>
- </contents>
- <compatible>
-  <name>PEAR</name>
-  <channel>pear.php.net</channel>
-  <min>1.4.0a1</min>
-  <max>1.4.0a4</max>
- </compatible>
- <dependencies>
-  <required>
-   <php>
-    <min>4.2.0</min>
-    <max>6.0.0</max>
-   </php>
-   <pearinstaller>
-    <min>1.4.0a1</min>
-   </pearinstaller>
-  </required>
- </dependencies>
- <phprelease />
- <changelog>
-  <release>
-   <version>
-    <release>1.2.1</release>
-    <api>1.2.0</api>
-   </version>
-   <stability>
-    <release>stable</release>
-    <api>stable</api>
-   </stability>
-   <date>2005-03-01</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* Add isset() check before examining the dispatch map.  Bug 3658.</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0</release>
-    <api>1.2.0</api>
-   </version>
-   <stability>
-    <release>stable</release>
-    <api>stable</api>
-   </stability>
-   <date>2005-02-27</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* Provide the &quot;stable&quot; release.
-* Add package2.xml for compatibility with PEAR 1.4.0.
-* For changes since 1.1.0, see the changelogs for the various RC releases.</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0RC7</release>
-    <api>1.2.0RC7</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2005-02-22</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* Add the setSendEncoding() method and $send_encoding
-  property to XML_RPC_Message.  Request 3537.
-* Allow class methods to be mapped using either syntax:
-     &apos;function&apos; =&gt; &apos;hello::sayHello&apos;,
-     or
-     &apos;function&apos; =&gt; array(&apos;hello&apos;, &apos;sayhello&apos;),
-  Bug 3363.
-* Use 8192 instead of 32768 for bytes in fread()
-  in parseResponseFile().  Bug 3340.</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0RC6</release>
-    <api>1.2.0RC6</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2005-01-25</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* Don&apos;t put the protocol in the Host field of the POST data.  (danielc)</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0RC5</release>
-    <api>1.2.0RC5</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2005-01-24</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* If $port is 443 but a protocol isn&apos;t specified in $server, assume ssl:// is the protocol.</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0RC4</release>
-    <api>1.2.0RC4</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2005-01-24</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* When a connection attempt fails, have the method return 0.  (danielc)
-* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor.  (danielc)
-* Add tests for setting the client properties.  (danielc)
-* Remove $GLOBALS[&apos;XML_RPC_twoslash&apos;] since it&apos;s not used.  (danielc)
-* Bundle the tests with the package.  (danielc)</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0RC3</release>
-    <api>1.2.0RC3</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2005-01-19</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* ssl uses port 443, not 445.</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0RC2</release>
-    <api>1.2.0RC2</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2005-01-11</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* Handle ssl:// in the $server string.  (danielc)
-* Also default to port 445 for ssl:// requests as well.  (danielc)
-* Enhance debugging in the server.  (danielc)</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.2.0RC1</release>
-    <api>1.2.0RC1</api>
-   </version>
-   <stability>
-    <release>beta</release>
-    <api>beta</api>
-   </stability>
-   <date>2004-12-30</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* Make things work with SSL.  Bug 2489.  (nkukard lbsd net)
-* Allow array function callbacks (Matt Kane)
-* Some minor speed-ups (Matt Kane)
-* Add Dump.php to the package (Christian Weiske)
-* Replace all line endings with \r\n.  Had only done replacements on \n.  Bug 2521.  (danielc)
-* Silence fsockopen() errors.  Bug 1714.  (danielc)
-* Encode empty arrays as an array. Bug 1493.  (danielc)
-* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode().  Bug 1819.  (danielc)
-* Speed up check for enumerated arrays in XML_RPC_Encode().  (danielc)
-* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()&apos;ing error messages.  (danielc)
-* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded.  (danielc)
-* Allow raiseError() to be called statically.  (danielc)
-* Stop double escaping of character entities.  Bug 987.  (danielc)
-  NOTICE: the following have been removed:
-    * XML_RPC_dh()
-    * $GLOBALS[&apos;XML_RPC_entities&apos;]
-    * XML_RPC_entity_decode()
-    * XML_RPC_lookup_entity()
-* Determine the XML&apos;s encoding via the encoding attribute in the XML declaration.  Bug 52.  (danielc)</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.1.0</release>
-    <api>1.1.0</api>
-   </version>
-   <stability>
-    <release>stable</release>
-    <api>stable</api>
-   </stability>
-   <date>2004-03-15</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
-* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
-* Remove &quot;require_once &apos;PEAR.php&apos;&quot;, include only when needed to raise an error
-* Replace echo and error_log() with raiseError() (mroch)
-* Make all classes extend XML_RPC_Base, which will handle common functions  (mroch)
-* be tolerant of junk after methodResponse (Luca Mariano, mroch)
-* Silent notice even in the error log (pierre)
-* fix include of shared xml extension on win32 (pierre)</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.0.4</release>
-    <api>1.0.4</api>
-   </version>
-   <stability>
-    <release>stable</release>
-    <api>stable</api>
-   </stability>
-   <date>2002-10-02</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.0.3</release>
-    <api>1.0.3</api>
-   </version>
-   <stability>
-    <release>stable</release>
-    <api>stable</api>
-   </stability>
-   <date>2002-05-19</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* fix bug when parsing responses with boolean types</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.0.2</release>
-    <api>1.0.2</api>
-   </version>
-   <stability>
-    <release>stable</release>
-    <api>stable</api>
-   </stability>
-   <date>2002-04-16</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>* E_ALL fixes
-* fix HTTP response header parsing</notes>
-  </release>
-  <release>
-   <version>
-    <release>1.0.1</release>
-    <api>1.0.1</api>
-   </version>
-   <stability>
-    <release>stable</release>
-    <api>stable</api>
-   </stability>
-   <date>2001-09-25</date>
-   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
-   <notes>This is a PEAR-ified version of Useful Inc&apos;s 1.0.1 release.
-Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.</notes>
-  </release>
- </changelog>
-</package>XML_RPC-1.2.2/tests/protoport.php100666      0      0       25543 10213112550  11656 <?php
-
-/**
- * Tests that properties of XML_RPC_Client get properly set
- *
- * Any individual tests that fail will have their name, expected result
- * and actual result printed out.  So seeing no output when executing
- * this file is a good thing.
- *
- * Can be run via CLI or a web server.
- *
- * PHP versions 4 and 5
- *
- * LICENSE: This source file is subject to version 3.0 of the PHP license
- * that is available through the world-wide-web at the following URI:
- * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
- * the PHP License and are unable to obtain it through the web, please
- * send a note to license@php.net so we can mail you a copy immediately.
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Daniel Convissor <danielc@php.net>
- * @copyright  2005 The PHP Group
- * @license    http://www.php.net/license/3_0.txt  PHP License
- * @version    CVS: $Id: protoport.php,v 1.4 2005/01/24 17:48:47 danielc Exp $
- * @link       http://pear.php.net/package/XML_RPC
- * @since      File available since Release 1.2
- */
-
-/*
- * If the package version number is found in the left hand
- * portion of the if() expression below, that means this file has
- * come from the PEAR installer.  Therefore, let's test the
- * installed version of XML_RPC which should be in the include path.
- * 
- * If the version has not been substituted in the if() expression,
- * this file has likely come from a CVS checkout or a .tar file.
- * Therefore, we'll assume the tests should use the version of
- * XML_RPC that has come from there as well.
- */
-if ('1.2.2' != '@'.'package_version'.'@') {
-    /**
-     * Get the needed class from the PEAR installation
-     */
-    require_once 'XML/RPC.php';
-} else {
-    /**
-     * Get the needed class from the parent directory
-     */
-    require_once '../RPC.php';
-}
-
-/**
- * Compare the test result to the expected result
- *
- * If the test fails, echo out the results.
- *
- * @param array  $expect     the array of object properties you expect
- *                            from the test
- * @param object $actual     the object results from the test
- * @param string $test_name  the name of the test
- *
- * @return void
- */
-function compare($expect, $actual, $test_name) {
-    $actual = get_object_vars($actual);
-    if (count(array_diff($actual, $expect))) {
-        echo "$test_name failed.\nExpect: ";
-        print_r($expect);
-        echo "Actual: ";
-        print_r($actual);
-        echo "\n";
-    }
-}
-
-if (php_sapi_name() != 'cli') {
-    echo "<pre>\n";
-}
-
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 80,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'theserver');
-compare($x, $c, 'defaults');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 80,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'http://theserver');
-compare($x, $c, 'defaults with http');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 443,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'https://theserver');
-compare($x, $c, 'defaults with https');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 443,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'ssl://theserver');
-compare($x, $c, 'defaults with ssl');
-
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 65,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'theserver', 65);
-compare($x, $c, 'port 65');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 65,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'http://theserver', 65);
-compare($x, $c, 'port 65 with http');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 65,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'https://theserver', 65);
-compare($x, $c, 'port 65 with https');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 65,
-    'proxy' => '',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65);
-compare($x, $c, 'port 65 with ssl');
-
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 80,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'theserver', 0,
-                        'theproxy');
-compare($x, $c, 'defaults proxy');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 80,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 8080,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'http://theserver', 0,
-                        'http://theproxy');
-compare($x, $c, 'defaults with http proxy');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 443,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'ssl://',
-    'proxy_port' => 443,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'https://theserver', 0,
-                        'https://theproxy');
-compare($x, $c, 'defaults with https proxy');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 443,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'ssl://',
-    'proxy_port' => 443,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 0,
-                        'ssl://theproxy');
-compare($x, $c, 'defaults with ssl proxy');
-
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 65,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 6565,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'theserver', 65,
-                        'theproxy', 6565);
-compare($x, $c, 'port 65 proxy 6565');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 65,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'http://',
-    'proxy_port' => 6565,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'http://theserver', 65,
-                        'http://theproxy', 6565);
-compare($x, $c, 'port 65 with http proxy 6565');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 65,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'ssl://',
-    'proxy_port' => 6565,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'https://theserver', 65,
-                        'https://theproxy', 6565);
-compare($x, $c, 'port 65 with https proxy 6565');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 65,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'ssl://',
-    'proxy_port' => 6565,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65,
-                        'ssl://theproxy', 6565);
-compare($x, $c, 'port 65 with ssl proxy 6565');
-
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'ssl://',
-    'port' => 443,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'ssl://',
-    'proxy_port' => 443,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'theserver', 443,
-                        'theproxy', 443);
-compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
-
-$x = array(
-    'path' => 'thepath',
-    'server' => 'theserver',
-    'protocol' => 'http://',
-    'port' => 80,
-    'proxy' => 'theproxy',
-    'proxy_protocol' => 'ssl://',
-    'proxy_port' => 6565,
-    'proxy_user' => '',
-    'proxy_pass' => '',
-    'errno' => 0,
-    'errstring' => '',
-    'debug' => 0,
-    'username' => '',
-    'password' => '',
-);
-$c = new XML_RPC_Client('thepath', 'theserver', 0,
-                        'ssl://theproxy', 6565);
-compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
-XML_RPC-1.2.2/tests/test_Dump.php100666      0      0        3042 10213112550  11520 <?php
-
-/*
- * If the package version number is found in the left hand
- * portion of the if() expression below, that means this file has
- * come from the PEAR installer.  Therefore, let's test the
- * installed version of XML_RPC which should be in the include path.
- * 
- * If the version has not been substituted in the if() expression,
- * this file has likely come from a CVS checkout or a .tar file.
- * Therefore, we'll assume the tests should use the version of
- * XML_RPC that has come from there as well.
- */
-if ('1.2.2' != '@'.'package_version'.'@') {
-    /**
-     * Get the needed class from the PEAR installation
-     */
-    require_once 'XML/RPC/Dump.php';
-} else {
-    /**
-     * Get the needed class from the parent directory
-     */
-    require_once '../Dump.php';
-}
-
-$val = new XML_RPC_Value(array(
-    'title'    =>new XML_RPC_Value('das ist der Titel', 'string'),
-    'startDate'=>new XML_RPC_Value(mktime(0,0,0,13,11,2004), 'dateTime.iso8601'),
-    'endDate'  =>new XML_RPC_Value(mktime(0,0,0,15,11,2004), 'dateTime.iso8601'),
-    'error'    =>'string',
-    'arkey'    => new XML_RPC_Value( array(
-        new XML_RPC_Value('simple string'),
-        new XML_RPC_Value(12345, 'int')
-        ), 'array')
-    )
-    ,'struct');
-
-XML_RPC_Dump($val);
-
-echo '==============' . "\r\n";
-$val2 = new XML_RPC_Value(44353, 'int');
-XML_RPC_Dump($val2);
-
-echo '==============' . "\r\n";
-$val3 = new XML_RPC_Value('this should be a string', 'string');
-XML_RPC_Dump($val3);
-
-echo '==============' . "\r\n";
-$val4 = new XML_RPC_Value(true, 'boolean');
-XML_RPC_Dump($val4);
-XML_RPC-1.2.2/Dump.php100666      0      0       12074 10213112550   7344 <?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Function and class to dump XML_RPC_Value objects in a nice way
- *
- * Should be helpful as a normal var_dump(..) displays all internals which
- * doesn't really give you an overview due to too much information.
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Christian Weiske <cweiske@php.net>
- * @version    CVS: $Id: Dump.php,v 1.7 2005/01/24 03:47:55 danielc Exp $
- * @link       http://pear.php.net/package/XML_RPC
- */
-
-
-/**
- * Pull in the XML_RPC class
- */
-require_once 'XML/RPC.php';
-
-
-/**
- * Generates the dump of the XML_RPC_Value and echoes it
- *
- * @param object $value  the XML_RPC_Value object to dump
- *
- * @return void
- */
-function XML_RPC_Dump($value)
-{
-    $dumper = new XML_RPC_Dump();
-    echo $dumper->generateDump($value);
-}
-
-
-/**
- * Class which generates a dump of a XML_RPC_Value object
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Christian Weiske <cweiske@php.net>
- * @version    Release: 1.2.2
- * @link       http://pear.php.net/package/XML_RPC
- */
-class XML_RPC_Dump
-{
-    /**
-     * The indentation array cache
-     * @var array
-     */
-    var $arIndent      = array();
-
-    /**
-     * The spaces used for indenting the XML
-     * @var string
-     */
-    var $strBaseIndent = '    ';
-
-    /**
-     * Returns the dump in XML format without printing it out
-     *
-     * @param object $value   the XML_RPC_Value object to dump
-     * @param int    $nLevel  the level of indentation
-     *
-     * @return string  the dump
-     */
-    function generateDump($value, $nLevel = 0)
-    {
-        if (!is_object($value) && get_class($value) != 'xml_rpc_value') {
-            require_once 'PEAR.php';
-            PEAR::raiseError('Tried to dump non-XML_RPC_Value variable' . "\r\n",
-                             0, PEAR_ERROR_PRINT);
-            if (is_object($value)) {
-                $strType = get_class($value);
-            } else {
-                $strType = gettype($value);
-            }
-            return $this->getIndent($nLevel) . 'NOT A XML_RPC_Value: '
-                   . $strType . "\r\n";
-        }
-
-        switch ($value->kindOf()) {
-        case 'struct':
-            $ret = $this->genStruct($value, $nLevel);
-            break;
-        case 'array':
-            $ret = $this->genArray($value, $nLevel);
-            break;
-        case 'scalar':
-            $ret = $this->genScalar($value->scalarval(), $nLevel);
-            break;
-        default:
-            require_once 'PEAR.php';
-            PEAR::raiseError('Illegal type "' . $value->kindOf()
-                             . '" in XML_RPC_Value' . "\r\n", 0,
-                             PEAR_ERROR_PRINT);
-        }
-
-        return $ret;
-    }
-
-    /**
-     * Returns the scalar value dump
-     *
-     * @param object $value   the scalar XML_RPC_Value object to dump
-     * @param int    $nLevel  the level of indentation
-     *
-     * @return string  Dumped version of the scalar value
-     */
-    function genScalar($value, $nLevel)
-    {
-        if (gettype($value) == 'object') {
-            $strClass = ' ' . get_class($value);
-        } else {
-            $strClass = '';
-        }
-        return $this->getIndent($nLevel) . gettype($value) . $strClass
-               . ' ' . $value . "\r\n";
-    }
-
-    /**
-     * Returns the dump of a struct
-     *
-     * @param object $value   the struct XML_RPC_Value object to dump
-     * @param int    $nLevel  the level of indentation
-     *
-     * @return string  Dumped version of the scalar value
-     */
-    function genStruct($value, $nLevel)
-    {
-        $value->structreset();
-        $strOutput = $this->getIndent($nLevel) . 'struct' . "\r\n";
-        while (list($key, $keyval) = $value->structeach()) {
-            $strOutput .= $this->getIndent($nLevel + 1) . $key . "\r\n";
-            $strOutput .= $this->generateDump($keyval, $nLevel + 2);
-        }
-        return $strOutput;
-    }
-
-    /**
-     * Returns the dump of an array
-     *
-     * @param object $value   the array XML_RPC_Value object to dump
-     * @param int    $nLevel  the level of indentation
-     *
-     * @return string  Dumped version of the scalar value
-     */
-    function genArray($value, $nLevel)
-    {
-        $nSize     = $value->arraysize();
-        $strOutput = $this->getIndent($nLevel) . 'array' . "\r\n";
-        for($nA = 0; $nA < $nSize; $nA++) {
-            $strOutput .= $this->getIndent($nLevel + 1) . $nA . "\r\n";
-            $strOutput .= $this->generateDump($value->arraymem($nA),
-                                              $nLevel + 2);
-        }
-        return $strOutput;
-    }
-
-    /**
-     * Returns the indent for a specific level and caches it for faster use
-     *
-     * @param int $nLevel  the level
-     *
-     * @return string  the indented string
-     */
-    function getIndent($nLevel)
-    {
-        if (!isset($this->arIndent[$nLevel])) {
-            $this->arIndent[$nLevel] = str_repeat($this->strBaseIndent, $nLevel);
-        }
-        return $this->arIndent[$nLevel];
-    }
-}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * c-hanging-comment-ender-p: nil
- * End:
- */
-
-?>
-XML_RPC-1.2.2/RPC.php100666      0      0      141000 10213112550   7073 <?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * PHP implementation of the XML-RPC protocol
- *
- * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
- * It has support for HTTP transport, proxies and authentication.
- *
- * PHP versions 4 and 5
- *
- * LICENSE: License is granted to use or modify this software
- * ("XML-RPC for PHP") for commercial or non-commercial use provided the
- * copyright of the author is preserved in any distributed or derivative work.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    CVS: $Id: RPC.php,v 1.60 2005/03/07 17:45:08 danielc Exp $
- * @link       http://pear.php.net/package/XML_RPC
- */
-
-
-if (!function_exists('xml_parser_create')) {
-    // Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
-    if ($WINDIR) {
-        dl('php_xml.dll');
-    } else {
-        dl('xml.so');
-    }
-}
-
-/**#@+
- * Error constants
- */
-define('XML_RPC_ERROR_INVALID_TYPE',        101);
-define('XML_RPC_ERROR_NON_NUMERIC_FOUND',   102);
-define('XML_RPC_ERROR_CONNECTION_FAILED',   103);
-define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104);
-/**#@-*/
-
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_I4']
- */
-$GLOBALS['XML_RPC_I4'] = 'i4';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_Int']
- */
-$GLOBALS['XML_RPC_Int'] = 'int';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_Boolean']
- */
-$GLOBALS['XML_RPC_Boolean'] = 'boolean';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_Double']
- */
-$GLOBALS['XML_RPC_Double'] = 'double';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_String']
- */
-$GLOBALS['XML_RPC_String'] = 'string';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_DateTime']
- */
-$GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_Base64']
- */
-$GLOBALS['XML_RPC_Base64'] = 'base64';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_Array']
- */
-$GLOBALS['XML_RPC_Array'] = 'array';
-
-/**
- * Data types
- * @global string $GLOBALS['XML_RPC_Struct']
- */
-$GLOBALS['XML_RPC_Struct'] = 'struct';
-
-
-/**
- * Data type meta-types
- * @global array $GLOBALS['XML_RPC_Types']
- */
-$GLOBALS['XML_RPC_Types'] = array(
-    $GLOBALS['XML_RPC_I4']       => 1,
-    $GLOBALS['XML_RPC_Int']      => 1,
-    $GLOBALS['XML_RPC_Boolean']  => 1,
-    $GLOBALS['XML_RPC_String']   => 1,
-    $GLOBALS['XML_RPC_Double']   => 1,
-    $GLOBALS['XML_RPC_DateTime'] => 1,
-    $GLOBALS['XML_RPC_Base64']   => 1,
-    $GLOBALS['XML_RPC_Array']    => 2,
-    $GLOBALS['XML_RPC_Struct']   => 3,
-);
-
-
-/**
- * Error message numbers
- * @global array $GLOBALS['XML_RPC_err']
- */
-$GLOBALS['XML_RPC_err'] = array(
-    'unknown_method'      => 1,
-    'invalid_return'      => 2,
-    'incorrect_params'    => 3,
-    'introspect_unknown'  => 4,
-    'http_error'          => 5,
-);
-
-/**
- * Error message strings
- * @global array $GLOBALS['XML_RPC_str']
- */
-$GLOBALS['XML_RPC_str'] = array(
-    'unknown_method'      => 'Unknown method',
-    'invalid_return'      => 'Invalid return payload: enable debugging to examine incoming payload',
-    'incorrect_params'    => 'Incorrect parameters passed to method',
-    'introspect_unknown'  => 'Can\'t introspect: method unknown',
-    'http_error'          => 'Didn\'t receive 200 OK from remote server.',
-);
-
-
-/**
- * Default XML encoding (ISO-8859-1, UTF-8 or US-ASCII)
- * @global string $GLOBALS['XML_RPC_defencoding']
- */
-$GLOBALS['XML_RPC_defencoding'] = 'UTF-8';
-
-/**
- * User error codes start at 800
- * @global int $GLOBALS['XML_RPC_erruser']
- */
-$GLOBALS['XML_RPC_erruser'] = 800;
-
-/**
- * XML parse error codes start at 100
- * @global int $GLOBALS['XML_RPC_errxml']
- */
-$GLOBALS['XML_RPC_errxml'] = 100;
-
-
-/**
- * Compose backslashes for escaping regexp
- * @global string $GLOBALS['XML_RPC_backslash']
- */
-$GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92);
-
-
-/**
- * Stores state during parsing
- *
- * quick explanation of components:
- *   + st     = builds up a string for evaluation
- *   + ac     = accumulates values
- *   + qt     = decides if quotes are needed for evaluation
- *   + cm     = denotes struct or array (comma needed)
- *   + isf    = indicates a fault
- *   + lv     = indicates "looking for a value": implements the logic
- *               to allow values with no types to be strings
- *   + params = stores parameters in method calls
- *   + method = stores method name
- *
- * @global array $GLOBALS['XML_RPC_xh']
- */
-$GLOBALS['XML_RPC_xh'] = array();
-
-
-/**
- * Start element handler for the XML parser
- *
- * @return void
- */
-function XML_RPC_se($parser, $name, $attrs)
-{
-    global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String;
-
-    switch ($name) {
-    case 'STRUCT':
-    case 'ARRAY':
-        $XML_RPC_xh[$parser]['st'] .= 'array(';
-        $XML_RPC_xh[$parser]['cm']++;
-        // this last line turns quoting off
-        // this means if we get an empty array we'll
-        // simply get a bit of whitespace in the eval
-        $XML_RPC_xh[$parser]['qt'] = 0;
-        break;
-
-    case 'NAME':
-        $XML_RPC_xh[$parser]['st'] .= "'";
-        $XML_RPC_xh[$parser]['ac'] = '';
-        break;
-
-    case 'FAULT':
-        $XML_RPC_xh[$parser]['isf'] = 1;
-        break;
-
-    case 'PARAM':
-        $XML_RPC_xh[$parser]['st'] = '';
-        break;
-
-    case 'VALUE':
-        $XML_RPC_xh[$parser]['st'] .= 'new XML_RPC_Value(';
-        $XML_RPC_xh[$parser]['lv'] = 1;
-        $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String;
-        $XML_RPC_xh[$parser]['ac'] = '';
-        $XML_RPC_xh[$parser]['qt'] = 0;
-        // look for a value: if this is still 1 by the
-        // time we reach the first data segment then the type is string
-        // by implication and we need to add in a quote
-        break;
-
-    case 'I4':
-    case 'INT':
-    case 'STRING':
-    case 'BOOLEAN':
-    case 'DOUBLE':
-    case 'DATETIME.ISO8601':
-    case 'BASE64':
-        $XML_RPC_xh[$parser]['ac'] = ''; // reset the accumulator
-
-        if ($name == 'DATETIME.ISO8601' || $name == 'STRING') {
-            $XML_RPC_xh[$parser]['qt'] = 1;
-
-            if ($name == 'DATETIME.ISO8601') {
-                $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime;
-            }
-
-        } elseif ($name == 'BASE64') {
-            $XML_RPC_xh[$parser]['qt'] = 2;
-        } else {
-            // No quoting is required here -- but
-            // at the end of the element we must check
-            // for data format errors.
-            $XML_RPC_xh[$parser]['qt'] = 0;
-        }
-        break;
-
-    case 'MEMBER':
-        $XML_RPC_xh[$parser]['ac'] = '';
-    }
-
-    if ($name != 'VALUE') {
-        $XML_RPC_xh[$parser]['lv'] = 0;
-    }
-}
-
-/**
- * End element handler for the XML parser
- *
- * @return void
- */
-function XML_RPC_ee($parser, $name)
-{
-    global $XML_RPC_xh, $XML_RPC_Types, $XML_RPC_String;
-
-    switch ($name) {
-    case 'STRUCT':
-    case 'ARRAY':
-        if ($XML_RPC_xh[$parser]['cm']
-            && substr($XML_RPC_xh[$parser]['st'], -1) == ',')
-        {
-            $XML_RPC_xh[$parser]['st'] = substr($XML_RPC_xh[$parser]['st'], 0, -1);
-        }
-
-        $XML_RPC_xh[$parser]['st'] .= ')';
-        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
-        $XML_RPC_xh[$parser]['cm']--;
-        break;
-
-    case 'NAME':
-        $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . "' => ";
-        break;
-
-    case 'BOOLEAN':
-        // special case here: we translate boolean 1 or 0 into PHP
-        // constants true or false
-        if ($XML_RPC_xh[$parser]['ac'] == '1') {
-            $XML_RPC_xh[$parser]['ac'] = 'true';
-        } else {
-            $XML_RPC_xh[$parser]['ac'] = 'false';
-        }
-
-        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
-        // Drop through intentionally.
-
-    case 'I4':
-    case 'INT':
-    case 'STRING':
-    case 'DOUBLE':
-    case 'DATETIME.ISO8601':
-    case 'BASE64':
-        if ($XML_RPC_xh[$parser]['qt'] == 1) {
-            // we use double quotes rather than single so backslashification works OK
-            $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
-        } elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
-            $XML_RPC_xh[$parser]['st'] .= "base64_decode('"
-                                        . $XML_RPC_xh[$parser]['ac'] . "')";
-        } elseif ($name == 'BOOLEAN') {
-            $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
-        } else {
-            // we have an I4, INT or a DOUBLE
-            // we must check that only 0123456789-.<space> are characters here
-            if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
-                XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE',
-                                         XML_RPC_ERROR_NON_NUMERIC_FOUND);
-                $XML_RPC_xh[$parser]['st'] .= 'XML_RPC_ERROR_NON_NUMERIC_FOUND';
-            } else {
-                // it's ok, add it on
-                $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
-            }
-        }
-
-        $XML_RPC_xh[$parser]['ac'] = '';
-        $XML_RPC_xh[$parser]['qt'] = 0;
-        $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
-        break;
-
-    case 'VALUE':
-        // deal with a string value
-        if (strlen($XML_RPC_xh[$parser]['ac']) > 0 &&
-            $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) {
-
-            $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
-        }
-
-        // This if () detects if no scalar was inside <VALUE></VALUE>
-        // and pads an empty "".
-        if ($XML_RPC_xh[$parser]['st'][strlen($XML_RPC_xh[$parser]['st'])-1] == '(') {
-            $XML_RPC_xh[$parser]['st'] .= '""';
-        }
-        $XML_RPC_xh[$parser]['st'] .= ", '" . $XML_RPC_xh[$parser]['vt'] . "')";
-        if ($XML_RPC_xh[$parser]['cm']) {
-            $XML_RPC_xh[$parser]['st'] .= ',';
-        }
-        break;
-
-    case 'MEMBER':
-        $XML_RPC_xh[$parser]['ac'] = '';
-        $XML_RPC_xh[$parser]['qt'] = 0;
-        break;
-
-    case 'DATA':
-        $XML_RPC_xh[$parser]['ac'] = '';
-        $XML_RPC_xh[$parser]['qt'] = 0;
-        break;
-
-    case 'PARAM':
-        $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['st'];
-        break;
-
-    case 'METHODNAME':
-        $XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", '',
-                                                      $XML_RPC_xh[$parser]['ac']);
-        break;
-
-    case 'BOOLEAN':
-        // special case here: we translate boolean 1 or 0 into PHP
-        // constants true or false
-        if ($XML_RPC_xh[$parser]['ac'] == '1') {
-            $XML_RPC_xh[$parser]['ac'] = 'true';
-        } else {
-            $XML_RPC_xh[$parser]['ac'] = 'false';
-        }
-
-        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
-    }
-
-    // if it's a valid type name, set the type
-    if (isset($XML_RPC_Types[strtolower($name)])) {
-        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
-    }
-}
-
-/**
- * Character data handler for the XML parser
- *
- * @return void
- */
-function XML_RPC_cd($parser, $data)
-{
-    global $XML_RPC_xh, $XML_RPC_backslash;
-
-    if ($XML_RPC_xh[$parser]['lv'] != 3) {
-        // "lookforvalue==3" means that we've found an entire value
-        // and should discard any further character data
-
-        if ($XML_RPC_xh[$parser]['lv'] == 1) {
-            // if we've found text and we're just in a <value> then
-            // turn quoting on, as this will be a string
-            $XML_RPC_xh[$parser]['qt'] = 1;
-            // and say we've found a value
-            $XML_RPC_xh[$parser]['lv'] = 2;
-        }
-
-        // replace characters that eval would
-        // do special things with
-        if (!isset($XML_RPC_xh[$parser]['ac'])) {
-            $XML_RPC_xh[$parser]['ac'] = '';
-        }
-        $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$',
-            str_replace('"', '\"', str_replace(chr(92),
-            $XML_RPC_backslash, $data)));
-    }
-}
-
-/**
- * Base class
- *
- * This class provides common functions for all of the XML_RPC classes.
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    Release: 1.2.2
- * @link       http://pear.php.net/package/XML_RPC
- */
-class XML_RPC_Base {
-
-    /**
-     * PEAR Error handling
-     *
-     * @return object  PEAR_Error object
-     */
-    function raiseError($msg, $code)
-    {
-        include_once 'PEAR.php';
-        if (is_object(@$this)) {
-            return PEAR::raiseError(get_class($this) . ': ' . $msg, $code);
-        } else {
-            return PEAR::raiseError('XML_RPC: ' . $msg, $code);
-        }
-    }
-
-    /**
-     * Tell whether something is a PEAR_Error object
-     *
-     * @param mixed $value  the item to check
-     *
-     * @return bool  whether $value is a PEAR_Error object or not
-     *
-     * @access public
-     */
-    function isError($value)
-    {
-        return is_a($value, 'PEAR_Error');
-    }
-}
-
-/**
- *
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    Release: 1.2.2
- * @link       http://pear.php.net/package/XML_RPC
- */
-class XML_RPC_Client extends XML_RPC_Base {
-
-    /**
-     * The path and name of the RPC server script you want the request to go to
-     * @var string
-     */
-    var $path = '';
-
-    /**
-     * The name of the remote server to connect to
-     * @var string
-     */
-    var $server = '';
-
-    /**
-     * The protocol to use in contacting the remote server
-     * @var string
-     */
-    var $protocol = 'http://';
-
-    /**
-     * The port for connecting to the remote server
-     *
-     * The default is 80 for http:// connections
-     * and 443 for https:// and ssl:// connections.
-     *
-     * @var integer
-     */
-    var $port = 80;
-
-    /**
-     * A user name for accessing the RPC server
-     * @var string
-     * @see XML_RPC_Client::setCredentials()
-     */
-    var $username = '';
-
-    /**
-     * A password for accessing the RPC server
-     * @var string
-     * @see XML_RPC_Client::setCredentials()
-     */
-    var $password = '';
-
-    /**
-     * The name of the proxy server to use, if any
-     * @var string
-     */
-    var $proxy = '';
-
-    /**
-     * The protocol to use in contacting the proxy server, if any
-     * @var string
-     */
-    var $proxy_protocol = 'http://';
-
-    /**
-     * The port for connecting to the proxy server
-     *
-     * The default is 8080 for http:// connections
-     * and 443 for https:// and ssl:// connections.
-     *
-     * @var integer
-     */
-    var $proxy_port = 8080;
-
-    /**
-     * A user name for accessing the proxy server
-     * @var string
-     */
-    var $proxy_user = '';
-
-    /**
-     * A password for accessing the proxy server
-     * @var string
-     */
-    var $proxy_pass = '';
-
-    /**
-     * The error number, if any
-     * @var integer
-     */
-    var $errno = 0;
-
-    /**
-     * The error message, if any
-     * @var string
-     */
-    var $errstring = '';
-
-    /**
-     * The current debug mode (1 = on, 0 = off)
-     * @var integer
-     */
-    var $debug = 0;
-
-
-    /**
-     * Sets the object's properties
-     *
-     * @param string  $path        the path and name of the RPC server script
-     *                              you want the request to go to
-     * @param string  $server      the URL of the remote server to connect to.
-     *                              If this parameter doesn't specify a
-     *                              protocol and $port is 443, ssl:// is
-     *                              assumed.
-     * @param integer $port        a port for connecting to the remote server.
-     *                              Defaults to 80 for http:// connections and
-     *                              443 for https:// and ssl:// connections.
-     * @param string  $proxy       the URL of the proxy server to use, if any.
-     *                              If this parameter doesn't specify a
-     *                              protocol and $port is 443, ssl:// is
-     *                              assumed.
-     * @param integer $proxy_port  a port for connecting to the remote server.
-     *                              Defaults to 8080 for http:// connections and
-     *                              443 for https:// and ssl:// connections.
-     * @param string  $proxy_user  a user name for accessing the proxy server
-     * @param string  $proxy_pass  a password for accessing the proxy server
-     *
-     * @return void
-     */
-    function XML_RPC_Client($path, $server, $port = 0,
-                            $proxy = '', $proxy_port = 0,
-                            $proxy_user = '', $proxy_pass = '')
-    {
-        $this->path       = $path;
-        $this->proxy_user = $proxy_user;
-        $this->proxy_pass = $proxy_pass;
-
-        preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match);
-        if ($match[1] == '') {
-            if ($port == 443) {
-                $this->server   = $match[2];
-                $this->protocol = 'ssl://';
-                $this->port     = 443;
-            } else {
-                $this->server = $match[2];
-                if ($port) {
-                    $this->port = $port;
-                }
-            }
-        } elseif ($match[1] == 'http://') {
-            $this->server = $match[2];
-            if ($port) {
-                $this->port = $port;
-            }
-        } else {
-            $this->server   = $match[2];
-            $this->protocol = 'ssl://';
-            if ($port) {
-                $this->port = $port;
-            } else {
-                $this->port = 443;
-            }
-        }
-
-        if ($proxy) {
-            preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match);
-            if ($match[1] == '') {
-                if ($proxy_port == 443) {
-                    $this->proxy          = $match[2];
-                    $this->proxy_protocol = 'ssl://';
-                    $this->proxy_port     = 443;
-                } else {
-                    $this->proxy = $match[2];
-                    if ($proxy_port) {
-                        $this->proxy_port = $proxy_port;
-                    }
-                }
-            } elseif ($match[1] == 'http://') {
-                $this->proxy = $match[2];
-                if ($proxy_port) {
-                    $this->proxy_port = $proxy_port;
-                }
-            } else {
-                $this->proxy          = $match[2];
-                $this->proxy_protocol = 'ssl://';
-                if ($proxy_port) {
-                    $this->proxy_port = $proxy_port;
-                } else {
-                    $this->proxy_port = 443;
-                }
-            }
-        }
-    }
-
-    /**
-     * Change the current debug mode
-     *
-     * @param int $in  where 1 = on, 0 = off
-     *
-     * @return void
-     */
-    function setDebug($in)
-    {
-        if ($in) {
-            $this->debug = 1;
-        } else {
-            $this->debug = 0;
-        }
-    }
-
-    /**
-     * Set username and password properties for connecting to the RPC server
-     *
-     * @param string $u  the user name
-     * @param string $p  the password
-     *
-     * @return void
-     *
-     * @see XML_RPC_Client::$username, XML_RPC_Client::$password
-     */
-    function setCredentials($u, $p)
-    {
-        $this->username = $u;
-        $this->password = $p;
-    }
-
-    /**
-     * Transmit the RPC request via HTTP 1.0 protocol
-     *
-     * @param object $msg       the XML_RPC_Message object
-     * @param int    $timeout   how many seconds to wait for the request
-     *
-     * @return object  an XML_RPC_Response object.  0 is returned if any
-     *                  problems happen.
-     *
-     * @see XML_RPC_Message, XML_RPC_Client::XML_RPC_Client(),
-     *      XML_RPC_Client::setCredentials()
-     */
-    function send($msg, $timeout = 0)
-    {
-        $msg->debug = $this->debug;
-        return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
-                                        $timeout, $this->username,
-                                        $this->password);
-    }
-
-    /**
-     * Transmit the RPC request via HTTP 1.0 protocol
-     *
-     * Requests should be sent using XML_RPC_Client send() rather than
-     * calling this method directly.
-     *
-     * @param object $msg       the XML_RPC_Message object
-     * @param string $server    the server to send the request to
-     * @param int    $port      the server port send the request to
-     * @param int    $timeout   how many seconds to wait for the request
-     *                           before giving up
-     * @param string $username  a user name for accessing the RPC server
-     * @param string $password  a password for accessing the RPC server
-     *
-     * @return object  an XML_RPC_Response object.  0 is returned if any
-     *                  problems happen.
-     *
-     * @see XML_RPC_Client::send()
-     */
-    function sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
-                               $username = '', $password = '')
-    {
-        /*
-         * If we're using a proxy open a socket to the proxy server
-         * instead to the xml-rpc server
-         */
-        if ($this->proxy) {
-            if ($this->proxy_protocol == 'http://') {
-                $protocol = '';
-            } else {
-                $protocol = $this->proxy_protocol;
-            }
-            if ($timeout > 0) {
-                $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
-                                 $this->errno, $this->errstr, $timeout);
-            } else {
-                $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
-                                 $this->errno, $this->errstr);
-            }
-        } else {
-            if ($this->protocol == 'http://') {
-                $protocol = '';
-            } else {
-                $protocol = $this->protocol;
-            }
-            if ($timeout > 0) {
-                $fp = @fsockopen($protocol . $server, $port,
-                                 $this->errno, $this->errstr, $timeout);
-            } else {
-                $fp = @fsockopen($protocol . $server, $port,
-                                 $this->errno, $this->errstr);
-            }
-        }
-
-        /*
-         * Just raising the error without returning it is strange,
-         * but keep it here for backwards compatibility.
-         */
-        if (!$fp && $this->proxy) {
-            $this->raiseError('Connection to proxy server '
-                              . $this->proxy . ':' . $this->proxy_port
-                              . ' failed. ' . $this->errstr,
-                              XML_RPC_ERROR_CONNECTION_FAILED);
-            return 0;
-        } elseif (!$fp) {
-            $this->raiseError('Connection to RPC server '
-                              . $server . ':' . $port
-                              . ' failed. ' . $this->errstr,
-                              XML_RPC_ERROR_CONNECTION_FAILED);
-            return 0;
-        }
-
-        // Only create the payload if it was not created previously
-        if (empty($msg->payload)) {
-            $msg->createPayload();
-        }
-
-        // thanks to Grant Rauscher <grant7@firstworld.net> for this
-        $credentials = '';
-        if ($username != '') {
-            $credentials = 'Authorization: Basic ' .
-                base64_encode($username . ':' . $password) . "\r\n";
-        }
-
-        if ($this->proxy) {
-            $op = 'POST ' . $this->protocol . $server;
-            if ($this->proxy_port) {
-                $op .= ':' . $this->port;
-            }
-        } else {
-           $op = 'POST ';
-        }
-
-        $op .= $this->path. " HTTP/1.0\r\n" .
-               "User-Agent: PEAR XML_RPC\r\n" .
-               'Host: ' . $server . "\r\n";
-        if ($this->proxy && $this->proxy_user != '') {
-            $op .= 'Proxy-Authorization: Basic ' .
-                base64_encode($this->proxy_user . ':' . $this->proxy_pass) .
-                "\r\n";
-        }
-        $op .= $credentials .
-               "Content-Type: text/xml\r\n" .
-               'Content-Length: ' . strlen($msg->payload) . "\r\n\r\n" .
-               $msg->payload;
-
-        if (!fputs($fp, $op, strlen($op))) {
-            $this->errstr = 'Write error';
-            return 0;
-        }
-        $resp = $msg->parseResponseFile($fp);
-        fclose($fp);
-        return $resp;
-    }
-}
-
-/**
- *
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    Release: 1.2.2
- * @link       http://pear.php.net/package/XML_RPC
- */
-class XML_RPC_Response extends XML_RPC_Base
-{
-    var $xv;
-    var $fn;
-    var $fs;
-    var $hdrs;
-
-    /**
-     * @return void
-     */
-    function XML_RPC_Response($val, $fcode = 0, $fstr = '')
-    {
-        if ($fcode != 0) {
-            $this->fn = $fcode;
-            $this->fs = htmlspecialchars($fstr);
-        } else {
-            $this->xv = $val;
-        }
-    }
-
-    /**
-     * @return int  the error code
-     */
-    function faultCode()
-    {
-        if (isset($this->fn)) {
-            return $this->fn;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * @return string  the error string
-     */
-    function faultString()
-    {
-        return $this->fs;
-    }
-
-    /**
-     * @return mixed  the value
-     */
-    function value()
-    {
-        return $this->xv;
-    }
-
-    /**
-     * @return string  the error message in XML format
-     */
-    function serialize()
-    {
-        $rs = "<methodResponse>\n";
-        if ($this->fn) {
-            $rs .= "<fault>
-  <value>
-    <struct>
-      <member>
-        <name>faultCode</name>
-        <value><int>" . $this->fn . "</int></value>
-      </member>
-      <member>
-        <name>faultString</name>
-        <value><string>" . $this->fs . "</string></value>
-      </member>
-    </struct>
-  </value>
-</fault>";
-        } else {
-            $rs .= "<params>\n<param>\n" . $this->xv->serialize() .
-        "</param>\n</params>";
-        }
-        $rs .= "\n</methodResponse>";
-        return $rs;
-    }
-}
-
-/**
- *
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @author     Daniel Convissor <danielc@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    Release: 1.2.2
- * @link       http://pear.php.net/package/XML_RPC
- */
-class XML_RPC_Message extends XML_RPC_Base
-{
-    /**
-     * The current debug mode (1 = on, 0 = off)
-     * @var integer
-     */
-    var $debug = 0;
-
-    /**
-     * The encoding to be used for outgoing messages
-     *
-     * Defaults to the value of <var>$GLOBALS['XML_RPC_defencoding']</var>
-     *
-     * @var string
-     * @see XML_RPC_Message::setSendEncoding(),
-     *      $GLOBALS['XML_RPC_defencoding'], XML_RPC_Message::xml_header()
-     */
-    var $send_encoding = '';
-
-    /**
-     * The method presently being evaluated
-     * @var string
-     */
-    var $methodname = '';
-
-    /**
-     * @var array
-     */
-    var $params = array();
-
-    /**
-     * The XML message being generated
-     * @var string
-     */
-    var $payload = '';
-
-    /**
-     * @return void
-     */
-    function XML_RPC_Message($meth, $pars = 0)
-    {
-        $this->methodname = $meth;
-        if (is_array($pars) && sizeof($pars) > 0) {
-            for ($i = 0; $i < sizeof($pars); $i++) {
-                $this->addParam($pars[$i]);
-            }
-        }
-    }
-
-    /**
-     * Produces the XML declaration including the encoding attribute
-     *
-     * The encoding is determined by this class' <var>$send_encoding</var>
-     * property.  If the <var>$send_encoding</var> property is not set, use
-     * <var>$GLOBALS['XML_RPC_defencoding']</var>.
-     *
-     * @return string  the XML declaration and <methodCall> element
-     *
-     * @see XML_RPC_Message::setSendEncoding(),
-     *      XML_RPC_Message::$send_encoding, $GLOBALS['XML_RPC_defencoding']
-     */
-    function xml_header()
-    {
-        global $XML_RPC_defencoding;
-        if (!$this->send_encoding) {
-            $this->send_encoding = $XML_RPC_defencoding;
-        }
-        return '<?xml version="1.0" encoding="' . $this->send_encoding . '"?>'
-               . "\n<methodCall>\n";
-    }
-
-    /**
-     * @return string  the closing </methodCall> tag
-     */
-    function xml_footer()
-    {
-        return "</methodCall>\n";
-    }
-
-    /**
-     * @return void
-     *
-     * @uses XML_RPC_Message::xml_header(), XML_RPC_Message::xml_footer()
-     */
-    function createPayload()
-    {
-        $this->payload = $this->xml_header();
-        $this->payload .= '<methodName>' . $this->methodname . "</methodName>\n";
-        $this->payload .= "<params>\n";
-        for ($i = 0; $i < sizeof($this->params); $i++) {
-            $p = $this->params[$i];
-            $this->payload .= "<param>\n" . $p->serialize() . "</param>\n";
-        }
-        $this->payload .= "</params>\n";
-        $this->payload .= $this->xml_footer();
-        $this->payload = ereg_replace("[\r\n]+", "\r\n", $this->payload);
-    }
-
-    /**
-     * @return string  the name of the method
-     */
-    function method($meth = '')
-    {
-        if ($meth != '') {
-            $this->methodname = $meth;
-        }
-        return $this->methodname;
-    }
-
-    /**
-     * @return string  the payload
-     */
-    function serialize()
-    {
-        $this->createPayload();
-        return $this->payload;
-    }
-
-    /**
-     * @return void
-     */
-    function addParam($par)
-    {
-        $this->params[] = $par;
-    }
-
-    /**
-     * @return void
-     */
-    function getParam($i)
-    {
-        return $this->params[$i];
-    }
-
-    /**
-     * @return int  the number of parameters
-     */
-    function getNumParams()
-    {
-        return sizeof($this->params);
-    }
-
-    /**
-     * Sets the XML declaration's encoding attribute
-     *
-     * @param string $type  the encoding type (ISO-8859-1, UTF-8 or US-ASCII)
-     *
-     * @return void
-     *
-     * @see XML_RPC_Message::$send_encoding, XML_RPC_Message::xml_header()
-     * @since Method available since Release 1.2.0
-     */
-    function setSendEncoding($type)
-    {
-        $this->send_encoding = $type;
-    }
-
-    /**
-     * Determine the XML's encoding via the encoding attribute
-     * in the XML declaration
-     *
-     * If the encoding parameter is not set or is not ISO-8859-1, UTF-8
-     * or US-ASCII, $XML_RPC_defencoding will be returned.
-     *
-     * @param string $data  the XML that will be parsed
-     *
-     * @return string  the encoding to be used
-     *
-     * @link   http://php.net/xml_parser_create
-     * @since  Method available since Release 1.2.0
-     */
-    function getEncoding($data)
-    {
-        global $XML_RPC_defencoding;
-
-        if (preg_match('/<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]/i',
-                       $data, $match))
-        {
-            $match[1] = trim(strtoupper($match[1]));
-            switch ($match[1]) {
-                case 'ISO-8859-1':
-                case 'UTF-8':
-                case 'US-ASCII':
-                    return $match[1];
-                    break;
-
-                default:
-                    return $XML_RPC_defencoding;
-            }
-        } else {
-            return $XML_RPC_defencoding;
-        }
-    }
-
-    /**
-     * @return object  a new XML_RPC_Response object
-     */
-    function parseResponseFile($fp)
-    {
-        $ipd = '';
-        while ($data = @fread($fp, 8192)) {
-            $ipd .= $data;
-        }
-        return $this->parseResponse($ipd);
-    }
-
-    /**
-     * @return object  a new XML_RPC_Response object
-     */
-    function parseResponse($data = '')
-    {
-        global $XML_RPC_xh, $XML_RPC_err, $XML_RPC_str, $XML_RPC_defencoding;
-
-        $encoding = $this->getEncoding($data);
-        $parser = xml_parser_create($encoding);
-
-        $XML_RPC_xh[$parser] = array();
-
-        $XML_RPC_xh[$parser]['st'] = '';
-        $XML_RPC_xh[$parser]['cm'] = 0;
-        $XML_RPC_xh[$parser]['isf'] = 0;
-        $XML_RPC_xh[$parser]['ac'] = '';
-        $XML_RPC_xh[$parser]['qt'] = '';
-
-        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
-        xml_set_element_handler($parser, 'XML_RPC_se', 'XML_RPC_ee');
-        xml_set_character_data_handler($parser, 'XML_RPC_cd');
-
-        $hdrfnd = 0;
-        if ($this->debug) {
-            print "<PRE>---GOT---\n";
-            print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
-            print "\n---END---\n</PRE>";
-        }
-
-        // see if we got an HTTP 200 OK, else bomb
-        // but only do this if we're using the HTTP protocol.
-        if (ereg('^HTTP', $data) &&
-            !ereg('^HTTP/[0-9\.]+ 200 ', $data)) {
-                $errstr = substr($data, 0, strpos($data, "\n") - 1);
-                error_log('HTTP error, got response: ' . $errstr);
-                $r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
-                                          $XML_RPC_str['http_error'] . ' (' .
-                                          $errstr . ')');
-                xml_parser_free($parser);
-                return $r;
-        }
-        // gotta get rid of headers here
-
-
-        if ((!$hdrfnd) && ($brpos = strpos($data,"\r\n\r\n"))) {
-            $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
-            $data = substr($data, $brpos + 4);
-            $hdrfnd = 1;
-        }
-
-        /*
-         * be tolerant of junk after methodResponse
-         * (e.g. javascript automatically inserted by free hosts)
-         * thanks to Luca Mariano <luca.mariano@email.it>
-         */
-        $data = substr($data, 0, strpos($data, "</methodResponse>") + 17);
-
-        if (!xml_parse($parser, $data, sizeof($data))) {
-            // thanks to Peter Kocks <peter.kocks@baygate.com>
-            if ((xml_get_current_line_number($parser)) == 1) {
-                $errstr = 'XML error at line 1, check URL';
-            } else {
-                $errstr = sprintf('XML error: %s at line %d',
-                                  xml_error_string(xml_get_error_code($parser)),
-                                  xml_get_current_line_number($parser));
-            }
-            error_log($errstr);
-            $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
-                                      $XML_RPC_str['invalid_return']);
-            xml_parser_free($parser);
-            return $r;
-        }
-        xml_parser_free($parser);
-        if ($this->debug) {
-            print '<PRE>---EVALING---[' .
-            strlen($XML_RPC_xh[$parser]['st']) . " chars]---\n" .
-            htmlspecialchars($XML_RPC_xh[$parser]['st']) . ";\n---END---</PRE>";
-        }
-        if (strlen($XML_RPC_xh[$parser]['st']) == 0) {
-            // then something odd has happened
-            // and it's time to generate a client side error
-            // indicating something odd went on
-            $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
-                                      $XML_RPC_str['invalid_return']);
-        } else {
-            eval('$v=' . $XML_RPC_xh[$parser]['st'] . '; $allOK=1;');
-            if ($XML_RPC_xh[$parser]['isf']) {
-                $f = $v->structmem('faultCode');
-                $fs = $v->structmem('faultString');
-                $r = new XML_RPC_Response($v, $f->scalarval(),
-                                          $fs->scalarval());
-            } else {
-                $r = new XML_RPC_Response($v);
-            }
-        }
-        $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]);
-        return $r;
-    }
-}
-
-/**
- *
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    Release: 1.2.2
- * @link       http://pear.php.net/package/XML_RPC
- */
-class XML_RPC_Value extends XML_RPC_Base
-{
-    var $me = array();
-    var $mytype = 0;
-
-    /**
-     * @return void
-     */
-    function XML_RPC_Value($val = -1, $type = '')
-    {
-        global $XML_RPC_Types;
-        $this->me = array();
-        $this->mytype = 0;
-        if ($val != -1 || $type != '') {
-            if ($type == '') {
-                $type = 'string';
-            }
-            if (!array_key_exists($type, $XML_RPC_Types)) {
-                // XXX
-                // need some way to report this error
-            } elseif ($XML_RPC_Types[$type] == 1) {
-                $this->addScalar($val, $type);
-            } elseif ($XML_RPC_Types[$type] == 2) {
-                $this->addArray($val);
-            } elseif ($XML_RPC_Types[$type] == 3) {
-                $this->addStruct($val);
-            }
-        }
-    }
-
-    /**
-     * @return int  returns 1 if successful or 0 if there are problems
-     */
-    function addScalar($val, $type = 'string')
-    {
-        global $XML_RPC_Types, $XML_RPC_Boolean;
-
-        if ($this->mytype == 1) {
-            $this->raiseError('Scalar can have only one value',
-                              XML_RPC_ERROR_INVALID_TYPE);
-            return 0;
-        }
-        $typeof = $XML_RPC_Types[$type];
-        if ($typeof != 1) {
-            $this->raiseError("Not a scalar type (${typeof})",
-                              XML_RPC_ERROR_INVALID_TYPE);
-            return 0;
-        }
-
-        if ($type == $XML_RPC_Boolean) {
-            if (strcasecmp($val, 'true') == 0
-                || $val == 1
-                || ($val == true && strcasecmp($val, 'false')))
-            {
-                $val = 1;
-            } else {
-                $val = 0;
-            }
-        }
-
-        if ($this->mytype == 2) {
-            // we're adding to an array here
-            $ar = $this->me['array'];
-            $ar[] = new XML_RPC_Value($val, $type);
-            $this->me['array'] = $ar;
-        } else {
-            // a scalar, so set the value and remember we're scalar
-            $this->me[$type] = $val;
-            $this->mytype = $typeof;
-        }
-        return 1;
-    }
-
-    /**
-     * @return int  returns 1 if successful or 0 if there are problems
-     */
-    function addArray($vals)
-    {
-        global $XML_RPC_Types;
-        if ($this->mytype != 0) {
-            $this->raiseError(
-                    'Already initialized as a [' . $this->kindOf() . ']',
-                    XML_RPC_ERROR_ALREADY_INITIALIZED);
-            return 0;
-        }
-        $this->mytype = $XML_RPC_Types['array'];
-        $this->me['array'] = $vals;
-        return 1;
-    }
-
-    /**
-     * @return int  returns 1 if successful or 0 if there are problems
-     */
-    function addStruct($vals)
-    {
-        global $XML_RPC_Types;
-        if ($this->mytype != 0) {
-            $this->raiseError(
-                    'Already initialized as a [' . $this->kindOf() . ']',
-                    XML_RPC_ERROR_ALREADY_INITIALIZED);
-            return 0;
-        }
-        $this->mytype = $XML_RPC_Types['struct'];
-        $this->me['struct'] = $vals;
-        return 1;
-    }
-
-    /**
-     * @return void
-     */
-    function dump($ar)
-    {
-        reset($ar);
-        while (list($key, $val) = each($ar)) {
-            echo "$key => $val<br>";
-            if ($key == 'array') {
-                while (list($key2, $val2) = each($val)) {
-                    echo "-- $key2 => $val2<br>";
-                }
-            }
-        }
-    }
-
-    /**
-     * @return string  the data type of the current value
-     */
-    function kindOf()
-    {
-        switch ($this->mytype) {
-        case 3:
-            return 'struct';
-
-        case 2:
-            return 'array';
-
-        case 1:
-            return 'scalar';
-
-        default:
-            return 'undef';
-        }
-    }
-
-    /**
-     * @return string  the data in XML format
-     */
-    function serializedata($typ, $val)
-    {
-        $rs = '';
-        global $XML_RPC_Types, $XML_RPC_Base64, $XML_RPC_String, $XML_RPC_Boolean;
-        if (!array_key_exists($typ, $XML_RPC_Types)) {
-            // XXX
-            // need some way to report this error
-            return;
-        }
-        switch ($XML_RPC_Types[$typ]) {
-        case 3:
-            // struct
-            $rs .= "<struct>\n";
-            reset($val);
-            while (list($key2, $val2) = each($val)) {
-                $rs .= "<member><name>${key2}</name>\n";
-                $rs .= $this->serializeval($val2);
-                $rs .= "</member>\n";
-            }
-            $rs .= '</struct>';
-            break;
-
-        case 2:
-            // array
-            $rs .= "<array>\n<data>\n";
-            for ($i = 0; $i < sizeof($val); $i++) {
-                $rs .= $this->serializeval($val[$i]);
-            }
-            $rs .= "</data>\n</array>";
-            break;
-
-        case 1:
-            switch ($typ) {
-            case $XML_RPC_Base64:
-                $rs .= "<${typ}>" . base64_encode($val) . "</${typ}>";
-                break;
-            case $XML_RPC_Boolean:
-                $rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
-                break;
-            case $XML_RPC_String:
-                $rs .= "<${typ}>" . htmlspecialchars($val). "</${typ}>";
-                break;
-            default:
-                $rs .= "<${typ}>${val}</${typ}>";
-            }
-        }
-        return $rs;
-    }
-
-    /**
-     * @return string  the data in XML format
-     */
-    function serialize()
-    {
-        return $this->serializeval($this);
-    }
-
-    /**
-     * @return string  the data in XML format
-     */
-    function serializeval($o)
-    {
-        $rs = '';
-        $ar = $o->me;
-        reset($ar);
-        list($typ, $val) = each($ar);
-        $rs .= '<value>';
-        $rs .= $this->serializedata($typ, $val);
-        $rs .= "</value>\n";
-        return $rs;
-    }
-
-    /**
-     * @return mixed  the contents of the element requested
-     */
-    function structmem($m)
-    {
-        return $this->me['struct'][$m];
-    }
-
-    /**
-     * @return void
-     */
-    function structreset()
-    {
-        reset($this->me['struct']);
-    }
-
-    /**
-     * @return  the key/value pair of the struct's current element
-     */
-    function structeach()
-    {
-        return each($this->me['struct']);
-    }
-
-    /**
-     * @return mixed  the current value
-     */
-    function getval() {
-        // UNSTABLE
-        global $XML_RPC_BOOLEAN, $XML_RPC_Base64;
-
-        reset($this->me);
-        list($a, $b) = each($this->me);
-
-        // contributed by I Sofer, 2001-03-24
-        // add support for nested arrays to scalarval
-        // i've created a new method here, so as to
-        // preserve back compatibility
-
-        if (is_array($b)) {
-            foreach ($b as $id => $cont) {
-                $b[$id] = $cont->scalarval();
-            }
-        }
-
-        // add support for structures directly encoding php objects
-        if (is_object($b)) {
-            $t = get_object_vars($b);
-            foreach ($t as $id => $cont) {
-                $t[$id] = $cont->scalarval();
-            }
-            foreach ($t as $id => $cont) {
-                eval('$b->'.$id.' = $cont;');
-            }
-        }
-
-        // end contrib
-        return $b;
-    }
-
-    /**
-     * @return mixed
-     */
-    function scalarval()
-    {
-        global $XML_RPC_Boolean, $XML_RPC_Base64;
-        reset($this->me);
-        list($a, $b) = each($this->me);
-        return $b;
-    }
-
-    /**
-     * @return string
-     */
-    function scalartyp()
-    {
-        global $XML_RPC_I4, $XML_RPC_Int;
-        reset($this->me);
-        list($a, $b) = each($this->me);
-        if ($a == $XML_RPC_I4) {
-            $a = $XML_RPC_Int;
-        }
-        return $a;
-    }
-
-    /**
-     * @return mixed  the struct's current element
-     */
-    function arraymem($m)
-    {
-        return $this->me['array'][$m];
-    }
-
-    /**
-     * @return int  the number of elements in the array
-     */
-    function arraysize()
-    {
-        reset($this->me);
-        list($a, $b) = each($this->me);
-        return sizeof($b);
-    }
-}
-
-/**
- * Return an ISO8601 encoded string
- *
- * While timezones ought to be supported, the XML-RPC spec says:
- *
- * "Don't assume a timezone. It should be specified by the server in its
- * documentation what assumptions it makes about timezones."
- *
- * This routine always assumes localtime unless $utc is set to 1, in which
- * case UTC is assumed and an adjustment for locale is made when encoding.
- *
- * @return string  the formatted date
- */
-function XML_RPC_iso8601_encode($timet, $utc = 0) {
-    if (!$utc) {
-        $t = strftime('%Y%m%dT%H:%M:%S', $timet);
-    } else {
-        if (function_exists('gmstrftime')) {
-            // gmstrftime doesn't exist in some versions
-            // of PHP
-            $t = gmstrftime('%Y%m%dT%H:%M:%S', $timet);
-        } else {
-            $t = strftime('%Y%m%dT%H:%M:%S', $timet - date('Z'));
-        }
-    }
-    return $t;
-}
-
-/**
- * Convert a datetime string into a Unix timestamp
- *
- * While timezones ought to be supported, the XML-RPC spec says:
- *
- * "Don't assume a timezone. It should be specified by the server in its
- * documentation what assumptions it makes about timezones."
- *
- * This routine always assumes localtime unless $utc is set to 1, in which
- * case UTC is assumed and an adjustment for locale is made when encoding.
- *
- * @return int  the unix timestamp of the date submitted
- */
-function XML_RPC_iso8601_decode($idate, $utc = 0) {
-    $t = 0;
-    if (ereg('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) {
-        if ($utc) {
-            $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
-        } else {
-            $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
-        }
-    }
-    return $t;
-}
-
-/**
- * Takes a message in PHP XML_RPC object format and translates it into
- * native PHP types
- *
- * @return mixed
- *
- * @author Dan Libby <dan@libby.com>
- */
-function XML_RPC_decode($XML_RPC_val)
-{
-    $kind = $XML_RPC_val->kindOf();
-
-    if ($kind == 'scalar') {
-        return $XML_RPC_val->scalarval();
-
-    } elseif ($kind == 'array') {
-        $size = $XML_RPC_val->arraysize();
-        $arr = array();
-        for ($i = 0; $i < $size; $i++) {
-            $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i));
-        }
-        return $arr;
-
-    } elseif ($kind == 'struct') {
-        $XML_RPC_val->structreset();
-        $arr = array();
-        while (list($key, $value) = $XML_RPC_val->structeach()) {
-            $arr[$key] = XML_RPC_decode($value);
-        }
-        return $arr;
-    }
-}
-
-/**
- * Takes native php types and encodes them into XML_RPC PHP object format
- *
- * Feature creep -- could support more types via optional type argument.
- *
- * @return string
- *
- * @author Dan Libby <dan@libby.com>
- */
-function XML_RPC_encode($php_val) {
-    global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double, $XML_RPC_String,
-            $XML_RPC_Array, $XML_RPC_Struct;
-
-    $type = gettype($php_val);
-    $XML_RPC_val = new XML_RPC_Value;
-
-    switch ($type) {
-    case 'array':
-        if (empty($php_val)) {
-            $XML_RPC_val->addArray($php_val);
-            break;
-        }
-        $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
-        if (empty($tmp)) {
-           $arr = array();
-           foreach ($php_val as $k => $v) {
-               $arr[$k] = XML_RPC_encode($v);
-           }
-           $XML_RPC_val->addArray($arr);
-           break;
-        }
-        // fall though if it's not an enumerated array
-
-    case 'object':
-        $arr = array();
-        foreach ($php_val as $k => $v) {
-            $arr[$k] = XML_RPC_encode($v);
-        }
-        $XML_RPC_val->addStruct($arr);
-        break;
-
-    case 'integer':
-        $XML_RPC_val->addScalar($php_val, $XML_RPC_Int);
-        break;
-
-    case 'double':
-        $XML_RPC_val->addScalar($php_val, $XML_RPC_Double);
-        break;
-
-    case 'string':
-    case 'NULL':
-        $XML_RPC_val->addScalar($php_val, $XML_RPC_String);
-        break;
-
-    case 'boolean':
-        // Add support for encoding/decoding of booleans, since they
-        // are supported in PHP
-        // by <G_Giunta_2001-02-29>
-        $XML_RPC_val->addScalar($php_val, $XML_RPC_Boolean);
-        break;
-
-    case 'unknown type':
-    default:
-        $XML_RPC_val = false;
-    }
-    return $XML_RPC_val;
-}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * c-hanging-comment-ender-p: nil
- * End:
- */
-
-?>
-XML_RPC-1.2.2/Server.php100666      0      0       36235 10213112551   7713 <?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * PHP implementation of the XML-RPC protocol
- *
- * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
- * It has support for HTTP transport, proxies and authentication.
- *
- * PHP versions 4 and 5
- *
- * LICENSE: License is granted to use or modify this software
- * ("XML-RPC for PHP") for commercial or non-commercial use provided the
- * copyright of the author is preserved in any distributed or derivative work.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    CVS: $Id: Server.php,v 1.17 2005/03/01 17:09:49 danielc Exp $
- * @link       http://pear.php.net/package/XML_RPC
- */
-
-
-/**
- * Pull in the XML_RPC class
- */
-require_once 'XML/RPC.php';
-
-
-/**
- * listMethods: either a string, or nothing
- * @global array $GLOBALS['XML_RPC_Server_listMethods_sig']
- */
-$GLOBALS['XML_RPC_Server_listMethods_sig'] = array(
-    array($GLOBALS['XML_RPC_Array'],
-          $GLOBALS['XML_RPC_String']
-    ),
-    array($GLOBALS['XML_RPC_Array'])
-);
-
-/**
- * @global string $GLOBALS['XML_RPC_Server_listMethods_doc']
- */
-$GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the'
-        . ' methods that the XML-RPC server knows how to dispatch';
-
-/**
- * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig']
- */
-$GLOBALS['XML_RPC_Server_methodSignature_sig'] = array(
-    array($GLOBALS['XML_RPC_Array'],
-          $GLOBALS['XML_RPC_String']
-    )
-);
-
-/**
- * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc']
- */
-$GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known'
-        . ' signatures (an array of arrays) for the method name passed. If'
-        . ' no signatures are known, returns a none-array (test for type !='
-        . ' array to detect missing signature)';
-
-/**
- * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig']
- */
-$GLOBALS['XML_RPC_Server_methodHelp_sig'] = array(
-    array($GLOBALS['XML_RPC_String'],
-          $GLOBALS['XML_RPC_String']
-    )
-);
-
-/**
- * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc']
- */
-$GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined'
-        . ' for the method passed, otherwise returns an empty string';
-
-/**
- * @global array $GLOBALS['XML_RPC_Server_dmap']
- */
-$GLOBALS['XML_RPC_Server_dmap'] = array(
-    'system.listMethods' => array(
-        'function'  => 'XML_RPC_Server_listMethods',
-        'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'],
-        'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc']
-    ),
-    'system.methodHelp' => array(
-        'function'  => 'XML_RPC_Server_methodHelp',
-        'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
-        'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc']
-    ),
-    'system.methodSignature' => array(
-        'function'  => 'XML_RPC_Server_methodSignature',
-        'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
-        'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc']
-    )
-);
-
-/**
- * @global string $GLOBALS['XML_RPC_Server_debuginfo']
- */
-$GLOBALS['XML_RPC_Server_debuginfo'] = '';
-
-
-/**
- * Lists all the methods that the XML-RPC server knows how to dispatch
- *
- * @return object  a new XML_RPC_Response object
- */
-function XML_RPC_Server_listMethods($server, $m)
-{
-    global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
-
-    $v = new XML_RPC_Value();
-    $dmap = $server->dmap;
-    $outAr = array();
-    for (reset($dmap); list($key, $val) = each($dmap); ) {
-        $outAr[] = new XML_RPC_Value($key, 'string');
-    }
-    $dmap = $XML_RPC_Server_dmap;
-    for (reset($dmap); list($key, $val) = each($dmap); ) {
-        $outAr[] = new XML_RPC_Value($key, 'string');
-    }
-    $v->addArray($outAr);
-    return new XML_RPC_Response($v);
-}
-
-/**
- * Returns an array of known signatures (an array of arrays)
- * for the given method
- *
- * If no signatures are known, returns a none-array
- * (test for type != array to detect missing signature)
- *
- * @return object  a new XML_RPC_Response object
- */
-function XML_RPC_Server_methodSignature($server, $m)
-{
-    global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
-
-    $methName = $m->getParam(0);
-    $methName = $methName->scalarval();
-    if (strpos($methName, 'system.') === 0) {
-        $dmap = $XML_RPC_Server_dmap;
-        $sysCall = 1;
-    } else {
-        $dmap = $server->dmap;
-        $sysCall = 0;
-    }
-    //  print "<!-- ${methName} -->\n";
-    if (isset($dmap[$methName])) {
-        if ($dmap[$methName]['signature']) {
-            $sigs = array();
-            $thesigs = $dmap[$methName]['signature'];
-            for ($i = 0; $i < sizeof($thesigs); $i++) {
-                $cursig = array();
-                $inSig = $thesigs[$i];
-                for ($j = 0; $j < sizeof($inSig); $j++) {
-                    $cursig[] = new XML_RPC_Value($inSig[$j], 'string');
-                }
-                $sigs[] = new XML_RPC_Value($cursig, 'array');
-            }
-            $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array'));
-        } else {
-            $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string'));
-        }
-    } else {
-        $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
-                                  $XML_RPC_str['introspect_unknown']);
-    }
-    return $r;
-}
-
-/**
- * Returns help text if defined for the method passed, otherwise returns
- * an empty string
- *
- * @return object  a new XML_RPC_Response object
- */
-function XML_RPC_Server_methodHelp($server, $m)
-{
-    global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
-
-    $methName = $m->getParam(0);
-    $methName = $methName->scalarval();
-    if (strpos($methName, 'system.') === 0) {
-        $dmap = $XML_RPC_Server_dmap;
-        $sysCall = 1;
-    } else {
-        $dmap = $server->dmap;
-        $sysCall = 0;
-    }
-    //  print "<!-- ${methName} -->\n";
-    if (isset($dmap[$methName])) {
-        if ($dmap[$methName]['docstring']) {
-            $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']),
-                                                        'string');
-        } else {
-            $r = new XML_RPC_Response(new XML_RPC_Value('', 'string'));
-        }
-    } else {
-        $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
-                                     $XML_RPC_str['introspect_unknown']);
-    }
-    return $r;
-}
-
-/**
- * @return void
- */
-function XML_RPC_Server_debugmsg($m)
-{
-    global $XML_RPC_Server_debuginfo;
-    $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
-}
-
-
-/**
- *
- *
- * @category   Web Services
- * @package    XML_RPC
- * @author     Edd Dumbill <edd@usefulinc.com>
- * @author     Stig Bakken <stig@php.net>
- * @author     Martin Jansen <mj@php.net>
- * @copyright  1999-2001 Edd Dumbill
- * @version    Release: 1.2.2
- * @link       http://pear.php.net/package/XML_RPC
- */
-class XML_RPC_Server
-{
-    var $dmap = array();
-    var $encoding = '';
-    var $debug = 0;
-
-    /**
-     * @return void
-     */
-    function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0)
-    {
-        global $HTTP_RAW_POST_DATA;
-
-        if ($debug) {
-            $this->debug = 1;
-        } else {
-            $this->debug = 0;
-        }
-
-        // dispMap is a despatch array of methods
-        // mapped to function names and signatures
-        // if a method
-        // doesn't appear in the map then an unknown
-        // method error is generated
-        $this->dmap = $dispMap;
-        if ($serviceNow) {
-            $this->service();
-        }
-    }
-
-    /**
-     * @return string  the debug information if debug debug mode is on
-     */
-    function serializeDebug()
-    {
-        global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA;
-
-        if ($this->debug) {
-            XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n"
-                                    . $HTTP_RAW_POST_DATA
-                                    . "\n" . '^^^ END POST DATA ^^^');
-        }
-
-        if ($XML_RPC_Server_debuginfo != '') {
-            return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n"
-                   . preg_replace('/-(?=-)/', '- ', $XML_RPC_Server_debuginfo)
-                   . "-->\n";
-        } else {
-            return '';
-        }
-    }
-
-    /**
-     * Print out the result
-     *
-     * The encoding and content-type are determined by
-     * XML_RPC_Message::getEncoding()
-     *
-     * @return void
-     *
-     * @see XML_RPC_Message::getEncoding()
-     */
-    function service()
-    {
-        $r = $this->parseRequest();
-        $payload = '<?xml version="1.0" encoding="'
-                 . $this->encoding . '"?>' . "\n"
-                 . $this->serializeDebug()
-                 . $r->serialize();
-        header('Content-Length: ' . strlen($payload));
-        header('Content-Type: text/xml; charset=' . $this->encoding);
-        print $payload;
-    }
-
-    /**
-     * @return array
-     */
-    function verifySignature($in, $sig)
-    {
-        for ($i = 0; $i < sizeof($sig); $i++) {
-            // check each possible signature in turn
-            $cursig = $sig[$i];
-            if (sizeof($cursig) == $in->getNumParams() + 1) {
-                $itsOK = 1;
-                for ($n = 0; $n < $in->getNumParams(); $n++) {
-                    $p = $in->getParam($n);
-                    // print "<!-- $p -->\n";
-                    if ($p->kindOf() == 'scalar') {
-                        $pt = $p->scalartyp();
-                    } else {
-                        $pt = $p->kindOf();
-                    }
-                    // $n+1 as first type of sig is return type
-                    if ($pt != $cursig[$n+1]) {
-                        $itsOK = 0;
-                        $pno = $n+1;
-                        $wanted = $cursig[$n+1];
-                        $got = $pt;
-                        break;
-                    }
-                }
-                if ($itsOK) {
-                    return array(1);
-                }
-            }
-        }
-        return array(0, "Wanted ${wanted}, got ${got} at param ${pno})");
-    }
-
-    /**
-     * @return object  a new XML_RPC_Response object
-     */
-    function parseRequest($data = '')
-    {
-        global $XML_RPC_xh, $HTTP_RAW_POST_DATA,
-                $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
-                $XML_RPC_defencoding, $XML_RPC_Server_dmap;
-
-        if ($data == '') {
-            $data = $HTTP_RAW_POST_DATA;
-        }
-
-        $this->encoding = XML_RPC_Message::getEncoding($data);
-        $parser = xml_parser_create($this->encoding);
-
-        $XML_RPC_xh[$parser] = array();
-        $XML_RPC_xh[$parser]['st']     = '';
-        $XML_RPC_xh[$parser]['cm']     = 0;
-        $XML_RPC_xh[$parser]['isf']    = 0;
-        $XML_RPC_xh[$parser]['params'] = array();
-        $XML_RPC_xh[$parser]['method'] = '';
-
-        $plist = '';
-
-        // decompose incoming XML into request structure
-
-        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
-        xml_set_element_handler($parser, 'XML_RPC_se', 'XML_RPC_ee');
-        xml_set_character_data_handler($parser, 'XML_RPC_cd');
-        if (!xml_parse($parser, $data, 1)) {
-            // return XML error as a faultCode
-            $r = new XML_RPC_Response(0,
-                                      $XML_RPC_errxml+xml_get_error_code($parser),
-                                      sprintf('XML error: %s at line %d',
-                                              xml_error_string(xml_get_error_code($parser)),
-                                              xml_get_current_line_number($parser)));
-            xml_parser_free($parser);
-        } else {
-            xml_parser_free($parser);
-            $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
-            // now add parameters in
-            for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
-                // print '<!-- ' . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
-                $plist .= "$i - " . $XML_RPC_xh[$parser]['params'][$i] . " \n";
-                eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i] . ');');
-            }
-            XML_RPC_Server_debugmsg($plist);
-
-            // now to deal with the method
-            $methName = $XML_RPC_xh[$parser]['method'];
-            if (strpos($methName, 'system.') === 0) {
-                $dmap = $XML_RPC_Server_dmap;
-                $sysCall = 1;
-            } else {
-                $dmap = $this->dmap;
-                $sysCall = 0;
-            }
-
-            if (isset($dmap[$methName]['function'])
-                && is_string($dmap[$methName]['function'])
-                && strpos($dmap[$methName]['function'], '::') !== false)
-            {
-                $dmap[$methName]['function'] =
-                        explode('::', $dmap[$methName]['function']);
-            }
-
-            if (isset($dmap[$methName]['function'])
-                && is_callable($dmap[$methName]['function']))
-            {
-                // dispatch if exists
-                if (isset($dmap[$methName]['signature'])) {
-                    $sr = $this->verifySignature($m,
-                                                 $dmap[$methName]['signature'] );
-                }
-                if ( (!isset($dmap[$methName]['signature'])) || $sr[0]) {
-                    // if no signature or correct signature
-                    if ($sysCall) {
-                        $r = call_user_func($dmap[$methName]['function'], $this, $m);
-                    } else {
-                        $r = call_user_func($dmap[$methName]['function'], $m);
-                    }
-                } else {
-                    $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
-                                              $XML_RPC_str['incorrect_params']
-                                              . ': ' . $sr[1]);
-                }
-            } else {
-                // else prepare error response
-                $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'],
-                                          $XML_RPC_str['unknown_method']);
-            }
-        }
-        return $r;
-    }
-
-    /**
-     * Echos back the input packet as a string value
-     *
-     * @return void
-     *
-     * Useful for debugging.
-     */
-    function echoInput() {
-        global $HTTP_RAW_POST_DATA;
-
-        $r = new XML_RPC_Response(0);
-        $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
-        print $r->serialize();
-    }
-}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * c-hanging-comment-ender-p: nil
- * End:
- */
-
-?>
-package.xml100666      0      0       15556 10213112551   6252 <?xml version="1.0" encoding="ISO-8859-1" ?>
-<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
-<package version="1.0" packagerversion="1.4.0a1">
- <name>XML_RPC</name>       
- <summary>PHP implementation of the XML-RPC protocol</summary>
- <description>A PEAR-ified version of Useful Inc's XML-RPC for PHP.
-
-It has support for HTTP/HTTPS transport, proxies and authentication.
- </description>
- <maintainers>
-  <maintainer>
-   <user>ssb</user>
-   <name>Stig Bakken</name>
-   <email>stig@php.net</email>
-   <role>lead</role>
-  </maintainer>
-  <maintainer>
-   <user>danielc</user>
-   <name>Daniel Convissor</name>
-   <email>danielc@php.net</email>
-   <role>lead</role>
-  </maintainer>
-  </maintainers>
- <release>
-  <version>1.2.2</version>
-  <date>2005-03-07</date>
-  <license>PHP License</license>
-  <state>stable</state>
-  <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec.  Bug 3679.
-  </notes>
-  <filelist>
-   <file role="php" baseinstalldir="XML" name="RPC.php">
-    <replace from="@package_version@" to="version" type="package-info"/>
-   </file>
-   <file role="php" baseinstalldir="XML/RPC" name="Server.php">
-    <replace from="@package_version@" to="version" type="package-info"/>
-   </file>
-   <file role="php" baseinstalldir="XML/RPC" name="Dump.php">
-    <replace from="@package_version@" to="version" type="package-info"/>
-   </file>
-   <file role="test" name="tests/protoport.php">
-    <replace from="@package_version@" to="version" type="package-info"/>
-   </file>
-   <file role="test" name="tests/test_Dump.php">
-    <replace from="@package_version@" to="version" type="package-info"/>
-   </file>
-  </filelist>
- </release>
- <changelog>
-   <release>
-    <version>1.2.1</version>
-    <date>2005-03-01</date>
-    <state>stable</state>
-    <notes>* Add isset() check before examining the dispatch map.  Bug 3658.
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0</version>
-    <date>2005-02-27</date>
-    <state>stable</state>
-    <notes>* Provide the &quot;stable&quot; release.
-* Add package2.xml for compatibility with PEAR 1.4.0.
-* For changes since 1.1.0, see the changelogs for the various RC releases.
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0RC7</version>
-    <date>2005-02-22</date>
-    <state>beta</state>
-    <notes>* Add the setSendEncoding() method and $send_encoding
-  property to XML_RPC_Message.  Request 3537.
-* Allow class methods to be mapped using either syntax:
-     'function' =&gt; 'hello::sayHello',
-     or
-     'function' =&gt; array('hello', 'sayhello'),
-  Bug 3363.
-* Use 8192 instead of 32768 for bytes in fread()
-  in parseResponseFile().  Bug 3340.
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0RC6</version>
-    <date>2005-01-25</date>
-    <state>beta</state>
-    <notes>* Don't put the protocol in the Host field of the POST data.  (danielc)
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0RC5</version>
-    <date>2005-01-24</date>
-    <state>beta</state>
-    <notes>* If $port is 443 but a protocol isn't specified in $server, assume ssl:// is the protocol.
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0RC4</version>
-    <date>2005-01-24</date>
-    <state>beta</state>
-    <notes>* When a connection attempt fails, have the method return 0.  (danielc)
-* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor.  (danielc)
-* Add tests for setting the client properties.  (danielc)
-* Remove $GLOBALS['XML_RPC_twoslash'] since it's not used.  (danielc)
-* Bundle the tests with the package.  (danielc)
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0RC3</version>
-    <date>2005-01-19</date>
-    <state>beta</state>
-    <notes>* ssl uses port 443, not 445.
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0RC2</version>
-    <date>2005-01-11</date>
-    <state>beta</state>
-    <notes>* Handle ssl:// in the $server string.  (danielc)
-* Also default to port 445 for ssl:// requests as well.  (danielc)
-* Enhance debugging in the server.  (danielc)
-    </notes>
-   </release>
-   <release>
-    <version>1.2.0RC1</version>
-    <date>2004-12-30</date>
-    <state>beta</state>
-    <notes>* Make things work with SSL.  Bug 2489.  (nkukard lbsd net)
-* Allow array function callbacks (Matt Kane)
-* Some minor speed-ups (Matt Kane)
-* Add Dump.php to the package (Christian Weiske)
-* Replace all line endings with \r\n.  Had only done replacements on \n.  Bug 2521.  (danielc)
-* Silence fsockopen() errors.  Bug 1714.  (danielc)
-* Encode empty arrays as an array. Bug 1493.  (danielc)
-* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode().  Bug 1819.  (danielc)
-* Speed up check for enumerated arrays in XML_RPC_Encode().  (danielc)
-* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()'ing error messages.  (danielc)
-* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded.  (danielc)
-* Allow raiseError() to be called statically.  (danielc)
-* Stop double escaping of character entities.  Bug 987.  (danielc)
-  NOTICE: the following have been removed:
-    * XML_RPC_dh()
-    * $GLOBALS['XML_RPC_entities']
-    * XML_RPC_entity_decode()
-    * XML_RPC_lookup_entity()
-* Determine the XML's encoding via the encoding attribute in the XML declaration.  Bug 52.  (danielc)
-    </notes>
-   </release>
-   <release>
-    <version>1.1.0</version>
-    <date>2004-03-15</date>
-    <state>stable</state>
-    <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
-* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
-* Remove &quot;require_once 'PEAR.php'&quot;, include only when needed to raise an error
-* Replace echo and error_log() with raiseError() (mroch)
-* Make all classes extend XML_RPC_Base, which will handle common functions  (mroch)
-* be tolerant of junk after methodResponse (Luca Mariano, mroch)
-* Silent notice even in the error log (pierre)
-* fix include of shared xml extension on win32 (pierre)
-    </notes>
-   </release>
-   <release>
-    <version>1.0.4</version>
-    <date>2002-10-02</date>
-    <state>stable</state>
-    <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)
-    </notes>
-   </release>
-   <release>
-    <version>1.0.3</version>
-    <date>2002-05-19</date>
-    <state>stable</state>
-    <notes>* fix bug when parsing responses with boolean types
-    </notes>
-   </release>
-   <release>
-    <version>1.0.2</version>
-    <date>2002-04-16</date>
-    <state>stable</state>
-    <notes>* E_ALL fixes
-* fix HTTP response header parsing
-    </notes>
-   </release>
-   <release>
-    <version>1.0.1</version>
-    <date>2001-09-25</date>
-    <state>stable</state>
-    <notes>This is a PEAR-ified version of Useful Inc's 1.0.1 release.
-Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.
-    </notes>
-   </release>
- </changelog>
-</package>
-
\ Kein Zeilenumbruch am Dateiende.
diff -Nura php-5.0.4/pear/packages/XML_RPC-1.3.1.tar hardening-patch-5.0.4-0.4.1/pear/packages/XML_RPC-1.3.1.tar
--- php-5.0.4/pear/packages/XML_RPC-1.3.1.tar	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/pear/packages/XML_RPC-1.3.1.tar	2005-08-04 12:06:45.000000000 +0200
@@ -0,0 +1,3733 @@
+package2.xml100644   1750    144       32557 10260516576   6517 <?xml version="1.0"?>
+<package packagerversion="1.4.0a12" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0     http://pear.php.net/dtd/tasks-1.0.xsd     http://pear.php.net/dtd/package-2.0     http://pear.php.net/dtd/package-2.0.xsd">
+ <name>XML_RPC</name>
+ <channel>pear.php.net</channel>
+ <summary>PHP implementation of the XML-RPC protocol</summary>
+ <description>A PEAR-ified version of Useful Inc&apos;s XML-RPC for PHP.
+
+It has support for HTTP/HTTPS transport, proxies and authentication.</description>
+ <lead>
+  <name>Stig Bakken</name>
+  <user>ssb</user>
+  <email>stig@php.net</email>
+  <active>no</active>
+ </lead>
+ <lead>
+  <name>Daniel Convissor</name>
+  <user>danielc</user>
+  <email>danielc@php.net</email>
+  <active>yes</active>
+ </lead>
+ <date>2005-06-29</date>
+ <time>15:09:18</time>
+ <version>
+  <release>1.3.1</release>
+  <api>1.3.0</api>
+ </version>
+ <stability>
+  <release>stable</release>
+  <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+ <notes>* Security fix. Update highly recommended!</notes>
+ <contents>
+  <dir name="/">
+   <file md5sum="9b06c053e8e534f8d731eb90de2d0681" name="tests/protoport.php" role="test">
+    <tasks:replace from="@package_version@" to="version" type="package-info" />
+   </file>
+   <file md5sum="74d1c90ae551d28bd40030fcc0b0f38d" name="tests/test_Dump.php" role="test">
+    <tasks:replace from="@package_version@" to="version" type="package-info" />
+   </file>
+   <file baseinstalldir="XML/RPC" md5sum="5e2dfc5771116965655e07b4665563ce" name="Dump.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info" />
+   </file>
+   <file baseinstalldir="XML" md5sum="1e79cf06ae3ada5a6603c003ac0521e3" name="RPC.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info" />
+   </file>
+   <file baseinstalldir="XML/RPC" md5sum="6a750e3517d25ca01e685e8afe3976d6" name="Server.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info" />
+   </file>
+  </dir>
+ </contents>
+ <compatible>
+  <name>PEAR</name>
+  <channel>pear.php.net</channel>
+  <min>1.4.0a1</min>
+  <max>1.4.0a12</max>
+ </compatible>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.2.0</min>
+    <max>6.0.0</max>
+   </php>
+   <pearinstaller>
+    <min>1.4.0a1</min>
+   </pearinstaller>
+  </required>
+ </dependencies>
+ <phprelease />
+ <changelog>
+  <release>
+   <version>
+    <release>1.3.0RC3</release>
+    <api>1.3.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>stable</api>
+   </stability>
+   <date>2005-05-10</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* When verifying requests against function signatures, if the number of parameters don&apos;t match, provide an appropriate message.  NOTE: this resolves a path disclosure vulnerability.  (Refines the changes made in the last commit.)  Bug 4231.
+* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error.  Changed from Release 1.3.0RC2.
+* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
+* If XML_RPC_Client::send() is given an incorrect $msg parameter, raise an error with the new XML_RPC_ERROR_PROGRAMMING code and return 0.
+* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
+* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.3.0RC2</release>
+    <api>1.3.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-05-05</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* If XML_RPC_Message::getParam() is given an incorrect parameter, raise an error with the new XML_RPC_ERROR_INCORRECT_PARAMS code and return FALSE.
+* Handle improper requests to XML_RPC_Server::verifySignature().  Bug 4231.
+* Try to allow HTTP 100 responses if followed by a 200 response.  Bug 4116.
+* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME.  Request 4205.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.3.0RC1</release>
+    <api>1.3.0</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-04-07</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Improve timeout handling for situations where connection to server is made but no response is not received in time. Accomplished via stream_set_timeout().  Request 3963.
+* Add Fault Code 6: &quot;The requested method didn&apos;t return an XML_RPC_Response object.&quot;  Request 4032.
+* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties.  Request 3121.
+* As in earlier versions, if the $serviceNow parameter to XML_RPC_Server() is 0, no data will be returned, but now the new $server_payload and $server_headers properties will be set.
+* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser].  Reduces E_STRICT notices.  Bug 3782.
+* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.2</release>
+    <api>1.2.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2005-03-07</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec.  Bug 3679.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.1</release>
+    <api>1.2.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2005-03-01</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Add isset() check before examining the dispatch map.  Bug 3658.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0</release>
+    <api>1.2.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2005-02-27</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Provide the &quot;stable&quot; release.
+* Add package2.xml for compatibility with PEAR 1.4.0.
+* For changes since 1.1.0, see the changelogs for the various RC releases.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0RC7</release>
+    <api>1.2.0RC7</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-02-22</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Add the setSendEncoding() method and $send_encoding
+  property to XML_RPC_Message.  Request 3537.
+* Allow class methods to be mapped using either syntax:
+     &apos;function&apos; =&gt; &apos;hello::sayHello&apos;,
+     or
+     &apos;function&apos; =&gt; array(&apos;hello&apos;, &apos;sayhello&apos;),
+  Bug 3363.
+* Use 8192 instead of 32768 for bytes in fread()
+  in parseResponseFile().  Bug 3340.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0RC6</release>
+    <api>1.2.0RC6</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-01-25</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Don&apos;t put the protocol in the Host field of the POST data.  (danielc)</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0RC5</release>
+    <api>1.2.0RC5</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-01-24</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* If $port is 443 but a protocol isn&apos;t specified in $server, assume ssl:// is the protocol.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0RC4</release>
+    <api>1.2.0RC4</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-01-24</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* When a connection attempt fails, have the method return 0.  (danielc)
+* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor.  (danielc)
+* Add tests for setting the client properties.  (danielc)
+* Remove $GLOBALS[&apos;XML_RPC_twoslash&apos;] since it&apos;s not used.  (danielc)
+* Bundle the tests with the package.  (danielc)</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0RC3</release>
+    <api>1.2.0RC3</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-01-19</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* ssl uses port 443, not 445.</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0RC2</release>
+    <api>1.2.0RC2</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2005-01-11</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Handle ssl:// in the $server string.  (danielc)
+* Also default to port 445 for ssl:// requests as well.  (danielc)
+* Enhance debugging in the server.  (danielc)</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.2.0RC1</release>
+    <api>1.2.0RC1</api>
+   </version>
+   <stability>
+    <release>beta</release>
+    <api>beta</api>
+   </stability>
+   <date>2004-12-30</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Make things work with SSL.  Bug 2489.  (nkukard lbsd net)
+* Allow array function callbacks (Matt Kane)
+* Some minor speed-ups (Matt Kane)
+* Add Dump.php to the package (Christian Weiske)
+* Replace all line endings with \r\n.  Had only done replacements on \n.  Bug 2521.  (danielc)
+* Silence fsockopen() errors.  Bug 1714.  (danielc)
+* Encode empty arrays as an array. Bug 1493.  (danielc)
+* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode().  Bug 1819.  (danielc)
+* Speed up check for enumerated arrays in XML_RPC_Encode().  (danielc)
+* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()&apos;ing error messages.  (danielc)
+* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded.  (danielc)
+* Allow raiseError() to be called statically.  (danielc)
+* Stop double escaping of character entities.  Bug 987.  (danielc)
+  NOTICE: the following have been removed:
+    * XML_RPC_dh()
+    * $GLOBALS[&apos;XML_RPC_entities&apos;]
+    * XML_RPC_entity_decode()
+    * XML_RPC_lookup_entity()
+* Determine the XML&apos;s encoding via the encoding attribute in the XML declaration.  Bug 52.  (danielc)</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.1.0</release>
+    <api>1.1.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2004-03-15</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
+* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
+* Remove &quot;require_once &apos;PEAR.php&apos;&quot;, include only when needed to raise an error
+* Replace echo and error_log() with raiseError() (mroch)
+* Make all classes extend XML_RPC_Base, which will handle common functions  (mroch)
+* be tolerant of junk after methodResponse (Luca Mariano, mroch)
+* Silent notice even in the error log (pierre)
+* fix include of shared xml extension on win32 (pierre)</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.0.4</release>
+    <api>1.0.4</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2002-10-02</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.0.3</release>
+    <api>1.0.3</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2002-05-19</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* fix bug when parsing responses with boolean types</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.0.2</release>
+    <api>1.0.2</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2002-04-16</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>* E_ALL fixes
+* fix HTTP response header parsing</notes>
+  </release>
+  <release>
+   <version>
+    <release>1.0.1</release>
+    <api>1.0.1</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2001-09-25</date>
+   <license uri="http://www.php.net/license/3_0.txt">PHP License</license>
+   <notes>This is a PEAR-ified version of Useful Inc&apos;s 1.0.1 release.
+Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.</notes>
+  </release>
+ </changelog>
+</package>
+XML_RPC-1.3.1/tests/protoport.php100644   1750    144       25543 10260516576  12042 <?php
+
+/**
+ * Tests that properties of XML_RPC_Client get properly set
+ *
+ * Any individual tests that fail will have their name, expected result
+ * and actual result printed out.  So seeing no output when executing
+ * this file is a good thing.
+ *
+ * Can be run via CLI or a web server.
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: This source file is subject to version 3.0 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
+ * the PHP License and are unable to obtain it through the web, please
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  2005 The PHP Group
+ * @license    http://www.php.net/license/3_0.txt  PHP License
+ * @version    CVS: $Id: protoport.php,v 1.4 2005/01/24 17:48:47 danielc Exp $
+ * @link       http://pear.php.net/package/XML_RPC
+ * @since      File available since Release 1.2
+ */
+
+/*
+ * If the package version number is found in the left hand
+ * portion of the if() expression below, that means this file has
+ * come from the PEAR installer.  Therefore, let's test the
+ * installed version of XML_RPC which should be in the include path.
+ * 
+ * If the version has not been substituted in the if() expression,
+ * this file has likely come from a CVS checkout or a .tar file.
+ * Therefore, we'll assume the tests should use the version of
+ * XML_RPC that has come from there as well.
+ */
+if ('1.3.1' != '@'.'package_version'.'@') {
+    /**
+     * Get the needed class from the PEAR installation
+     */
+    require_once 'XML/RPC.php';
+} else {
+    /**
+     * Get the needed class from the parent directory
+     */
+    require_once '../RPC.php';
+}
+
+/**
+ * Compare the test result to the expected result
+ *
+ * If the test fails, echo out the results.
+ *
+ * @param array  $expect     the array of object properties you expect
+ *                            from the test
+ * @param object $actual     the object results from the test
+ * @param string $test_name  the name of the test
+ *
+ * @return void
+ */
+function compare($expect, $actual, $test_name) {
+    $actual = get_object_vars($actual);
+    if (count(array_diff($actual, $expect))) {
+        echo "$test_name failed.\nExpect: ";
+        print_r($expect);
+        echo "Actual: ";
+        print_r($actual);
+        echo "\n";
+    }
+}
+
+if (php_sapi_name() != 'cli') {
+    echo "<pre>\n";
+}
+
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 80,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'theserver');
+compare($x, $c, 'defaults');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 80,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'http://theserver');
+compare($x, $c, 'defaults with http');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 443,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'https://theserver');
+compare($x, $c, 'defaults with https');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 443,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'ssl://theserver');
+compare($x, $c, 'defaults with ssl');
+
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 65,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'theserver', 65);
+compare($x, $c, 'port 65');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 65,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'http://theserver', 65);
+compare($x, $c, 'port 65 with http');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 65,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'https://theserver', 65);
+compare($x, $c, 'port 65 with https');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 65,
+    'proxy' => '',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65);
+compare($x, $c, 'port 65 with ssl');
+
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 80,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'theserver', 0,
+                        'theproxy');
+compare($x, $c, 'defaults proxy');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 80,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 8080,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'http://theserver', 0,
+                        'http://theproxy');
+compare($x, $c, 'defaults with http proxy');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 443,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'ssl://',
+    'proxy_port' => 443,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'https://theserver', 0,
+                        'https://theproxy');
+compare($x, $c, 'defaults with https proxy');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 443,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'ssl://',
+    'proxy_port' => 443,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 0,
+                        'ssl://theproxy');
+compare($x, $c, 'defaults with ssl proxy');
+
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 65,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 6565,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'theserver', 65,
+                        'theproxy', 6565);
+compare($x, $c, 'port 65 proxy 6565');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 65,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'http://',
+    'proxy_port' => 6565,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'http://theserver', 65,
+                        'http://theproxy', 6565);
+compare($x, $c, 'port 65 with http proxy 6565');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 65,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'ssl://',
+    'proxy_port' => 6565,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'https://theserver', 65,
+                        'https://theproxy', 6565);
+compare($x, $c, 'port 65 with https proxy 6565');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 65,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'ssl://',
+    'proxy_port' => 6565,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'ssl://theserver', 65,
+                        'ssl://theproxy', 6565);
+compare($x, $c, 'port 65 with ssl proxy 6565');
+
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'ssl://',
+    'port' => 443,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'ssl://',
+    'proxy_port' => 443,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'theserver', 443,
+                        'theproxy', 443);
+compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
+
+$x = array(
+    'path' => 'thepath',
+    'server' => 'theserver',
+    'protocol' => 'http://',
+    'port' => 80,
+    'proxy' => 'theproxy',
+    'proxy_protocol' => 'ssl://',
+    'proxy_port' => 6565,
+    'proxy_user' => '',
+    'proxy_pass' => '',
+    'errno' => 0,
+    'errstring' => '',
+    'debug' => 0,
+    'username' => '',
+    'password' => '',
+);
+$c = new XML_RPC_Client('thepath', 'theserver', 0,
+                        'ssl://theproxy', 6565);
+compare($x, $c, 'port 443 no protocol and proxy port 443 no protocol');
+XML_RPC-1.3.1/tests/test_Dump.php100644   1750    144        3042 10260516576  11704 <?php
+
+/*
+ * If the package version number is found in the left hand
+ * portion of the if() expression below, that means this file has
+ * come from the PEAR installer.  Therefore, let's test the
+ * installed version of XML_RPC which should be in the include path.
+ * 
+ * If the version has not been substituted in the if() expression,
+ * this file has likely come from a CVS checkout or a .tar file.
+ * Therefore, we'll assume the tests should use the version of
+ * XML_RPC that has come from there as well.
+ */
+if ('1.3.1' != '@'.'package_version'.'@') {
+    /**
+     * Get the needed class from the PEAR installation
+     */
+    require_once 'XML/RPC/Dump.php';
+} else {
+    /**
+     * Get the needed class from the parent directory
+     */
+    require_once '../Dump.php';
+}
+
+$val = new XML_RPC_Value(array(
+    'title'    =>new XML_RPC_Value('das ist der Titel', 'string'),
+    'startDate'=>new XML_RPC_Value(mktime(0,0,0,13,11,2004), 'dateTime.iso8601'),
+    'endDate'  =>new XML_RPC_Value(mktime(0,0,0,15,11,2004), 'dateTime.iso8601'),
+    'error'    =>'string',
+    'arkey'    => new XML_RPC_Value( array(
+        new XML_RPC_Value('simple string'),
+        new XML_RPC_Value(12345, 'int')
+        ), 'array')
+    )
+    ,'struct');
+
+XML_RPC_Dump($val);
+
+echo '==============' . "\r\n";
+$val2 = new XML_RPC_Value(44353, 'int');
+XML_RPC_Dump($val2);
+
+echo '==============' . "\r\n";
+$val3 = new XML_RPC_Value('this should be a string', 'string');
+XML_RPC_Dump($val3);
+
+echo '==============' . "\r\n";
+$val4 = new XML_RPC_Value(true, 'boolean');
+XML_RPC_Dump($val4);
+XML_RPC-1.3.1/Dump.php100644   1750    144       12074 10260516576   7530 <?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Function and class to dump XML_RPC_Value objects in a nice way
+ *
+ * Should be helpful as a normal var_dump(..) displays all internals which
+ * doesn't really give you an overview due to too much information.
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Christian Weiske <cweiske@php.net>
+ * @version    CVS: $Id: Dump.php,v 1.7 2005/01/24 03:47:55 danielc Exp $
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+
+
+/**
+ * Pull in the XML_RPC class
+ */
+require_once 'XML/RPC.php';
+
+
+/**
+ * Generates the dump of the XML_RPC_Value and echoes it
+ *
+ * @param object $value  the XML_RPC_Value object to dump
+ *
+ * @return void
+ */
+function XML_RPC_Dump($value)
+{
+    $dumper = new XML_RPC_Dump();
+    echo $dumper->generateDump($value);
+}
+
+
+/**
+ * Class which generates a dump of a XML_RPC_Value object
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Christian Weiske <cweiske@php.net>
+ * @version    Release: 1.3.1
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+class XML_RPC_Dump
+{
+    /**
+     * The indentation array cache
+     * @var array
+     */
+    var $arIndent      = array();
+
+    /**
+     * The spaces used for indenting the XML
+     * @var string
+     */
+    var $strBaseIndent = '    ';
+
+    /**
+     * Returns the dump in XML format without printing it out
+     *
+     * @param object $value   the XML_RPC_Value object to dump
+     * @param int    $nLevel  the level of indentation
+     *
+     * @return string  the dump
+     */
+    function generateDump($value, $nLevel = 0)
+    {
+        if (!is_object($value) && get_class($value) != 'xml_rpc_value') {
+            require_once 'PEAR.php';
+            PEAR::raiseError('Tried to dump non-XML_RPC_Value variable' . "\r\n",
+                             0, PEAR_ERROR_PRINT);
+            if (is_object($value)) {
+                $strType = get_class($value);
+            } else {
+                $strType = gettype($value);
+            }
+            return $this->getIndent($nLevel) . 'NOT A XML_RPC_Value: '
+                   . $strType . "\r\n";
+        }
+
+        switch ($value->kindOf()) {
+        case 'struct':
+            $ret = $this->genStruct($value, $nLevel);
+            break;
+        case 'array':
+            $ret = $this->genArray($value, $nLevel);
+            break;
+        case 'scalar':
+            $ret = $this->genScalar($value->scalarval(), $nLevel);
+            break;
+        default:
+            require_once 'PEAR.php';
+            PEAR::raiseError('Illegal type "' . $value->kindOf()
+                             . '" in XML_RPC_Value' . "\r\n", 0,
+                             PEAR_ERROR_PRINT);
+        }
+
+        return $ret;
+    }
+
+    /**
+     * Returns the scalar value dump
+     *
+     * @param object $value   the scalar XML_RPC_Value object to dump
+     * @param int    $nLevel  the level of indentation
+     *
+     * @return string  Dumped version of the scalar value
+     */
+    function genScalar($value, $nLevel)
+    {
+        if (gettype($value) == 'object') {
+            $strClass = ' ' . get_class($value);
+        } else {
+            $strClass = '';
+        }
+        return $this->getIndent($nLevel) . gettype($value) . $strClass
+               . ' ' . $value . "\r\n";
+    }
+
+    /**
+     * Returns the dump of a struct
+     *
+     * @param object $value   the struct XML_RPC_Value object to dump
+     * @param int    $nLevel  the level of indentation
+     *
+     * @return string  Dumped version of the scalar value
+     */
+    function genStruct($value, $nLevel)
+    {
+        $value->structreset();
+        $strOutput = $this->getIndent($nLevel) . 'struct' . "\r\n";
+        while (list($key, $keyval) = $value->structeach()) {
+            $strOutput .= $this->getIndent($nLevel + 1) . $key . "\r\n";
+            $strOutput .= $this->generateDump($keyval, $nLevel + 2);
+        }
+        return $strOutput;
+    }
+
+    /**
+     * Returns the dump of an array
+     *
+     * @param object $value   the array XML_RPC_Value object to dump
+     * @param int    $nLevel  the level of indentation
+     *
+     * @return string  Dumped version of the scalar value
+     */
+    function genArray($value, $nLevel)
+    {
+        $nSize     = $value->arraysize();
+        $strOutput = $this->getIndent($nLevel) . 'array' . "\r\n";
+        for($nA = 0; $nA < $nSize; $nA++) {
+            $strOutput .= $this->getIndent($nLevel + 1) . $nA . "\r\n";
+            $strOutput .= $this->generateDump($value->arraymem($nA),
+                                              $nLevel + 2);
+        }
+        return $strOutput;
+    }
+
+    /**
+     * Returns the indent for a specific level and caches it for faster use
+     *
+     * @param int $nLevel  the level
+     *
+     * @return string  the indented string
+     */
+    function getIndent($nLevel)
+    {
+        if (!isset($this->arIndent[$nLevel])) {
+            $this->arIndent[$nLevel] = str_repeat($this->strBaseIndent, $nLevel);
+        }
+        return $this->arIndent[$nLevel];
+    }
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * c-hanging-comment-ender-p: nil
+ * End:
+ */
+
+?>
+XML_RPC-1.3.1/RPC.php100644   1750    144      150065 10260516576   7272 <?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * PHP implementation of the XML-RPC protocol
+ *
+ * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
+ * It has support for HTTP transport, proxies and authentication.
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: License is granted to use or modify this software
+ * ("XML-RPC for PHP") for commercial or non-commercial use provided the
+ * copyright of the author is preserved in any distributed or derivative work.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    CVS: $Id: RPC.php,v 1.74 2005/05/09 20:51:54 danielc Exp $
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+
+
+if (!function_exists('xml_parser_create')) {
+    PEAR::loadExtension('xml');
+}
+
+/**#@+
+ * Error constants
+ */
+/**
+ * Parameter values don't match parameter types
+ */
+define('XML_RPC_ERROR_INVALID_TYPE', 101);
+/**
+ * Parameter declared to be numeric but the values are not
+ */
+define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102);
+/**
+ * Communication error
+ */
+define('XML_RPC_ERROR_CONNECTION_FAILED', 103);
+/**
+ * The array or struct has already been started
+ */
+define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104);
+/**
+ * Incorrect parameters submitted
+ */
+define('XML_RPC_ERROR_INCORRECT_PARAMS', 105);
+/**
+ * Programming error by developer
+ */
+define('XML_RPC_ERROR_PROGRAMMING', 106);
+/**#@-*/
+
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_I4']
+ */
+$GLOBALS['XML_RPC_I4'] = 'i4';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_Int']
+ */
+$GLOBALS['XML_RPC_Int'] = 'int';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_Boolean']
+ */
+$GLOBALS['XML_RPC_Boolean'] = 'boolean';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_Double']
+ */
+$GLOBALS['XML_RPC_Double'] = 'double';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_String']
+ */
+$GLOBALS['XML_RPC_String'] = 'string';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_DateTime']
+ */
+$GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_Base64']
+ */
+$GLOBALS['XML_RPC_Base64'] = 'base64';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_Array']
+ */
+$GLOBALS['XML_RPC_Array'] = 'array';
+
+/**
+ * Data types
+ * @global string $GLOBALS['XML_RPC_Struct']
+ */
+$GLOBALS['XML_RPC_Struct'] = 'struct';
+
+
+/**
+ * Data type meta-types
+ * @global array $GLOBALS['XML_RPC_Types']
+ */
+$GLOBALS['XML_RPC_Types'] = array(
+    $GLOBALS['XML_RPC_I4']       => 1,
+    $GLOBALS['XML_RPC_Int']      => 1,
+    $GLOBALS['XML_RPC_Boolean']  => 1,
+    $GLOBALS['XML_RPC_String']   => 1,
+    $GLOBALS['XML_RPC_Double']   => 1,
+    $GLOBALS['XML_RPC_DateTime'] => 1,
+    $GLOBALS['XML_RPC_Base64']   => 1,
+    $GLOBALS['XML_RPC_Array']    => 2,
+    $GLOBALS['XML_RPC_Struct']   => 3,
+);
+
+
+/**
+ * Error message numbers
+ * @global array $GLOBALS['XML_RPC_err']
+ */
+$GLOBALS['XML_RPC_err'] = array(
+    'unknown_method'      => 1,
+    'invalid_return'      => 2,
+    'incorrect_params'    => 3,
+    'introspect_unknown'  => 4,
+    'http_error'          => 5,
+    'not_response_object' => 6,
+);
+
+/**
+ * Error message strings
+ * @global array $GLOBALS['XML_RPC_str']
+ */
+$GLOBALS['XML_RPC_str'] = array(
+    'unknown_method'      => 'Unknown method',
+    'invalid_return'      => 'Invalid return payload: enable debugging to examine incoming payload',
+    'incorrect_params'    => 'Incorrect parameters passed to method',
+    'introspect_unknown'  => 'Can\'t introspect: method unknown',
+    'http_error'          => 'Didn\'t receive 200 OK from remote server.',
+    'not_response_object' => 'The requested method didn\'t return an XML_RPC_Response object.',
+);
+
+
+/**
+ * Default XML encoding (ISO-8859-1, UTF-8 or US-ASCII)
+ * @global string $GLOBALS['XML_RPC_defencoding']
+ */
+$GLOBALS['XML_RPC_defencoding'] = 'UTF-8';
+
+/**
+ * User error codes start at 800
+ * @global int $GLOBALS['XML_RPC_erruser']
+ */
+$GLOBALS['XML_RPC_erruser'] = 800;
+
+/**
+ * XML parse error codes start at 100
+ * @global int $GLOBALS['XML_RPC_errxml']
+ */
+$GLOBALS['XML_RPC_errxml'] = 100;
+
+
+/**
+ * Compose backslashes for escaping regexp
+ * @global string $GLOBALS['XML_RPC_backslash']
+ */
+$GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92);
+
+
+/**
+ * Stores state during parsing
+ *
+ * quick explanation of components:
+ *   + st     = builds up a string for evaluation
+ *   + ac     = accumulates values
+ *   + qt     = decides if quotes are needed for evaluation
+ *   + cm     = denotes struct or array (comma needed)
+ *   + isf    = indicates a fault
+ *   + lv     = indicates "looking for a value": implements the logic
+ *               to allow values with no types to be strings
+ *   + params = stores parameters in method calls
+ *   + method = stores method name
+ *
+ * @global array $GLOBALS['XML_RPC_xh']
+ */
+$GLOBALS['XML_RPC_xh'] = array();
+
+
+/**
+ * Start element handler for the XML parser
+ *
+ * @return void
+ */
+function XML_RPC_se($parser_resource, $name, $attrs)
+{
+    global $XML_RPC_xh, $XML_RPC_DateTime, $XML_RPC_String;
+    $parser = (int) $parser_resource;
+
+    switch ($name) {
+    case 'STRUCT':
+    case 'ARRAY':
+        $XML_RPC_xh[$parser]['st'] .= 'array(';
+        $XML_RPC_xh[$parser]['cm']++;
+        // this last line turns quoting off
+        // this means if we get an empty array we'll
+        // simply get a bit of whitespace in the eval
+        $XML_RPC_xh[$parser]['qt'] = 0;
+        break;
+
+    case 'NAME':
+        $XML_RPC_xh[$parser]['st'] .= '"';
+        $XML_RPC_xh[$parser]['ac'] = '';
+        break;
+
+    case 'FAULT':
+        $XML_RPC_xh[$parser]['isf'] = 1;
+        break;
+
+    case 'PARAM':
+        $XML_RPC_xh[$parser]['st'] = '';
+        break;
+
+    case 'VALUE':
+        $XML_RPC_xh[$parser]['st'] .= 'new XML_RPC_Value(';
+        $XML_RPC_xh[$parser]['lv'] = 1;
+        $XML_RPC_xh[$parser]['vt'] = $XML_RPC_String;
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['qt'] = 0;
+        // look for a value: if this is still 1 by the
+        // time we reach the first data segment then the type is string
+        // by implication and we need to add in a quote
+        break;
+
+    case 'I4':
+    case 'INT':
+    case 'STRING':
+    case 'BOOLEAN':
+    case 'DOUBLE':
+    case 'DATETIME.ISO8601':
+    case 'BASE64':
+        $XML_RPC_xh[$parser]['ac'] = ''; // reset the accumulator
+
+        if ($name == 'DATETIME.ISO8601' || $name == 'STRING') {
+            $XML_RPC_xh[$parser]['qt'] = 1;
+
+            if ($name == 'DATETIME.ISO8601') {
+                $XML_RPC_xh[$parser]['vt'] = $XML_RPC_DateTime;
+            }
+
+        } elseif ($name == 'BASE64') {
+            $XML_RPC_xh[$parser]['qt'] = 2;
+        } else {
+            // No quoting is required here -- but
+            // at the end of the element we must check
+            // for data format errors.
+            $XML_RPC_xh[$parser]['qt'] = 0;
+        }
+        break;
+
+    case 'MEMBER':
+        $XML_RPC_xh[$parser]['ac'] = '';
+    }
+
+    if ($name != 'VALUE') {
+        $XML_RPC_xh[$parser]['lv'] = 0;
+    }
+}
+
+/**
+ * End element handler for the XML parser
+ *
+ * @return void
+ */
+function XML_RPC_ee($parser_resource, $name)
+{
+    global $XML_RPC_xh, $XML_RPC_Types, $XML_RPC_String;
+    $parser = (int) $parser_resource;
+
+    switch ($name) {
+    case 'STRUCT':
+    case 'ARRAY':
+        if ($XML_RPC_xh[$parser]['cm']
+            && substr($XML_RPC_xh[$parser]['st'], -1) == ',')
+        {
+            $XML_RPC_xh[$parser]['st'] = substr($XML_RPC_xh[$parser]['st'], 0, -1);
+        }
+
+        $XML_RPC_xh[$parser]['st'] .= ')';
+        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
+        $XML_RPC_xh[$parser]['cm']--;
+        break;
+
+    case 'NAME':
+        $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . '" => ';
+        break;
+
+    case 'BOOLEAN':
+        // special case here: we translate boolean 1 or 0 into PHP
+        // constants true or false
+        if ($XML_RPC_xh[$parser]['ac'] == '1') {
+            $XML_RPC_xh[$parser]['ac'] = 'true';
+        } else {
+            $XML_RPC_xh[$parser]['ac'] = 'false';
+        }
+
+        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
+        // Drop through intentionally.
+
+    case 'I4':
+    case 'INT':
+    case 'STRING':
+    case 'DOUBLE':
+    case 'DATETIME.ISO8601':
+    case 'BASE64':
+        if ($XML_RPC_xh[$parser]['qt'] == 1) {
+            // we use double quotes rather than single so backslashification works OK
+            $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
+        } elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
+            $XML_RPC_xh[$parser]['st'] .= 'base64_decode("'
+                                        . $XML_RPC_xh[$parser]['ac'] . '")';
+        } elseif ($name == 'BOOLEAN') {
+            $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
+        } else {
+            // we have an I4, INT or a DOUBLE
+            // we must check that only 0123456789-.<space> are characters here
+            if (!ereg("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) {
+                XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE',
+                                         XML_RPC_ERROR_NON_NUMERIC_FOUND);
+                $XML_RPC_xh[$parser]['st'] .= 'XML_RPC_ERROR_NON_NUMERIC_FOUND';
+            } else {
+                // it's ok, add it on
+                $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
+            }
+        }
+
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['qt'] = 0;
+        $XML_RPC_xh[$parser]['lv'] = 3; // indicate we've found a value
+        break;
+
+    case 'VALUE':
+        // deal with a string value
+        if (strlen($XML_RPC_xh[$parser]['ac']) > 0 &&
+            $XML_RPC_xh[$parser]['vt'] == $XML_RPC_String) {
+
+            $XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
+        }
+
+        // This if () detects if no scalar was inside <VALUE></VALUE>
+        // and pads an empty "".
+        if ($XML_RPC_xh[$parser]['st'][strlen($XML_RPC_xh[$parser]['st'])-1] == '(') {
+            $XML_RPC_xh[$parser]['st'] .= '""';
+        }
+        $XML_RPC_xh[$parser]['st'] .= ", '" . $XML_RPC_xh[$parser]['vt'] . "')";
+        if ($XML_RPC_xh[$parser]['cm']) {
+            $XML_RPC_xh[$parser]['st'] .= ',';
+        }
+        break;
+
+    case 'MEMBER':
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['qt'] = 0;
+        break;
+
+    case 'DATA':
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['qt'] = 0;
+        break;
+
+    case 'PARAM':
+        $XML_RPC_xh[$parser]['params'][] = $XML_RPC_xh[$parser]['st'];
+        break;
+
+    case 'METHODNAME':
+    case 'RPCMETHODNAME':
+        $XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", '',
+                                                      $XML_RPC_xh[$parser]['ac']);
+        break;
+    }
+
+    // if it's a valid type name, set the type
+    if (isset($XML_RPC_Types[strtolower($name)])) {
+        $XML_RPC_xh[$parser]['vt'] = strtolower($name);
+    }
+}
+
+/**
+ * Character data handler for the XML parser
+ *
+ * @return void
+ */
+function XML_RPC_cd($parser_resource, $data)
+{
+    global $XML_RPC_xh, $XML_RPC_backslash;
+    $parser = (int) $parser_resource;
+
+    if ($XML_RPC_xh[$parser]['lv'] != 3) {
+        // "lookforvalue==3" means that we've found an entire value
+        // and should discard any further character data
+
+        if ($XML_RPC_xh[$parser]['lv'] == 1) {
+            // if we've found text and we're just in a <value> then
+            // turn quoting on, as this will be a string
+            $XML_RPC_xh[$parser]['qt'] = 1;
+            // and say we've found a value
+            $XML_RPC_xh[$parser]['lv'] = 2;
+        }
+
+        // replace characters that eval would
+        // do special things with
+        if (!isset($XML_RPC_xh[$parser]['ac'])) {
+            $XML_RPC_xh[$parser]['ac'] = '';
+        }
+        $XML_RPC_xh[$parser]['ac'] .= str_replace('$', '\$',
+            str_replace('"', '\"', str_replace(chr(92),
+            $XML_RPC_backslash, $data)));
+    }
+}
+
+/**
+ * The common methods and properties for all of the XML_RPC classes
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    Release: 1.3.1
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+class XML_RPC_Base {
+
+    /**
+     * PEAR Error handling
+     *
+     * @return object  PEAR_Error object
+     */
+    function raiseError($msg, $code)
+    {
+        include_once 'PEAR.php';
+        if (is_object(@$this)) {
+            return PEAR::raiseError(get_class($this) . ': ' . $msg, $code);
+        } else {
+            return PEAR::raiseError('XML_RPC: ' . $msg, $code);
+        }
+    }
+
+    /**
+     * Tell whether something is a PEAR_Error object
+     *
+     * @param mixed $value  the item to check
+     *
+     * @return bool  whether $value is a PEAR_Error object or not
+     *
+     * @access public
+     */
+    function isError($value)
+    {
+        return is_a($value, 'PEAR_Error');
+    }
+}
+
+/**
+ * The methods and properties for submitting XML RPC requests
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    Release: 1.3.1
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+class XML_RPC_Client extends XML_RPC_Base {
+
+    /**
+     * The path and name of the RPC server script you want the request to go to
+     * @var string
+     */
+    var $path = '';
+
+    /**
+     * The name of the remote server to connect to
+     * @var string
+     */
+    var $server = '';
+
+    /**
+     * The protocol to use in contacting the remote server
+     * @var string
+     */
+    var $protocol = 'http://';
+
+    /**
+     * The port for connecting to the remote server
+     *
+     * The default is 80 for http:// connections
+     * and 443 for https:// and ssl:// connections.
+     *
+     * @var integer
+     */
+    var $port = 80;
+
+    /**
+     * A user name for accessing the RPC server
+     * @var string
+     * @see XML_RPC_Client::setCredentials()
+     */
+    var $username = '';
+
+    /**
+     * A password for accessing the RPC server
+     * @var string
+     * @see XML_RPC_Client::setCredentials()
+     */
+    var $password = '';
+
+    /**
+     * The name of the proxy server to use, if any
+     * @var string
+     */
+    var $proxy = '';
+
+    /**
+     * The protocol to use in contacting the proxy server, if any
+     * @var string
+     */
+    var $proxy_protocol = 'http://';
+
+    /**
+     * The port for connecting to the proxy server
+     *
+     * The default is 8080 for http:// connections
+     * and 443 for https:// and ssl:// connections.
+     *
+     * @var integer
+     */
+    var $proxy_port = 8080;
+
+    /**
+     * A user name for accessing the proxy server
+     * @var string
+     */
+    var $proxy_user = '';
+
+    /**
+     * A password for accessing the proxy server
+     * @var string
+     */
+    var $proxy_pass = '';
+
+    /**
+     * The error number, if any
+     * @var integer
+     */
+    var $errno = 0;
+
+    /**
+     * The error message, if any
+     * @var string
+     */
+    var $errstring = '';
+
+    /**
+     * The current debug mode (1 = on, 0 = off)
+     * @var integer
+     */
+    var $debug = 0;
+
+    /**
+     * The HTTP headers for the current request.
+     * @var string
+     */
+    var $headers = '';
+
+
+    /**
+     * Sets the object's properties
+     *
+     * @param string  $path        the path and name of the RPC server script
+     *                              you want the request to go to
+     * @param string  $server      the URL of the remote server to connect to.
+     *                              If this parameter doesn't specify a
+     *                              protocol and $port is 443, ssl:// is
+     *                              assumed.
+     * @param integer $port        a port for connecting to the remote server.
+     *                              Defaults to 80 for http:// connections and
+     *                              443 for https:// and ssl:// connections.
+     * @param string  $proxy       the URL of the proxy server to use, if any.
+     *                              If this parameter doesn't specify a
+     *                              protocol and $port is 443, ssl:// is
+     *                              assumed.
+     * @param integer $proxy_port  a port for connecting to the remote server.
+     *                              Defaults to 8080 for http:// connections and
+     *                              443 for https:// and ssl:// connections.
+     * @param string  $proxy_user  a user name for accessing the proxy server
+     * @param string  $proxy_pass  a password for accessing the proxy server
+     *
+     * @return void
+     */
+    function XML_RPC_Client($path, $server, $port = 0,
+                            $proxy = '', $proxy_port = 0,
+                            $proxy_user = '', $proxy_pass = '')
+    {
+        $this->path       = $path;
+        $this->proxy_user = $proxy_user;
+        $this->proxy_pass = $proxy_pass;
+
+        preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match);
+        if ($match[1] == '') {
+            if ($port == 443) {
+                $this->server   = $match[2];
+                $this->protocol = 'ssl://';
+                $this->port     = 443;
+            } else {
+                $this->server = $match[2];
+                if ($port) {
+                    $this->port = $port;
+                }
+            }
+        } elseif ($match[1] == 'http://') {
+            $this->server = $match[2];
+            if ($port) {
+                $this->port = $port;
+            }
+        } else {
+            $this->server   = $match[2];
+            $this->protocol = 'ssl://';
+            if ($port) {
+                $this->port = $port;
+            } else {
+                $this->port = 443;
+            }
+        }
+
+        if ($proxy) {
+            preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match);
+            if ($match[1] == '') {
+                if ($proxy_port == 443) {
+                    $this->proxy          = $match[2];
+                    $this->proxy_protocol = 'ssl://';
+                    $this->proxy_port     = 443;
+                } else {
+                    $this->proxy = $match[2];
+                    if ($proxy_port) {
+                        $this->proxy_port = $proxy_port;
+                    }
+                }
+            } elseif ($match[1] == 'http://') {
+                $this->proxy = $match[2];
+                if ($proxy_port) {
+                    $this->proxy_port = $proxy_port;
+                }
+            } else {
+                $this->proxy          = $match[2];
+                $this->proxy_protocol = 'ssl://';
+                if ($proxy_port) {
+                    $this->proxy_port = $proxy_port;
+                } else {
+                    $this->proxy_port = 443;
+                }
+            }
+        }
+    }
+
+    /**
+     * Change the current debug mode
+     *
+     * @param int $in  where 1 = on, 0 = off
+     *
+     * @return void
+     */
+    function setDebug($in)
+    {
+        if ($in) {
+            $this->debug = 1;
+        } else {
+            $this->debug = 0;
+        }
+    }
+
+    /**
+     * Set username and password properties for connecting to the RPC server
+     *
+     * @param string $u  the user name
+     * @param string $p  the password
+     *
+     * @return void
+     *
+     * @see XML_RPC_Client::$username, XML_RPC_Client::$password
+     */
+    function setCredentials($u, $p)
+    {
+        $this->username = $u;
+        $this->password = $p;
+    }
+
+    /**
+     * Transmit the RPC request via HTTP 1.0 protocol
+     *
+     * @param object $msg       the XML_RPC_Message object
+     * @param int    $timeout   how many seconds to wait for the request
+     *
+     * @return object  an XML_RPC_Response object.  0 is returned if any
+     *                  problems happen.
+     *
+     * @see XML_RPC_Message, XML_RPC_Client::XML_RPC_Client(),
+     *      XML_RPC_Client::setCredentials()
+     */
+    function send($msg, $timeout = 0)
+    {
+        if (strtolower(get_class($msg)) != 'xml_rpc_message') {
+            $this->errstr = 'send()\'s $msg parameter must be an'
+                          . ' XML_RPC_Message object.';
+            $this->raiseError($this->errstr, XML_RPC_ERROR_PROGRAMMING);
+            return 0;
+        }
+        $msg->debug = $this->debug;
+        return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
+                                        $timeout, $this->username,
+                                        $this->password);
+    }
+
+    /**
+     * Transmit the RPC request via HTTP 1.0 protocol
+     *
+     * Requests should be sent using XML_RPC_Client send() rather than
+     * calling this method directly.
+     *
+     * @param object $msg       the XML_RPC_Message object
+     * @param string $server    the server to send the request to
+     * @param int    $port      the server port send the request to
+     * @param int    $timeout   how many seconds to wait for the request
+     *                           before giving up
+     * @param string $username  a user name for accessing the RPC server
+     * @param string $password  a password for accessing the RPC server
+     *
+     * @return object  an XML_RPC_Response object.  0 is returned if any
+     *                  problems happen.
+     *
+     * @access protected
+     * @see XML_RPC_Client::send()
+     */
+    function sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
+                               $username = '', $password = '')
+    {
+        /*
+         * If we're using a proxy open a socket to the proxy server
+         * instead to the xml-rpc server
+         */
+        if ($this->proxy) {
+            if ($this->proxy_protocol == 'http://') {
+                $protocol = '';
+            } else {
+                $protocol = $this->proxy_protocol;
+            }
+            if ($timeout > 0) {
+                $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
+                                 $this->errno, $this->errstr, $timeout);
+            } else {
+                $fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
+                                 $this->errno, $this->errstr);
+            }
+        } else {
+            if ($this->protocol == 'http://') {
+                $protocol = '';
+            } else {
+                $protocol = $this->protocol;
+            }
+            if ($timeout > 0) {
+                $fp = @fsockopen($protocol . $server, $port,
+                                 $this->errno, $this->errstr, $timeout);
+            } else {
+                $fp = @fsockopen($protocol . $server, $port,
+                                 $this->errno, $this->errstr);
+            }
+        }
+
+        /*
+         * Just raising the error without returning it is strange,
+         * but keep it here for backwards compatibility.
+         */
+        if (!$fp && $this->proxy) {
+            $this->raiseError('Connection to proxy server '
+                              . $this->proxy . ':' . $this->proxy_port
+                              . ' failed. ' . $this->errstr,
+                              XML_RPC_ERROR_CONNECTION_FAILED);
+            return 0;
+        } elseif (!$fp) {
+            $this->raiseError('Connection to RPC server '
+                              . $server . ':' . $port
+                              . ' failed. ' . $this->errstr,
+                              XML_RPC_ERROR_CONNECTION_FAILED);
+            return 0;
+        }
+
+        if ($timeout) {
+            stream_set_timeout($fp, $timeout);
+        }
+
+        // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly
+        if ($username != $this->username) {
+            $this->setCredentials($username, $password);
+        }
+
+        // Only create the payload if it was not created previously
+        if (empty($msg->payload)) {
+            $msg->createPayload();
+        }
+        $this->createHeaders($msg);
+
+        $op  = $this->headers . "\r\n\r\n";
+        $op .= $msg->payload;
+
+        if (!fputs($fp, $op, strlen($op))) {
+            $this->errstr = 'Write error';
+            return 0;
+        }
+        $resp = $msg->parseResponseFile($fp);
+
+        $meta = stream_get_meta_data($fp);
+        if ($meta['timed_out']) {
+            fclose($fp);
+            $this->errstr = 'RPC server did not send response before timeout.';
+            $this->raiseError($this->errstr, XML_RPC_ERROR_CONNECTION_FAILED);
+            return 0;
+        }
+
+        fclose($fp);
+        return $resp;
+    }
+
+    /**
+     * Determines the HTTP headers and puts it in the $headers property
+     *
+     * @param object $msg       the XML_RPC_Message object
+     *
+     * @return boolean  TRUE if okay, FALSE if the message payload isn't set.
+     *
+     * @access protected
+     */
+    function createHeaders($msg)
+    {
+        if (empty($msg->payload)) {
+            return false;
+        }
+        if ($this->proxy) {
+            $this->headers = 'POST ' . $this->protocol . $this->server;
+            if ($this->proxy_port) {
+                $this->headers .= ':' . $this->port;
+            }
+        } else {
+           $this->headers = 'POST ';
+        }
+        $this->headers .= $this->path. " HTTP/1.0\r\n";
+        
+        $this->headers .= "User-Agent: PEAR XML_RPC\r\n";
+        $this->headers .= 'Host: ' . $this->server . "\r\n";
+
+        if ($this->proxy && $this->proxy_user) {
+            $this->headers .= 'Proxy-Authorization: Basic '
+                     . base64_encode("$this->proxy_user:$this->proxy_pass")
+                     . "\r\n";
+        }
+
+        // thanks to Grant Rauscher <grant7@firstworld.net> for this
+        if ($this->username) {
+            $this->headers .= 'Authorization: Basic '
+                     . base64_encode("$this->username:$this->password")
+                     . "\r\n";
+        }
+
+        $this->headers .= "Content-Type: text/xml\r\n";
+        $this->headers .= 'Content-Length: ' . strlen($msg->payload);
+        return true;
+    }
+}
+
+/**
+ * The methods and properties for interpreting responses to XML RPC requests
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    Release: 1.3.1
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+class XML_RPC_Response extends XML_RPC_Base
+{
+    var $xv;
+    var $fn;
+    var $fs;
+    var $hdrs;
+
+    /**
+     * @return void
+     */
+    function XML_RPC_Response($val, $fcode = 0, $fstr = '')
+    {
+        if ($fcode != 0) {
+            $this->fn = $fcode;
+            $this->fs = htmlspecialchars($fstr);
+        } else {
+            $this->xv = $val;
+        }
+    }
+
+    /**
+     * @return int  the error code
+     */
+    function faultCode()
+    {
+        if (isset($this->fn)) {
+            return $this->fn;
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * @return string  the error string
+     */
+    function faultString()
+    {
+        return $this->fs;
+    }
+
+    /**
+     * @return mixed  the value
+     */
+    function value()
+    {
+        return $this->xv;
+    }
+
+    /**
+     * @return string  the error message in XML format
+     */
+    function serialize()
+    {
+        $rs = "<methodResponse>\n";
+        if ($this->fn) {
+            $rs .= "<fault>
+  <value>
+    <struct>
+      <member>
+        <name>faultCode</name>
+        <value><int>" . $this->fn . "</int></value>
+      </member>
+      <member>
+        <name>faultString</name>
+        <value><string>" . $this->fs . "</string></value>
+      </member>
+    </struct>
+  </value>
+</fault>";
+        } else {
+            $rs .= "<params>\n<param>\n" . $this->xv->serialize() .
+        "</param>\n</params>";
+        }
+        $rs .= "\n</methodResponse>";
+        return $rs;
+    }
+}
+
+/**
+ * The methods and properties for composing XML RPC messages
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    Release: 1.3.1
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+class XML_RPC_Message extends XML_RPC_Base
+{
+    /**
+     * The current debug mode (1 = on, 0 = off)
+     * @var integer
+     */
+    var $debug = 0;
+
+    /**
+     * The encoding to be used for outgoing messages
+     *
+     * Defaults to the value of <var>$GLOBALS['XML_RPC_defencoding']</var>
+     *
+     * @var string
+     * @see XML_RPC_Message::setSendEncoding(),
+     *      $GLOBALS['XML_RPC_defencoding'], XML_RPC_Message::xml_header()
+     */
+    var $send_encoding = '';
+
+    /**
+     * The method presently being evaluated
+     * @var string
+     */
+    var $methodname = '';
+
+    /**
+     * @var array
+     */
+    var $params = array();
+
+    /**
+     * The XML message being generated
+     * @var string
+     */
+    var $payload = '';
+
+    /**
+     * @return void
+     */
+    function XML_RPC_Message($meth, $pars = 0)
+    {
+        $this->methodname = $meth;
+        if (is_array($pars) && sizeof($pars) > 0) {
+            for ($i = 0; $i < sizeof($pars); $i++) {
+                $this->addParam($pars[$i]);
+            }
+        }
+    }
+
+    /**
+     * Produces the XML declaration including the encoding attribute
+     *
+     * The encoding is determined by this class' <var>$send_encoding</var>
+     * property.  If the <var>$send_encoding</var> property is not set, use
+     * <var>$GLOBALS['XML_RPC_defencoding']</var>.
+     *
+     * @return string  the XML declaration and <methodCall> element
+     *
+     * @see XML_RPC_Message::setSendEncoding(),
+     *      XML_RPC_Message::$send_encoding, $GLOBALS['XML_RPC_defencoding']
+     */
+    function xml_header()
+    {
+        global $XML_RPC_defencoding;
+        if (!$this->send_encoding) {
+            $this->send_encoding = $XML_RPC_defencoding;
+        }
+        return '<?xml version="1.0" encoding="' . $this->send_encoding . '"?>'
+               . "\n<methodCall>\n";
+    }
+
+    /**
+     * @return string  the closing </methodCall> tag
+     */
+    function xml_footer()
+    {
+        return "</methodCall>\n";
+    }
+
+    /**
+     * @return void
+     *
+     * @uses XML_RPC_Message::xml_header(), XML_RPC_Message::xml_footer()
+     */
+    function createPayload()
+    {
+        $this->payload = $this->xml_header();
+        $this->payload .= '<methodName>' . $this->methodname . "</methodName>\n";
+        $this->payload .= "<params>\n";
+        for ($i = 0; $i < sizeof($this->params); $i++) {
+            $p = $this->params[$i];
+            $this->payload .= "<param>\n" . $p->serialize() . "</param>\n";
+        }
+        $this->payload .= "</params>\n";
+        $this->payload .= $this->xml_footer();
+        $this->payload = ereg_replace("[\r\n]+", "\r\n", $this->payload);
+    }
+
+    /**
+     * @return string  the name of the method
+     */
+    function method($meth = '')
+    {
+        if ($meth != '') {
+            $this->methodname = $meth;
+        }
+        return $this->methodname;
+    }
+
+    /**
+     * @return string  the payload
+     */
+    function serialize()
+    {
+        $this->createPayload();
+        return $this->payload;
+    }
+
+    /**
+     * @return void
+     */
+    function addParam($par)
+    {
+        $this->params[] = $par;
+    }
+
+    /**
+     * Obtains an XML_RPC_Value object for the given parameter
+     *
+     * @param int $i  the index number of the parameter to obtain
+     *
+     * @return object  the XML_RPC_Value object.
+     *                  If the parameter doesn't exist, an XML_RPC_Response object.
+     *
+     * @since Returns XML_RPC_Response object on error since Release 1.3.0
+     */
+    function getParam($i)
+    {
+        global $XML_RPC_err, $XML_RPC_str;
+
+        if (isset($this->params[$i])) {
+            return $this->params[$i];
+        } else {
+            $this->raiseError('The submitted request did not contain this parameter',
+                              XML_RPC_ERROR_INCORRECT_PARAMS);
+            return new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
+                                        $XML_RPC_str['incorrect_params']);
+        }
+    }
+
+    /**
+     * @return int  the number of parameters
+     */
+    function getNumParams()
+    {
+        return sizeof($this->params);
+    }
+
+    /**
+     * Sets the XML declaration's encoding attribute
+     *
+     * @param string $type  the encoding type (ISO-8859-1, UTF-8 or US-ASCII)
+     *
+     * @return void
+     *
+     * @see XML_RPC_Message::$send_encoding, XML_RPC_Message::xml_header()
+     * @since Method available since Release 1.2.0
+     */
+    function setSendEncoding($type)
+    {
+        $this->send_encoding = $type;
+    }
+
+    /**
+     * Determine the XML's encoding via the encoding attribute
+     * in the XML declaration
+     *
+     * If the encoding parameter is not set or is not ISO-8859-1, UTF-8
+     * or US-ASCII, $XML_RPC_defencoding will be returned.
+     *
+     * @param string $data  the XML that will be parsed
+     *
+     * @return string  the encoding to be used
+     *
+     * @link   http://php.net/xml_parser_create
+     * @since  Method available since Release 1.2.0
+     */
+    function getEncoding($data)
+    {
+        global $XML_RPC_defencoding;
+
+        if (preg_match('/<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]/i',
+                       $data, $match))
+        {
+            $match[1] = trim(strtoupper($match[1]));
+            switch ($match[1]) {
+                case 'ISO-8859-1':
+                case 'UTF-8':
+                case 'US-ASCII':
+                    return $match[1];
+                    break;
+
+                default:
+                    return $XML_RPC_defencoding;
+            }
+        } else {
+            return $XML_RPC_defencoding;
+        }
+    }
+
+    /**
+     * @return object  a new XML_RPC_Response object
+     */
+    function parseResponseFile($fp)
+    {
+        $ipd = '';
+        while ($data = @fread($fp, 8192)) {
+            $ipd .= $data;
+        }
+        return $this->parseResponse($ipd);
+    }
+
+    /**
+     * @return object  a new XML_RPC_Response object
+     */
+    function parseResponse($data = '')
+    {
+        global $XML_RPC_xh, $XML_RPC_err, $XML_RPC_str, $XML_RPC_defencoding;
+
+        $encoding = $this->getEncoding($data);
+        $parser_resource = xml_parser_create($encoding);
+        $parser = (int) $parser_resource;
+
+        $XML_RPC_xh[$parser] = array();
+
+        $XML_RPC_xh[$parser]['st'] = '';
+        $XML_RPC_xh[$parser]['cm'] = 0;
+        $XML_RPC_xh[$parser]['isf'] = 0;
+        $XML_RPC_xh[$parser]['ac'] = '';
+        $XML_RPC_xh[$parser]['qt'] = '';
+
+        xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
+        xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
+        xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
+
+        $hdrfnd = 0;
+        if ($this->debug) {
+            print "<PRE>---GOT---\n";
+            print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
+            print "\n---END---\n</PRE>";
+        }
+
+        // See if response is a 200 or a 100 then a 200, else raise error.
+        // But only do this if we're using the HTTP protocol.
+        if (ereg('^HTTP', $data) &&
+            !ereg('^HTTP/[0-9\.]+ 200 ', $data) &&
+            !preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Za-z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data))
+        {
+                $errstr = substr($data, 0, strpos($data, "\n") - 1);
+                error_log('HTTP error, got response: ' . $errstr);
+                $r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
+                                          $XML_RPC_str['http_error'] . ' (' .
+                                          $errstr . ')');
+                xml_parser_free($parser_resource);
+                return $r;
+        }
+        // gotta get rid of headers here
+
+
+        if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) {
+            $XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
+            $data = substr($data, $brpos + 4);
+            $hdrfnd = 1;
+        }
+
+        /*
+         * be tolerant of junk after methodResponse
+         * (e.g. javascript automatically inserted by free hosts)
+         * thanks to Luca Mariano <luca.mariano@email.it>
+         */
+        $data = substr($data, 0, strpos($data, "</methodResponse>") + 17);
+
+        if (!xml_parse($parser_resource, $data, sizeof($data))) {
+            // thanks to Peter Kocks <peter.kocks@baygate.com>
+            if (xml_get_current_line_number($parser_resource) == 1) {
+                $errstr = 'XML error at line 1, check URL';
+            } else {
+                $errstr = sprintf('XML error: %s at line %d',
+                                  xml_error_string(xml_get_error_code($parser_resource)),
+                                  xml_get_current_line_number($parser_resource));
+            }
+            error_log($errstr);
+            $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
+                                      $XML_RPC_str['invalid_return']);
+            xml_parser_free($parser_resource);
+            return $r;
+        }
+        xml_parser_free($parser_resource);
+        if ($this->debug) {
+            print '<PRE>---EVALING---[' .
+            strlen($XML_RPC_xh[$parser]['st']) . " chars]---\n" .
+            htmlspecialchars($XML_RPC_xh[$parser]['st']) . ";\n---END---</PRE>";
+        }
+        if (strlen($XML_RPC_xh[$parser]['st']) == 0) {
+            // then something odd has happened
+            // and it's time to generate a client side error
+            // indicating something odd went on
+            $r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
+                                      $XML_RPC_str['invalid_return']);
+        } else {
+            eval('$v=' . $XML_RPC_xh[$parser]['st'] . '; $allOK=1;');
+            if ($XML_RPC_xh[$parser]['isf']) {
+                $f = $v->structmem('faultCode');
+                $fs = $v->structmem('faultString');
+                $r = new XML_RPC_Response($v, $f->scalarval(),
+                                          $fs->scalarval());
+            } else {
+                $r = new XML_RPC_Response($v);
+            }
+        }
+        $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]);
+        return $r;
+    }
+}
+
+/**
+ * The methods and properties that represent data in XML RPC format
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    Release: 1.3.1
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+class XML_RPC_Value extends XML_RPC_Base
+{
+    var $me = array();
+    var $mytype = 0;
+
+    /**
+     * @return void
+     */
+    function XML_RPC_Value($val = -1, $type = '')
+    {
+        global $XML_RPC_Types;
+        $this->me = array();
+        $this->mytype = 0;
+        if ($val != -1 || $type != '') {
+            if ($type == '') {
+                $type = 'string';
+            }
+            if (!array_key_exists($type, $XML_RPC_Types)) {
+                // XXX
+                // need some way to report this error
+            } elseif ($XML_RPC_Types[$type] == 1) {
+                $this->addScalar($val, $type);
+            } elseif ($XML_RPC_Types[$type] == 2) {
+                $this->addArray($val);
+            } elseif ($XML_RPC_Types[$type] == 3) {
+                $this->addStruct($val);
+            }
+        }
+    }
+
+    /**
+     * @return int  returns 1 if successful or 0 if there are problems
+     */
+    function addScalar($val, $type = 'string')
+    {
+        global $XML_RPC_Types, $XML_RPC_Boolean;
+
+        if ($this->mytype == 1) {
+            $this->raiseError('Scalar can have only one value',
+                              XML_RPC_ERROR_INVALID_TYPE);
+            return 0;
+        }
+        $typeof = $XML_RPC_Types[$type];
+        if ($typeof != 1) {
+            $this->raiseError("Not a scalar type (${typeof})",
+                              XML_RPC_ERROR_INVALID_TYPE);
+            return 0;
+        }
+
+        if ($type == $XML_RPC_Boolean) {
+            if (strcasecmp($val, 'true') == 0
+                || $val == 1
+                || ($val == true && strcasecmp($val, 'false')))
+            {
+                $val = 1;
+            } else {
+                $val = 0;
+            }
+        }
+
+        if ($this->mytype == 2) {
+            // we're adding to an array here
+            $ar = $this->me['array'];
+            $ar[] = new XML_RPC_Value($val, $type);
+            $this->me['array'] = $ar;
+        } else {
+            // a scalar, so set the value and remember we're scalar
+            $this->me[$type] = $val;
+            $this->mytype = $typeof;
+        }
+        return 1;
+    }
+
+    /**
+     * @return int  returns 1 if successful or 0 if there are problems
+     */
+    function addArray($vals)
+    {
+        global $XML_RPC_Types;
+        if ($this->mytype != 0) {
+            $this->raiseError(
+                    'Already initialized as a [' . $this->kindOf() . ']',
+                    XML_RPC_ERROR_ALREADY_INITIALIZED);
+            return 0;
+        }
+        $this->mytype = $XML_RPC_Types['array'];
+        $this->me['array'] = $vals;
+        return 1;
+    }
+
+    /**
+     * @return int  returns 1 if successful or 0 if there are problems
+     */
+    function addStruct($vals)
+    {
+        global $XML_RPC_Types;
+        if ($this->mytype != 0) {
+            $this->raiseError(
+                    'Already initialized as a [' . $this->kindOf() . ']',
+                    XML_RPC_ERROR_ALREADY_INITIALIZED);
+            return 0;
+        }
+        $this->mytype = $XML_RPC_Types['struct'];
+        $this->me['struct'] = $vals;
+        return 1;
+    }
+
+    /**
+     * @return void
+     */
+    function dump($ar)
+    {
+        reset($ar);
+        foreach ($ar as $key => $val) {
+            echo "$key => $val<br />";
+            if ($key == 'array') {
+                foreach ($val as $key2 => $val2) {
+                    echo "-- $key2 => $val2<br />";
+                }
+            }
+        }
+    }
+
+    /**
+     * @return string  the data type of the current value
+     */
+    function kindOf()
+    {
+        switch ($this->mytype) {
+        case 3:
+            return 'struct';
+
+        case 2:
+            return 'array';
+
+        case 1:
+            return 'scalar';
+
+        default:
+            return 'undef';
+        }
+    }
+
+    /**
+     * @return string  the data in XML format
+     */
+    function serializedata($typ, $val)
+    {
+        $rs = '';
+        global $XML_RPC_Types, $XML_RPC_Base64, $XML_RPC_String, $XML_RPC_Boolean;
+        if (!array_key_exists($typ, $XML_RPC_Types)) {
+            // XXX
+            // need some way to report this error
+            return;
+        }
+        switch ($XML_RPC_Types[$typ]) {
+        case 3:
+            // struct
+            $rs .= "<struct>\n";
+            reset($val);
+            foreach ($val as $key2 => $val2) {
+                $rs .= "<member><name>${key2}</name>\n";
+                $rs .= $this->serializeval($val2);
+                $rs .= "</member>\n";
+            }
+            $rs .= '</struct>';
+            break;
+
+        case 2:
+            // array
+            $rs .= "<array>\n<data>\n";
+            for ($i = 0; $i < sizeof($val); $i++) {
+                $rs .= $this->serializeval($val[$i]);
+            }
+            $rs .= "</data>\n</array>";
+            break;
+
+        case 1:
+            switch ($typ) {
+            case $XML_RPC_Base64:
+                $rs .= "<${typ}>" . base64_encode($val) . "</${typ}>";
+                break;
+            case $XML_RPC_Boolean:
+                $rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
+                break;
+            case $XML_RPC_String:
+                $rs .= "<${typ}>" . htmlspecialchars($val). "</${typ}>";
+                break;
+            default:
+                $rs .= "<${typ}>${val}</${typ}>";
+            }
+        }
+        return $rs;
+    }
+
+    /**
+     * @return string  the data in XML format
+     */
+    function serialize()
+    {
+        return $this->serializeval($this);
+    }
+
+    /**
+     * @return string  the data in XML format
+     */
+    function serializeval($o)
+    {
+        $rs = '';
+        $ar = $o->me;
+        reset($ar);
+        list($typ, $val) = each($ar);
+        $rs .= '<value>';
+        $rs .= $this->serializedata($typ, $val);
+        $rs .= "</value>\n";
+        return $rs;
+    }
+
+    /**
+     * @return mixed  the contents of the element requested
+     */
+    function structmem($m)
+    {
+        return $this->me['struct'][$m];
+    }
+
+    /**
+     * @return void
+     */
+    function structreset()
+    {
+        reset($this->me['struct']);
+    }
+
+    /**
+     * @return  the key/value pair of the struct's current element
+     */
+    function structeach()
+    {
+        return each($this->me['struct']);
+    }
+
+    /**
+     * @return mixed  the current value
+     */
+    function getval()
+    {
+        // UNSTABLE
+        global $XML_RPC_BOOLEAN, $XML_RPC_Base64;
+
+        reset($this->me);
+        $b = current($this->me);
+
+        // contributed by I Sofer, 2001-03-24
+        // add support for nested arrays to scalarval
+        // i've created a new method here, so as to
+        // preserve back compatibility
+
+        if (is_array($b)) {
+            foreach ($b as $id => $cont) {
+                $b[$id] = $cont->scalarval();
+            }
+        }
+
+        // add support for structures directly encoding php objects
+        if (is_object($b)) {
+            $t = get_object_vars($b);
+            foreach ($t as $id => $cont) {
+                $t[$id] = $cont->scalarval();
+            }
+            foreach ($t as $id => $cont) {
+                eval('$b->'.$id.' = $cont;');
+            }
+        }
+
+        // end contrib
+        return $b;
+    }
+
+    /**
+     * @return mixed
+     */
+    function scalarval()
+    {
+        global $XML_RPC_Boolean, $XML_RPC_Base64;
+        reset($this->me);
+        return current($this->me);
+    }
+
+    /**
+     * @return string
+     */
+    function scalartyp()
+    {
+        global $XML_RPC_I4, $XML_RPC_Int;
+        reset($this->me);
+        $a = key($this->me);
+        if ($a == $XML_RPC_I4) {
+            $a = $XML_RPC_Int;
+        }
+        return $a;
+    }
+
+    /**
+     * @return mixed  the struct's current element
+     */
+    function arraymem($m)
+    {
+        return $this->me['array'][$m];
+    }
+
+    /**
+     * @return int  the number of elements in the array
+     */
+    function arraysize()
+    {
+        reset($this->me);
+        list($a, $b) = each($this->me);
+        return sizeof($b);
+    }
+
+    /**
+     * Determines if the item submitted is an XML_RPC_Value object
+     *
+     * @param mixed $val  the variable to be evaluated
+     *
+     * @return bool  TRUE if the item is an XML_RPC_Value object
+     *
+     * @static
+     * @since Method available since Release 1.3.0
+     */
+    function isValue($val)
+    {
+        return (strtolower(get_class($val)) == 'xml_rpc_value');
+    }
+}
+
+/**
+ * Return an ISO8601 encoded string
+ *
+ * While timezones ought to be supported, the XML-RPC spec says:
+ *
+ * "Don't assume a timezone. It should be specified by the server in its
+ * documentation what assumptions it makes about timezones."
+ *
+ * This routine always assumes localtime unless $utc is set to 1, in which
+ * case UTC is assumed and an adjustment for locale is made when encoding.
+ *
+ * @return string  the formatted date
+ */
+function XML_RPC_iso8601_encode($timet, $utc = 0)
+{
+    if (!$utc) {
+        $t = strftime('%Y%m%dT%H:%M:%S', $timet);
+    } else {
+        if (function_exists('gmstrftime')) {
+            // gmstrftime doesn't exist in some versions
+            // of PHP
+            $t = gmstrftime('%Y%m%dT%H:%M:%S', $timet);
+        } else {
+            $t = strftime('%Y%m%dT%H:%M:%S', $timet - date('Z'));
+        }
+    }
+    return $t;
+}
+
+/**
+ * Convert a datetime string into a Unix timestamp
+ *
+ * While timezones ought to be supported, the XML-RPC spec says:
+ *
+ * "Don't assume a timezone. It should be specified by the server in its
+ * documentation what assumptions it makes about timezones."
+ *
+ * This routine always assumes localtime unless $utc is set to 1, in which
+ * case UTC is assumed and an adjustment for locale is made when encoding.
+ *
+ * @return int  the unix timestamp of the date submitted
+ */
+function XML_RPC_iso8601_decode($idate, $utc = 0)
+{
+    $t = 0;
+    if (ereg('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) {
+        if ($utc) {
+            $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+        } else {
+            $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+        }
+    }
+    return $t;
+}
+
+/**
+ * Converts an XML_RPC_Value object into native PHP types
+ *
+ * @param object $XML_RPC_val  the XML_RPC_Value object to decode
+ *
+ * @return mixed  the PHP values
+ */
+function XML_RPC_decode($XML_RPC_val)
+{
+    $kind = $XML_RPC_val->kindOf();
+
+    if ($kind == 'scalar') {
+        return $XML_RPC_val->scalarval();
+
+    } elseif ($kind == 'array') {
+        $size = $XML_RPC_val->arraysize();
+        $arr = array();
+        for ($i = 0; $i < $size; $i++) {
+            $arr[] = XML_RPC_decode($XML_RPC_val->arraymem($i));
+        }
+        return $arr;
+
+    } elseif ($kind == 'struct') {
+        $XML_RPC_val->structreset();
+        $arr = array();
+        while (list($key, $value) = $XML_RPC_val->structeach()) {
+            $arr[$key] = XML_RPC_decode($value);
+        }
+        return $arr;
+    }
+}
+
+/**
+ * Converts native PHP types into an XML_RPC_Value object
+ *
+ * @param mixed $php_val  the PHP value or variable you want encoded
+ *
+ * @return object  the XML_RPC_Value object
+ */
+function XML_RPC_encode($php_val)
+{
+    global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double, $XML_RPC_String,
+           $XML_RPC_Array, $XML_RPC_Struct;
+
+    $type = gettype($php_val);
+    $XML_RPC_val = new XML_RPC_Value;
+
+    switch ($type) {
+    case 'array':
+        if (empty($php_val)) {
+            $XML_RPC_val->addArray($php_val);
+            break;
+        }
+        $tmp = array_diff(array_keys($php_val), range(0, count($php_val)-1));
+        if (empty($tmp)) {
+           $arr = array();
+           foreach ($php_val as $k => $v) {
+               $arr[$k] = XML_RPC_encode($v);
+           }
+           $XML_RPC_val->addArray($arr);
+           break;
+        }
+        // fall though if it's not an enumerated array
+
+    case 'object':
+        $arr = array();
+        foreach ($php_val as $k => $v) {
+            $arr[$k] = XML_RPC_encode($v);
+        }
+        $XML_RPC_val->addStruct($arr);
+        break;
+
+    case 'integer':
+        $XML_RPC_val->addScalar($php_val, $XML_RPC_Int);
+        break;
+
+    case 'double':
+        $XML_RPC_val->addScalar($php_val, $XML_RPC_Double);
+        break;
+
+    case 'string':
+    case 'NULL':
+        $XML_RPC_val->addScalar($php_val, $XML_RPC_String);
+        break;
+
+    case 'boolean':
+        // Add support for encoding/decoding of booleans, since they
+        // are supported in PHP
+        // by <G_Giunta_2001-02-29>
+        $XML_RPC_val->addScalar($php_val, $XML_RPC_Boolean);
+        break;
+
+    case 'unknown type':
+    default:
+        $XML_RPC_val = false;
+    }
+    return $XML_RPC_val;
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * c-hanging-comment-ender-p: nil
+ * End:
+ */
+
+?>
+XML_RPC-1.3.1/Server.php100644   1750    144       47770 10260516576  10104 <?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Server commands for our PHP implementation of the XML-RPC protocol
+ *
+ * This is a PEAR-ified version of Useful inc's XML-RPC for PHP.
+ * It has support for HTTP transport, proxies and authentication.
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: License is granted to use or modify this software
+ * ("XML-RPC for PHP") for commercial or non-commercial use provided the
+ * copyright of the author is preserved in any distributed or derivative work.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    CVS: $Id: Server.php,v 1.26 2005/05/09 21:39:47 danielc Exp $
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+
+
+/**
+ * Pull in the XML_RPC class
+ */
+require_once 'XML/RPC.php';
+
+
+/**
+ * signature for system.listMethods: return = array,
+ * parameters = a string or nothing
+ * @global array $GLOBALS['XML_RPC_Server_listMethods_sig']
+ */
+$GLOBALS['XML_RPC_Server_listMethods_sig'] = array(
+    array($GLOBALS['XML_RPC_Array'],
+          $GLOBALS['XML_RPC_String']
+    ),
+    array($GLOBALS['XML_RPC_Array'])
+);
+
+/**
+ * docstring for system.listMethods
+ * @global string $GLOBALS['XML_RPC_Server_listMethods_doc']
+ */
+$GLOBALS['XML_RPC_Server_listMethods_doc'] = 'This method lists all the'
+        . ' methods that the XML-RPC server knows how to dispatch';
+
+/**
+ * signature for system.methodSignature: return = array,
+ * parameters = string
+ * @global array $GLOBALS['XML_RPC_Server_methodSignature_sig']
+ */
+$GLOBALS['XML_RPC_Server_methodSignature_sig'] = array(
+    array($GLOBALS['XML_RPC_Array'],
+          $GLOBALS['XML_RPC_String']
+    )
+);
+
+/**
+ * docstring for system.methodSignature
+ * @global string $GLOBALS['XML_RPC_Server_methodSignature_doc']
+ */
+$GLOBALS['XML_RPC_Server_methodSignature_doc'] = 'Returns an array of known'
+        . ' signatures (an array of arrays) for the method name passed. If'
+        . ' no signatures are known, returns a none-array (test for type !='
+        . ' array to detect missing signature)';
+
+/**
+ * signature for system.methodHelp: return = string,
+ * parameters = string
+ * @global array $GLOBALS['XML_RPC_Server_methodHelp_sig']
+ */
+$GLOBALS['XML_RPC_Server_methodHelp_sig'] = array(
+    array($GLOBALS['XML_RPC_String'],
+          $GLOBALS['XML_RPC_String']
+    )
+);
+
+/**
+ * docstring for methodHelp
+ * @global string $GLOBALS['XML_RPC_Server_methodHelp_doc']
+ */
+$GLOBALS['XML_RPC_Server_methodHelp_doc'] = 'Returns help text if defined'
+        . ' for the method passed, otherwise returns an empty string';
+
+/**
+ * dispatch map for the automatically declared XML-RPC methods.
+ * @global array $GLOBALS['XML_RPC_Server_dmap']
+ */
+$GLOBALS['XML_RPC_Server_dmap'] = array(
+    'system.listMethods' => array(
+        'function'  => 'XML_RPC_Server_listMethods',
+        'signature' => $GLOBALS['XML_RPC_Server_listMethods_sig'],
+        'docstring' => $GLOBALS['XML_RPC_Server_listMethods_doc']
+    ),
+    'system.methodHelp' => array(
+        'function'  => 'XML_RPC_Server_methodHelp',
+        'signature' => $GLOBALS['XML_RPC_Server_methodHelp_sig'],
+        'docstring' => $GLOBALS['XML_RPC_Server_methodHelp_doc']
+    ),
+    'system.methodSignature' => array(
+        'function'  => 'XML_RPC_Server_methodSignature',
+        'signature' => $GLOBALS['XML_RPC_Server_methodSignature_sig'],
+        'docstring' => $GLOBALS['XML_RPC_Server_methodSignature_doc']
+    )
+);
+
+/**
+ * @global string $GLOBALS['XML_RPC_Server_debuginfo']
+ */
+$GLOBALS['XML_RPC_Server_debuginfo'] = '';
+
+
+/**
+ * Lists all the methods that the XML-RPC server knows how to dispatch
+ *
+ * @return object  a new XML_RPC_Response object
+ */
+function XML_RPC_Server_listMethods($server, $m)
+{
+    global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
+
+    $v = new XML_RPC_Value();
+    $outAr = array();
+    foreach ($server->dmap as $key => $val) {
+        $outAr[] = new XML_RPC_Value($key, 'string');
+    }
+    foreach ($XML_RPC_Server_dmap as $key => $val) {
+        $outAr[] = new XML_RPC_Value($key, 'string');
+    }
+    $v->addArray($outAr);
+    return new XML_RPC_Response($v);
+}
+
+/**
+ * Returns an array of known signatures (an array of arrays)
+ * for the given method
+ *
+ * If no signatures are known, returns a none-array
+ * (test for type != array to detect missing signature)
+ *
+ * @return object  a new XML_RPC_Response object
+ */
+function XML_RPC_Server_methodSignature($server, $m)
+{
+    global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
+
+    $methName = $m->getParam(0);
+    $methName = $methName->scalarval();
+    if (strpos($methName, 'system.') === 0) {
+        $dmap = $XML_RPC_Server_dmap;
+        $sysCall = 1;
+    } else {
+        $dmap = $server->dmap;
+        $sysCall = 0;
+    }
+    //  print "<!-- ${methName} -->\n";
+    if (isset($dmap[$methName])) {
+        if ($dmap[$methName]['signature']) {
+            $sigs = array();
+            $thesigs = $dmap[$methName]['signature'];
+            for ($i = 0; $i < sizeof($thesigs); $i++) {
+                $cursig = array();
+                $inSig = $thesigs[$i];
+                for ($j = 0; $j < sizeof($inSig); $j++) {
+                    $cursig[] = new XML_RPC_Value($inSig[$j], 'string');
+                }
+                $sigs[] = new XML_RPC_Value($cursig, 'array');
+            }
+            $r = new XML_RPC_Response(new XML_RPC_Value($sigs, 'array'));
+        } else {
+            $r = new XML_RPC_Response(new XML_RPC_Value('undef', 'string'));
+        }
+    } else {
+        $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
+                                  $XML_RPC_str['introspect_unknown']);
+    }
+    return $r;
+}
+
+/**
+ * Returns help text if defined for the method passed, otherwise returns
+ * an empty string
+ *
+ * @return object  a new XML_RPC_Response object
+ */
+function XML_RPC_Server_methodHelp($server, $m)
+{
+    global $XML_RPC_err, $XML_RPC_str, $XML_RPC_Server_dmap;
+
+    $methName = $m->getParam(0);
+    $methName = $methName->scalarval();
+    if (strpos($methName, 'system.') === 0) {
+        $dmap = $XML_RPC_Server_dmap;
+        $sysCall = 1;
+    } else {
+        $dmap = $server->dmap;
+        $sysCall = 0;
+    }
+    //  print "<!-- ${methName} -->\n";
+    if (isset($dmap[$methName])) {
+        if ($dmap[$methName]['docstring']) {
+            $r = new XML_RPC_Response(new XML_RPC_Value($dmap[$methName]['docstring']),
+                                                        'string');
+        } else {
+            $r = new XML_RPC_Response(new XML_RPC_Value('', 'string'));
+        }
+    } else {
+        $r = new XML_RPC_Response(0, $XML_RPC_err['introspect_unknown'],
+                                     $XML_RPC_str['introspect_unknown']);
+    }
+    return $r;
+}
+
+/**
+ * @return void
+ */
+function XML_RPC_Server_debugmsg($m)
+{
+    global $XML_RPC_Server_debuginfo;
+    $XML_RPC_Server_debuginfo = $XML_RPC_Server_debuginfo . $m . "\n";
+}
+
+
+/**
+ * A server for receiving and replying to XML RPC requests
+ *
+ * <code>
+ * $server = new XML_RPC_Server(
+ *     array(
+ *         'isan8' =>
+ *             array(
+ *                 'function' => 'is_8',
+ *                 'signature' =>
+ *                      array(
+ *                          array('boolean', 'int'),
+ *                          array('boolean', 'int', 'boolean'),
+ *                          array('boolean', 'string'),
+ *                          array('boolean', 'string', 'boolean'),
+ *                      ),
+ *                 'docstring' => 'Is the value an 8?'
+ *             ),
+ *     ),
+ *     1,
+ *     0
+ * ); 
+ * </code>
+ *
+ * @category   Web Services
+ * @package    XML_RPC
+ * @author     Edd Dumbill <edd@usefulinc.com>
+ * @author     Stig Bakken <stig@php.net>
+ * @author     Martin Jansen <mj@php.net>
+ * @author     Daniel Convissor <danielc@php.net>
+ * @copyright  1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version    Release: 1.3.1
+ * @link       http://pear.php.net/package/XML_RPC
+ */
+class XML_RPC_Server
+{
+    /**
+     * The dispatch map, listing the methods this server provides.
+     * @var array
+     */
+    var $dmap = array();
+
+    /**
+     * The present response's encoding
+     * @var string
+     * @see XML_RPC_Message::getEncoding()
+     */
+    var $encoding = '';
+
+    /**
+     * Debug mode (0 = off, 1 = on)
+     * @var integer
+     */
+    var $debug = 0;
+
+    /**
+     * The response's HTTP headers
+     * @var string
+     */
+    var $server_headers = '';
+
+    /**
+     * The response's XML payload
+     * @var string
+     */
+    var $server_payload = '';
+
+
+    /**
+     * Constructor for the XML_RPC_Server class
+     *
+     * @param array $dispMap   the dispatch map. An associative array
+     *                          explaining each function. The keys of the main
+     *                          array are the procedure names used by the
+     *                          clients. The value is another associative array
+     *                          that contains up to three elements:
+     *                            + The 'function' element's value is the name
+     *                              of the function or method that gets called.
+     *                              To define a class' method: 'class::method'.
+     *                            + The 'signature' element (optional) is an
+     *                              array describing the return values and
+     *                              parameters
+     *                            + The 'docstring' element (optional) is a
+     *                              string describing what the method does
+     * @param int $serviceNow  should the HTTP response be sent now?
+     *                          (1 = yes, 0 = no)
+     * @param int $debug       should debug output be displayed?
+     *                          (1 = yes, 0 = no)
+     *
+     * @return void
+     */
+    function XML_RPC_Server($dispMap, $serviceNow = 1, $debug = 0)
+    {
+        global $HTTP_RAW_POST_DATA;
+
+        if ($debug) {
+            $this->debug = 1;
+        } else {
+            $this->debug = 0;
+        }
+
+        $this->dmap = $dispMap;
+
+        if ($serviceNow) {
+            $this->service();
+        } else {
+            $this->createServerPayload();
+            $this->createServerHeaders();
+        }
+    }
+
+    /**
+     * @return string  the debug information if debug debug mode is on
+     */
+    function serializeDebug()
+    {
+        global $XML_RPC_Server_debuginfo, $HTTP_RAW_POST_DATA;
+
+        if ($this->debug) {
+            XML_RPC_Server_debugmsg('vvv POST DATA RECEIVED BY SERVER vvv' . "\n"
+                                    . $HTTP_RAW_POST_DATA
+                                    . "\n" . '^^^ END POST DATA ^^^');
+        }
+
+        if ($XML_RPC_Server_debuginfo != '') {
+            return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n"
+                   . preg_replace('/-(?=-)/', '- ', $XML_RPC_Server_debuginfo)
+                   . "-->\n";
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     * Sends the response
+     *
+     * The encoding and content-type are determined by
+     * XML_RPC_Message::getEncoding()
+     *
+     * @return void
+     *
+     * @uses XML_RPC_Server::createServerPayload(),
+     *       XML_RPC_Server::createServerHeaders()
+     */
+    function service()
+    {
+        $this->createServerPayload();
+        $this->createServerHeaders();
+        header($this->server_headers);
+        print $this->server_payload;
+    }
+
+    /**
+     * Generates the payload and puts it in the $server_payload property
+     *
+     * @return void
+     *
+     * @uses XML_RPC_Server::parseRequest(), XML_RPC_Server::$encoding,
+     *       XML_RPC_Response::serialize(), XML_RPC_Server::serializeDebug()
+     */
+    function createServerPayload()
+    {
+        $r = $this->parseRequest();
+        $this->server_payload = '<?xml version="1.0" encoding="'
+                              . $this->encoding . '"?>' . "\n"
+                              . $this->serializeDebug()
+                              . $r->serialize();
+    }
+
+    /**
+     * Determines the HTTP headers and puts them in the $server_headers
+     * property
+     *
+     * @return boolean  TRUE if okay, FALSE if $server_payload isn't set.
+     *
+     * @uses XML_RPC_Server::createServerPayload(),
+     *       XML_RPC_Server::$server_headers
+     */
+    function createServerHeaders()
+    {
+        if (!$this->server_payload) {
+            return false;
+        }
+        $this->server_headers = 'Content-Length: '
+                              . strlen($this->server_payload) . "\r\n"
+                              . 'Content-Type: text/xml;'
+                              . ' charset=' . $this->encoding;
+        return true;
+    }
+
+    /**
+     * @return array
+     */
+    function verifySignature($in, $sig)
+    {
+        for ($i = 0; $i < sizeof($sig); $i++) {
+            // check each possible signature in turn
+            $cursig = $sig[$i];
+            if (sizeof($cursig) == $in->getNumParams() + 1) {
+                $itsOK = 1;
+                for ($n = 0; $n < $in->getNumParams(); $n++) {
+                    $p = $in->getParam($n);
+                    // print "<!-- $p -->\n";
+                    if ($p->kindOf() == 'scalar') {
+                        $pt = $p->scalartyp();
+                    } else {
+                        $pt = $p->kindOf();
+                    }
+                    // $n+1 as first type of sig is return type
+                    if ($pt != $cursig[$n+1]) {
+                        $itsOK = 0;
+                        $pno = $n+1;
+                        $wanted = $cursig[$n+1];
+                        $got = $pt;
+                        break;
+                    }
+                }
+                if ($itsOK) {
+                    return array(1);
+                }
+            }
+        }
+        if (isset($wanted)) {
+            return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
+        } else {
+            $allowed = array();
+            foreach ($sig as $val) {
+                end($val);
+                $allowed[] = key($val);
+            }
+            $allowed = array_unique($allowed);
+            $last = count($allowed) - 1;
+            if ($last > 0) {
+                $allowed[$last] = 'or ' . $allowed[$last];
+            }
+            return array(0,
+                         'Signature permits ' . implode(', ', $allowed)
+                                . ' parameters but the request had '
+                                . $in->getNumParams());
+        }
+    }
+
+    /**
+     * @return object  a new XML_RPC_Response object
+     *
+     * @uses XML_RPC_Message::getEncoding(), XML_RPC_Server::$encoding
+     */
+    function parseRequest($data = '')
+    {
+        global $XML_RPC_xh, $HTTP_RAW_POST_DATA,
+                $XML_RPC_err, $XML_RPC_str, $XML_RPC_errxml,
+                $XML_RPC_defencoding, $XML_RPC_Server_dmap;
+
+        if ($data == '') {
+            $data = $HTTP_RAW_POST_DATA;
+        }
+
+        $this->encoding = XML_RPC_Message::getEncoding($data);
+        $parser_resource = xml_parser_create($this->encoding);
+        $parser = (int) $parser_resource;
+
+        $XML_RPC_xh[$parser] = array();
+        $XML_RPC_xh[$parser]['st']     = '';
+        $XML_RPC_xh[$parser]['cm']     = 0;
+        $XML_RPC_xh[$parser]['isf']    = 0;
+        $XML_RPC_xh[$parser]['params'] = array();
+        $XML_RPC_xh[$parser]['method'] = '';
+
+        $plist = '';
+
+        // decompose incoming XML into request structure
+
+        xml_parser_set_option($parser_resource, XML_OPTION_CASE_FOLDING, true);
+        xml_set_element_handler($parser_resource, 'XML_RPC_se', 'XML_RPC_ee');
+        xml_set_character_data_handler($parser_resource, 'XML_RPC_cd');
+        if (!xml_parse($parser_resource, $data, 1)) {
+            // return XML error as a faultCode
+            $r = new XML_RPC_Response(0,
+                                      $XML_RPC_errxml+xml_get_error_code($parser_resource),
+                                      sprintf('XML error: %s at line %d',
+                                              xml_error_string(xml_get_error_code($parser_resource)),
+                                              xml_get_current_line_number($parser_resource)));
+            xml_parser_free($parser_resource);
+        } else {
+            xml_parser_free($parser_resource);
+            $m = new XML_RPC_Message($XML_RPC_xh[$parser]['method']);
+            // now add parameters in
+            for ($i = 0; $i < sizeof($XML_RPC_xh[$parser]['params']); $i++) {
+                // print '<!-- ' . $XML_RPC_xh[$parser]['params'][$i]. "-->\n";
+                $plist .= "$i - " . $XML_RPC_xh[$parser]['params'][$i] . " \n";
+                eval('$m->addParam(' . $XML_RPC_xh[$parser]['params'][$i] . ');');
+            }
+            XML_RPC_Server_debugmsg($plist);
+
+            // now to deal with the method
+            $methName = $XML_RPC_xh[$parser]['method'];
+            if (strpos($methName, 'system.') === 0) {
+                $dmap = $XML_RPC_Server_dmap;
+                $sysCall = 1;
+            } else {
+                $dmap = $this->dmap;
+                $sysCall = 0;
+            }
+
+            if (isset($dmap[$methName]['function'])
+                && is_string($dmap[$methName]['function'])
+                && strpos($dmap[$methName]['function'], '::') !== false)
+            {
+                $dmap[$methName]['function'] =
+                        explode('::', $dmap[$methName]['function']);
+            }
+
+            if (isset($dmap[$methName]['function'])
+                && is_callable($dmap[$methName]['function']))
+            {
+                // dispatch if exists
+                if (isset($dmap[$methName]['signature'])) {
+                    $sr = $this->verifySignature($m,
+                                                 $dmap[$methName]['signature'] );
+                }
+                if (!isset($dmap[$methName]['signature']) || $sr[0]) {
+                    // if no signature or correct signature
+                    if ($sysCall) {
+                        $r = call_user_func($dmap[$methName]['function'], $this, $m);
+                    } else {
+                        $r = call_user_func($dmap[$methName]['function'], $m);
+                    }
+                    if (!is_a($r, 'XML_RPC_Response')) {
+                        $r = new XML_RPC_Response(0, $XML_RPC_err['not_response_object'],
+                                                  $XML_RPC_str['not_response_object']);
+                    }
+                } else {
+                    $r = new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
+                                              $XML_RPC_str['incorrect_params']
+                                              . ': ' . $sr[1]);
+                }
+            } else {
+                // else prepare error response
+                $r = new XML_RPC_Response(0, $XML_RPC_err['unknown_method'],
+                                          $XML_RPC_str['unknown_method']);
+            }
+        }
+        return $r;
+    }
+
+    /**
+     * Echos back the input packet as a string value
+     *
+     * @return void
+     *
+     * Useful for debugging.
+     */
+    function echoInput()
+    {
+        global $HTTP_RAW_POST_DATA;
+
+        $r = new XML_RPC_Response(0);
+        $r->xv = new XML_RPC_Value("'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string');
+        print $r->serialize();
+    }
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * c-hanging-comment-ender-p: nil
+ * End:
+ */
+
+?>
+package.xml100644   1750    144       22507 10260516576   6427 <?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
+<package version="1.0" packagerversion="1.4.0a12">
+ <name>XML_RPC</name>
+ <summary>PHP implementation of the XML-RPC protocol</summary>
+ <description>A PEAR-ified version of Useful Inc's XML-RPC for PHP.
+
+It has support for HTTP/HTTPS transport, proxies and authentication.
+ </description>
+ <maintainers>
+  <maintainer>
+   <user>ssb</user>
+   <name>Stig Bakken</name>
+   <email>stig@php.net</email>
+   <role>lead</role>
+  </maintainer>
+  <maintainer>
+   <user>danielc</user>
+   <name>Daniel Convissor</name>
+   <email>danielc@php.net</email>
+   <role>lead</role>
+  </maintainer>
+  </maintainers>
+ <release>
+  <version>1.3.1</version>
+  <date>2005-06-29</date>
+  <license>PHP License</license>
+  <state>stable</state>
+  <notes>* Security fix. Update highly recommended!
+  </notes>
+  <filelist>
+   <file role="php" baseinstalldir="XML" name="RPC.php">
+    <replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file role="php" baseinstalldir="XML/RPC" name="Server.php">
+    <replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file role="php" baseinstalldir="XML/RPC" name="Dump.php">
+    <replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file role="test" name="tests/protoport.php">
+    <replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+   <file role="test" name="tests/test_Dump.php">
+    <replace from="@package_version@" to="version" type="package-info"/>
+   </file>
+  </filelist>
+ </release>
+ <changelog>
+   <release>
+    <version>1.3.0RC3</version>
+    <date>2005-05-10</date>
+    <state>beta</state>
+    <notes>* When verifying requests against function signatures, if the number of parameters don't match, provide an appropriate message.  NOTE: this resolves a path disclosure vulnerability.  (Refines the changes made in the last commit.)  Bug 4231.
+* XML_RPC_Message::getParam() now returns an XML_RPC_Response object upon error.  Changed from Release 1.3.0RC2.
+* Add the XML_RPC_Value::isValue() method. For testing if an item is an XML_RPC_Value object.
+* If XML_RPC_Client::send() is given an incorrect $msg parameter, raise an error with the new XML_RPC_ERROR_PROGRAMMING code and return 0.
+* Improve cross-platform operation by using PEAR::loadExtension() instead of dl().
+* Use &lt;br /&gt; instead of &lt;br&gt; in XML_RPC_Value::dump().
+    </notes>
+   </release>
+   <release>
+    <version>1.3.0RC2</version>
+    <date>2005-05-05</date>
+    <state>beta</state>
+    <notes>* If XML_RPC_Message::getParam() is given an incorrect parameter, raise an error with the new XML_RPC_ERROR_INCORRECT_PARAMS code and return FALSE.
+* Handle improper requests to XML_RPC_Server::verifySignature().  Bug 4231.
+* Try to allow HTTP 100 responses if followed by a 200 response.  Bug 4116.
+* Help Delphi users by making RPCMETHODNAME an alias for METHODNAME.  Request 4205.
+    </notes>
+   </release>
+   <release>
+    <version>1.3.0RC1</version>
+    <date>2005-04-07</date>
+    <state>beta</state>
+    <notes>* Improve timeout handling for situations where connection to server is made but no response is not received in time. Accomplished via stream_set_timeout().  Request 3963.
+* Add Fault Code 6: &quot;The requested method didn't return an XML_RPC_Response object.&quot;  Request 4032.
+* Add the createServerPayload() and createServerHeaders() methods and the $server_payload and $server_headers properties.  Request 3121.
+* As in earlier versions, if the $serviceNow parameter to XML_RPC_Server() is 0, no data will be returned, but now the new $server_payload and $server_headers properties will be set.
+* Convert the parser handle to an integer before using it as an index for $XML_RPC_xh[$parser].  Reduces E_STRICT notices.  Bug 3782.
+* Add createHeaders() method and $headers property to XML_RPC_Client to make testing easier.
+    </notes>
+   </release>
+   <release>
+    <version>1.2.2</version>
+    <date>2005-03-07</date>
+    <state>stable</state>
+    <notes>* When using a proxy, add the protocol to the Request-URI, making it an &quot;absoluteURI&quot; as per the HTTP 1.0 spec.  Bug 3679.
+    </notes>
+   </release>
+   <release>
+    <version>1.2.1</version>
+    <date>2005-03-01</date>
+    <state>stable</state>
+    <notes>* Add isset() check before examining the dispatch map.  Bug 3658.
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0</version>
+    <date>2005-02-27</date>
+    <state>stable</state>
+    <notes>* Provide the &quot;stable&quot; release.
+* Add package2.xml for compatibility with PEAR 1.4.0.
+* For changes since 1.1.0, see the changelogs for the various RC releases.
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0RC7</version>
+    <date>2005-02-22</date>
+    <state>beta</state>
+    <notes>* Add the setSendEncoding() method and $send_encoding
+  property to XML_RPC_Message.  Request 3537.
+* Allow class methods to be mapped using either syntax:
+     'function' =&gt; 'hello::sayHello',
+     or
+     'function' =&gt; array('hello', 'sayhello'),
+  Bug 3363.
+* Use 8192 instead of 32768 for bytes in fread()
+  in parseResponseFile().  Bug 3340.
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0RC6</version>
+    <date>2005-01-25</date>
+    <state>beta</state>
+    <notes>* Don't put the protocol in the Host field of the POST data.  (danielc)
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0RC5</version>
+    <date>2005-01-24</date>
+    <state>beta</state>
+    <notes>* If $port is 443 but a protocol isn't specified in $server, assume ssl:// is the protocol.
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0RC4</version>
+    <date>2005-01-24</date>
+    <state>beta</state>
+    <notes>* When a connection attempt fails, have the method return 0.  (danielc)
+* Move the protocol/port checking/switching and the property settings from sendPayloadHTTP10() to the XML_RPC_Client constructor.  (danielc)
+* Add tests for setting the client properties.  (danielc)
+* Remove $GLOBALS['XML_RPC_twoslash'] since it's not used.  (danielc)
+* Bundle the tests with the package.  (danielc)
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0RC3</version>
+    <date>2005-01-19</date>
+    <state>beta</state>
+    <notes>* ssl uses port 443, not 445.
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0RC2</version>
+    <date>2005-01-11</date>
+    <state>beta</state>
+    <notes>* Handle ssl:// in the $server string.  (danielc)
+* Also default to port 445 for ssl:// requests as well.  (danielc)
+* Enhance debugging in the server.  (danielc)
+    </notes>
+   </release>
+   <release>
+    <version>1.2.0RC1</version>
+    <date>2004-12-30</date>
+    <state>beta</state>
+    <notes>* Make things work with SSL.  Bug 2489.  (nkukard lbsd net)
+* Allow array function callbacks (Matt Kane)
+* Some minor speed-ups (Matt Kane)
+* Add Dump.php to the package (Christian Weiske)
+* Replace all line endings with \r\n.  Had only done replacements on \n.  Bug 2521.  (danielc)
+* Silence fsockopen() errors.  Bug 1714.  (danielc)
+* Encode empty arrays as an array. Bug 1493.  (danielc)
+* Eliminate undefined index notice when submitting empty arrays to XML_RPC_Encode().  Bug 1819.  (danielc)
+* Speed up check for enumerated arrays in XML_RPC_Encode().  (danielc)
+* Prepend &quot;XML_RPC_&quot; to ERROR_NON_NUMERIC_FOUND, eliminating problem when eval()'ing error messages.  (danielc)
+* Use XML_RPC_Base::raiseError() instead of PEAR::raiseError() in XML_RPC_ee() because PEAR.php is lazy loaded.  (danielc)
+* Allow raiseError() to be called statically.  (danielc)
+* Stop double escaping of character entities.  Bug 987.  (danielc)
+  NOTICE: the following have been removed:
+    * XML_RPC_dh()
+    * $GLOBALS['XML_RPC_entities']
+    * XML_RPC_entity_decode()
+    * XML_RPC_lookup_entity()
+* Determine the XML's encoding via the encoding attribute in the XML declaration.  Bug 52.  (danielc)
+    </notes>
+   </release>
+   <release>
+    <version>1.1.0</version>
+    <date>2004-03-15</date>
+    <state>stable</state>
+    <notes>* Added support for sequential arrays to XML_RPC_encode() (mroch)
+* Cleaned up new XML_RPC_encode() changes a bit (mroch, pierre)
+* Remove &quot;require_once 'PEAR.php'&quot;, include only when needed to raise an error
+* Replace echo and error_log() with raiseError() (mroch)
+* Make all classes extend XML_RPC_Base, which will handle common functions  (mroch)
+* be tolerant of junk after methodResponse (Luca Mariano, mroch)
+* Silent notice even in the error log (pierre)
+* fix include of shared xml extension on win32 (pierre)
+    </notes>
+   </release>
+   <release>
+    <version>1.0.4</version>
+    <date>2002-10-02</date>
+    <state>stable</state>
+    <notes>* added HTTP proxy authorization support (thanks to Arnaud Limbourg)
+    </notes>
+   </release>
+   <release>
+    <version>1.0.3</version>
+    <date>2002-05-19</date>
+    <state>stable</state>
+    <notes>* fix bug when parsing responses with boolean types
+    </notes>
+   </release>
+   <release>
+    <version>1.0.2</version>
+    <date>2002-04-16</date>
+    <state>stable</state>
+    <notes>* E_ALL fixes
+* fix HTTP response header parsing
+    </notes>
+   </release>
+   <release>
+    <version>1.0.1</version>
+    <date>2001-09-25</date>
+    <state>stable</state>
+    <notes>This is a PEAR-ified version of Useful Inc's 1.0.1 release.
+Includes an urgent security fix identified by Dan Libby &lt;dan@libby.com&gt;.
+    </notes>
+   </release>
+ </changelog>
+</package>
+
\ Kein Zeilenumbruch am Dateiende.
diff -Nura php-5.0.4/php.ini-dist hardening-patch-5.0.4-0.4.1/php.ini-dist
--- php-5.0.4/php.ini-dist	2005-03-01 01:25:09.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/php.ini-dist	2005-08-06 23:43:57.404114784 +0200
@@ -1187,6 +1187,185 @@
 ; instead of original one.
 soap.wsdl_cache_ttl=86400
 
+[hardening-patch]
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's logging ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;
+; hphp.log.syslog   - Configures level for alerts reported through syslog
+; hphp.log.sapi     - Configures level for alerts reported through SAPI errorlog
+; hphp.log.script   - Configures level for alerts reported through external script
+;
+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
+; Or each number up to get desired Hardening-Patch's reporting level
+; 
+; S_ALL             - All alerts
+; S_MEMORY          - All canary violations and the safe unlink protection use this class
+; S_VARS            - All variable filters trigger this class
+; S_FILES           - All violation of uploaded files filter use this class
+; S_INCLUDE         - The protection against malicious include filenames use this class
+; S_SQL             - Failed SQL queries in MySQL are logged with this class
+; S_EXECUTOR        - The execution depth protection uses this logging class
+; S_MISC            - All other log messages (f.e. format string protection) use this class
+;
+; Example:
+;
+;   - Report all alerts (except memory alerts) to the SAPI errorlog, 
+;     memory alerts through syslog and SQL+Include alerts fo the script
+;
+;hphp.log.syslog = S_MEMORY
+;hphp.log.sapi   = S_ALL & ~S_MEMORY
+;hphp.log.script = S_INCLUDE | S_SQL
+;
+; Syslog logging:
+; 
+;   - Facility configuration: one of the following facilities
+;
+;        LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
+;        LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
+;        LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
+;        LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
+;        LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
+;        LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
+;        LOG_PERROR
+;
+;   - Priority configuration: one of the followinf priorities
+;
+;        LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
+;        LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
+; 
+hphp.log.syslog.priority = LOG_ALERT
+hphp.log.syslog.facility = LOG_USER
+;
+; Script logging:
+;
+;hphp.log.script.name = /home/hphp/log_script
+;
+; Alert configuration:
+;
+;   - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
+;
+;hphp.log.use-x-forwarded-for = On
+;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's Executor options ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Execution depth limit
+;hphp.executor.max_depth = 8000
+
+; White-/blacklist for function calls during normal execution
+;hphp.executor.func.whitelist = ord,chr
+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
+
+; White-/blacklist for function calls during eval() execution
+;hphp.executor.eval.whitelist = ord,chr
+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's REQUEST variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of REQUEST variables
+hphp.request.max_vars = 200
+
+; Limits the length of variable names (without indices)
+hphp.request.max_varname_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.request.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.request.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.request.max_array_depth = 100
+
+; Limits the length of variable values
+hphp.request.max_value_length = 65000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's COOKIE variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of COOKIE variables
+hphp.cookie.max_vars = 100
+
+; Limits the length of variable names (without indices)
+hphp.cookie.max_name_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.cookie.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.cookie.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.cookie.max_array_depth = 100
+
+; Limits the length of variable values
+hphp.cookie.max_value_length = 10000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's GET variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of COOKIE variables
+hphp.get.max_vars = 100
+
+; Limits the length of variable names (without indices)
+hphp.get.max_name_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.get.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.get.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.get.max_array_depth = 50
+
+; Limits the length of variable values
+hphp.get.max_value_length = 512
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's POST variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of POST variables
+hphp.post.max_vars = 200
+
+; Limits the length of variable names (without indices)
+hphp.post.max_name_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.post.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.post.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.post.max_array_depth = 100
+
+; Limits the length of variable values
+hphp.post.max_value_length = 65000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's fileupload variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of uploadable files
+hphp.upload.max_uploads = 25
+
+; Filter out the upload of ELF executables
+hphp.upload.disallow_elf_files = On
+
+; External filterscript for upload verification
+;hphp.upload.verification_script = /home/hphp/verify_script
+
+
 ; Local Variables:
 ; tab-width: 4
 ; End:
diff -Nura php-5.0.4/php.ini-recommended hardening-patch-5.0.4-0.4.1/php.ini-recommended
--- php-5.0.4/php.ini-recommended	2005-03-01 01:25:09.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/php.ini-recommended	2005-08-06 23:44:27.724505384 +0200
@@ -1245,6 +1245,184 @@
 ; instead of original one.
 soap.wsdl_cache_ttl=86400
 
+[hardening-patch]
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's logging ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;
+; hphp.log.syslog   - Configures level for alerts reported through syslog
+; hphp.log.sapi     - Configures level for alerts reported through SAPI errorlog
+; hphp.log.script   - Configures level for alerts reported through external script
+;
+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
+; Or each number up to get desired Hardening-Patch's reporting level
+; 
+; S_ALL             - All alerts
+; S_MEMORY          - All canary violations and the safe unlink protection use this class
+; S_VARS            - All variable filters trigger this class
+; S_FILES           - All violation of uploaded files filter use this class
+; S_INCLUDE         - The protection against malicious include filenames use this class
+; S_SQL             - Failed SQL queries in MySQL are logged with this class
+; S_EXECUTOR        - The execution depth protection uses this logging class
+; S_MISC            - All other log messages (f.e. format string protection) use this class
+;
+; Example:
+;
+;   - Report all alerts (except memory alerts) to the SAPI errorlog, 
+;     memory alerts through syslog and SQL+Include alerts fo the script
+;
+;hphp.log.syslog = S_MEMORY
+;hphp.log.sapi   = S_ALL & ~S_MEMORY
+;hphp.log.script = S_INCLUDE | S_SQL
+;
+; Syslog logging:
+; 
+;   - Facility configuration: one of the following facilities
+;
+;        LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
+;        LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
+;        LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
+;        LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
+;        LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
+;        LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
+;        LOG_PERROR
+;
+;   - Priority configuration: one of the followinf priorities
+;
+;        LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
+;        LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
+; 
+hphp.log.syslog.priority = LOG_ALERT
+hphp.log.syslog.facility = LOG_USER
+;
+; Script logging:
+;
+;hphp.log.script.name = /home/hphp/log_script
+;
+; Alert configuration:
+;
+;   - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
+;
+;hphp.log.use-x-forwarded-for = On
+;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's Executor options ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Execution depth limit
+;hphp.executor.max_depth = 8000
+
+; White-/blacklist for function calls during normal execution
+;hphp.executor.func.whitelist = ord,chr
+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
+
+; White-/blacklist for function calls during eval() execution
+;hphp.executor.eval.whitelist = ord,chr
+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's REQUEST variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of REQUEST variables
+hphp.request.max_vars = 200
+
+; Limits the length of variable names (without indices)
+hphp.request.max_varname_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.request.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.request.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.request.max_array_depth = 100
+
+; Limits the length of variable values
+hphp.request.max_value_length = 65000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's COOKIE variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of COOKIE variables
+hphp.cookie.max_vars = 100
+
+; Limits the length of variable names (without indices)
+hphp.cookie.max_name_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.cookie.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.cookie.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.cookie.max_array_depth = 100
+
+; Limits the length of variable values
+hphp.cookie.max_value_length = 10000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's GET variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of COOKIE variables
+hphp.get.max_vars = 100
+
+; Limits the length of variable names (without indices)
+hphp.get.max_name_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.get.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.get.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.get.max_array_depth = 50
+
+; Limits the length of variable values
+hphp.get.max_value_length = 512
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's POST variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of POST variables
+hphp.post.max_vars = 200
+
+; Limits the length of variable names (without indices)
+hphp.post.max_name_length = 64
+
+; Limits the length of complete variable names (with indices)
+hphp.post.max_totalname_length = 256
+
+; Limits the length of array indices
+hphp.post.max_array_index_length = 64
+
+; Limits the depth of arrays
+hphp.post.max_array_depth = 100
+
+; Limits the length of variable values
+hphp.post.max_value_length = 65000
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Hardening-Patch's fileupload variable filters ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Limits the number of uploadable files
+hphp.upload.max_uploads = 25
+
+; Filter out the upload of ELF executables
+hphp.upload.disallow_elf_files = On
+
+; External filterscript for upload verification
+;hphp.upload.verification_script = /home/hphp/verify_script
+
 ; Local Variables:
 ; tab-width: 4
 ; End:
diff -Nura php-5.0.4/sapi/apache/mod_php5.c hardening-patch-5.0.4-0.4.1/sapi/apache/mod_php5.c
--- php-5.0.4/sapi/apache/mod_php5.c	2004-07-14 11:43:26.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/sapi/apache/mod_php5.c	2005-08-04 12:06:45.000000000 +0200
@@ -447,7 +447,7 @@
 	sapi_apache_get_fd,
 	sapi_apache_force_http_10,
 	sapi_apache_get_target_uid,
-	sapi_apache_get_target_gid
+	sapi_apache_get_target_gid,
 };
 /* }}} */
 
@@ -899,7 +899,11 @@
 	{
 		TSRMLS_FETCH();
 		if (PG(expose_php)) {
+#if HARDENING_PATCH
+			ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
+#else
 			ap_add_version_component("PHP/" PHP_VERSION);
+#endif			
 		}
 	}
 #endif
diff -Nura php-5.0.4/sapi/apache2filter/sapi_apache2.c hardening-patch-5.0.4-0.4.1/sapi/apache2filter/sapi_apache2.c
--- php-5.0.4/sapi/apache2filter/sapi_apache2.c	2005-01-07 07:28:24.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/sapi/apache2filter/sapi_apache2.c	2005-08-04 12:06:45.000000000 +0200
@@ -572,7 +572,11 @@
 {
 	TSRMLS_FETCH();
 	if (PG(expose_php)) {
+#if HARDENING_PATCH
+		ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
+#else
 		ap_add_version_component(p, "PHP/" PHP_VERSION);
+#endif
 	}
 }
 
diff -Nura php-5.0.4/sapi/apache2handler/sapi_apache2.c hardening-patch-5.0.4-0.4.1/sapi/apache2handler/sapi_apache2.c
--- php-5.0.4/sapi/apache2handler/sapi_apache2.c	2005-03-10 12:23:57.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/sapi/apache2handler/sapi_apache2.c	2005-08-04 12:06:45.000000000 +0200
@@ -340,7 +340,11 @@
 {
 	TSRMLS_FETCH();
 	if (PG(expose_php)) {
+#if HARDENING_PATCH
+		ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
+#else
 		ap_add_version_component(p, "PHP/" PHP_VERSION);
+#endif
 	}
 }
 
diff -Nura php-5.0.4/sapi/cgi/cgi_main.c hardening-patch-5.0.4-0.4.1/sapi/cgi/cgi_main.c
--- php-5.0.4/sapi/cgi/cgi_main.c	2005-02-11 03:06:48.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/sapi/cgi/cgi_main.c	2005-08-04 12:06:45.000000000 +0200
@@ -1414,11 +1414,19 @@
 							SG(headers_sent) = 1;
 							SG(request_info).no_headers = 1;
 						}
+#if HARDENING_PATCH
+#if ZEND_DEBUG
+						php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+#else
+						php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+#endif
+#else
 #if ZEND_DEBUG
 						php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
 #else
 						php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
 #endif
+#endif
 						php_end_ob_buffers(1 TSRMLS_CC);
 						exit(1);
 						break;
diff -Nura php-5.0.4/sapi/cli/php_cli.c hardening-patch-5.0.4-0.4.1/sapi/cli/php_cli.c
--- php-5.0.4/sapi/cli/php_cli.c	2005-03-22 16:09:20.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/sapi/cli/php_cli.c	2005-08-04 12:06:45.000000000 +0200
@@ -694,11 +694,19 @@
 				if (php_request_startup(TSRMLS_C)==FAILURE) {
 					goto err;
 				}
+#if HARDENING_PATCH
+#if ZEND_DEBUG
+				php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+#else
+				php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+#endif
+#else
 #if ZEND_DEBUG
 				php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
 #else
 				php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
 #endif
+#endif
 				php_end_ob_buffers(1 TSRMLS_CC);
 				exit_status=1;
 				goto out;
diff -Nura php-5.0.4/TSRM/TSRM.h hardening-patch-5.0.4-0.4.1/TSRM/TSRM.h
--- php-5.0.4/TSRM/TSRM.h	2005-03-11 12:12:07.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/TSRM/TSRM.h	2005-08-04 12:06:45.000000000 +0200
@@ -33,6 +33,13 @@
 #	define TSRM_API
 #endif
 
+#if HARDENING_PATCH
+# if HAVE_REALPATH
+#  undef realpath
+#  define realpath php_realpath
+# endif
+#endif
+
 /* Only compile multi-threading functions if we're in ZTS mode */
 #ifdef ZTS
 
@@ -88,6 +95,7 @@
 
 #define THREAD_HASH_OF(thr,ts)  (unsigned long)thr%(unsigned long)ts
 
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff -Nura php-5.0.4/TSRM/tsrm_virtual_cwd.c hardening-patch-5.0.4-0.4.1/TSRM/tsrm_virtual_cwd.c
--- php-5.0.4/TSRM/tsrm_virtual_cwd.c	2005-03-11 12:09:42.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/TSRM/tsrm_virtual_cwd.c	2005-08-04 12:06:45.000000000 +0200
@@ -197,6 +197,165 @@
     return p;
 }
 
+#if HARDENING_PATCH
+CWD_API char *php_realpath(const char *path, char *resolved)
+{
+        struct stat sb;
+        char *p, *q, *s;
+        size_t left_len, resolved_len;
+        unsigned symlinks;
+        int serrno, slen;
+        int is_dir = 1;
+        char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
+
+        serrno = errno;
+        symlinks = 0;
+        if (path[0] == '/') {
+                resolved[0] = '/';
+                resolved[1] = '\0';
+                if (path[1] == '\0')
+                        return (resolved);
+                resolved_len = 1;
+                left_len = strlcpy(left, path + 1, sizeof(left));
+        } else {
+                if (getcwd(resolved, PATH_MAX) == NULL) {
+                        strlcpy(resolved, ".", PATH_MAX);
+                        return (NULL);
+                }
+                resolved_len = strlen(resolved);
+                left_len = strlcpy(left, path, sizeof(left));
+        }
+        if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
+                errno = ENAMETOOLONG;
+                return (NULL);
+        }
+
+        /*
+         * Iterate over path components in `left'.
+         */
+        while (left_len != 0) {
+                /*
+                 * Extract the next path component and adjust `left'
+                 * and its length.
+                 */
+                p = strchr(left, '/');
+                s = p ? p : left + left_len;
+                if (s - left >= sizeof(next_token)) {
+                        errno = ENAMETOOLONG;
+                        return (NULL);
+                }
+                memcpy(next_token, left, s - left);
+                next_token[s - left] = '\0';
+                left_len -= s - left;
+                if (p != NULL)
+                        memmove(left, s + 1, left_len + 1);
+                if (resolved[resolved_len - 1] != '/') {
+                        if (resolved_len + 1 >= PATH_MAX) {
+                                errno = ENAMETOOLONG;
+                                return (NULL);
+                        }
+                        resolved[resolved_len++] = '/';
+                        resolved[resolved_len] = '\0';
+                }
+                if (next_token[0] == '\0')
+                        continue;
+                else if (strcmp(next_token, ".") == 0)
+                        continue;
+                else if (strcmp(next_token, "..") == 0) {
+                        /*
+                         * Strip the last path component except when we have
+                         * single "/"
+                         */
+                        if (!is_dir) {
+                                errno = ENOENT;
+                                return (NULL);
+                        }
+                        if (resolved_len > 1) {
+                                resolved[resolved_len - 1] = '\0';
+                                q = strrchr(resolved, '/');
+                                *q = '\0';
+                                resolved_len = q - resolved;
+                        }
+                        continue;
+                }
+
+                /*
+                 * Append the next path component and lstat() it. If
+                 * lstat() fails we still can return successfully if
+                 * there are no more path components left.
+                 */
+                resolved_len = strlcat(resolved, next_token, PATH_MAX);
+                if (resolved_len >= PATH_MAX) {
+                        errno = ENAMETOOLONG;
+                        return (NULL);
+                }
+                if (lstat(resolved, &sb) != 0) {
+                        if (errno == ENOENT && p == NULL) {
+                                errno = serrno;
+                                return (resolved);
+                        }
+                        return (NULL);
+                }
+                if (S_ISLNK(sb.st_mode)) {
+                        if (symlinks++ > MAXSYMLINKS) {
+                                errno = ELOOP;
+                                return (NULL);
+                        }
+                        slen = readlink(resolved, symlink, sizeof(symlink) - 1);
+                        if (slen < 0)
+                                return (NULL);
+                        symlink[slen] = '\0';
+                        if (symlink[0] == '/') {
+                                resolved[1] = 0;
+                                resolved_len = 1;
+                        } else if (resolved_len > 1) {
+                                /* Strip the last path component. */
+                                resolved[resolved_len - 1] = '\0';
+                                q = strrchr(resolved, '/');
+                                *q = '\0';
+                                resolved_len = q - resolved;
+                        }
+
+                        /*
+                         * If there are any path components left, then
+                         * append them to symlink. The result is placed
+                         * in `left'.
+                         */
+                        if (p != NULL) {
+                                if (symlink[slen - 1] != '/') {
+                                        if (slen + 1 >= sizeof(symlink)) {
+                                                errno = ENAMETOOLONG;
+                                                return (NULL);
+                                        }
+                                        symlink[slen] = '/';
+                                        symlink[slen + 1] = 0;
+                                }
+                                left_len = strlcat(symlink, left, sizeof(left));
+                                if (left_len >= sizeof(left)) {
+                                        errno = ENAMETOOLONG;
+                                        return (NULL);
+                                }
+                        }
+                        left_len = strlcpy(left, symlink, sizeof(left));
+                } else {
+            		if (S_ISDIR(sb.st_mode)) {
+                    		is_dir = 1;
+            		} else {
+                    		is_dir = 0;
+            		}
+		}
+        }
+
+        /*
+         * Remove trailing slash except when the resolved pathname
+         * is a single "/".
+         */
+        if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
+                resolved[resolved_len - 1] = '\0';
+        return (resolved);
+}
+#endif
+
 CWD_API void virtual_cwd_startup(void)
 {
 	char cwd[MAXPATHLEN];
@@ -321,8 +480,7 @@
 				path = resolved_path;
 				path_length = strlen(path);
 			} else {
-				/* disable for now
-				return 1; */
+				return 1;
 			}
 		}
 	} else { /* Concat current directory with relative path and then run realpath() on it */
@@ -348,9 +506,8 @@
 				path = resolved_path;
 				path_length = strlen(path);
 			} else {
-				/* disable for now 
 				free(tmp);
-				return 1; */
+				return 1;
 			}
 		}
 		free(tmp);
diff -Nura php-5.0.4/TSRM/tsrm_virtual_cwd.h hardening-patch-5.0.4-0.4.1/TSRM/tsrm_virtual_cwd.h
--- php-5.0.4/TSRM/tsrm_virtual_cwd.h	2005-03-11 12:07:17.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/TSRM/tsrm_virtual_cwd.h	2005-08-04 12:06:45.000000000 +0200
@@ -128,6 +128,22 @@
 
 typedef int (*verify_path_func)(const cwd_state *);
 
+#ifndef HAVE_STRLCPY
+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
+#undef strlcpy
+#define strlcpy php_strlcpy
+#endif
+
+#ifndef HAVE_STRLCAT
+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
+#undef strlcat
+#define strlcat php_strlcat
+#endif
+
+
+#if HARDENING_PATCH
+CWD_API char *php_realpath(const char *path, char *resolved);
+#endif
 CWD_API void virtual_cwd_startup(void);
 CWD_API void virtual_cwd_shutdown(void);
 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
diff -Nura php-5.0.4/Zend/zend_alloc.c hardening-patch-5.0.4-0.4.1/Zend/zend_alloc.c
--- php-5.0.4/Zend/zend_alloc.c	2004-08-27 18:49:54.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_alloc.c	2005-08-04 12:54:06.000000000 +0200
@@ -64,6 +64,11 @@
 # define END_MAGIC_SIZE 0
 #endif
 
+#if HARDENING_PATCH_MM_PROTECT
+# define CANARY_SIZE sizeof(unsigned int)
+#else
+# define CANARY_SIZE 0
+#endif
 
 # if MEMORY_LIMIT
 #  if ZEND_DEBUG
@@ -104,9 +109,17 @@
 	if (p==AG(head)) {							\
 		AG(head) = p->pNext;					\
 	} else {									\
+		if (p != p->pLast->pNext) {				\
+			zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
+			exit(1);							\
+		}										\
 		p->pLast->pNext = p->pNext;				\
 	}											\
 	if (p->pNext) {								\
+		if (p != p->pNext->pLast) {				\
+			zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
+			exit(1);							\
+		}										\
 		p->pNext->pLast = p->pLast;				\
 	}
 #else
@@ -145,6 +158,12 @@
 	DECLARE_CACHE_VARS();
 	TSRMLS_FETCH();
 
+#if HARDENING_PATCH_MM_PROTECT
+	if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
+		zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
+		exit(1);
+	}
+#endif
 	CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
 
 #if !ZEND_DISABLE_MEMORY_CACHE
@@ -163,6 +182,10 @@
 		AG(cache_stats)[CACHE_INDEX][1]++;
 		memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
 #endif
+#if HARDENING_PATCH_MM_PROTECT
+		p->canary = HG(canary_1);
+		memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
+#endif
 		p->cached = 0;
 		p->size = size;
 		return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
@@ -179,7 +202,7 @@
 			AG(allocated_memory_peak) = AG(allocated_memory);
 		}
 #endif
-		p  = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
+		p  = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
 #if !ZEND_DISABLE_MEMORY_CACHE
 	}
 #endif
@@ -211,7 +234,10 @@
 # endif
 	memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
 #endif
-
+#if HARDENING_PATCH_MM_PROTECT
+ 	p->canary = HG(canary_1);
+ 	memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
+#endif
 	HANDLE_UNBLOCK_INTERRUPTIONS();
 	return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
 }
@@ -239,6 +265,10 @@
 		}
 	}
 
+	
+#if HARDENING_PATCH
+	zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
+#endif
 	zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
 	return 0;
 }
@@ -247,9 +277,25 @@
 
 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
+#if HARDENING_PATCH_MM_PROTECT
+	unsigned int canary_2;
+#endif
 	zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
 	DECLARE_CACHE_VARS();
 	TSRMLS_FETCH();
+  
+#if HARDENING_PATCH_MM_PROTECT
+	if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
+	memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
+	if (canary_2 != HG(canary_2)) {
+efree_canary_mismatch:
+		zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
+		exit(1);
+	}
+	/* to catch double efree()s */
+	memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
+	p->canary = 0;
+#endif
 
 #if defined(ZTS) && TSRM_DEBUG
 	if (p->thread_id != tsrm_thread_id()) {
@@ -291,23 +337,35 @@
 
 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
-	void *p;
-	int final_size = size*nmemb;
+	char *p;
+	size_t _size = nmemb * size;
+    
+	if (nmemb && (_size/nmemb!=size)) {
+#if HARDENING_PATCH
+		zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
+#endif
+		fprintf(stderr,"FATAL:  ecalloc():  Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
+		kill(getpid(), SIGSEGV);
+#else
+		exit(1);
+#endif
+	}
 	
-	HANDLE_BLOCK_INTERRUPTIONS();
-	p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
-	if (!p) {
-		HANDLE_UNBLOCK_INTERRUPTIONS();
-		return (void *) p;
+	p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
+	if (p) {
+		memset(p, 0, _size);
 	}
-	memset(p, 0, final_size);
-	HANDLE_UNBLOCK_INTERRUPTIONS();
-	return p;
+	
+	return ((void *)p);
 }
 
 
 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
 {
+#if HARDENING_PATCH_MM_PROTECT
+	unsigned int canary_2;
+#endif
 	zend_mem_header *p;
 	zend_mem_header *orig;
 	DECLARE_CACHE_VARS();
@@ -319,6 +377,16 @@
 
 	p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
 
+#if HARDENING_PATCH_MM_PROTECT
+	if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
+	memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
+	if (canary_2 != HG(canary_2)) {
+erealloc_canary_mismatch:
+		zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
+		exit(1);
+	}
+#endif
+
 #if defined(ZTS) && TSRM_DEBUG
 	if (p->thread_id != tsrm_thread_id()) {
 		void *new_p;
@@ -342,7 +410,7 @@
 	}
 #endif
 	REMOVE_POINTER_FROM_LIST(p);
-	p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
+	p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
 	if (!p) {
 		if (!allow_failure) {
 			fprintf(stderr,"FATAL:  erealloc():  Unable to allocate %ld bytes\n", (long) size);
@@ -364,6 +432,9 @@
 	memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
 #endif	
 
+#if HARDENING_PATCH_MM_PROTECT
+ 	memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
+#endif
 	p->size = size;
 
 	HANDLE_UNBLOCK_INTERRUPTIONS();
@@ -439,6 +510,10 @@
 {
 	AG(head) = NULL;
 	
+#if HARDENING_PATCH_MM_PROTECT
+	HG(canary_1) = zend_canary();
+	HG(canary_2) = zend_canary();
+#endif
 #if MEMORY_LIMIT
 	AG(memory_limit) = 1<<30;		/* ridiculous limit, effectively no limit */
 	AG(allocated_memory) = 0;
diff -Nura php-5.0.4/Zend/zend_alloc.h hardening-patch-5.0.4-0.4.1/Zend/zend_alloc.h
--- php-5.0.4/Zend/zend_alloc.h	2004-08-11 08:13:12.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_alloc.h	2005-08-04 12:06:45.000000000 +0200
@@ -35,6 +35,9 @@
 #define MEM_BLOCK_CACHED_MAGIC	0xFB8277DCL
 
 typedef struct _zend_mem_header {
+#if HARDENING_PATCH_MM_PROTECT
+	unsigned int canary;
+#endif
 #if ZEND_DEBUG
 	long magic;
 	char *filename;
diff -Nura php-5.0.4/Zend/zend_API.h hardening-patch-5.0.4-0.4.1/Zend/zend_API.h
--- php-5.0.4/Zend/zend_API.h	2005-01-22 13:29:13.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_API.h	2005-08-04 12:06:45.000000000 +0200
@@ -47,6 +47,7 @@
 #define ZEND_METHOD(classname, name)	ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
 
 #define ZEND_FENTRY(zend_name, name, arg_info, flags)	{ #zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
+#define ZEND_STATIC_FE(zend_name, name, arg_info)	{ zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), 0 },
 
 #define ZEND_NAMED_FE(zend_name, name, arg_info)	ZEND_FENTRY(zend_name, name, arg_info, 0)
 #define ZEND_FE(name, arg_info)						ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
diff -Nura php-5.0.4/Zend/zend_builtin_functions.c hardening-patch-5.0.4-0.4.1/Zend/zend_builtin_functions.c
--- php-5.0.4/Zend/zend_builtin_functions.c	2005-03-14 10:13:14.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_builtin_functions.c	2005-08-04 12:06:45.000000000 +0200
@@ -52,6 +52,9 @@
 static ZEND_FUNCTION(crash);
 #endif
 #endif
+#if HARDENING_PATCH_MM_PROTECT_DEBUG
+static ZEND_FUNCTION(heap_overflow);
+#endif
 static ZEND_FUNCTION(get_included_files);
 static ZEND_FUNCTION(is_subclass_of);
 static ZEND_FUNCTION(is_a);
@@ -111,6 +114,9 @@
 	ZEND_FE(crash,				NULL)
 #endif
 #endif
+#if HARDENING_PATCH_MM_PROTECT_DEBUG
+	ZEND_FE(heap_overflow,			NULL)
+#endif
 	ZEND_FE(get_included_files,	NULL)
 	ZEND_FALIAS(get_required_files,	get_included_files,		NULL)
 	ZEND_FE(is_subclass_of,		NULL)
@@ -999,6 +1005,19 @@
 
 #endif /* ZEND_DEBUG */
 
+
+#if HARDENING_PATCH_MM_PROTECT_DEBUG
+ZEND_FUNCTION(heap_overflow)
+{
+	char *nowhere = emalloc(10);
+
+	memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
+	
+	efree(nowhere);
+}
+#endif
+
+
 /* {{{ proto array get_included_files(void)
    Returns an array with the file names that were include_once()'d */
 ZEND_FUNCTION(get_included_files)
diff -Nura php-5.0.4/Zend/zend.c hardening-patch-5.0.4-0.4.1/Zend/zend.c
--- php-5.0.4/Zend/zend.c	2005-03-16 00:47:12.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend.c	2005-08-04 18:26:27.000000000 +0200
@@ -54,6 +54,12 @@
 ZEND_API void (*zend_unblock_interruptions)(void);
 ZEND_API void (*zend_ticks_function)(int ticks);
 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
+#if HARDENING_PATCH
+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
+#endif
+#if HARDENING_PATCH_INC_PROTECT
+ZEND_API int (*zend_is_valid_include)(zval *z);
+#endif
 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
 
 void (*zend_on_timeout)(int seconds TSRMLS_DC);
@@ -72,9 +78,289 @@
 	return SUCCESS;
 }
 
+#if HARDENING_PATCH
+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
+{
+	if (!new_value) {
+		EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY;
+	} else {
+		EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY;
+	}
+	return SUCCESS;
+}
+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
+{
+	if (!new_value) {
+		EG(hphp_log_syslog_facility) = LOG_USER;
+	} else {
+		EG(hphp_log_syslog_facility) = atoi(new_value);
+	}
+	return SUCCESS;
+}
+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
+{
+	if (!new_value) {
+		EG(hphp_log_syslog_priority) = LOG_ALERT;
+	} else {
+		EG(hphp_log_syslog_priority) = atoi(new_value);
+	}
+	return SUCCESS;
+}
+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
+{
+	if (!new_value) {
+		EG(hphp_log_sapi) = S_ALL & ~S_SQL;
+	} else {
+		EG(hphp_log_sapi) = atoi(new_value);
+	}
+	return SUCCESS;
+}
+static ZEND_INI_MH(OnUpdateHPHP_log_script)
+{
+	if (!new_value) {
+		EG(hphp_log_script) = S_ALL & ~S_MEMORY;
+	} else {
+		EG(hphp_log_script) = atoi(new_value) & ~S_MEMORY;
+	}
+	return SUCCESS;
+}
+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
+{
+	if (!new_value) {
+		EG(hphp_log_scriptname) = NULL;
+	} else {
+		if (EG(hphp_log_scriptname)) {
+			pefree(EG(hphp_log_scriptname),1);
+		}
+		EG(hphp_log_scriptname) = pestrdup(new_value,1);
+	}
+	return SUCCESS;
+}
+
+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
+{
+	char *s = NULL, *e, *val;
+	unsigned long dummy = 1;
+
+	if (!new_value) {
+eval_whitelist_destroy:
+		if (HG(eval_whitelist)) {
+			zend_hash_destroy(HG(eval_whitelist));
+			efree(HG(eval_whitelist));
+		}
+		HG(eval_whitelist) = NULL;
+		return SUCCESS;
+	}
+	if (!(*new_value)) {
+		goto eval_whitelist_destroy;
+	}
+	
+	ALLOC_HASHTABLE(HG(eval_whitelist));
+	zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 0);
+	
+	val = zend_str_tolower_dup(new_value, strlen(new_value));
+	e = val;
+
+	while (*e) {
+		switch (*e) {
+			case ' ':
+			case ',':
+				if (s) {
+					*e = '\0';
+					zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+					s = NULL;
+				}
+				break;
+			default:
+				if (!s) {
+					s = e;
+				}
+				break;
+		}
+		e++;
+	}
+	if (s) {
+		zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+	}
+	efree(val);
+	
+	return SUCCESS;
+}
+
+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
+{
+	char *s = NULL, *e, *val;
+	unsigned long dummy = 1;
+
+	if (!new_value) {
+eval_blacklist_destroy:
+		if (HG(eval_blacklist)) {
+			zend_hash_destroy(HG(eval_blacklist));
+			efree(HG(eval_blacklist));
+		}
+		HG(eval_blacklist) = NULL;
+		return SUCCESS;
+	}
+	if (!(*new_value)) {
+		goto eval_blacklist_destroy;
+	}
+	
+	ALLOC_HASHTABLE(HG(eval_blacklist));
+	zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 0);
+	
+	val = zend_str_tolower_dup(new_value, strlen(new_value));
+	e = val;
+
+	while (*e) {
+		switch (*e) {
+			case ' ':
+			case ',':
+				if (s) {
+					*e = '\0';
+					zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+					s = NULL;
+				}
+				break;
+			default:
+				if (!s) {
+					s = e;
+				}
+				break;
+		}
+		e++;
+	}
+	if (s) {
+		zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+	}
+	efree(val);
+	
+	
+	return SUCCESS;
+}
+
+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
+{
+	char *s = NULL, *e, *val;
+	unsigned long dummy = 1;
+
+	if (!new_value) {
+func_whitelist_destroy:
+		if (HG(func_whitelist)) {
+			zend_hash_destroy(HG(func_whitelist));
+			efree(HG(func_whitelist));
+		}
+		HG(func_whitelist) = NULL;
+		return SUCCESS;
+	}
+	if (!(*new_value)) {
+		goto func_whitelist_destroy;
+	}
+	
+	ALLOC_HASHTABLE(HG(func_whitelist));
+	zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 0);
+	
+	val = zend_str_tolower_dup(new_value, strlen(new_value));
+	e = val;
+
+	while (*e) {
+		switch (*e) {
+			case ' ':
+			case ',':
+				if (s) {
+					*e = '\0';
+					zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+					s = NULL;
+				}
+				break;
+			default:
+				if (!s) {
+					s = e;
+				}
+				break;
+		}
+		e++;
+	}
+	if (s) {
+		zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+	}
+	efree(val);
+	
+	return SUCCESS;
+}
+
+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
+{
+	char *s = NULL, *e, *val;
+	unsigned long dummy = 1;
+
+	if (!new_value) {
+func_blacklist_destroy:
+		if (HG(func_blacklist)) {
+			zend_hash_destroy(HG(func_blacklist));
+			efree(HG(func_blacklist));
+		}
+		HG(func_blacklist) = NULL;
+		return SUCCESS;
+	}
+	if (!(*new_value)) {
+		goto func_blacklist_destroy;
+	}
+	
+	ALLOC_HASHTABLE(HG(func_blacklist));
+	zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 0);
+	
+	val = zend_str_tolower_dup(new_value, strlen(new_value));
+	e = val;
+
+	while (*e) {
+		switch (*e) {
+			case ' ':
+			case ',':
+				if (s) {
+					*e = '\0';
+					zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+					s = NULL;
+				}
+				break;
+			default:
+				if (!s) {
+					s = e;
+				}
+				break;
+		}
+		e++;
+	}
+	if (s) {
+		zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
+	}
+	efree(val);
+	
+	
+	return SUCCESS;
+}
+
+#endif
 
 ZEND_INI_BEGIN()
 	ZEND_INI_ENTRY("error_reporting",				NULL,		ZEND_INI_ALL,		OnUpdateErrorReporting)
+#if HARDENING_PATCH
+	ZEND_INI_ENTRY("hphp.log.syslog",			NULL,		ZEND_INI_SYSTEM,	OnUpdateHPHP_log_syslog)
+	ZEND_INI_ENTRY("hphp.log.syslog.facility",		NULL,		ZEND_INI_SYSTEM,	OnUpdateHPHP_log_syslog_facility)
+	ZEND_INI_ENTRY("hphp.log.syslog.priority",		NULL,		ZEND_INI_SYSTEM,	OnUpdateHPHP_log_syslog_priority)
+	ZEND_INI_ENTRY("hphp.log.sapi",				NULL,		ZEND_INI_SYSTEM,	OnUpdateHPHP_log_sapi)
+	ZEND_INI_ENTRY("hphp.log.script",			NULL,		ZEND_INI_SYSTEM,	OnUpdateHPHP_log_script)
+	ZEND_INI_ENTRY("hphp.log.script.name",			NULL,		ZEND_INI_SYSTEM,	OnUpdateHPHP_log_scriptname)
+	STD_ZEND_INI_BOOLEAN("hphp.log.use-x-forwarded-for",	"0",		ZEND_INI_SYSTEM,	OnUpdateBool, hphp_log_use_x_forwarded_for,	zend_executor_globals,	executor_globals)
+
+	ZEND_INI_ENTRY("hphp.executor.eval.whitelist",	NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateHPHP_eval_whitelist)
+	ZEND_INI_ENTRY("hphp.executor.eval.blacklist",	NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateHPHP_eval_blacklist)
+	ZEND_INI_ENTRY("hphp.executor.func.whitelist",	NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateHPHP_func_whitelist)
+	ZEND_INI_ENTRY("hphp.executor.func.blacklist",	NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateHPHP_func_blacklist)
+
+	STD_ZEND_INI_ENTRY("hphp.executor.max_depth",		"0",		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
+	STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error",	"0",		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateBool, hphp_sql_bailout_on_error,	hardened_globals_struct,	hardened_globals)
+	STD_ZEND_INI_BOOLEAN("hphp.multiheader",		"0",		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateBool, hphp_multiheader,	hardened_globals_struct,	hardened_globals)
+#endif
 	STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode",	"0",	ZEND_INI_ALL,		OnUpdateBool,	ze1_compatibility_mode,	zend_executor_globals,	executor_globals)
 ZEND_INI_END()
 
@@ -476,6 +762,7 @@
 	EG(user_error_handler) = NULL;
 	EG(user_exception_handler) = NULL;
 	EG(in_execution) = 0;
+	EG(in_code_type) = 0;
 	EG(in_autoload) = NULL;
 	EG(current_execute_data) = NULL;
 	EG(current_module) = NULL;
@@ -545,6 +832,14 @@
 	extern zend_scanner_globals language_scanner_globals;
 #endif
 
+	/* Set up Hardening-Patch utility functions first */
+#if HARDENING_PATCH
+	zend_security_log = utility_functions->security_log_function;
+#endif
+#if HARDENING_PATCH_INC_PROTECT
+	zend_is_valid_include = utility_functions->is_valid_include;
+#endif
+
 #ifdef ZTS
 	ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
 #else
@@ -747,6 +1042,7 @@
 	}
 	CG(unclean_shutdown) = 1;
 	CG(in_compilation) = EG(in_execution) = 0;
+	EG(in_code_type) = 0;
 	EG(current_execute_data) = NULL;
 	longjmp(EG(bailout), FAILURE);
 }
diff -Nura php-5.0.4/Zend/zend_canary.c hardening-patch-5.0.4-0.4.1/Zend/zend_canary.c
--- php-5.0.4/Zend/zend_canary.c	1970-01-01 01:00:00.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_canary.c	2005-08-04 12:06:45.000000000 +0200
@@ -0,0 +1,58 @@
+/*
+   +----------------------------------------------------------------------+
+   | Hardening-Patch for PHP                                              |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 2004-2005 Stefan Esser                                 |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Stefan Esser <sesser@hardened-php.net>                       |
+   +----------------------------------------------------------------------+
+ */
+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
+
+#include "zend.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
+
+/* will be replaced later with more compatible method */
+ZEND_API unsigned int zend_canary()
+{
+	time_t t;
+	unsigned int canary;
+	int fd;
+	
+	fd = open("/dev/urandom", 0);
+	if (fd != -1) {
+		int r = read(fd, &canary, sizeof(canary));
+		close(fd);
+		if (r == sizeof(canary)) {
+			return (canary);
+		}
+	}
+	/* not good but we never want to do this */
+	time(&t);
+	canary = *(unsigned int *)&t + getpid() << 16;
+	return (canary);
+}
+#endif
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */
diff -Nura php-5.0.4/Zend/zend_compile.c hardening-patch-5.0.4-0.4.1/Zend/zend_compile.c
--- php-5.0.4/Zend/zend_compile.c	2005-03-10 14:24:32.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_compile.c	2005-08-06 10:08:48.000000000 +0200
@@ -969,6 +969,13 @@
 	op_array.prototype = NULL;
 
 	op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
+#if HARDENING_PATCH
+	if (EG(in_code_type)==ZEND_EVAL_CODE) {
+		op_array.created_by_eval = 1;
+	} else {
+		op_array.created_by_eval = 0;
+	}
+#endif
 
 	if (is_method) {
 		char *short_class_name = CG(active_class_entry)->name;
@@ -1455,7 +1462,7 @@
 	zend_op *opline;
 	
 	if (switch_entry->cond.op_type != IS_VAR && switch_entry->cond.op_type != IS_TMP_VAR) {
-		return 0;
+		return (switch_entry->cond.op_type == IS_UNUSED);
 	}
 	
 	opline = get_next_op(CG(active_op_array) TSRMLS_CC);
diff -Nura php-5.0.4/Zend/zend_compile.h hardening-patch-5.0.4-0.4.1/Zend/zend_compile.h
--- php-5.0.4/Zend/zend_compile.h	2004-09-16 02:44:12.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_compile.h	2005-08-06 09:42:21.000000000 +0200
@@ -197,6 +197,9 @@
 	zend_uint doc_comment_len;
 
 	void *reserved[ZEND_MAX_RESERVED_RESOURCES];
+#if HARDENING_PATCH
+	zend_bool created_by_eval;
+#endif	
 };
 
 
@@ -275,6 +278,8 @@
 	zval *object;
 	union _temp_variable *Ts;
 	zend_bool original_in_execution;
+	zend_uint original_in_code_type;
+	zend_uint execute_depth;
 	zend_class_entry *calling_scope;
 	struct _zend_execute_data *prev_execute_data;
 };
@@ -767,6 +772,7 @@
 #define ZEND_OVERLOADED_FUNCTION			3
 #define	ZEND_EVAL_CODE						4
 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY	5
+#define ZEND_SANDBOX_CODE			6
 
 #define ZEND_INTERNAL_CLASS         1
 #define ZEND_USER_CLASS             2
diff -Nura php-5.0.4/Zend/zend_constants.c hardening-patch-5.0.4-0.4.1/Zend/zend_constants.c
--- php-5.0.4/Zend/zend_constants.c	2004-07-13 21:22:11.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_constants.c	2005-08-04 12:06:45.000000000 +0200
@@ -107,6 +107,72 @@
 	REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
 
 	REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
+#if HARDENING_PATCH
+	REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_VARS, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
+	REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
+
+	/* error levels */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); 
+	REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
+	/* facility: type of program logging the message */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
+#ifdef LOG_NEWS
+	/* No LOG_NEWS on HP-UX */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
+#endif
+#ifdef LOG_UUCP
+	/* No LOG_UUCP on HP-UX */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef LOG_CRON
+	/* apparently some systems don't have this one */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef LOG_AUTHPRIV
+	/* AIX doesn't have LOG_AUTHPRIV */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
+#endif
+#if !defined(PHP_WIN32) && !defined(NETWARE)
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
+#endif
+	/* options */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
+	REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
+#ifdef LOG_NOWAIT
+	REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef LOG_PERROR
+	/* AIX doesn't have LOG_PERROR */
+	REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
+#endif
+#endif
 
 	/* true/false constants */
 	{
diff -Nura php-5.0.4/Zend/zend_errors.h hardening-patch-5.0.4-0.4.1/Zend/zend_errors.h
--- php-5.0.4/Zend/zend_errors.h	2004-01-08 18:31:47.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_errors.h	2005-08-04 14:15:42.000000000 +0200
@@ -38,6 +38,17 @@
 #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
 
+#if HARDENING_PATCH
+#define S_MEMORY			(1<<0L)
+#define S_VARS				(1<<1L)
+#define S_FILES				(1<<2L)
+#define S_INCLUDE			(1<<3L)
+#define S_SQL				(1<<4L)
+#define S_EXECUTOR			(1<<5L)
+#define S_MISC				(1<<30L)
+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
+#endif
+
 #endif /* ZEND_ERRORS_H */
 
 /*
diff -Nura php-5.0.4/Zend/zend_execute_API.c hardening-patch-5.0.4-0.4.1/Zend/zend_execute_API.c
--- php-5.0.4/Zend/zend_execute_API.c	2005-03-19 15:29:18.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_execute_API.c	2005-08-04 18:31:56.000000000 +0200
@@ -137,6 +137,7 @@
 	EG(class_table) = CG(class_table);
 
 	EG(in_execution) = 0;
+	EG(in_code_type) = 0;
 	EG(in_autoload) = NULL;
 
 	zend_ptr_stack_init(&EG(argument_stack));
@@ -714,6 +715,39 @@
 			if (zend_hash_find(fci->function_table, function_name_lc, fci->function_name->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
 			  EX(function_state).function = NULL;
 			}
+#if HARDENING_PATCH	
+			else {
+				if (EG(in_code_type) == ZEND_EVAL_CODE) {
+					if (HG(eval_whitelist) != NULL) {
+						if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
+							zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc);
+							efree(function_name_lc);
+							zend_bailout();
+						}
+					} else if (HG(eval_blacklist) != NULL) {
+						if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
+			    				zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc);
+			    				efree(function_name_lc);
+							zend_bailout();
+						}
+					}
+				}
+				
+				if (HG(func_whitelist) != NULL) {
+					if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
+						zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc);
+						efree(function_name_lc);
+						zend_bailout();
+					}
+				} else if (HG(func_blacklist) != NULL) {
+					if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
+			    			zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc);
+			    			efree(function_name_lc);
+						zend_bailout();
+					}
+				}
+			}
+#endif
 			efree(function_name_lc);
 		}
 
@@ -966,7 +1000,7 @@
 	return retval;
 }
 
-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
 {
 	zval pv;
 	zend_op_array *new_op_array;
@@ -999,6 +1033,7 @@
 		zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
 		zend_op **original_opline_ptr = EG(opline_ptr);
 
+		new_op_array->type = type;
 		EG(return_value_ptr_ptr) = &local_retval_ptr;
 		EG(active_op_array) = new_op_array;
 		EG(no_extensions)=1;
@@ -1033,6 +1068,12 @@
 }
 
 
+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
+{
+	return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
+}
+
+
 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
 {
 	int result;
diff -Nura php-5.0.4/Zend/zend_execute.c hardening-patch-5.0.4-0.4.1/Zend/zend_execute.c
--- php-5.0.4/Zend/zend_execute.c	2005-03-21 17:22:10.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_execute.c	2005-08-06 09:47:01.000000000 +0200
@@ -1343,6 +1343,7 @@
  		efree(EX(Ts));							\
  	}									\
 	EG(in_execution) = EX(original_in_execution);							\
+	EG(in_code_type) = EX(original_in_code_type);								\
 	EG(current_execute_data) = EX(prev_execute_data);						\
 	return 1; /* CHECK_ME */
 
@@ -1369,6 +1370,16 @@
 	EX(original_in_execution) = EG(in_execution);
 	EX(prev_execute_data) = EG(current_execute_data);
 	EG(current_execute_data) = &execute_data;
+#if HARDENING_PATCH	
+	EX(execute_depth) = 0;
+
+	if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
+		EG(in_code_type) = ZEND_EVAL_CODE;
+	} else if (op_array->type == ZEND_SANDBOX_CODE) {
+		EG(in_code_type) = ZEND_SANDBOX_CODE;
+		op_array->type = ZEND_EVAL_CODE;
+	}
+#endif
 
 	EG(in_execution) = 1;
 	if (op_array->start_op) {
@@ -1395,6 +1406,19 @@
 	EX(function_state).function_symbol_table = NULL;
 #endif
 	
+#if HARDENING_PATCH	
+	if (EX(prev_execute_data) == NULL) {
+		EX(execute_depth) = 0;
+	} else {
+		EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
+	}
+
+	if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
+		zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
+		zend_bailout();
+	}
+#endif
+
 	while (1) {
 #ifdef ZEND_WIN32
 		if (EG(timed_out)) {
@@ -2647,6 +2671,37 @@
 		efree(lcname);
 		zend_error(E_ERROR, "Call to undefined function %s()", function_name_strval);
 	}
+#if HARDENING_PATCH	
+	if (EG(in_code_type) == ZEND_EVAL_CODE) {
+		if (HG(eval_whitelist) != NULL) {
+			if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
+			    zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
+			    efree(lcname);
+			    zend_bailout();
+			}
+		} else if (HG(eval_blacklist) != NULL) {
+			if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
+			    zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
+			    efree(lcname);
+			    zend_bailout();
+			}
+		}
+	}
+	
+	if (HG(func_whitelist) != NULL) {
+		if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
+		    zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
+		    efree(lcname);
+		    zend_bailout();
+		}
+	} else if (HG(func_blacklist) != NULL) {
+		if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
+		    zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
+		    efree(lcname);
+		    zend_bailout();
+		}
+	}
+#endif
 
 	efree(lcname);
 	if (!is_const) {
@@ -2851,6 +2906,34 @@
 	if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
 		zend_error(E_ERROR, "Unknown function:  %s()\n", fname->value.str.val);
 	}
+#if HARDENING_PATCH	
+	if (EG(in_code_type) == ZEND_EVAL_CODE) {
+		if (HG(eval_whitelist) != NULL) {
+			if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
+			    zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
+			    zend_bailout();
+			}
+		} else if (HG(eval_blacklist) != NULL) {
+			if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
+			    zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
+			    zend_bailout();
+			}
+		}
+	}
+
+	if (HG(func_whitelist) != NULL) {
+		if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
+		    zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
+		    zend_bailout();
+		}
+	} else if (HG(func_blacklist) != NULL) {
+		if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
+		    zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
+		    zend_bailout();
+		}
+	}
+#endif
+	
 	EX(object) = NULL;
 	EX(calling_scope) = EX(function_state).function->common.scope;
 
@@ -3523,7 +3606,12 @@
 				int dummy = 1;
 				zend_file_handle file_handle;
 
+#if HARDENING_PATCH_INC_PROTECT
+				if (zend_is_valid_include(inc_filename) 
+					&& (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
+#else
 				if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
+#endif
 
 					if (!file_handle.opened_path) {
 						file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
@@ -3548,6 +3636,11 @@
 			break;
 		case ZEND_INCLUDE:
 		case ZEND_REQUIRE:
+#if HARDENING_PATCH_INC_PROTECT
+			if (!zend_is_valid_include(inc_filename)) {
+				break;
+			}
+#endif
 			new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
 			break;
 		case ZEND_EVAL: {
diff -Nura php-5.0.4/Zend/zend_extensions.c hardening-patch-5.0.4-0.4.1/Zend/zend_extensions.c
--- php-5.0.4/Zend/zend_extensions.c	2004-01-08 18:31:47.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_extensions.c	2005-08-04 13:02:02.000000000 +0200
@@ -55,23 +55,44 @@
 		return FAILURE;
 	}
 
+	/* check if module is compiled against Hardening-Patch */
+	if (extension_version_info->zend_extension_api_no < 1000000000) {
+		fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
+				"The Hardening-Patch version %d is installed.\n\n",
+				new_extension->name,
+				HARDENING_PATCH_ZEND_EXTENSION_API_NO);
+		DL_UNLOAD(handle);
+		return FAILURE;
+	}
+
+
+	/* check if module is compiled against correct Hardening-Patch version */
+	if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
+		fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
+				"The Hardening-Patch version %d is installed.\n\n",
+				new_extension->name,
+				extension_version_info->zend_extension_api_no,
+				HARDENING_PATCH_ZEND_EXTENSION_API_NO);
+		DL_UNLOAD(handle);
+		return FAILURE;
+	}
 
 	/* allow extension to proclaim compatibility with any Zend version */
-	if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
-		if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
+	if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
+		if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
 			fprintf(stderr, "%s requires Zend Engine API version %d.\n"
 					"The Zend Engine API version %d which is installed, is outdated.\n\n",
 					new_extension->name,
-					extension_version_info->zend_extension_api_no,
+					extension_version_info->real_zend_extension_api_no,
 					ZEND_EXTENSION_API_NO);
 			DL_UNLOAD(handle);
 			return FAILURE;
-		} else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
+		} else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
 			fprintf(stderr, "%s requires Zend Engine API version %d.\n"
 					"The Zend Engine API version %d which is installed, is newer.\n"
 					"Contact %s at %s for a later version of %s.\n\n",
 					new_extension->name,
-					extension_version_info->zend_extension_api_no,
+					extension_version_info->real_zend_extension_api_no,
 					ZEND_EXTENSION_API_NO,
 					new_extension->author,
 					new_extension->URL,
diff -Nura php-5.0.4/Zend/zend_extensions.h hardening-patch-5.0.4-0.4.1/Zend/zend_extensions.h
--- php-5.0.4/Zend/zend_extensions.h	2004-11-25 21:26:48.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_extensions.h	2005-08-06 18:16:17.328900512 +0200
@@ -24,9 +24,11 @@
 
 #include "zend_compile.h"
 
-/* The first number is the engine version and the rest is the date.
+/* The first API number is a flag saying that Hardening-Patch is used.
+ * The second number is the engine version and the date.
  * This way engine 2 API no. is always greater than engine 1 API no..
  */
+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO	1002050805
 #define ZEND_EXTENSION_API_NO	220040412
 
 typedef struct _zend_extension_version_info {
@@ -34,6 +36,7 @@
 	char *required_zend_version;
 	unsigned char thread_safe;
 	unsigned char debug;
+	int real_zend_extension_api_no;
 } zend_extension_version_info;
 
 
@@ -101,7 +104,7 @@
 
 
 #define ZEND_EXTENSION()	\
-	ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
+	ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
 
 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
 #define COMPAT_ZEND_EXTENSION_PROPERTIES   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
diff -Nura php-5.0.4/Zend/zend_globals.h hardening-patch-5.0.4-0.4.1/Zend/zend_globals.h
--- php-5.0.4/Zend/zend_globals.h	2004-11-04 00:14:31.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_globals.h	2005-08-04 12:06:45.000000000 +0200
@@ -174,6 +174,16 @@
 
 	int error_reporting;
 	int orig_error_reporting;
+#if HARDENING_PATCH
+	int hphp_log_syslog;
+	int hphp_log_syslog_facility;
+	int hphp_log_syslog_priority;
+	int hphp_log_sapi;
+	int hphp_log_script;
+	char *hphp_log_scriptname;
+	zend_bool hphp_log_use_x_forwarded_for;
+	long hphp_executor_max_depth;
+#endif
 	int exit_status;
 
 	zend_op_array *active_op_array;
@@ -191,6 +201,7 @@
 	int ticks_count;
 
 	zend_bool in_execution;
+	zend_uint in_code_type;
 	HashTable *in_autoload;
 	zend_bool bailout_set;
 	zend_bool full_tables_cleanup;
diff -Nura php-5.0.4/Zend/zend.h hardening-patch-5.0.4-0.4.1/Zend/zend.h
--- php-5.0.4/Zend/zend.h	2005-03-10 12:30:44.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend.h	2005-08-04 12:06:45.000000000 +0200
@@ -290,6 +290,7 @@
 	/* Variable information */
 	zvalue_value value;		/* value */
 	zend_uint refcount;
+	zend_ushort flags;
 	zend_uchar type;	/* active type */
 	zend_uchar is_ref;
 };
@@ -359,6 +360,12 @@
 	void (*on_timeout)(int seconds TSRMLS_DC);
 	int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
 	int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
+#if HARDENING_PATCH
+	void (*security_log_function)(int loglevel, char *fmt, ...);
+#endif	
+#if HARDENING_PATCH_INC_PROTECT
+	int (*is_valid_include)(zval *z);
+#endif
 } zend_utility_functions;
 
 		
@@ -496,6 +503,16 @@
 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
+#if HARDENING_PATCH
+extern ZEND_API	void (*zend_security_log)(int loglevel, char *fmt, ...);
+#endif	
+#if HARDENING_PATCH_INC_PROTECT
+extern ZEND_API int (*zend_is_valid_include)(zval *z);
+#endif
+  
+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
+ZEND_API unsigned int zend_canary(void);
+#endif
 
 
 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
@@ -620,6 +637,11 @@
 #define ZEND_MAX_RESERVED_RESOURCES	4
 
 
+#if HARDENING_PATCH
+#include "hardened_globals.h"
+#include "php_syslog.h"
+#endif
+
 #endif /* ZEND_H */
 
 /*
diff -Nura php-5.0.4/Zend/zend_hash.c hardening-patch-5.0.4-0.4.1/Zend/zend_hash.c
--- php-5.0.4/Zend/zend_hash.c	2004-07-10 09:45:49.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_hash.c	2005-08-04 12:06:45.000000000 +0200
@@ -21,6 +21,18 @@
 
 #include "zend.h"
 
+#if HARDENING_PATCH_HASH_PROTECT
+	unsigned int zend_hash_canary = 0x1234567;
+	zend_bool zend_hash_canary_inited = 0;
+#endif
+
+#define CHECK_HASH_CANARY(hash) \
+	if (zend_hash_canary != (hash)->canary) { \
+		zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
+		exit(1); \
+	}
+
+
 #define CONNECT_TO_BUCKET_DLLIST(element, list_head)		\
 	(element)->pNext = (list_head);							\
 	(element)->pLast = NULL;								\
@@ -138,6 +150,9 @@
 {
 	uint i = 3;
 	Bucket **tmp;
+#if HARDENING_PATCH_HASH_PROTECT
+	TSRMLS_FETCH();	
+#endif	
 
 	SET_INCONSISTENT(HT_OK);
 
@@ -147,6 +162,13 @@
 
 	ht->nTableSize = 1 << i;
 	ht->nTableMask = ht->nTableSize - 1;
+#if HARDENING_PATCH_HASH_PROTECT
+	if (zend_hash_canary_inited==0) {
+		zend_hash_canary = zend_canary();
+		zend_hash_canary_inited = 1;
+	}
+	ht->canary = zend_hash_canary;
+#endif
 	ht->pDestructor = pDestructor;
 	ht->arBuckets = NULL;
 	ht->pListHead = NULL;
@@ -226,6 +248,9 @@
 				}
 #endif
 				if (ht->pDestructor) {
+#if HARDENING_PATCH_HASH_PROTECT
+					CHECK_HASH_CANARY(ht);
+#endif	
 					ht->pDestructor(p->pData);
 				}
 				UPDATE_DATA(ht, p, pData, nDataSize);
@@ -291,6 +316,9 @@
 				}
 #endif
 				if (ht->pDestructor) {
+#if HARDENING_PATCH_HASH_PROTECT
+					CHECK_HASH_CANARY(ht);
+#endif	
 					ht->pDestructor(p->pData);
 				}
 				UPDATE_DATA(ht, p, pData, nDataSize);
@@ -366,6 +394,9 @@
 			}
 #endif
 			if (ht->pDestructor) {
+#if HARDENING_PATCH_HASH_PROTECT
+				CHECK_HASH_CANARY(ht);
+#endif	
 				ht->pDestructor(p->pData);
 			}
 			UPDATE_DATA(ht, p, pData, nDataSize);
@@ -414,7 +445,7 @@
 	IS_CONSISTENT(ht);
 
 	if ((ht->nTableSize << 1) > 0) {	/* Let's double the table size */
-		t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
+		t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
 		if (t) {
 			HANDLE_BLOCK_INTERRUPTIONS();
 			ht->arBuckets = t;
@@ -424,6 +455,7 @@
 			HANDLE_UNBLOCK_INTERRUPTIONS();
 			return SUCCESS;
 		}
+		zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
 		return FAILURE;
 	}
 	return SUCCESS;
@@ -487,6 +519,9 @@
 				ht->pInternalPointer = p->pListNext;
 			}
 			if (ht->pDestructor) {
+#if HARDENING_PATCH_HASH_PROTECT
+				CHECK_HASH_CANARY(ht);
+#endif	
 				ht->pDestructor(p->pData);
 			}
 			if (!p->pDataPtr) {
@@ -516,6 +551,9 @@
 		q = p;
 		p = p->pListNext;
 		if (ht->pDestructor) {
+#if HARDENING_PATCH_HASH_PROTECT
+			CHECK_HASH_CANARY(ht);
+#endif	
 			ht->pDestructor(q->pData);
 		}
 		if (!q->pDataPtr && q->pData) {
@@ -542,6 +580,9 @@
 		q = p;
 		p = p->pListNext;
 		if (ht->pDestructor) {
+#if HARDENING_PATCH_HASH_PROTECT
+			CHECK_HASH_CANARY(ht);
+#endif	
 			ht->pDestructor(q->pData);
 		}
 		if (!q->pDataPtr && q->pData) {
@@ -571,6 +612,9 @@
 	HANDLE_BLOCK_INTERRUPTIONS();
 
 	if (ht->pDestructor) {
+#if HARDENING_PATCH_HASH_PROTECT
+		CHECK_HASH_CANARY(ht);
+#endif	
 		ht->pDestructor(p->pData);
 	}
 	if (!p->pDataPtr) {
diff -Nura php-5.0.4/Zend/zend_hash.h hardening-patch-5.0.4-0.4.1/Zend/zend_hash.h
--- php-5.0.4/Zend/zend_hash.h	2004-01-08 18:31:47.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_hash.h	2005-08-04 12:06:45.000000000 +0200
@@ -58,6 +58,9 @@
 } Bucket;
 
 typedef struct _hashtable {
+#if HARDENING_PATCH_HASH_PROTECT
+	unsigned int canary;
+#endif	
 	uint nTableSize;
 	uint nTableMask;
 	uint nNumOfElements;
diff -Nura php-5.0.4/Zend/zend_language_scanner.c hardening-patch-5.0.4-0.4.1/Zend/zend_language_scanner.c
--- php-5.0.4/Zend/zend_language_scanner.c	2005-04-03 11:42:53.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_language_scanner.c	2005-08-06 10:08:58.000000000 +0200
@@ -3152,6 +3152,13 @@
 		compilation_successful=0;
 	} else {
 		init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
+#if HARDENING_PATCH
+		if (EG(in_code_type)==ZEND_EVAL_CODE) {
+			op_array->created_by_eval = 1;
+		} else {
+			op_array->created_by_eval = 0;
+		}
+#endif
 		CG(in_compilation) = 1;
 		CG(active_op_array) = op_array;
 		compiler_result = zendparse(TSRMLS_C);
diff -Nura php-5.0.4/Zend/zend_language_scanner.l hardening-patch-5.0.4-0.4.1/Zend/zend_language_scanner.l
--- php-5.0.4/Zend/zend_language_scanner.l	2005-03-07 17:48:12.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_language_scanner.l	2005-08-06 10:08:40.000000000 +0200
@@ -385,6 +385,13 @@
 		compilation_successful=0;
 	} else {
 		init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
+#if HARDENING_PATCH
+		if (EG(in_code_type)==ZEND_EVAL_CODE) {
+			op_array->created_by_eval = 1;
+		} else {
+			op_array->created_by_eval = 0;
+		}
+#endif
 		CG(in_compilation) = 1;
 		CG(active_op_array) = op_array;
 		compiler_result = zendparse(TSRMLS_C);
diff -Nura php-5.0.4/Zend/zend_llist.c hardening-patch-5.0.4-0.4.1/Zend/zend_llist.c
--- php-5.0.4/Zend/zend_llist.c	2004-01-08 18:31:47.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_llist.c	2005-08-04 12:06:45.000000000 +0200
@@ -22,9 +22,34 @@
 #include "zend.h"
 #include "zend_llist.h"
 #include "zend_qsort.h"
+#include "zend_globals.h"
+
+#define CHECK_LIST_CANARY(list) \
+	if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
+		zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
+		exit(1); \
+	}
+
+#define CHECK_LISTELEMENT_CANARY(elem) \
+	if (HG(canary_3) != (elem)->canary) { \
+		zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
+		exit(1); \
+	}
+
 
 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
 {
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	
+	if (!HG(ll_canary_inited)) {
+		HG(canary_3) = zend_canary();
+		HG(canary_4) = zend_canary();
+		HG(ll_canary_inited) = 1;
+	}
+	l->canary_h = HG(canary_3);
+	l->canary_t = HG(canary_4);
+#endif
 	l->head  = NULL;
 	l->tail  = NULL;
 	l->count = 0;
@@ -38,6 +63,11 @@
 {
 	zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	CHECK_LIST_CANARY(l)
+	tmp->canary = HG(canary_3);
+#endif
 	tmp->prev = l->tail;
 	tmp->next = NULL;
 	if (l->tail) {
@@ -56,6 +86,11 @@
 {
 	zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	CHECK_LIST_CANARY(l)
+	tmp->canary = HG(canary_3);
+#endif
 	tmp->next = l->head;
 	tmp->prev = NULL;
 	if (l->head) {
@@ -93,10 +128,20 @@
 	zend_llist_element *current=l->head;
 	zend_llist_element *next;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	CHECK_LIST_CANARY(l)
+#endif
 	while (current) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(current)
+#endif
 		next = current->next;
 		if (compare(current->data, element)) {
 			DEL_LLIST_ELEMENT(current, l);
+#if HARDENING_PATCH_LL_PROTECT
+			current->canary = 0;
+#endif
 			break;
 		}
 		current = next;
@@ -108,7 +153,14 @@
 {
 	zend_llist_element *current=l->head, *next;
 	
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	CHECK_LIST_CANARY(l)
+#endif
 	while (current) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(current)
+#endif
 		next = current->next;
 		if (l->dtor) {
 			l->dtor(current->data);
@@ -133,7 +185,14 @@
 	zend_llist_element *old_tail;
 	void *data;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	CHECK_LIST_CANARY(l)
+#endif
 	if ((old_tail = l->tail)) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(old_tail)
+#endif
 		if (l->tail->prev) {
 			l->tail->prev->next = NULL;
 		}
@@ -159,9 +218,16 @@
 {
 	zend_llist_element *ptr;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	CHECK_LIST_CANARY(src)
+#endif
 	zend_llist_init(dst, src->size, src->dtor, src->persistent);
 	ptr = src->head;
 	while (ptr) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(ptr)
+#endif
 		zend_llist_add_element(dst, ptr->data);
 		ptr = ptr->next;
 	}
@@ -172,11 +238,21 @@
 {
 	zend_llist_element *element, *next;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();	
+	CHECK_LIST_CANARY(l)
+#endif
 	element=l->head;
 	while (element) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(element)
+#endif
 		next = element->next;
 		if (func(element->data)) {
 			DEL_LLIST_ELEMENT(element, l);
+#if HARDENING_PATCH_LL_PROTECT
+			element->canary = 0;
+#endif
 		}
 		element = next;
 	}
@@ -187,7 +263,13 @@
 {
 	zend_llist_element *element;
 
+#if HARDENING_PATCH_LL_PROTECT
+	CHECK_LIST_CANARY(l)
+#endif
 	for (element=l->head; element; element=element->next) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(element)
+#endif
 		func(element->data TSRMLS_CC);
 	}
 }
@@ -199,6 +281,9 @@
 	zend_llist_element **elements;
 	zend_llist_element *element, **ptr;
 
+#if HARDENING_PATCH_LL_PROTECT
+	CHECK_LIST_CANARY(l)
+#endif
 	if (l->count <= 0) {
 		return;
 	}
@@ -208,6 +293,9 @@
 	ptr = &elements[0];
 
 	for (element=l->head; element; element=element->next) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(element)
+#endif
 		*ptr++ = element;
 	}
 
@@ -230,7 +318,13 @@
 {
 	zend_llist_element *element;
 
+#if HARDENING_PATCH_LL_PROTECT
+	CHECK_LIST_CANARY(l)
+#endif
 	for (element=l->head; element; element=element->next) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(element)
+#endif
 		func(element->data, arg TSRMLS_CC);
 	}
 }
@@ -241,8 +335,14 @@
 	zend_llist_element *element;
 	va_list args;
 
+#if HARDENING_PATCH_LL_PROTECT
+	CHECK_LIST_CANARY(l)
+#endif
 	va_start(args, num_args);
 	for (element=l->head; element; element=element->next) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(element)
+#endif
 		func(element->data, num_args, args TSRMLS_CC);
 	}
 	va_end(args);
@@ -251,6 +351,10 @@
 
 ZEND_API int zend_llist_count(zend_llist *l)
 {
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();
+	CHECK_LIST_CANARY(l)
+#endif
 	return l->count;
 }
 
@@ -259,8 +363,15 @@
 {
 	zend_llist_position *current = pos ? pos : &l->traverse_ptr;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();
+	CHECK_LIST_CANARY(l)
+#endif
 	*current = l->head;
 	if (*current) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(*current)
+#endif
 		return (*current)->data;
 	} else {
 		return NULL;
@@ -272,8 +383,15 @@
 {
 	zend_llist_position *current = pos ? pos : &l->traverse_ptr;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();
+	CHECK_LIST_CANARY(l)
+#endif
 	*current = l->tail;
 	if (*current) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(*current)
+#endif
 		return (*current)->data;
 	} else {
 		return NULL;
@@ -285,9 +403,19 @@
 {
 	zend_llist_position *current = pos ? pos : &l->traverse_ptr;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();
+	CHECK_LIST_CANARY(l)
+#endif
 	if (*current) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(*current)
+#endif
 		*current = (*current)->next;
 		if (*current) {
+#if HARDENING_PATCH_LL_PROTECT
+			CHECK_LISTELEMENT_CANARY(*current)
+#endif
 			return (*current)->data;
 		}
 	}
@@ -299,9 +427,19 @@
 {
 	zend_llist_position *current = pos ? pos : &l->traverse_ptr;
 
+#if HARDENING_PATCH_LL_PROTECT
+	TSRMLS_FETCH();
+	CHECK_LIST_CANARY(l)
+#endif
 	if (*current) {
+#if HARDENING_PATCH_LL_PROTECT
+		CHECK_LISTELEMENT_CANARY(*current)
+#endif
 		*current = (*current)->prev;
 		if (*current) {
+#if HARDENING_PATCH_LL_PROTECT
+			CHECK_LISTELEMENT_CANARY(*current)
+#endif
 			return (*current)->data;
 		}
 	}
diff -Nura php-5.0.4/Zend/zend_llist.h hardening-patch-5.0.4-0.4.1/Zend/zend_llist.h
--- php-5.0.4/Zend/zend_llist.h	2004-01-08 18:31:47.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_llist.h	2005-08-04 12:06:45.000000000 +0200
@@ -23,6 +23,9 @@
 #define ZEND_LLIST_H
 
 typedef struct _zend_llist_element {
+#if HARDENING_PATCH_LL_PROTECT
+	unsigned int canary;
+#endif	
 	struct _zend_llist_element *next;
 	struct _zend_llist_element *prev;
 	char data[1]; /* Needs to always be last in the struct */
@@ -35,6 +38,9 @@
 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
 
 typedef struct _zend_llist {
+#if HARDENING_PATCH_LL_PROTECT
+	unsigned int canary_h; /* head */
+#endif	
 	zend_llist_element *head;
 	zend_llist_element *tail;
 	size_t count;
@@ -42,6 +48,9 @@
 	llist_dtor_func_t dtor;
 	unsigned char persistent;
 	zend_llist_element *traverse_ptr;
+#if HARDENING_PATCH_LL_PROTECT
+	unsigned int canary_t; /* tail */
+#endif	
 } zend_llist;
 
 typedef zend_llist_element* zend_llist_position;
diff -Nura php-5.0.4/Zend/zend_modules.h hardening-patch-5.0.4-0.4.1/Zend/zend_modules.h
--- php-5.0.4/Zend/zend_modules.h	2005-03-16 00:47:12.000000000 +0100
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_modules.h	2005-08-06 18:16:27.582341752 +0200
@@ -38,6 +38,7 @@
 extern struct _zend_arg_info fourth_arg_force_ref[5];
 extern struct _zend_arg_info all_args_by_ref[1];
 
+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002050805
 #define ZEND_MODULE_API_NO 20041030
 #ifdef ZTS
 #define USING_ZTS 1
@@ -45,10 +46,10 @@
 #define USING_ZTS 0
 #endif
 
-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, NULL
-#define ZE2_STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, ini_entries
+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, NULL
+#define ZE2_STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, ini_entries
 
-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
 
 #define STANDARD_MODULE_PROPERTIES \
 	NULL, STANDARD_MODULE_PROPERTIES_EX
@@ -81,6 +82,7 @@
 	unsigned char type;
 	void *handle;
 	int module_number;
+	unsigned int real_zend_api;
 };
 
 
diff -Nura php-5.0.4/Zend/zend_opcode.c hardening-patch-5.0.4-0.4.1/Zend/zend_opcode.c
--- php-5.0.4/Zend/zend_opcode.c	2004-06-06 10:37:12.000000000 +0200
+++ hardening-patch-5.0.4-0.4.1/Zend/zend_opcode.c	2005-08-06 10:08:19.000000000 +0200
@@ -92,6 +92,9 @@
 	op_array->uses_this = 0;
 
 	op_array->start_op = NULL;
+#if HARDENING_PATCH
+	op_array->created_by_eval = 0;
+#endif
 
 	zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
 }
